tilt 2.0.10 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +5 -5
  2. data/COPYING +1 -0
  3. data/bin/tilt +2 -120
  4. data/lib/tilt/_emacs_org.rb +2 -0
  5. data/lib/tilt/_handlebars.rb +2 -0
  6. data/lib/tilt/_jbuilder.rb +2 -0
  7. data/lib/tilt/_org.rb +2 -0
  8. data/lib/tilt/asciidoc.rb +11 -23
  9. data/lib/tilt/babel.rb +5 -13
  10. data/lib/tilt/builder.rb +18 -13
  11. data/lib/tilt/cli.rb +134 -0
  12. data/lib/tilt/coffee.rb +12 -31
  13. data/lib/tilt/commonmarker.rb +82 -65
  14. data/lib/tilt/creole.rb +9 -20
  15. data/lib/tilt/csv.rb +6 -18
  16. data/lib/tilt/erb.rb +23 -21
  17. data/lib/tilt/erubi.rb +29 -6
  18. data/lib/tilt/erubis.rb +19 -11
  19. data/lib/tilt/etanni.rb +5 -4
  20. data/lib/tilt/haml.rb +73 -65
  21. data/lib/tilt/kramdown.rb +8 -20
  22. data/lib/tilt/liquid.rb +10 -14
  23. data/lib/tilt/livescript.rb +8 -20
  24. data/lib/tilt/mapping.rb +228 -109
  25. data/lib/tilt/markaby.rb +5 -7
  26. data/lib/tilt/maruku.rb +6 -18
  27. data/lib/tilt/nokogiri.rb +11 -10
  28. data/lib/tilt/pandoc.rb +33 -43
  29. data/lib/tilt/pipeline.rb +19 -0
  30. data/lib/tilt/plain.rb +4 -15
  31. data/lib/tilt/prawn.rb +10 -25
  32. data/lib/tilt/radius.rb +15 -22
  33. data/lib/tilt/rdiscount.rb +17 -33
  34. data/lib/tilt/rdoc.rb +14 -35
  35. data/lib/tilt/redcarpet.rb +20 -72
  36. data/lib/tilt/redcloth.rb +9 -19
  37. data/lib/tilt/rst-pandoc.rb +7 -15
  38. data/lib/tilt/sass.rb +54 -28
  39. data/lib/tilt/slim.rb +5 -0
  40. data/lib/tilt/string.rb +9 -3
  41. data/lib/tilt/template.rb +235 -77
  42. data/lib/tilt/typescript.rb +11 -18
  43. data/lib/tilt/wikicloth.rb +8 -18
  44. data/lib/tilt/yajl.rb +5 -11
  45. data/lib/tilt.rb +60 -39
  46. metadata +24 -16
  47. data/lib/tilt/bluecloth.rb +0 -24
  48. data/lib/tilt/dummy.rb +0 -3
  49. data/lib/tilt/less.rb +0 -30
  50. data/lib/tilt/sigil.rb +0 -34
data/lib/tilt/mapping.rb CHANGED
@@ -1,6 +1,81 @@
1
- require 'monitor'
1
+ # frozen_string_literal: true
2
+ require_relative 'pipeline'
2
3
 
3
4
  module Tilt
