tilt 2.0.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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/template.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
|
2
|
-
require 'thread'
|
3
|
-
|
1
|
+
# frozen_string_literal: true
|
4
2
|
module Tilt
|
5
3
|
# @private
|
6
|
-
|
4
|
+
module CompiledTemplates
|
5
|
+
end
|
6
|
+
|
7
|
+
# @private
|
8
|
+
TOPOBJECT = CompiledTemplates
|
9
|
+
|
7
10
|
# @private
|
8
11
|
LOCK = Mutex.new
|
9
12
|
|
@@ -25,6 +28,12 @@ module Tilt
|
|
25
28
|
# interface.
|
26
29
|
attr_reader :options
|
27
30
|
|
31
|
+
# A path ending in .rb that the template code will be written to, then
|
32
|
+
# required, instead of being evaled. This is useful for determining
|
33
|
+
# coverage of compiled template code, or to use static analysis tools
|
34
|
+
# on the compiled template code.
|
35
|
+
attr_reader :compiled_path
|
36
|
+
|
28
37
|
class << self
|
29
38
|
# An empty Hash that the template engine can populate with various
|
30
39
|
# metadata.
|
@@ -32,12 +41,12 @@ module Tilt
|
|
32
41
|
@metadata ||= {}
|
33
42
|
end
|
34
43
|
|
35
|
-
#
|
44
|
+
# Use `.metadata[:mime_type]` instead.
|
36
45
|
def default_mime_type
|
37
46
|
metadata[:mime_type]
|
38
47
|
end
|
39
48
|
|
40
|
-
#
|
49
|
+
# Use `.metadata[:mime_type] = val` instead.
|
41
50
|
def default_mime_type=(value)
|
42
51
|
metadata[:mime_type] = value
|
43
52
|
end
|
@@ -49,36 +58,34 @@ module Tilt
|
|
49
58
|
# a block is required.
|
50
59
|
#
|
51
60
|
# All arguments are optional.
|
52
|
-
def initialize(file=nil, line=
|
53
|
-
@file, @line, @options = nil, 1,
|
61
|
+
def initialize(file=nil, line=nil, options=nil)
|
62
|
+
@file, @line, @options = nil, 1, nil
|
54
63
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
when arg.respond_to?(:to_int) ; @line = arg.to_int
|
59
|
-
when arg.respond_to?(:to_hash) ; @options = arg.to_hash.dup
|
60
|
-
when arg.respond_to?(:path) ; @file = arg.path
|
61
|
-
when arg.respond_to?(:to_path) ; @file = arg.to_path
|
62
|
-
else raise TypeError, "Can't load the template file. Pass a string with a path " +
|
63
|
-
"or an object that responds to 'to_str', 'path' or 'to_path'"
|
64
|
-
end
|
65
|
-
end
|
64
|
+
process_arg(options)
|
65
|
+
process_arg(line)
|
66
|
+
process_arg(file)
|
66
67
|
|
67
|
-
raise ArgumentError, "file or block required"
|
68
|
+
raise ArgumentError, "file or block required" unless @file || block_given?
|
68
69
|
|
69
|
-
|
70
|
-
|
70
|
+
@options ||= {}
|
71
|
+
|
72
|
+
set_compiled_method_cache
|
71
73
|
|
72
|
-
#
|
73
|
-
# currently only used if template compiles to ruby
|
74
|
+
# Force the encoding of the input data
|
74
75
|
@default_encoding = @options.delete :default_encoding
|
75
76
|
|
77
|
+
# Skip encoding detection from magic comments and forcing that encoding
|
78
|
+
# for compiled templates
|
79
|
+
@skip_compiled_encoding_detection = @options.delete :skip_compiled_encoding_detection
|
80
|
+
|
76
81
|
# load template data and prepare (uses binread to avoid encoding issues)
|
77
|
-
@
|
78
|
-
@data = @reader.call(self)
|
82
|
+
@data = block_given? ? yield(self) : read_template_file
|
79
83
|
|
80
84
|
if @data.respond_to?(:force_encoding)
|
81
|
-
|
85
|
+
if default_encoding
|
86
|
+
@data = @data.dup if @data.frozen?
|
87
|
+
@data.force_encoding(default_encoding)
|
88
|
+
end
|
82
89
|
|
83
90
|
if !@data.valid_encoding?
|
84
91
|
raise Encoding::InvalidByteSequenceError, "#{eval_file} is not valid #{@data.encoding}"
|
@@ -91,27 +98,25 @@ module Tilt
|
|
91
98
|
# Render the template in the given scope with the locals specified. If a
|
92
99
|
# block is given, it is typically available within the template via
|
93
100
|
# +yield+.
|
94
|
-
def render(scope=
|
95
|
-
|
96
|
-
Thread.current[:tilt_current_template] = self
|
97
|
-
evaluate(scope, locals || {}, &block)
|
98
|
-
ensure
|
99
|
-
Thread.current[:tilt_current_template] = current_template
|
101
|
+
def render(scope=nil, locals=nil, &block)
|
102
|
+
evaluate(scope || Object.new, locals || EMPTY_HASH, &block)
|
100
103
|
end
|
101
104
|
|
102
105
|
# The basename of the template file.
|
103
106
|
def basename(suffix='')
|
104
|
-
File.basename(file, suffix) if file
|
107
|
+
File.basename(@file, suffix) if @file
|
105
108
|
end
|
106
109
|
|
107
110
|
# The template file's basename with all extensions chomped off.
|
108
111
|
def name
|
109
|
-
|
112
|
+
if bname = basename
|
113
|
+
bname.split('.', 2).first
|
114
|
+
end
|
110
115
|
end
|
111
116
|
|
112
117
|
# The filename used in backtraces to describe the template.
|
113
118
|
def eval_file
|
114
|
-
file || '(__TEMPLATE__)'
|
119
|
+
@file || '(__TEMPLATE__)'
|
115
120
|
end
|
116
121
|
|
117
122
|
# An empty Hash that the template engine can populate with various
|
@@ -124,6 +129,35 @@ module Tilt
|
|
124
129
|
end
|
125
130
|
end
|
126
131
|
|
132
|
+
# Set the prefix to use for compiled paths.
|
133
|
+
def compiled_path=(path)
|
134
|
+
if path
|
135
|
+
# Use expanded paths when loading, since that is helpful
|
136
|
+
# for coverage. Remove any .rb suffix, since that will
|
137
|
+
# be added back later.
|
138
|
+
path = File.expand_path(path.sub(/\.rb\z/i, ''))
|
139
|
+
end
|
140
|
+
@compiled_path = path
|
141
|
+
end
|
142
|
+
|
143
|
+
# The compiled method for the locals keys and scope_class provided.
|
144
|
+
# Returns an UnboundMethod, which can be used to define methods
|
145
|
+
# directly on the scope class, which are much faster to call than
|
146
|
+
# Tilt's normal rendering.
|
147
|
+
def compiled_method(locals_keys, scope_class=nil)
|
148
|
+
key = [scope_class, locals_keys].freeze
|
149
|
+
LOCK.synchronize do
|
150
|
+
if meth = @compiled_method[key]
|
151
|
+
return meth
|
152
|
+
end
|
153
|
+
end
|
154
|
+
meth = compile_template_method(locals_keys, scope_class)
|
155
|
+
LOCK.synchronize do
|
156
|
+
@compiled_method[key] = meth
|
157
|
+
end
|
158
|
+
meth
|
159
|
+
end
|
160
|
+
|
127
161
|
protected
|
128
162
|
|
129
163
|
# @!group For template implementations
|
@@ -132,19 +166,23 @@ module Tilt
|
|
132
166
|
# default_encoding-option if present. You may override this method
|
133
167
|
# in your template class if you have a better hint of the data's
|
134
168
|
# encoding.
|
135
|
-
|
136
|
-
|
169
|
+
attr_reader :default_encoding
|
170
|
+
|
171
|
+
def skip_compiled_encoding_detection?
|
172
|
+
@skip_compiled_encoding_detection
|
137
173
|
end
|
138
174
|
|
139
175
|
# Do whatever preparation is necessary to setup the underlying template
|
140
176
|
# engine. Called immediately after template data is loaded. Instance
|
141
177
|
# variables set in this method are available when #evaluate is called.
|
142
178
|
#
|
143
|
-
#
|
179
|
+
# Empty by default as some subclasses do not need separate preparation.
|
144
180
|
def prepare
|
145
|
-
raise NotImplementedError
|
146
181
|
end
|
147
182
|
|
183
|
+
CLASS_METHOD = Kernel.instance_method(:class)
|
184
|
+
USE_BIND_CALL = RUBY_VERSION >= '2.7'
|
185
|
+
|
148
186
|
# Execute the compiled template and return the result string. Template
|
149
187
|
# evaluation is guaranteed to be performed in the scope object with the
|
150
188
|
# locals specified and with support for yielding to the block.
|
@@ -152,8 +190,26 @@ module Tilt
|
|
152
190
|
# This method is only used by source generating templates. Subclasses that
|
153
191
|
# override render() may not support all features.
|
154
192
|
def evaluate(scope, locals, &block)
|
155
|
-
|
156
|
-
|
193
|
+
locals_keys = locals.keys
|
194
|
+
locals_keys.sort!{|x, y| x.to_s <=> y.to_s}
|
195
|
+
|
196
|
+
case scope
|
197
|
+
when Object
|
198
|
+
scope_class = Module === scope ? scope : scope.class
|
199
|
+
else
|
200
|
+
# :nocov:
|
201
|
+
scope_class = USE_BIND_CALL ? CLASS_METHOD.bind_call(scope) : CLASS_METHOD.bind(scope).call
|
202
|
+
# :nocov:
|
203
|
+
end
|
204
|
+
method = compiled_method(locals_keys, scope_class)
|
205
|
+
|
206
|
+
if USE_BIND_CALL
|
207
|
+
method.bind_call(scope, locals, &block)
|
208
|
+
# :nocov:
|
209
|
+
else
|
210
|
+
method.bind(scope).call(locals, &block)
|
211
|
+
# :nocov:
|
212
|
+
end
|
157
213
|
end
|
158
214
|
|
159
215
|
# Generates all template source by combining the preamble, template, and
|
@@ -169,17 +225,21 @@ module Tilt
|
|
169
225
|
preamble = precompiled_preamble(local_keys)
|
170
226
|
template = precompiled_template(local_keys)
|
171
227
|
postamble = precompiled_postamble(local_keys)
|
172
|
-
source =
|
228
|
+
source = String.new
|
173
229
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
template_encoding = extract_encoding(template)
|
230
|
+
unless skip_compiled_encoding_detection?
|
231
|
+
# Ensure that our generated source code has the same encoding as the
|
232
|
+
# the source code generated by the template engine.
|
233
|
+
template_encoding = extract_encoding(template){|t| template = t}
|
178
234
|
|
179
|
-
|
180
|
-
|
235
|
+
if template.encoding != template_encoding
|
236
|
+
# template should never be frozen here. If it was frozen originally,
|
237
|
+
# then extract_encoding should yield a dup.
|
238
|
+
template.force_encoding(template_encoding)
|
239
|
+
end
|
181
240
|
end
|
182
241
|
|
242
|
+
source.force_encoding(template.encoding)
|
183
243
|
source << preamble << "\n" << template << "\n" << postamble
|
184
244
|
|
185
245
|
[source, preamble.count("\n")+1]
|
@@ -207,75 +267,143 @@ module Tilt
|
|
207
267
|
|
208
268
|
private
|
209
269
|
|
210
|
-
def
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
270
|
+
def process_arg(arg)
|
271
|
+
if arg
|
272
|
+
case
|
273
|
+
when arg.respond_to?(:to_str) ; @file = arg.to_str
|
274
|
+
when arg.respond_to?(:to_int) ; @line = arg.to_int
|
275
|
+
when arg.respond_to?(:to_hash) ; @options = arg.to_hash.dup
|
276
|
+
when arg.respond_to?(:path) ; @file = arg.path
|
277
|
+
when arg.respond_to?(:to_path) ; @file = arg.to_path
|
278
|
+
else raise TypeError, "Can't load the template file. Pass a string with a path " +
|
279
|
+
"or an object that responds to 'to_str', 'path' or 'to_path'"
|
280
|
+
end
|
215
281
|
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def read_template_file
|
285
|
+
data = File.binread(file)
|
286
|
+
# Set it to the default external (without verifying)
|
287
|
+
# :nocov:
|
288
|
+
data.force_encoding(Encoding.default_external) if Encoding.default_external
|
289
|
+
# :nocov:
|
216
290
|
data
|
217
291
|
end
|
218
292
|
|
219
|
-
|
220
|
-
|
221
|
-
LOCK.synchronize do
|
222
|
-
@compiled_method[locals_keys] ||= compile_template_method(locals_keys)
|
223
|
-
end
|
293
|
+
def set_compiled_method_cache
|
294
|
+
@compiled_method = {}
|
224
295
|
end
|
225
296
|
|
226
297
|
def local_extraction(local_keys)
|
227
|
-
local_keys.map do |k|
|
298
|
+
assignments = local_keys.map do |k|
|
228
299
|
if k.to_s =~ /\A[a-z_][a-zA-Z_0-9]*\z/
|
229
300
|
"#{k} = locals[#{k.inspect}]"
|
230
301
|
else
|
231
302
|
raise "invalid locals key: #{k.inspect} (keys must be variable names)"
|
232
303
|
end
|
233
|
-
end
|
304
|
+
end
|
305
|
+
|
306
|
+
s = "locals = locals[:locals]"
|
307
|
+
if assignments.delete(s)
|
308
|
+
# If there is a locals key itself named `locals`, delete it from the ordered keys so we can
|
309
|
+
# assign it last. This is important because the assignment of all other locals depends on the
|
310
|
+
# `locals` local variable still matching the `locals` method argument given to the method
|
311
|
+
# created in `#compile_template_method`.
|
312
|
+
assignments << s
|
313
|
+
end
|
314
|
+
|
315
|
+
assignments.join("\n")
|
234
316
|
end
|
235
317
|
|
236
|
-
def compile_template_method(local_keys)
|
318
|
+
def compile_template_method(local_keys, scope_class=nil)
|
237
319
|
source, offset = precompiled(local_keys)
|
238
320
|
local_code = local_extraction(local_keys)
|
239
321
|
|
240
322
|
method_name = "__tilt_#{Thread.current.object_id.abs}"
|
241
|
-
method_source =
|
323
|
+
method_source = String.new
|
324
|
+
method_source.force_encoding(source.encoding)
|
242
325
|
|
243
|
-
if
|
244
|
-
method_source
|
326
|
+
if freeze_string_literals?
|
327
|
+
method_source << "# frozen-string-literal: true\n"
|
245
328
|
end
|
246
329
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
Thread.current[:tilt_vars] = [self, locals]
|
251
|
-
class << self
|
252
|
-
this, locals = Thread.current[:tilt_vars]
|
253
|
-
this.instance_eval do
|
254
|
-
#{local_code}
|
255
|
-
RUBY
|
330
|
+
# Don't indent method source, to avoid indentation warnings when using compiled paths
|
331
|
+
method_source << "::Tilt::TOPOBJECT.class_eval do\ndef #{method_name}(locals)\n#{local_code}\n"
|
332
|
+
|
256
333
|
offset += method_source.count("\n")
|
257
334
|
method_source << source
|
258
|
-
method_source << "\nend;end;
|
259
|
-
|
335
|
+
method_source << "\nend;end;"
|
336
|
+
|
337
|
+
bind_compiled_method(method_source, offset, scope_class)
|
260
338
|
unbind_compiled_method(method_name)
|
261
339
|
end
|
262
340
|
|
341
|
+
def bind_compiled_method(method_source, offset, scope_class)
|
342
|
+
path = compiled_path
|
343
|
+
if path && scope_class.name
|
344
|
+
path = path.dup
|
345
|
+
|
346
|
+
if defined?(@compiled_path_counter)
|
347
|
+
path << '-' << @compiled_path_counter.succ!
|
348
|
+
else
|
349
|
+
@compiled_path_counter = "0".dup
|
350
|
+
end
|
351
|
+
path << ".rb"
|
352
|
+
|
353
|
+
# Wrap method source in a class block for the scope, so constant lookup works
|
354
|
+
if freeze_string_literals?
|
355
|
+
method_source_prefix = "# frozen-string-literal: true\n"
|
356
|
+
method_source = method_source.sub(/\A# frozen-string-literal: true\n/, '')
|
357
|
+
end
|
358
|
+
method_source = "#{method_source_prefix}class #{scope_class.name}\n#{method_source}\nend"
|
359
|
+
|
360
|
+
load_compiled_method(path, method_source)
|
361
|
+
else
|
362
|
+
if path
|
363
|
+
warn "compiled_path (#{compiled_path.inspect}) ignored on template with anonymous scope_class (#{scope_class.inspect})"
|
364
|
+
end
|
365
|
+
|
366
|
+
eval_compiled_method(method_source, offset, scope_class)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
def eval_compiled_method(method_source, offset, scope_class)
|
371
|
+
(scope_class || Object).class_eval(method_source, eval_file, line - offset)
|
372
|
+
end
|
373
|
+
|
374
|
+
def load_compiled_method(path, method_source)
|
375
|
+
File.binwrite(path, method_source)
|
376
|
+
|
377
|
+
# Use load and not require, so unbind_compiled_method does not
|
378
|
+
# break if the same path is used more than once.
|
379
|
+
load path
|
380
|
+
end
|
381
|
+
|
263
382
|
def unbind_compiled_method(method_name)
|
264
383
|
method = TOPOBJECT.instance_method(method_name)
|
265
384
|
TOPOBJECT.class_eval { remove_method(method_name) }
|
266
385
|
method
|
267
386
|
end
|
268
387
|
|
269
|
-
def extract_encoding(script)
|
270
|
-
extract_magic_comment(script) || script.encoding
|
388
|
+
def extract_encoding(script, &block)
|
389
|
+
extract_magic_comment(script, &block) || script.encoding
|
271
390
|
end
|
272
391
|
|
273
392
|
def extract_magic_comment(script)
|
393
|
+
if script.frozen?
|
394
|
+
script = script.dup
|
395
|
+
yield script
|
396
|
+
end
|
397
|
+
|
274
398
|
binary(script) do
|
275
399
|
script[/\A[ \t]*\#.*coding\s*[=:]\s*([[:alnum:]\-_]+).*$/n, 1]
|
276
400
|
end
|
277
401
|
end
|
278
402
|
|
403
|
+
def freeze_string_literals?
|
404
|
+
false
|
405
|
+
end
|
406
|
+
|
279
407
|
def binary(string)
|
280
408
|
original_encoding = string.encoding
|
281
409
|
string.force_encoding(Encoding::BINARY)
|
@@ -284,4 +412,44 @@ module Tilt
|
|
284
412
|
string.force_encoding(original_encoding)
|
285
413
|
end
|
286
414
|
end
|
415
|
+
|
416
|
+
class StaticTemplate < Template
|
417
|
+
def self.subclass(mime_type: 'text/html', &block)
|
418
|
+
Class.new(self) do
|
419
|
+
self.default_mime_type = mime_type
|
420
|
+
|
421
|
+
private
|
422
|
+
|
423
|
+
define_method(:_prepare_output, &block)
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
# Static templates always return the prepared output.
|
428
|
+
def render(scope=nil, locals=nil)
|
429
|
+
@output
|
430
|
+
end
|
431
|
+
|
432
|
+
# Raise NotImplementedError, since static templates
|
433
|
+
# do not support compiled methods.
|
434
|
+
def compiled_method(locals_keys, scope_class=nil)
|
435
|
+
raise NotImplementedError
|
436
|
+
end
|
437
|
+
|
438
|
+
# Static templates never allow script.
|
439
|
+
def allows_script?
|
440
|
+
false
|
441
|
+
end
|
442
|
+
|
443
|
+
protected
|
444
|
+
|
445
|
+
def prepare
|
446
|
+
@output = _prepare_output
|
447
|
+
end
|
448
|
+
|
449
|
+
private
|
450
|
+
|
451
|
+
# Do nothing, since compiled method cache is not used.
|
452
|
+
def set_compiled_method_cache
|
453
|
+
end
|
454
|
+
end
|
287
455
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'template'
|
3
|
+
require 'typescript-node'
|
4
|
+
|
5
|
+
Tilt::TypeScriptTemplate = Tilt::StaticTemplate.subclass(mime_type: 'application/javascript') do
|
6
|
+
option_args = []
|
7
|
+
|
8
|
+
@options.each do |key, value|
|
9
|
+
next unless value
|
10
|
+
|
11
|
+
option_args << "--#{key}"
|
12
|
+
|
13
|
+
if value != true
|
14
|
+
option_args << value.to_s
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
TypeScript::Node.compile(@data, *option_args)
|
19
|
+
end
|
data/lib/tilt/wikicloth.rb
CHANGED
@@ -1,22 +1,12 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'template'
|
2
3
|
require 'wikicloth'
|
3
4
|
|
4
|
-
|
5
|
-
# WikiCloth implementation. See:
|
6
|
-
# http://redcloth.org/
|
7
|
-
class WikiClothTemplate < Template
|
8
|
-
def prepare
|
9
|
-
@parser = options.delete(:parser) || WikiCloth::Parser
|
10
|
-
@engine = @parser.new options.merge(:data => data)
|
11
|
-
@output = nil
|
12
|
-
end
|
5
|
+
warn 'tilt/wikicloth is deprecated, as wikicloth requires modifying string literals', uplevel: 1
|
13
6
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
false
|
20
|
-
end
|
21
|
-
end
|
7
|
+
# WikiCloth implementation. See: https://github.com/nricciar/wikicloth
|
8
|
+
Tilt::WikiClothTemplate = Tilt::StaticTemplate.subclass do
|
9
|
+
parser = @options.delete(:parser) || WikiCloth::Parser
|
10
|
+
@options[:data] = @data
|
11
|
+
parser.new(@options).to_html
|
22
12
|
end
|
data/lib/tilt/yajl.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'template'
|
2
3
|
require 'yajl'
|
3
4
|
|
4
5
|
module Tilt
|
5
|
-
|
6
6
|
# Yajl Template implementation
|
7
7
|
#
|
8
8
|
# Yajl is a fast JSON parsing and encoding library for Ruby
|
@@ -40,14 +40,10 @@ module Tilt
|
|
40
40
|
# template.render(self)
|
41
41
|
#
|
42
42
|
class YajlTemplate < Template
|
43
|
-
|
44
43
|
self.default_mime_type = 'application/json'
|
45
44
|
|
46
|
-
def prepare
|
47
|
-
end
|
48
|
-
|
49
45
|
def evaluate(scope, locals, &block)
|
50
|
-
decorate
|
46
|
+
decorate(super)
|
51
47
|
end
|
52
48
|
|
53
49
|
def precompiled_preamble(locals)
|
@@ -60,10 +56,9 @@ module Tilt
|
|
60
56
|
end
|
61
57
|
|
62
58
|
def precompiled_template(locals)
|
63
|
-
data.to_str
|
59
|
+
@data.to_str
|
64
60
|
end
|
65
61
|
|
66
|
-
|
67
62
|
# Decorates the +json+ input according to given +options+.
|
68
63
|
#
|
69
64
|
# json - The json String to decorate.
|
@@ -71,7 +66,7 @@ module Tilt
|
|
71
66
|
#
|
72
67
|
# Returns the decorated String.
|
73
68
|
def decorate(json)
|
74
|
-
callback, variable = options[:callback], options[:variable]
|
69
|
+
callback, variable = @options[:callback], @options[:variable]
|
75
70
|
if callback && variable
|
76
71
|
"var #{variable} = #{json}; #{callback}(#{variable});"
|
77
72
|
elsif variable
|
@@ -83,5 +78,4 @@ module Tilt
|
|
83
78
|
end
|
84
79
|
end
|
85
80
|
end
|
86
|
-
|
87
81
|
end
|