octopress-printable 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 08895c17e55c60513b22e894ad0d273f20275276
4
+ data.tar.gz: c92e6d6cfafd0b8f00e2496935f9f4bf5b0a5f6a
5
+ SHA512:
6
+ metadata.gz: a0dd29e2f8ec949cc655bfef4b52321cbedef3545d746aad4ad179f0fd9b609ba9079aec1489e21523931940d7b1fa4855c7bd47b71f227c4993ea901aa5498a
7
+ data.tar.gz: 8ae4905565a407993dbf2c81c008838b2243756544aca556d510690939f4f96cfe1d6ad4d27aaba43fc41b99ecedc4a2719b7f0a62990e2114bc90eb2371de46
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0 - 2015-04-29
4
+ - Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Wang Jian
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # octopress-printable
2
+
3
+ An octopress ink plugin generating printable version of markdown posts.
4
+
5
+ [![Build Status](https://travis-ci.org/wantee/octopress-printable.svg)](https://travis-ci.org/wantee/octopress-printable)
6
+ [![Gem Version](https://badge.fury.io/rb/octopress-printable.svg)](http://badge.fury.io/rb/octopress-printable)
7
+ [![License](http://img.shields.io/:license-mit-blue.svg)](https://github.com/wantee/octopress-printable/blob/master/LICENSE.txt)
8
+
9
+ ## Prerequisites
10
+ * [Pandoc](pandoc.org/), >= 1.13.2
11
+ * TeX Live 2013
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'octopress-printable'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install octopress-printable
28
+
29
+ ## Usage
30
+
31
+ Add `{% include octopress-printable:printable.html %}` to your site's layout, this will create a link to the pdf files corresponding current post or page.
32
+
33
+ Tags will be converted includes `img` (from [octopress-image-tag](https://github.com/octopress/image-tag)), `gist` (from [octopress-gist](https://github.com/octopress/gist)), `bibliography` and `cite` (from [jekyll-scholar](https://github.com/inukshuk/jekyll-scholar)).
34
+
35
+ Details please refer to `test/test-site/_posts/2015-04-29-foo.markdown`.
36
+
37
+ ## Configuration
38
+
39
+ To configure this plugin, run `$ octopress ink copy octopress-printable --config`, then the config should be in `_plugins/octopress-printable/config.yml` and add your settings. Here are
40
+ the defaults.
41
+
42
+ ```yaml config
43
+ posts_dir: "_posts"
44
+ printables_dir: "assets/printables"
45
+ source_dir: "."
46
+ blog_url: "http://example.com" # used in pdf post_links
47
+ bibliography_dir: "_bibliography"
48
+ bibliography: "references.bib"
49
+
50
+ # only convert markdowns, without running pandoc and xelatex
51
+ dry_run : false
52
+
53
+ # debug files
54
+ dump_tex_file: false
55
+ dump_markdown_file: false
56
+ dump_bib_file: false
57
+ dump_cmds: false
58
+ keep_tmp_files: false
59
+
60
+ ```
61
+
62
+ ## Contributing
63
+
64
+ 1. Fork it ( https://github.com/wantee/octopress-printable/fork )
65
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
66
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
67
+ 4. Push to the branch (`git push origin my-new-feature`)
68
+ 5. Create a new Pull Request
data/assets/config.yml ADDED
@@ -0,0 +1,17 @@
1
+ posts_dir: "_posts"
2
+ printables_dir: "assets/printables"
3
+ source_dir: "."
4
+ blog_url: "http://example.com" # used in pdf post_links
5
+ bibliography_dir: "_bibliography"
6
+ bibliography: "references.bib"
7
+
8
+ # only convert markdowns, without running pandoc and xelatex
9
+ dry_run : false
10
+
11
+ # debug files
12
+ dump_tex_file: false
13
+ dump_markdown_file: false
14
+ dump_bib_file: false
15
+ dump_cmds: false
16
+ keep_tmp_files: false
17
+
Binary file
@@ -0,0 +1,13 @@
1
+ <span class="printable">
2
+
3
+ {% if post %}
4
+ {% capture url %}assets/printables/{{ post.url | url2filename }}.pdf{% endcapture %}
5
+ {% else %}
6
+ {% capture url %}assets/printables/{{ page.id | url2filename }}.pdf{% endcapture %}
7
+ {% endif %}
8
+
9
+ {% if url %}
10
+ <a href="{{ root_url }}/{{ url }}"> <img src="/images/octopress-printable/printer.png" alt="printable version"> </a>
11
+ {% endif %}
12
+
13
+ </span>
@@ -0,0 +1,8 @@
1
+ .printable {
2
+ img, a {
3
+ border: none;
4
+ outline: none;
5
+ text-decoration: none;
6
+ };
7
+ }
8
+
@@ -0,0 +1,26 @@
1
+ require 'octopress-printable/version'
2
+ require 'octopress-ink'
3
+
4
+ module Octopress
5
+ module Printable
6
+ autoload :Filters, 'octopress-printable/filters'
7
+ autoload :Tags, 'octopress-printable/tags'
8
+ autoload :Plugin, 'octopress-printable/plugin'
9
+ end
10
+ end
11
+
12
+ Liquid::Template.register_filter(Octopress::Printable::Filters)
13
+
14
+ Liquid::Template.register_tag('post_link', Octopress::Printable::Tags)
15
+
16
+ Octopress::Ink.register_plugin(Octopress::Printable::Plugin, {
17
+ name: "Octopress Printable",
18
+ slug: "octopress-printable",
19
+ gem: "octopress-printable",
20
+ path: File.expand_path(File.join(File.dirname(__FILE__), "..")),
21
+ type: "plugin",
22
+ version: Octopress::Printable::VERSION,
23
+ description: "Printable version for post generator.",
24
+ source_url: "https://github.com/wantee/octopress-printable",
25
+ website: ""
26
+ })
@@ -0,0 +1,69 @@
1
+ module Octopress
2
+ module Printable
3
+ class BibConverter < Converter
4
+
5
+ def initialize(src_bib, tgt_bib)
6
+ super()
7
+
8
+ @src_bib = src_bib
9
+ @tgt_bib = tgt_bib
10
+ end
11
+
12
+ def convert(line)
13
+ str = line
14
+ if /##*\s*References/ =~ str
15
+ return ""
16
+ end
17
+
18
+ if /{% bibliography .*? %}/ =~ str
19
+ @match = true
20
+
21
+ str = "\\bibliographystyle{unsrt}\\bibliography{#{@tgt_bib.sub(/\..*$/, "")}}"
22
+
23
+ gen_bib("#{@src_bib}", "#{@tgt_bib}")
24
+ end
25
+
26
+ while /{% cite\s+(?<citation>.*?)\s+%}/ =~ str
27
+ @match = true
28
+ citation = citation.sub(/\s+/, ',')
29
+ str = str.sub(/{% cite\s+(.*?)\s+%}/, "\\cite{#{citation}}")
30
+ end
31
+
32
+ str
33
+ end
34
+
35
+ def gen_bib(obib, bib)
36
+ File.open(obib, 'r') do |f|
37
+ File.open(bib, 'w') do |o|
38
+ while l = f.gets
39
+ if /<a\s+href="?(?<url>.*?)"?\s*>(?<text>.*?)<\/a>/ =~ l
40
+ l = l.sub(/<a\s+href=(.*?)>(.*?)<\/a>/, "\\href{#{url}}{#{text}}")
41
+ end
42
+
43
+ o.puts l
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ def cleanup()
50
+ File.delete(@tgt_bib)
51
+ end
52
+
53
+ def header
54
+ lines = []
55
+ lines << '\\usepackage[sort&compress, numbers]{natbib}'
56
+ end
57
+
58
+ def before_xelatex(step, texfile)
59
+ cmds = []
60
+ if step == 2
61
+ cmds << "bibtex #{texfile.sub(/\.tex$/, "")} >/dev/null"
62
+ end
63
+ cmds
64
+ end
65
+
66
+ end
67
+ end
68
+ end
69
+
@@ -0,0 +1,37 @@
1
+ module Octopress
2
+ module Printable
3
+ class Converter
4
+
5
+ attr_accessor :match
6
+
7
+ def initialize()
8
+ @match = false
9
+ end
10
+
11
+ def convert(line)
12
+ line
13
+ end
14
+
15
+ def header()
16
+ []
17
+ end
18
+
19
+ def pandoc_args
20
+ []
21
+ end
22
+
23
+ def xelatex_args(step)
24
+ []
25
+ end
26
+
27
+ def before_xelatex(step, texfile)
28
+ []
29
+ end
30
+
31
+ def last_xelatex(texfile)
32
+ []
33
+ end
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,16 @@
1
+ module Octopress
2
+ module Printable
3
+ module Filters
4
+ def url2filename(url)
5
+ url = url.to_s.gsub(/\//, '-')
6
+ url = url.sub(/^[^0-9]*-/, '')
7
+ url = url.sub(/-$/, '')
8
+ end
9
+
10
+ def latex(*p)
11
+ ""
12
+ end
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,42 @@
1
+ require 'octopress-printable/gist_cache'
2
+
3
+ module Octopress
4
+ module Printable
5
+ class GistConverter < Converter
6
+
7
+ def convert(line)
8
+ str = line
9
+
10
+ if /{%\s+gist\s+(?<gist_txt>.*?)\s+%}/ =~ str
11
+ @match = true
12
+
13
+ gist = GistCache.new(gist_txt)
14
+ gist_file = gist.render()
15
+ if gist_file == ""
16
+ str = ""
17
+ else
18
+ lang = "text"
19
+ if /\.py$/ =~ gist_file
20
+ lang = 'Python'
21
+ end
22
+
23
+ str = "\\inputminted[mathescape, linenos, frame=lines, framesep=2mm]{#{lang}}{#{gist_file}}"
24
+ end
25
+ end
26
+
27
+ str
28
+ end
29
+
30
+ def header
31
+ lines = []
32
+ lines << '\\usepackage{minted}'
33
+ end
34
+
35
+ def xelatex_args(step)
36
+ args = []
37
+ args << "-shell-escape"
38
+ end
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,124 @@
1
+ # A Liquid tag for Jekyll sites that allows embedding Gists and showing code for non-JavaScript enabled browsers and readers.
2
+ # by: Brandon Tilly
3
+ # Source URL: https://gist.github.com/1027674
4
+ # Post http://brandontilley.com/2011/01/31/gist-tag-for-jekyll.html
5
+ #
6
+ # Example usage: {% gist 1027674 gist_tag.rb %} //embeds a gist for this plugin
7
+
8
+ require 'cgi'
9
+ require 'digest/md5'
10
+ require 'net/https'
11
+ require 'uri'
12
+
13
+ module Octopress
14
+ module Printable
15
+ class GistCache
16
+
17
+ def initialize(text)
18
+ @text = text
19
+ @cache_disabled = false
20
+ @cache_folder = '.gist-cache'
21
+ FileUtils.mkdir_p @cache_folder
22
+ end
23
+
24
+ def render()
25
+ if parts = @text.match(/([a-zA-Z\d]*) (.*)/)
26
+ gist, file = parts[1].strip, parts[2].strip
27
+ else
28
+ gist, file = @text.strip, ""
29
+ end
30
+ if gist.empty?
31
+ ""
32
+ else
33
+ script_url = script_url_for gist, file
34
+ code = get_cached_gist(gist, file) || get_gist_from_web(gist, file)
35
+ #html_output_for script_url, code
36
+ cache_file = get_cache_file_for gist, file
37
+ end
38
+ end
39
+
40
+ def html_output_for(script_url, code)
41
+ code = CGI.escapeHTML code
42
+ <<-HTML
43
+ iv><script src='#{script_url}'></script>
44
+ oscript><pre><code>#{code}</code></pre></noscript></div>
45
+ HTML
46
+ end
47
+
48
+ def script_url_for(gist_id, filename)
49
+ url = "https://gist.github.com/#{gist_id}.js"
50
+ url = "#{url}?file=#{filename}" unless filename.nil? or filename.empty?
51
+ url
52
+ end
53
+
54
+ def get_gist_url_for(gist, file)
55
+ "https://gist.githubusercontent.com/raw/#{gist}/#{file}"
56
+ end
57
+
58
+ def cache(gist, file, data)
59
+ cache_file = get_cache_file_for gist, file
60
+ File.open(cache_file, "w") do |io|
61
+ io.write data
62
+ end
63
+ end
64
+
65
+ def get_cached_gist(gist, file)
66
+ return nil if @cache_disabled
67
+ cache_file = get_cache_file_for gist, file
68
+ File.read cache_file if File.exist? cache_file
69
+ end
70
+
71
+ def get_cache_file_for(gist, file)
72
+ bad_chars = /[^a-zA-Z0-9\-_.]/
73
+ gist = gist.gsub bad_chars, ''
74
+ file = file.gsub bad_chars, ''
75
+ md5 = Digest::MD5.hexdigest "#{gist}-#{file}"
76
+ File.join @cache_folder, "cache.#{md5}-#{gist}-#{file}"
77
+ end
78
+
79
+ def get_gist_from_web(gist, file)
80
+ gist_url = get_gist_url_for(gist, file)
81
+ data = get_web_content(gist_url)
82
+
83
+ locations = Array.new
84
+ while (data.code.to_i == 301 || data.code.to_i == 302)
85
+ data = handle_gist_redirecting(data)
86
+ break if locations.include? data.header['Location']
87
+ locations << data.header['Location']
88
+ end
89
+
90
+ if data.code.to_i != 200
91
+ raise RuntimeError, "Gist replied with #{data.code} for #{gist_url}"
92
+ end
93
+
94
+ cache(gist, file, data.body) unless @cache_disabled
95
+ data.body
96
+ end
97
+
98
+ def handle_gist_redirecting(data)
99
+ redirected_url = data.header['Location']
100
+ if redirected_url.nil? || redirected_url.empty?
101
+ raise ArgumentError, "GitHub replied with a 302 but didn't provide a location in the response headers."
102
+ end
103
+
104
+ get_web_content(redirected_url)
105
+ end
106
+
107
+ def get_web_content(url)
108
+ raw_uri = URI.parse url
109
+ proxy = ENV['http_proxy']
110
+ if proxy
111
+ proxy_uri = URI.parse(proxy)
112
+ https = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port).new raw_uri.host, raw_uri.port
113
+ else
114
+ https = Net::HTTP.new raw_uri.host, raw_uri.port
115
+ end
116
+ https.use_ssl = true
117
+ https.verify_mode = OpenSSL::SSL::VERIFY_NONE
118
+ request = Net::HTTP::Get.new raw_uri.request_uri
119
+ data = https.request request
120
+ end
121
+ end
122
+ end
123
+ end
124
+
@@ -0,0 +1,60 @@
1
+ module Octopress
2
+ module Printable
3
+ class ImgConverter < Converter
4
+
5
+ TITLE_REGEX = /title:['|"](.+?)['|"]/
6
+
7
+ def initialize(source_dir)
8
+ super()
9
+
10
+ @source_dir = source_dir
11
+ end
12
+
13
+ def convert(line)
14
+ str = line
15
+
16
+ if /{% img (?<markup>.*) %}/ =~ str
17
+ @match = true
18
+
19
+ img = get_img_label(markup)
20
+ str="\\begin{figure}[h]\\centering\\includegraphics[width=\\textwidth]{#{@source_dir}/#{img['src']}}\\caption{#{img['title']}}\\label{#{img['alt']}}\\end{figure}"
21
+ end
22
+
23
+ str
24
+ end
25
+
26
+ # from octopress-image-tag plugin
27
+ def get_img_label(markup)
28
+ title = markup.scan(TITLE_REGEX).flatten.compact.last
29
+ markup.gsub!(TITLE_REGEX, '')
30
+
31
+ if markup =~ /(?<class>\S.*\s+)?(?<src>(?:https?:\/\/|\/|\S+\/)\S+)(?:\s+(?<width>\d\S+))?(?:\s+(?<height>\d\S+))?(?<alt>\s+.+)?/i
32
+ attributes = ['class', 'src', 'width', 'height', 'alt']
33
+ image = attributes.reduce({}) { |img, attr| img[attr] ||= $~[attr].strip if $~[attr]; img }
34
+ text = image['alt']
35
+
36
+ # Allow parsing "title" "alt"
37
+ if text =~ /(?:"|')(?<title>[^"']+)?(?:"|')\s+(?:"|')(?<alt>[^"']+)?(?:"|')/
38
+ image['title'] = title
39
+ image['alt'] = alt
40
+ else
41
+ # Set alt text and title from text
42
+ image['alt'].gsub!(/"/, '') if image['alt']
43
+ end
44
+ end
45
+
46
+ image['title'] ||= title
47
+ image['alt'] ||= title
48
+
49
+ image
50
+ end
51
+
52
+ def header
53
+ lines = []
54
+ lines << '\\usepackage{graphicx}'
55
+ lines << '\\usepackage[all]{hypcap}'
56
+ end
57
+ end
58
+ end
59
+ end
60
+
@@ -0,0 +1,21 @@
1
+ module Octopress
2
+ module Printable
3
+ class LatexConverter < Converter
4
+
5
+ def convert(line)
6
+ str = line
7
+ while /{{\s+(?<arg>\S+)\s*\|\s*latex:(?<cmd>\S+)\s*\s*}}/ =~ str
8
+ @match = true
9
+ if ! arg.gsub!(/\A"|"\Z/, '')
10
+ arg.gsub!(/\A'|'\Z/, '')
11
+ end
12
+
13
+ str.sub!(/{{\s+\S+\s*\|\s*latex:\S+\s*}}/, "(\\#{cmd}{#{arg}})")
14
+ end
15
+
16
+ str
17
+ end
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,24 @@
1
+ module Octopress
2
+ module Printable
3
+ class MathConverter < Converter
4
+
5
+ def convert(line)
6
+ str = line.gsub(/\$\$\s*\\begin{equation}/, '\\begin{equation}')
7
+ str.gsub!(/\\end{equation}\s*\$\$/, '\\end{equation}')
8
+
9
+ str.gsub!(/\\\*/, '*')
10
+ str.gsub!(/\\\|/, '|')
11
+ str.gsub!(/\\_/, '_')
12
+
13
+ if !@match
14
+ if str != line
15
+ @match = true
16
+ end
17
+ end
18
+
19
+ str
20
+ end
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,246 @@
1
+ module Octopress
2
+ module Printable
3
+ autoload :Converter, 'octopress-printable/converter'
4
+ autoload :MathConverter, 'octopress-printable/math'
5
+ autoload :ImgConverter, 'octopress-printable/img'
6
+ autoload :BibConverter, 'octopress-printable/bib'
7
+ autoload :GistConverter, 'octopress-printable/gist'
8
+ autoload :PostLinkConverter, 'octopress-printable/post_link'
9
+ autoload :LatexConverter, 'octopress-printable/latex'
10
+
11
+ class Plugin < Ink::Plugin
12
+
13
+ def register
14
+ super
15
+ if Octopress::Ink.enabled?
16
+ self.generate(Octopress.site, config)
17
+ end
18
+ end
19
+
20
+ def generate(site, config)
21
+ @conf = inject_configs
22
+
23
+ posts_dir = @conf['posts_dir']
24
+ printables_dir = @conf['printables_dir']
25
+ source_dir = @conf['source_dir']
26
+ blog_url = @conf['blog_url']
27
+ bib_dir = @conf['bibliography_dir']
28
+ bib = @conf['bibliography']
29
+
30
+ if !File.exists?(printables_dir)
31
+ FileUtils.mkdir_p(printables_dir)
32
+ end
33
+
34
+ site.posts.each do |p|
35
+ post = p.path
36
+ pdf = post.sub(/#{posts_dir}\//, "#{printables_dir}/")
37
+ pdf = pdf.sub(/\.markdown$/, ".pdf")
38
+ pdf = pdf.sub(/\.md$/, ".pdf")
39
+
40
+ if !File.exists?(pdf) || File.stat(post).mtime > File.stat(pdf).mtime
41
+ puts "Converting #{post} to #{pdf}"
42
+ gen_pdf(post, pdf, source_dir, posts_dir, blog_url, bib_dir, bib)
43
+ if File.exists?(pdf)
44
+ site.static_files << Jekyll::StaticFile.new(site,
45
+ site.source, printables_dir, File.basename(pdf))
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def inject_configs
52
+ @conf = self.config
53
+ @conf = Jekyll::Utils.deep_merge_hashes(YAML.load(Plugin.default_config), @conf)
54
+ end
55
+
56
+ def self.default_config
57
+ <<-CONFIG
58
+ posts_dir: "_posts"
59
+ printables_dir: "assets/printables"
60
+ source_dir: "."
61
+ blog_url: "http://example.com" # used in pdf post_links
62
+ bibliography_dir: "_bibliography"
63
+ bibliography: "references.bib"
64
+
65
+ # only convert markdowns, without running pandoc and xelatex
66
+ dry_run : false
67
+
68
+ # debug files
69
+ dump_tex_file: false
70
+ dump_markdown_file: false
71
+ dump_bib_file: false
72
+ dump_cmds: false
73
+ keep_tmp_files: false
74
+
75
+ CONFIG
76
+ end
77
+
78
+ def gen_pdf(mdfile, pdffile, source_dir, posts_dir, blog_url, bib_dir, bib)
79
+ pdfdir = File.dirname(pdffile)
80
+ if ! File.exists?(pdfdir)
81
+ FileUtils.mkdir_p pdfdir
82
+ end
83
+
84
+ converters = []
85
+ math = MathConverter.new
86
+ converters << math
87
+ img = ImgConverter.new(source_dir)
88
+ converters << img
89
+ bib = BibConverter.new("#{source_dir}/#{bib_dir}/#{bib}",
90
+ "#{pdfdir}/#{bib}")
91
+ converters << bib
92
+ gist = GistConverter.new
93
+ converters << gist
94
+ post_link = PostLinkConverter.new(source_dir, posts_dir, blog_url)
95
+ converters << post_link
96
+ latex = LatexConverter.new
97
+ converters << latex
98
+
99
+ tmpfile="#{pdffile}.markdown"
100
+ comment = false
101
+ File.open(tmpfile, 'w') do |post|
102
+ File.open(mdfile, "r") do |file|
103
+ while line = file.gets
104
+ line = line.strip
105
+
106
+ if /^{% comment %}$/ =~ line
107
+ comment = true
108
+ next
109
+ end
110
+
111
+ if /^{% endcomment %}$/ =~ line
112
+ comment = false
113
+ next
114
+ end
115
+
116
+ if comment
117
+ next
118
+ end
119
+
120
+ line = line.gsub(/{% comment %} (.*?) {% endcomment %}/, "")
121
+
122
+ line = line.gsub(/\* list element with functor item/, '')
123
+ line = line.gsub(/{:toc}/, '\tableofcontents')
124
+
125
+ line = line.sub(/^#(#*)/, '\1')
126
+
127
+ for converter in converters
128
+ line = converter.convert(line)
129
+ end
130
+
131
+ post.puts line
132
+ end
133
+ end
134
+ end
135
+
136
+ cts = []
137
+ for converter in converters
138
+ if converter.match
139
+ cts << converter
140
+ end
141
+ end
142
+ converters = cts
143
+
144
+ texfile = pdffile.sub(/.pdf$/, '.tex')
145
+ base = pdffile.sub(/.pdf$/, '')
146
+ pkgfile = "#{pdffile}.header.tex"
147
+
148
+ File.open(pkgfile, "w") { |f|
149
+ for converter in converters
150
+ converter.header.each do |h|
151
+ f.puts h
152
+ end
153
+ end
154
+ }
155
+
156
+ cmds = []
157
+ args = []
158
+ for converter in converters
159
+ args += converter.pandoc_args
160
+ end
161
+
162
+ cmds << "pandoc -s -N #{args.join(" ")} --include-in-header=#{pkgfile} #{tmpfile} -o #{texfile} "
163
+
164
+ (1..2).each do |step|
165
+ args = []
166
+ extra_cmds = []
167
+ for converter in converters
168
+ extra_cmds += converter.before_xelatex(step, texfile)
169
+ end
170
+ for cmd in extra_cmds
171
+ cmds << cmd
172
+ end
173
+
174
+ for converter in converters
175
+ args += converter.xelatex_args(step)
176
+ end
177
+ cmds << "xelatex #{args.join(" ")} -output-directory=#{pdfdir} -no-pdf --interaction=nonstopmode #{base} >/dev/null"
178
+ end
179
+
180
+ extra_cmds = []
181
+ for converter in converters
182
+ extra_cmds += converter.before_xelatex(3, texfile)
183
+ end
184
+ for cmd in extra_cmds
185
+ cmds << cmd
186
+ end
187
+ cmds << "xelatex #{args.join(" ")} -output-directory=#{pdfdir} --interaction=nonstopmode #{base} >/dev/null"
188
+
189
+ extra_cmds = []
190
+ for converter in converters
191
+ extra_cmds += converter.last_xelatex(texfile)
192
+ end
193
+ for cmd in extra_cmds
194
+ cmds << cmd
195
+ end
196
+
197
+ if ! @conf['dry_run']
198
+ for cmd in cmds
199
+ system cmd
200
+ end
201
+ end
202
+
203
+ if @conf['dump_cmds']
204
+ File.open("#{base}.sh", 'w') { |f|
205
+ f.write(cmds.join("\n"))
206
+ }
207
+ FileUtils.chmod(0755, "#{base}.sh")
208
+ end
209
+
210
+ if File.exists?("#{File.basename(base)}.pyg")
211
+ FileUtils.mv("#{File.basename(base)}.pyg", pdfdir)
212
+ end
213
+
214
+ if !@conf['keep_tmp_files']
215
+ FileUtils.rm_f("#{base}.aux")
216
+ FileUtils.rm_f("#{base}.log")
217
+ FileUtils.rm_f("#{base}.lot")
218
+ FileUtils.rm_f("#{base}.out")
219
+ FileUtils.rm_f("#{base}.toc")
220
+ FileUtils.rm_f("#{base}.blg")
221
+ FileUtils.rm_f("#{base}.bbl")
222
+ FileUtils.rm_f("#{base}.lof")
223
+ FileUtils.rm_f("#{base}.xdv")
224
+ FileUtils.rm_f("#{base}.hst")
225
+ FileUtils.rm_f("#{base}.ver")
226
+ FileUtils.rm_f("#{base}.synctex.gz")
227
+ FileUtils.rm_f("#{base}.pyg")
228
+ end
229
+
230
+ if !@conf['dump_tex_file']
231
+ FileUtils.rm_f("#{texfile}")
232
+ FileUtils.rm_f("#{pkgfile}")
233
+ end
234
+
235
+ if !@conf['dump_markdown_file']
236
+ FileUtils.rm_f("#{tmpfile}")
237
+ end
238
+
239
+ if !@conf['dump_bib_file']
240
+ bib.cleanup
241
+ end
242
+ end
243
+
244
+ end
245
+ end
246
+ end
@@ -0,0 +1,38 @@
1
+ module Octopress
2
+ module Printable
3
+ class PostLinkConverter < Converter
4
+
5
+ def initialize(source_dir, posts_dir, blog_url)
6
+ super()
7
+
8
+ @source_dir = source_dir
9
+ @posts_dir = posts_dir
10
+ @blog_url = blog_url
11
+ end
12
+
13
+ def convert(line)
14
+ str = line
15
+
16
+ while /{% post_link (?<markup>[^\s]+)(?<text>\s+.+)? %}/ =~ str
17
+ @match = true
18
+
19
+ /^(?<year>\d+)-(?<month>\d+)-(?<day>\d+)-(?<title>.*)/ =~ markup
20
+
21
+ if ! text
22
+ File.open("#{@source_dir}/#{@posts_dir}/#{markup}.markdown", 'r') do |f|
23
+ while l = f.gets
24
+ if /title: (?:"|')(?<text>.*)(?:"|')/ =~ l
25
+ break
26
+ end
27
+ end
28
+ end
29
+ end
30
+ str = str.sub(/{% post_link (.*?) %}/, "\\href{#{@blog_url}/#{year}/#{month}/#{day}/#{title}/}{#{text}}")
31
+ end
32
+
33
+ str
34
+ end
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,82 @@
1
+ # post_link
2
+ # http://brm.io/jekyll-post-links/
3
+ #
4
+ # usage {% post_link post text %}
5
+ #
6
+ # Where post is a post in the usual date-slug format.
7
+ # If text is specified, it uses that as the anchor text, otherwise it's the post title.
8
+ #
9
+ # Output is a full anchor tag. Broken links will be detected by compiler.
10
+ #
11
+ # based on post_url.rb
12
+ # https://github.com/jekyll/jekyll/blob/master/lib/jekyll/tags/post_url.rb
13
+
14
+ module Octopress
15
+ module Printable
16
+ class PostLinkComparer
17
+ MATCHER = /^(.+\/)*(\d+-\d+-\d+)-([^\s]*)(\s.*)?$/
18
+
19
+ attr_accessor :date, :slug, :text
20
+
21
+ def initialize(name)
22
+ all, path, date, slug, text = *name.sub(/^\//, "").match(MATCHER)
23
+ raise ArgumentError.new("'#{name}' does not contain valid date and/or title") unless all
24
+ @slug = path ? path + slug : slug
25
+ @date = Time.parse(date)
26
+ @text = text
27
+ end
28
+
29
+ def ==(other)
30
+ slug == post_slug(other)
31
+
32
+ # disabled the date check below (used in post_url.rb)
33
+ # otherwise posts with a custom date front-matter will fail if it's different to the slug
34
+
35
+ #&& date.year == other.date.year &&
36
+ #date.month == other.date.month &&
37
+ #date.day == other.date.day
38
+ end
39
+
40
+ private
41
+ def post_slug(other)
42
+ path = other.name.split("/")[0...-1].join("/")
43
+ if path.nil? || path == ""
44
+ other.slug
45
+ else
46
+ path + '/' + other.slug
47
+ end
48
+ end
49
+ end
50
+
51
+ class Tags < Liquid::Tag
52
+ def initialize(tag_name, post, tokens)
53
+ super
54
+ @orig_post = post.strip
55
+ begin
56
+ @post = PostLinkComparer.new(@orig_post)
57
+ rescue
58
+ raise ArgumentError.new <<-eos
59
+ Could not parse name of post "#{@orig_post}" in tag 'post_link'.
60
+ Make sure the post exists and the name and date is correct.
61
+ eos
62
+ end
63
+ end
64
+
65
+ def render(context)
66
+ site = context.registers[:site]
67
+
68
+ site.posts.each do |p|
69
+ if @post == p
70
+ return "<a href=\"#{ p.url }\">#{ @post.text ? @post.text.strip! : p.title }</a>"
71
+ end
72
+ end
73
+
74
+ raise ArgumentError.new <<-eos
75
+ Could not find post "#{@orig_post}" in tag 'post_link'.
76
+ Make sure the post exists and the name and date is correct.
77
+ eos
78
+ end
79
+ end
80
+ end
81
+ end
82
+
@@ -0,0 +1,5 @@
1
+ module Octopress
2
+ module Printable
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,162 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: octopress-printable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Wang Jian
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: clash
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 2.2.2
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 2.2.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: octopress-image-tag
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.1.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.1.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: octopress-ink
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: jekyll-gist
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.2.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.2.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: jekyll-scholar
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 4.3.5
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 4.3.5
111
+ description: Printable version for post generator.
112
+ email:
113
+ - wantee.wang@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - CHANGELOG.md
119
+ - LICENSE.txt
120
+ - README.md
121
+ - assets/config.yml
122
+ - assets/images/printer.png
123
+ - assets/includes/printable.html
124
+ - assets/stylesheets/printable.scss
125
+ - lib/octopress-printable.rb
126
+ - lib/octopress-printable/bib.rb
127
+ - lib/octopress-printable/converter.rb
128
+ - lib/octopress-printable/filters.rb
129
+ - lib/octopress-printable/gist.rb
130
+ - lib/octopress-printable/gist_cache.rb
131
+ - lib/octopress-printable/img.rb
132
+ - lib/octopress-printable/latex.rb
133
+ - lib/octopress-printable/math.rb
134
+ - lib/octopress-printable/plugin.rb
135
+ - lib/octopress-printable/post_link.rb
136
+ - lib/octopress-printable/tags.rb
137
+ - lib/octopress-printable/version.rb
138
+ homepage: https://github.com/wantee/octopress-printable
139
+ licenses:
140
+ - MIT
141
+ metadata: {}
142
+ post_install_message:
143
+ rdoc_options: []
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ requirements: []
157
+ rubyforge_project:
158
+ rubygems_version: 2.4.5
159
+ signing_key:
160
+ specification_version: 4
161
+ summary: Printable version for post generator.
162
+ test_files: []