tilt 2.1.0 → 2.3.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  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 +47 -81
  14. data/lib/tilt/creole.rb +9 -20
  15. data/lib/tilt/csv.rb +5 -4
  16. data/lib/tilt/erb.rb +9 -17
  17. data/lib/tilt/erubi.rb +7 -6
  18. data/lib/tilt/erubis.rb +9 -6
  19. data/lib/tilt/etanni.rb +3 -2
  20. data/lib/tilt/haml.rb +12 -9
  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 +180 -104
  25. data/lib/tilt/markaby.rb +5 -7
  26. data/lib/tilt/maruku.rb +5 -19
  27. data/lib/tilt/nokogiri.rb +11 -10
  28. data/lib/tilt/pandoc.rb +33 -51
  29. data/lib/tilt/pipeline.rb +1 -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 -75
  36. data/lib/tilt/redcloth.rb +9 -19
  37. data/lib/tilt/rst-pandoc.rb +6 -19
  38. data/lib/tilt/sass.rb +34 -43
  39. data/lib/tilt/slim.rb +5 -0
  40. data/lib/tilt/string.rb +9 -3
  41. data/lib/tilt/template.rb +151 -61
  42. data/lib/tilt/typescript.rb +11 -18
  43. data/lib/tilt/wikicloth.rb +7 -19
  44. data/lib/tilt/yajl.rb +5 -11
  45. data/lib/tilt.rb +56 -40
  46. metadata +10 -7
  47. data/lib/tilt/bluecloth.rb +0 -26
  48. data/lib/tilt/less.rb +0 -32
  49. data/lib/tilt/sigil.rb +0 -36
data/lib/tilt/sass.rb CHANGED
@@ -1,17 +1,31 @@
1
- require 'tilt/template'
1
+ # frozen_string_literal: true
2
+ require_relative 'template'
2
3
 
3
4
  module Tilt
4
- # Sass template implementation. See:
5
- # http://haml.hamptoncatlin.com/
5
+ # Sass template implementation for generating CSS. See: https://sass-lang.com/
6
6
  #
7
7
  # Sass templates do not support object scopes, locals, or yield.
8
- class SassTemplate < Template
8
+ class SassTemplate < StaticTemplate
9
9
  self.default_mime_type = 'text/css'
10
10
 
11
11
  begin
12
12
  require 'sass-embedded'
13
+ # :nocov:
13
14
  require 'uri'
14
- Engine = nil
15
+
16
+ private
17
+
18
+ def _prepare_output
19
+ ::Sass.compile_string(@data, **sass_options).css
20
+ end
21
+
22
+ def sass_options
23
+ path = File.absolute_path(eval_file)
24
+ path = '/' + path unless path.start_with?('/')
25
+ @options[:url] = ::URI::File.build([nil, ::URI::DEFAULT_PARSER.escape(path)]).to_s
26
+ @options[:syntax] = :indented
27
+ @options
28
+ end
15
29
  rescue LoadError => err
16
30
  begin
17
31
  require 'sassc'
@@ -24,55 +38,32 @@ module Tilt
24
38
  raise err
25
39
  end
26
40
  end
27
- end
28
-
29
- def prepare
30
- @engine = unless Engine.nil?
31
- Engine.new(data, sass_options)
32
- end
33
- end
34
-
35
- def evaluate(scope, locals, &block)
36
- @output ||= if @engine.nil?
37
- ::Sass.compile_string(data, **sass_embedded_options).css
38
- else
39
- @engine.render
40
- end
41
- end
42
41
 
43
- def allows_script?
44
- false
45
- end
46
-
47
- private
48
- def eval_file_url
49
- path = File.absolute_path(eval_file)
50
- path = '/' + path unless path.start_with?('/')
51
- ::URI::File.build([nil, ::URI::DEFAULT_PARSER.escape(path)]).to_s
52
- end
42
+ private
53
43
 
54
- def sass_embedded_options
55
- options.merge(:url => eval_file_url, :syntax => :indented)
56
- end
44
+ def _prepare_output
45
+ Engine.new(@data, sass_options).render
46
+ end
57
47
 
58
- def sass_options
59
- options.merge(:filename => eval_file, :line => line, :syntax => :sass)
48
+ def sass_options
49
+ @options[:filename] = eval_file
50
+ @options[:line] = @line
51
+ @options[:syntax] = :sass
52
+ @options
53
+ end
54
+ # :nocov:
60
55
  end
61
56
  end
62
57
 
63
- # Sass's new .scss type template implementation.
64
58
  class ScssTemplate < SassTemplate
65
59
  self.default_mime_type = 'text/css'
66
60
 
