tilt 1.4.1 → 2.0.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 (72) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +17 -0
  3. data/Gemfile +33 -26
  4. data/README.md +23 -49
  5. data/Rakefile +21 -30
  6. data/{TEMPLATES.md → docs/TEMPLATES.md} +11 -4
  7. data/docs/common.css +14 -0
  8. data/lib/tilt/asciidoc.rb +1 -8
  9. data/lib/tilt/bluecloth.rb +24 -0
  10. data/lib/tilt/builder.rb +1 -8
  11. data/lib/tilt/coffee.rb +1 -8
  12. data/lib/tilt/creole.rb +25 -0
  13. data/lib/tilt/csv.rb +7 -13
  14. data/lib/tilt/erb.rb +2 -55
  15. data/lib/tilt/erubis.rb +43 -0
  16. data/lib/tilt/haml.rb +1 -8
  17. data/lib/tilt/kramdown.rb +33 -0
  18. data/lib/tilt/less.rb +38 -0
  19. data/lib/tilt/liquid.rb +1 -8
  20. data/lib/tilt/mapping.rb +265 -0
  21. data/lib/tilt/markaby.rb +1 -8
  22. data/lib/tilt/maruku.rb +22 -0
  23. data/lib/tilt/nokogiri.rb +1 -8
  24. data/lib/tilt/radius.rb +1 -8
  25. data/lib/tilt/rdiscount.rb +39 -0
  26. data/lib/tilt/rdoc.rb +3 -10
  27. data/lib/tilt/redcarpet.rb +104 -0
  28. data/lib/tilt/{textile.rb → redcloth.rb} +1 -8
  29. data/lib/tilt/sass.rb +41 -0
  30. data/lib/tilt/template.rb +88 -93
  31. data/lib/tilt/wikicloth.rb +22 -0
  32. data/lib/tilt/yajl.rb +1 -8
  33. data/lib/tilt.rb +87 -154
  34. data/test/{contest.rb → test_helper.rb} +7 -11
  35. data/test/tilt_asciidoctor_test.rb +6 -6
  36. data/test/tilt_blueclothtemplate_test.rb +3 -15
  37. data/test/tilt_buildertemplate_test.rb +3 -3
  38. data/test/tilt_cache_test.rb +2 -2
  39. data/test/tilt_coffeescripttemplate_test.rb +8 -18
  40. data/test/tilt_compilesite_test.rb +2 -2
  41. data/test/tilt_creoletemplate_test.rb +3 -7
  42. data/test/tilt_csv_test.rb +5 -9
  43. data/test/tilt_erbtemplate_test.rb +7 -7
  44. data/test/tilt_erubistemplate_test.rb +7 -7
  45. data/test/tilt_etannitemplate_test.rb +4 -3
  46. data/test/tilt_hamltemplate_test.rb +4 -4
  47. data/test/tilt_kramdown_test.rb +5 -27
  48. data/test/tilt_lesstemplate_test.rb +3 -3
  49. data/test/tilt_liquidtemplate_test.rb +3 -3
  50. data/test/tilt_mapping_test.rb +229 -0
  51. data/test/tilt_markaby_test.rb +4 -4
  52. data/test/tilt_markdown_test.rb +23 -21
  53. data/test/tilt_marukutemplate_test.rb +9 -21
  54. data/test/tilt_metadata_test.rb +42 -0
  55. data/test/tilt_nokogiritemplate_test.rb +3 -3
  56. data/test/tilt_radiustemplate_test.rb +3 -3
  57. data/test/tilt_rdiscounttemplate_test.rb +7 -19
  58. data/test/tilt_rdoctemplate_test.rb +3 -5
  59. data/test/tilt_redcarpettemplate_test.rb +11 -23
  60. data/test/tilt_redclothtemplate_test.rb +3 -3
  61. data/test/tilt_sasstemplate_test.rb +4 -4
  62. data/test/tilt_stringtemplate_test.rb +4 -3
  63. data/test/tilt_template_test.rb +42 -49
  64. data/test/tilt_test.rb +10 -15
  65. data/test/tilt_wikiclothtemplate_test.rb +3 -3
  66. data/test/tilt_yajltemplate_test.rb +3 -3
  67. data/tilt.gemspec +19 -32
  68. metadata +26 -385
  69. data/lib/tilt/css.rb +0 -80
  70. data/lib/tilt/markdown.rb +0 -214
  71. data/lib/tilt/wiki.rb +0 -58
  72. data/test/tilt_fallback_test.rb +0 -122