5
+ # Private internal base class for both Mapping and FinalizedMapping, for the shared methods.
6
+ class BaseMapping
7
+ # Instantiates a new template class based on the file.
8
+ #
9
+ # @raise [RuntimeError] if there is no template class registered for the
10
+ # file name.
11
+ #
12
+ # @example
13
+ # mapping.new('index.mt') # => instance of MyEngine::Template
14
+ #
15
+ # @see Tilt::Template.new
16
+ def new(file, line=nil, options={}, &block)
17
+ if template_class = self[file]
18
+ template_class.new(file, line, options, &block)
19
+ else
20
+ fail "No template engine registered for #{File.basename(file)}"
21
+ end
22
+ end
23
+
24
+ # Looks up a template class based on file name and/or extension.
25
+ #
26
+ # @example
27
+ # mapping['views/hello.erb'] # => Tilt::ERBTemplate
28
+ # mapping['hello.erb'] # => Tilt::ERBTemplate
29
+ # mapping['erb'] # => Tilt::ERBTemplate
30
+ #
31
+ # @return [template class]
32
+ def [](file)
33
+ _, ext = split(file)
34
+ ext && lookup(ext)
35
+ end
36
+
37
+ alias template_for []
38
+
39
+ # Looks up a list of template classes based on file name. If the file name
40
+ # has multiple extensions, it will return all template classes matching the
41
+ # extensions from the end.
42
+ #
43
+ # @example
44
+ # mapping.templates_for('views/index.haml.erb')
45
+ # # => [Tilt::ERBTemplate, Tilt::HamlTemplate]
46
+ #
47
+ # @return [Array<template class>]
48
+ def templates_for(file)
49
+ templates = []
50
+
51
+ while true
52
+ prefix, ext = split(file)
53
+ break unless ext
54
+ templates << lookup(ext)
55
+ file = prefix
56
+ end
57
+
58
+ templates
59
+ end
60
+
61
+ private
62
+
63
+ def split(file)
64
+ pattern = file.to_s.downcase
65
+ full_pattern = pattern.dup
66
+
67
+ until registered?(pattern)
68
+ return if pattern.empty?
69
+ pattern = File.basename(pattern)
70
+ pattern.sub!(/\A[^.]*\.?/, '')
71
+ end
72
+
73
+ prefix_size = full_pattern.size - pattern.size
74
+ [full_pattern[0,prefix_size-1], pattern]
75
+ end
76
+ end
77
+ private_constant :BaseMapping
78
+
4
79
  # Tilt::Mapping associates file extensions with template implementations.
5
80
  #
6
81
  # mapping = Tilt::Mapping.new
@@ -38,16 +113,18 @@ module Tilt
38
113
  # the exception of the first, since that was the most preferred one.
39
114
  #
40
115
  # mapping = Tilt::Mapping.new
41
- # mapping.register_lazy('Bluecloth::Template', 'bluecloth/template', 'md')
116
+ # mapping.register_lazy('Maruku::Template', 'maruku/template', 'md')
42
117
  # mapping.register_lazy('RDiscount::Template', 'rdiscount/template', 'md')
43
118
  # mapping['index.md']
44
119
  # # => RDiscount::Template
45
120
  #
46
121
  # In the previous example we say that RDiscount has a *higher priority* than
47
- # BlueCloth. Tilt will first try to `require "rdiscount/template"`, falling
48
- # back to `require "bluecloth/template"`. If none of these are successful,
122
+ # Maruku. Tilt will first try to `require "rdiscount/template"`, falling
123
+ # back to `require "maruku/template"`. If none of these are successful,
49
124
  # the first error will be raised.
50
- class Mapping
125
+ class Mapping < BaseMapping
126
+ LOCK = Mutex.new
127
+
51
128
  # @private
52
129
  attr_reader :lazy_map, :template_map
53
130
 
@@ -58,8 +135,26 @@ module Tilt
58
135
 
59
136
  # @private
60
137
  def initialize_copy(other)
61
- @template_map = other.template_map.dup
62
- @lazy_map = other.lazy_map.dup
138
+ LOCK.synchronize do
139
+ @template_map = other.template_map.dup
140
+ @lazy_map = other.lazy_map.dup
141
+ end
142
+ end
143
+
144
+ # Return a finalized mapping. A finalized mapping will only include
145
+ # support for template libraries already loaded, and will not
146
+ # allow registering new template libraries or lazy loading template
147
+ # libraries not yet loaded. Finalized mappings improve performance
148
+ # by not requiring synchronization and ensure that the mapping will
149
+ # not attempt to load additional files (useful when restricting
150
+ # file system access after template libraries in use are loaded).
151
+ def finalized
152
+ LOCK.synchronize{@lazy_map.dup}.each do |pattern, classes|
153
+ register_defined_classes(LOCK.synchronize{classes.map(&:first)}, pattern)
154
+ end
155
+
156
+ # Check if a template class is already present
157
+ FinalizedMapping.new(LOCK.synchronize{@template_map.dup}.freeze)
63
158
  end
