tilt 1.4.1 → 2.0.11
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/COPYING +1 -1
- data/bin/tilt +18 -8
- data/lib/tilt/asciidoc.rb +1 -8
- data/lib/tilt/babel.rb +16 -0
- data/lib/tilt/bluecloth.rb +24 -0
- data/lib/tilt/builder.rb +12 -15
- data/lib/tilt/coffee.rb +10 -6
- data/lib/tilt/commonmarker.rb +88 -0
- data/lib/tilt/creole.rb +25 -0
- data/lib/tilt/csv.rb +12 -18
- data/lib/tilt/dummy.rb +3 -0
- data/lib/tilt/erb.rb +9 -56
- data/lib/tilt/erubi.rb +32 -0
- data/lib/tilt/erubis.rb +43 -0
- data/lib/tilt/haml.rb +66 -44
- data/lib/tilt/kramdown.rb +25 -0
- data/lib/tilt/less.rb +30 -0
- data/lib/tilt/liquid.rb +9 -10
- data/lib/tilt/livescript.rb +23 -0
- data/lib/tilt/mapping.rb +293 -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/pandoc.rb +57 -0
- data/lib/tilt/plain.rb +0 -4
- data/lib/tilt/prawn.rb +43 -0
- 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 +86 -0
- data/lib/tilt/{textile.rb → redcloth.rb} +1 -8
- data/lib/tilt/rst-pandoc.rb +23 -0
- data/lib/tilt/sass.rb +78 -0
- data/lib/tilt/sigil.rb +34 -0
- data/lib/tilt/string.rb +1 -1
- data/lib/tilt/template.rb +121 -105
- data/lib/tilt/typescript.rb +26 -0
- data/lib/tilt/wikicloth.rb +22 -0
- data/lib/tilt/yajl.rb +1 -8
- data/lib/tilt.rb +118 -155
- metadata +38 -469
- data/CHANGELOG.md +0 -44
- data/Gemfile +0 -32
- data/HACKING +0 -16
- data/README.md +0 -232
- data/Rakefile +0 -104
- data/TEMPLATES.md +0 -516
- data/lib/tilt/css.rb +0 -80
- data/lib/tilt/markdown.rb +0 -214
- data/lib/tilt/wiki.rb +0 -58
- data/test/contest.rb +0 -68
- 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/tilt_asciidoctor_test.rb +0 -44
- data/test/tilt_blueclothtemplate_test.rb +0 -45
- data/test/tilt_buildertemplate_test.rb +0 -59
- data/test/tilt_cache_test.rb +0 -32
- data/test/tilt_coffeescripttemplate_test.rb +0 -114
- data/test/tilt_compilesite_test.rb +0 -51
- data/test/tilt_creoletemplate_test.rb +0 -28
- data/test/tilt_csv_test.rb +0 -69
- data/test/tilt_erbtemplate_test.rb +0 -239
- data/test/tilt_erubistemplate_test.rb +0 -151
- data/test/tilt_etannitemplate_test.rb +0 -173
- data/test/tilt_fallback_test.rb +0 -122
- data/test/tilt_hamltemplate_test.rb +0 -144
- data/test/tilt_kramdown_test.rb +0 -42
- 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_markaby_test.rb +0 -88
- data/test/tilt_markdown_test.rb +0 -172
- data/test/tilt_marukutemplate_test.rb +0 -48
- data/test/tilt_nokogiritemplate_test.rb +0 -87
- data/test/tilt_radiustemplate_test.rb +0 -75
- data/test/tilt_rdiscounttemplate_test.rb +0 -55
- data/test/tilt_rdoctemplate_test.rb +0 -31
- data/test/tilt_redcarpettemplate_test.rb +0 -71
- data/test/tilt_redclothtemplate_test.rb +0 -36
- data/test/tilt_sasstemplate_test.rb +0 -41
- data/test/tilt_stringtemplate_test.rb +0 -170
- data/test/tilt_template_test.rb +0 -323
- data/test/tilt_test.rb +0 -65
- data/test/tilt_wikiclothtemplate_test.rb +0 -32
- data/test/tilt_yajltemplate_test.rb +0 -101
- data/tilt.gemspec +0 -120
data/lib/tilt/haml.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'tilt/template'
|
2
|
+
require 'haml'
|
2
3
|
|
3
4
|
module Tilt
|
4
5
|
# Haml template implementation. See:
|
@@ -6,59 +7,80 @@ module Tilt
|
|
6
7
|
class HamlTemplate < Template
|
7
8
|
self.default_mime_type = 'text/html'
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
10
|
+
# `Gem::Version.correct?` may return false because of Haml::VERSION #=> "3.1.8 (Separated Sally)". After Haml 4, it's always correct.
|
11
|
+
if Gem::Version.correct?(Haml::VERSION) && Gem::Version.new(Haml::VERSION) >= Gem::Version.new('5.0.0.beta.2')
|
12
|
+
def prepare
|
13
|
+
options = {}.update(@options).update(filename: eval_file, line: line)
|
14
|
+
if options.include?(:outvar)
|
15
|
+
options[:buffer] = options.delete(:outvar)
|
16
|
+
options[:save_buffer] = true
|
17
|
+
end
|
18
|
+
@engine = ::Haml::TempleEngine.new(options)
|
19
|
+
@engine.compile(data)
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
def evaluate(scope, locals, &block)
|
23
|
+
raise ArgumentError, 'invalid scope: must not be frozen' if scope.frozen?
|
24
24
|
super
|
25
|
-
else
|
26
|
-
@engine.render(scope, locals, &block)
|
27
25
|
end
|
28
|
-
end
|
29
26
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@engine.precompiled
|
35
|
-
end
|
36
|
-
|
37
|
-
def precompiled_preamble(locals)
|
38
|
-
local_assigns = super
|
39
|
-
@engine.instance_eval do
|
40
|
-
<<-RUBY
|
41
|
-
begin
|
42
|
-
extend Haml::Helpers
|
43
|
-
_hamlout = @haml_buffer = Haml::Buffer.new(@haml_buffer, #{options_for_buffer.inspect})
|
44
|
-
_erbout = _hamlout.buffer
|
27
|
+
def precompiled_template(locals)
|
28
|
+
@engine.precompiled_with_ambles(
|
29
|
+
[],
|
30
|
+
after_preamble: <<-RUBY
|
45
31
|
__in_erb_template = true
|
46
32
|
_haml_locals = locals
|
47
|
-
|
48
|
-
|
33
|
+
RUBY
|
34
|
+
)
|
49
35
|
end
|
50
|
-
|
36
|
+
else # Following definitions are for Haml <= 4 and deprecated.
|
37
|
+
def prepare
|
38
|
+
options = @options.merge(:filename => eval_file, :line => line)
|
39
|
+
@engine = ::Haml::Engine.new(data, options)
|
40
|
+
end
|
41
|
+
|
42
|
+
def evaluate(scope, locals, &block)
|
43
|
+
raise ArgumentError, 'invalid scope: must not be frozen' if scope.frozen?
|
51
44
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
45
|
+
if @engine.respond_to?(:precompiled_method_return_value, true)
|
46
|
+
super
|
47
|
+
else
|
48
|
+
@engine.render(scope, locals, &block)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Precompiled Haml source. Taken from the precompiled_with_ambles
|
53
|
+
# method in Haml::Precompiler:
|
54
|
+
# http://github.com/nex3/haml/blob/master/lib/haml/precompiler.rb#L111-126
|
55
|
+
def precompiled_template(locals)
|
56
|
+
@engine.precompiled
|
57
|
+
end
|
58
|
+
|
59
|
+
def precompiled_preamble(locals)
|
60
|
+
local_assigns = super
|
61
|
+
@engine.instance_eval do
|
62
|
+
<<-RUBY
|
63
|
+
begin
|
64
|
+
extend Haml::Helpers
|
65
|
+
_hamlout = @haml_buffer = Haml::Buffer.new(haml_buffer, #{options_for_buffer.inspect})
|
66
|
+
_erbout = _hamlout.buffer
|
67
|
+
__in_erb_template = true
|
68
|
+
_haml_locals = locals
|
69
|
+
#{local_assigns}
|
70
|
+
RUBY
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def precompiled_postamble(locals)
|
75
|
+
@engine.instance_eval do
|
76
|
+
<<-RUBY
|
77
|
+
#{precompiled_method_return_value}
|
78
|
+
ensure
|
79
|
+
@haml_buffer = @haml_buffer.upper if haml_buffer
|
80
|
+
end
|
81
|
+
RUBY
|
82
|
+
end
|
60
83
|
end
|
61
84
|
end
|
62
85
|
end
|
63
86
|
end
|
64
|
-
|
@@ -0,0 +1,25 @@
|
|
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 prepare
|
11
|
+
options[:smart_quotes] = DUMB_QUOTES unless options[:smartypants]
|
12
|
+
@engine = Kramdown::Document.new(data, options)
|
13
|
+
@output = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def evaluate(scope, locals, &block)
|
17
|
+
@output ||= @engine.to_html
|
18
|
+
end
|
19
|
+
|
20
|
+
def allows_script?
|
21
|
+
false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
data/lib/tilt/less.rb
ADDED
@@ -0,0 +1,30 @@
|
|
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 prepare
|
13
|
+
if ::Less.const_defined? :Engine
|
14
|
+
@engine = ::Less::Engine.new(data)
|
15
|
+
else
|
16
|
+
parser = ::Less::Parser.new(options.merge :filename => eval_file, :line => line)
|
17
|
+
@engine = parser.parse(data)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def evaluate(scope, locals, &block)
|
22
|
+
@output ||= @engine.to_css(options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def allows_script?
|
26
|
+
false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
data/lib/tilt/liquid.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'tilt/template'
|
2
|
+
require 'liquid'
|
2
3
|
|
3
4
|
module Tilt
|
4
5
|
# Liquid template implementation. See:
|
5
|
-
# http://
|
6
|
+
# http://liquidmarkup.org/
|
6
7
|
#
|
7
8
|
# Liquid is designed to be a *safe* template system and threfore
|
8
9
|
# does not provide direct access to execuatable scopes. In order to
|
@@ -15,16 +16,8 @@ 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
|
-
@engine = ::Liquid::Template.parse(data)
|
20
|
+
@engine = ::Liquid::Template.parse(data, liquid_options)
|
28
21
|
end
|
29
22
|
|
30
23
|
def evaluate(scope, locals, &block)
|
@@ -41,5 +34,11 @@ module Tilt
|
|
41
34
|
def allows_script?
|
42
35
|
false
|
43
36
|
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def liquid_options
|
41
|
+
{ line_numbers: true }.merge options
|
42
|
+
end
|
44
43
|
end
|
45
44
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'tilt/template'
|
2
|
+
require 'livescript'
|
3
|
+
|
4
|
+
module Tilt
|
5
|
+
# LiveScript template implementation. See:
|
6
|
+
# http://livescript.net/
|
7
|
+
#
|
8
|
+
# LiveScript templates do not support object scopes, locals, or yield.
|
9
|
+
class LiveScriptTemplate < Template
|
10
|
+
self.default_mime_type = 'application/javascript'
|
11
|
+
|
12
|
+
def prepare
|
13
|
+
end
|
14
|
+
|
15
|
+
def evaluate(scope, locals, &block)
|
16
|
+
@output ||= LiveScript.compile(data, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def allows_script?
|
20
|
+
false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/tilt/mapping.rb
ADDED
@@ -0,0 +1,293 @@
|
|
1
|
+
require 'monitor'
|
2
|
+
|
3
|
+
module Tilt
|
4
|
+
# Tilt::Mapping associates file extensions with template implementations.
|
5
|
+
#
|
6
|
+
# mapping = Tilt::Mapping.new
|
7
|
+
# mapping.register(Tilt::RDocTemplate, 'rdoc')
|
8
|
+
# mapping['index.rdoc'] # => Tilt::RDocTemplate
|
9
|
+
# mapping.new('index.rdoc').render
|
10
|
+
#
|
11
|
+
# You can use {#register} to register a template class by file
|
12
|
+
# extension, {#registered?} to see if a file extension is mapped,
|
13
|
+
# {#[]} to lookup template classes, and {#new} to instantiate template
|
14
|
+
# objects.
|
15
|
+
#
|
16
|
+
# Mapping also supports *lazy* template implementations. Note that regularly
|
17
|
+
# registered template implementations *always* have preference over lazily
|
18
|
+
# registered template implementations. You should use {#register} if you
|
19
|
+
# depend on a specific template implementation and {#register_lazy} if there
|
20
|
+
# are multiple alternatives.
|
21
|
+
#
|
22
|
+
# mapping = Tilt::Mapping.new
|
23
|
+
# mapping.register_lazy('RDiscount::Template', 'rdiscount/template', 'md')
|
24
|
+
# mapping['index.md']
|
25
|
+
# # => RDiscount::Template
|
26
|
+
#
|
27
|
+
# {#register_lazy} takes a class name, a filename, and a list of file
|
28
|
+
# extensions. When you try to lookup a template name that matches the
|
29
|
+
# file extension, Tilt will automatically try to require the filename and
|
30
|
+
# constantize the class name.
|
31
|
+
#
|
32
|
+
# Unlike {#register}, there can be multiple template implementations
|
33
|
+
# registered lazily to the same file extension. Tilt will attempt to load the
|
34
|
+
# template implementations in order (registered *last* would be tried first),
|
35
|
+
# returning the first which doesn't raise LoadError.
|
36
|
+
#
|
37
|
+
# If all of the registered template implementations fails, Tilt will raise
|
38
|
+
# the exception of the first, since that was the most preferred one.
|
39
|
+
#
|
40
|
+
# mapping = Tilt::Mapping.new
|
41
|
+
# mapping.register_lazy('Bluecloth::Template', 'bluecloth/template', 'md')
|
42
|
+
# mapping.register_lazy('RDiscount::Template', 'rdiscount/template', 'md')
|
43
|
+
# mapping['index.md']
|
44
|
+
# # => RDiscount::Template
|
45
|
+
#
|
46
|
+
# In the previous example we say that RDiscount has a *higher priority* than
|
47
|
+
# BlueCloth. Tilt will first try to `require "rdiscount/template"`, falling
|
48
|
+
# back to `require "bluecloth/template"`. If none of these are successful,
|
49
|
+
# the first error will be raised.
|
50
|
+
class Mapping
|
51
|
+
# @private
|
52
|
+
attr_reader :lazy_map, :template_map
|
53
|
+
|
54
|
+
def initialize
|
55
|
+
@template_map = Hash.new
|
56
|
+
@lazy_map = Hash.new { |h, k| h[k] = [] }
|
57
|
+
end
|
58
|
+
|
59
|
+
# @private
|
60
|
+
def initialize_copy(other)
|
61
|
+
@template_map = other.template_map.dup
|
62
|
+
@lazy_map = other.lazy_map.dup
|
63
|
+
end
|
64
|
+
|
65
|
+
# Registers a lazy template implementation by file extension. You
|
66
|
+
# can have multiple lazy template implementations defined on the
|
67
|
+
# same file extension, in which case the template implementation
|
68
|
+
# defined *last* will be attempted loaded *first*.
|
69
|
+
#
|
70
|
+
# @param class_name [String] Class name of a template class.
|
71
|
+
# @param file [String] Filename where the template class is defined.
|
72
|
+
# @param extensions [Array<String>] List of extensions.
|
73
|
+
# @return [void]
|
74
|
+
#
|
75
|
+
# @example
|
76
|
+
# mapping.register_lazy 'MyEngine::Template', 'my_engine/template', 'mt'
|
77
|
+
#
|
78
|
+
# defined?(MyEngine::Template) # => false
|
79
|
+
# mapping['index.mt'] # => MyEngine::Template
|
80
|
+
# defined?(MyEngine::Template) # => true
|
81
|
+
def register_lazy(class_name, file, *extensions)
|
82
|
+
# Internal API
|
83
|
+
if class_name.is_a?(Symbol)
|
84
|
+
Tilt.autoload class_name, file
|
85
|
+
class_name = "Tilt::#{class_name}"
|
86
|
+
end
|
87
|
+
|
88
|
+
extensions.each do |ext|
|
89
|
+
@lazy_map[ext].unshift([class_name, file])
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Registers a template implementation by file extension. There can only be
|
94
|
+
# one template implementation per file extension, and this method will
|
95
|
+
# override any existing mapping.
|
96
|
+
#
|
97
|
+
# @param template_class
|
98
|
+
# @param extensions [Array<String>] List of extensions.
|
99
|
+
# @return [void]
|
100
|
+
#
|
101
|
+
# @example
|
102
|
+
# mapping.register MyEngine::Template, 'mt'
|
103
|
+
# mapping['index.mt'] # => MyEngine::Template
|
104
|
+
def register(template_class, *extensions)
|
105
|
+
if template_class.respond_to?(:to_str)
|
106
|
+
# Support register(ext, template_class) too
|
107
|
+
extensions, template_class = [template_class], extensions[0]
|
108
|
+
end
|
109
|
+
|
110
|
+
extensions.each do |ext|
|
111
|
+
@template_map[ext.to_s] = template_class
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Checks if a file extension is registered (either eagerly or
|
116
|
+
# lazily) in this mapping.
|
117
|
+
#
|
118
|
+
# @param ext [String] File extension.
|
119
|
+
#
|
120
|
+
# @example
|
121
|
+
# mapping.registered?('erb') # => true
|
122
|
+
# mapping.registered?('nope') # => false
|
123
|
+
def registered?(ext)
|
124
|
+
@template_map.has_key?(ext.downcase) or lazy?(ext)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Instantiates a new template class based on the file.
|
128
|
+
#
|
129
|
+
# @raise [RuntimeError] if there is no template class registered for the
|
130
|
+
# file name.
|
131
|
+
#
|
132
|
+
# @example
|
133
|
+
# mapping.new('index.mt') # => instance of MyEngine::Template
|
134
|
+
#
|
135
|
+
# @see Tilt::Template.new
|
136
|
+
def new(file, line=nil, options={}, &block)
|
137
|
+
if template_class = self[file]
|
138
|
+
template_class.new(file, line, options, &block)
|
139
|
+
else
|
140
|
+
fail "No template engine registered for #{File.basename(file)}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Looks up a template class based on file name and/or extension.
|
145
|
+
#
|
146
|
+
# @example
|
147
|
+
# mapping['views/hello.erb'] # => Tilt::ERBTemplate
|
148
|
+
# mapping['hello.erb'] # => Tilt::ERBTemplate
|
149
|
+
# mapping['erb'] # => Tilt::ERBTemplate
|
150
|
+
#
|
151
|
+
# @return [template class]
|
152
|
+
def [](file)
|
153
|
+
_, ext = split(file)
|
154
|
+
ext && lookup(ext)
|
155
|
+
end
|
156
|
+
|
157
|
+
alias template_for []
|
158
|
+
|
159
|
+
# Looks up a list of template classes based on file name. If the file name
|
160
|
+
# has multiple extensions, it will return all template classes matching the
|
161
|
+
# extensions from the end.
|
162
|
+
#
|
163
|
+
# @example
|
164
|
+
# mapping.templates_for('views/index.haml.erb')
|
165
|
+
# # => [Tilt::ERBTemplate, Tilt::HamlTemplate]
|
166
|
+
#
|
167
|
+
# @return [Array<template class>]
|
168
|
+
def templates_for(file)
|
169
|
+
templates = []
|
170
|
+
|
171
|
+
while true
|
172
|
+
prefix, ext = split(file)
|
173
|
+
break unless ext
|
174
|
+
templates << lookup(ext)
|
175
|
+
file = prefix
|
176
|
+
end
|
177
|
+
|
178
|
+
templates
|
179
|
+
end
|
180
|
+
|
181
|
+
# Finds the extensions the template class has been registered under.
|
182
|
+
# @param [template class] template_class
|
183
|
+
def extensions_for(template_class)
|
184
|
+
res = []
|
185
|
+
template_map.each do |ext, klass|
|
186
|
+
res << ext if template_class == klass
|
187
|
+
end
|
188
|
+
lazy_map.each do |ext, choices|
|
189
|
+
res << ext if choices.any? { |klass, file| template_class.to_s == klass }
|
190
|
+
end
|
191
|
+
res
|
192
|
+
end
|
193
|
+
|
194
|
+
private
|
195
|
+
|
196
|
+
def lazy?(ext)
|
197
|
+
ext = ext.downcase
|
198
|
+
@lazy_map.has_key?(ext) && !@lazy_map[ext].empty?
|
199
|
+
end
|
200
|
+
|
201
|
+
def split(file)
|
202
|
+
pattern = file.to_s.downcase
|
203
|
+
full_pattern = pattern.dup
|
204
|
+
|
205
|
+
until registered?(pattern)
|
206
|
+
return if pattern.empty?
|
207
|
+
pattern = File.basename(pattern)
|
208
|
+
pattern.sub!(/^[^.]*\.?/, '')
|
209
|
+
end
|
210
|
+
|
211
|
+
prefix_size = full_pattern.size - pattern.size
|
212
|
+
[full_pattern[0,prefix_size-1], pattern]
|
213
|
+
end
|
214
|
+
|
215
|
+
def lookup(ext)
|
216
|
+
@template_map[ext] || lazy_load(ext)
|
217
|
+
end
|
218
|
+
|
219
|
+
LOCK = Monitor.new
|
220
|
+
|
221
|
+
def lazy_load(pattern)
|
222
|
+
return unless @lazy_map.has_key?(pattern)
|
223
|
+
|
224
|
+
LOCK.enter
|
225
|
+
entered = true
|
226
|
+
|
227
|
+
choices = @lazy_map[pattern]
|
228
|
+
|
229
|
+
# Check if a template class is already present
|
230
|
+
choices.each do |class_name, file|
|
231
|
+
template_class = constant_defined?(class_name)
|
232
|
+
if template_class
|
233
|
+
register(template_class, pattern)
|
234
|
+
return template_class
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
first_failure = nil
|
239
|
+
|
240
|
+
# Load in order
|
241
|
+
choices.each do |class_name, file|
|
242
|
+
begin
|
243
|
+
require file
|
244
|
+
# It's safe to eval() here because constant_defined? will
|
245
|
+
# raise NameError on invalid constant names
|
246
|
+
template_class = eval(class_name)
|
247
|
+
rescue LoadError => ex
|
248
|
+
first_failure ||= ex
|
249
|
+
else
|
250
|
+
register(template_class, pattern)
|
251
|
+
return template_class
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
raise first_failure if first_failure
|
256
|
+
ensure
|
257
|
+
LOCK.exit if entered
|
258
|
+
end
|
259
|
+
|
260
|
+
# This is due to a bug in JRuby (see GH issue jruby/jruby#3585)
|
261
|
+
Tilt.autoload :Dummy, "tilt/dummy"
|
262
|
+
require "tilt/dummy"
|
263
|
+
AUTOLOAD_IS_BROKEN = Tilt.autoload?(:Dummy)
|
264
|
+
|
265
|
+
# The proper behavior (in MRI) for autoload? is to
|
266
|
+
# return `false` when the constant/file has been
|
267
|
+
# explicitly required.
|
268
|
+
#
|
269
|
+
# However, in JRuby it returns `true` even after it's
|
270
|
+
# been required. In that case it turns out that `defined?`
|
271
|
+
# returns `"constant"` if it exists and `nil` when it doesn't.
|
272
|
+
# This is actually a second bug: `defined?` should resolve
|
273
|
+
# autoload (aka. actually try to require the file).
|
274
|
+
#
|
275
|
+
# We use the second bug in order to resolve the first bug.
|
276
|
+
|
277
|
+
def constant_defined?(name)
|
278
|
+
name.split('::').inject(Object) do |scope, n|
|
279
|
+
if scope.autoload?(n)
|
280
|
+
if !AUTOLOAD_IS_BROKEN
|
281
|
+
return false
|
282
|
+
end
|
283
|
+
|
284
|
+
if eval("!defined?(scope::#{n})")
|
285
|
+
return false
|
286
|
+
end
|
287
|
+
end
|
288
|
+
return false if !scope.const_defined?(n)
|
289
|
+
scope.const_get(n)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
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/pandoc.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'tilt/template'
|
2
|
+
require 'pandoc-ruby'
|
3
|
+
|
4
|
+
module Tilt
|
5
|
+
# Pandoc markdown implementation. See:
|
6
|
+
# http://pandoc.org/
|
7
|
+
class PandocTemplate < Template
|
8
|
+
self.default_mime_type = 'text/html'
|
9
|
+
|
10
|
+
# turn options hash into an array
|
11
|
+
# Map tilt options to pandoc options
|
12
|
+
# Replace hash keys with value true with symbol for key
|
13
|
+
# Remove hash keys with value false
|
14
|
+
# Leave other hash keys untouched
|
15
|
+
def pandoc_options
|
16
|
+
result = []
|
17
|
+
from = "markdown"
|
18
|
+
smart_extension = "-smart"
|
19
|
+
options.each do |k,v|
|
20
|
+
case k
|
21
|
+
when :smartypants
|
22
|
+
smart_extension = "+smart" if v
|
23
|
+
when :escape_html
|
24
|
+
from = "markdown-raw_html" if v
|
25
|
+
when :commonmark
|
26
|
+
from = "commonmark" if v
|
27
|
+
when :markdown_strict
|
28
|
+
from = "markdown_strict" if v
|
29
|
+
else
|
30
|
+
case v
|
31
|
+
when true
|
32
|
+
result << k
|
33
|
+
when false
|
34
|
+
# do nothing
|
35
|
+
else
|
36
|
+
result << { k => v }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
result << { :f => from + smart_extension }
|
41
|
+
result
|
42
|
+
end
|
43
|
+
|
44
|
+
def prepare
|
45
|
+
@engine = PandocRuby.new(data, *pandoc_options)
|
46
|
+
@output = nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def evaluate(scope, locals, &block)
|
50
|
+
@output ||= @engine.to_html.strip
|
51
|
+
end
|
52
|
+
|
53
|
+
def allows_script?
|
54
|
+
false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|