@@ -0,0 +1,33 @@
1
+ require 'tilt/template'
2
+ require 'kramdown'
3
+
4
+ module Tilt
5
+ # Kramdown Markdown implementation. See:
6
+ # http://kramdown.rubyforge.org/
7
+ class KramdownTemplate < Template
8
+ DUMB_QUOTES = [39, 39, 34, 34]
9
+
10
+ def self.engine_initialized?
11
+ defined? ::Kramdown
12
+ end
13
+
14
+ def initialize_engine
15
+ require_template_library 'kramdown'
16
+ end
17
+
18
+ def prepare
19
+ options[:smart_quotes] = DUMB_QUOTES unless options[:smartypants]
20
+ @engine = Kramdown::Document.new(data, options)
21
+ @output = nil
22
+ end
23
+
24
+ def evaluate(scope, locals, &block)
25
+ @output ||= @engine.to_html
26
+ end
27
+
28
+ def allows_script?
29
+ false
30
+ end
31
+ end
32
+ end
33
+
data/lib/tilt/less.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'tilt/template'
2
+ require 'less'
3
+
4
+ module Tilt
5
+ # Lessscss template implementation. See:
6
+ # http://lesscss.org/
7
+ #
8
+ # Less templates do not support object scopes, locals, or yield.
9
+ class LessTemplate < Template
10
+ self.default_mime_type = 'text/css'
11
+
12
+ def self.engine_initialized?
13
+ defined? ::Less
14
+ end
15
+
16
+ def initialize_engine
17
+ require_template_library 'less'
18
+ end
19
+
20
+ def prepare
21
+ if ::Less.const_defined? :Engine
22
+ @engine = ::Less::Engine.new(data)
23
+ else
24
+ parser = ::Less::Parser.new(options.merge :filename => eval_file, :line => line)
25
+ @engine = parser.parse(data)
26
+ end
27
+ end
28
+
29
+ def evaluate(scope, locals, &block)
30
+ @output ||= @engine.to_css(options)
31
+ end
32
+
33
+ def allows_script?
34
+ false
35
+ end
36
+ end
37
+ end
38
+
data/lib/tilt/liquid.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'tilt/template'
2
+ require 'liquid'
2
3
 
3
4
  module Tilt
4
5
  # Liquid template implementation. See:
@@ -15,14 +16,6 @@ module Tilt
15
16
  # It's suggested that your program require 'liquid' at load
16
17
  # time when using this template engine.
17
18
  class LiquidTemplate < Template
18
- def self.engine_initialized?
19
- defined? ::Liquid::Template
20
- end
21
-
22
- def initialize_engine
23
- require_template_library 'liquid'
24
- end
25
-
26
19
  def prepare
27
20
  @engine = ::Liquid::Template.parse(data)
28
21
  end