67
- private
68
- def sass_embedded_options
69
- options.merge(:url => eval_file_url, :syntax => :scss)
70
- end
61
+ private
71
62
 
72
63
  def sass_options
73
- options.merge(:filename => eval_file, :line => line, :syntax => :scss)
64
+ super
65
+ @options[:syntax] = :scss
66
+ @options
74
67
  end
75
68
  end
76
-
77
69
  end
78
-
data/lib/tilt/slim.rb ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+ require_relative 'template'
3
+ require 'slim'
4
+
5
+ Tilt::SlimTemplate = Slim::Template
data/lib/tilt/string.rb CHANGED
@@ -1,12 +1,14 @@
1
- require 'tilt/template'
1
+ # frozen_string_literal: true
2
+ require_relative 'template'
2
3
 
3
4
  module Tilt
4
5
  # The template source is evaluated as a Ruby string. The #{} interpolation
5
6
  # syntax can be used to generated dynamic output.
6
7
  class StringTemplate < Template
7
8
  def prepare
8
- hash = "TILT#{data.hash.abs}"
9
- @code = String.new("<<#{hash}.chomp\n#{data}\n#{hash}")
9
+ hash = "TILT#{@data.hash.abs}"
10
+ @freeze_string_literals = !!@options[:freeze]
11
+ @code = String.new("<<#{hash}.chomp\n#{@data}\n#{hash}")
10
12
  end
11
13
 
12
14
  def precompiled_template(locals)
@@ -17,5 +19,9 @@ module Tilt
17
19
  source, offset = super
18
20
  [source, offset + 1]
19
21
  end
22
+
23
+ def freeze_string_literals?
24
+ @freeze_string_literals
25
+ end
20
26
  end
21
27
  end
data/lib/tilt/template.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Tilt
2
3
  # @private
3
4
  module CompiledTemplates
@@ -40,12 +41,12 @@ module Tilt
40
41
  @metadata ||= {}
41
42
  end
42
43
 
43
- # @deprecated Use `.metadata[:mime_type]` instead.
44
+ # Use `.metadata[:mime_type]` instead.
44
45
  def default_mime_type
45
46
  metadata[:mime_type]
46
47
  end
47
48
 
48
- # @deprecated Use `.metadata[:mime_type] = val` instead.
49
+ # Use `.metadata[:mime_type] = val` instead.
49
50
  def default_mime_type=(value)
50
51
  metadata[:mime_type] = value
51
52
  end
@@ -57,33 +58,28 @@ module Tilt
57
58
  # a block is required.
58
59
  #
59
60
  # All arguments are optional.
60
- def initialize(file=nil, line=1, options={}, &block)
61
- @file, @line, @options = nil, 1, {}
61
+ def initialize(file=nil, line=nil, options=nil)
62
+ @file, @line, @options = nil, 1, nil
62
63
 
63
- [options, line, file].compact.each do |arg|
64
- case
65
- when arg.respond_to?(:to_str) ; @file = arg.to_str
66
- when arg.respond_to?(:to_int) ; @line = arg.to_int
67
- when arg.respond_to?(:to_hash) ; @options = arg.to_hash.dup
68
- when arg.respond_to?(:path) ; @file = arg.path
69
- when arg.respond_to?(:to_path) ; @file = arg.to_path
70
- else raise TypeError, "Can't load the template file. Pass a string with a path " +
71
- "or an object that responds to 'to_str', 'path' or 'to_path'"
72
- end
73
- end
64
+ process_arg(options)
65
+ process_arg(line)
66
+ process_arg(file)
74
67
 
75
- raise ArgumentError, "file or block required" if (@file || block).nil?
68
+ raise ArgumentError, "file or block required" unless @file || block_given?
76
69
 
77
- # used to hold compiled template methods
78
- @compiled_method = {}
70
+ @options ||= {}
71
+
72
+ set_compiled_method_cache
79
73
 
80
- # used on 1.9 to set the encoding if it is not set elsewhere (like a magic comment)
81
- # currently only used if template compiles to ruby
74
+ # Force the encoding of the input data
82
75
  @default_encoding = @options.delete :default_encoding
83
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
+
84
81
  # load template data and prepare (uses binread to avoid encoding issues)
85
- @reader = block || lambda { |t| read_template_file }
86
- @data = @reader.call(self)
82
+ @data = block_given? ? yield(self) : read_template_file
87
83
 
88
84
  if @data.respond_to?(:force_encoding)
89
85
  if default_encoding
@@ -102,28 +98,25 @@ module Tilt
102
98
  # Render the template in the given scope with the locals specified. If a
103
99
  # block is given, it is typically available within the template via
104
100
  # +yield+.
