bridgetown-core 1.0.0.beta2 → 1.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e6a9d2528b695e8e0cf1016e12d9ef4f83ea3983568db4b20e740f5256024990
4
- data.tar.gz: 8cfdc7484ba7f011cac11708667eb93e3fa27400269b7a548fc1cbc80dee37c1
3
+ metadata.gz: 34e42f164cec4d31c4904ed8f35ea1ac8079a60d79ec89fb97946b4e9799e65a
4
+ data.tar.gz: a590bd4e904bbbd89d0fa57541280fc9c01c11bbac5974261940020a4bb9d832
5
5
  SHA512:
6
- metadata.gz: 98523ff2520d3428505ba743408fd20f4672cdfdebdb50fe914b025b7e63e6d661f923cdd6ee0d27c9f8cd126fc08b8b522206461b5e5862b6ddc7b30fcfe02c
7
- data.tar.gz: 795673a2a1e3b44aa0624fbf1c7bb0e9bac35d2f3882dd45d309f70346777896a9ed75c1993f186f2a3adfc94df0d5c69e0beb71a7fbeaea3aa7ac5bf774400f
6
+ metadata.gz: 7a6654c80468f31af2d728bcef3820f1c265e67df5f0e8c92e8d495c4376d309da919d3c31a69b69ac87ad3b9d6849f93ec45e69630f2875e43c5282dbd54d4d
7
+ data.tar.gz: 709855c6285071f112206bf7f2a96f5956abc74f35c8bbf591f2b13f222a6e75e83158d93062f948d34f878ee62048747a6c9337710ebe9f0da2ef4f18db25bd
@@ -10,7 +10,7 @@ class Bridgetown::Site
10
10
  Bridgetown::Hooks.trigger :site, :pre_render, self
11
11
  execute_inline_ruby_for_layouts!
12
12
  render_resources
13
- render_generated_pages
13
+ generated_pages.each(&:transform!)
14
14
  Bridgetown::Hooks.trigger :site, :post_render, self
15
15
  end
16
16
 
@@ -46,6 +46,32 @@ class Bridgetown::Site
46
46
  matches
47
47
  end
48
48
 
49
+ # @return [Array<Bridgetown::Layout>]
50
+ def validated_layouts_for(convertible, layout_name)
51
+ layout = layouts[layout_name]
52
+ warn_on_missing_layout convertible, layout, layout_name
53
+
54
+ layout_list = Set.new([layout])
55
+ while layout
56
+ layout_name = layout.data.layout
57
+ layout = layouts[layout_name]
58
+ warn_on_missing_layout convertible, layout, layout_name
59
+
60
+ layout_list << layout
61
+ end
62
+
63
+ layout_list.to_a.compact
64
+ end
65
+
66
+ def warn_on_missing_layout(convertible, layout, layout_name)
67
+ return unless layout.nil? && layout_name
68
+
69
+ Bridgetown.logger.warn(
70
+ "Build Warning:",
71
+ "Layout '#{layout_name}' requested via #{convertible.relative_path} does not exist."
72
+ )
73
+ end
74
+
49
75
  # Renders all resources
50
76
  # @return [void]
51
77
  def render_resources
@@ -58,14 +84,6 @@ class Bridgetown::Site
58
84
  end
59
85
  end
60
86
 
61
- # Renders all generated pages
62
- # @return [void]
63
- def render_generated_pages
64
- generated_pages.each do |page|
65
- render_page page
66
- end
67
- end
68
-
69
87
  # Renders a content item while ensuring site locale is set if the data is available.
70
88
  # @param item [Document, Page, Bridgetown::Resource::Base] The item to render
71
89
  # @yield Runs the block in between locale setting and resetting
@@ -80,12 +98,5 @@ class Bridgetown::Site
80
98
  yield
81
99
  end
82
100
  end
83
-
84
- # Regenerates a content item using {Renderer}
85
- # @param item [Page] The page to render
86
- # @return [void]
87
- def render_page(page)
88
- Bridgetown::Renderer.new(self, page).run
89
- end
90
101
  end
91
102
  end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bridgetown