@@ -0,0 +1,265 @@
1
+ module Tilt
2
+ # Tilt::Mapping associates file extensions with template implementations.
3
+ #
4
+ # mapping = Tilt::Mapping.new
5
+ # mapping.register(Tilt::RDocTemplate, 'rdoc')
6
+ # mapping['index.rdoc'] # => Tilt::RDocTemplate
7
+ # mapping.new('index.rdoc').render
8
+ #
9
+ # You can use {#register} to register a template class by file
10
+ # extension, {#registered?} to see if a file extension is mapped,
11
+ # {#[]} to lookup template classes, and {#new} to instantiate template
12
+ # objects.
13
+ #
14
+ # Mapping also supports *lazy* template implementations. Note that regularly
15
+ # registered template implementations *always* have preference over lazily
16
+ # registered template implementations. You should use {#register} if you
17
+ # depend on a specific template implementation and {#register_lazy} if there
18
+ # are multiple alternatives.
19
+ #
20
+ # mapping = Tilt::Mapping.new
21
+ # mapping.register_lazy('RDiscount::Template', 'rdiscount/template', 'md')
22
+ # mapping['index.md']
23
+ # # => RDiscount::Template
24
+ #
25
+ # {#register_lazy} takes a class name, a filename, and a list of file
26
+ # extensions. When you try to lookup a template name that matches the
27
+ # file extension, Tilt will automatically try to require the filename and
28
+ # constantize the class name.
29
+ #
30
+ # Unlike {#register}, there can be multiple template implementations
31
+ # registered lazily to the same file extension. Tilt will attempt to load the
32
+ # template implementations in order (registered *last* would be tried first),
33
+ # returning the first which doesn't raise LoadError.
34
+ #
35
+ # If all of the registered template implementations fails, Tilt will raise
36
+ # the exception of the first, since that was the most preferred one.
37
+ #
38
+ # mapping = Tilt::Mapping.new
39
+ # mapping.register_lazy('Bluecloth::Template', 'bluecloth/template', 'md')
40
+ # mapping.register_lazy('RDiscount::Template', 'rdiscount/template', 'md')
41
+ # mapping['index.md']
42
+ # # => RDiscount::Template
43
+ #
44
+ # In the previous example we say that RDiscount has a *higher priority* than
45
+ # BlueCloth. Tilt will first try to `require "rdiscount/template"`, falling
46
+ # back to `require "bluecloth/template"`. If none of these are successful,
47
+ # the first error will be raised.
48
+ class Mapping
49
+ # @private
50
+ attr_reader :lazy_map, :template_map
51
+
52
+ def initialize
53
+ @template_map = Hash.new
54
+ @lazy_map = Hash.new { |h, k| h[k] = [] }
55
+ end
56
+
57
+ # @private
58
+ def initialize_copy(other)
59
+ @template_map = other.template_map.dup
60
+ @lazy_map = other.lazy_map.dup
61
+ end
62
+
63
+ # Registrers a lazy template implementation by file extension. You
64
+ # can have multiple lazy template implementations defined on the
65
+ # same file extension, in which case the template implementation
66
+ # defined *last* will be attempted loaded *first*.
67
+ #
68
+ # @param class_name [String] Class name of a template class.
69
+ # @param file [String] Filename where the template class is defined.
70
+ # @param extensions [Array<String>] List of extensions.
71
+ # @return [void]
72
+ #
73
+ # @example
74
+ # mapping.register_lazy 'MyEngine::Template', 'my_engine/template', 'mt'
75
+ #
76
+ # defined?(MyEngine::Template) # => false
77
+ # mapping['index.mt'] # => MyEngine::Template
78
+ # defined?(MyEngine::Template) # => true
79
+ def register_lazy(class_name, file, *extensions)
80
+ # Internal API
81
+ if class_name.is_a?(Symbol)
82
+ Tilt.autoload class_name, file
83
+ class_name = "Tilt::#{class_name}"
84
+ end
85
+
86
+ extensions.each do |ext|
87
+ @lazy_map[ext].unshift([class_name, file])
88
+ end
89
+ end
90
+
91
+ # Registers a template implementation by file extension. There can only be
92
+ # one template implementation per file extension, and this method will
93
+ # override any existing mapping.
94
+ #
95
+ # @param template_class
96
+ # @param extensions [Array<String>] List of extensions.
97
+ # @return [void]
98
+ #
99
+ # @example
100
+ # mapping.register MyEngine::Template, 'mt'
101
+ # mapping['index.mt'] # => MyEngine::Template
102
+ def register(template_class, *extensions)
103
+ if template_class.respond_to?(:to_str)
104
+ # Support register(ext, template_class) too
105
+ extensions, template_class = [template_class], extensions[0]
106
+ end
107
+
108
+ extensions.each do |ext|
109
+ @template_map[ext.to_s] = template_class
110
+ end
111
+ end
112
+
113
+ # Checks if a file extension is registered (either eagerly or
114
+ # lazily) in this mapping.
115
+ #
116
+ # @param ext [String] File extension.
117
+ #
118
+ # @example
119
+ # mapping.registered?('erb') # => true
120
+ # mapping.registered?('nope') # => false
121
+ def registered?(ext)
122
+ @template_map.has_key?(ext.downcase) or lazy?(ext)
123
+ end
124
+
125
+ # Instantiates a new template class based on the file.
126
+ #
127
+ # @raise [RuntimeError] if there is no template class registered for the
128
+ # file name.
129
+ #
130
+ # @example
131
+ # mapping.new('index.mt') # => instance of MyEngine::Template
132
+ #
133
+ # @see Tilt::Template.new
134
+ def new(file, line=nil, options={}, &block)
135
+ if template_class = self[file]
136
+ template_class.new(file, line, options, &block)
137
+ else
138
+ fail "No template engine registered for #{File.basename(file)}"
139
+ end
140
+ end
141
+
142
+ # Looks up a template class based on file name and/or extension.
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)
153
+ end
154
+
155
+ alias template_for []
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.
160
+ #
161
+ # @example
162
+ # mapping.templates_for('views/index.haml.erb')
163
+ # # => [Tilt::ERBTemplate, Tilt::HamlTemplate]
164
+ #
165
+ # @return [Array<template class>]
166
+ def templates_for(file)
167
+ templates = []
168
+
169
+ while true
170
+ prefix, ext = split(file)
171
+ break unless ext
172
+ templates << lookup(ext)
173
+ file = prefix
174
+ end
175
+
176
+ templates
177
+ end
178
+
179
+ # Finds the extensions the template class has been registered under.
180
+ # @param [template class] template_class
181
+ def extensions_for(template_class)
182
+ res = []
183
+ template_map.each do |ext, klass|
184
+ res << ext if template_class == klass
185
+ end
186
+ lazy_map.each do |ext, choices|
187
+ res << ext if choices.any? { |klass, file| template_class.to_s == klass }
188
+ end
189
+ res
190
+ end
191
+
192
+ private
193
+
194
+ def lazy?(ext)
195
+ 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]
211
+ end
212
+
213
+ def lookup(ext)
214
+ @template_map[ext] || lazy_load(ext)
215
+ end
216
+
217
+ def lazy_load(pattern)
218
+ return unless @lazy_map.has_key?(pattern)
219
+
220
+ choices = @lazy_map[pattern]
221
+
222
+ # Check if a template class is already present
223
+ choices.each do |class_name, file|
224
+ template_class = constant_defined?(class_name)
225
+ if template_class
226
+ register(template_class, pattern)
227
+ return template_class
228
+ end
229
+ end
230
+
231
+ first_failure = nil
232
+
233
+ # Load in order
234
+ choices.each do |class_name, file|
235
+ begin
236
+ 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
+ # It's safe to eval() here because constant_defined? will
244
+ # raise NameError on invalid constant names
245
+ template_class = eval(class_name)
246
+ rescue LoadError => ex
247
+ first_failure ||= ex
248
+ else
249
+ register(template_class, pattern)
250
+ return template_class
251
+ end
252
+ end
253
+
254
+ raise first_failure if first_failure
255
+ end
256
+
257
+ def constant_defined?(name)
258
+ name.split('::').inject(Object) do |scope, n|
259
+ return false unless scope.const_defined?(n)
260
+ return false if scope.autoload?(n) # skip autload
261
+ scope.const_get(n)
262
+ end
263
+ end
264
+ end
265
+ end
data/lib/tilt/markaby.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'tilt/template'
2
+ require 'markaby'
2
3
 
