tilt 2.0.0 → 2.4.0
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 +5 -5
- data/COPYING +2 -1
- data/bin/tilt +2 -110
- data/lib/tilt/_emacs_org.rb +2 -0
- data/lib/tilt/_handlebars.rb +2 -0
- data/lib/tilt/_jbuilder.rb +2 -0
- data/lib/tilt/_org.rb +2 -0
- data/lib/tilt/asciidoc.rb +11 -23
- data/lib/tilt/babel.rb +8 -0
- data/lib/tilt/builder.rb +23 -14
- data/lib/tilt/cli.rb +134 -0
- data/lib/tilt/coffee.rb +17 -25
- data/lib/tilt/commonmarker.rb +95 -0
- data/lib/tilt/creole.rb +9 -20
- data/lib/tilt/csv.rb +9 -21
- data/lib/tilt/erb.rb +27 -19
- data/lib/tilt/erubi.rb +55 -0
- data/lib/tilt/erubis.rb +20 -12
- data/lib/tilt/etanni.rb +5 -4
- data/lib/tilt/haml.rb +79 -42
- data/lib/tilt/kramdown.rb +8 -28
- data/lib/tilt/liquid.rb +11 -9
- data/lib/tilt/livescript.rb +11 -0
- data/lib/tilt/mapping.rb +242 -95
- data/lib/tilt/markaby.rb +5 -7
- data/lib/tilt/maruku.rb +6 -18
- data/lib/tilt/nokogiri.rb +11 -10
- data/lib/tilt/pandoc.rb +39 -0
- data/lib/tilt/pipeline.rb +19 -0
- data/lib/tilt/plain.rb +4 -19
- data/lib/tilt/prawn.rb +28 -0
- data/lib/tilt/radius.rb +15 -22
- data/lib/tilt/rdiscount.rb +17 -33
- data/lib/tilt/rdoc.rb +14 -35
- data/lib/tilt/redcarpet.rb +20 -93
- data/lib/tilt/redcloth.rb +9 -19
- data/lib/tilt/rst-pandoc.rb +10 -0
- data/lib/tilt/sass.rb +59 -22
- data/lib/tilt/slim.rb +5 -0
- data/lib/tilt/string.rb +9 -3
- data/lib/tilt/template.rb +246 -78
- data/lib/tilt/typescript.rb +19 -0
- data/lib/tilt/wikicloth.rb +8 -18
- data/lib/tilt/yajl.rb +5 -11
- data/lib/tilt.rb +91 -41
- metadata +39 -102
- data/CHANGELOG.md +0 -61
- data/Gemfile +0 -39
- data/HACKING +0 -16
- data/README.md +0 -206
- data/Rakefile +0 -95
- data/docs/TEMPLATES.md +0 -523
- data/docs/common.css +0 -14
- data/lib/tilt/bluecloth.rb +0 -24
- data/lib/tilt/less.rb +0 -38
- data/test/markaby/locals.mab +0 -1
- data/test/markaby/markaby.mab +0 -1
- data/test/markaby/markaby_other_static.mab +0 -1
- data/test/markaby/render_twice.mab +0 -1
- data/test/markaby/scope.mab +0 -1
- data/test/markaby/yielding.mab +0 -2
- data/test/test_helper.rb +0 -64
- data/test/tilt_asciidoctor_test.rb +0 -44
- data/test/tilt_blueclothtemplate_test.rb +0 -33
- data/test/tilt_buildertemplate_test.rb +0 -59
- data/test/tilt_cache_test.rb +0 -32
- data/test/tilt_coffeescripttemplate_test.rb +0 -104
- data/test/tilt_compilesite_test.rb +0 -51
- data/test/tilt_creoletemplate_test.rb +0 -24
- data/test/tilt_csv_test.rb +0 -65
- data/test/tilt_erbtemplate_test.rb +0 -239
- data/test/tilt_erubistemplate_test.rb +0 -151
- data/test/tilt_etannitemplate_test.rb +0 -174
- data/test/tilt_hamltemplate_test.rb +0 -144
- data/test/tilt_kramdown_test.rb +0 -20
- data/test/tilt_lesstemplate_test.less +0 -1
- data/test/tilt_lesstemplate_test.rb +0 -42
- data/test/tilt_liquidtemplate_test.rb +0 -78
- data/test/tilt_mapping_test.rb +0 -229
- data/test/tilt_markaby_test.rb +0 -88
- data/test/tilt_markdown_test.rb +0 -174
- data/test/tilt_marukutemplate_test.rb +0 -36
- data/test/tilt_metadata_test.rb +0 -42
- data/test/tilt_nokogiritemplate_test.rb +0 -87
- data/test/tilt_radiustemplate_test.rb +0 -75
- data/test/tilt_rdiscounttemplate_test.rb +0 -43
- data/test/tilt_rdoctemplate_test.rb +0 -29
- data/test/tilt_redcarpettemplate_test.rb +0 -59
- data/test/tilt_redclothtemplate_test.rb +0 -36
- data/test/tilt_sasstemplate_test.rb +0 -41
- data/test/tilt_stringtemplate_test.rb +0 -171
- data/test/tilt_template_test.rb +0 -316
- data/test/tilt_test.rb +0 -60
- data/test/tilt_wikiclothtemplate_test.rb +0 -32
- data/test/tilt_yajltemplate_test.rb +0 -101
- data/tilt.gemspec +0 -107
data/lib/tilt/mapping.rb
CHANGED
@@ -1,4 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'pipeline'
|
3
|
+
|
1
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
|
+
|
2
79
|
# Tilt::Mapping associates file extensions with template implementations.
|
3
80
|
#
|
4
81
|
# mapping = Tilt::Mapping.new
|
@@ -36,16 +113,18 @@ module Tilt
|
|
36
113
|
# the exception of the first, since that was the most preferred one.
|
37
114
|
#
|
38
115
|
# mapping = Tilt::Mapping.new
|
39
|
-
# mapping.register_lazy('
|
116
|
+
# mapping.register_lazy('Maruku::Template', 'maruku/template', 'md')
|
40
117
|
# mapping.register_lazy('RDiscount::Template', 'rdiscount/template', 'md')
|
41
118
|
# mapping['index.md']
|
42
119
|
# # => RDiscount::Template
|
43
120
|
#
|
44
121
|
# In the previous example we say that RDiscount has a *higher priority* than
|
45
|
-
#
|
46
|
-
# back to `require "
|
122
|
+
# Maruku. Tilt will first try to `require "rdiscount/template"`, falling
|
123
|
+
# back to `require "maruku/template"`. If none of these are successful,
|
47
124
|
# the first error will be raised.
|
48
|
-
class Mapping
|
125
|
+
class Mapping < BaseMapping
|
126
|
+
LOCK = Mutex.new
|
127
|
+
|
49
128
|
# @private
|
50
129
|
attr_reader :lazy_map, :template_map
|
51
130
|
|
@@ -56,11 +135,29 @@ module Tilt
|
|
56
135
|
|
57
136
|
# @private
|
58
137
|
def initialize_copy(other)
|
59
|
-
|
60
|
-
|
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)
|
61
158
|
end
|
62
159
|
|
63
|
-
#
|
160
|
+
# Registers a lazy template implementation by file extension. You
|
64
161
|
# can have multiple lazy template implementations defined on the
|
65
162
|
# same file extension, in which case the template implementation
|
66
163
|
# defined *last* will be attempted loaded *first*.
|
@@ -83,8 +180,9 @@ module Tilt
|
|
83
180
|
class_name = "Tilt::#{class_name}"
|
84
181
|
end
|
85
182
|
|
183
|
+
v = [class_name, file].freeze
|
86
184
|
extensions.each do |ext|
|
87
|
-
@lazy_map[ext].unshift(
|
185
|
+
LOCK.synchronize{@lazy_map[ext].unshift(v)}
|
88
186
|
end
|
89
187
|
end
|
90
188
|
|
@@ -106,86 +204,95 @@ module Tilt
|
|
106
204
|
end
|
107
205
|
|
108
206
|
extensions.each do |ext|
|
109
|
-
|
207
|
+
ext = ext.to_s
|
208
|
+
LOCK.synchronize do
|
209
|
+
@template_map[ext] = template_class
|
210
|
+
end
|
110
211
|
end
|
111
212
|
end
|
112
213
|
|
113
|
-
#
|
114
|
-
#
|
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.
|
115
218
|
#
|
116
|
-
#
|
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]
|
117
232
|
#
|
118
233
|
# @example
|
119
|
-
# mapping.
|
120
|
-
# mapping.
|
121
|
-
|
122
|
-
|
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
|
123
247
|
end
|
124
248
|
|
125
|
-
#
|
249
|
+
# Unregisters an extension. This removes the both normal registrations
|
250
|
+
# and lazy registrations.
|
126
251
|
#
|
127
|
-
# @
|
128
|
-
#
|
252
|
+
# @param extensions [Array<String>] List of extensions.
|
253
|
+
# @return nil
|
129
254
|
#
|
130
255
|
# @example
|
131
|
-
# mapping.
|
132
|
-
#
|
133
|
-
#
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
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
|
139
267
|
end
|
140
|
-
end
|
141
268
|
|
142
|
-
|
143
|
-
#
|
144
|
-
# @example
|
145
|
-
# mapping['views/hello.erb'] # => Tilt::ERBTemplate
|
146
|
-
# mapping['hello.erb'] # => Tilt::ERBTemplate
|
147
|
-
# mapping['erb'] # => Tilt::ERBTemplate
|
148
|
-
#
|
149
|
-
# @return [template class]
|
150
|
-
def [](file)
|
151
|
-
prefix, ext = split(file)
|
152
|
-
ext && lookup(ext)
|
269
|
+
nil
|
153
270
|
end
|
154
271
|
|
155
|
-
|
156
|
-
|
157
|
-
# Looks up a list of template classes based on file name. If the file name
|
158
|
-
# has multiple extensions, it will return all template classes matching the
|
159
|
-
# extensions from the end.
|
272
|
+
# Checks if a file extension is registered (either eagerly or
|
273
|
+
# lazily) in this mapping.
|
160
274
|
#
|
161
|
-
# @
|
162
|
-
# mapping.templates_for('views/index.haml.erb')
|
163
|
-
# # => [Tilt::ERBTemplate, Tilt::HamlTemplate]
|
275
|
+
# @param ext [String] File extension.
|
164
276
|
#
|
165
|
-
# @
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
break unless ext
|
172
|
-
templates << lookup(ext)
|
173
|
-
file = prefix
|
174
|
-
end
|
175
|
-
|
176
|
-
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)
|
177
283
|
end
|
178
284
|
|
179
285
|
# Finds the extensions the template class has been registered under.
|
180
286
|
# @param [template class] template_class
|
181
287
|
def extensions_for(template_class)
|
182
288
|
res = []
|
183
|
-
template_map.each do |ext, klass|
|
289
|
+
LOCK.synchronize{@template_map.to_a}.each do |ext, klass|
|
184
290
|
res << ext if template_class == klass
|
185
291
|
end
|
186
|
-
lazy_map.each do |ext, choices|
|
187
|
-
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 }
|
188
294
|
end
|
295
|
+
res.uniq!
|
189
296
|
res
|
190
297
|
end
|
191
298
|
|
@@ -193,40 +300,30 @@ module Tilt
|
|
193
300
|
|
194
301
|
def lazy?(ext)
|
195
302
|
ext = ext.downcase
|
196
|
-
@lazy_map.has_key?(ext) && !@lazy_map[ext].empty?
|
197
|
-
end
|
198
|
-
|
199
|
-
def split(file)
|
200
|
-
pattern = file.to_s.downcase
|
201
|
-
full_pattern = pattern.dup
|
202
|
-
|
203
|
-
until registered?(pattern)
|
204
|
-
return if pattern.empty?
|
205
|
-
pattern = File.basename(pattern)
|
206
|
-
pattern.sub!(/^[^.]*\.?/, '')
|
207
|
-
end
|
208
|
-
|
209
|
-
prefix_size = full_pattern.size - pattern.size
|
210
|
-
[full_pattern[0,prefix_size-1], pattern]
|
303
|
+
LOCK.synchronize{@lazy_map.has_key?(ext) && !@lazy_map[ext].empty?}
|
211
304
|
end
|
212
305
|
|
213
306
|
def lookup(ext)
|
214
|
-
@template_map[ext] || lazy_load(ext)
|
307
|
+
LOCK.synchronize{@template_map[ext]} || lazy_load(ext)
|
215
308
|
end
|
216
309
|
|
217
|
-
def
|
218
|
-
|
219
|
-
|
220
|
-
choices = @lazy_map[pattern]
|
221
|
-
|
222
|
-
# Check if a template class is already present
|
223
|
-
choices.each do |class_name, file|
|
310
|
+
def register_defined_classes(class_names, pattern)
|
311
|
+
class_names.each do |class_name|
|
224
312
|
template_class = constant_defined?(class_name)
|
225
313
|
if template_class
|
226
314
|
register(template_class, pattern)
|
227
|
-
|
315
|
+
yield template_class if block_given?
|
228
316
|
end
|
229
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
|
230
327
|
|
231
328
|
first_failure = nil
|
232
329
|
|
@@ -234,12 +331,6 @@ module Tilt
|
|
234
331
|
choices.each do |class_name, file|
|
235
332
|
begin
|
236
333
|
require file
|
237
|
-
|
238
|
-
if Thread.list.size > 1
|
239
|
-
warn "WARN: tilt autoloading '#{file}' in a non thread-safe way; " +
|
240
|
-
"explicit require '#{file}' suggested."
|
241
|
-
end
|
242
|
-
|
243
334
|
# It's safe to eval() here because constant_defined? will
|
244
335
|
# raise NameError on invalid constant names
|
245
336
|
template_class = eval(class_name)
|
@@ -251,15 +342,71 @@ module Tilt
|
|
251
342
|
end
|
252
343
|
end
|
253
344
|
|
254
|
-
raise first_failure
|
345
|
+
raise first_failure
|
255
346
|
end
|
256
347
|
|
348
|
+
# The proper behavior (in MRI) for autoload? is to
|
349
|
+
# return `false` when the constant/file has been
|
350
|
+
# explicitly required.
|
351
|
+
#
|
352
|
+
# However, in JRuby it returns `true` even after it's
|
353
|
+
# been required. In that case it turns out that `defined?`
|
354
|
+
# returns `"constant"` if it exists and `nil` when it doesn't.
|
355
|
+
# This is actually a second bug: `defined?` should resolve
|
356
|
+
# autoload (aka. actually try to require the file).
|
357
|
+
#
|
358
|
+
# We use the second bug in order to resolve the first bug.
|
359
|
+
|
257
360
|
def constant_defined?(name)
|
258
361
|
name.split('::').inject(Object) do |scope, n|
|
259
|
-
return false
|
260
|
-
return false if scope.autoload?(n) # skip autload
|
362
|
+
return false if scope.autoload?(n) || !scope.const_defined?(n)
|
261
363
|
scope.const_get(n)
|
262
364
|
end
|
263
365
|
end
|
264
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
|
265
412
|
end
|
data/lib/tilt/markaby.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
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__,
|
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
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'template'
|
2
3
|
require 'maruku'
|
3
4
|
|
4
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
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 =
|
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
|
-
|
16
|
-
|
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
|
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
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'template'
|
3
|
+
require 'pandoc-ruby'
|
4
|
+
|
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
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
pandoc_options << { :f => from + smart_extension }
|
37
|
+
|
38
|
+
PandocRuby.new(@data, *pandoc_options).to_html.strip
|
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,20 +1,5 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'template'
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
# Raw text (no template functionality).
|
6
|
-
class PlainTemplate < Template
|
7
|
-
self.default_mime_type = 'text/html'
|
8
|
-
|
9
|
-
def self.engine_initialized?
|
10
|
-
true
|
11
|
-
end
|
12
|
-
|
13
|
-
def prepare
|
14
|
-
end
|
15
|
-
|
16
|
-
def evaluate(scope, locals, &block)
|
17
|
-
@output ||= data
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
4
|
+
# Raw text (no template functionality).
|
5
|
+
Tilt::PlainTemplate = Tilt::StaticTemplate.subclass{@data}
|
data/lib/tilt/prawn.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'template'
|
3
|
+
require 'prawn'
|
4
|
+
|
5
|
+
module Tilt
|
6
|
+
# Prawn template implementation. See: http://prawnpdf.org
|
7
|
+
class PrawnTemplate < Template
|
8
|
+
self.default_mime_type = 'application/pdf'
|
9
|
+
|
10
|
+
def prepare
|
11
|
+
@options[:page_size] = 'A4' unless @options.has_key?(:page_size)
|
12
|
+
@options[:page_layout] = :portrait unless @options.has_key?(:page_layout)
|
13
|
+
@engine = ::Prawn::Document.new(@options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def evaluate(scope, locals, &block)
|
17
|
+
pdf = @engine
|
18
|
+
locals = locals.dup
|
19
|
+
locals[:pdf] = pdf
|
20
|
+
super
|
21
|
+
pdf.render
|
22
|
+
end
|
23
|
+
|
24
|
+
def precompiled_template(locals)
|
25
|
+
@data.to_str
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|