jekyll 4.0.1 → 4.2.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.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +350 -163
  3. data/LICENSE +21 -21
  4. data/README.markdown +86 -90
  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 -103
  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 -173
  18. data/lib/jekyll/commands/help.rb +34 -34
  19. data/lib/jekyll/commands/new.rb +169 -169
  20. data/lib/jekyll/commands/new_theme.rb +40 -42
  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 -354
  26. data/lib/jekyll/configuration.rb +313 -316
  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 -130
  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 -254
  33. data/lib/jekyll/deprecator.rb +50 -50
  34. data/lib/jekyll/document.rb +544 -522
  35. data/lib/jekyll/drops/collection_drop.rb +20 -20
  36. data/lib/jekyll/drops/document_drop.rb +70 -69
  37. data/lib/jekyll/drops/drop.rb +293 -215
  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 -132
  44. data/lib/jekyll/entry_filter.rb +121 -110
  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 -68
  51. data/lib/jekyll/filters.rb +535 -454
  52. data/lib/jekyll/frontmatter_defaults.rb +240 -245
  53. data/lib/jekyll/generator.rb +5 -5
  54. data/lib/jekyll/hooks.rb +107 -106
  55. data/lib/jekyll/inclusion.rb +32 -0
  56. data/lib/jekyll/layout.rb +67 -62
  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 -75
  60. data/lib/jekyll/liquid_renderer.rb +80 -77
  61. data/lib/jekyll/log_adapter.rb +151 -151
  62. data/lib/jekyll/mime.types +866 -866
  63. data/lib/jekyll/page.rb +217 -186
  64. data/lib/jekyll/page_excerpt.rb +25 -0
  65. data/lib/jekyll/page_without_a_file.rb +14 -14
  66. data/lib/jekyll/path_manager.rb +74 -31
  67. data/lib/jekyll/plugin.rb +92 -92
  68. data/lib/jekyll/plugin_manager.rb +115 -115
  69. data/lib/jekyll/profiler.rb +58 -0
  70. data/lib/jekyll/publisher.rb +23 -23
  71. data/lib/jekyll/reader.rb +192 -187
  72. data/lib/jekyll/readers/collection_reader.rb +23 -22
  73. data/lib/jekyll/readers/data_reader.rb +79 -75
  74. data/lib/jekyll/readers/layout_reader.rb +62 -61
  75. data/lib/jekyll/readers/page_reader.rb +25 -24
  76. data/lib/jekyll/readers/post_reader.rb +85 -84
  77. data/lib/jekyll/readers/static_file_reader.rb +25 -24
  78. data/lib/jekyll/readers/theme_assets_reader.rb +52 -51
  79. data/lib/jekyll/regenerator.rb +195 -195
  80. data/lib/jekyll/related_posts.rb +52 -52
  81. data/lib/jekyll/renderer.rb +265 -267
  82. data/lib/jekyll/site.rb +551 -527
  83. data/lib/jekyll/static_file.rb +208 -203
  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 -221
  87. data/lib/jekyll/tags/link.rb +42 -41
  88. data/lib/jekyll/tags/post_url.rb +106 -107
  89. data/lib/jekyll/theme.rb +86 -80
  90. data/lib/jekyll/theme_builder.rb +121 -121
  91. data/lib/jekyll/url.rb +167 -164
  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 -82
  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 -206
  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 -19
  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 +20 -38