105
- def render(scope=nil, locals={}, &block)
106
- scope ||= Object.new
107
- current_template = Thread.current[:tilt_current_template]
108
- Thread.current[:tilt_current_template] = self
109
- evaluate(scope, locals || {}, &block)
110
- ensure
111
- Thread.current[:tilt_current_template] = current_template
101
+ def render(scope=nil, locals=nil, &block)
102
+ evaluate(scope || Object.new, locals || EMPTY_HASH, &block)
112
103
  end
113
104
 
114
105
  # The basename of the template file.
115
106
  def basename(suffix='')
116
- File.basename(file, suffix) if file
107
+ File.basename(@file, suffix) if @file
117
108
  end
118
109
 
119
110
  # The template file's basename with all extensions chomped off.
120
111
  def name
121
- basename.split('.', 2).first if basename
112
+ if bname = basename
113
+ bname.split('.', 2).first
114
+ end
122
115
  end
123
116
 
124
117
  # The filename used in backtraces to describe the template.
125
118
  def eval_file
126
- file || '(__TEMPLATE__)'
119
+ @file || '(__TEMPLATE__)'
127
120
  end
128
121
 
129
122
  # An empty Hash that the template engine can populate with various
@@ -147,6 +140,24 @@ module Tilt
147
140
  @compiled_path = path
148
141
  end
149
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
+
150
161
  protected
151
162
 
152
163
  # @!group For template implementations
@@ -157,13 +168,16 @@ module Tilt
157
168
  # encoding.
158
169
  attr_reader :default_encoding
159
170
 
171
+ def skip_compiled_encoding_detection?
172
+ @skip_compiled_encoding_detection
173
+ end
174
+
160
175
  # Do whatever preparation is necessary to setup the underlying template
161
176
  # engine. Called immediately after template data is loaded. Instance
162
177
  # variables set in this method are available when #evaluate is called.
163
178
  #
164
- # Subclasses must provide an implementation of this method.
179
+ # Empty by default as some subclasses do not need separate preparation.
165
180
  def prepare
166
- raise NotImplementedError
167
181
  end
168
182
 
169
183
  CLASS_METHOD = Kernel.instance_method(:class)
@@ -183,14 +197,18 @@ module Tilt
183
197
  when Object
184
198
  scope_class = Module === scope ? scope : scope.class
185
199
  else
200
+ # :nocov:
186
201
  scope_class = USE_BIND_CALL ? CLASS_METHOD.bind_call(scope) : CLASS_METHOD.bind(scope).call
202
+ # :nocov:
187
203
  end
188
204
  method = compiled_method(locals_keys, scope_class)
189
205
 
190
206
  if USE_BIND_CALL
191
207
  method.bind_call(scope, locals, &block)
208
+ # :nocov:
192
209
  else
193
210
  method.bind(scope).call(locals, &block)
211
+ # :nocov:
194
212
  end
195
213
  end
196
214
 
@@ -209,15 +227,19 @@ module Tilt
209
227
  postamble = precompiled_postamble(local_keys)
210
228
  source = String.new
211
229
 
212
- # Ensure that our generated source code has the same encoding as the
213
- # the source code generated by the template engine.
214
- if source.respond_to?(:force_encoding)
215
- 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}
216
234
 
217
- source.force_encoding(template_encoding)
218
- template.force_encoding(template_encoding)
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
219
240
  end
220
241
 
242
+ source.force_encoding(template.encoding)
221
243
  source << preamble << "\n" << template << "\n" << postamble
222
244
 
223
245
  [source, preamble.count("\n")+1]
@@ -245,30 +267,52 @@ module Tilt
245
267
 
246
268
  private
247
269
 
248
- def read_template_file
249
- data = File.open(file, 'rb') { |io| io.read }
250
- if data.respond_to?(:force_encoding)
251
- # Set it to the default external (without verifying)
252
- data.force_encoding(Encoding.default_external) if Encoding.default_external
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
253
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:
254
290
  data
255
291
  end
256
292
 
257
- # The compiled method for the locals keys provided.
258
- def compiled_method(locals_keys, scope_class=nil)
259
- LOCK.synchronize do
260
- @compiled_method[[scope_class, locals_keys]] ||= compile_template_method(locals_keys, scope_class)
261
- end
293
+ def set_compiled_method_cache
294
+ @compiled_method = {}
262
295
  end
263
296
 
264
297
  def local_extraction(local_keys)
265
- local_keys.map do |k|
298
+ assignments = local_keys.map do |k|
266
299
  if k.to_s =~ /\A[a-z_][a-zA-Z_0-9]*\z/
267
300
  "#{k} = locals[#{k.inspect}]"