3
4
  module Tilt
4
5
  # Markaby
@@ -14,14 +15,6 @@ module Tilt
14
15
  end
15
16
  end
16
17
 
17
- def self.engine_initialized?
18
- defined? ::Markaby
19
- end
20
-
21
- def initialize_engine
22
- require_template_library 'markaby'
23
- end
24
-
25
18
  def prepare
26
19
  end
27
20
 
@@ -0,0 +1,22 @@
1
+ require 'tilt/template'
2
+ require 'maruku'
3
+
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
12
+
13
+ def evaluate(scope, locals, &block)
14
+ @output ||= @engine.to_html
15
+ end
16
+
17
+ def allows_script?
18
+ false
19
+ end
20
+ end
21
+ end
22
+
data/lib/tilt/nokogiri.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'tilt/template'
2
+ require 'nokogiri'
2
3
 
3
4
  module Tilt
4
5
  # Nokogiri template implementation. See:
@@ -7,14 +8,6 @@ module Tilt
7
8
  DOCUMENT_HEADER = /^<\?xml version=\"1\.0\"\?>\n?/
8
9
  self.default_mime_type = 'text/xml'
9
10
 
10
- def self.engine_initialized?
11
- defined? ::Nokogiri
12
- end
13
-
14
- def initialize_engine
15
- require_template_library 'nokogiri'
16
- end
17
-
18
11
  def prepare; end
19
12
 
20
13
  def evaluate(scope, locals)
