sub parse_template {
my $self = shift;
my $line;
my $in_if = 0; my $in_loop = 0; my $in_js = 0; my $in_np = 0; # Use for syntax checking
$self->{'last'} = 'text'; # Inside which statement
$self->{'b'} = {}; # which line of current block are we in
$self->{'cblock'} = 0; # Whick block are we in
$self->{'bcount'} = $self->{'cblock'}; # KISS block id generator
my @structs;
$self->load_syntax($self->{'cblock'});
while ($line = shift @{$self->{'TEMPLATE'}}) {
$self->{'b'}{$self->{'cblock'}}{$self->{'last'}} = 0 unless (defined $self->{'b'}{$self->{'cblock'}}{$self->{'last'}});
# print "[$self->{'bcount'}][$self->{'cblock'}][$self->{'last'}]<$self->{'b'}{$self->{'cblock'}}{$self->{'last'}}> $line";
if ($in_np) { goto ENDNP; }
if ($line =~ /\Q$self->{'syntax'}{t}\E(\w+)/) { $self->{'BLOCK'}{'DEFINED'}{$1}++; }
if ($line =~ /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{'syn'}\E\s(.+)\Q$self->{'syntax'}{te}\E/i) {
my $change = $1;
#my $t = $self->separate( split /\Q$self->{'syntax'}{'ts'}\E\s*\Q$self->{'syntax'}{'syn'}\E\s+.+?\Q$self->{'syntax'}{te}\E/i,$line,2 );
my $t = $self->separate( split /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{'syn'}\E\s.+?\Q$self->{'syntax'}{te}\E/i,$line,2 );
my @a = ($change =~ m/(\w+)\s*=\s*['"]*(.+?)['"]*(?=\h+\w+\h*=|$)/g);
my $thisline = $self->{'b'}{$self->{'cblock'}}{$self->{'last'}}++;
if ($t) { $thisline++; }
$self->{'BLOCK'}{$self->{'cblock'}}{'jumps'}{$self->{'last'}}{$thisline} = ++$self->{'bcount'};
push @structs,$self->{'cblock'};
$self->{'cblock'} = $self->{'bcount'};
$self->{'BLOCK'}{$self->{'cblock'}}{'type'} = 'syntax';
@{$self->{'BLOCK'}{$self->{'cblock'}}{'syntax'}} = @a;
$self->load_syntax($self->{'cblock'});
push @structs,$self->{'last'}; $self->{'last'} = 'text';
next;
}
if ($line =~ /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{load}\E\s+\Q$self->{'syntax'}{file}\E\s*=\s*["']*(.+?)['"]*\/*\Q$self->{'syntax'}{te}\E/i) {
my $file = "$self->{'BASEDIR'}/$1";
$self->separate( split /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{load}\E\s+.+?\Q$self->{'syntax'}{te}\E/i,$line,2 );
if (-e $file) {
my @in = file_slurp($file);
unshift @{$self->{'TEMPLATE'}},@in;
push @{$self->{'BLOCK'}{'Files2'}}, $file;
} else { unshift @{$self->{'TEMPLATE'}}, "<strong>File not found: $file</strong>"; }
my $thisline = $self->{'b'}{$self->{'cblock'}}{$self->{'last'}}++;
next;
}
if ($line =~ /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{it}\E\s+(.+?)\Q$self->{'syntax'}{te}\E/i) {
my $statement = $1;
my $t = $self->separate( split /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{it}\E\s+.+?\Q$self->{'syntax'}{te}\E/i,$line,2 );
my $thisline = $self->{'b'}{$self->{'cblock'}}{$self->{'last'}}++;
if ($t) { $thisline++; }
$self->{'BLOCK'}{$self->{'cblock'}}{'jumps'}{$self->{'last'}}{$thisline} = ++$self->{'bcount'};
push @structs,$self->{'cblock'};
$self->{'cblock'} = $self->{'bcount'};
$self->{'BLOCK'}{$self->{'cblock'}}{'type'} = 'if';
$self->{'BLOCK'}{$self->{'cblock'}}{'statement'} = $statement;
push @structs,$self->{'last'}; $self->{'last'} = 'if';
$in_if++;
next;
}
if ($line =~ /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{et}\E.*?\Q$self->{'syntax'}{te}\E/i) {
warn "else, no if" unless ($in_if);
$self->separate( split /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{et}\E.*?\Q$self->{'syntax'}{te}\E/i,$line,2 );
$self->{'last'} = 'else';
next;
}
if ($line =~ /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{noparse}\E\Q$self->{'syntax'}{te}\E/i) {
my $t = $self->separate( split /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{noparse}\E\s+.+?\Q$self->{'syntax'}{te}\E/i,$line,2 );
my $thisline = $self->{'b'}{$self->{'cblock'}}{$self->{'last'}}++;
if ($t) { $thisline++; }
$self->{'BLOCK'}{$self->{'cblock'}}{'jumps'}{$self->{'last'}}{$thisline} = ++$self->{'bcount'};
push @structs,$self->{'cblock'};
$self->{'cblock'} = $self->{'bcount'};
$self->{'BLOCK'}{$self->{'cblock'}}{'type'} = 'noparse';
push @structs,$self->{'last'}; $self->{'last'} = 'text';
$in_np++;
next;
}
if ($line =~ /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{lt}\E\s+(.+?)\Q$self->{'syntax'}{te}\E/i) {
my $statement = $1;
if ($statement =~ /\w+[sS]\s*=\s*[\@\Q$self->{'syntax'}{t}\E](\w+)/) { $self->{'BLOCK'}{'DEFINED'}{$1}++; }
my $t = $self->separate( split /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{lt}\E\s+.+?\Q$self->{'syntax'}{te}\E/,$line,2 );
my $thisline = $self->{'b'}{$self->{'cblock'}}{$self->{'last'}}++;
if ($t) { $thisline++; }
$self->{'BLOCK'}{$self->{'cblock'}}{'jumps'}{$self->{'last'}}{$thisline} = ++$self->{'bcount'};
push @structs,$self->{'cblock'};
$self->{'cblock'} = $self->{'bcount'};
$self->{'BLOCK'}{$self->{'cblock'}}{'type'} = 'loop';
$self->{'BLOCK'}{$self->{'cblock'}}{'statement'} = $statement;
push @structs,$self->{'last'}; $self->{'last'} = 'text';
$in_loop++;
next;
}
if ($line =~ /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{e}\E\s*\Q$self->{'syntax'}{syn}\E.*?\Q$self->{'syntax'}{te}\E/i) {
$self->separate( split /\Q$self->{'syntax'}{ts}\E\s*\/\s*\Q$self->{'syntax'}{syn}\E.*?\Q$self->{'syntax'}{te}\E/i,$line,2 );
$self->{'last'} = pop @structs;
#$self->{'cblock'} = --$self->{'bcount'};
$self->{'cblock'} = pop @structs;
$self->load_syntax($self->{'cblock'});
next;
}
if ($line =~ /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{e}\E\s*\Q$self->{'syntax'}{it}\E.*?\Q$self->{'syntax'}{te}\E/i) {
warn "endif without if" unless ($in_if);
$self->separate( split /\Q$self->{'syntax'}{ts}\E\s*\/\s*\Q$self->{'syntax'}{it}\E.*?\Q$self->{'syntax'}{te}\E/i,$line,2 );
$in_if--;
$self->{'last'} = pop @structs;
$self->{'cblock'} = pop @structs;
next;
}
ENDNP: if ($line =~ /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{e}\E\s*\Q$self->{'syntax'}{noparse}\E.*?\Q$self->{'syntax'}{te}\E/i) {
warn "end $self->{'syntax'}{'noparse'} without if" unless ($in_np);
$self->separate( split /\Q$self->{'syntax'}{ts}\E\s*\/\s*\Q$self->{'syntax'}{noparse}\E.*?\Q$self->{'syntax'}{te}\E/i,$line,2 );
$in_np--;
$self->{'last'} = pop @structs;
$self->{'cblock'} = pop @structs;
next;
}
if ($line =~ /\Q$self->{'syntax'}{ts}\E\s*\Q$self->{'syntax'}{e}\E\s*\Q$self->{'syntax'}{lt}\E.*?\Q$self->{'syntax'}{te}\E/i) {
warn "endloop, no loop" unless ($in_loop);
$self->separate( split /\Q$self->{'syntax'}{ts}\E\s*\/\s*\Q$self->{'syntax'}{lt}\E.*?\Q$self->{'syntax'}{te}\E/i,$line,2 );
$in_loop--;
$self->{'last'} = pop @structs;
$self->{'cblock'} = pop @structs;
next;
}
push @{$self->{'BLOCK'}{$self->{'cblock'}}{$self->{'last'}}},$line;
$self->{'b'}{$self->{'cblock'}}{$self->{'last'}}++;
# print "[$self->{'bcount'}][$self->{'cblock'}][$self->{'last'}]<$self->{'b'}{$self->{'cblock'}}{$self->{'last'}}> $line";
}
if ($in_if) { warn " hanging if not closed "; }
if ($in_loop) { warn " hanging loop not closed "; }
}
sub separate {
my $self = shift;
my $prematch = shift; my $postmatch = shift;
my $ret = 0;
if (defined $prematch) {
#push @{$self->{'BLOCK'}{$self->{'cblock'}}{$self->{'last'}}},$prematch;
$ret = $self->{'b'}{$self->{'cblock'}}{$self->{'last'}};
${$self->{'BLOCK'}{$self->{'cblock'}}{$self->{'last'}}}[$ret] .= $prematch;
$ret++; }
if (defined $postmatch) { unshift @{$self->{'TEMPLATE'}},$postmatch; }
return $ret;
}