use 5.010; use strict; use warnings; our $start_time = time; #Embedded perl HTML template compiler object class package HTML::template; #Preloads new template object: #@_ = class, embedded perl/html input source sub new { my ($class, $input) = @_; $input //= $_; #Slurp the source template open my $fh, "<", $input or die "$! \"$input\""; local $/; my $slurp = <$fh>; close $fh; #Extract perl script from the template my $content = \$slurp; my $position = 0; my $script = "sub {\n\# line 1 \"$input\"\n"; #Scan html comment tags while ( $slurp =~ //gso ) { #Insert text block $script .= "print substr(\${\$content},$position,$-[0]-$position);\n"; #Translate line numbers my $line = ( substr($slurp,0,$position) =~ tr/\n// ) + 1; #Insert perl block using fixed line number $script .= "\# line $line\n$+{cmd}\n"; #Advance to next block $position = $+[0]; } #Insert the last text block $script .= "print substr(\${\$content},$position);}"; #Precompile script my $compiled = eval($script) or die; #Define template object list bless [$content, $compiled], $class; } #Execute the template object ##@_ = class, html output target sub run { my ($self, $output) = @_; my ($content, $compiled) = @{$self}; $output //= $_; #Redirect output local (*STDOUT); open(STDOUT, ">", $output); #Excute precompiled script $compiled->(); } #Sample program utilizing HTML::template my $sample_input = <<'END'; Numbers generated at
Number=
Time used seconds.
END my $template = HTML::template->new(\$sample_input); my $sample_output = ''; $template->run(\$sample_output); print $sample_output; #Output from sample_template Numbers generated at 1265498059
Number=1
Number=2
Number=3
Number=4
Time used 0 seconds.