64
159
 
65
160
  # Registers a lazy template implementation by file extension. You
@@ -85,8 +180,9 @@ module Tilt
85
180
  class_name = "Tilt::#{class_name}"
86
181
  end
87
182
 
183
+ v = [class_name, file].freeze
88
184
  extensions.each do |ext|
89
- @lazy_map[ext].unshift([class_name, file])
185
+ LOCK.synchronize{@lazy_map[ext].unshift(v)}
90
186
  end
91
187
  end
92
188
 
@@ -108,86 +204,95 @@ module Tilt
108
204
  end
109
205
 
110
206
  extensions.each do |ext|
111
- @template_map[ext.to_s] = template_class
207
+ ext = ext.to_s
208
+ LOCK.synchronize do
209
+ @template_map[ext] = template_class
210
+ end
112
211
  end
113
212
  end
114
213
 
115
- # Checks if a file extension is registered (either eagerly or
116
- # lazily) in this mapping.
214
+ # Register a new template class using the given extension that
215
+ # represents a pipeline of multiple existing template, where the
216
+ # output from the previous template is used as input to the next
217
+ # template.
117
218
  #
118
- # @param ext [String] File extension.
219
+ # This will register a template class that processes the input
220
+ # with the *erb* template processor, and takes the output of
221
+ # that and feeds it to the *scss* template processor, returning
222
+ # the output of the *scss* template processor as the result of
223
+ # the pipeline.
224
+ #
225
+ # @param ext [String] Primary extension to register
226
+ # @option :templates [Array<String>] Extensions of templates
227
+ # to execute in order (defaults to the ext.split('.').reverse)
228
+ # @option :extra_exts [Array<String>] Additional extensions to register
229
+ # @option String [Hash] Options hash for individual template in the
230
+ # pipeline (key is extension).
231
+ # @return [void]
119
232
  #
120
233
  # @example
121
- # mapping.registered?('erb') # => true
122
- # mapping.registered?('nope') # => false
123
- def registered?(ext)
124
- @template_map.has_key?(ext.downcase) or lazy?(ext)
234
+ # mapping.register_pipeline('scss.erb')
235
+ # mapping.register_pipeline('scss.erb', 'erb'=>{:outvar=>'@foo'})
236
+ # mapping.register_pipeline('scsserb', :extra_exts => 'scss.erb',
237
+ # :templates=>['erb', 'scss'])
238
+ def register_pipeline(ext, options=EMPTY_HASH)
239
+ templates = options[:templates] || ext.split('.').reverse
240
+ templates = templates.map{|t| [self[t], options[t] || EMPTY_HASH]}
241
+
242
+ klass = Class.new(Pipeline)
243
+ klass.send(:const_set, :TEMPLATES, templates)
244
+
245
+ register(klass, ext, *Array(options[:extra_exts]))
246
+ klass
125
247
  end
126
248
 
127
- # Instantiates a new template class based on the file.
249
+ # Unregisters an extension. This removes the both normal registrations
250
+ # and lazy registrations.
128
251
  #
129
- # @raise [RuntimeError] if there is no template class registered for the
130
- # file name.
252
+ # @param extensions [Array<String>] List of extensions.
253
+ # @return nil
131
254
  #
132
255
  # @example
