jekyll-printing-press 1.0.0rc1

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
+ SHA256:
3
+ metadata.gz: 4a3b26467e087e03edaf35e1dc1ad9d6308db3cf0863b50e85cd567df62377ab
4
+ data.tar.gz: 6f40f3d1f0ff47d26352d7a22a2aa306caffeab3e2a58124af6b8431f9bbf12c
5
+ SHA512:
6
+ metadata.gz: cf9d1904526652fec66d92ba883d37f767490a68830e5704644167770d4c68317d591a91f38607ce66919717730fbd57d801469ebc20f0409d73ea9de420e459
7
+ data.tar.gz: a6f78d032bcae07dc0e4635ce9f0c0d65c56a7816ee2ebc6dabf30dc5d9cb63d7647f4c8c71fdc2eacd702836f64022fec854ce7259d70ccc5870242a9eb49b8
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2012-2021 fauno <fauno@endefensadelsl.org>
2
+ See CONTRIBUTORS.md
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,222 @@
1
+ # Another pandoc plugin for jekyll
2
+
3
+ This jekyll plugin was inspired by [jekyll-pandoc-plugin][1] but it was changed
4
+ to generate multiple outputs, rather than just using pandoc to generate jekyll
5
+ html posts. Besides, it doesn't require the 'pandoc-ruby' gem.
6
+
7
+ It's used on [En Defensa del Software Libre][0]. Please check [our
8
+ repo](https://github.com/edsl/endefensadelsl.org) if you like to see how
9
+ it works in production.
10
+
11
+ [0]: http://endefensadelsl.org
12
+ [1]: https://github.com/dsanson/jekyll-pandoc-plugin
13
+
14
+
15
+ ## What does it do
16
+
17
+ It replaces the html generation for pandoc. This means you will have
18
+ support for pandoc's markdown extensions, like ~strikethrough~ and
19
+ [@cite], tables and [a lot more stuff](http://pandoc.org/README.html).
20
+
21
+ It'll also generate the post in other formats you like, so your
22
+ blog can be made available in different formats at the same time. Epub
23
+ for ebook readers, mediawiki for copy&paste to wikis, etc.
24
+
25
+ If instructed, this plugin will also generate pdfs in ready for print
26
+ format.
27
+
28
+
29
+ ## Configuration
30
+
31
+ Add to `_config.yml`:
32
+
33
+ ```yaml
34
+
35
+ markdown: pandoc
36
+ pandoc:
37
+ skip:
38
+ full: false
39
+ posts: false
40
+ categories: false
41
+ bundle_permalink: ':output_ext/:slug.:output_ext'
42
+ papersize: 'a5paper'
43
+ sheetsize: 'a4paper'
44
+ imposition: true
45
+ binder: true
46
+ covers_dir: assets/covers
47
+ signature: 20
48
+ full_file: true
49
+
50
+ flags: '--smart'
51
+ site_flags: '--toc'
52
+ outputs:
53
+ latex:
54
+ pdf: '--latex-engine=xelatex'
55
+ epub: '--epub-chapter-level=2'
56
+ lang:
57
+ ar:
58
+ all: '-V mainfont="Amiri"'
59
+ pdf: '--include-in-header=_layouts/rtl.tex'
60
+ ```
61
+
62
+ * `markdown: pandoc` will instruct jekyll to use the pandoc html
63
+ converter.
64
+
65
+ * `skip` allows you to skip the other formats generation and proceed
66
+ with the regular jekyll site build. You can skip some of the
67
+ generation process or all of it. Older versions of this plugin
68
+ required `true` or `false` to skip the process altogether.
69
+
70
+ * `full_flags` if `full_file` is defined, these flags are used on it.
71
+ By default are set to `--top-level-division=part` so each category is
72
+ a different book part.
73
+
74
+ * `site_flags` are flags applied to the html generation
75
+
76
+ * `flags` is a string with the flags you will normally pass to `pandoc` on cli.
77
+ It's used on all output types.
78
+
79
+ * `outputs` is a hash of output formats (even markdown!). You can add
80
+ output-specific flags.
81
+
82
+ * `imposition` creates ready to print PDFs if you're creating PDF
83
+ output.
84
+
85
+ * `binder` creates ready to print PDFs
86
+
87
+ * `bundle_permalink` is the path of the bundled articles
88
+
89
+ * `papersize` is the page size for PDF. You can also use this option on
90
+ the front matter.
91
+
92
+ * `sheetsize` is the page size for ready the print PDF. You can also
93
+ use this option on the front matter.
94
+
95
+ * `covers_dir` the directory where covers are stored. If you have a
96
+ `lang` defined, it will append the language to the `covers_dir` when
97
+ looking for a category/full site cover, so you can have localized
98
+ covers.
99
+
100
+ * `signature` is the amount of pages per fold on the imposition version.
101
+ Specify `0` for a single fold of all the pages. You can also use this
102
+ option on the front matter.
103
+
104
+ * `full_file` generates a single file containing all articles, sectioned
105
+ by their main category (the first one defined if many).
106
+
107
+ * `lang` is a hash where you can define per-language flags. If you have
108
+ a `lang` attribute in your site config, this plugin will add the
109
+ `-V lang=XX` flag and any language-specific flag you want. You can
110
+ define language flags for `all` formats or for specific formats.
111
+
112
+ **IMPORTANT**: As of version 0.1.0 the syntax of the config changed.
113
+ Please upgrade your `_config.yml` accordingly.
114
+
115
+
116
+ ## Front Matter
117
+
118
+ ### Covers
119
+
120
+ Support for epub covers has been added. You can add the path to
121
+ a cover on the front matter of the article to have pandoc add a cover
122
+ image on the epub result.
123
+
124
+ ---
125
+ cover: images/awesome.png
126
+ ---
127
+
128
+ For categories or posts without a cover specified, the plugin looks for
129
+ a PNG file inside the `covers_dir` whose file name will be the
130
+ category/post slug.
131
+
132
+ Since 0.2.0, there's also support for PDF covers. If you have a PNG
133
+ cover, it will get converted to PDF. You can also provide a PDF cover
134
+ as long as it's the same file name as the PNG cover.
135
+
136
+ * Category cover: `assets/covers/the_category_slug.png`
137
+ * PDF cover: `assets/covers/the_slug.pdf`
138
+
139
+ ### Paper sizes
140
+
141
+ For PDFs, each article can have a `papersize` and a `sheetsize`. The
142
+ `papersize` indicates the page size, and the `sheetsize` indicates the
143
+ pages per fold size.
144
+
145
+ Only A* sizes from A7 to A0 are supported for now.
146
+
147
+ ---
148
+ papersize: a5paper
149
+ sheesize: a4paper
150
+ ---
151
+
152
+ This example will generate a 2 pages per A4 sheet.
153
+
154
+ ### Bundled articles
155
+
156
+ If articles share a category, the generator will create a PDF book
157
+ including all of them. The name of the category will become the title
158
+ of the book.
159
+
160
+ ---
161
+ category: [ 'En Defensa del Software Libre #0' ]
162
+ ---
163
+
164
+ The papersize will be the `papersize` of the first article found or the
165
+ default papersize on the `_config.yml` file. Same applies for
166
+ `sheetsize`.
167
+
168
+ NOTE: Authorship will be set to empty. This could change in the future.
169
+
170
+ ## Bibliography
171
+
172
+ If you have bibliography, pandoc recommends leaving an empty
173
+ section at the end of the document if you want to have a separate
174
+ section for it. For bundled articles, this plugin will remove the extra
175
+ sections and create one for everything at the end.
176
+
177
+ # Bibliography
178
+
179
+ <EOF>
180
+
181
+ You can also use the underlined version of the section title (aka
182
+ `settext style` vs `atx style`).
183
+
184
+
185
+ ## Layout
186
+
187
+ Add this liquid snippet on your `_layout/post.html` to generate links to the
188
+ other available formats from the post itself:
189
+
190
+ <ul>
191
+ {% for format in site.pandoc.outputs %}
192
+ {% capture extension %}{{ format | first }}{% endcapture %}
193
+ <li>
194
+ <a href="{{ page.url | remove:'.html' }}.{{ extension }}">
195
+ {{ extension }}
196
+ </a>
197
+ </li>
198
+ {% endfor %}
199
+ </ul>
200
+
201
+ ## How to install
202
+
203
+ Add this snippet to your `_config.yml` on jekyll 1.3
204
+
205
+ gems: [ 'jekyll-pandoc-multiple-formats' ]
206
+
207
+ Alternative, see
208
+ [here](https://github.com/fauno/jekyll-pandoc-multiple-formats/issues/7).
209
+
210
+
211
+ ## How to run
212
+
213
+ Execute `jekyll build` normally :D
214
+
215
+ ## Tectonic
216
+
217
+ If you want to use Tectonic, make sure it's installed into
218
+ `/usr/bin/tectonic` (or symlink it). It will be used instead of rtex
219
+ for imposition and adding covers.
220
+
221
+ It's specially useful if you're using unicode characters in your file
222
+ names.
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll/pandoc/paru_helper'
4
+ require 'jekyll/pandoc/utils'
5
+
6
+ module Jekyll
7
+ module Converters
8
+ class Markdown
9
+ # Converts markdown content using Pandoc.
10
+ #
11
+ # A previous iteration of this converter monkeypatched Jekyll (10
12
+ # years ago!). Now we just use the method Jekyll provides which
13
+ # also provides caching.
14
+ #
15
+ # @see Jekyll::Converters::Markdown
16
+ # @see Jekyll::Converters::Markdown::KramdownParser
17
+ class Pandoc
18
+ # @return [Jekyll::Configuration]
19
+ attr_reader :config
20
+
21
+ # @param config [Jekyll::Configuration]
22
+ def initialize(config)
23
+ @config = config
24
+ end
25
+
26
+ # Convert the content into HTML
27
+ #
28
+ # @param content [String] Markdown
29
+ # @return [String] HTML
30
+ def convert(content)
31
+ parser << content
32
+ end
33
+
34
+ private
35
+
36
+ # Generates a parser from config
37
+ #
38
+ # @return [Paru::Pandoc]
39
+ def parser
40
+ @parser ||= Jekyll::Pandoc::ParuHelper.from(from: 'markdown+smart', to: 'html5',
41
+ metadata: 'title=Jekyll',
42
+ **config['pandoc'].options[:html5])
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll/utils'
4
+
5
+ module Jekyll
6
+ module Pandoc
7
+ # Processes Pandoc configuration by merging common, per format and
8
+ # current locale options.
9
+ #
10
+ # There's no default configuration.
11
+ class Configuration
12
+ extend Forwardable
13
+
14
+ SPECIAL_OPTIONS = %w[common locales].freeze
15
+
16
+ # Jekyll site
17
+ #
18
+ # @return [Jekyll::Site]
19
+ attr_reader :site
20
+
21
+ # Processed options
22
+ #
23
+ # @return [Hash]
24
+ attr_reader :options
25
+
26
+ # Delegate key accessors to config
27
+ def_delegators :config, :[], :dig
28
+
29
+ # @param site [Jekyll::Site]
30
+ def initialize(site)
31
+ @site = site
32
+ @options = {}
33
+ end
34
+
35
+ # Configuration from site
36
+ #
37
+ # @return [Hash]
38
+ def config
39
+ @config ||= site.config['pandoc'] || {}
40
+ end
41
+
42
+ # Current locale. If you're using jekyll-locales, the site will
43
+ # be built once per locale, so the locale will be configured.
44
+ #
45
+ # @return [String,nil]
46
+ def current_locale
47
+ @current_locale ||= site.config['lang'] || site.config['locale']
48
+ end
49
+
50
+ # Available formats
51
+ #
52
+ # @return [Array]
53
+ def available_formats
54
+ @available_formats ||= ((config['options']&.keys || []) - SPECIAL_OPTIONS).map(&:to_sym).freeze
55
+ end
56
+
57
+ # Find PDF papersize
58
+ #
59
+ # @return [Symbol]
60
+ def papersize
61
+ @papersize ||= options.dig(:pdf, :variable).find do |v|
62
+ v.start_with? 'papersize='
63
+ end&.split('=', 2)&.last&.to_sym
64
+ end
65
+
66
+ # Merge all options and remove the ones disabled
67
+ #
68
+ # TODO: Process common first so it's not done for every format.
69
+ #
70
+ # @return [nil]
71
+ def process
72
+ return unless options.empty?
73
+
74
+ available_formats.each do |format|
75
+ options[format] =
76
+ paru_options(disable_options(reduce_options(format.to_s)))
77
+ end
78
+
79
+ nil
80
+ end
81
+
82
+ private
83
+
84
+ # @param format [String]
85
+ # @return [Hash]
86
+ def reduce_options(format)
87
+ [
88
+ config.dig('options', 'common'),
89
+ config.dig('options', 'locales', current_locale, 'common'),
90
+ config.dig('options', format),
91
+ config.dig('options', 'locales', current_locale)
92
+ ].compact.reduce do |config, next_config|
93
+ next_config = {} if next_config == true
94
+
95
+ Jekyll::Utils.deep_merge_hashes(config, next_config)
96
+ end
97
+ end
98
+
99
+ # Removes options with non truthy values
100
+ #
101
+ # @param options [Hash,nil]
102
+ # @return [Hash,nil]
103
+ def disable_options(options)
104
+ options&.select do |_, v|
105
+ v
106
+ end
107
+ end
108
+
109
+ # Convert options to Paru methods
110
+ #
111
+ # @param options [Hash,nil]
112
+ # @return [Hash,nil]
113
+ def paru_options(options)
114
+ options&.transform_keys do |k|
115
+ k.gsub('-', '_').to_sym
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,202 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tempfile'
4
+ require 'jekyll/document'
5
+ require_relative 'renderer'
6
+
7
+ module Jekyll
8
+ module Pandoc
9
+ # Represents a single document. Extends Jekyll::Document since it's
10
+ # the most complete class for managing documents. Either
11
+ # Convertible or Page are too constrained and would require to
12
+ # rewrite a lot of code.
13
+ class Document < Jekyll::Document
14
+ # Binary formats are treated specially because Pandoc writes them
15
+ # to disk, unless we were to use - as output file and read
16
+ # everything into memory.
17
+ #
18
+ # @return [Array]
19
+ BINARY_FORMATS = %i[pdf epub epub3 fb2 docx odt].freeze
20
+
21
+ # Site
22
+ #
23
+ # @return [Jekyll::Site]
24
+ attr_reader :site
25
+
26
+ # Collection
27
+ #
28
+ # @return [Jekyll::Collection]
29
+ attr_reader :collection
30
+
31
+ # Source document
32
+ #
33
+ # @return [Jekyll::Document]
34
+ attr_reader :source_document
35
+
36
+ # Content
37
+ #
38
+ # @return [String]
39
+ attr_accessor :content
40
+
41
+ # Output. Empty string if the file is in binary format
42
+ #
43
+ # @return [String]
44
+ attr_accessor :output
45
+
46
+ # @param path [String]
47
+ # @param relations [Hash]
48
+ def initialize(path, relations = {})
49
+ @source_document = relations[:source_document]
50
+ super
51
+ end
52
+
53
+ # Remove collection directory too so Jekyll doesn't confuse it
54
+ # with a category
55
+ #
56
+ # @return [String]
57
+ def relative_path
58
+ @relative_path ||= super.sub(source_document.collection.relative_directory, '')
59
+ end
60
+
61
+ # Temporary file where Pandoc writes binary formats
62
+ #
63
+ # @return [Tempfile]
64
+ def tempfile
65
+ @tempfile ||= Tempfile.new([data['slug'], output_ext])
66
+ end
67
+
68
+ # The path where the renderer wrote the actual contents for binary
69
+ # files.
70
+ #
71
+ # @return [String]
72
+ def rendered_path
73
+ tempfile.path
74
+ end
75
+
76
+ # Clone data from the source document
77
+ #
78
+ # @return [Hash]
79
+ def data
80
+ @data ||= source_document.data.dup
81
+ end
82
+
83
+ # Do nothing
84
+ def merge_defaults; end
85
+
86
+ # Duplicate the content
87
+ #
88
+ # @return [nil]
89
+ def read_content(**)
90
+ self.content = source_document.content.dup
91
+
92
+ nil
93
+ end
94
+
95
+ # "Read" data and adds itself to the source document data.
96
+ #
97
+ # @return [nil]
98
+ def read_post_data
99
+ # Assign a new UUIDv4 if the source document has one.
100
+ #
101
+ # TODO: How to assign the same UUID to every document?
102
+ if data.key? 'uuid'
103
+ require 'securerandom'
104
+ data['uuid'] = SecureRandom.uuid
105
+ end
106
+
107
+ data['binary'] = binary?
108
+
109
+ source_document.data['formats'] ||= []
110
+ source_document.data['formats'] << self
111
+ # Can't guarantee the front matter won't use the same key
112
+ source_document.data[collection.label] ||= self
113
+
114
+ nil
115
+ end
116
+
117
+ # The renderer will know how to convert this document to the
118
+ # needed format.
119
+ #
120
+ # @return [Jekyll::Pandoc::Renderer]
121
+ def renderer
122
+ @renderer ||= Renderer.new(site, self)
123
+ end
124
+
125
+ # If the format is binary, we need to copy the tempfile to the
126
+ # destination.
127
+ #
128
+ # @return [nil]
129
+ def write(dest)
130
+ super
131
+
132
+ return unless binary?
133
+
134
+ path = destination(dest)
135
+
136
+ FileUtils.rm path
137
+ FileUtils.cp rendered_path, path
138
+
139
+ nil
140
+ end
141
+
142
+ # Detect if the format is binary. The type is set from the
143
+ # collection label, which in turn is the Pandoc-supported format.
144
+ #
145
+ # @return [Boolean]
146
+ def binary?
147
+ BINARY_FORMATS.include? type
148
+ end
149
+
150
+ # Generate the destination from the URL and change .html to the
151
+ # output extension.
152
+ #
153
+ # @return [String]
154
+ def destination(dest)
155
+ super.sub(/\.html\z/, output_ext)
156
+ end
157
+
158
+ def url
159
+ @url ||= super.tap do |u|
160
+ u << data['slug'] << output_ext if u.end_with? '/'
161
+ end
162
+ end
163
+
164
+ # We don't have layouts (yet?)
165
+ #
166
+ # @return [FalseClass]
167
+ def place_in_layout?
168
+ false
169
+ end
170
+
171
+ # It's not an asset...
172
+ #
173
+ # @return [FalseClass]
174
+ def asset_file?
175
+ false
176
+ end
177
+
178
+ # Nor a SASS file...
179
+ #
180
+ # @return [FalseClass]
181
+ def sass_file?
182
+ false
183
+ end
184
+
185
+ # Or a CoffeeScript file...
186
+ #
187
+ # @return [FalseClass]
188
+ def coffeescript_file?
189
+ false
190
+ end
191
+
192
+ # No need to generate an excerpt either.
193
+ #
194
+ # @return [FalseClass]
195
+ def generate_excerpt?
196
+ false
197
+ end
198
+
199
+ def generate_excerpt; end
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../document'
4
+ require_relative '../renderers/binder'
5
+
6
+ module Jekyll
7
+ module Pandoc
8
+ module Documents
9
+ # A bound document is printed, cut and bound with pegament (or
10
+ # sewn, etc.)
11
+ class Bound < Jekyll::Pandoc::Document
12
+ def read_content(**)
13
+ self.content = ''
14
+ nil
15
+ end
16
+
17
+ # Adds relations to source documents
18
+ #
19
+ # @return [nil]
20
+ def read_post_data
21
+ if data.key? 'uuid'
22
+ require 'securerandom'
23
+ data['uuid'] = SecureRandom.uuid
24
+ end
25
+
26
+ source_document.source_document.data['bound'] =
27
+ source_document.data['bound'] = self
28
+
29
+ source_document.source_document.data['formats'] ||= []
30
+ source_document.source_document.data['formats'] << self
31
+
32
+ nil
33
+ end
34
+
35
+ # Binding
36
+ #
37
+ # @return [Jekyll::Pandoc::Renderers::Binder]
38
+ def renderer
39
+ @renderer ||= Jekyll::Pandoc::Renderers::Binder.new(site, self)
40
+ end
41
+
42
+ # The file is always binary
43
+ #
44
+ # @return [TrueClass]
45
+ def binary?
46
+ true
47
+ end
48
+
49
+ # PDFs can't be rendered with Liquid
50
+ #
51
+ # @return [FalseClass]
52
+ def render_with_liquid?
53
+ false
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end