sub get_template { local($template) = @_; $template =~ m|(.*/)?([^/]+)|; $basepath = $1; $template = $2; @depends=("$basepath$template"); open(TEMP, $basepath . $template); $template = ""; while() { # s|\r||g; s|\n$||; s|\n|\\n|g; $template .= "$_\n"; } #@template = ; close(TEMP); #$template = join "", @template; @theeval = &parse_template(""," "); @theeval = ( "sub { local(\$ref) = \@_; local(\%myhash) = \%\$ref; local(\$output) = \"\"; ", @theeval, " return \$output; }"); $theeval = join("\n", @theeval); #print "\$theeval ='$theeval'\n"; $theeval = eval($theeval) or die $!; #print "\$theeval ='$theeval'\n"; return $theeval; } @thetags = ( "foreach", "include", "include-sub", "print", "eval", "if", "ifnot", "ifeval", "else", "elseif", "elseifnot", "elseifeval", "!if", "!else", "!elseif", "!endif", ); $thetagreg = join '|', map quotemeta, @thetags; sub parse_template { local($endtag,$indent) = @_; local(@myeval); while($template) { # 1 12 3 34 45 56 6 27 78 8 if( $template =~ /^(.*?)(<(\/?)($thetagreg)(\s([^>]*?))?(\/?)>)(\n?)(.*)$/si ) { $pretext = $1; $tagbody = $2; $isend = $3; $tag = $4; $tagatts = $6; $hasend = $7; $newline = $8; $template = $9; $lineindent = ""; if($pretext =~ m|\n( *)$|is) { $lineindent = $1; $pretext =~ s|\n( *)$|\n|is; } $pretext =~ s/\n/\\newline\\/g; $pretext = quotemeta($pretext); $pretext =~ s/\\\\newline\\\\/\\n/g; $tag = lc($tag); $tagatts =~ s/^ +//; @myeval = (@myeval, "$indent\$output .= \"" . $pretext . "\";"); if($isend eq "/") { if($tag eq $endtag) { return @myeval; } } if($tag eq "print") { $newline = "\\n" if $newline eq "\n"; if($lineindent) { @myeval = (@myeval, "$indent\{"); @myeval = (@myeval, "$indent local(\$text) = \$myhash{" . $tagatts . "};"); @myeval = (@myeval, "$indent \$text =~ s|^(.)|" . $lineindent . "\$1|gim;"); @myeval = (@myeval, "$indent \$output .= \"\$text$newline\";"); @myeval = (@myeval, "$indent\}"); } else { @myeval = (@myeval, "$indent \$output .= \"\$myhash{" . $tagatts . "}$newline\";"); } } elsif($tag eq "eval") { @myeval = (@myeval, "$indent\$output .= eval(\"" . quotemeta($tagatts) . "\") . \"$newline\";"); } elsif($tag eq "if") { if($isend eq "") { @myeval = (@myeval, "$indent\if(&istrue(\$myhash{" . $tagatts . "})) {"); $indent .= " "; } else { $indent =~ s/ $//; @myeval = (@myeval, "$indent\}"); } } elsif($tag eq "ifnot") { if($isend eq "") { @myeval = (@myeval, "$indent\if(! &istrue(\$myhash{" . $tagatts . "})) {"); $indent .= " "; } else { $indent =~ s/ $//; @myeval = (@myeval, "$indent\}"); } } elsif($tag eq "ifeval") { if($isend eq "") { @myeval = (@myeval, "$indent\if(&istrue(eval(\"" . quotemeta($tagatts) . "\"))) {"); $indent .= " "; } else { $indent =~ s/ $//; @myeval = (@myeval, "$indent\}"); } } elsif($tag eq "else") { $indent =~ s/ $//; @myeval = (@myeval, "$indent\} else {"); $indent .= " "; } elsif($tag eq "elseif") { $indent =~ s/ $//; @myeval = (@myeval, "$indent\} elsif(&istrue(\$myhash{" . $tagatts . "})) {"); $indent .= " "; } elsif($tag eq "elseifnot") { $indent =~ s/ $//; @myeval = (@myeval, "$indent\} elsif(! &istrue(\$myhash{" . $tagatts . "})) {"); $indent .= " "; } elsif($tag eq "elseifeval") { $indent =~ s/ $//; @myeval = (@myeval, "$indent\} elsif(&istrue(eval(\"" . quotemeta($tagatts) . "\"))) {"); $indent .= " "; } elsif($tag eq "foreach") { @myeval = (@myeval, "$indent\{"); @myeval = (@myeval, "$indent local(\$ref) = \$myhash{" . $tagatts . "};"); @myeval = (@myeval, "$indent local(\%myhash) = \%\$ref;"); @myeval = (@myeval, "$indent local(\@keys) = sort(keys(\%myhash));"); @myeval = (@myeval, "$indent local(\$n) = 0;"); # @myeval = (@myeval, "$indent foreach \$key (sort keys(\%myhash)) {"); @myeval = (@myeval, "$indent for(\$n=0; \$n<=\$#keys; \$n++) {"); @myeval = (@myeval, "$indent local(\$key) = \$keys[\$n];"); @myeval = (@myeval, "$indent local(\$ref) = \$myhash{\$key};"); @myeval = (@myeval, "$indent local(\%myhash) = \%\$ref;"); @myeval = (@myeval, &parse_template($tag, $indent . " ")); @myeval = (@myeval, "$indent }"); @myeval = (@myeval, "$indent}"); } elsif($tag eq "include") { open(TEMP, "templates/$tagatts") or die "Can't open subtemplate $tagatts: $!"; @depends = (@depends, "templates/$tagatts"); local(@text) = ; local($text) = join("",@text); close(TEMP); $text =~ s|^(.)|$lineindent$1|gim; $template = $text . $template; } elsif($tag eq "include-sub") { $tagatts =~ m|(.*) (.*) (.*)|; local($file, $from, $to) = ($1, $2, $3); open(TEMP, "templates/$file") or die "Can't open subtemplate $tagatts: $!"; @depends = (@depends, "templates/$file"); local(@text) = ; local($text) = join("",@text); close(TEMP); $text =~ s|\<\%$from\%\>|$to|gs; $template = $text . $template; } elsif($tag eq "!if") { $r = eval($tagatts); $collect = !!$r; $template =~ s|^.*?\<\!|\<\!|s unless $collect; push @beentrue, 0; $beentrue[-1] = 1 if $collect; } elsif($tag eq "!else") { $collect = !$beentrue[-1]; $template =~ s|^.*?\<\!|\<\!|s unless $collect; } elsif($tag eq "!elseif") { if($collect) { $collect = 0; } else { $r = eval($tagatts); $collect = !!$r; } $template =~ s|^.*?\<\!|\<\!|s unless $collect; $beentrue[-1] = 1 if $collect; } elsif($tag eq "!endif") { $collect = 1; pop @beentrue; } } else { $template =~ s/\n/\\newline\\/g; $template = quotemeta($template); $template =~ s/\\\\newline\\\\/\\n/g; @myeval = (@myeval, "$indent\$output .= \"" . $template . "\";"); $template = ""; } } return @myeval; } 1;