jekyll 4.2.1 → 4.2.2

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.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +350 -350
  3. data/LICENSE +21 -21
  4. data/README.markdown +86 -86
  5. data/exe/jekyll +57 -57
  6. data/lib/blank_template/_config.yml +3 -3
  7. data/lib/blank_template/_layouts/default.html +12 -12
  8. data/lib/blank_template/_sass/main.scss +9 -9
  9. data/lib/blank_template/assets/css/main.scss +4 -4
  10. data/lib/blank_template/index.md +8 -8
  11. data/lib/jekyll/cache.rb +190 -190
  12. data/lib/jekyll/cleaner.rb +111 -111
  13. data/lib/jekyll/collection.rb +309 -309
  14. data/lib/jekyll/command.rb +105 -105
  15. data/lib/jekyll/commands/build.rb +93 -93
  16. data/lib/jekyll/commands/clean.rb +45 -45
  17. data/lib/jekyll/commands/doctor.rb +177 -177
  18. data/lib/jekyll/commands/help.rb +34 -34
  19. data/lib/jekyll/commands/new.rb +172 -169
  20. data/lib/jekyll/commands/new_theme.rb +40 -40
  21. data/lib/jekyll/commands/serve/live_reload_reactor.rb +122 -122
  22. data/lib/jekyll/commands/serve/livereload_assets/livereload.js +1183 -1183
  23. data/lib/jekyll/commands/serve/servlet.rb +202 -202
  24. data/lib/jekyll/commands/serve/websockets.rb +81 -81
  25. data/lib/jekyll/commands/serve.rb +362 -362
  26. data/lib/jekyll/configuration.rb +313 -313
  27. data/lib/jekyll/converter.rb +54 -54
  28. data/lib/jekyll/converters/identity.rb +41 -41
  29. data/lib/jekyll/converters/markdown/kramdown_parser.rb +199 -199
  30. data/lib/jekyll/converters/markdown.rb +113 -113
  31. data/lib/jekyll/converters/smartypants.rb +70 -70
  32. data/lib/jekyll/convertible.rb +257 -257
  33. data/lib/jekyll/deprecator.rb +50 -50
  34. data/lib/jekyll/document.rb +544 -544
  35. data/lib/jekyll/drops/collection_drop.rb +20 -20
  36. data/lib/jekyll/drops/document_drop.rb +70 -70
  37. data/lib/jekyll/drops/drop.rb +293 -293
  38. data/lib/jekyll/drops/excerpt_drop.rb +19 -19
  39. data/lib/jekyll/drops/jekyll_drop.rb +32 -32
  40. data/lib/jekyll/drops/site_drop.rb +66 -66
  41. data/lib/jekyll/drops/static_file_drop.rb +14 -14
  42. data/lib/jekyll/drops/unified_payload_drop.rb +26 -26
  43. data/lib/jekyll/drops/url_drop.rb +140 -140
  44. data/lib/jekyll/entry_filter.rb +121 -121
  45. data/lib/jekyll/errors.rb +20 -20
  46. data/lib/jekyll/excerpt.rb +201 -201
  47. data/lib/jekyll/external.rb +79 -79
  48. data/lib/jekyll/filters/date_filters.rb +110 -110
  49. data/lib/jekyll/filters/grouping_filters.rb +64 -64
  50. data/lib/jekyll/filters/url_filters.rb +98 -98
  51. data/lib/jekyll/filters.rb +535 -535
  52. data/lib/jekyll/frontmatter_defaults.rb +240 -240
  53. data/lib/jekyll/generator.rb +5 -5
  54. data/lib/jekyll/hooks.rb +107 -107
  55. data/lib/jekyll/inclusion.rb +32 -32
  56. data/lib/jekyll/layout.rb +67 -67
  57. data/lib/jekyll/liquid_extensions.rb +22 -22
  58. data/lib/jekyll/liquid_renderer/file.rb +77 -77
  59. data/lib/jekyll/liquid_renderer/table.rb +55 -55
  60. data/lib/jekyll/liquid_renderer.rb +80 -80
  61. data/lib/jekyll/log_adapter.rb +151 -151
  62. data/lib/jekyll/mime.types +866 -866
  63. data/lib/jekyll/page.rb +217 -217
  64. data/lib/jekyll/page_excerpt.rb +25 -25
  65. data/lib/jekyll/page_without_a_file.rb +14 -14
  66. data/lib/jekyll/path_manager.rb +74 -74
  67. data/lib/jekyll/plugin.rb +92 -92
  68. data/lib/jekyll/plugin_manager.rb +115 -115
  69. data/lib/jekyll/profiler.rb +58 -58
  70. data/lib/jekyll/publisher.rb +23 -23
  71. data/lib/jekyll/reader.rb +192 -192
  72. data/lib/jekyll/readers/collection_reader.rb +23 -23
  73. data/lib/jekyll/readers/data_reader.rb +79 -79
  74. data/lib/jekyll/readers/layout_reader.rb +62 -62
  75. data/lib/jekyll/readers/page_reader.rb +25 -25
  76. data/lib/jekyll/readers/post_reader.rb +85 -85
  77. data/lib/jekyll/readers/static_file_reader.rb +25 -25
  78. data/lib/jekyll/readers/theme_assets_reader.rb +52 -52
  79. data/lib/jekyll/regenerator.rb +195 -195
  80. data/lib/jekyll/related_posts.rb +52 -52
  81. data/lib/jekyll/renderer.rb +265 -265
  82. data/lib/jekyll/site.rb +551 -551
  83. data/lib/jekyll/static_file.rb +208 -208
  84. data/lib/jekyll/stevenson.rb +60 -60
  85. data/lib/jekyll/tags/highlight.rb +110 -110
  86. data/lib/jekyll/tags/include.rb +275 -275
  87. data/lib/jekyll/tags/link.rb +42 -42
  88. data/lib/jekyll/tags/post_url.rb +106 -106
  89. data/lib/jekyll/theme.rb +86 -86
  90. data/lib/jekyll/theme_builder.rb +121 -121
  91. data/lib/jekyll/url.rb +167 -167
  92. data/lib/jekyll/utils/ansi.rb +57 -57
  93. data/lib/jekyll/utils/exec.rb +26 -26
  94. data/lib/jekyll/utils/internet.rb +37 -37
  95. data/lib/jekyll/utils/platforms.rb +67 -67
  96. data/lib/jekyll/utils/thread_event.rb +31 -31
  97. data/lib/jekyll/utils/win_tz.rb +75 -75
  98. data/lib/jekyll/utils.rb +367 -367
  99. data/lib/jekyll/version.rb +5 -5
  100. data/lib/jekyll.rb +195 -195
  101. data/lib/site_template/.gitignore +5 -5
  102. data/lib/site_template/404.html +25 -25
  103. data/lib/site_template/_config.yml +55 -55
  104. data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +29 -29
  105. data/lib/site_template/about.markdown +18 -18
  106. data/lib/site_template/index.markdown +6 -6
  107. data/lib/theme_template/CODE_OF_CONDUCT.md.erb +74 -74
  108. data/lib/theme_template/Gemfile +4 -4
  109. data/lib/theme_template/LICENSE.txt.erb +21 -21
  110. data/lib/theme_template/README.md.erb +52 -52
  111. data/lib/theme_template/_layouts/default.html +1 -1
  112. data/lib/theme_template/_layouts/page.html +5 -5
  113. data/lib/theme_template/_layouts/post.html +5 -5
  114. data/lib/theme_template/example/_config.yml.erb +1 -1
  115. data/lib/theme_template/example/_post.md +12 -12
  116. data/lib/theme_template/example/index.html +14 -14
  117. data/lib/theme_template/example/style.scss +7 -7
  118. data/lib/theme_template/gitignore.erb +6 -6
  119. data/lib/theme_template/theme.gemspec.erb +16 -16
  120. data/rubocop/jekyll/assert_equal_literal_actual.rb +149 -149
  121. data/rubocop/jekyll/no_p_allowed.rb +23 -23
  122. data/rubocop/jekyll/no_puts_allowed.rb +23 -23
  123. data/rubocop/jekyll.rb +5 -5
  124. metadata +3 -3