133
- # mapping.new('index.mt') # => instance of MyEngine::Template
134
- #
135
- # @see Tilt::Template.new
136
- def new(file, line=nil, options={}, &block)
137
- if template_class = self[file]
138
- template_class.new(file, line, options, &block)
139
- else
140
- fail "No template engine registered for #{File.basename(file)}"
256
+ # mapping.register MyEngine::Template, 'mt'
257
+ # mapping['index.mt'] # => MyEngine::Template
258
+ # mapping.unregister('mt')
259
+ # mapping['index.mt'] # => nil
260
+ def unregister(*extensions)
261
+ extensions.each do |ext|
262
+ ext = ext.to_s
263
+ LOCK.synchronize do
264
+ @template_map.delete(ext)
265
+ @lazy_map.delete(ext)
266
+ end
141
267
  end
142
- end
143
268
 
144
- # Looks up a template class based on file name and/or extension.
145
- #
146
- # @example
147
- # mapping['views/hello.erb'] # => Tilt::ERBTemplate
148
- # mapping['hello.erb'] # => Tilt::ERBTemplate
149
- # mapping['erb'] # => Tilt::ERBTemplate
150
- #
151
- # @return [template class]
152
- def [](file)
153
- _, ext = split(file)
154
- ext && lookup(ext)
269
+ nil
155
270
  end
156
271
 
157
- alias template_for []
158
-
159
- # Looks up a list of template classes based on file name. If the file name
160
- # has multiple extensions, it will return all template classes matching the
161
- # extensions from the end.
272
+ # Checks if a file extension is registered (either eagerly or
273
+ # lazily) in this mapping.
162
274
  #
163
- # @example
164
- # mapping.templates_for('views/index.haml.erb')
165
- # # => [Tilt::ERBTemplate, Tilt::HamlTemplate]
275
+ # @param ext [String] File extension.
166
276
  #
167
- # @return [Array<template class>]
168
- def templates_for(file)
169
- templates = []
170
-
171
- while true
172
- prefix, ext = split(file)
173
- break unless ext
174
- templates << lookup(ext)
175
- file = prefix
176
- end
177
-
178
- templates
277
+ # @example
278
+ # mapping.registered?('erb') # => true
279
+ # mapping.registered?('nope') # => false
280
+ def registered?(ext)
281
+ ext_downcase = ext.downcase
282
+ LOCK.synchronize{@template_map.has_key?(ext_downcase)} or lazy?(ext)
179
283
  end
180
284
 
181
285
  # Finds the extensions the template class has been registered under.
182
286
  # @param [template class] template_class
183
287
  def extensions_for(template_class)
184
288
  res = []
185
- template_map.each do |ext, klass|
289
+ LOCK.synchronize{@template_map.to_a}.each do |ext, klass|
186
290
  res << ext if template_class == klass
187
291
  end
188
- lazy_map.each do |ext, choices|
189
- res << ext if choices.any? { |klass, file| template_class.to_s == klass }
292
+ LOCK.synchronize{@lazy_map.to_a}.each do |ext, choices|
293
+ res << ext if LOCK.synchronize{choices.dup}.any? { |klass, file| template_class.to_s == klass }
190
294
  end
295
+ res.uniq!
191
296
  res
192
297
  end
193
298
 
@@ -195,45 +300,30 @@ module Tilt
195
300
 
196
301
  def lazy?(ext)
197
302
  ext = ext.downcase
198
- @lazy_map.has_key?(ext) && !@lazy_map[ext].empty?
199
- end
200
-
201
- def split(file)
202
- pattern = file.to_s.downcase
203
- full_pattern = pattern.dup
204
-
205
- until registered?(pattern)
206
- return if pattern.empty?
207
- pattern = File.basename(pattern)
208
- pattern.sub!(/^[^.]*\.?/, '')
209
- end
210
-
211
- prefix_size = full_pattern.size - pattern.size
212
- [full_pattern[0,prefix_size-1], pattern]
303
+ LOCK.synchronize{@lazy_map.has_key?(ext) && !@lazy_map[ext].empty?}
213
304
  end
214
305
 
215
306
  def lookup(ext)