@@ -1,267 +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) }.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 AbcSize
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
- if document.place_in_layout?
88
- Jekyll.logger.debug "Rendering Layout:", document.relative_path
89
- output = place_in_layouts(output, payload, info)
90
- end
91
-
92
- output
93
- end
94
- # rubocop: enable AbcSize
95
-
96
- # Convert the document using the converters which match this renderer's document.
97
- #
98
- # Returns String the converted content.
99
- def convert(content)
100
- converters.reduce(content) do |output, converter|
101
- begin
102
- converter.convert output
103
- rescue StandardError => e
104
- Jekyll.logger.error "Conversion error:",
105
- "#{converter.class} encountered an error while "\
106
- "converting '#{document.relative_path}':"
107
- Jekyll.logger.error("", e.to_s)
108
- raise e
109
- end
110
- end
111
- end
112
-
113
- # Render the given content with the payload and info
114
- #
115
- # content -
116
- # payload -
117
- # info -
118
- # path - (optional) the path to the file, for use in ex
119
- #
120
- # Returns String the content, rendered by Liquid.
121
- def render_liquid(content, payload, info, path = nil)
122
- template = site.liquid_renderer.file(path).parse(content)
123
- template.warnings.each do |e|
124
- Jekyll.logger.warn "Liquid Warning:",
125
- LiquidRenderer.format_error(e, path || document.relative_path)
126
- end
127
- template.render!(payload, info)
128
- # rubocop: disable RescueException
129
- rescue Exception => e
130
- Jekyll.logger.error "Liquid Exception:",
131
- LiquidRenderer.format_error(e, path || document.relative_path)
132
- raise e
133
- end
134
- # rubocop: enable RescueException
135
-
136
- # Checks if the layout specified in the document actually exists
137
- #
138
- # layout - the layout to check
139
- #
140
- # Returns Boolean true if the layout is invalid, false if otherwise
141
- def invalid_layout?(layout)
142
- !document.data["layout"].nil? && layout.nil? && !(document.is_a? Jekyll::Excerpt)
143
- end
144
-
145
- # Render layouts and place document content inside.
146
- #
147
- # Returns String rendered content
148
- def place_in_layouts(content, payload, info)
149
- output = content.dup
150
- layout = layouts[document.data["layout"].to_s]
151
- validate_layout(layout)
152
-
153
- used = Set.new([layout])
154
-
155
- # Reset the payload layout data to ensure it starts fresh for each page.
156
- payload["layout"] = nil
157
-
158
- while layout
159
- output = render_layout(output, layout, info)
160
- add_regenerator_dependencies(layout)
161
-
162
- next unless (layout = site.layouts[layout.data["layout"]])
163
- break if used.include?(layout)
164
-
165
- used << layout
166
- end
167
- output
168
- end
169
-
170
- private
171
-
172
- # Checks if the layout specified in the document actually exists
173
- #
174
- # layout - the layout to check
175
- # Returns nothing
176
- def validate_layout(layout)
177
- if invalid_layout?(layout)
178
- Jekyll.logger.warn(
179
- "Build Warning:",
180
- "Layout '#{document.data["layout"]}' requested "\
181
- "in #{document.relative_path} does not exist."
182
- )
183
- elsif !layout.nil?
184
- layout_source = layout.path.start_with?(site.source) ? :site : :theme
185
- Jekyll.logger.debug "Layout source:", layout_source
186
- end
187
- end
188
-
189
- # Render layout content into document.output
190
- #
191
- # Returns String rendered content
192
- def render_layout(output, layout, info)
193
- payload["content"] = output
194
- payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
195
-
196
- render_liquid(
197
- layout.content,
198
- payload,
199
- info,
200
- layout.relative_path
201
- )
202
- end
203
-
204
- def add_regenerator_dependencies(layout)
205
- return unless document.write?
206
-
207
- site.regenerator.add_dependency(
208
- site.in_source_dir(document.path),
209
- layout.path
210
- )
211
- end
212
-
213
- # Set page content to payload and assign pager if document has one.
214
- #
215
- # Returns nothing
216
- def assign_pages!
217
- payload["page"] = document.to_liquid
218
- payload["paginator"] = (document.pager.to_liquid if document.respond_to?(:pager))
219
- end
220
-
221
- # Set related posts to payload if document is a post.
222
- #
223
- # Returns nothing
224
- def assign_current_document!
225
- payload["site"].current_document = document
226
- end
227
-
228
- # Set highlighter prefix and suffix
229
- #
230
- # Returns nothing
231
- def assign_highlighter_options!
232
- payload["highlighter_prefix"] = converters.first.highlighter_prefix
233
- payload["highlighter_suffix"] = converters.first.highlighter_suffix
234
- end
235
-
236
- def assign_layout_data!
237
- layout = layouts[document.data["layout"]]
238
- payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {}) if layout
239
- end
240
-
241
- def permalink_ext
242
- document_permalink = document.permalink
243
- if document_permalink && !document_permalink.end_with?("/")
244
- permalink_ext = File.extname(document_permalink)
245
- permalink_ext unless permalink_ext.empty?
246
- end
247
- end
248
-
249
- def converter_output_ext
250
- if output_exts.size == 1
251
- output_exts.last
252
- else
253
- output_exts[-2]
254
- end
255
- end
256
-
257
- def output_exts
258
- @output_exts ||= converters.map do |c|
259
- c.output_ext(document.extname)
260
- end.compact
261
- end
262
-
263
- def liquid_options
264
- @liquid_options ||= site.config["liquid"]
265
- end
266
- end
267
- 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