summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2017-12-23 15:52:22 -0500
committerLuke Shumaker <lukeshu@lukeshu.com>2017-12-23 21:32:16 -0500
commitefbd3731c986a8555869c184cda69ff9b910ce9f (patch)
tree0fb2ab20c6618c120baac1d192ee5c5558fb1fe0
parent7c62b0a53c35f2cfce07469fb771ef0aa8f2302d (diff)
pdf support
-rw-r--r--Makefile12
-rw-r--r--README.org16
-rw-r--r--lib/page_local.rb3
-rw-r--r--lib/page_pdf.rb62
-rw-r--r--src/main.scss26
-rw-r--r--tmpl/pdf.md.erb5
6 files changed, 122 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index 96e0fdf..f61c4c3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,9 @@
MAKEFLAGS += -j1
+pdfjs = https://github.com/mozilla/pdf.js/releases/download/v1.9.426/pdfjs-1.9.426-dist.zip
+
# Default target
-all: out/index.html out/main.css
+all: out/index.html out/main.css out/pdfjs
phony += all
# Boilerplate
@@ -25,7 +27,13 @@ out/%.css: src/%.scss
@mkdir -p $(@D)
scss --stdin < $< > $@
-targets = $(phony) %.css
+out/$(notdir $(pdfjs)):
+ wget -c --no-use-server-timestamp -O $@ $(pdfjs)
+out/pdfjs: out/$(notdir $(pdfjs))
+ rm -rf -- $@
+ mkdir -- $@ && bsdtar -xf $(abspath $<) -C $@ --exclude '*.pdf' || { rm -rf -- $@; false; }
+
+targets = $(phony) %.css out/pdfjs%
$(sort $(filter-out $(targets),out/index.html $(MAKECMDGOALS))): FORCE
./bin/sitegen
diff --git a/README.org b/README.org
index e8a3542..e95aff5 100644
--- a/README.org
+++ b/README.org
@@ -63,6 +63,7 @@ Currently supported formats are:
- Markdown (~.md~) : converted with Pandoc
- Org-mode (~.org~) : converted with Pandoc
+ - PDF (~.pdf~) : embedded with PDF.js
I don't need to tell you how to make these types of files.
@@ -107,6 +108,21 @@ when converting to HTML. See the Org-mode and Pandoc documentation.
AFAIK, unfortunately Org-mode only has values as strings, no
structured data.
+** Setting metadata: PDF
+
+PDF files natively support embedding certain bits of metadata. The
+bits that we use are:
+
+ - title
+ - author
+ - creation date
+ - modification date
+
+If you need to set any other metadata attributes, or want to override
+the values in the PDF (since setting them can be difficult), create
+YAML file with the same name as the PDF file, but with the ~.yaml~
+file extension instead of ~.pdf~.
+
** Metadata attributes that are handles specially
There are some metadata attributes that are used specially by the site
diff --git a/lib/page_local.rb b/lib/page_local.rb
index e956f6a..6c70ac3 100644
--- a/lib/page_local.rb
+++ b/lib/page_local.rb
@@ -16,6 +16,9 @@ class LocalPage < Page
return IndexPage::new(inpath)
when [".md", ".org"].include?(File::extname(inpath))
return LocalPage::new(inpath)
+ when ".pdf" == File::extname(inpath)
+ require 'page_pdf'
+ return PdfPage::new(inpath)
else
return nil
end
diff --git a/lib/page_pdf.rb b/lib/page_pdf.rb
new file mode 100644
index 0000000..e70c887
--- /dev/null
+++ b/lib/page_pdf.rb
@@ -0,0 +1,62 @@
+# coding: utf-8
+require 'erb'
+require 'open3'
+require 'yaml'
+
+require 'page_local'
+
+class PdfPage < LocalPage
+ def initialize(filename)
+ super(filename)
+ end
+
+ def pdf_metadata
+ if @metadata.nil?
+ stdout, stderr, status = Open3::capture3("pdfinfo", "--", local_infile)
+ unless stderr.empty?
+ raise stderr
+ end
+ unless status.success?
+ raise status
+ end
+ raw_metadata = stdout.split("\n").map{|l|l.split(":", 2).map{|c|c.strip}}.to_h
+
+ # Transform the PDF property names to match our metadata names
+ key_map = {
+ "Title" => "title",
+ "Author" => "author",
+ "CreationDate" => "published",
+ "ModDate" => "updated",
+ # "Keywords" => "categories",
+ }
+ @metadata = raw_metadata.map{|k,v|[key_map[k]||k,v]}.to_h
+
+ yamlfile = local_infile.sub(/\.pdf$/, '.yaml')
+ if File::exist?(yamlfile)
+ @metadata = @metadata.merge(YAML::load(File::read(yamlfile)))
+ end
+ end
+ @metadata
+ end
+ def pdf_js_url
+ @@pdjfs ||= Config::get.url + 'pdfjs/web/viewer.html'
+ end
+ def pdf_viewer_url
+ @viewer_url ||= pdf_js_url + ('?file=' + URI::encode_www_form_component(pdf_js_url.route_to(local_srcurl)))
+ end
+
+ def local_intype
+ return 'markdown'
+ end
+ def local_depends
+ if @depends.nil?
+ yamlfile = local_infile.sub(/\.pdf$/, '.yaml')
+ metafile = File::exist?(yamlfile) ? yamlfile : File::dirname(yamlfile)
+ tmplfile = "tmpl/pdf.md.erb"
+ @depends = super.map{|k,v|[k,v.merge([metafile, tmplfile])]}.to_h
+ end
+ @depends
+ end
+end
+
+ERB::new(File::read("tmpl/pdf.md.erb")).def_method(PdfPage, 'local_input()', "tmpl/pdf.md.erb")
diff --git a/src/main.scss b/src/main.scss
index be00d49..cdbc200 100644
--- a/src/main.scss
+++ b/src/main.scss
@@ -287,3 +287,29 @@ body.dnd {
font-weight:bold; }
}
}
+
+/* D&D-style pages ************************************************************/
+
+body.pdf {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ bottom: 0;
+
+ display: flex;
+ flex-direction: column;
+
+ article {
+ flex-grow: 2;
+ padding: 0;
+
+ h1 {
+ text-align: center;
+ margin: 0.25em 0;
+ }
+ iframe {
+ width: 100%;
+ height: 100%;
+ }
+ }
+}
diff --git a/tmpl/pdf.md.erb b/tmpl/pdf.md.erb
new file mode 100644
index 0000000..2ce7327
--- /dev/null
+++ b/tmpl/pdf.md.erb
@@ -0,0 +1,5 @@
+<%= pdf_metadata.to_yaml %>
+class: pdf
+---
+
+<iframe src="<%= url.route_to(pdf_viewer_url) %>" ></iframe>