216
- @template_map[ext] || lazy_load(ext)
307
+ LOCK.synchronize{@template_map[ext]} || lazy_load(ext)
217
308
  end
218
309
 
219
- LOCK = Monitor.new
220
-
221
- def lazy_load(pattern)
222
- return unless @lazy_map.has_key?(pattern)
223
-
224
- LOCK.enter
225
- entered = true
226
-
227
- choices = @lazy_map[pattern]
228
-
229
- # Check if a template class is already present
230
- choices.each do |class_name, file|
310
+ def register_defined_classes(class_names, pattern)
311
+ class_names.each do |class_name|
231
312
  template_class = constant_defined?(class_name)
232
313
  if template_class
233
314
  register(template_class, pattern)
234
- return template_class
315
+ yield template_class if block_given?
235
316
  end
236
317
  end
318
+ end
319
+
320
+ def lazy_load(pattern)
321
+ choices = LOCK.synchronize{@lazy_map[pattern].dup}
322
+
323
+ # Check if a template class is already present
324
+ register_defined_classes(choices.map(&:first), pattern) do |template_class|
325
+ return template_class
326
+ end
237
327
 
238
328
  first_failure = nil
239
329
 
@@ -252,16 +342,9 @@ module Tilt
252
342
  end
253
343
  end
254
344
 
255
- raise first_failure if first_failure
256
- ensure
257
- LOCK.exit if entered
345
+ raise first_failure
258
346
  end
259
347
 
260
- # This is due to a bug in JRuby (see GH issue jruby/jruby#3585)
261
- Tilt.autoload :Dummy, "tilt/dummy"
262
- require "tilt/dummy"
263
- AUTOLOAD_IS_BROKEN = Tilt.autoload?(:Dummy)
264
-
265
348
  # The proper behavior (in MRI) for autoload? is to
266
349
  # return `false` when the constant/file has been
267
350
  # explicitly required.
@@ -276,18 +359,54 @@ module Tilt
276
359
 
277
360
  def constant_defined?(name)
278
361
  name.split('::').inject(Object) do |scope, n|
279
- if scope.autoload?(n)
280
- if !AUTOLOAD_IS_BROKEN
281
- return false
282
- end
283
-
284
- if eval("!defined?(scope::#{n})")
285
- return false
286
- end
287
- end
288
- return false if !scope.const_defined?(n)
362
+ return false if scope.autoload?(n) || !scope.const_defined?(n)
289
363
  scope.const_get(n)
290
364
  end
291
365
  end
292
366
  end
367
+
368
+ # Private internal class for finalized mappings, which are frozen and
369
+ # cannot be modified.
370
+ class FinalizedMapping < BaseMapping
371
+ # Set the template map to use. The template map should already
372
+ # be frozen, but this is an internal class, so it does not
373
+ # explicitly check for that.
374
+ def initialize(template_map)
375
+ @template_map = template_map
376
+ freeze
377
+ end
378
+
379
+ # Returns receiver, since instances are always frozen.
380
+ def dup
381
+ self
382
+ end
383
+
384
+ # Returns receiver, since instances are always frozen.
385
+ def clone(freeze: false)
386
+ self
387
+ end
388
+
389
+ # Return whether the given file extension has been registered.
390
+ def registered?(ext)
391
+ @template_map.has_key?(ext.downcase)
392
+ end
393
+
394
+ # Returns an aarry of all extensions the template class will
395
+ # be used for.
396
+ def extensions_for(template_class)
397
+ res = []
398
+ @template_map.each do |ext, klass|
399
+ res << ext if template_class == klass
400
+ end
401
+ res.uniq!
402
+ res
403
+ end
404
+
405
+ private
406
+
407
+ def lookup(ext)
408
+ @template_map[ext]
409
+ end
410
+ end
411
+ private_constant :FinalizedMapping
293
412
  end
data/lib/tilt/markaby.rb CHANGED
@@ -1,4 +1,5 @@
1
- require 'tilt/template'
1
+ # frozen_string_literal: true
2
+ require_relative 'template'
2
3
  require 'markaby'