data/lib/tilt/radius.rb CHANGED
@@ -1,13 +1,10 @@
1
1
  require 'tilt/template'
2
+ require 'radius'
2
3
 
3
4
  module Tilt
4
5
  # Radius Template
5
6
  # http://github.com/jlong/radius/
6
7
  class RadiusTemplate < Template
7
- def self.engine_initialized?
8
- defined? ::Radius
9
- end
10
-
11
8
  def self.context_class
12
9
  @context_class ||= Class.new(Radius::Context) do
13
10
  attr_accessor :tilt_scope
@@ -24,10 +21,6 @@ module Tilt
24
21
  end
25
22
  end
26
23
 
27
- def initialize_engine
28
- require_template_library 'radius'
29
- end
30
-
31
24
  def prepare
32
25
  end
33
26
 
@@ -0,0 +1,39 @@
1
+ require 'tilt/template'
2
+ require 'rdiscount'
3
+
4
+ module Tilt
5
+ # Discount Markdown implementation. See:
6
+ # http://github.com/rtomayko/rdiscount
7
+ #
8
+ # RDiscount is a simple text filter. It does not support +scope+ or
9
+ # +locals+. The +:smart+ and +:filter_html+ options may be set true
10
+ # to enable those flags on the underlying RDiscount object.
11
+ class RDiscountTemplate < Template
12
+ self.default_mime_type = 'text/html'
13
+
14
+ ALIAS = {
15
+ :escape_html => :filter_html,
16
+ :smartypants => :smart
17
+ }
18
+
19
+ FLAGS = [:smart, :filter_html, :smartypants, :escape_html]
20
+
21
+ def flags
22
+ FLAGS.select { |flag| options[flag] }.map { |flag| ALIAS[flag] || flag }
23
+ end
24
+
25
+ def prepare
26
+ @engine = RDiscount.new(data, *flags)
27
+ @output = nil
28
+ end
29
+
30
+ def evaluate(scope, locals, &block)
31
+ @output ||= @engine.to_html
32
+ end
33
+
34
+ def allows_script?
35
+ false
36
+ end
37
+ end
38
+ end
39
+
data/lib/tilt/rdoc.rb CHANGED
@@ -1,4 +1,7 @@
1
1
  require 'tilt/template'
2
+ require 'rdoc'
3
+ require 'rdoc/markup'
4
+ require 'rdoc/markup/to_html'
2
5
 
3
6
  module Tilt
4
7
  # RDoc template. See:
@@ -10,16 +13,6 @@ module Tilt
10
13
  class RDocTemplate < Template
11
14
  self.default_mime_type = 'text/html'
12
15
 
13
- def self.engine_initialized?
14
- defined? ::RDoc::Markup::ToHtml
15
- end
16
-
17
- def initialize_engine
18
- require_template_library 'rdoc'
19
- require_template_library 'rdoc/markup'
20
- require_template_library 'rdoc/markup/to_html'
21
- end
22
-
23
16
  def markup
24
17
  begin
25
18
  # RDoc 4.0
