-
Notifications
You must be signed in to change notification settings - Fork 6
/
Template.pm
151 lines (100 loc) · 3.37 KB
/
Template.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package Here::Template;
=head1 NAME
Here::Template - heredoc templates
=head1 SYNOPSIS
use Here::Template;
print <<'TMPL';
Hello, my pid is <?= $$ ?>
Let's count to 10: <? for (1..10) { ?>$_ <? } ?>
TMPL
=head1 DESCRIPTION
Simple Filter::Util::Call based implementation of heredoc templates.
To enable templates in some heredoc use quoted heredoc mark that contains
B<TMPL>. Output is added to the buffer C<$here>. You can append data
there as well:
print <<'TMPL';
Hello, my pid is <?= $$ ?>
Let's count to 10: <? for (1..10) { $here.= "$_" } ?>
TMPL
=head1 EXPORT
This module doesn't export anything by default.
Special argument B<relaxed> can be used to disable strict and
warnings inside templates. E.g.:
use strict;
use warnings;
use Here::Template 'relaxed';
print <<'TMPL';
Let's count to 10: <?
for $k (1..10) {
$here .= "$k ";
}
?>
TMPL
=cut
our $VERSION = '0.2';
use strict;
use warnings;
no warnings 'uninitialized';
use Filter::Util::Call;
sub import {
my $ctl = $_[1] eq 'relaxed'
? 'no strict; no warnings;' : '';
filter_add sub {
my $st = filter_read();
if ( m/ << \s* (['"]) ( [^\1]* TMPL [^\1]* ) \1 \s* /gcx ) {
my $q = $1;
my $eof = quotemeta $2;
my $start = quotemeta '<?';
my $out = '$here';
my $end = quotemeta '?>';
my $buf = substr($_, 0, pos($_) - length($&));
my $buf_end = substr($_, pos($_));
chomp($buf_end);
return $st
if /^\s*#/;
$_ = '';
# do { my $var = '
$buf .= "do{ $ctl \n".($out eq '$_' ? 'local' : 'my')." $out =$q";
while (1) {
$st = filter_read();
if (/ $start (=)? /gcx) {
my $echo = $1;
# foo bar\' baz
my $tmp = substr($_, 0, pos($_) - length($&));
$_ = substr($_, pos($_));
$tmp =~ s/$q/\\$q/g;
$buf .= $tmp;
$st = filter_read()
while !/ $end /gcx;
# '; ... ; $out .='
$tmp = substr($_, 0, pos($_) - length($&));
$_ = substr($_, pos($_));
$buf .= "$q; ".
($echo ? "$out.=$tmp" : "$tmp").
"; $out .=$q";
}
if (/ $eof /gcx) {
my $tmp = substr($_, 0, pos($_) - length($&));
$_ = substr($_, pos($_));
$tmp =~ s/$q/\\$q/g;
$buf .= $tmp;
# '; $var }
$buf .= "$q; $out }";
$_ = $buf.$buf_end.$_;
last;
}
last
unless $st;
}
}
return $st;
};
}
=head1 AUTHOR
Alexandr Gomoliako <zzz@zzz.org.ua>
=head1 LICENSE
Copyright 2011-2012 Alexandr Gomoliako. All rights reserved.
This module is free software. It may be used, redistributed and/or modified
under the same terms as perl itself.
=cut
1;