3
4
 
4
5
  module Tilt
@@ -15,19 +16,16 @@ module Tilt
15
16
  end
16
17
  end
17
18
 
18
- def prepare
19
- end
20
-
21
19
  def evaluate(scope, locals, &block)
22
20
  builder = self.class.builder_class.new({}, scope)
23
21
  builder.locals = locals
24
22
 
25
- if data.kind_of? Proc
26
- (class << builder; self end).send(:define_method, :__run_markaby_tilt__, &data)
23
+ if @data.kind_of? Proc
24
+ (class << builder; self end).send(:define_method, :__run_markaby_tilt__, &@data)
27
25
  else
28
26
  builder.instance_eval <<-CODE, __FILE__, __LINE__
29
27
  def __run_markaby_tilt__
30
- #{data}
28
+ #{@data}
31
29
  end
32
30
  CODE
33
31
  end
data/lib/tilt/maruku.rb CHANGED
@@ -1,22 +1,10 @@
1
- require 'tilt/template'
1
+ # frozen_string_literal: true
2
+ require_relative 'template'
2
3
  require 'maruku'
3
4
 
4
- module Tilt
5
- # Maruku markdown implementation. See:
6
- # http://maruku.rubyforge.org/
7
- class MarukuTemplate < Template
8
- def prepare
9
- @engine = Maruku.new(data, options)
10
- @output = nil
11
- end
5
+ warn 'tilt/maruku is deprecated, as maruku requires modifying string literals', uplevel: 1
12
6
 
13
- def evaluate(scope, locals, &block)
14
- @output ||= @engine.to_html
15
- end
16
-
17
- def allows_script?
18
- false
19
- end
20
- end
7
+ # Maruku markdown implementation. See: https://github.com/bhollis/maruku
8
+ Tilt::MarukuTemplate = Tilt::StaticTemplate.subclass do
9
+ Maruku.new(@data, @options).to_html
21
10
  end
22
-
data/lib/tilt/nokogiri.rb CHANGED
@@ -1,21 +1,23 @@
1
- require 'tilt/template'
1
+ # frozen_string_literal: true
2
+ require_relative 'template'
2
3
  require 'nokogiri'
3
4
 
4
5
  module Tilt
5
6
  # Nokogiri template implementation. See:
6
7
  # http://nokogiri.org/
7
8
  class NokogiriTemplate < Template
8
- DOCUMENT_HEADER = /^<\?xml version=\"1\.0\"\?>\n?/
9
+ DOCUMENT_HEADER = /\A<\?xml version=\"1\.0\"\?>\n?/
9
10
  self.default_mime_type = 'text/xml'
10
11
 
11
- def prepare; end
12
-
13
12
  def evaluate(scope, locals)
14
- if data.respond_to?(:to_str)
15
- wrapper = proc { yield.sub(DOCUMENT_HEADER, "") } if block_given?
16
- super(scope, locals, &wrapper)
13
+ if @data.respond_to?(:to_str)
14
+ if block_given?
15
+ super(scope, locals){yield.sub(DOCUMENT_HEADER, "")}
16
+ else
17
+ super
18
+ end
17
19
  else
18
- ::Nokogiri::XML::Builder.new.tap(&data).to_xml
20
+ ::Nokogiri::XML::Builder.new(&@data).to_xml
19
21
  end
20
22
  end
21
23
 
@@ -29,8 +31,7 @@ module Tilt
29
31
  end
30
32
 
31
33
  def precompiled_template(locals)
32
- data.to_str
34
+ @data.to_str
33
35
  end
34
36
  end
35
37
  end
36
-
data/lib/tilt/pandoc.rb CHANGED
@@ -1,49 +1,39 @@
1
- require 'tilt/template'
1
+ # frozen_string_literal: true
2
+ require_relative 'template'
2
3
  require 'pandoc-ruby'