4
+ module Transformable
5
+ # Transforms an input document by running it through available converters
6
+ # (requires a `converter` method to be present on the including class)
7
+ #
8
+ # @param document [Bridgetown::GeneratedPage, Bridgetown::Resource::Base]
9
+ # @return String
10
+ # @yieldparam converter [Bridgetown::Converter]
11
+ # @yieldparam index [Integer] index of the conversion step
12
+ # @yieldparam output [String]
13
+ def transform_content(document)
14
+ converters.each_with_index.inject(document.content.to_s) do |content, (converter, index)|
15
+ output = if converter.method(:convert).arity == 1
16
+ converter.convert content
17
+ else
18
+ converter.convert content, document
19
+ end
20
+
21
+ yield converter, index, output if block_given?
22
+
23
+ output.html_safe
24
+ rescue StandardError => e
25
+ Bridgetown.logger.error "Conversion error:",
26
+ "#{converter.class} encountered an error while "\
27
+ "converting `#{document.relative_path}'"
28
+ raise e
29
+ end
30
+ end
31
+
32
+ # Transforms an input document by placing it within the specified layout
33
+ #
34
+ # @param layout [Bridgetown::Layout]
35
+ # @param output [String] the output from document content conversions
36
+ # @param document [Bridgetown::GeneratedPage, Bridgetown::Resource::Base]
37
+ # @return String
38
+ # @yieldparam converter [Bridgetown::Converter]
39
+ # @yieldparam layout_output [String]
40
+ def transform_with_layout(layout, output, document)
41
+ layout_converters = site.matched_converters_for_convertible(layout)
42
+ layout_input = layout.content.dup
43
+
44
+ layout_converters.inject(layout_input) do |content, converter|
45
+ next(content) unless [2, -2].include?(converter.method(:convert).arity) # rubocop:disable Performance/CollectionLiteralInLoop
46
+
47
+ layout.current_document = document
48
+ layout.current_document_output = output
49
+ layout_output = converter.convert content, layout
50
+
51
+ yield converter, layout_output if block_given?
52
+
53
+ layout_output
54
+ rescue StandardError => e
55
+ Bridgetown.logger.error "Conversion error:",
56
+ "#{converter.class} encountered an error while "\
57
+ "converting `#{document.relative_path}'"
58
+ raise e
59
+ end
60
+ end
61
+ end
62
+ end
@@ -5,6 +5,7 @@ module Bridgetown
5
5
  include LayoutPlaceable
6
6
  include LiquidRenderable
7
7
  include Publishable
8
+ include Transformable
8
9
 
9
10
  attr_writer :dir
10
11
  attr_accessor :site, :paginator, :name, :ext, :basename, :data, :content, :output
@@ -12,7 +13,7 @@ module Bridgetown
12
13
  alias_method :extname, :ext
13
14
 
14
15
  # A set of extensions that are considered HTML or HTML-like so we
15
- # should not alter them, this includes .xhtml through XHTM5.
16
+ # should not alter them
16
17
 
