tilt 1.2.2 → 1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +54 -24
- data/TEMPLATES.md +250 -175
- data/lib/tilt.rb +104 -817
- data/lib/tilt/builder.rb +40 -0
- data/lib/tilt/coffee.rb +50 -0
- data/lib/tilt/creole.rb +28 -0
- data/lib/tilt/css.rb +67 -0
- data/lib/tilt/erb.rb +110 -0
- data/lib/tilt/haml.rb +64 -0
- data/lib/tilt/liquid.rb +41 -0
- data/lib/tilt/markaby.rb +52 -0
- data/lib/tilt/markdown.rb +131 -0
- data/lib/tilt/nokogiri.rb +43 -0
- data/lib/tilt/radius.rb +51 -0
- data/lib/tilt/rdoc.rb +32 -0
- data/lib/tilt/string.rb +21 -0
- data/lib/tilt/template.rb +285 -0
- data/lib/tilt/textile.rb +25 -0
- data/test/tilt_blueclothtemplate_test.rb +6 -25
- data/test/tilt_coffeescripttemplate_test.rb +31 -1
- data/test/tilt_creoletemplate_test.rb +24 -0
- data/test/tilt_erbtemplate_test.rb +18 -19
- data/test/tilt_erubistemplate_test.rb +12 -2
- data/test/tilt_fallback_test.rb +122 -0
- data/test/tilt_hamltemplate_test.rb +4 -4
- data/test/tilt_kramdown_test.rb +42 -0
- data/test/tilt_markdown_test.rb +149 -0
- data/test/tilt_marukutemplate_test.rb +48 -0
- data/test/tilt_rdiscounttemplate_test.rb +16 -6
- data/test/tilt_redcarpettemplate_test.rb +55 -0
- data/test/tilt_stringtemplate_test.rb +10 -3
- data/test/tilt_template_test.rb +6 -0
- data/tilt.gemspec +28 -2
- metadata +86 -36
data/lib/tilt/builder.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'tilt/template'
|
2
|
+
|
3
|
+
module Tilt
|
4
|
+
# Builder template implementation. See:
|
5
|
+
# http://builder.rubyforge.org/
|
6
|
+
class BuilderTemplate < Template
|
7
|
+
self.default_mime_type = 'text/xml'
|
8
|
+
|
9
|
+
def self.engine_initialized?
|
10
|
+
defined? ::Builder
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize_engine
|
14
|
+
require_template_library 'builder'
|
15
|
+
end
|
16
|
+
|
17
|
+
def prepare; end
|
18
|
+
|
19
|
+
def evaluate(scope, locals, &block)
|
20
|
+
return super(scope, locals, &block) if data.respond_to?(:to_str)
|
21
|
+
xml = ::Builder::XmlMarkup.new(:indent => 2)
|
22
|
+
data.call(xml)
|
23
|
+
xml.target!
|
24
|
+
end
|
25
|
+
|
26
|
+
def precompiled_preamble(locals)
|
27
|
+
return super if locals.include? :xml
|
28
|
+
"xml = ::Builder::XmlMarkup.new(:indent => 2)\n#{super}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def precompiled_postamble(locals)
|
32
|
+
"xml.target!"
|
33
|
+
end
|
34
|
+
|
35
|
+
def precompiled_template(locals)
|
36
|
+
data.to_str
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
data/lib/tilt/coffee.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'tilt/template'
|
2
|
+
|
3
|
+
module Tilt
|
4
|
+
# CoffeeScript template implementation. See:
|
5
|
+
# http://coffeescript.org/
|
6
|
+
#
|
7
|
+
# CoffeeScript templates do not support object scopes, locals, or yield.
|
8
|
+
class CoffeeScriptTemplate < Template
|
9
|
+
self.default_mime_type = 'application/javascript'
|
10
|
+
|
11
|
+
@@default_bare = true
|
12
|
+
|
13
|
+
def self.default_bare
|
14
|
+
@@default_bare
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.default_bare=(value)
|
18
|
+
@@default_bare = value
|
19
|
+
end
|
20
|
+
|
21
|
+
# DEPRECATED
|
22
|
+
def self.default_no_wrap
|
23
|
+
@@default_bare
|
24
|
+
end
|
25
|
+
|
26
|
+
# DEPRECATED
|
27
|
+
def self.default_no_wrap=(value)
|
28
|
+
@@default_bare = value
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.engine_initialized?
|
32
|
+
defined? ::CoffeeScript
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize_engine
|
36
|
+
require_template_library 'coffee_script'
|
37
|
+
end
|
38
|
+
|
39
|
+
def prepare
|
40
|
+
if !options.key?(:bare) and !options.key?(:no_wrap)
|
41
|
+
options[:bare] = self.class.default_bare
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def evaluate(scope, locals, &block)
|
46
|
+
@output ||= CoffeeScript.compile(data, options)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
data/lib/tilt/creole.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'tilt/template'
|
2
|
+
|
3
|
+
module Tilt
|
4
|
+
# Creole implementation. See:
|
5
|
+
# http://www.wikicreole.org/
|
6
|
+
class CreoleTemplate < Template
|
7
|
+
def self.engine_initialized?
|
8
|
+
defined? ::Creole
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize_engine
|
12
|
+
require_template_library 'creole'
|
13
|
+
end
|
14
|
+
|
15
|
+
def prepare
|
16
|
+
opts = {}
|
17
|
+
[:allowed_schemes, :extensions, :no_escape].each do |k|
|
18
|
+
opts[k] = options[k] if options[k]
|
19
|
+
end
|
20
|
+
@engine = Creole::Parser.new(data, opts)
|
21
|
+
@output = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def evaluate(scope, locals, &block)
|
25
|
+
@output ||= @engine.to_html
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/tilt/css.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'tilt/template'
|
2
|
+
|
3
|
+
module Tilt
|
4
|
+
# Sass template implementation. See:
|
5
|
+
# http://haml.hamptoncatlin.com/
|
6
|
+
#
|
7
|
+
# Sass templates do not support object scopes, locals, or yield.
|
8
|
+
class SassTemplate < Template
|
9
|
+
self.default_mime_type = 'text/css'
|
10
|
+
|
11
|
+
def self.engine_initialized?
|
12
|
+
defined? ::Sass::Engine
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize_engine
|
16
|
+
require_template_library 'sass'
|
17
|
+
end
|
18
|
+
|
19
|
+
def prepare
|
20
|
+
@engine = ::Sass::Engine.new(data, sass_options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def evaluate(scope, locals, &block)
|
24
|
+
@output ||= @engine.render
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def sass_options
|
29
|
+
options.merge(:filename => eval_file, :line => line, :syntax => :sass)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Sass's new .scss type template implementation.
|
34
|
+
class ScssTemplate < SassTemplate
|
35
|
+
self.default_mime_type = 'text/css'
|
36
|
+
|
37
|
+
private
|
38
|
+
def sass_options
|
39
|
+
options.merge(:filename => eval_file, :line => line, :syntax => :scss)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Lessscss template implementation. See:
|
44
|
+
# http://lesscss.org/
|
45
|
+
#
|
46
|
+
# Less templates do not support object scopes, locals, or yield.
|
47
|
+
class LessTemplate < Template
|
48
|
+
self.default_mime_type = 'text/css'
|
49
|
+
|
50
|
+
def self.engine_initialized?
|
51
|
+
defined? ::Less::Engine
|
52
|
+
end
|
53
|
+
|
54
|
+
def initialize_engine
|
55
|
+
require_template_library 'less'
|
56
|
+
end
|
57
|
+
|
58
|
+
def prepare
|
59
|
+
@engine = ::Less::Engine.new(data)
|
60
|
+
end
|
61
|
+
|
62
|
+
def evaluate(scope, locals, &block)
|
63
|
+
@engine.to_css
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
data/lib/tilt/erb.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'tilt/template'
|
2
|
+
|
3
|
+
module Tilt
|
4
|
+
# ERB template implementation. See:
|
5
|
+
# http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html
|
6
|
+
class ERBTemplate < Template
|
7
|
+
@@default_output_variable = '_erbout'
|
8
|
+
|
9
|
+
def self.default_output_variable
|
10
|
+
@@default_output_variable
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.default_output_variable=(name)
|
14
|
+
@@default_output_variable = name
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.engine_initialized?
|
18
|
+
defined? ::ERB
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize_engine
|
22
|
+
require_template_library 'erb'
|
23
|
+
end
|
24
|
+
|
25
|
+
def prepare
|
26
|
+
@outvar = options[:outvar] || self.class.default_output_variable
|
27
|
+
options[:trim] = '<>' if options[:trim].nil? || options[:trim] == true
|
28
|
+
@engine = ::ERB.new(data, options[:safe], options[:trim], @outvar)
|
29
|
+
end
|
30
|
+
|
31
|
+
def precompiled_template(locals)
|
32
|
+
source = @engine.src
|
33
|
+
source
|
34
|
+
end
|
35
|
+
|
36
|
+
def precompiled_preamble(locals)
|
37
|
+
<<-RUBY
|
38
|
+
begin
|
39
|
+
__original_outvar = #{@outvar} if defined?(#{@outvar})
|
40
|
+
#{super}
|
41
|
+
RUBY
|
42
|
+
end
|
43
|
+
|
44
|
+
def precompiled_postamble(locals)
|
45
|
+
<<-RUBY
|
46
|
+
#{super}
|
47
|
+
ensure
|
48
|
+
#{@outvar} = __original_outvar
|
49
|
+
end
|
50
|
+
RUBY
|
51
|
+
end
|
52
|
+
|
53
|
+
# ERB generates a line to specify the character coding of the generated
|
54
|
+
# source in 1.9. Account for this in the line offset.
|
55
|
+
if RUBY_VERSION >= '1.9.0'
|
56
|
+
def precompiled(locals)
|
57
|
+
source, offset = super
|
58
|
+
[source, offset + 1]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Erubis template implementation. See:
|
64
|
+
# http://www.kuwata-lab.com/erubis/
|
65
|
+
#
|
66
|
+
# ErubisTemplate supports the following additional options, which are not
|
67
|
+
# passed down to the Erubis engine:
|
68
|
+
#
|
69
|
+
# :engine_class allows you to specify a custom engine class to use
|
70
|
+
# instead of the default (which is ::Erubis::Eruby).
|
71
|
+
#
|
72
|
+
# :escape_html when true, ::Erubis::EscapedEruby will be used as
|
73
|
+
# the engine class instead of the default. All content
|
74
|
+
# within <%= %> blocks will be automatically html escaped.
|
75
|
+
class ErubisTemplate < ERBTemplate
|
76
|
+
def self.engine_initialized?
|
77
|
+
defined? ::Erubis
|
78
|
+
end
|
79
|
+
|
80
|
+
def initialize_engine
|
81
|
+
require_template_library 'erubis'
|
82
|
+
end
|
83
|
+
|
84
|
+
def prepare
|
85
|
+
@outvar = options.delete(:outvar) || self.class.default_output_variable
|
86
|
+
@options.merge!(:preamble => false, :postamble => false, :bufvar => @outvar)
|
87
|
+
engine_class = options.delete(:engine_class)
|
88
|
+
engine_class = ::Erubis::EscapedEruby if options.delete(:escape_html)
|
89
|
+
@engine = (engine_class || ::Erubis::Eruby).new(data, options)
|
90
|
+
end
|
91
|
+
|
92
|
+
def precompiled_preamble(locals)
|
93
|
+
[super, "#{@outvar} = _buf = ''"].join("\n")
|
94
|
+
end
|
95
|
+
|
96
|
+
def precompiled_postamble(locals)
|
97
|
+
[@outvar, super].join("\n")
|
98
|
+
end
|
99
|
+
|
100
|
+
# Erubis doesn't have ERB's line-off-by-one under 1.9 problem.
|
101
|
+
# Override and adjust back.
|
102
|
+
if RUBY_VERSION >= '1.9.0'
|
103
|
+
def precompiled(locals)
|
104
|
+
source, offset = super
|
105
|
+
[source, offset - 1]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
data/lib/tilt/haml.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'tilt/template'
|
2
|
+
|
3
|
+
module Tilt
|
4
|
+
# Haml template implementation. See:
|
5
|
+
# http://haml.hamptoncatlin.com/
|
6
|
+
class HamlTemplate < Template
|
7
|
+
self.default_mime_type = 'text/html'
|
8
|
+
|
9
|
+
def self.engine_initialized?
|
10
|
+
defined? ::Haml::Engine
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize_engine
|
14
|
+
require_template_library 'haml'
|
15
|
+
end
|
16
|
+
|
17
|
+
def prepare
|
18
|
+
options = @options.merge(:filename => eval_file, :line => line)
|
19
|
+
@engine = ::Haml::Engine.new(data, options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def evaluate(scope, locals, &block)
|
23
|
+
if @engine.respond_to?(:precompiled_method_return_value, true)
|
24
|
+
super
|
25
|
+
else
|
26
|
+
@engine.render(scope, locals, &block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Precompiled Haml source. Taken from the precompiled_with_ambles
|
31
|
+
# method in Haml::Precompiler:
|
32
|
+
# http://github.com/nex3/haml/blob/master/lib/haml/precompiler.rb#L111-126
|
33
|
+
def precompiled_template(locals)
|
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
|
45
|
+
__in_erb_template = true
|
46
|
+
_haml_locals = locals
|
47
|
+
#{local_assigns}
|
48
|
+
RUBY
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def precompiled_postamble(locals)
|
53
|
+
@engine.instance_eval do
|
54
|
+
<<-RUBY
|
55
|
+
#{precompiled_method_return_value}
|
56
|
+
ensure
|
57
|
+
@haml_buffer = @haml_buffer.upper
|
58
|
+
end
|
59
|
+
RUBY
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
data/lib/tilt/liquid.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'tilt/template'
|
2
|
+
|
3
|
+
module Tilt
|
4
|
+
# Liquid template implementation. See:
|
5
|
+
# http://liquid.rubyforge.org/
|
6
|
+
#
|
7
|
+
# Liquid is designed to be a *safe* template system and threfore
|
8
|
+
# does not provide direct access to execuatable scopes. In order to
|
9
|
+
# support a +scope+, the +scope+ must be able to represent itself
|
10
|
+
# as a hash by responding to #to_h. If the +scope+ does not respond
|
11
|
+
# to #to_h it will be ignored.
|
12
|
+
#
|
13
|
+
# LiquidTemplate does not support yield blocks.
|
14
|
+
#
|
15
|
+
# It's suggested that your program require 'liquid' at load
|
16
|
+
# time when using this template engine.
|
17
|
+
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
|
+
def prepare
|
27
|
+
@engine = ::Liquid::Template.parse(data)
|
28
|
+
end
|
29
|
+
|
30
|
+
def evaluate(scope, locals, &block)
|
31
|
+
locals = locals.inject({}){ |h,(k,v)| h[k.to_s] = v ; h }
|
32
|
+
if scope.respond_to?(:to_h)
|
33
|
+
scope = scope.to_h.inject({}){ |h,(k,v)| h[k.to_s] = v ; h }
|
34
|
+
locals = scope.merge(locals)
|
35
|
+
end
|
36
|
+
locals['yield'] = block.nil? ? '' : yield
|
37
|
+
locals['content'] = locals['yield']
|
38
|
+
@engine.render(locals)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/tilt/markaby.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'tilt/template'
|
2
|
+
|
3
|
+
module Tilt
|
4
|
+
# Markaby
|
5
|
+
# http://github.com/markaby/markaby
|
6
|
+
class MarkabyTemplate < Template
|
7
|
+
def self.builder_class
|
8
|
+
@builder_class ||= Class.new(Markaby::Builder) do
|
9
|
+
def __capture_markaby_tilt__(&block)
|
10
|
+
__run_markaby_tilt__ do
|
11
|
+
text capture(&block)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.engine_initialized?
|
18
|
+
defined? ::Markaby
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize_engine
|
22
|
+
require_template_library 'markaby'
|
23
|
+
end
|
24
|
+
|
25
|
+
def prepare
|
26
|
+
end
|
27
|
+
|
28
|
+
def evaluate(scope, locals, &block)
|
29
|
+
builder = self.class.builder_class.new({}, scope)
|
30
|
+
builder.locals = locals
|
31
|
+
|
32
|
+
if data.kind_of? Proc
|
33
|
+
(class << builder; self end).send(:define_method, :__run_markaby_tilt__, &data)
|
34
|
+
else
|
35
|
+
builder.instance_eval <<-CODE, __FILE__, __LINE__
|
36
|
+
def __run_markaby_tilt__
|
37
|
+
#{data}
|
38
|
+
end
|
39
|
+
CODE
|
40
|
+
end
|
41
|
+
|
42
|
+
if block
|
43
|
+
builder.__capture_markaby_tilt__(&block)
|
44
|
+
else
|
45
|
+
builder.__run_markaby_tilt__
|
46
|
+
end
|
47
|
+
|
48
|
+
builder.to_s
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|