| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Text::TemplateLite; |
|
2
|
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
62366
|
use 5.006; |
|
|
2
|
|
|
|
|
8
|
|
|
|
2
|
|
|
|
|
80
|
|
|
4
|
2
|
|
|
2
|
|
11
|
use strict; |
|
|
2
|
|
|
|
|
10
|
|
|
|
2
|
|
|
|
|
78
|
|
|
5
|
2
|
|
|
2
|
|
12
|
use warnings; |
|
|
2
|
|
|
|
|
28
|
|
|
|
2
|
|
|
|
|
58
|
|
|
6
|
2
|
|
|
2
|
|
11
|
use Carp; |
|
|
2
|
|
|
|
|
2
|
|
|
|
2
|
|
|
|
|
204
|
|
|
7
|
2
|
|
|
2
|
|
13
|
use Scalar::Util qw(blessed); |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
160
|
|
|
8
|
2
|
|
|
2
|
|
1297
|
use Text::TemplateLite::Renderer; |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
4927
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
=head1 NAME |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
Text::TemplateLite - Pure-Perl text templates with bare-bones syntax, |
|
13
|
|
|
|
|
|
|
compact size, and limitable resource usage |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 VERSION |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
Version 0.01 |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=cut |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
our $VERSION = '0.01'; |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
use Text::TemplateLite; |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
my $tpl = Text::TemplateLite->new; |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
$tpl->set('Hello, <<$who>>'); |
|
30
|
|
|
|
|
|
|
print $tpl->render({ who => 'world' })->result; |
|
31
|
|
|
|
|
|
|
# Generates "Hello, world" |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
my $rdr = $tpl->new_renderer; |
|
34
|
|
|
|
|
|
|
print $rdr->render({ who => 'universe' })->result; |
|
35
|
|
|
|
|
|
|
# Generates "Hello, universe" with a configurable and |
|
36
|
|
|
|
|
|
|
# reusable renderer (see Text::TemplateLite::Renderer) |
|
37
|
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
=head2 Overview |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
Text::TemplateLite is intended primarily for "string-sized" templating |
|
43
|
|
|
|
|
|
|
(e.g. for message localization rather than entire "pages") using compact |
|
44
|
|
|
|
|
|
|
(terse?) templates with a (relatively) simple syntax. |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
It is anticipated that templates may (at least sometimes) be entered or |
|
47
|
|
|
|
|
|
|
managed by users whose skill set does not include "Perl programmer" |
|
48
|
|
|
|
|
|
|
(perhaps a web site administrator, translator, or non-Perl programmer). |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
Basic length and execution limits provide a measure of protection against |
|
51
|
|
|
|
|
|
|
accidental or malicious time- and/or space-based resource attacks. These |
|
52
|
|
|
|
|
|
|
are managed by the rendering companion class, |
|
53
|
|
|
|
|
|
|
L. |
|
54
|
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
By design, only basic functionality is included in this module. Use parts |
|
56
|
|
|
|
|
|
|
or all of the L function library and/or |
|
57
|
|
|
|
|
|
|
create your own custom library to extend its capabilities. |
|
58
|
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=head2 Syntax |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
A template consists of literal text and template code. Any text between |
|
62
|
|
|
|
|
|
|
"<<" and ">>" that does not contain "<<" or ">>" is treated as template |
|
63
|
|
|
|
|
|
|
code. Everything else is literal text. |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
Template code can contain sequences in any combination of the following: |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=over |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
=item Comments |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
Anything from "/*" to the closest "*/" is ignored and does not count |
|
72
|
|
|
|
|
|
|
as a step (see L<"Steps">). |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=item String Literals |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
To include literal text within code text, surround the text with single |
|
77
|
|
|
|
|
|
|
quotes (') or double quotes ("). You can "escape" either kind of quote |
|
78
|
|
|
|
|
|
|
or < or > in either kind of string by preceding it with a backslash |
|
79
|
|
|
|
|
|
|
(\', \", \<, or \>). Use '<\<' or '>\>' to generate "<<" or ">>" within |
|
80
|
|
|
|
|
|
|
code text. |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
No variable substitution is performed within either kind of string literal. |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
=item Numeric Literals |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
Numeric literals consist of an optional minus sign and one or more |
|
87
|
|
|
|
|
|
|
digits, optionally followed by a decimal point and additional digits. |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=item Variable Substitutions |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
A dollar sign ($) followed by a name consisting of one or more letters, |
|
92
|
|
|
|
|
|
|
digits, underscores (_), and/or non-initial periods (.) will be replaced |
|
93
|
|
|
|
|
|
|
by the corresponding value from the variables supplied either at rendering |
|
94
|
|
|
|
|
|
|
time or set during template execution. |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
Variables can also store nested templates. Substituting a variable |
|
97
|
|
|
|
|
|
|
containing a nested template executes the nested template. These templates |
|
98
|
|
|
|
|
|
|
can be passed parameters using the same syntax as function calls. The |
|
99
|
|
|
|
|
|
|
parameters will appear in the nested template as template variables "$1", |
|
100
|
|
|
|
|
|
|
"$2", etc. Parameter "$0" will contain the number of parameters. |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
Parameters after a non-template variable are ignored, unevaluated. |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
$foo /* variable or nested template without parameters */ |
|
105
|
|
|
|
|
|
|
"$foo is " $foo /* only the second $foo is substituted */ |
|
106
|
|
|
|
|
|
|
$foo('hey', 'there') /* nested template(?) with parameters */ |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
See L for information |
|
109
|
|
|
|
|
|
|
on creating nested templates. |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
In future releases, periods in variable names may have structural meaning |
|
112
|
|
|
|
|
|
|
(e.g. to support lists or maps). Do not write templates that expect "$a" |
|
113
|
|
|
|
|
|
|
to be unrelated to "$a.b" or "$a.5", for example. For now, however, periods |
|
114
|
|
|
|
|
|
|
are just part of the name. |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=item Function And External Template Calls |
|
117
|
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
Any other combination of alpha-numeric characters, or combination of symbols |
|
119
|
|
|
|
|
|
|
other than parentheses or comma, are treated as the name of a function or |
|
120
|
|
|
|
|
|
|
external template call. Either may optionally be passed a list of zero or |
|
121
|
|
|
|
|
|
|
more parameters, surrounded by parentheses and separated by commas. |
|
122
|
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
Parameters to external templates should be provided in "name, value" pairs. |
|
124
|
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
cr nl /* call "cr" and "nl" without parameters */ |
|
126
|
|
|
|
|
|
|
foo('hey', 'there') /* pass foo two strings (or hey=there) */ |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
See L for some related |
|
129
|
|
|
|
|
|
|
functions. |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
Calls to unregistered names will instead call a definition with a zero-length |
|
132
|
|
|
|
|
|
|
name, if registered, or L<"undef_call($name, $args, $renderer)"> otherwise. |
|
133
|
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
=back |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
=head2 Steps |
|
137
|
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
Each element (literal, substitution, call, etc.) evaluated during template |
|
139
|
|
|
|
|
|
|
execution is counted as a "step". For example: |
|
140
|
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
$=('a', 2) /* 3 steps: $=, 'a', and 2 */ |
|
142
|
|
|
|
|
|
|
??(=($a, 1), /* +4 steps: ??, =, $a, and 1 */ |
|
143
|
|
|
|
|
|
|
'$a is 1', /* 1 step not eval'd/counted (= was false) */ |
|
144
|
|
|
|
|
|
|
=($a, 2), /* +3 steps: =, $a, 2 */ |
|
145
|
|
|
|
|
|
|
'$a is 2', /* +1 step: '$a is 2' */ |
|
146
|
|
|
|
|
|
|
'other') /* 1 step not eval'd/counted (not reached) */ |
|
147
|
|
|
|
|
|
|
/* renders '$a is 2' in 11 steps */ |
|
148
|
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
?*(<($a, 4), 'loop' $=('a', +($a, 1))) |
|
150
|
|
|
|
|
|
|
/* 1 step: ?* |
|
151
|
|
|
|
|
|
|
+3 steps: <, $a, 4 (assuming $a is 2 from above) |
|
152
|
|
|
|
|
|
|
+6 steps: 'loop', $=, 'a', +, $a, 1 ($a becomes 3) |
|
153
|
|
|
|
|
|
|
+3 steps: <, $a, 4 |
|
154
|
|
|
|
|
|
|
+6 steps: 'loop', $=, 'a', +, $a, 1 ($a becomes 4) |
|
155
|
|
|
|
|
|
|
+3 steps: <, $a, 4 (now false, so loop stops) |
|
156
|
|
|
|
|
|
|
renders 'looploop' in 22 steps */ |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=head1 USER METHODS |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
This section describes methods for normal usage. |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=head2 new( ) |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
This returns a new Text::TemplateLite template engine. |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=cut |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub new { |
|
169
|
2
|
|
|
2
|
1
|
22
|
my ($class) = @_; |
|
170
|
|
|
|
|
|
|
|
|
171
|
2
|
|
|
|
|
10
|
return bless { |
|
172
|
|
|
|
|
|
|
}, $class; |
|
173
|
|
|
|
|
|
|
} |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
=head2 register($name, $definition) |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
Register a function (coderef definition) or an external template |
|
178
|
|
|
|
|
|
|
(Text::TemplateLite definition). |
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
$ttl->register('my_function', sub { |
|
181
|
|
|
|
|
|
|
my ($name, $args, $renderer) = @_; |
|
182
|
|
|
|
|
|
|
"You called function $name." }); |
|
183
|
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
my $other_ttl = Text::TemplateLite->new(); |
|
185
|
|
|
|
|
|
|
$other_ttl->set('You called an external template.'); |
|
186
|
|
|
|
|
|
|
$ttl->register('external_tpl', $other_ttl); |
|
187
|
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
If you register a definition with a zero-length name, it will be called |
|
189
|
|
|
|
|
|
|
in place of any call to an undefined function or external template instead |
|
190
|
|
|
|
|
|
|
of using the default undefined-call handler, |
|
191
|
|
|
|
|
|
|
L<"undef_call($name, $args, $renderer)">. |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
Library functions (registered as coderefs) are passed three parameters: |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=over |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=item $name |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
This is the name of the function as it was invoked from the template. |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=item $args |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
This is an arrayref of code sequences for any parameters passed from the |
|
204
|
|
|
|
|
|
|
template. See L<"execute_sequence($code, $renderer)"> and |
|
205
|
|
|
|
|
|
|
L<"execute_each($list, $renderer)">. |
|
206
|
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=item $renderer |
|
208
|
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
This is the instance of L that is managing |
|
210
|
|
|
|
|
|
|
rendering of the template. |
|
211
|
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
=back |
|
213
|
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
=cut |
|
215
|
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
sub register { |
|
217
|
3
|
|
|
3
|
1
|
545
|
my ($self, $name, $def) = @_; |
|
218
|
|
|
|
|
|
|
|
|
219
|
3
|
|
|
|
|
11
|
$self->{defs}{$name} = $def; |
|
220
|
3
|
|
|
|
|
7
|
return $self; |
|
221
|
|
|
|
|
|
|
} |
|
222
|
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
=head2 unregister($name) |
|
224
|
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
Unregister a function or external template definition. |
|
226
|
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=cut |
|
228
|
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
sub unregister { |
|
230
|
2
|
|
|
2
|
1
|
10
|
my ($self, $name) = @_; |
|
231
|
|
|
|
|
|
|
|
|
232
|
2
|
|
|
|
|
10
|
delete($self->{defs}{$name}); |
|
233
|
2
|
|
|
|
|
6
|
return $self; |
|
234
|
|
|
|
|
|
|
} |
|
235
|
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
=head2 set($string) |
|
237
|
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
Set or change the template string (see L<"Syntax">) and return the |
|
239
|
|
|
|
|
|
|
template object. |
|
240
|
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
=cut |
|
242
|
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
sub set { |
|
244
|
20
|
|
|
20
|
1
|
44
|
my ($self, $template) = @_; |
|
245
|
|
|
|
|
|
|
|
|
246
|
20
|
|
|
|
|
53
|
delete($self->{code}); |
|
247
|
|
|
|
|
|
|
|
|
248
|
20
|
|
|
|
|
150
|
my @parts = split(/<<(?!<)((?:[^<>]|<[^<]|>[^>])*)>>/s, $template); |
|
249
|
20
|
|
|
|
|
28
|
my @code; |
|
250
|
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
# Template "text<>text<>..." => (text, code, text, code, ...) |
|
252
|
20
|
|
|
|
|
55
|
for (my $literal = 1; @parts; $literal = !$literal) { |
|
253
|
37
|
100
|
|
|
|
118
|
if (length(my $part = shift(@parts))) { |
|
254
|
22
|
100
|
|
|
|
41
|
if ($literal) { |
|
255
|
|
|
|
|
|
|
# Even elements are literal text. |
|
256
|
8
|
|
|
|
|
36
|
push(@code, [ "''" => $part ]); |
|
257
|
|
|
|
|
|
|
} else { |
|
258
|
|
|
|
|
|
|
# Odd elements are template code text. |
|
259
|
14
|
|
|
|
|
62
|
my @tokens = $self->get_tokens($part); |
|
260
|
14
|
|
|
|
|
50
|
push(@code, $self->parse_list(\@tokens, [])); |
|
261
|
|
|
|
|
|
|
} |
|
262
|
|
|
|
|
|
|
} |
|
263
|
|
|
|
|
|
|
} |
|
264
|
|
|
|
|
|
|
|
|
265
|
20
|
|
|
|
|
40
|
$self->{code} = \@code; |
|
266
|
|
|
|
|
|
|
|
|
267
|
20
|
|
|
|
|
53
|
return $self; |
|
268
|
|
|
|
|
|
|
} |
|
269
|
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=head2 new_renderer( ) |
|
271
|
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
Returns a new renderer companion object assigned to this template |
|
273
|
|
|
|
|
|
|
engine. See L. |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
=cut |
|
276
|
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
sub new_renderer { |
|
278
|
5
|
|
|
5
|
1
|
2648
|
return Text::TemplateLite::Renderer->new->template(shift); |
|
279
|
|
|
|
|
|
|
} |
|
280
|
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
=head2 render(\%variables) |
|
282
|
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
Create a new renderer via L<"new_renderer( )">, render the template, |
|
284
|
|
|
|
|
|
|
and return the renderer (not the result). |
|
285
|
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
=cut |
|
287
|
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
sub render { |
|
289
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
290
|
|
|
|
|
|
|
|
|
291
|
0
|
|
|
|
|
0
|
return $self->new_renderer->render(@_); |
|
292
|
|
|
|
|
|
|
} |
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
=head1 AUTHOR METHODS |
|
295
|
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
This section describes methods generally only used by library function |
|
297
|
|
|
|
|
|
|
authors. |
|
298
|
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
=head2 execute_sequence($code, $renderer) |
|
300
|
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
Execute the code step(s), if any, in the sequence $code using renderer |
|
302
|
|
|
|
|
|
|
$renderer. |
|
303
|
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
A code sequence looks like: |
|
305
|
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
[ \@step1code, \@step2code, ... ] |
|
307
|
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
This method is useful for "progressive" evaluation of individual parameters to |
|
309
|
|
|
|
|
|
|
functions. It is also used to execute the code resulting from each section |
|
310
|
|
|
|
|
|
|
of template code in a template. |
|
311
|
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
Execution may stop or step results may be truncated in response to |
|
313
|
|
|
|
|
|
|
exceeded execution limits or a stop set in the rendering information. |
|
314
|
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
A sequence consisting of a single function call can return multiple values |
|
316
|
|
|
|
|
|
|
if execute_sequence is called in array context. Otherwise, the concatenation |
|
317
|
|
|
|
|
|
|
of step values is returned. |
|
318
|
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
=cut |
|
320
|
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
sub execute_sequence { |
|
322
|
31
|
|
|
31
|
1
|
41
|
my ($self, $code, $renderer) = @_; |
|
323
|
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
# Return nothing on empty sequence or rendering stop. |
|
325
|
31
|
50
|
100
|
|
|
206
|
return wantarray? (): '' |
|
|
|
100
|
66
|
|
|
|
|
|
326
|
|
|
|
|
|
|
if !$code || !@$code || $renderer->info->{stop}; |
|
327
|
|
|
|
|
|
|
|
|
328
|
27
|
|
|
|
|
77
|
my $max_len = $renderer->limit('step_length'); |
|
329
|
27
|
|
|
|
|
38
|
my @parts; |
|
330
|
|
|
|
|
|
|
|
|
331
|
27
|
100
|
66
|
|
|
71
|
if (wantarray && @$code == 1) { |
|
332
|
|
|
|
|
|
|
# A one-step sequence may return multiple values. |
|
333
|
2
|
|
|
|
|
6
|
@parts = $self->execute_step($code->[0], $renderer); |
|
334
|
|
|
|
|
|
|
|
|
335
|
2
|
50
|
|
|
|
11
|
if (defined($max_len)) { |
|
336
|
|
|
|
|
|
|
# Enforce the step-length limit value-by-value. |
|
337
|
0
|
|
|
|
|
0
|
foreach (@parts) { |
|
338
|
0
|
0
|
|
|
|
0
|
if (length > $max_len) { |
|
339
|
0
|
|
|
|
|
0
|
$_ = substr($_, 0, $max_len); |
|
340
|
0
|
|
|
|
|
0
|
$renderer->exceeded_limits('step_length'); |
|
341
|
|
|
|
|
|
|
} |
|
342
|
|
|
|
|
|
|
} |
|
343
|
|
|
|
|
|
|
} |
|
344
|
2
|
|
|
|
|
15
|
return @parts; |
|
345
|
|
|
|
|
|
|
} |
|
346
|
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
# Combine all the parts of a multi-step sequence into a single value. |
|
348
|
|
|
|
|
|
|
# The result must not exceed the step-length limit. |
|
349
|
25
|
|
|
|
|
53
|
foreach (@$code) { |
|
350
|
43
|
|
|
|
|
100
|
my $part = join('', $self->execute_step($_, $renderer)); |
|
351
|
|
|
|
|
|
|
|
|
352
|
43
|
100
|
|
|
|
119
|
if (defined($max_len)) { |
|
353
|
|
|
|
|
|
|
# Enforce the length limit for the entire sequence. |
|
354
|
1
|
|
|
|
|
3
|
my $part_len = length($part); |
|
355
|
1
|
50
|
|
|
|
5
|
if ($part_len > $max_len) { |
|
356
|
1
|
|
|
|
|
3
|
push(@parts, substr($part, 0, $max_len)); |
|
357
|
1
|
|
|
|
|
5
|
$renderer->exceeded_limits('step_length'); |
|
358
|
1
|
|
|
|
|
2
|
last; |
|
359
|
|
|
|
|
|
|
} |
|
360
|
0
|
|
|
|
|
0
|
$max_len -= $part_len; |
|
361
|
|
|
|
|
|
|
} |
|
362
|
|
|
|
|
|
|
|
|
363
|
42
|
|
|
|
|
105
|
push(@parts, $part); |
|
364
|
|
|
|
|
|
|
} |
|
365
|
|
|
|
|
|
|
|
|
366
|
25
|
|
|
|
|
115
|
return join('', @parts); |
|
367
|
|
|
|
|
|
|
} |
|
368
|
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
=head2 execute_each($list, $renderer) |
|
370
|
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
Execute an arrayref of code sequences and return a corresponding array |
|
372
|
|
|
|
|
|
|
of results. This is typically used by library functions to "bulk evaluate" |
|
373
|
|
|
|
|
|
|
their list of call parameters. |
|
374
|
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
$ttl->register('echo', sub { |
|
376
|
|
|
|
|
|
|
my ($name, $args, $renderer) = @_; |
|
377
|
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
"$name(" . join(', ', $renderer->execute_each($args)) |
|
379
|
|
|
|
|
|
|
. ")"; |
|
380
|
|
|
|
|
|
|
}); |
|
381
|
|
|
|
|
|
|
$ttl->set(q{<>}); |
|
382
|
|
|
|
|
|
|
$ttl->render; # renders "echo(hello, world)" |
|
383
|
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
$ttl->register('uses2', sub { |
|
385
|
|
|
|
|
|
|
my ($name, $args, $renderer) = @_; |
|
386
|
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
join('', $renderer->template->execute_each(@{$args}[0, 1])); |
|
388
|
|
|
|
|
|
|
}); |
|
389
|
|
|
|
|
|
|
$ttl->set(q{<>}); |
|
390
|
|
|
|
|
|
|
$ttl->render; # renders "justthese" using 3 steps (not 5) |
|
391
|
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
=cut |
|
393
|
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
sub execute_each { |
|
395
|
4
|
|
|
4
|
1
|
52
|
my ($self, $list, $renderer) = @_; |
|
396
|
|
|
|
|
|
|
|
|
397
|
4
|
|
|
|
|
17
|
return map($self->execute_sequence($_, $renderer), @$list); |
|
398
|
|
|
|
|
|
|
} |
|
399
|
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
=head2 execute_step($code, $renderer) |
|
401
|
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
Execute one code step $code with renderer $renderer unless the total_steps |
|
403
|
|
|
|
|
|
|
limit has been reached, in which case the total_steps limit is marked |
|
404
|
|
|
|
|
|
|
exceeded. |
|
405
|
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
=cut |
|
407
|
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
sub execute_step { |
|
409
|
45
|
|
|
45
|
1
|
60
|
my $self = shift; |
|
410
|
45
|
|
|
|
|
62
|
my ($code, $renderer) = @_; |
|
411
|
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
# This is a hack in case someone wants to sub-class step execution |
|
413
|
45
|
100
|
|
|
|
108
|
return $renderer->step? $self->_execute_step(@_): (); |
|
414
|
|
|
|
|
|
|
} |
|
415
|
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
=head2 _execute_step($code, $renderer) |
|
417
|
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
This method does the "heavy lifting" after execute_step checks resource |
|
419
|
|
|
|
|
|
|
usage. |
|
420
|
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
The step $code can be one of the following: |
|
422
|
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
[ "''" => $literal ] |
|
424
|
|
|
|
|
|
|
[ '$' => $var_name ] |
|
425
|
|
|
|
|
|
|
[ '()' => $fn_or_tpl [ \@a1codeseq, \@a2codeseq, ... ] ] |
|
426
|
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
A variable substitution is executed as a nested template if it's value |
|
428
|
|
|
|
|
|
|
looks like this: |
|
429
|
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
[ '<>' => \@code_sequence ] |
|
431
|
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
=cut |
|
433
|
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
sub _execute_step { |
|
435
|
43
|
|
|
43
|
|
70
|
my ($self, $code, $renderer) = @_; |
|
436
|
43
|
|
|
|
|
61
|
my $type = $code->[0]; |
|
437
|
43
|
|
|
|
|
45
|
my $value; |
|
438
|
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
# Figure out what to do in this step... |
|
440
|
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
# [ "''" => $string ] : Return a literal. |
|
442
|
43
|
100
|
|
|
|
108
|
if ($type eq "''") { |
|
443
|
32
|
|
|
|
|
113
|
return $code->[1]; |
|
444
|
|
|
|
|
|
|
} |
|
445
|
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
# Note: The only currently supported array values are internal |
|
447
|
|
|
|
|
|
|
# templates. They look like this: [ '<>' => \@code_sequence ] |
|
448
|
|
|
|
|
|
|
# Other array values are ignored. |
|
449
|
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
# [ '$' => $name ] : Interpolate a variable (possibly an internal template). |
|
451
|
11
|
100
|
|
|
|
26
|
if ($type eq '$') { |
|
452
|
3
|
|
|
|
|
10
|
$value = $renderer->vars->{$code->[1]}; |
|
453
|
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
# Check for an internal template. |
|
455
|
3
|
0
|
0
|
|
|
9
|
return ((@$value && $value->[0] eq '<>')? |
|
|
|
50
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
$self->execute_template($value->[1], [], $renderer): '') |
|
457
|
|
|
|
|
|
|
if ref($value) eq 'ARRAY'; |
|
458
|
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
# Ordinary variable substitution. |
|
460
|
3
|
50
|
|
|
|
14
|
return defined($value)? $value: ''; |
|
461
|
|
|
|
|
|
|
} |
|
462
|
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
# [ '()' => $name, [ @arg_code_sequences ] ] : |
|
464
|
|
|
|
|
|
|
# Call a function or a template (possibly with parameters). |
|
465
|
8
|
50
|
|
|
|
22
|
if ($type eq '()') { |
|
466
|
8
|
|
|
|
|
15
|
my $name = $code->[1]; |
|
467
|
|
|
|
|
|
|
|
|
468
|
8
|
50
|
|
|
|
23
|
if ($name =~ /^\$([a-zA-Z0-9_\.]+)$/) { |
|
469
|
0
|
|
|
|
|
0
|
$value = $renderer->vars->{$1}; |
|
470
|
|
|
|
|
|
|
|
|
471
|
0
|
0
|
|
|
|
0
|
if (ref($value) eq 'ARRAY') { |
|
472
|
0
|
0
|
0
|
|
|
0
|
return ((@$value && $value->[0] eq '<>')? |
|
473
|
|
|
|
|
|
|
$self->execute_template($value->[1], $code->[2], $renderer): |
|
474
|
|
|
|
|
|
|
()); |
|
475
|
|
|
|
|
|
|
} |
|
476
|
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
# Ignore any call parameters and revert to plain variable |
|
478
|
|
|
|
|
|
|
# substitution. |
|
479
|
0
|
0
|
|
|
|
0
|
return defined($value)? $value: ''; |
|
480
|
|
|
|
|
|
|
} |
|
481
|
|
|
|
|
|
|
|
|
482
|
8
|
|
|
|
|
19
|
$value = $self->{defs}{$name}; |
|
483
|
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
# Call an external template's renderer if available. |
|
485
|
8
|
100
|
66
|
|
|
59
|
return $renderer->render_external($value, |
|
486
|
|
|
|
|
|
|
{ $self->execute_each($code->[2], $renderer) })->result |
|
487
|
|
|
|
|
|
|
if blessed($value) && $value->can('render'); |
|
488
|
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
# Call a registered function (or an undefined-call handler). |
|
490
|
4
|
100
|
|
|
|
14
|
unless (ref($value) eq 'CODE') { |
|
491
|
3
|
|
|
|
|
5
|
$value = $self->{defs}{''}; |
|
492
|
3
|
100
|
|
|
|
13
|
$value = \&undef_call unless ref($value) eq 'CODE'; |
|
493
|
|
|
|
|
|
|
} |
|
494
|
4
|
|
|
|
|
11
|
return &$value($name, $code->[2], $renderer); |
|
495
|
|
|
|
|
|
|
} |
|
496
|
|
|
|
|
|
|
|
|
497
|
0
|
|
|
|
|
0
|
croak "Unrecognized " . blessed($self) . " step-type: $type"; |
|
498
|
|
|
|
|
|
|
} |
|
499
|
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
=head2 execute($renderer) |
|
501
|
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
Execute the main template code with renderer $renderer and return the result. |
|
503
|
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
You shouldn't need to use this method unless you're building or sub-classing |
|
505
|
|
|
|
|
|
|
a renderer. |
|
506
|
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
=cut |
|
508
|
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
sub execute { |
|
510
|
29
|
|
|
29
|
1
|
36
|
my ($self, $renderer) = @_; |
|
511
|
|
|
|
|
|
|
|
|
512
|
29
|
|
|
|
|
87
|
return scalar($self->execute_sequence($self->{code}, $renderer)); |
|
513
|
|
|
|
|
|
|
} |
|
514
|
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
=head2 execute_template($code, $args, $renderer) |
|
516
|
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
This executes the code from a nested template after saving any |
|
518
|
|
|
|
|
|
|
previous numeric variables and then setting $0 and parameters $1 through |
|
519
|
|
|
|
|
|
|
$I. |
|
520
|
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
Any previous numeric variables are restored before returning. |
|
522
|
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
You shouldn't need this method except possibly if you're extending |
|
524
|
|
|
|
|
|
|
nested template functionality in some way. |
|
525
|
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
=cut |
|
527
|
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
sub execute_template { |
|
529
|
0
|
|
|
0
|
1
|
0
|
my ($self, $code, $args, $renderer) = @_; |
|
530
|
0
|
|
|
|
|
0
|
my (%save_vars, $vars, $result); |
|
531
|
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
# Save and remove any previously existing numbered parameters. |
|
533
|
0
|
|
|
|
|
0
|
$vars = $renderer->vars; |
|
534
|
0
|
|
|
|
|
0
|
$save_vars{$_} = delete($vars->{$_}) foreach (grep(/^\d+$/, keys(%$vars))); |
|
535
|
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
# Save arguments as numbered parameters $1..$n. |
|
537
|
|
|
|
|
|
|
# Set $0 to the number of arguments. |
|
538
|
0
|
|
|
|
|
0
|
$vars->{0} = @$args; |
|
539
|
0
|
|
|
|
|
0
|
for (my $i = 0; $i < @$args; ++$i) { |
|
540
|
0
|
|
|
|
|
0
|
$vars->{$i + 1} = $self->execute_sequence($args->[$i], $renderer); |
|
541
|
|
|
|
|
|
|
} |
|
542
|
|
|
|
|
|
|
|
|
543
|
0
|
|
|
|
|
0
|
$result = $self->execute_sequence($code, $renderer); |
|
544
|
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
# Remove current numbered parameters and restore anything we removed. |
|
546
|
0
|
|
|
|
|
0
|
delete($vars->{$_}) foreach grep(/^\d+$/, keys(%$vars)); |
|
547
|
0
|
|
|
|
|
0
|
@$vars{keys(%save_vars)} = values(%save_vars); |
|
548
|
|
|
|
|
|
|
|
|
549
|
0
|
|
|
|
|
0
|
return $result; |
|
550
|
|
|
|
|
|
|
} |
|
551
|
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
=head2 undef_call($name, $args, $renderer) |
|
553
|
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
This function is the default undefined-call handler called by the |
|
555
|
|
|
|
|
|
|
L<"_execute_step($code, $renderer)"> method if no zero-length name is |
|
556
|
|
|
|
|
|
|
currently registered. |
|
557
|
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
It increments the C count in the rendering information and |
|
559
|
|
|
|
|
|
|
returns no value. |
|
560
|
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
=cut |
|
562
|
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
sub undef_call { |
|
564
|
2
|
|
|
2
|
1
|
4
|
my ($name, $args, $renderer) = @_; |
|
565
|
|
|
|
|
|
|
|
|
566
|
2
|
|
|
|
|
9
|
++$renderer->info->{undef_calls}; |
|
567
|
2
|
|
|
|
|
10
|
return (); |
|
568
|
|
|
|
|
|
|
} |
|
569
|
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
=head1 PARSING METHODS |
|
571
|
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
These methods are used for parsing. If you extend these in a sub-class it's |
|
573
|
|
|
|
|
|
|
likely to get ugly pretty quickly. |
|
574
|
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
=head2 get_tokens($text) |
|
576
|
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
Split template code text into tokens and return them as a list. |
|
578
|
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
=cut |
|
580
|
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
sub get_tokens { |
|
582
|
15
|
|
|
15
|
1
|
41
|
my ($self, $text) = @_; |
|
583
|
|
|
|
|
|
|
|
|
584
|
15
|
|
|
|
|
705
|
return grep(!/^\s*$/, split( |
|
585
|
|
|
|
|
|
|
/( |
|
586
|
|
|
|
|
|
|
\/\*.*?\*\/ # \/* comment *\/ |
|
587
|
|
|
|
|
|
|
| |
|
588
|
|
|
|
|
|
|
'(?:\\'|[^'])*' # 'string' |
|
589
|
|
|
|
|
|
|
| |
|
590
|
|
|
|
|
|
|
"(?:\\"|[^"])*" # "string" |
|
591
|
|
|
|
|
|
|
| |
|
592
|
|
|
|
|
|
|
\$[a-zA-Z0-9_][a-zA-Z0-9_\.]* # $vari.able |
|
593
|
|
|
|
|
|
|
| |
|
594
|
|
|
|
|
|
|
[a-zA-Z_][a-zA-Z0-9_]* # alpha-numeric function |
|
595
|
|
|
|
|
|
|
| |
|
596
|
|
|
|
|
|
|
-?\d+(?:\.\d*)? # integer or floating numeric literal |
|
597
|
|
|
|
|
|
|
| |
|
598
|
|
|
|
|
|
|
[(),] # (parameter, lists) |
|
599
|
|
|
|
|
|
|
| |
|
600
|
|
|
|
|
|
|
\s+ |
|
601
|
|
|
|
|
|
|
)/x, |
|
602
|
|
|
|
|
|
|
$text)); |
|
603
|
|
|
|
|
|
|
} |
|
604
|
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
=head2 parse_list(\@tokens, \@stops) |
|
606
|
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
Parse a block of code from the token list up to one of the stop |
|
608
|
|
|
|
|
|
|
symbols. This might be an entire code segment or parts of a call's |
|
609
|
|
|
|
|
|
|
parameter list. The code tree is returned. |
|
610
|
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
=cut |
|
612
|
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
sub parse_list { |
|
614
|
16
|
|
|
16
|
1
|
24
|
my ($self, $tokens, $stops) = @_; |
|
615
|
16
|
|
|
|
|
20
|
my (@code, $token); |
|
616
|
|
|
|
|
|
|
|
|
617
|
16
|
|
|
|
|
43
|
while (@$tokens) { |
|
618
|
27
|
|
|
|
|
36
|
$token = shift(@$tokens); |
|
619
|
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
# Remove comments |
|
621
|
27
|
100
|
|
|
|
75
|
next if $token =~ /^\/\*.*\*\/$/s; |
|
622
|
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
# String literals |
|
624
|
25
|
100
|
100
|
|
|
148
|
if ($token =~ /^'(.*)'$/s || $token =~ /^"(.*)"$/s) { |
|
625
|
17
|
|
|
|
|
43
|
push(@code, [ "''" => $self->unescape($1) ]); |
|
626
|
17
|
|
|
|
|
57
|
next; |
|
627
|
|
|
|
|
|
|
} |
|
628
|
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
# Numeric literals |
|
630
|
8
|
50
|
|
|
|
31
|
if ($token =~ /^-?\d+(?:\.\d*)?$/) { |
|
631
|
0
|
|
|
|
|
0
|
push(@code, [ "''" => $token ]); |
|
632
|
0
|
|
|
|
|
0
|
next; |
|
633
|
|
|
|
|
|
|
} |
|
634
|
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
# Variables or internal template calls |
|
636
|
8
|
100
|
|
|
|
25
|
if ($token =~ /^\$([a-zA-Z0-9_]+)$/) { |
|
637
|
3
|
50
|
66
|
|
|
18
|
if (@$tokens && $tokens->[0] eq '(') { |
|
638
|
0
|
|
|
|
|
0
|
push(@code, $self->parse_call($token, $tokens)); |
|
639
|
|
|
|
|
|
|
} else { |
|
640
|
3
|
|
|
|
|
10
|
push(@code, [ '$' => $1 ]); |
|
641
|
|
|
|
|
|
|
} |
|
642
|
3
|
|
|
|
|
9
|
next; |
|
643
|
|
|
|
|
|
|
} |
|
644
|
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
# Check stop list |
|
646
|
5
|
|
|
|
|
14
|
foreach (@$stops) { |
|
647
|
3
|
100
|
|
|
|
9
|
if ($token eq $_) { |
|
648
|
2
|
|
|
|
|
4
|
unshift(@$tokens, $token); |
|
649
|
2
|
|
|
|
|
9
|
return @code; |
|
650
|
|
|
|
|
|
|
} |
|
651
|
|
|
|
|
|
|
} |
|
652
|
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
# Function or external template call, with or without parameters |
|
654
|
3
|
|
|
|
|
9
|
push(@code, $self->parse_call($token, $tokens)); |
|
655
|
|
|
|
|
|
|
} |
|
656
|
|
|
|
|
|
|
|
|
657
|
14
|
|
|
|
|
84
|
return @code; |
|
658
|
|
|
|
|
|
|
} |
|
659
|
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
=head2 parse_call($name, $tokens) |
|
661
|
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
Parse a parameter list if one follows in the token stream and return the |
|
663
|
|
|
|
|
|
|
code tree for a call to the function or template in $name. |
|
664
|
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
=cut |
|
666
|
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
sub parse_call { |
|
668
|
3
|
|
|
3
|
1
|
6
|
my ($self, $name, $tokens) = @_; |
|
669
|
3
|
|
|
|
|
5
|
my (@args, $token); |
|
670
|
|
|
|
|
|
|
|
|
671
|
3
|
100
|
100
|
|
|
19
|
if (@$tokens && $tokens->[0] eq '(') { |
|
672
|
1
|
|
|
|
|
2
|
shift(@$tokens); |
|
673
|
1
|
|
|
|
|
7
|
while (@$tokens) { |
|
674
|
4
|
|
|
|
|
7
|
$token = $tokens->[0]; |
|
675
|
4
|
100
|
100
|
|
|
21
|
shift(@$tokens) if $token eq ',' || $token eq ')'; |
|
676
|
4
|
100
|
|
|
|
11
|
last if $token eq ')'; |
|
677
|
|
|
|
|
|
|
|
|
678
|
3
|
100
|
|
|
|
11
|
if ($token ne ',') { |
|
679
|
|
|
|
|
|
|
# The argument continues to the next ',' or ')'. |
|
680
|
2
|
|
|
|
|
10
|
my @code = $self->parse_list($tokens, [',', ')']); |
|
681
|
2
|
50
|
|
|
|
11
|
push(@args, \@code) if @code; |
|
682
|
|
|
|
|
|
|
} |
|
683
|
|
|
|
|
|
|
} |
|
684
|
|
|
|
|
|
|
} |
|
685
|
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
# [ '()' => $name, [ \@arg0_code_seq, \@arg1_code_seq, ... ] ] |
|
687
|
3
|
|
|
|
|
16
|
return [ '()' => $name, \@args ]; |
|
688
|
|
|
|
|
|
|
} |
|
689
|
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
=head2 unescape($string) |
|
691
|
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
Un-escape backslashed characters for string literals. |
|
693
|
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
=cut |
|
695
|
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
sub unescape { |
|
697
|
17
|
|
|
17
|
1
|
34
|
my ($self, $string) = @_; |
|
698
|
|
|
|
|
|
|
|
|
699
|
17
|
|
|
|
|
29
|
$string =~ s/\\(.)/$1/g; |
|
700
|
17
|
|
|
|
|
50
|
return $string; |
|
701
|
|
|
|
|
|
|
} |
|
702
|
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
=head1 AUTHOR |
|
704
|
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
Brian Katzung, C<< >> |
|
706
|
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
=head1 BUGS |
|
708
|
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
Please report any bugs or feature requests to |
|
710
|
|
|
|
|
|
|
C, or through the web interface at |
|
711
|
|
|
|
|
|
|
L. I |
|
712
|
|
|
|
|
|
|
will be notified, and then you'll automatically be notified of progress |
|
713
|
|
|
|
|
|
|
on your bug as I make changes. |
|
714
|
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
=head1 SUPPORT |
|
716
|
|
|
|
|
|
|
|
|
717
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
|
718
|
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
perldoc Text::TemplateLite |
|
720
|
|
|
|
|
|
|
|
|
721
|
|
|
|
|
|
|
You can also look for information at: |
|
722
|
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
=over 4 |
|
724
|
|
|
|
|
|
|
|
|
725
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker (report bugs here) |
|
726
|
|
|
|
|
|
|
|
|
727
|
|
|
|
|
|
|
L |
|
728
|
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
|
730
|
|
|
|
|
|
|
|
|
731
|
|
|
|
|
|
|
L |
|
732
|
|
|
|
|
|
|
|
|
733
|
|
|
|
|
|
|
=item * CPAN Ratings |
|
734
|
|
|
|
|
|
|
|
|
735
|
|
|
|
|
|
|
L |
|
736
|
|
|
|
|
|
|
|
|
737
|
|
|
|
|
|
|
=item * Search CPAN |
|
738
|
|
|
|
|
|
|
|
|
739
|
|
|
|
|
|
|
L |
|
740
|
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
=back |
|
742
|
|
|
|
|
|
|
|
|
743
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
744
|
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
L (the companion class to |
|
746
|
|
|
|
|
|
|
Text::TemplateLite for rendering management) and |
|
747
|
|
|
|
|
|
|
L (for standard library functions, |
|
748
|
|
|
|
|
|
|
with examples) |
|
749
|
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
L ("powerful, high-performance templating for web and beyond") |
|
751
|
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
L (an alternative template system based on embedding |
|
753
|
|
|
|
|
|
|
Perl code in templates) |
|
754
|
|
|
|
|
|
|
|
|
755
|
|
|
|
|
|
|
L (an alternative template system [based on "including |
|
756
|
|
|
|
|
|
|
the kitchen sink"]) |
|
757
|
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
L for a |
|
759
|
|
|
|
|
|
|
comparison of template modules |
|
760
|
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
=head2 EVEN MORE TEMPLATE MODULES |
|
762
|
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
L, |
|
764
|
|
|
|
|
|
|
L, |
|
765
|
|
|
|
|
|
|
L, |
|
766
|
|
|
|
|
|
|
L, |
|
767
|
|
|
|
|
|
|
L, |
|
768
|
|
|
|
|
|
|
L, |
|
769
|
|
|
|
|
|
|
L, |
|
770
|
|
|
|
|
|
|
L, |
|
771
|
|
|
|
|
|
|
L, |
|
772
|
|
|
|
|
|
|
L, |
|
773
|
|
|
|
|
|
|
L, |
|
774
|
|
|
|
|
|
|
L, |
|
775
|
|
|
|
|
|
|
L, |
|
776
|
|
|
|
|
|
|
L, |
|
777
|
|
|
|
|
|
|
L, |
|
778
|
|
|
|
|
|
|
L, |
|
779
|
|
|
|
|
|
|
L, |
|
780
|
|
|
|
|
|
|
L, |
|
781
|
|
|
|
|
|
|
L, |
|
782
|
|
|
|
|
|
|
L, |
|
783
|
|
|
|
|
|
|
L, |
|
784
|
|
|
|
|
|
|
L, |
|
785
|
|
|
|
|
|
|
L, |
|
786
|
|
|
|
|
|
|
L, |
|
787
|
|
|
|
|
|
|
L, |
|
788
|
|
|
|
|
|
|
L, |
|
789
|
|
|
|
|
|
|
L, |
|
790
|
|
|
|
|
|
|
L, |
|
791
|
|
|
|
|
|
|
L |
|
792
|
|
|
|
|
|
|
L, |
|
793
|
|
|
|
|
|
|
L, |
|
794
|
|
|
|
|
|
|
L |
|
795
|
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
... and probably some I missed. |
|
797
|
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
|
799
|
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
Copyright 2012 Brian Katzung. |
|
801
|
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
|
803
|
|
|
|
|
|
|
under the terms of either: the GNU General Public License as published |
|
804
|
|
|
|
|
|
|
by the Free Software Foundation; or the Artistic License. |
|
805
|
|
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
See http://dev.perl.org/licenses/ for more information. |
|
807
|
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
=cut |
|
809
|
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
1; # End of Text::TemplateLite |
|
811
|
|
|
|
|
|
|
|