#!/usr/bin/perl
use HTML::TreeBuilder;
use HTML::Element;
use strict;
my %macros;
my ($a,$b,$c) = 0..2;
sub expand_includes
{
my $node = shift;
my @includes = $node->find_by_tag_name('include');
foreach my $inc (@includes)
{
my $filename = $inc->attr('file');
#print "Including file: $filename\n";
my $tree = HTML::TreeBuilder->new;
$tree->ignore_unknown(0);
$tree->implicit_tags(0);
$tree->parse_file($filename);
expand_includes($tree); # Recursively include
$inc->push_content($tree->content_list());
$inc->replace_with_content->delete;
}
}
sub extract_macros
{
my $node = shift;
my @macro_list = $node->find_by_tag_name('macro');
foreach my $mnode (@macro_list)
{
#push @macros,($mnode->clone());
my $name = $mnode->attr('name');
foreach my $content ($mnode->content_list())
{
if ($content->tag eq 'option')
{
#push @{$macros{$name}[0]{$content->attr('name')}},
# HTML::Element->clone_list($content->content_list());
my $c;
foreach my $n ($content->content_refs_list())
{
if (ref $$n)
{
#print "HTML ";
$c .= $$n->as_HTML;
} else {
#print "TEXT ";
$c .= $$n;
}
}
#push @{$macros{$name}[0]{$content->attr('name')}},$c;
$macros{$name}[0]{$content->attr('name')} = $c;
#print "PUSHING: ",$content->attr('name')," -> '$c'\n";
} elsif ($content->tag eq 'body') {
$macros{$name}[1] = $content->clone()
# ,HTML::Element->clone_list($content->content_list());
}
}
#$macros{$name} = @content;
#push @macros,[$name,@content];
$mnode->delete();
}
}
sub expand_options
{
my $node = shift;
my %vals = @_;
foreach my $attr ($node->all_external_attr_names())
{
#print "Expanding $attr = ",$node->attr($attr),"\n";
foreach my $v (keys %vals)
{
#print " Trying $v -> $vals{$v}\n";
my $n = $node->attr($attr);
#print " Got $v = $n\n" if $n =~ s/\$$v/$vals{$v}/;
#print " Do $v = $n\n";
$n =~ s/\$$v/$vals{$v}/;
$node->attr($attr,$n);
}
#print " Ended with $attr = ",$node->attr($attr),"\n";
}
foreach my $item ($node->content_refs_list)
{
if (ref $$item)
{
expand_options($$item,%vals);
} else {
foreach my $v (sort keys %vals)
{
#print " Got $v = $$item\n" if $$item =~ s/\$$v/$vals{$v}/;
$$item =~ s/\$$v/$vals{$v}/;
}
}
}
return $node;
}
sub expand_macros
{
my $node = shift;
foreach my $mac (sort keys %macros)
{
my @nlist = $node->find_by_tag_name($mac);
foreach my $enode (@nlist)
{
# Expand all the found macros
my $new_contents = $macros{$mac}[1];
my %vals = %{$macros{$mac}[0]};
my %nondefvals = $enode->all_external_attr();
foreach my $v (sort keys %vals)
{
#print "val $v: $vals{$v}\n";
}
#print "--\n";
# set the non-defaults
foreach my $v (sort keys %nondefvals)
{
#print "Adding non-default $v: $nondefvals{$v}\n";
$vals{$v} = $nondefvals{$v};
}
foreach my $v (sort keys %vals)
{
#print "val $v: $vals{$v}\n";
}
# Find and expand $options
$new_contents = expand_options($new_contents,%vals);
# Replace the 'content' tag with contents
my @middle = $new_contents->find_by_tag_name('content');
foreach my $mid (@middle)
{
$mid->replace_with($enode->content_list());
}
# Actually replace the node with expansion
$enode->replace_with($new_contents->content_list());
}
}
}
foreach my $filename (@ARGV)
{
$filename =~ s/\.mhtml$//;
if ( -e "$filename.mhtml")
{
#print "It exists! [$filename.mhtml]\n";
my $tree = HTML::TreeBuilder->new;
$tree->ignore_unknown(0);
$tree->implicit_tags(0);
$tree->parse_file($filename.'.mhtml');
$tree = $tree->elementify();
#print "A lovely dump:\n";
#$tree->dump;
#print "A lovely render:\n";
#print $tree->as_HTML(undef," "), "\n";
#print "Calling expand_inludes...\n";
expand_includes($tree);
#print "Calling extract_macros...\n";
extract_macros($tree);
#print "Macro list:\n";
#foreach my $name (sort keys %macros)
#{
# print "$name\noptions: ";
# foreach my $opt (sort keys %{$macros{$name}[0]})
# {
# print "$opt ";
# if ($macros{$name}[0]{$opt})
# {
# #foreach my $c (@{$macros{$name}[0]{$opt}})
# #{
# # print $c;
# #}
# print $macros{$name}[0]{$opt};
# }
# }
# print "\n";
#foreach my $content ($macros{$name})
#{
# print $content->as_HTML(undef," "),"\n";
#}
# }
# print "Calling expand_macros...\n";
expand_macros($tree);
# print "\n\nThe new render:\n";
#my $out;
open OUT,">$filename.html";
foreach my $content ($tree->content_list())
{
#$out .= $content->as_HTML(undef," "),"\n";
if (ref $content)
{
print OUT $content->as_HTML(undef," "),"\n";
} else {
#print OUT ">>$content<<";
}
# #$content->dump;
}
# print OUT $tree->as_HTML(undef," "),"\n";
close OUT;
#print $tree->as_HTML(undef," "),"\n\n";
$tree = $tree->delete;
#$tree = HTML::TreeBuilder->new;
#$tree->ignore_unknown(0);
#$tree->parse($out);
#$tree->eof();
#print $tree->as_HTML(undef," "),"\n";
#$tree = $tree->delete;
}
}