17
18
  HTML_EXTENSIONS = %w(
18
19
  .html
@@ -54,11 +55,11 @@ module Bridgetown
54
55
  output || content || ""
55
56
  end
56
57
 
57
- # Accessor for data properties by Liquid.
58
+ # Accessor for data properties by Liquid
58
59
  #
59
- # property - The String name of the property to retrieve.
60
+ # @param property [String] name of the property to retrieve
60
61
  #
61
- # Returns the String value or nil if the property isn't included.
62
+ # @return [Object]
62
63
  def [](property)
63
64
  data[property]
64
65
  end
@@ -67,7 +68,7 @@ module Bridgetown
67
68
  # upon generation. This is derived from the permalink or, if
68
69
  # permalink is absent, will be '/'
69
70
  #
70
- # Returns the String destination directory.
71
+ # @return [String]
71
72
  def dir
72
73
  if url.end_with?("/")
73
74
  url
@@ -78,6 +79,8 @@ module Bridgetown
78
79
  end
79
80
 
80
81
  # Liquid representation of current page
82
+ #
83
+ # @return [Bridgetown::Drops::GeneratedPageDrop]
81
84
  def to_liquid
82
85
  @liquid_drop ||= Drops::GeneratedPageDrop.new(self)
83
86
  end
@@ -90,7 +93,7 @@ module Bridgetown
90
93
 
91
94
  # The template of the permalink.
92
95
  #
93
- # Returns the template String.
96
+ # @return [String]
94
97
  def template
95
98
  if !html?
96
99
  "/:path/:basename:output_ext"
@@ -103,7 +106,7 @@ module Bridgetown
103
106
 
104
107
  # The generated relative url of this page. e.g. /about.html.
105
108
  #
106
- # Returns the String url.
109
+ # @return [String]
107
110
  def url
108
111
  @url ||= URL.new(
109
112
  template: template,
@@ -123,6 +126,22 @@ module Bridgetown
123
126
  }
124
127
  end
125
128
 
129
+ # Layout associated with this resource
130
+ # This will output a warning if the layout can't be found.
131
+ #
132
+ # @return [Bridgetown::Layout]
133
+ def layout
134
+ return @layout if @layout
135
+ return if no_layout?
136
+
137
+ @layout = site.layouts[data.layout].tap do |layout|
138
+ unless layout
139
+ Bridgetown.logger.warn "Generated Page:", "Layout '#{data.layout}' " \
140
+ "requested via #{relative_path} does not exist."
141
+ end
142
+ end
143
+ end
144
+
126
145
  # Overide this in subclasses for custom initialization behavior
127
146
  def process
128
147
  # no-op by default
@@ -139,21 +158,68 @@ module Bridgetown
139
158
  @relative_path ||= File.join(*[@dir, @name].map(&:to_s).reject(&:empty?)).delete_prefix("/")
140
159
  end
141
160
 
142
- # FIXME: spinning up a new Renderer object just to get an extension
143
- # seems excessive
144
- #
145
161
  # The output extension of the page.
146
162
  #
147
- # Returns the output extension
163
+ # @return [String]
148
164
  def output_ext
149
- @output_ext ||= Bridgetown::Renderer.new(site, self).output_ext
165
+ @output_ext ||= (permalink_ext || converter_output_ext)
166
+ end
167
+
168
+ def permalink_ext
169
+ page_permalink = permalink
170
+ if page_permalink &&
171
+ !page_permalink.end_with?("/")
172
+ permalink_ext = File.extname(page_permalink)
173
+ permalink_ext unless permalink_ext.empty?
174
+ end
175
+ end
176
+
177
+ def converter_output_ext
178
+ if output_exts.size == 1
179
+ output_exts.last
180
+ else
181
+ output_exts[-2]
182
+ end
183
+ end
184
+
185
+ def output_exts
186
+ @output_exts ||= converters.filter_map do |c|
187
+ c.output_ext(extname)
188
+ end
189
+ end
190
+
191
+ # @return [Array<Bridgetown::Converter>]
192
+ def converters
193
+ @converters ||= site.matched_converters_for_convertible(self)
194
+ end
195
+
196
+ def transform!
197
+ Bridgetown.logger.debug "Transforming:", relative_path
198
+
199
+ trigger_hooks :pre_render
200
+ self.content = transform_content(self)
201
+ place_in_layout? ? place_into_layouts : self.output = content.dup
202
+ trigger_hooks :post_render
203
+
204
+ self
205
+ end
206
+
207
+ def place_into_layouts
208
+ Bridgetown.logger.debug "Placing in Layouts:", relative_path
209
+ rendered_output = content.dup
210
+
211
+ site.validated_layouts_for(self, data.layout).each do |layout|
212
+ rendered_output = transform_with_layout(layout, rendered_output, self)
213
+ end
214
+
215
+ self.output = rendered_output
150
216
  end
151
217
 
152
218
  # Obtain destination path.
153
219
  #
154
- # dest - The String path to the destination dir.
220
+ # @param dest [String] path to the destination dir
155
221
  #
156
- # Returns the destination file path String.
222
+ # @return [String]
157
223
  def destination(dest)
158
224
  path = site.in_dest_dir(dest, URL.unescape_path(url))
159
225
  path = File.join(path, "index") if url.end_with?("/")
@@ -163,9 +229,7 @@ module Bridgetown
163
229
 
164
230
  # Write the generated page file to the destination directory.
165
231
  #
166
- # dest - The String path to the destination dir.
167
- #
168
- # Returns nothing.
232
+ # @param dest [String] path to the destination dir
169
233
  def write(dest)
170
234
  path = destination(dest)
171
235
  FileUtils.mkdir_p(File.dirname(path))
@@ -3,6 +3,8 @@
3
3
  module Bridgetown
4
4
  module Resource
5
5
  class Transformer
6
+ include Transformable
7
+
6
8
  # @return [Array<Hash>]
7
9
  attr_reader :conversions
8
10
 
@@ -30,10 +32,18 @@ module Bridgetown
30
32
  permalink_ext || output_ext
31
33
  end
32
34
 
33
- def process!
35
+ def process! # rubocop:disable Metrics/AbcSize
34
36
  Bridgetown.logger.debug "Transforming:", resource.relative_path
35
37
  resource.around_hook :render do
36
- run_conversions
38
+ resource.content = transform_content(resource) do |converter, index, output|
39
+ conversions[index] = {
40
+ type: :content,
41
+ converter: converter,
42
+ output: Bridgetown.env.production? ? nil : output,
43
+ output_ext: conversions[index]&.dig(:output_ext) ||
44
+ converter.output_ext(resource.extname),
45
+ }
46
+ end
37
47
  resource.place_in_layout? ? place_into_layouts : resource.output = resource.content.dup
38
48
  end
39
49
  end
@@ -85,95 +95,21 @@ module Bridgetown
85
95
  .fetch(:output_ext)
86
96
  end
87
97
 
88
- # @return [Array<Bridgetown::Layout>]
89
- def validated_layouts
90
- layout = site.layouts[resource.data.layout]
91
- warn_on_missing_layout layout, resource.data.layout
92
-
93
- layout_list = Set.new([layout])
94
- while layout
95
- layout_name = layout.data.layout
96
- layout = site.layouts[layout_name]
97
- warn_on_missing_layout layout, layout_name
98
-
99
- layout_list << layout
100
- end
101
-
102
- layout_list.to_a.compact
103
- end
104
-
105
- def warn_on_missing_layout(layout, layout_name)
106
- return unless layout.nil? && layout_name
107
-
108
- Bridgetown.logger.warn(
109
- "Build Warning:",
110
- "Layout '#{layout_name}' requested via #{resource.relative_path} does not exist."
111
- )
112
- end
113
-
114
- ### Transformation Actions
115
-
116
- def run_conversions # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
117
- input = resource.content.to_s
118
-
119
- # @param content [String]
120
- # @param converter [Bridgetown::Converter]
121
- resource.content = converters.each_with_index.inject(input) do |content, (converter, index)|
122
- output = if converter.method(:convert).arity == 1
123
- converter.convert content
124
- else
125
- converter.convert content, resource
126
- end
127
- conversions[index] = {
128
- type: :content,
129
- converter: converter,
130
- output: Bridgetown.env.production? ? nil : output,
131
- output_ext: conversions[index]&.dig(:output_ext) ||
132
- converter.output_ext(resource.extname),
133
- }
134
- output.html_safe
135
- rescue StandardError => e
136
- Bridgetown.logger.error "Conversion error:",
137
- "#{converter.class} encountered an error while "\
138
- "converting `#{resource.relative_path}'"
139
- raise e
140
- end
141
- end
142
-
143
98
  def place_into_layouts
144
99
  Bridgetown.logger.debug "Placing in Layouts:", resource.relative_path
145
100
  output = resource.content.dup
146
- validated_layouts.each do |layout|
147
- output = run_layout_conversions layout, output
101
+ site.validated_layouts_for(resource, resource.data.layout).each do |layout|
102
+ output = transform_with_layout(layout, output, resource) do |converter, layout_output|
103
+ conversions << {
104
+ type: :layout,
105
+ layout: layout,
106
+ converter: converter,
107
+ output: Bridgetown.env.production? ? nil : layout_output,
108
+ }
109
+ end
148
110
  end
149
111
  resource.output = output
150
112
  end
151
-
152
- def run_layout_conversions(layout, output)
153
- layout_converters = site.matched_converters_for_convertible(layout)
154
- layout_input = layout.content.dup
155
-
156
- layout_converters.inject(layout_input) do |content, converter|
157
- next(content) unless [2, -2].include?(converter.method(:convert).arity) # rubocop:disable Performance/CollectionLiteralInLoop
158
-
159
- layout.current_document = resource
160
- layout.current_document_output = output
161
- layout_output = converter.convert content, layout
162
-
163
- conversions << {
164
- type: :layout,
165
- layout: layout,
166
- converter: converter,
167
- output: Bridgetown.env.production? ? nil : layout_output,
168
- }
169
- layout_output
170
- rescue StandardError => e
171
- Bridgetown.logger.error "Conversion error:",
172
- "#{converter.class} encountered an error while "\
173
- "converting `#{resource.relative_path}'"
174
- raise e
175
- end
176
- end
177
113
  end
178
114
  end
179
115
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bridgetown
4
- VERSION = "1.0.0.beta2"
4
+ VERSION = "1.0.0.beta3"
5
5
  CODE_NAME = "Pearl"
6
6
  end
@@ -92,11 +92,11 @@ module Bridgetown
92
92
  autoload :Publishable, "bridgetown-core/concerns/publishable"
93
93
  autoload :Publisher, "bridgetown-core/publisher"
94
94
  autoload :Reader, "bridgetown-core/reader"
95
- autoload :Renderer, "bridgetown-core/renderer"
96
95
  autoload :RubyTemplateView, "bridgetown-core/ruby_template_view"
97
96
  autoload :LogWriter, "bridgetown-core/log_writer"
98
97
  autoload :Site, "bridgetown-core/site"
99
98
  autoload :StaticFile, "bridgetown-core/static_file"
99
+ autoload :Transformable, "bridgetown-core/concerns/transformable"
100
100
  autoload :URL, "bridgetown-core/url"
101
101
  autoload :Utils, "bridgetown-core/utils"
102
102
  autoload :VERSION, "bridgetown-core/version"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bridgetown-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta2
4
+ version: 1.0.0.beta3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bridgetown Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-26 00:00:00.000000000 Z
11
+ date: 2022-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -418,6 +418,7 @@ files:
418
418
  - lib/bridgetown-core/concerns/site/renderable.rb
419
419
  - lib/bridgetown-core/concerns/site/ssr.rb
420
420
  - lib/bridgetown-core/concerns/site/writable.rb
421
+ - lib/bridgetown-core/concerns/transformable.rb
421
422
  - lib/bridgetown-core/configuration.rb
422
423
  - lib/bridgetown-core/configurations/.keep
423
424
  - lib/bridgetown-core/configurations/bt-postcss.rb
@@ -508,7 +509,6 @@ files:
508
509
  - lib/bridgetown-core/readers/defaults_reader.rb
509
510
  - lib/bridgetown-core/readers/layout_reader.rb
510
511
  - lib/bridgetown-core/readers/plugin_content_reader.rb
511
- - lib/bridgetown-core/renderer.rb
512
512
  - lib/bridgetown-core/resource/base.rb
513
513
  - lib/bridgetown-core/resource/destination.rb
514
514
  - lib/bridgetown-core/resource/permalink_processor.rb
@@ -1,169 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Bridgetown
4
- # This class handles the output rendering and layout placement of pages and
5
- # documents. For rendering of resources in particular, see Bridgetown::Resource::Transformer
6
- class Renderer
7
- attr_reader :document, :site
8
-
9
- def initialize(site, document)
10
- @site = site
11
- @document = document
12
- end
13
-
14
- # Determine which converters to use based on this document's
15
- # extension.
16
- #
17
- # Returns Array of Converter instances.
18
- def converters
19
- @converters ||= site.converters.select do |converter|
20
- if converter.method(:matches).arity == 1
21
- converter.matches(document.extname)
22
- else
23
- converter.matches(document.extname, document)
24
- end
25
- end.sort
26
- end
27
-
28
- # Determine the extname the outputted file should have
29
- #
30
- # Returns String the output extname including the leading period.
31
- def output_ext
32
- @output_ext ||= (permalink_ext || converter_output_ext)
33
- end
34
-
35
- # Run hooks and render the document
36
- #
37
- # Returns nothing
38
- def run
39
- Bridgetown.logger.debug "Rendering:", document.relative_path
40
-
41
- document.trigger_hooks :pre_render
42
- document.output = render_document
43
- document.trigger_hooks :post_render
44
- end
45
-
46
- # Render the document.
47
- #
48
- # Returns String rendered document output
49
- def render_document
50
- execute_inline_ruby!
51
-
52
- output = document.content
53
- Bridgetown.logger.debug "Rendering Markup:", document.relative_path
54
- output = convert(output.to_s, document)
55
- document.content = output.html_safe
56
-
57
- if document.place_in_layout?
58
- Bridgetown.logger.debug "Rendering Layout:", document.relative_path
59
- output = place_in_layouts(output)
60
- end
61
-
62
- output
63
- end
64
-
65
- def execute_inline_ruby!
66
- return unless site.config.should_execute_inline_ruby?
67
-
68
- Bridgetown::Utils::RubyExec.search_data_for_ruby_code(document)
69
- end
70
-
71
- # Convert the document using the converters which match this renderer's document.
72
- #
73
- # Returns String the converted content.
74
- def convert(content, document)
75
- converters.reduce(content) do |output, converter|
76
- if converter.method(:convert).arity == 1
77
- converter.convert output
78
- else
79
- converter.convert output, document
80
- end
81
- rescue StandardError => e
82
- Bridgetown.logger.error "Conversion error:",
83
- "#{converter.class} encountered an error while "\
84
- "converting `#{document.relative_path}'"
85
- raise e
86
- end
87
- end
88
-
89
- # Render layouts and place document content inside.
90
- #
91
- # Returns String rendered content
92
- def place_in_layouts(content)
93
- output = content.dup
94
- layout = site.layouts[document.data["layout"]]
95
- validate_layout(layout)
96
-
97
- used = Set.new([layout])
98
-
99
- while layout
100
- output = render_layout(output, layout)
101
-
102
- next unless (layout = site.layouts[layout.data["layout"]])
103
- break if used.include?(layout)
104
-
105
- used << layout
106
- end
107
- output
108
- end
109
-
110
- private
111
-
112
- # Checks if the layout specified in the document actually exists
113
- #
114
- # layout - the layout to check
115
- # Returns nothing
116
- def validate_layout(layout)
117
- return unless document.data["layout"].present? &&
118
- layout.nil? &&
119
- !(document.is_a? Bridgetown::Excerpt)
120
-
121
- Bridgetown.logger.warn "Build Warning:", "Layout '#{document.data["layout"]}' requested " \
122
- "in #{document.relative_path} does not exist."
123
- end
124
-
125
- # Render layout content into document.output
126
- #
127
- # Returns String rendered content
128
- def render_layout(output, layout)
129
- layout_converters = site.matched_converters_for_convertible(layout)
130
-
131
- layout_content = layout.content.dup
132
- layout_converters.reduce(layout_content) do |layout_output, converter|
133
- next(layout_output) unless converter.method(:convert).arity == 2
134
-
135
- layout.current_document = document
136
- layout.current_document_output = output
137
- converter.convert layout_output, layout
138
- rescue StandardError => e
139
- Bridgetown.logger.error "Conversion error:",
140
- "#{converter.class} encountered an error while "\
141
- "converting `#{document.relative_path}'"
142
- raise e
143
- end
144
- end
145
-
146
- def permalink_ext
147
- document_permalink = document.permalink
148
- if document_permalink &&
149
- !document_permalink.end_with?("/")
150
- permalink_ext = File.extname(document_permalink)
151
- permalink_ext unless permalink_ext.empty?
152
- end
153
- end
154
-
155
- def converter_output_ext
156
- if output_exts.size == 1
157
- output_exts.last
158
- else
159
- output_exts[-2]
160
- end
161
- end
162
-
163
- def output_exts
164
- @output_exts ||= converters.filter_map do |c|
165
- c.output_ext(document.extname)
166
- end
167
- end
168
- end
169
- end