3
4
 
4
- module Tilt
5
- # Pandoc markdown implementation. See:
6
- # http://pandoc.org/
7
- class PandocTemplate < Template
8
- self.default_mime_type = 'text/html'
9
-
10
- def tilt_to_pandoc_mapping
11
- { :smartypants => :smart,
12
- :escape_html => { :f => 'markdown-raw_html' },
13
- :commonmark => { :f => 'commonmark' },
14
- :markdown_strict => { :f => 'markdown_strict' }
15
- }
16
- end
17
-
18
- # turn options hash into an array
19
- # Map tilt options to pandoc options
20
- # Replace hash keys with value true with symbol for key
21
- # Remove hash keys with value false
22
- # Leave other hash keys untouched
23
- def pandoc_options
24
- options.reduce([]) do |sum, (k,v)|
25
- case v
26
- when true
27
- sum << (tilt_to_pandoc_mapping[k] || k)
28
- when false
29
- sum
30
- else
31
- sum << { k => v }
32
- end
5
+ # Pandoc markdown implementation. See: http://pandoc.org/
6
+ Tilt::PandocTemplate = Tilt::StaticTemplate.subclass do
7
+ # turn options hash into an array
8
+ # Map tilt options to pandoc options
9
+ # Replace hash keys with value true with symbol for key
10
+ # Remove hash keys with value false
11
+ # Leave other hash keys untouched
12
+ pandoc_options = []
13
+ from = "markdown"
14
+ smart_extension = "-smart"
15
+ @options.each do |k,v|
16
+ case k
17
+ when :smartypants
18
+ smart_extension = "+smart" if v
19
+ when :escape_html
20
+ from = "markdown-raw_html" if v
21
+ when :commonmark
22
+ from = "commonmark" if v
23
+ when :markdown_strict
24
+ from = "markdown_strict" if v
25
+ else
26
+ case v
27
+ when true
28
+ pandoc_options << k
29
+ when false
30
+ # do nothing
31
+ else
32
+ pandoc_options << { k => v }
33
33
  end
34
34
  end
35
-
36
- def prepare
37
- @engine = PandocRuby.new(data, *pandoc_options)
38
- @output = nil
39
- end
40
-
41
- def evaluate(scope, locals, &block)
42
- @output ||= @engine.to_html.strip
43
- end
44
-
45
- def allows_script?
46
- false
47
- end
48
35
  end
36
+ pandoc_options << { :f => from + smart_extension }
37
+
38
+ PandocRuby.new(@data, *pandoc_options).to_html.strip
49
39
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ require_relative 'template'
3
+
4
+ module Tilt
5
+ # Superclass used for pipeline templates. Should not be used directly.
6
+ class Pipeline < Template
7
+ def prepare
8
+ @pipeline = self.class::TEMPLATES.inject(proc{|*| data}) do |data, (klass, options)|
9
+ proc do |s,l,&sb|
10
+ klass.new(file, line, options, &proc{|*| data.call(s, l, &sb)}).render(s, l, &sb)
11
+ end
12
+ end
13
+ end
14
+
15
+ def evaluate(scope, locals, &block)
16
+ @pipeline.call(scope, locals, &block)
17
+ end
18
+ end
19
+ end
data/lib/tilt/plain.rb CHANGED
@@ -1,16 +1,5 @@
1
- require 'tilt/template'
1
+ # frozen_string_literal: true
2
+ require_relative 'template'
2
3
 
3
-
4
- module Tilt
5
- # Raw text (no template functionality).
6
- class PlainTemplate < Template
7
- self.default_mime_type = 'text/html'
8
-
9
- def prepare
10
- end
11
-
12
- def evaluate(scope, locals, &block)
13
- @output ||= data
14
- end
15
- end
16
- end
4
+ # Raw text (no template functionality).
5
+ Tilt::PlainTemplate = Tilt::StaticTemplate.subclass{@data}