# Copyright (c) 2004, 2005 Denis Petrov # $Id: magic.pl,v 1.8 2005/02/18 02:22:28 Owner Exp $ # Distributed under the terms of the GNU General Public License # # Magic Template Processor # # Magic Home: http://www.denispetrov.com/magic/ use strict; # use Data::Dumper; package main; sub Magic { my $label_regexp = "[a-zA-z_][a-zA-z0-9_]*"; my %labels; my @parsed = ('<%_%>' . $_[0] . '<%END%>') =~ /(<%.+?(?=%>)%>)(.*?)(?=<%|$)/gs; my $i = 0; my $len = scalar(@parsed); for ( $i = 0; $i < $len; $i++ ) { my $l = $parsed[$i]; if ( $l =~ /<%($label_regexp)%>/ ) { if ( exists($labels{$1}) && $labels{$1} != $i ) { warn("Found duplicate label '$1', it has been ignored"); } else { $labels{$1} = $i; } } elsif ( $l =~ /<%(.+)%>/s ) { my $result = eval($1); if ( !defined($result) ) { warn("$@\n TEMPLATE CODE:\n$l\nEND TEMPLATE CODE\n"); } elsif ( $result =~ /$label_regexp/ ) { if ( exists $labels{$result} ) { $i = $labels{$result}; } else { #trace labels forward my $j; my $found_label = undef; for ( $j = $i+1; $j < $len; $j++ ) { if ( $parsed[$j] =~ /<%($label_regexp)%>/ ) { $labels{$1} = $j; if ( $1 eq $result ) { $i = $j; $found_label = 1; last; } } } if ( !$found_label ) { warn("Label '$result' does not exist in the template near" . "\nTEMPLATE CODE:\n$l\nEND TEMPLATE CODE\n"); } } } } else { $l =~ s/\"/\\\"/g; my $result = eval("\"".$l."\""); if ( !defined($result) ) { warn("$@\n TEMPLATE TEXT:\n$l\nEND TEMPLATE TEXT\n"); } else { print( $result ); } } } # print Dumper(\@parsed); # print Dumper(%labels); } 1;