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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +17 -0
- data/Gemfile +33 -26
- data/README.md +23 -49
- data/Rakefile +21 -30
- data/{TEMPLATES.md → docs/TEMPLATES.md} +11 -4
- data/docs/common.css +14 -0
- data/lib/tilt/asciidoc.rb +1 -8
- data/lib/tilt/bluecloth.rb +24 -0
- data/lib/tilt/builder.rb +1 -8
- data/lib/tilt/coffee.rb +1 -8
- data/lib/tilt/creole.rb +25 -0
- data/lib/tilt/csv.rb +7 -13
- data/lib/tilt/erb.rb +2 -55
- data/lib/tilt/erubis.rb +43 -0
- data/lib/tilt/haml.rb +1 -8
- data/lib/tilt/kramdown.rb +33 -0
- data/lib/tilt/less.rb +38 -0
- data/lib/tilt/liquid.rb +1 -8
- data/lib/tilt/mapping.rb +265 -0
- data/lib/tilt/markaby.rb +1 -8
- data/lib/tilt/maruku.rb +22 -0
- data/lib/tilt/nokogiri.rb +1 -8
- data/lib/tilt/radius.rb +1 -8
- data/lib/tilt/rdiscount.rb +39 -0
- data/lib/tilt/rdoc.rb +3 -10
- data/lib/tilt/redcarpet.rb +104 -0
- data/lib/tilt/{textile.rb → redcloth.rb} +1 -8
- data/lib/tilt/sass.rb +41 -0
- data/lib/tilt/template.rb +88 -93
- data/lib/tilt/wikicloth.rb +22 -0
- data/lib/tilt/yajl.rb +1 -8
- data/lib/tilt.rb +87 -154
- data/test/{contest.rb → test_helper.rb} +7 -11
- data/test/tilt_asciidoctor_test.rb +6 -6
- data/test/tilt_blueclothtemplate_test.rb +3 -15
- data/test/tilt_buildertemplate_test.rb +3 -3
- data/test/tilt_cache_test.rb +2 -2
- data/test/tilt_coffeescripttemplate_test.rb +8 -18
- data/test/tilt_compilesite_test.rb +2 -2
- data/test/tilt_creoletemplate_test.rb +3 -7
- data/test/tilt_csv_test.rb +5 -9
- data/test/tilt_erbtemplate_test.rb +7 -7
- data/test/tilt_erubistemplate_test.rb +7 -7
- data/test/tilt_etannitemplate_test.rb +4 -3
- data/test/tilt_hamltemplate_test.rb +4 -4
- data/test/tilt_kramdown_test.rb +5 -27
- data/test/tilt_lesstemplate_test.rb +3 -3
- data/test/tilt_liquidtemplate_test.rb +3 -3
- data/test/tilt_mapping_test.rb +229 -0
- data/test/tilt_markaby_test.rb +4 -4
- data/test/tilt_markdown_test.rb +23 -21
- data/test/tilt_marukutemplate_test.rb +9 -21
- data/test/tilt_metadata_test.rb +42 -0
- data/test/tilt_nokogiritemplate_test.rb +3 -3
- data/test/tilt_radiustemplate_test.rb +3 -3
- data/test/tilt_rdiscounttemplate_test.rb +7 -19
- data/test/tilt_rdoctemplate_test.rb +3 -5
- data/test/tilt_redcarpettemplate_test.rb +11 -23
- data/test/tilt_redclothtemplate_test.rb +3 -3
- data/test/tilt_sasstemplate_test.rb +4 -4
- data/test/tilt_stringtemplate_test.rb +4 -3
- data/test/tilt_template_test.rb +42 -49
- data/test/tilt_test.rb +10 -15
- data/test/tilt_wikiclothtemplate_test.rb +3 -3
- data/test/tilt_yajltemplate_test.rb +3 -3
- data/tilt.gemspec +19 -32
- metadata +26 -385
- data/lib/tilt/css.rb +0 -80
- data/lib/tilt/markdown.rb +0 -214
- data/lib/tilt/wiki.rb +0 -58
- 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
|
data/lib/tilt/mapping.rb
ADDED
@@ -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
|
|
data/lib/tilt/maruku.rb
ADDED
@@ -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
|
+
|