@@ -0,0 +1,104 @@
1
+ require 'tilt/template'
2
+ require 'redcarpet'
3
+
4
+ module Tilt
5
+ # Compatibility mode for Redcarpet 1.x
6
+ class Redcarpet1Template < Template
7
+ self.default_mime_type = 'text/html'
8
+
9
+ ALIAS = {
10
+ :escape_html => :filter_html,
11
+ :smartypants => :smart
12
+ }
13
+
14
+ FLAGS = [:smart, :filter_html, :smartypants, :escape_html]
15
+
16
+ def flags
17
+ FLAGS.select { |flag| options[flag] }.map { |flag| ALIAS[flag] || flag }
18
+ end
19
+
20
+ def prepare
21
+ @engine = RedcarpetCompat.new(data, *flags)
22
+ @output = nil
23
+ end
24
+
25
+ def evaluate(scope, locals, &block)
26
+ @output ||= @engine.to_html
27
+ end
28
+
29
+ def allows_script?
30
+ false
31
+ end
32
+ end
33
+
34
+ # Future proof mode for Redcarpet 2.x (not yet released)
35
+ class Redcarpet2Template < Template
36
+ self.default_mime_type = 'text/html'
37
+
38
+ def self.engine_initialized?
39
+ defined? ::Redcarpet::Render and defined? ::Redcarpet::Markdown
40
+ end
41
+
42
+ def generate_renderer
43
+ renderer = options.delete(:renderer) || ::Redcarpet::Render::HTML
44
+ return renderer unless options.delete(:smartypants)
45
+ return renderer if renderer.is_a?(Class) && renderer <= ::Redcarpet::Render::SmartyPants
46
+
47
+ if renderer == ::Redcarpet::Render::XHTML
48
+ ::Redcarpet::Render::SmartyHTML.new(:xhtml => true)
49
+ elsif renderer == ::Redcarpet::Render::HTML
50
+ ::Redcarpet::Render::SmartyHTML
51
+ elsif renderer.is_a? Class
52
+ Class.new(renderer) { include ::Redcarpet::Render::SmartyPants }
53
+ else
54
+ renderer.extend ::Redcarpet::Render::SmartyPants
55
+ end
56
+ end
57
+
58
+ def prepare
59
+ # try to support the same aliases
60
+ Redcarpet1Template::ALIAS.each do |opt, aka|
61
+ next if options.key? opt or not options.key? aka
62
+ options[opt] = options.delete(aka)
63
+ end
64
+
65
+ # only raise an exception if someone is trying to enable :escape_html
66
+ options.delete(:escape_html) unless options[:escape_html]
67
+
68
+ @engine = ::Redcarpet::Markdown.new(generate_renderer, options)
69
+ @output = nil
70
+ end
71
+
72
+ def evaluate(scope, locals, &block)
73
+ @output ||= @engine.render(data)
74
+ end
75
+
76
+ def allows_script?
77
+ false
78
+ end
79
+ end
80
+
81
+ # Upskirt Markdown implementation. See:
82
+ # https://github.com/tanoku/redcarpet
83
+ #
84
+ # Supports both Redcarpet 1.x and 2.x
85
+ class RedcarpetTemplate < Template
86
+ Redcarpet1 = Redcarpet1Template
87
+ Redcarpet2 = Redcarpet2Template
88
+
89
+ def prepare
90
+ klass = Redcarpet2.engine_initialized? ? Redcarpet2 : Redcarpet1
91
+ @engine = klass.new(file, line, options) { data }
92
+ end
93
+
94
+ def evaluate(scope, locals, &block)
95
+ @engine.evaluate(scope, locals, &block)
96
+ end
97
+
98
+ def allows_script?
99
+ false
100
+ end
101
+ end
102
+
103
+ end
104
+
@@ -1,17 +1,10 @@
1
1
  require 'tilt/template'
2
+ require 'redcloth'
2
3
 
3
4
  module Tilt
4
5
  # RedCloth implementation. See:
5
6
  # http://redcloth.org/
6
7
  class RedClothTemplate < Template
7
- def self.engine_initialized?
8
- defined? ::RedCloth
9
- end
10
-
11
- def initialize_engine
12
- require_template_library 'redcloth'
13
- end
14
-
15
8
  def prepare
16
9
  @engine = RedCloth.new(data)
17
10
  options.each {|k, v| @engine.send("#{k}=", v) if @engine.respond_to? "#{k}="}
data/lib/tilt/sass.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'tilt/template'
2
+ require 'sass'
3
+
4
+ module Tilt
5
+ # Sass template implementation. See:
6
+ # http://haml.hamptoncatlin.com/
7
+ #
8
+ # Sass templates do not support object scopes, locals, or yield.
9
+ class SassTemplate < Template
10
+ self.default_mime_type = 'text/css'
11
+
12
+ def prepare
13
+ @engine = ::Sass::Engine.new(data, sass_options)
14
+ end
15
+
16
+ def evaluate(scope, locals, &block)
17
+ @output ||= @engine.render
18
+ end
19
+
20
+ def allows_script?
21
+ false
22
+ end
23
+
24
+ private
25
+ def sass_options
26
+ options.merge(:filename => eval_file, :line => line, :syntax => :sass)
27
+ end
28
+ end
29
+
30
+ # Sass's new .scss type template implementation.
31
+ class ScssTemplate < SassTemplate
32
+ self.default_mime_type = 'text/css'
33
+
34
+ private
35
+ def sass_options
36
+ options.merge(:filename => eval_file, :line => line, :syntax => :scss)
37
+ end
38
+ end
39
+
40
+ end
41
+