temple 0.4.0 → 0.4.1
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/CHANGES +7 -0
- data/EXPRESSIONS.md +7 -0
- data/README.md +2 -0
- data/lib/temple/engine.rb +1 -13
- data/lib/temple/filters/dynamic_inliner.rb +1 -1
- data/lib/temple/filters/static_merger.rb +2 -3
- data/lib/temple/generators.rb +28 -3
- data/lib/temple/grammar.rb +1 -0
- data/lib/temple/html/dispatcher.rb +4 -0
- data/lib/temple/html/fast.rb +7 -0
- data/lib/temple/html/pretty.rb +1 -1
- data/lib/temple/mixins/dispatcher.rb +13 -30
- data/lib/temple/mixins/engine_dsl.rb +56 -38
- data/lib/temple/mixins/grammar_dsl.rb +1 -1
- data/lib/temple/mixins/template.rb +17 -0
- data/lib/temple/templates.rb +1 -5
- data/lib/temple/templates/tilt.rb +4 -0
- data/lib/temple/version.rb +1 -1
- data/test/filters/test_dynamic_inliner.rb +8 -13
- data/test/filters/test_static_merger.rb +1 -3
- data/test/mixins/test_dispatcher.rb +17 -4
- data/test/test_engine.rb +18 -15
- data/test/test_generator.rb +13 -4
- metadata +25 -9
data/CHANGES
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
0.4.1
|
2
|
+
|
3
|
+
* Generators: produce optimized code
|
4
|
+
* remove deprecated method EngineDSL#wildcard
|
5
|
+
* Set tilt template default_mime_type to text/html
|
6
|
+
* HTML: Support conditional comments [:html, :condcomment, ...]
|
7
|
+
|
1
8
|
0.4.0
|
2
9
|
|
3
10
|
* Split Temple::HTML::AttributeMerger in AttributeSorter,
|
data/EXPRESSIONS.md
CHANGED
@@ -210,6 +210,13 @@ Example:
|
|
210
210
|
generates:
|
211
211
|
<!--comment-->
|
212
212
|
|
213
|
+
### [:html, :condcomment, condition, sexp]
|
214
|
+
|
215
|
+
Example:
|
216
|
+
[:html, :condcomment, 'IE', [:static, 'comment']]
|
217
|
+
generates:
|
218
|
+
<!--[if IE]>comment<![endif]-->
|
219
|
+
|
213
220
|
### [:html, :tag, identifier, attributes, optional-sexp]
|
214
221
|
|
215
222
|
HTML tag abstraction. Identifier can be a String or a Symbol. If the optional content Sexp is omitted
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
Temple
|
2
2
|
======
|
3
3
|
|
4
|
+
[](http://travis-ci.org/judofyr/temple) [](https://gemnasium.com/judofyr/temple) [](https://codeclimate.com/github/judofyr/temple)
|
5
|
+
|
4
6
|
Temple is an abstraction and a framework for compiling templates to pure Ruby.
|
5
7
|
It's all about making it easier to experiment, implement and optimize template
|
6
8
|
languages. If you're interested in implementing your own template language, or
|
data/lib/temple/engine.rb
CHANGED
@@ -56,19 +56,7 @@ module Temple
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def call_chain
|
59
|
-
@call_chain ||= @chain.map
|
60
|
-
name, filter, option_filter, local_options = e
|
61
|
-
case filter
|
62
|
-
when Class
|
63
|
-
filtered_options = Hash[*option_filter.select {|k| options.include?(k) }.map {|k| [k, options[k]] }.flatten]
|
64
|
-
filter.new(ImmutableHash.new(local_options, filtered_options))
|
65
|
-
when UnboundMethod
|
66
|
-
filter = filter.bind(self)
|
67
|
-
filter.arity == 1 ? filter : filter.call
|
68
|
-
else
|
69
|
-
filter
|
70
|
-
end
|
71
|
-
end.compact
|
59
|
+
@call_chain ||= @chain.map {|name, constructor| constructor.call(self) }.compact
|
72
60
|
end
|
73
61
|
end
|
74
62
|
end
|
@@ -8,8 +8,7 @@ module Temple
|
|
8
8
|
#
|
9
9
|
# Compiles to:
|
10
10
|
#
|
11
|
-
# [:
|
12
|
-
# [:static, "Hello World!"]]
|
11
|
+
# [:static, "Hello World!"]
|
13
12
|
#
|
14
13
|
# @api public
|
15
14
|
class StaticMerger < Filter
|
@@ -31,7 +30,7 @@ module Temple
|
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
34
|
-
result
|
33
|
+
result.size == 2 ? result[1] : result
|
35
34
|
end
|
36
35
|
end
|
37
36
|
end
|
data/lib/temple/generators.rb
CHANGED
@@ -65,7 +65,7 @@ module Temple
|
|
65
65
|
# _buf = []
|
66
66
|
# _buf << "static"
|
67
67
|
# _buf << dynamic
|
68
|
-
# _buf
|
68
|
+
# _buf
|
69
69
|
#
|
70
70
|
# @api public
|
71
71
|
class Array < Generator
|
@@ -79,8 +79,25 @@ module Temple
|
|
79
79
|
end
|
80
80
|
|
81
81
|
# Just like Array, but calls #join on the array.
|
82
|
+
#
|
83
|
+
# _buf = []
|
84
|
+
# _buf << "static"
|
85
|
+
# _buf << dynamic
|
86
|
+
# _buf.join
|
87
|
+
#
|
82
88
|
# @api public
|
83
89
|
class ArrayBuffer < Array
|
90
|
+
def call(exp)
|
91
|
+
case exp.first
|
92
|
+
when :static
|
93
|
+
"#{buffer} = #{exp.last.inspect}"
|
94
|
+
when :dynamic
|
95
|
+
"#{buffer} = (#{exp.last}).to_s"
|
96
|
+
else
|
97
|
+
super
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
84
101
|
def postamble
|
85
102
|
"#{buffer} = #{buffer}.join"
|
86
103
|
end
|
@@ -94,11 +111,15 @@ module Temple
|
|
94
111
|
# _buf
|
95
112
|
#
|
96
113
|
# @api public
|
97
|
-
class StringBuffer <
|
114
|
+
class StringBuffer < ArrayBuffer
|
98
115
|
def preamble
|
99
116
|
"#{buffer} = ''"
|
100
117
|
end
|
101
118
|
|
119
|
+
def postamble
|
120
|
+
buffer
|
121
|
+
end
|
122
|
+
|
102
123
|
def on_dynamic(code)
|
103
124
|
concat("(#{code}).to_s")
|
104
125
|
end
|
@@ -106,7 +127,7 @@ module Temple
|
|
106
127
|
|
107
128
|
# Implements a rails output buffer.
|
108
129
|
#
|
109
|
-
# @output_buffer = ActionView::
|
130
|
+
# @output_buffer = ActionView::SafeBuffer
|
110
131
|
# @output_buffer.safe_concat "static"
|
111
132
|
# @output_buffer.safe_concat dynamic.to_s
|
112
133
|
# @output_buffer
|
@@ -118,6 +139,10 @@ module Temple
|
|
118
139
|
# output_buffer is needed for Rails 3.1 Streaming support
|
119
140
|
:capture_generator => RailsOutputBuffer
|
120
141
|
|
142
|
+
def call(exp)
|
143
|
+
[preamble, compile(exp), postamble].join('; ')
|
144
|
+
end
|
145
|
+
|
121
146
|
def preamble
|
122
147
|
if options[:streaming] && options[:buffer] == '@output_buffer'
|
123
148
|
"#{buffer} = output_buffer || #{options[:buffer_class]}.new"
|
data/lib/temple/grammar.rb
CHANGED
@@ -14,6 +14,10 @@ module Temple
|
|
14
14
|
[:html, :comment, compile(content)]
|
15
15
|
end
|
16
16
|
|
17
|
+
def on_html_condcomment(condition, content)
|
18
|
+
[:html, :condcomment, condition, compile(content)]
|
19
|
+
end
|
20
|
+
|
17
21
|
def on_html_tag(name, attrs, content = nil)
|
18
22
|
result = [:html, :tag, name, compile(attrs)]
|
19
23
|
content ? (result << compile(content)) : result
|
data/lib/temple/html/fast.rb
CHANGED
@@ -65,6 +65,13 @@ module Temple
|
|
65
65
|
[:static, '-->']]
|
66
66
|
end
|
67
67
|
|
68
|
+
def on_html_condcomment(condition, content)
|
69
|
+
on_html_comment [:multi,
|
70
|
+
[:static, "[#{condition}]>"],
|
71
|
+
content,
|
72
|
+
[:static, '<![endif]']]
|
73
|
+
end
|
74
|
+
|
68
75
|
def on_html_tag(name, attrs, content = nil)
|
69
76
|
name = name.to_s
|
70
77
|
closed = !content || (empty_exp?(content) && options[:autoclose].include?(name))
|
data/lib/temple/html/pretty.rb
CHANGED
@@ -6,7 +6,7 @@ module Temple
|
|
6
6
|
:pretty => true,
|
7
7
|
:indent_tags => %w(article aside audio base body datalist dd div dl dt
|
8
8
|
fieldset figure footer form head h1 h2 h3 h4 h5 h6
|
9
|
-
header hgroup hr html
|
9
|
+
header hgroup hr html li link meta nav ol p
|
10
10
|
rp rt ruby section script style table tbody td tfoot
|
11
11
|
th thead title tr ul video).freeze,
|
12
12
|
:pre_tags => %w(code pre textarea).freeze
|
@@ -60,15 +60,10 @@ module Temple
|
|
60
60
|
dispatched_methods.each do |method|
|
61
61
|
method.split('_')[1..-1].inject(tree) {|node, type| node[type.to_sym] }.method = method
|
62
62
|
end
|
63
|
-
self.class.class_eval %{
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
else
|
68
|
-
replace_dispatcher(exp)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
}
|
63
|
+
self.class.class_eval %{def dispatcher(exp)
|
64
|
+
return replace_dispatcher(exp) if self.class != #{self.class}
|
65
|
+
#{tree.compile.gsub("\n", "\n ")}
|
66
|
+
end}
|
72
67
|
dispatcher(exp)
|
73
68
|
end
|
74
69
|
|
@@ -86,31 +81,19 @@ module Temple
|
|
86
81
|
@method = nil
|
87
82
|
end
|
88
83
|
|
89
|
-
def compile(level = 0,
|
84
|
+
def compile(level = 0, call_parent = nil)
|
85
|
+
call_method = method ? (level == 0 ? "#{method}(*exp)" :
|
86
|
+
"#{method}(*exp[#{level}..-1])") : call_parent
|
90
87
|
if empty?
|
91
|
-
|
92
|
-
|
93
|
-
elsif !parent
|
94
|
-
'exp'
|
95
|
-
else
|
96
|
-
raise 'Invalid dispatcher node'
|
97
|
-
end
|
88
|
+
raise 'Invalid dispatcher node' unless method
|
89
|
+
call_method
|
98
90
|
else
|
99
|
-
code =
|
91
|
+
code = "case(exp[#{level}])\n"
|
100
92
|
each do |key, child|
|
101
|
-
code <<
|
102
|
-
|
103
|
-
end
|
104
|
-
if method || !parent
|
105
|
-
code << (' ' * level) + "else"
|
106
|
-
if method
|
107
|
-
code << (' ' * level) + " #{method}(*exp[#{level}..-1])"
|
108
|
-
else
|
109
|
-
code << (' ' * level) + " exp"
|
110
|
-
end
|
93
|
+
code << "when #{key.inspect}\n " <<
|
94
|
+
child.compile(level + 1, call_method).gsub("\n", "\n ") << "\n"
|
111
95
|
end
|
112
|
-
code << ('
|
113
|
-
code.join("\n")
|
96
|
+
code << "else\n " << (call_method || 'exp') << "\nend"
|
114
97
|
end
|
115
98
|
end
|
116
99
|
end
|
@@ -6,21 +6,24 @@ module Temple
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def append(*args, &block)
|
9
|
-
chain <<
|
9
|
+
chain << chain_element(args, block)
|
10
10
|
chain_modified!
|
11
11
|
end
|
12
12
|
|
13
13
|
def prepend(*args, &block)
|
14
|
-
chain.unshift(
|
14
|
+
chain.unshift(chain_element(args, block))
|
15
15
|
chain_modified!
|
16
16
|
end
|
17
17
|
|
18
18
|
def remove(name)
|
19
|
+
name = chain_name(name)
|
19
20
|
found = false
|
20
21
|
chain.reject! do |i|
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
if i.first == name
|
23
|
+
found = true
|
24
|
+
else
|
25
|
+
false
|
26
|
+
end
|
24
27
|
end
|
25
28
|
raise "#{name} not found" unless found
|
26
29
|
chain_modified!
|
@@ -28,20 +31,9 @@ module Temple
|
|
28
31
|
|
29
32
|
alias use append
|
30
33
|
|
31
|
-
# DEPRECATED!
|
32
|
-
#
|
33
|
-
# wildcard(:FilterName) { FilterClass.new(options) }
|
34
|
-
#
|
35
|
-
# is replaced by
|
36
|
-
#
|
37
|
-
# use(:FilterName) { FilterClass.new(options) }
|
38
|
-
#
|
39
|
-
alias wildcard use
|
40
|
-
|
41
34
|
def before(name, *args, &block)
|
42
|
-
name =
|
43
|
-
|
44
|
-
e = element(args, block)
|
35
|
+
name = chain_name(name)
|
36
|
+
e = chain_element(args, block)
|
45
37
|
found, i = false, 0
|
46
38
|
while i < chain.size
|
47
39
|
if chain[i].first == name
|
@@ -57,9 +49,8 @@ module Temple
|
|
57
49
|
end
|
58
50
|
|
59
51
|
def after(name, *args, &block)
|
60
|
-
name =
|
61
|
-
|
62
|
-
e = element(args, block)
|
52
|
+
name = chain_name(name)
|
53
|
+
e = chain_element(args, block)
|
63
54
|
found, i = false, 0
|
64
55
|
while i < chain.size
|
65
56
|
if chain[i].first == name
|
@@ -74,9 +65,8 @@ module Temple
|
|
74
65
|
end
|
75
66
|
|
76
67
|
def replace(name, *args, &block)
|
77
|
-
name =
|
78
|
-
|
79
|
-
e = element(args, block)
|
68
|
+
name = chain_name(name)
|
69
|
+
e = chain_element(args, block)
|
80
70
|
found = false
|
81
71
|
chain.each_with_index do |c, i|
|
82
72
|
if c.first == name
|
@@ -99,23 +89,55 @@ module Temple
|
|
99
89
|
|
100
90
|
private
|
101
91
|
|
102
|
-
def
|
92
|
+
def chain_name(name)
|
93
|
+
name = Class === name ? name.name.to_sym : name
|
94
|
+
raise(ArgumentError, 'Name argument must be Class or Symbol') unless Symbol === name
|
95
|
+
name
|
96
|
+
end
|
97
|
+
|
98
|
+
def chain_class_constructor(filter, option_filter)
|
99
|
+
local_options = Hash === option_filter.last ? option_filter.pop : nil
|
100
|
+
raise(ArgumentError, 'Only symbols allowed in option filter') unless option_filter.all? {|o| Symbol === o }
|
101
|
+
proc do |engine|
|
102
|
+
filtered_options = Hash[*option_filter.select {|k| engine.options.include?(k) }.map {|k| [k, engine.options[k]] }.flatten]
|
103
|
+
filter.new(ImmutableHash.new(local_options, filtered_options))
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def chain_proc_constructor(name, filter)
|
108
|
+
raise(ArgumentError, 'Proc or blocks must have arity 0 or 1') if filter.arity > 1
|
109
|
+
method_name = "FILTER #{name}"
|
103
110
|
if Class === self
|
104
|
-
define_method(
|
105
|
-
instance_method(
|
111
|
+
define_method(method_name, &filter)
|
112
|
+
filter = instance_method(method_name)
|
113
|
+
if filter.arity == 1
|
114
|
+
proc {|engine| filter.bind(engine) }
|
115
|
+
else
|
116
|
+
proc do |engine|
|
117
|
+
f = filter.bind(engine).call
|
118
|
+
raise 'Constructor must return callable object' unless f.respond_to?(:call)
|
119
|
+
f
|
120
|
+
end
|
121
|
+
end
|
106
122
|
else
|
107
|
-
(class << self; self; end).class_eval { define_method(
|
108
|
-
method(
|
123
|
+
(class << self; self; end).class_eval { define_method(method_name, &filter) }
|
124
|
+
filter = method(method_name)
|
125
|
+
proc {|engine| filter }
|
109
126
|
end
|
110
127
|
end
|
111
128
|
|
112
|
-
def
|
129
|
+
def chain_callable_constructor(filter)
|
130
|
+
raise(ArgumentError, 'Class or callable argument is required') unless filter.respond_to?(:call)
|
131
|
+
proc {|engine| filter }
|
132
|
+
end
|
133
|
+
|
134
|
+
def chain_element(args, block)
|
113
135
|
name = args.shift
|
114
136
|
if Class === name
|
115
137
|
filter = name
|
116
138
|
name = filter.name.to_sym
|
117
139
|
else
|
118
|
-
raise(ArgumentError, '
|
140
|
+
raise(ArgumentError, 'Name argument must be Class or Symbol') unless Symbol === name
|
119
141
|
end
|
120
142
|
|
121
143
|
if block
|
@@ -131,20 +153,16 @@ module Temple
|
|
131
153
|
# The proc is converted to a method of the engine class.
|
132
154
|
# The proc can then access the option hash of the engine.
|
133
155
|
raise(ArgumentError, 'Too many arguments') unless args.empty?
|
134
|
-
|
135
|
-
[name, define_chain_method("FILTER #{name}", filter)]
|
156
|
+
[name, chain_proc_constructor(name, filter)]
|
136
157
|
when Class
|
137
158
|
# Class argument (e.g Filter class)
|
138
159
|
# The options are passed to the classes constructor.
|
139
|
-
|
140
|
-
raise(ArgumentError, 'Only symbols allowed in option filter') unless args.all? {|o| Symbol === o }
|
141
|
-
[name, filter, args, local_options]
|
160
|
+
[name, chain_class_constructor(filter, args)]
|
142
161
|
else
|
143
162
|
# Other callable argument (e.g. Object of class which implements #call or Method)
|
144
163
|
# The callable has no access to the option hash of the engine.
|
145
164
|
raise(ArgumentError, 'Too many arguments') unless args.empty?
|
146
|
-
|
147
|
-
[name, filter]
|
165
|
+
[name, chain_callable_constructor(filter)]
|
148
166
|
end
|
149
167
|
end
|
150
168
|
end
|
@@ -33,7 +33,7 @@ module Temple
|
|
33
33
|
|
34
34
|
def match(exp, unmatched)
|
35
35
|
tmp = []
|
36
|
-
@children.any? {|rule| rule.match(exp, tmp) } || (unmatched.
|
36
|
+
@children.any? {|rule| rule.match(exp, tmp) } || (unmatched.concat(tmp) && false)
|
37
37
|
end
|
38
38
|
|
39
39
|
def after_copy(source)
|
@@ -9,6 +9,23 @@ module Temple
|
|
9
9
|
default_options[:engine]
|
10
10
|
end
|
11
11
|
|
12
|
+
def init
|
13
|
+
# Overwrite this for class initialization
|
14
|
+
end
|
15
|
+
|
16
|
+
def register_as(name)
|
17
|
+
raise NotImplementedError
|
18
|
+
end
|
19
|
+
|
20
|
+
def create(engine, options)
|
21
|
+
template = Class.new(self)
|
22
|
+
template.default_options[:engine] = engine
|
23
|
+
template.default_options.update(options)
|
24
|
+
template.init
|
25
|
+
template.register_as(options[:register_as]) if options[:register_as]
|
26
|
+
template
|
27
|
+
end
|
28
|
+
|
12
29
|
def build_engine(*options)
|
13
30
|
raise 'No engine configured' unless engine
|
14
31
|
options << default_options
|
data/lib/temple/templates.rb
CHANGED
@@ -5,11 +5,7 @@ module Temple
|
|
5
5
|
autoload :Rails, 'temple/templates/rails'
|
6
6
|
|
7
7
|
def self.method_missing(name, engine, options = {})
|
8
|
-
|
9
|
-
template.default_options[:engine] = engine
|
10
|
-
template.default_options.update(options)
|
11
|
-
template.register_as(options[:register_as]) if options[:register_as]
|
12
|
-
template
|
8
|
+
const_get(name).create(engine, options)
|
13
9
|
end
|
14
10
|
end
|
15
11
|
end
|
data/lib/temple/version.rb
CHANGED
@@ -10,7 +10,7 @@ describe Temple::Filters::DynamicInliner do
|
|
10
10
|
[:static, "Hello "],
|
11
11
|
[:static, "World\n "],
|
12
12
|
[:static, "Have a nice day"]
|
13
|
-
]).should.equal [:
|
13
|
+
]).should.equal [:dynamic, '"Hello World\n Have a nice day"']
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should compile several dynamics into dynamic' do
|
@@ -18,7 +18,7 @@ describe Temple::Filters::DynamicInliner do
|
|
18
18
|
[:dynamic, "@hello"],
|
19
19
|
[:dynamic, "@world"],
|
20
20
|
[:dynamic, "@yeah"]
|
21
|
-
]).should.equal [:
|
21
|
+
]).should.equal [:dynamic, '"#{@hello}#{@world}#{@yeah}"']
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'should compile static and dynamic into dynamic' do
|
@@ -27,7 +27,7 @@ describe Temple::Filters::DynamicInliner do
|
|
27
27
|
[:dynamic, "@world"],
|
28
28
|
[:dynamic, "@yeah"],
|
29
29
|
[:static, "Nice"]
|
30
|
-
]).should.equal [:
|
30
|
+
]).should.equal [:dynamic, '"Hello#{@world}#{@yeah}Nice"']
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'should merge statics and dynamics around a code' do
|
@@ -45,18 +45,15 @@ describe Temple::Filters::DynamicInliner do
|
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'should keep codes intact' do
|
48
|
-
|
49
|
-
@filter.call(exp).should.equal exp
|
48
|
+
@filter.call([:multi, [:code, 'foo']]).should.equal [:code, 'foo']
|
50
49
|
end
|
51
50
|
|
52
51
|
it 'should keep single statics intact' do
|
53
|
-
|
54
|
-
@filter.call(exp).should.equal exp
|
52
|
+
@filter.call([:multi, [:static, 'foo']]).should.equal [:static, 'foo']
|
55
53
|
end
|
56
54
|
|
57
55
|
it 'should keep single dynamic intact' do
|
58
|
-
|
59
|
-
@filter.call(exp).should.equal exp
|
56
|
+
@filter.call([:multi, [:dynamic, 'foo']]).should.equal [:dynamic, 'foo']
|
60
57
|
end
|
61
58
|
|
62
59
|
it 'should inline inside multi' do
|
@@ -70,7 +67,7 @@ describe Temple::Filters::DynamicInliner do
|
|
70
67
|
[:dynamic, "@world"]
|
71
68
|
]).should.equal [:multi,
|
72
69
|
[:dynamic, '"Hello #{@world}"'],
|
73
|
-
[:
|
70
|
+
[:dynamic, '"Hello #{@world}"'],
|
74
71
|
[:dynamic, '"Hello #{@world}"']
|
75
72
|
]
|
76
73
|
end
|
@@ -81,9 +78,7 @@ describe Temple::Filters::DynamicInliner do
|
|
81
78
|
[:newline],
|
82
79
|
[:dynamic, "@world"],
|
83
80
|
[:newline]
|
84
|
-
]).should.equal [:
|
85
|
-
[:dynamic, ['"Hello \n"', '"#{@world}"', '""'].join("\\\n")]
|
86
|
-
]
|
81
|
+
]).should.equal [:dynamic, ['"Hello \n"', '"#{@world}"', '""'].join("\\\n")]
|
87
82
|
end
|
88
83
|
|
89
84
|
it 'should compile static followed by newline' do
|
@@ -10,9 +10,7 @@ describe Temple::Filters::StaticMerger do
|
|
10
10
|
[:static, "Hello "],
|
11
11
|
[:static, "World, "],
|
12
12
|
[:static, "Good night"]
|
13
|
-
]).should.equal [:
|
14
|
-
[:static, "Hello World, Good night"]
|
15
|
-
]
|
13
|
+
]).should.equal [:static, "Hello World, Good night"]
|
16
14
|
end
|
17
15
|
|
18
16
|
it 'should merge serveral statics around code' do
|
@@ -15,8 +15,16 @@ class FilterWithDispatcherMixin
|
|
15
15
|
[:on_second_test, arg]
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
[:
|
18
|
+
def on_a_b(*arg)
|
19
|
+
[:on_ab, *arg]
|
20
|
+
end
|
21
|
+
|
22
|
+
def on_a_b_test(arg)
|
23
|
+
[:on_ab_test, arg]
|
24
|
+
end
|
25
|
+
|
26
|
+
def on_a_b_c_d_test(arg)
|
27
|
+
[:on_abcd_test, arg]
|
20
28
|
end
|
21
29
|
end
|
22
30
|
|
@@ -47,8 +55,13 @@ describe Temple::Mixins::Dispatcher do
|
|
47
55
|
@filter.call([:test, :check, 42]).should.equal [:on_check, 42]
|
48
56
|
end
|
49
57
|
|
50
|
-
it 'should dispatch
|
51
|
-
@filter.call([:
|
58
|
+
it 'should dispatch parent level' do
|
59
|
+
@filter.call([:a, 42]).should == [:a, 42]
|
60
|
+
@filter.call([:a, :b, 42]).should == [:on_ab, 42]
|
61
|
+
@filter.call([:a, :b, :test, 42]).should == [:on_ab_test, 42]
|
62
|
+
@filter.call([:a, :b, :c, 42]).should == [:on_ab, :c, 42]
|
63
|
+
@filter.call([:a, :b, :c, :d, 42]).should == [:on_ab, :c, :d, 42]
|
64
|
+
@filter.call([:a, :b, :c, :d, :test, 42]).should == [:on_abcd_test, 42]
|
52
65
|
end
|
53
66
|
|
54
67
|
it 'should dispatch zero level' do
|
data/test/test_engine.rb
CHANGED
@@ -32,32 +32,35 @@ describe Temple::Engine do
|
|
32
32
|
|
33
33
|
TestEngine.chain[0].first.should.equal :Parser
|
34
34
|
TestEngine.chain[0].size.should.equal 2
|
35
|
-
TestEngine.chain[0].last.should.be.instance_of
|
35
|
+
TestEngine.chain[0].last.should.be.instance_of Proc
|
36
36
|
|
37
37
|
TestEngine.chain[1].first.should.equal :MyFilter1
|
38
38
|
TestEngine.chain[1].size.should.equal 2
|
39
|
-
TestEngine.chain[1].last.should.be.instance_of
|
39
|
+
TestEngine.chain[1].last.should.be.instance_of Proc
|
40
40
|
|
41
41
|
TestEngine.chain[2].first.should.equal :MyFilter2
|
42
42
|
TestEngine.chain[2].size.should.equal 2
|
43
|
-
TestEngine.chain[2].last.should.be.instance_of
|
43
|
+
TestEngine.chain[2].last.should.be.instance_of Proc
|
44
44
|
|
45
|
-
TestEngine.chain[3].
|
46
|
-
TestEngine.chain[3].should.equal
|
45
|
+
TestEngine.chain[3].first.should.equal :'Temple::HTML::Pretty'
|
46
|
+
TestEngine.chain[3].size.should.equal 2
|
47
|
+
TestEngine.chain[3].last.should.be.instance_of Proc
|
47
48
|
|
48
|
-
TestEngine.chain[4].
|
49
|
-
TestEngine.chain[4].should.equal
|
49
|
+
TestEngine.chain[4].first.should.equal :MultiFlattener
|
50
|
+
TestEngine.chain[4].size.should.equal 2
|
51
|
+
TestEngine.chain[4].last.should.be.instance_of Proc
|
50
52
|
|
51
|
-
TestEngine.chain[5].
|
52
|
-
TestEngine.chain[5].should.equal
|
53
|
+
TestEngine.chain[5].first.should.equal :ArrayBuffer
|
54
|
+
TestEngine.chain[5].size.should.equal 2
|
55
|
+
TestEngine.chain[5].last.should.be.instance_of Proc
|
53
56
|
|
57
|
+
TestEngine.chain[6].first.should.equal :BeforeLast
|
54
58
|
TestEngine.chain[6].size.should.equal 2
|
55
|
-
TestEngine.chain[6]
|
56
|
-
TestEngine.chain[6][1].should.be.instance_of Callable1
|
59
|
+
TestEngine.chain[6].last.should.be.instance_of Proc
|
57
60
|
|
61
|
+
TestEngine.chain[7].first.should.equal :Last
|
58
62
|
TestEngine.chain[7].size.should.equal 2
|
59
|
-
TestEngine.chain[7]
|
60
|
-
TestEngine.chain[7][1].should.be.instance_of UnboundMethod
|
63
|
+
TestEngine.chain[7].last.should.be.instance_of Proc
|
61
64
|
end
|
62
65
|
|
63
66
|
it 'should instantiate chain' do
|
@@ -85,7 +88,7 @@ describe Temple::Engine do
|
|
85
88
|
engine.chain.size.should.equal 9
|
86
89
|
engine.chain[8].first.should.equal :MyFilter3
|
87
90
|
engine.chain[8].size.should.equal 2
|
88
|
-
engine.chain[8].last.should.be.instance_of
|
91
|
+
engine.chain[8].last.should.be.instance_of Proc
|
89
92
|
|
90
93
|
call_chain = engine.send(:call_chain)
|
91
94
|
call_chain.size.should.equal 9
|
@@ -105,7 +108,7 @@ describe Temple::Engine do
|
|
105
108
|
engine.chain.size.should.equal 9
|
106
109
|
engine.chain[0].first.should.equal :MyFilter0
|
107
110
|
engine.chain[0].size.should.equal 2
|
108
|
-
engine.chain[0].last.should.be.instance_of
|
111
|
+
engine.chain[0].last.should.be.instance_of Proc
|
109
112
|
engine.chain[1].first.should.equal :Parser
|
110
113
|
|
111
114
|
call_chain = engine.send(:call_chain)
|
data/test/test_generator.rb
CHANGED
@@ -81,24 +81,33 @@ describe Temple::Generators::Array do
|
|
81
81
|
gen.call([:static, 'test']).should.equal '_buf = []; _buf << ("test"); _buf'
|
82
82
|
gen.call([:dynamic, 'test']).should.equal '_buf = []; _buf << (test); _buf'
|
83
83
|
gen.call([:code, 'test']).should.equal '_buf = []; test; _buf'
|
84
|
+
|
85
|
+
gen.call([:multi, [:static, 'a'], [:static, 'b']]).should.equal '_buf = []; _buf << ("a"); _buf << ("b"); _buf'
|
86
|
+
gen.call([:multi, [:static, 'a'], [:dynamic, 'b']]).should.equal '_buf = []; _buf << ("a"); _buf << (b); _buf'
|
84
87
|
end
|
85
88
|
end
|
86
89
|
|
87
90
|
describe Temple::Generators::ArrayBuffer do
|
88
91
|
it 'should compile simple expressions' do
|
89
92
|
gen = Temple::Generators::ArrayBuffer.new
|
90
|
-
gen.call([:static, 'test']).should.equal '_buf =
|
91
|
-
gen.call([:dynamic, 'test']).should.equal '_buf =
|
93
|
+
gen.call([:static, 'test']).should.equal '_buf = "test"'
|
94
|
+
gen.call([:dynamic, 'test']).should.equal '_buf = (test).to_s'
|
92
95
|
gen.call([:code, 'test']).should.equal '_buf = []; test; _buf = _buf.join'
|
96
|
+
|
97
|
+
gen.call([:multi, [:static, 'a'], [:static, 'b']]).should.equal '_buf = []; _buf << ("a"); _buf << ("b"); _buf = _buf.join'
|
98
|
+
gen.call([:multi, [:static, 'a'], [:dynamic, 'b']]).should.equal '_buf = []; _buf << ("a"); _buf << (b); _buf = _buf.join'
|
93
99
|
end
|
94
100
|
end
|
95
101
|
|
96
102
|
describe Temple::Generators::StringBuffer do
|
97
103
|
it 'should compile simple expressions' do
|
98
104
|
gen = Temple::Generators::StringBuffer.new
|
99
|
-
gen.call([:static, 'test']).should.equal '_buf =
|
100
|
-
gen.call([:dynamic, 'test']).should.equal '_buf =
|
105
|
+
gen.call([:static, 'test']).should.equal '_buf = "test"'
|
106
|
+
gen.call([:dynamic, 'test']).should.equal '_buf = (test).to_s'
|
101
107
|
gen.call([:code, 'test']).should.equal '_buf = \'\'; test; _buf'
|
108
|
+
|
109
|
+
gen.call([:multi, [:static, 'a'], [:static, 'b']]).should.equal '_buf = \'\'; _buf << ("a"); _buf << ("b"); _buf'
|
110
|
+
gen.call([:multi, [:static, 'a'], [:dynamic, 'b']]).should.equal '_buf = \'\'; _buf << ("a"); _buf << ((b).to_s); _buf'
|
102
111
|
end
|
103
112
|
end
|
104
113
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: temple
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-09-04 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: tilt
|
17
|
-
requirement:
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,15 @@ dependencies:
|
|
22
22
|
version: '0'
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
|
-
version_requirements:
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
26
31
|
- !ruby/object:Gem::Dependency
|
27
32
|
name: bacon
|
28
|
-
requirement:
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
29
34
|
none: false
|
30
35
|
requirements:
|
31
36
|
- - ! '>='
|
@@ -33,10 +38,15 @@ dependencies:
|
|
33
38
|
version: '0'
|
34
39
|
type: :development
|
35
40
|
prerelease: false
|
36
|
-
version_requirements:
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
37
47
|
- !ruby/object:Gem::Dependency
|
38
48
|
name: rake
|
39
|
-
requirement:
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
40
50
|
none: false
|
41
51
|
requirements:
|
42
52
|
- - ! '>='
|
@@ -44,7 +54,12 @@ dependencies:
|
|
44
54
|
version: '0'
|
45
55
|
type: :development
|
46
56
|
prerelease: false
|
47
|
-
version_requirements:
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
48
63
|
description:
|
49
64
|
email:
|
50
65
|
- judofyr@gmail.com
|
@@ -138,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
153
|
version: '0'
|
139
154
|
requirements: []
|
140
155
|
rubyforge_project:
|
141
|
-
rubygems_version: 1.8.
|
156
|
+
rubygems_version: 1.8.24
|
142
157
|
signing_key:
|
143
158
|
specification_version: 3
|
144
159
|
summary: Template compilation framework in Ruby
|
@@ -164,3 +179,4 @@ test_files:
|
|
164
179
|
- test/test_grammar.rb
|
165
180
|
- test/test_hash.rb
|
166
181
|
- test/test_utils.rb
|
182
|
+
has_rdoc:
|