2 # A really simple template engine
3 # (c) 2004 Martin Mares <mj@ucw.cz>
17 my ($r,$left,$right) = @_;
22 if ($$r =~ /\G([^$left$right]+)/cgs) {
23 } elsif ($$r =~ /\G([$left])/cgs) {
25 } elsif ($$r =~ /\G([$right])/cgs) {
28 die "File ended when looking for matching $right";
39 return $res unless $@;
40 die "Error evaluating $x: $@";
48 if ($f =~ /^(if|fi|else|elif)$/) {
50 $a ne "()" or die "\@if requires an argument";
52 unshift @cond, (eval_if_ok($a) ? 1 : -1);
56 } elsif ($f eq "fi") {
57 $a eq "()" or die "\@fi takes no arguments";
58 $#cond or die "\@fi without \@if";
60 } elsif ($f eq "else") {
61 $a eq "()" or die "\@else takes no arguments";
62 $#cond or die "\@else without \@if";
64 } elsif ($f eq "elif") {
65 $a ne "()" or die "\@elif requires an argument";
66 $#cond or die "\@elif without \@if";
69 } elsif ($cond[0] < 0) {
71 $cond[0] = (eval_if_ok($a) ? 1 : -1);
74 # print "Cond stack: @cond\n";
84 if ($t =~ /\G([^\@]+)/cgs) {
85 print $1 if $cond[0] > 0;
86 } elsif ($t =~ /\G\@\s*\n/cgs) {
87 # @ at end of line is ignored and eats the end of line
88 } elsif ($t =~ /\G\@#[^\n]*\n/cgs) {
89 # a comment, which is ignored
90 } elsif ($t =~ /\G\@\@/cgs) {
92 } elsif ($t =~ /\G\@{/cgs) {
93 my $x = get_nested(\$t, "{", "}");
95 } elsif ($t =~ /\G\@\[/cgs) {
96 my $x = get_nested(\$t, '\[', '\]');
100 } elsif ($t =~ /\G\@(\w+)\(/cgs) {
102 my $args = get_nested(\$t, '(', ')');
103 eval_func($func, $args);
104 } elsif ($t =~ /\G\@(\w+)([^\n]*)\n/cgs) {
105 eval_func($1, "($2)");
106 } elsif ($t =~ /\G\@(\$\w+)/cgs) {
107 print eval_if_ok($1);
108 } elsif ($t =~ /\G(\@[^\n]*)/cgs) {
109 die "Unknown control sequence $1";
110 } elsif ($t =~ /\G$/cgs) {
112 } elsif ($t =~ /\G([^\n]*)/cgs) {
113 die "Internal parser error at $1 (pos " . pos($t) . ")";
120 my $fh = new IO::File $name;
121 die "Unable to open $name: $!" unless defined $fh;
123 { local $/; undef $/; $text = <$fh>; }
135 $#cond and die "Unterminated \@if (depth $#cond)";
138 sub process_file($) {
144 sub process_string($) {
150 ### Commands available from the templates
157 eval_if_ok("\$$v = \$temp");
164 (!defined $f || @_) and die "\@load requires only one argument";