temple 0.3.2 → 0.3.4
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.
- data/.gitignore +1 -0
- data/.travis.yml +7 -0
- data/CHANGES +9 -0
- data/Gemfile +3 -0
- data/lib/temple.rb +1 -0
- data/lib/temple/engine.rb +3 -2
- data/lib/temple/filters/escapable.rb +1 -1
- data/lib/temple/generators.rb +6 -1
- data/lib/temple/grammar.rb +3 -4
- data/lib/temple/html/attribute_merger.rb +75 -0
- data/lib/temple/html/fast.rb +13 -76
- data/lib/temple/html/pretty.rb +5 -3
- data/lib/temple/mixins/engine_dsl.rb +18 -8
- data/lib/temple/mixins/grammar_dsl.rb +5 -2
- data/lib/temple/templates.rb +2 -2
- data/lib/temple/templates/rails.rb +13 -4
- data/lib/temple/templates/tilt.rb +2 -1
- data/lib/temple/version.rb +1 -1
- data/temple.gemspec +1 -0
- data/test/filters/test_escapable.rb +1 -1
- data/test/html/test_attribute_merger.rb +69 -0
- data/test/html/test_fast.rb +3 -62
- data/test/test_engine.rb +39 -27
- data/test/test_grammar.rb +0 -5
- metadata +52 -43
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/CHANGES
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
master
|
2
2
|
|
3
|
+
0.3.3
|
4
|
+
|
5
|
+
* Support for rails 3.1 streaming
|
6
|
+
* Add EngineDSL#wildcard
|
7
|
+
* HTML::Fast/Pretty supports only :xhtml and :html formats from now on
|
8
|
+
* HTML::AttributeMerger extracted from HTML::Fast
|
9
|
+
|
10
|
+
0.3.1, 0.3.2
|
11
|
+
|
3
12
|
* Don't modify strings destructively with gsub! in HTML::Pretty.
|
4
13
|
This doesn't work with Rails safe buffers in version >= 3.0.8.
|
5
14
|
|
data/Gemfile
ADDED
data/lib/temple.rb
CHANGED
data/lib/temple/engine.rb
CHANGED
@@ -63,11 +63,12 @@ module Temple
|
|
63
63
|
filtered_options = Hash[*option_filter.select {|k| options.include?(k) }.map {|k| [k, options[k]] }.flatten]
|
64
64
|
filter.new(ImmutableHash.new(local_options, filtered_options))
|
65
65
|
when UnboundMethod
|
66
|
-
filter.bind(self)
|
66
|
+
filter = filter.bind(self)
|
67
|
+
filter.arity == 1 ? filter : filter.call
|
67
68
|
else
|
68
69
|
filter
|
69
70
|
end
|
70
|
-
end
|
71
|
+
end.compact
|
71
72
|
end
|
72
73
|
end
|
73
74
|
end
|
@@ -14,7 +14,7 @@ module Temple
|
|
14
14
|
def initialize(opts = {})
|
15
15
|
super
|
16
16
|
@escape_code = options[:escape_code] ||
|
17
|
-
"Temple::Utils.escape_html#{options[:use_html_safe] ? '_safe' : ''}((%s))"
|
17
|
+
"::Temple::Utils.escape_html#{options[:use_html_safe] ? '_safe' : ''}((%s))"
|
18
18
|
@escaper = eval("proc {|v| #{@escape_code % 'v'} }")
|
19
19
|
@escape = false
|
20
20
|
end
|
data/lib/temple/generators.rb
CHANGED
@@ -120,10 +120,15 @@ module Temple
|
|
120
120
|
class RailsOutputBuffer < StringBuffer
|
121
121
|
set_default_options :buffer_class => 'ActiveSupport::SafeBuffer',
|
122
122
|
:buffer => '@output_buffer',
|
123
|
+
# output_buffer is needed for Rails 3.1 Streaming support
|
123
124
|
:capture_generator => RailsOutputBuffer
|
124
125
|
|
125
126
|
def preamble
|
126
|
-
|
127
|
+
if options[:streaming] && options[:buffer] == '@output_buffer'
|
128
|
+
"#{buffer} = output_buffer || #{options[:buffer_class]}.new"
|
129
|
+
else
|
130
|
+
"#{buffer} = #{options[:buffer_class]}.new"
|
131
|
+
end
|
127
132
|
end
|
128
133
|
|
129
134
|
def concat(str)
|
data/lib/temple/grammar.rb
CHANGED
@@ -29,14 +29,13 @@ module Temple
|
|
29
29
|
# HTML abstraction
|
30
30
|
[:html, :doctype, String] |
|
31
31
|
[:html, :comment, Expression] |
|
32
|
-
[:html, :tag, HTMLIdentifier,
|
32
|
+
[:html, :tag, HTMLIdentifier, Expression, 'Expression?'] |
|
33
|
+
[:html, :attrs, 'HTMLAttr*'] |
|
34
|
+
HTMLAttr
|
33
35
|
|
34
36
|
EmptyExp <<
|
35
37
|
[:newline] | [:multi, 'EmptyExp*']
|
36
38
|
|
37
|
-
HTMLAttrs <<
|
38
|
-
Expression | [:html, :attrs, 'HTMLAttr*']
|
39
|
-
|
40
39
|
HTMLAttr <<
|
41
40
|
[:html, :attr, HTMLIdentifier, Expression]
|
42
41
|
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Temple
|
2
|
+
module HTML
|
3
|
+
# @api public
|
4
|
+
class AttributeMerger < Filter
|
5
|
+
default_options[:attr_delimiter] = {'id' => '_', 'class' => ' '}
|
6
|
+
|
7
|
+
def on_html_attrs(*attrs)
|
8
|
+
result = {}
|
9
|
+
attrs.each do |attr|
|
10
|
+
raise(InvalidExpression, 'Attribute is not a html attr') if attr[0] != :html || attr[1] != :attr
|
11
|
+
name, value = attr[2].to_s, attr[3]
|
12
|
+
next if empty_exp?(value)
|
13
|
+
if result[name]
|
14
|
+
delimiter = options[:attr_delimiter][name]
|
15
|
+
raise "Multiple #{name} attributes specified" unless delimiter
|
16
|
+
if empty_exp?(value)
|
17
|
+
result[name] = [:html, :attr, name,
|
18
|
+
[:multi,
|
19
|
+
result[name][3],
|
20
|
+
value]]
|
21
|
+
elsif contains_static?(value)
|
22
|
+
result[name] = [:html, :attr, name,
|
23
|
+
[:multi,
|
24
|
+
result[name][3],
|
25
|
+
[:static, delimiter],
|
26
|
+
value]]
|
27
|
+
else
|
28
|
+
tmp = unique_name
|
29
|
+
result[name] = [:html, :attr, name,
|
30
|
+
[:multi,
|
31
|
+
result[name][3],
|
32
|
+
[:capture, tmp, value],
|
33
|
+
[:if, "!#{tmp}.empty?",
|
34
|
+
[:multi,
|
35
|
+
[:static, delimiter],
|
36
|
+
[:dynamic, tmp]]]]]
|
37
|
+
end
|
38
|
+
else
|
39
|
+
result[name] = attr
|
40
|
+
end
|
41
|
+
end
|
42
|
+
[:multi, *result.sort.map {|name,attr| compile(attr) }]
|
43
|
+
end
|
44
|
+
|
45
|
+
def on_html_attr(name, value)
|
46
|
+
if empty_exp?(value)
|
47
|
+
value
|
48
|
+
elsif contains_static?(value)
|
49
|
+
[:html, :attr, name, value]
|
50
|
+
else
|
51
|
+
tmp = unique_name
|
52
|
+
[:multi,
|
53
|
+
[:capture, tmp, compile(value)],
|
54
|
+
[:if, "!#{tmp}.empty?",
|
55
|
+
[:html, :attr, name, [:dynamic, tmp]]]]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
protected
|
60
|
+
|
61
|
+
def contains_static?(exp)
|
62
|
+
case exp[0]
|
63
|
+
when :multi
|
64
|
+
exp[1..-1].any? {|e| contains_static?(e) }
|
65
|
+
when :escape
|
66
|
+
contains_static?(exp[2])
|
67
|
+
when :static
|
68
|
+
true
|
69
|
+
else
|
70
|
+
false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/temple/html/fast.rb
CHANGED
@@ -13,7 +13,9 @@ module Temple
|
|
13
13
|
'transitional' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
|
14
14
|
}.freeze
|
15
15
|
|
16
|
-
|
16
|
+
HTML_DOCTYPES = {
|
17
|
+
'5' => '<!DOCTYPE html>',
|
18
|
+
'html' => '<!DOCTYPE html>',
|
17
19
|
'strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
|
18
20
|
'frameset' => '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">',
|
19
21
|
'transitional' => '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
|
@@ -21,14 +23,13 @@ module Temple
|
|
21
23
|
|
22
24
|
set_default_options :format => :xhtml,
|
23
25
|
:attr_wrapper => "'",
|
24
|
-
:autoclose => %w[meta img link br hr input area param col base]
|
25
|
-
|
26
|
+
:autoclose => %w[meta img link br hr input area param col base]
|
27
|
+
|
28
|
+
HTML = [:html, :html4, :html5]
|
26
29
|
|
27
30
|
def initialize(opts = {})
|
28
31
|
super
|
29
|
-
|
30
|
-
options[:format] = :html5 if options[:format] == :html
|
31
|
-
unless [:xhtml, :html4, :html5].include?(options[:format])
|
32
|
+
unless [:xhtml, *HTML].include?(options[:format])
|
32
33
|
raise "Invalid format #{options[:format].inspect}"
|
33
34
|
end
|
34
35
|
end
|
@@ -38,7 +39,7 @@ module Temple
|
|
38
39
|
end
|
39
40
|
|
40
41
|
def html?
|
41
|
-
options[:format]
|
42
|
+
HTML.include?(options[:format])
|
42
43
|
end
|
43
44
|
|
44
45
|
def on_html_doctype(type)
|
@@ -50,19 +51,13 @@ module Temple
|
|
50
51
|
raise 'Invalid xml directive in html mode' if html?
|
51
52
|
wrapper = options[:attr_wrapper]
|
52
53
|
str = "<?xml version=#{wrapper}1.0#{wrapper} encoding=#{wrapper}#{text.split(' ')[1] || "utf-8"}#{wrapper} ?>"
|
54
|
+
elsif html?
|
55
|
+
str = HTML_DOCTYPES[text] || raise("Invalid html doctype #{text}")
|
53
56
|
else
|
54
|
-
|
55
|
-
when :html5
|
56
|
-
str = '<!DOCTYPE html>'
|
57
|
-
when :html4
|
58
|
-
str = HTML4_DOCTYPES[text] || HTML4_DOCTYPES['transitional']
|
59
|
-
when :xhtml
|
60
|
-
str = XHTML_DOCTYPES[text] || XHTML_DOCTYPES['transitional']
|
61
|
-
end
|
57
|
+
str = XHTML_DOCTYPES[text] || raise("Invalid xhtml doctype #{text}")
|
62
58
|
end
|
63
59
|
|
64
|
-
str << trailing_newlines
|
65
|
-
[:static, str]
|
60
|
+
[:static, str << trailing_newlines]
|
66
61
|
end
|
67
62
|
|
68
63
|
def on_html_comment(content)
|
@@ -83,73 +78,15 @@ module Temple
|
|
83
78
|
end
|
84
79
|
|
85
80
|
def on_html_attrs(*attrs)
|
86
|
-
|
87
|
-
attrs.each do |attr|
|
88
|
-
raise(InvalidExpression, 'Attribute is not a html attr') if attr[0] != :html || attr[1] != :attr
|
89
|
-
name, value = attr[2].to_s, attr[3]
|
90
|
-
next if empty_exp?(value)
|
91
|
-
if result[name]
|
92
|
-
delimiter = options[:attr_delimiter][name]
|
93
|
-
raise "Multiple #{name} attributes specified" unless delimiter
|
94
|
-
if contains_static?(value)
|
95
|
-
result[name] = [:html, :attr, name,
|
96
|
-
[:multi,
|
97
|
-
result[name][3],
|
98
|
-
[:static, delimiter],
|
99
|
-
value]]
|
100
|
-
else
|
101
|
-
tmp = unique_name
|
102
|
-
result[name] = [:html, :attr, name,
|
103
|
-
[:multi,
|
104
|
-
result[name][3],
|
105
|
-
[:capture, tmp, value],
|
106
|
-
[:if, "!#{tmp}.empty?",
|
107
|
-
[:multi,
|
108
|
-
[:static, delimiter],
|
109
|
-
[:dynamic, tmp]]]]]
|
110
|
-
end
|
111
|
-
else
|
112
|
-
result[name] = attr
|
113
|
-
end
|
114
|
-
end
|
115
|
-
[:multi, *result.sort.map {|name,attr| compile(attr) }]
|
81
|
+
[:multi, *attrs.map {|attr| compile(attr) }]
|
116
82
|
end
|
117
83
|
|
118
84
|
def on_html_attr(name, value)
|
119
|
-
if empty_exp?(value)
|
120
|
-
compile(value)
|
121
|
-
elsif contains_static?(value)
|
122
|
-
attribute(name, value)
|
123
|
-
else
|
124
|
-
tmp = unique_name
|
125
|
-
[:multi,
|
126
|
-
[:capture, tmp, compile(value)],
|
127
|
-
[:if, "!#{tmp}.empty?",
|
128
|
-
attribute(name, [:dynamic, tmp])]]
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
protected
|
133
|
-
|
134
|
-
def attribute(name, value)
|
135
85
|
[:multi,
|
136
86
|
[:static, " #{name}=#{options[:attr_wrapper]}"],
|
137
87
|
compile(value),
|
138
88
|
[:static, options[:attr_wrapper]]]
|
139
89
|
end
|
140
|
-
|
141
|
-
def contains_static?(exp)
|
142
|
-
case exp[0]
|
143
|
-
when :multi
|
144
|
-
exp[1..-1].any? {|e| contains_static?(e) }
|
145
|
-
when :escape
|
146
|
-
contains_static?(exp[2])
|
147
|
-
when :static
|
148
|
-
true
|
149
|
-
else
|
150
|
-
false
|
151
|
-
end
|
152
|
-
end
|
153
90
|
end
|
154
91
|
end
|
155
92
|
end
|
data/lib/temple/html/pretty.rb
CHANGED
@@ -4,9 +4,11 @@ module Temple
|
|
4
4
|
class Pretty < Fast
|
5
5
|
set_default_options :indent => ' ',
|
6
6
|
:pretty => true,
|
7
|
-
:indent_tags => %w(base body dd div dl dt
|
8
|
-
|
9
|
-
|
7
|
+
:indent_tags => %w(article aside audio base body datalist dd div dl dt
|
8
|
+
fieldset figure footer form head h1 h2 h3 h4 h5 h6
|
9
|
+
header hgroup hr html img input li link meta nav ol p
|
10
|
+
rp rt ruby section script style table tbody td tfoot
|
11
|
+
th thead title tr ul video).freeze,
|
10
12
|
:pre_tags => %w(code pre textarea).freeze
|
11
13
|
|
12
14
|
def initialize(opts = {})
|
@@ -86,8 +86,24 @@ module Temple
|
|
86
86
|
use(name, Temple::Generators.const_get(name), *options, &block)
|
87
87
|
end
|
88
88
|
|
89
|
+
def wildcard(name, &block)
|
90
|
+
raise(ArgumentError, 'Block must have arity 0') unless block.arity <= 0
|
91
|
+
chain << [name, define_chain_method("WILDCARD #{name}", block)]
|
92
|
+
chain_modified!
|
93
|
+
end
|
94
|
+
|
89
95
|
private
|
90
96
|
|
97
|
+
def define_chain_method(name, proc)
|
98
|
+
if Class === self
|
99
|
+
define_method(name, &proc)
|
100
|
+
instance_method(name)
|
101
|
+
else
|
102
|
+
(class << self; self; end).class_eval { define_method(name, &proc) }
|
103
|
+
method(name)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
91
107
|
def element(args, block)
|
92
108
|
name = args.shift
|
93
109
|
if Class === name
|
@@ -110,14 +126,7 @@ module Temple
|
|
110
126
|
# The proc can then access the option hash of the engine.
|
111
127
|
raise(ArgumentError, 'Too many arguments') unless args.empty?
|
112
128
|
raise(ArgumentError, 'Proc or blocks must have arity 1') unless filter.arity == 1
|
113
|
-
|
114
|
-
if Class === self
|
115
|
-
define_method(method_name, &filter)
|
116
|
-
[name, instance_method(method_name)]
|
117
|
-
else
|
118
|
-
(class << self; self; end).class_eval { define_method(method_name, &filter) }
|
119
|
-
[name, method(method_name)]
|
120
|
-
end
|
129
|
+
[name, define_chain_method("FILTER #{name}", filter)]
|
121
130
|
when Class
|
122
131
|
# Class argument (e.g Filter class)
|
123
132
|
# The options are passed to the classes constructor.
|
@@ -127,6 +136,7 @@ module Temple
|
|
127
136
|
else
|
128
137
|
# Other callable argument (e.g. Object of class which implements #call or Method)
|
129
138
|
# The callable has no access to the option hash of the engine.
|
139
|
+
raise(ArgumentError, 'Too many arguments') unless args.empty?
|
130
140
|
raise(ArgumentError, 'Class or callable argument is required') unless filter.respond_to?(:call)
|
131
141
|
[name, filter]
|
132
142
|
end
|
@@ -61,8 +61,11 @@ module Temple
|
|
61
61
|
unmatched = []
|
62
62
|
unless match(exp, unmatched)
|
63
63
|
require 'pp'
|
64
|
-
|
65
|
-
|
64
|
+
entry = unmatched.first
|
65
|
+
unmatched.reverse_each do |u|
|
66
|
+
entry = u if u.flatten.size < entry.flatten.size
|
67
|
+
end
|
68
|
+
raise(InvalidExpression, PP.pp(entry.last, "#{@grammar}::#{entry.first} did not match\n"))
|
66
69
|
end
|
67
70
|
end
|
68
71
|
|
data/lib/temple/templates.rb
CHANGED
@@ -6,9 +6,9 @@ module Temple
|
|
6
6
|
|
7
7
|
def self.method_missing(name, engine, options = {})
|
8
8
|
template = Class.new(const_get(name))
|
9
|
-
template.engine
|
10
|
-
template.register_as(options[:register_as]) if options[:register_as]
|
9
|
+
template.default_options[:engine] = engine
|
11
10
|
template.default_options.update(options)
|
11
|
+
template.register_as(options[:register_as]) if options[:register_as]
|
12
12
|
template
|
13
13
|
end
|
14
14
|
end
|
@@ -1,3 +1,7 @@
|
|
1
|
+
unless Object.const_defined?(:Rails)
|
2
|
+
raise "Rails is not loaded - Temple::Templates::Rails cannot be used"
|
3
|
+
end
|
4
|
+
|
1
5
|
if ::Rails::VERSION::MAJOR < 3
|
2
6
|
raise "Temple supports only Rails 3.x and greater, your Rails version is #{::Rails::VERSION::STRING}"
|
3
7
|
end
|
@@ -10,7 +14,8 @@ module Temple
|
|
10
14
|
extend Mixins::Template
|
11
15
|
|
12
16
|
def compile(template)
|
13
|
-
self.class.build_engine
|
17
|
+
self.class.build_engine(:streaming => false, # Overwrite option: No streaming support in Rails < 3.1
|
18
|
+
:file => template.identifier).call(template.source)
|
14
19
|
end
|
15
20
|
|
16
21
|
def self.register_as(name)
|
@@ -21,12 +26,16 @@ module Temple
|
|
21
26
|
class Rails
|
22
27
|
extend Mixins::Template
|
23
28
|
|
24
|
-
def
|
25
|
-
build_engine.call(template.source)
|
29
|
+
def call(template)
|
30
|
+
self.class.build_engine(:file => template.identifier).call(template.source)
|
31
|
+
end
|
32
|
+
|
33
|
+
def supports_streaming?
|
34
|
+
self.class.default_options[:streaming]
|
26
35
|
end
|
27
36
|
|
28
37
|
def self.register_as(name)
|
29
|
-
ActionView::Template.register_template_handler name.to_sym,
|
38
|
+
ActionView::Template.register_template_handler name.to_sym, new
|
30
39
|
end
|
31
40
|
end
|
32
41
|
end
|
@@ -11,7 +11,8 @@ module Temple
|
|
11
11
|
#
|
12
12
|
# @return [void]
|
13
13
|
def prepare
|
14
|
-
@src = self.class.build_engine({ :
|
14
|
+
@src = self.class.build_engine({ :streaming => false, # Overwrite option: No streaming support in Tilt
|
15
|
+
:file => eval_file }, options).call(data)
|
15
16
|
end
|
16
17
|
|
17
18
|
# A string containing the (Ruby) source code for the template.
|
data/lib/temple/version.rb
CHANGED
data/temple.gemspec
CHANGED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Temple::HTML::AttributeMerger do
|
4
|
+
before do
|
5
|
+
@merger = Temple::HTML::AttributeMerger.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should pass static attributes through' do
|
9
|
+
@merger.call([:html, :tag,
|
10
|
+
'div',
|
11
|
+
[:html, :attrs, [:html, :attr, 'class', [:static, 'b']]],
|
12
|
+
[:content]
|
13
|
+
]).should.equal [:html, :tag, "div",
|
14
|
+
[:multi,
|
15
|
+
[:html, :attr, "class", [:static, "b"]]],
|
16
|
+
[:content]]
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should check for empty dynamic attribute' do
|
20
|
+
@merger.call([:html, :tag,
|
21
|
+
'div',
|
22
|
+
[:html, :attrs, [:html, :attr, 'class', [:dynamic, 'b']]],
|
23
|
+
[:content]
|
24
|
+
]).should.equal [:html, :tag, "div",
|
25
|
+
[:multi,
|
26
|
+
[:multi,
|
27
|
+
[:capture, "_temple_html_attributemerger1", [:dynamic, "b"]],
|
28
|
+
[:if, "!_temple_html_attributemerger1.empty?",
|
29
|
+
[:html, :attr, "class", [:dynamic, "_temple_html_attributemerger1"]]]]],
|
30
|
+
[:content]]
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should merge ids' do
|
34
|
+
@merger.call([:html, :tag,
|
35
|
+
'div',
|
36
|
+
[:html, :attrs, [:html, :attr, 'id', [:dynamic, 'a']], [:html, :attr, 'id', [:dynamic, 'b']]],
|
37
|
+
[:content]
|
38
|
+
]).should.equal [:html, :tag, "div",
|
39
|
+
[:multi,
|
40
|
+
[:multi,
|
41
|
+
[:capture, "_temple_html_attributemerger2",
|
42
|
+
[:multi, [:dynamic, "a"],
|
43
|
+
[:capture, "_temple_html_attributemerger1",
|
44
|
+
[:dynamic, "b"]],
|
45
|
+
[:if, "!_temple_html_attributemerger1.empty?",
|
46
|
+
[:multi, [:static, "_"],
|
47
|
+
[:dynamic, "_temple_html_attributemerger1"]]]]],
|
48
|
+
[:if, "!_temple_html_attributemerger2.empty?",
|
49
|
+
[:html, :attr, "id", [:dynamic, "_temple_html_attributemerger2"]]]]],
|
50
|
+
[:content]]
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should merge classes' do
|
54
|
+
@merger.call([:html, :tag,
|
55
|
+
'div',
|
56
|
+
[:html, :attrs, [:html, :attr, 'class', [:static, 'a']], [:html, :attr, 'class', [:dynamic, 'b']]],
|
57
|
+
[:content]
|
58
|
+
]).should.equal [:html, :tag, "div",
|
59
|
+
[:multi,
|
60
|
+
[:html, :attr, "class",
|
61
|
+
[:multi, [:static, "a"],
|
62
|
+
[:capture, "_temple_html_attributemerger1", [:dynamic, "b"]],
|
63
|
+
[:if, "!_temple_html_attributemerger1.empty?",
|
64
|
+
[:multi, [:static, " "],
|
65
|
+
[:dynamic, "_temple_html_attributemerger1"]]]]]],
|
66
|
+
[:content]]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
data/test/html/test_fast.rb
CHANGED
@@ -51,77 +51,18 @@ describe Temple::HTML::Fast do
|
|
51
51
|
[:static, "</div>"]]
|
52
52
|
end
|
53
53
|
|
54
|
-
it 'should compile html with
|
54
|
+
it 'should compile html with attrs' do
|
55
55
|
@html.call([:html, :tag,
|
56
56
|
'div',
|
57
57
|
[:html, :attrs,
|
58
58
|
[:html, :attr, 'id', [:static, 'test']],
|
59
59
|
[:html, :attr, 'class', [:dynamic, 'block']]],
|
60
60
|
[:content]
|
61
|
-
]).should.equal [:multi,
|
62
|
-
[:static,
|
63
|
-
"<div"],
|
64
|
-
[:multi,
|
65
|
-
[:multi,
|
66
|
-
[:capture, "_temple_html_fast1",
|
67
|
-
[:dynamic, "block"]],
|
68
|
-
[:if, "!_temple_html_fast1.empty?",
|
69
|
-
[:multi,
|
70
|
-
[:static, " class='"],
|
71
|
-
[:dynamic, "_temple_html_fast1"],
|
72
|
-
[:static, "'"]]]],
|
73
|
-
[:multi,
|
74
|
-
[:static, " id='"],
|
75
|
-
[:static, "test"],
|
76
|
-
[:static, "'"]]],
|
77
|
-
[:static, ">"],
|
78
|
-
[:content],
|
79
|
-
[:static, "</div>"]]
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'should compile html with merged ids' do
|
83
|
-
@html.call([:html, :tag,
|
84
|
-
'div',
|
85
|
-
[:html, :attrs, [:html, :attr, 'id', [:static, 'a']], [:html, :attr, 'id', [:dynamic, 'b']]],
|
86
|
-
[:content]
|
87
|
-
]).should.equal [:multi,
|
88
|
-
[:static, "<div"],
|
89
|
-
[:multi,
|
90
|
-
[:multi,
|
91
|
-
[:static, " id='"],
|
92
|
-
[:multi,
|
93
|
-
[:static, "a"],
|
94
|
-
[:capture, "_temple_html_fast1",
|
95
|
-
[:dynamic, "b"]],
|
96
|
-
[:if, "!_temple_html_fast1.empty?",
|
97
|
-
[:multi,
|
98
|
-
[:static, "_"],
|
99
|
-
[:dynamic, "_temple_html_fast1"]]]],
|
100
|
-
[:static, "'"]]],
|
101
|
-
[:static, ">"],
|
102
|
-
[:content],
|
103
|
-
[:static, "</div>"]]
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'should compile html with merged classes' do
|
107
|
-
@html.call([:html, :tag,
|
108
|
-
'div',
|
109
|
-
[:html, :attrs, [:html, :attr, 'class', [:static, 'a']], [:html, :attr, 'class', [:dynamic, 'b']]],
|
110
|
-
[:content]
|
111
61
|
]).should.equal [:multi,
|
112
62
|
[:static, "<div"],
|
113
63
|
[:multi,
|
114
|
-
[:multi,
|
115
|
-
|
116
|
-
[:multi,
|
117
|
-
[:static, "a"],
|
118
|
-
[:capture, "_temple_html_fast1",
|
119
|
-
[:dynamic, "b"]],
|
120
|
-
[:if, "!_temple_html_fast1.empty?",
|
121
|
-
[:multi,
|
122
|
-
[:static, " "],
|
123
|
-
[:dynamic, "_temple_html_fast1"]]]],
|
124
|
-
[:static, "'"]]],
|
64
|
+
[:multi, [:static, " id='"], [:static, "test"], [:static, "'"]],
|
65
|
+
[:multi, [:static, " class='"], [:dynamic, "block"], [:static, "'"]]],
|
125
66
|
[:static, ">"],
|
126
67
|
[:content],
|
127
68
|
[:static, "</div>"]]
|
data/test/test_engine.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
require 'helper'
|
3
3
|
|
4
|
-
class
|
4
|
+
class Callable1
|
5
|
+
def call(exp)
|
6
|
+
exp
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Callable2
|
5
11
|
def call(exp)
|
6
12
|
exp
|
7
13
|
end
|
@@ -16,12 +22,13 @@ class TestEngine < Temple::Engine
|
|
16
22
|
use Temple::HTML::Pretty, :format, :pretty => true
|
17
23
|
filter :MultiFlattener
|
18
24
|
generator :ArrayBuffer
|
19
|
-
use :
|
25
|
+
use :BeforeLast, Callable1.new
|
26
|
+
wildcard(:Last) { Callable2.new }
|
20
27
|
end
|
21
28
|
|
22
29
|
describe Temple::Engine do
|
23
30
|
it 'should build chain' do
|
24
|
-
TestEngine.chain.size.should.equal
|
31
|
+
TestEngine.chain.size.should.equal 8
|
25
32
|
|
26
33
|
TestEngine.chain[0].first.should.equal :Parser
|
27
34
|
TestEngine.chain[0].size.should.equal 2
|
@@ -45,8 +52,12 @@ describe Temple::Engine do
|
|
45
52
|
TestEngine.chain[5].should.equal [:ArrayBuffer, Temple::Generators::ArrayBuffer, [], nil]
|
46
53
|
|
47
54
|
TestEngine.chain[6].size.should.equal 2
|
48
|
-
TestEngine.chain[6][0].should.equal :
|
49
|
-
TestEngine.chain[6][1].should.be.instance_of
|
55
|
+
TestEngine.chain[6][0].should.equal :BeforeLast
|
56
|
+
TestEngine.chain[6][1].should.be.instance_of Callable1
|
57
|
+
|
58
|
+
TestEngine.chain[7].size.should.equal 2
|
59
|
+
TestEngine.chain[7][0].should.equal :Last
|
60
|
+
TestEngine.chain[7][1].should.be.instance_of UnboundMethod
|
50
61
|
end
|
51
62
|
|
52
63
|
it 'should instantiate chain' do
|
@@ -57,47 +68,48 @@ describe Temple::Engine do
|
|
57
68
|
call_chain[3].should.be.instance_of Temple::HTML::Pretty
|
58
69
|
call_chain[4].should.be.instance_of Temple::Filters::MultiFlattener
|
59
70
|
call_chain[5].should.be.instance_of Temple::Generators::ArrayBuffer
|
60
|
-
call_chain[6].should.be.instance_of
|
71
|
+
call_chain[6].should.be.instance_of Callable1
|
72
|
+
call_chain[7].should.be.instance_of Callable2
|
61
73
|
end
|
62
74
|
|
63
75
|
it 'should have #append' do
|
64
76
|
engine = TestEngine.new
|
65
77
|
call_chain = engine.send(:call_chain)
|
66
|
-
call_chain.size.should.equal
|
78
|
+
call_chain.size.should.equal 8
|
67
79
|
|
68
80
|
engine.append :MyFilter3 do |exp|
|
69
81
|
exp
|
70
82
|
end
|
71
83
|
|
72
|
-
TestEngine.chain.size.should.equal
|
73
|
-
engine.chain.size.should.equal
|
74
|
-
engine.chain[
|
75
|
-
engine.chain[
|
76
|
-
engine.chain[
|
84
|
+
TestEngine.chain.size.should.equal 8
|
85
|
+
engine.chain.size.should.equal 9
|
86
|
+
engine.chain[8].first.should.equal :MyFilter3
|
87
|
+
engine.chain[8].size.should.equal 2
|
88
|
+
engine.chain[8].last.should.be.instance_of Method
|
77
89
|
|
78
90
|
call_chain = engine.send(:call_chain)
|
79
|
-
call_chain.size.should.equal
|
80
|
-
call_chain[
|
91
|
+
call_chain.size.should.equal 9
|
92
|
+
call_chain[8].should.be.instance_of Method
|
81
93
|
end
|
82
94
|
|
83
95
|
it 'should have #prepend' do
|
84
96
|
engine = TestEngine.new
|
85
97
|
call_chain = engine.send(:call_chain)
|
86
|
-
call_chain.size.should.equal
|
98
|
+
call_chain.size.should.equal 8
|
87
99
|
|
88
100
|
engine.prepend :MyFilter0 do |exp|
|
89
101
|
exp
|
90
102
|
end
|
91
103
|
|
92
|
-
TestEngine.chain.size.should.equal
|
93
|
-
engine.chain.size.should.equal
|
104
|
+
TestEngine.chain.size.should.equal 8
|
105
|
+
engine.chain.size.should.equal 9
|
94
106
|
engine.chain[0].first.should.equal :MyFilter0
|
95
107
|
engine.chain[0].size.should.equal 2
|
96
108
|
engine.chain[0].last.should.be.instance_of Method
|
97
109
|
engine.chain[1].first.should.equal :Parser
|
98
110
|
|
99
111
|
call_chain = engine.send(:call_chain)
|
100
|
-
call_chain.size.should.equal
|
112
|
+
call_chain.size.should.equal 9
|
101
113
|
call_chain[0].should.be.instance_of Method
|
102
114
|
end
|
103
115
|
|
@@ -106,7 +118,7 @@ describe Temple::Engine do
|
|
106
118
|
engine.after :Parser, :MyFilter0 do |exp|
|
107
119
|
exp
|
108
120
|
end
|
109
|
-
engine.chain.size.should.equal
|
121
|
+
engine.chain.size.should.equal 9
|
110
122
|
engine.chain[0].first.should.equal :Parser
|
111
123
|
engine.chain[1].first.should.equal :MyFilter0
|
112
124
|
engine.chain[2].first.should.equal :MyFilter1
|
@@ -117,7 +129,7 @@ describe Temple::Engine do
|
|
117
129
|
engine.before :MyFilter1, :MyFilter0 do |exp|
|
118
130
|
exp
|
119
131
|
end
|
120
|
-
engine.chain.size.should.equal
|
132
|
+
engine.chain.size.should.equal 9
|
121
133
|
engine.chain[0].first.should.equal :Parser
|
122
134
|
engine.chain[1].first.should.equal :MyFilter0
|
123
135
|
engine.chain[2].first.should.equal :MyFilter1
|
@@ -126,7 +138,7 @@ describe Temple::Engine do
|
|
126
138
|
it 'should have #remove' do
|
127
139
|
engine = TestEngine.new
|
128
140
|
engine.remove :MyFilter1
|
129
|
-
engine.chain.size.should.equal
|
141
|
+
engine.chain.size.should.equal 7
|
130
142
|
engine.chain[0].first.should.equal :Parser
|
131
143
|
engine.chain[1].first.should.equal :MyFilter2
|
132
144
|
end
|
@@ -136,24 +148,24 @@ describe Temple::Engine do
|
|
136
148
|
engine.before :Parser, :MyParser do |exp|
|
137
149
|
exp
|
138
150
|
end
|
139
|
-
engine.chain.size.should.equal
|
151
|
+
engine.chain.size.should.equal 9
|
140
152
|
engine.chain[0].first.should.equal :MyParser
|
141
153
|
end
|
142
154
|
|
143
155
|
it 'should work with inheritance' do
|
144
156
|
inherited_engine = Class.new(TestEngine)
|
145
|
-
inherited_engine.chain.size.should.equal
|
157
|
+
inherited_engine.chain.size.should.equal 8
|
146
158
|
inherited_engine.append :MyFilter3 do |exp|
|
147
159
|
exp
|
148
160
|
end
|
149
|
-
inherited_engine.chain.size.should.equal
|
150
|
-
TestEngine.chain.size.should.equal
|
161
|
+
inherited_engine.chain.size.should.equal 9
|
162
|
+
TestEngine.chain.size.should.equal 8
|
151
163
|
end
|
152
164
|
|
153
165
|
it 'should support chain option' do
|
154
166
|
engine = TestEngine.new(:chain => proc {|e| e.remove :MyFilter1 })
|
155
|
-
TestEngine.chain.size.should.equal
|
156
|
-
engine.chain.size.should.equal
|
167
|
+
TestEngine.chain.size.should.equal 8
|
168
|
+
engine.chain.size.should.equal 7
|
157
169
|
engine.chain[0].first.should.equal :Parser
|
158
170
|
engine.chain[1].first.should.equal :MyFilter2
|
159
171
|
end
|
data/test/test_grammar.rb
CHANGED
@@ -44,9 +44,4 @@ describe Temple::Grammar do
|
|
44
44
|
Temple::Grammar.should.match [:html, :tag, 'Tag', [:html, :attrs, [:html, :attr, 'id',
|
45
45
|
[:static, 'val']]], [:static, 'Text']]
|
46
46
|
end
|
47
|
-
|
48
|
-
it 'should not match lone html attributes' do
|
49
|
-
Temple::Grammar.should.not.match [:html, :attr, 'id', [:multi]]
|
50
|
-
Temple::Grammar.should.not.match [:html, :attrs]
|
51
|
-
end
|
52
47
|
end
|
metadata
CHANGED
@@ -1,55 +1,64 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: temple
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.4
|
4
5
|
prerelease:
|
5
|
-
version: 0.3.2
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Magnus Holm
|
9
9
|
- Daniel Mendler
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
- !ruby/object:Gem::Dependency
|
13
|
+
date: 2011-09-02 00:00:00.000000000Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
17
16
|
name: tilt
|
18
|
-
|
19
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: &70118806201520 !ruby/object:Gem::Requirement
|
20
18
|
none: false
|
21
|
-
requirements:
|
22
|
-
- -
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version:
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
25
23
|
type: :development
|
26
|
-
|
27
|
-
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *70118806201520
|
26
|
+
- !ruby/object:Gem::Dependency
|
28
27
|
name: bacon
|
28
|
+
requirement: &70118806201100 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
29
35
|
prerelease: false
|
30
|
-
|
36
|
+
version_requirements: *70118806201100
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rake
|
39
|
+
requirement: &70118806200640 !ruby/object:Gem::Requirement
|
31
40
|
none: false
|
32
|
-
requirements:
|
33
|
-
- -
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
version:
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
36
45
|
type: :development
|
37
|
-
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *70118806200640
|
38
48
|
description:
|
39
|
-
email:
|
49
|
+
email:
|
40
50
|
- judofyr@gmail.com
|
41
51
|
- mail@daniel-mendler.de
|
42
52
|
executables: []
|
43
|
-
|
44
53
|
extensions: []
|
45
|
-
|
46
54
|
extra_rdoc_files: []
|
47
|
-
|
48
|
-
files:
|
55
|
+
files:
|
49
56
|
- .gitignore
|
57
|
+
- .travis.yml
|
50
58
|
- .yardopts
|
51
59
|
- CHANGES
|
52
60
|
- EXPRESSIONS.md
|
61
|
+
- Gemfile
|
53
62
|
- LICENSE
|
54
63
|
- README.md
|
55
64
|
- Rakefile
|
@@ -70,6 +79,7 @@ files:
|
|
70
79
|
- lib/temple/generators.rb
|
71
80
|
- lib/temple/grammar.rb
|
72
81
|
- lib/temple/hash.rb
|
82
|
+
- lib/temple/html/attribute_merger.rb
|
73
83
|
- lib/temple/html/dispatcher.rb
|
74
84
|
- lib/temple/html/fast.rb
|
75
85
|
- lib/temple/html/filter.rb
|
@@ -92,6 +102,7 @@ files:
|
|
92
102
|
- test/filters/test_multi_flattener.rb
|
93
103
|
- test/filters/test_static_merger.rb
|
94
104
|
- test/helper.rb
|
105
|
+
- test/html/test_attribute_merger.rb
|
95
106
|
- test/html/test_fast.rb
|
96
107
|
- test/html/test_pretty.rb
|
97
108
|
- test/mixins/test_dispatcher.rb
|
@@ -105,32 +116,29 @@ files:
|
|
105
116
|
- test/test_utils.rb
|
106
117
|
homepage: http://dojo.rubyforge.org/
|
107
118
|
licenses: []
|
108
|
-
|
109
119
|
post_install_message:
|
110
120
|
rdoc_options: []
|
111
|
-
|
112
|
-
require_paths:
|
121
|
+
require_paths:
|
113
122
|
- lib
|
114
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
124
|
none: false
|
116
|
-
requirements:
|
117
|
-
- -
|
118
|
-
- !ruby/object:Gem::Version
|
119
|
-
version:
|
120
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ! '>='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
130
|
none: false
|
122
|
-
requirements:
|
123
|
-
- -
|
124
|
-
- !ruby/object:Gem::Version
|
125
|
-
version:
|
131
|
+
requirements:
|
132
|
+
- - ! '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
126
135
|
requirements: []
|
127
|
-
|
128
136
|
rubyforge_project:
|
129
|
-
rubygems_version: 1.8.
|
137
|
+
rubygems_version: 1.8.6
|
130
138
|
signing_key:
|
131
139
|
specification_version: 3
|
132
140
|
summary: Template compilation framework in Ruby
|
133
|
-
test_files:
|
141
|
+
test_files:
|
134
142
|
- test/filters/test_control_flow.rb
|
135
143
|
- test/filters/test_dynamic_inliner.rb
|
136
144
|
- test/filters/test_eraser.rb
|
@@ -138,6 +146,7 @@ test_files:
|
|
138
146
|
- test/filters/test_multi_flattener.rb
|
139
147
|
- test/filters/test_static_merger.rb
|
140
148
|
- test/helper.rb
|
149
|
+
- test/html/test_attribute_merger.rb
|
141
150
|
- test/html/test_fast.rb
|
142
151
|
- test/html/test_pretty.rb
|
143
152
|
- test/mixins/test_dispatcher.rb
|