@@ -1,265 +1,265 @@
1
- # frozen_string_literal: true
2
-
3
- module Jekyll
4
- class Renderer
5
- attr_reader :document, :site
6
- attr_writer :layouts, :payload
7
-
8
- def initialize(site, document, site_payload = nil)
9
- @site = site
10
- @document = document
11
- @payload = site_payload
12
- @layouts = nil
13
- end
14
-
15
- # Fetches the payload used in Liquid rendering.
16
- # It can be written with #payload=(new_payload)
17
- # Falls back to site.site_payload if no payload is set.
18
- #
19
- # Returns a Jekyll::Drops::UnifiedPayloadDrop
20
- def payload
21
- @payload ||= site.site_payload
22
- end
23
-
24
- # The list of layouts registered for this Renderer.
25
- # It can be written with #layouts=(new_layouts)
26
- # Falls back to site.layouts if no layouts are registered.
27
- #
28
- # Returns a Hash of String => Jekyll::Layout identified
29
- # as basename without the extension name.
30
- def layouts
31
- @layouts || site.layouts
32
- end
33
-
34
- # Determine which converters to use based on this document's
35
- # extension.
36
- #
37
- # Returns Array of Converter instances.
38
- def converters
39
- @converters ||= site.converters.select { |c| c.matches(document.extname) }.tap(&:sort!)
40
- end
41
-
42
- # Determine the extname the outputted file should have
43
- #
44
- # Returns String the output extname including the leading period.
45
- def output_ext
46
- @output_ext ||= (permalink_ext || converter_output_ext)
47
- end
48
-
49
- # Prepare payload and render the document
50
- #
51
- # Returns String rendered document output
52
- def run
53
- Jekyll.logger.debug "Rendering:", document.relative_path
54
-
55
- assign_pages!
56
- assign_current_document!
57
- assign_highlighter_options!
58
- assign_layout_data!
59
-
60
- Jekyll.logger.debug "Pre-Render Hooks:", document.relative_path
61
- document.trigger_hooks(:pre_render, payload)
62
-
63
- render_document
64
- end
65
-
66
- # Render the document.
67
- #
68
- # Returns String rendered document output
69
- # rubocop: disable Metrics/AbcSize, Metrics/MethodLength
70
- def render_document
71
- info = {
72
- :registers => { :site => site, :page => payload["page"] },
73
- :strict_filters => liquid_options["strict_filters"],
74
- :strict_variables => liquid_options["strict_variables"],
75
- }
76
-
77
- output = document.content
78
- if document.render_with_liquid?
79
- Jekyll.logger.debug "Rendering Liquid:", document.relative_path
80
- output = render_liquid(output, payload, info, document.path)
81
- end
82
-
83
- Jekyll.logger.debug "Rendering Markup:", document.relative_path
84
- output = convert(output.to_s)
85
- document.content = output
86
-
87
- Jekyll.logger.debug "Post-Convert Hooks:", document.relative_path
88
- document.trigger_hooks(:post_convert)
89
- output = document.content
90
-
91
- if document.place_in_layout?
92
- Jekyll.logger.debug "Rendering Layout:", document.relative_path
93
- output = place_in_layouts(output, payload, info)
94
- end
95
-
96
- output
97
- end
98
- # rubocop: enable Metrics/AbcSize, Metrics/MethodLength
99
-
100
- # Convert the document using the converters which match this renderer's document.
101
- #
102
- # Returns String the converted content.
103
- def convert(content)
104
- converters.reduce(content) do |output, converter|
105
- begin
106
- converter.convert output
107
- rescue StandardError => e
108
- Jekyll.logger.error "Conversion error:",
109
- "#{converter.class} encountered an error while "\
110
- "converting '#{document.relative_path}':"
111
- Jekyll.logger.error("", e.to_s)
112
- raise e
113
- end
114
- end
115
- end
116
-
117
- # Render the given content with the payload and info
118
- #
119
- # content -
120
- # payload -
121
- # info -
122
- # path - (optional) the path to the file, for use in ex
123
- #
124
- # Returns String the content, rendered by Liquid.
125
- def render_liquid(content, payload, info, path = nil)
126
- template = site.liquid_renderer.file(path).parse(content)
127
- template.warnings.each do |e|
128
- Jekyll.logger.warn "Liquid Warning:",
129
- LiquidRenderer.format_error(e, path || document.relative_path)
130
- end
131
- template.render!(payload, info)
132
- # rubocop: disable Lint/RescueException
133
- rescue Exception => e
134
- Jekyll.logger.error "Liquid Exception:",
135
- LiquidRenderer.format_error(e, path || document.relative_path)
136
- raise e
137
- end
138
- # rubocop: enable Lint/RescueException
139
-
140
- # Checks if the layout specified in the document actually exists
141
- #
142
- # layout - the layout to check
143
- #
144
- # Returns Boolean true if the layout is invalid, false if otherwise
145
- def invalid_layout?(layout)
146
- !document.data["layout"].nil? && layout.nil? && !(document.is_a? Jekyll::Excerpt)
147
- end
148
-
149
- # Render layouts and place document content inside.
150
- #
151
- # Returns String rendered content
152
- def place_in_layouts(content, payload, info)
153
- output = content.dup
154
- layout = layouts[document.data["layout"].to_s]
155
- validate_layout(layout)
156
-
157
- used = Set.new([layout])
158
-
159
- # Reset the payload layout data to ensure it starts fresh for each page.
160
- payload["layout"] = nil
161
-
162
- while layout
163
- output = render_layout(output, layout, info)
164
- add_regenerator_dependencies(layout)
165
-
166
- next unless (layout = site.layouts[layout.data["layout"]])
167
- break if used.include?(layout)
168
-
169
- used << layout
170
- end
171
- output
172
- end
173
-
174
- private
175
-
176
- # Checks if the layout specified in the document actually exists
177
- #
178
- # layout - the layout to check
179
- # Returns nothing
180
- def validate_layout(layout)
181
- return unless invalid_layout?(layout)
182
-
183
- Jekyll.logger.warn "Build Warning:", "Layout '#{document.data["layout"]}' requested " \
184
- "in #{document.relative_path} does not exist."
185
- end
186
-
187
- # Render layout content into document.output
188
- #
189
- # Returns String rendered content
190
- def render_layout(output, layout, info)
191
- payload["content"] = output
192
- payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
193
-
194
- render_liquid(
195
- layout.content,
196
- payload,
197
- info,
198
- layout.path
199
- )
200
- end
201
-
202
- def add_regenerator_dependencies(layout)
203
- return unless document.write?
204
-
205
- site.regenerator.add_dependency(
206
- site.in_source_dir(document.path),
207
- layout.path
208
- )
209
- end
210
-
211
- # Set page content to payload and assign pager if document has one.
212
- #
213
- # Returns nothing
214
- def assign_pages!
215
- payload["page"] = document.to_liquid
216
- payload["paginator"] = (document.pager.to_liquid if document.respond_to?(:pager))
217
- end
218
-
219
- # Set related posts to payload if document is a post.
220
- #
221
- # Returns nothing
222
- def assign_current_document!
223
- payload["site"].current_document = document
224
- end
225
-
226
- # Set highlighter prefix and suffix
227
- #
228
- # Returns nothing
229
- def assign_highlighter_options!
230
- payload["highlighter_prefix"] = converters.first.highlighter_prefix
231
- payload["highlighter_suffix"] = converters.first.highlighter_suffix
232
- end
233
-
234
- def assign_layout_data!
235
- layout = layouts[document.data["layout"]]
236
- payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {}) if layout
237
- end
238
-
239
- def permalink_ext
240
- document_permalink = document.permalink
241
- if document_permalink && !document_permalink.end_with?("/")
242
- permalink_ext = File.extname(document_permalink)
243
- permalink_ext unless permalink_ext.empty?
244
- end
245
- end
246
-
247
- def converter_output_ext
248
- if output_exts.size == 1
249
- output_exts.last
250
- else
251
- output_exts[-2]
252
- end
253
- end
254
-
255
- def output_exts
256
- @output_exts ||= converters.map do |c|
257
- c.output_ext(document.extname)
258
- end.tap(&:compact!)
259
- end
260
-
261
- def liquid_options
262
- @liquid_options ||= site.config["liquid"]
263
- end
264
- end
265
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class Renderer
5
+ attr_reader :document, :site
6
+ attr_writer :layouts, :payload
7
+
8
+ def initialize(site, document, site_payload = nil)
9
+ @site = site
10
+ @document = document
11
+ @payload = site_payload
12
+ @layouts = nil
13
+ end
14
+
15
+ # Fetches the payload used in Liquid rendering.
16
+ # It can be written with #payload=(new_payload)
17
+ # Falls back to site.site_payload if no payload is set.
18
+ #
19
+ # Returns a Jekyll::Drops::UnifiedPayloadDrop
20
+ def payload
21
+ @payload ||= site.site_payload
22
+ end
23
+
24
+ # The list of layouts registered for this Renderer.
25
+ # It can be written with #layouts=(new_layouts)
26
+ # Falls back to site.layouts if no layouts are registered.
27
+ #
28
+ # Returns a Hash of String => Jekyll::Layout identified
29
+ # as basename without the extension name.
30
+ def layouts
31
+ @layouts || site.layouts
32
+ end
33
+
34
+ # Determine which converters to use based on this document's
35
+ # extension.
36
+ #
37
+ # Returns Array of Converter instances.
38
+ def converters
39
+ @converters ||= site.converters.select { |c| c.matches(document.extname) }.tap(&:sort!)
40
+ end
41
+
42
+ # Determine the extname the outputted file should have
43
+ #
44
+ # Returns String the output extname including the leading period.
45
+ def output_ext
46
+ @output_ext ||= (permalink_ext || converter_output_ext)
47
+ end
48
+
49
+ # Prepare payload and render the document
50
+ #
51
+ # Returns String rendered document output
52
+ def run
53
+ Jekyll.logger.debug "Rendering:", document.relative_path
54
+
55
+ assign_pages!
56
+ assign_current_document!
57
+ assign_highlighter_options!
58
+ assign_layout_data!
59
+
60
+ Jekyll.logger.debug "Pre-Render Hooks:", document.relative_path
61
+ document.trigger_hooks(:pre_render, payload)
62
+
63
+ render_document
64
+ end
65
+
66
+ # Render the document.
67
+ #
68
+ # Returns String rendered document output
69
+ # rubocop: disable Metrics/AbcSize, Metrics/MethodLength
70
+ def render_document
71
+ info = {
72
+ :registers => { :site => site, :page => payload["page"] },
73
+ :strict_filters => liquid_options["strict_filters"],
74
+ :strict_variables => liquid_options["strict_variables"],
75
+ }
76
+
77
+ output = document.content
78
+ if document.render_with_liquid?
79
+ Jekyll.logger.debug "Rendering Liquid:", document.relative_path
80
+ output = render_liquid(output, payload, info, document.path)
81
+ end
82
+
83
+ Jekyll.logger.debug "Rendering Markup:", document.relative_path
84
+ output = convert(output.to_s)
85
+ document.content = output
86
+
87
+ Jekyll.logger.debug "Post-Convert Hooks:", document.relative_path
88
+ document.trigger_hooks(:post_convert)
89
+ output = document.content
90
+
91
+ if document.place_in_layout?
92
+ Jekyll.logger.debug "Rendering Layout:", document.relative_path
93
+ output = place_in_layouts(output, payload, info)
94
+ end
95
+
96
+ output
97
+ end
98
+ # rubocop: enable Metrics/AbcSize, Metrics/MethodLength
99
+
100
+ # Convert the document using the converters which match this renderer's document.
101
+ #
102
+ # Returns String the converted content.
103
+ def convert(content)
104
+ converters.reduce(content) do |output, converter|
105
+ begin
106
+ converter.convert output
107
+ rescue StandardError => e
108
+ Jekyll.logger.error "Conversion error:",
109
+ "#{converter.class} encountered an error while "\
110
+ "converting '#{document.relative_path}':"
111
+ Jekyll.logger.error("", e.to_s)
112
+ raise e
113
+ end
114
+ end
115
+ end
116
+
117
+ # Render the given content with the payload and info
118
+ #
119
+ # content -
120
+ # payload -
121
+ # info -
122
+ # path - (optional) the path to the file, for use in ex
123
+ #
124
+ # Returns String the content, rendered by Liquid.
125
+ def render_liquid(content, payload, info, path = nil)
126
+ template = site.liquid_renderer.file(path).parse(content)
127
+ template.warnings.each do |e|
128
+ Jekyll.logger.warn "Liquid Warning:",
129
+ LiquidRenderer.format_error(e, path || document.relative_path)
130
+ end
131
+ template.render!(payload, info)
132
+ # rubocop: disable Lint/RescueException
133
+ rescue Exception => e
134
+ Jekyll.logger.error "Liquid Exception:",
135
+ LiquidRenderer.format_error(e, path || document.relative_path)
136
+ raise e
137
+ end
138
+ # rubocop: enable Lint/RescueException
139
+
140
+ # Checks if the layout specified in the document actually exists
141
+ #
142
+ # layout - the layout to check
143
+ #
144
+ # Returns Boolean true if the layout is invalid, false if otherwise
145
+ def invalid_layout?(layout)
146
+ !document.data["layout"].nil? && layout.nil? && !(document.is_a? Jekyll::Excerpt)
147
+ end
148
+
149
+ # Render layouts and place document content inside.
150
+ #
151
+ # Returns String rendered content
152
+ def place_in_layouts(content, payload, info)
153
+ output = content.dup
154
+ layout = layouts[document.data["layout"].to_s]
155
+ validate_layout(layout)
156
+
157
+ used = Set.new([layout])
158
+
159
+ # Reset the payload layout data to ensure it starts fresh for each page.
160
+ payload["layout"] = nil
161
+
162
+ while layout
163
+ output = render_layout(output, layout, info)
164
+ add_regenerator_dependencies(layout)
165
+
166
+ next unless (layout = site.layouts[layout.data["layout"]])
167
+ break if used.include?(layout)
168
+
169
+ used << layout
170
+ end
171
+ output
172
+ end
173
+
174
+ private
175
+
176
+ # Checks if the layout specified in the document actually exists
177
+ #
178
+ # layout - the layout to check
179
+ # Returns nothing
180
+ def validate_layout(layout)
181
+ return unless invalid_layout?(layout)
182
+
183
+ Jekyll.logger.warn "Build Warning:", "Layout '#{document.data["layout"]}' requested " \
184
+ "in #{document.relative_path} does not exist."
185
+ end
186
+
187
+ # Render layout content into document.output
188
+ #
189
+ # Returns String rendered content
190
+ def render_layout(output, layout, info)
191
+ payload["content"] = output
192
+ payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
193
+
194
+ render_liquid(
195
+ layout.content,
196
+ payload,
197
+ info,
198
+ layout.path
199
+ )
200
+ end
201
+
202
+ def add_regenerator_dependencies(layout)
203
+ return unless document.write?
204
+
205
+ site.regenerator.add_dependency(
206
+ site.in_source_dir(document.path),
207
+ layout.path
208
+ )
209
+ end
210
+
211
+ # Set page content to payload and assign pager if document has one.
212
+ #
213
+ # Returns nothing
214
+ def assign_pages!
215
+ payload["page"] = document.to_liquid
216
+ payload["paginator"] = (document.pager.to_liquid if document.respond_to?(:pager))
217
+ end
218
+
219
+ # Set related posts to payload if document is a post.
220
+ #
221
+ # Returns nothing
222
+ def assign_current_document!
223
+ payload["site"].current_document = document
224
+ end
225
+
226
+ # Set highlighter prefix and suffix
227
+ #
228
+ # Returns nothing
229
+ def assign_highlighter_options!
230
+ payload["highlighter_prefix"] = converters.first.highlighter_prefix
231
+ payload["highlighter_suffix"] = converters.first.highlighter_suffix
232
+ end
233
+
234
+ def assign_layout_data!
235
+ layout = layouts[document.data["layout"]]
236
+ payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {}) if layout
237
+ end
238
+
239
+ def permalink_ext
240
+ document_permalink = document.permalink
241
+ if document_permalink && !document_permalink.end_with?("/")
242
+ permalink_ext = File.extname(document_permalink)
243
+ permalink_ext unless permalink_ext.empty?
244
+ end
245
+ end
246
+
247
+ def converter_output_ext
248
+ if output_exts.size == 1
249
+ output_exts.last
250
+ else
251
+ output_exts[-2]
252
+ end
253
+ end
254
+
255
+ def output_exts
256
+ @output_exts ||= converters.map do |c|
257
+ c.output_ext(document.extname)
258
+ end.tap(&:compact!)
259
+ end
260
+
261
+ def liquid_options
262
+ @liquid_options ||= site.config["liquid"]
263
+ end
264
+ end
265
+ end