268
301
  else
269
302
  raise "invalid locals key: #{k.inspect} (keys must be variable names)"
270
303
  end
271
- end.join("\n")
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")
272
316
  end
273
317
 
274
318
  def compile_template_method(local_keys, scope_class=nil)
@@ -277,10 +321,7 @@ module Tilt
277
321
 
278
322
  method_name = "__tilt_#{Thread.current.object_id.abs}"
279
323
  method_source = String.new
280
-
281
- if method_source.respond_to?(:force_encoding)
282
- method_source.force_encoding(source.encoding)
283
- end
324
+ method_source.force_encoding(source.encoding)
284
325
 
285
326
  if freeze_string_literals?
286
327
  method_source << "# frozen-string-literal: true\n"
@@ -293,11 +334,11 @@ module Tilt
293
334
  method_source << source
294
335
  method_source << "\nend;end;"
295
336
 
296
- bind_compiled_method(method_source, offset, scope_class, local_keys)
337
+ bind_compiled_method(method_source, offset, scope_class)
297
338
  unbind_compiled_method(method_name)
298
339
  end
299
340
 
300
- def bind_compiled_method(method_source, offset, scope_class, local_keys)
341
+ def bind_compiled_method(method_source, offset, scope_class)
301
342
  path = compiled_path
302
343
  if path && scope_class.name
303
344
  path = path.dup
@@ -310,7 +351,11 @@ module Tilt
310
351
  path << ".rb"
311
352
 
312
353
  # Wrap method source in a class block for the scope, so constant lookup works
313
- method_source = "class #{scope_class.name}\n#{method_source}\nend"
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"
314
359
 
315
360
  load_compiled_method(path, method_source)
316
361
  else
@@ -340,11 +385,16 @@ module Tilt
340
385
  method
341
386
  end
342
387
 
343
- def extract_encoding(script)
344
- extract_magic_comment(script) || script.encoding
388
+ def extract_encoding(script, &block)
389
+ extract_magic_comment(script, &block) || script.encoding
345
390
  end
346
391
 
347
392
  def extract_magic_comment(script)
393
+ if script.frozen?
394
+ script = script.dup
395
+ yield script
396
+ end
397
+
348
398
  binary(script) do
349
399
  script[/\A[ \t]*\#.*coding\s*[=:]\s*([[:alnum:]\-_]+).*$/n, 1]
350
400
  end
@@ -362,4 +412,44 @@ module Tilt
362
412
  string.force_encoding(original_encoding)
363
413
  end
364
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
365
455
  end
@@ -1,26 +1,19 @@
1
- require 'tilt/template'
1
+ # frozen_string_literal: true
2
+ require_relative 'template'
2
3
  require 'typescript-node'
3
4
 
4
- module Tilt
5
- class TypeScriptTemplate < Template
6
- self.default_mime_type = 'application/javascript'
5
+ Tilt::TypeScriptTemplate = Tilt::StaticTemplate.subclass(mime_type: 'application/javascript') do
6
+ option_args = []
7
7
 
8
- def prepare
9
- @option_args = []
8
+ @options.each do |key, value|
9
+ next unless value
10
10
 
11
- options.each do |key, value|
12
- next unless value
11
+ option_args << "--#{key}"
13
12
 
14
- @option_args << "--#{key}"
15
-
16
- if value != true
17
- @option_args << value.to_s
18
- end
19
- end
20
- end
21
-
22
- def evaluate(scope, locals, &block)
23
- @output ||= TypeScript::Node.compile(data, *@option_args)
13
+ if value != true
14
+ option_args << value.to_s
24
15
  end
25
16
  end
17
+
18
+ TypeScript::Node.compile(@data, *option_args)
26
19
  end
@@ -1,22 +1,10 @@
1
- require 'tilt/template'
1
+ # frozen_string_literal: true
2
+ require_relative 'template'
2
3
  require 'wikicloth'
3
4
 
4
- module Tilt
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
13
-
14
- def evaluate(scope, locals, &block)
15
- @output ||= @engine.to_html
16
- end
17
-
18
- def allows_script?
19
- false
20
- end
21
- end
5
+ # WikiCloth implementation. See: https://github.com/nricciar/wikicloth
6
+ Tilt::WikiClothTemplate = Tilt::StaticTemplate.subclass do
7
+ parser = @options.delete(:parser) || WikiCloth::Parser
8
+ @options[:data] = @data
9
+ parser.new(@options).to_html
22
10
  end
data/lib/tilt/yajl.rb CHANGED
@@ -1,8 +1,8 @@
1
- require 'tilt/template'
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 super(scope, locals, &block)
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