#!/usr/bin/perl
# pkg-comp xml formatter.

use XML::Parser;

my @formats=qw(deb rpm tgz slp pkg);

sub _handle_char {
	my $val=$_[1];
	my $tag=$tagstack[-1];

	if ($tag eq 'title') {
		$title.=$val;
	}
	elsif ($tag eq 'intro') {
		$intro.=$val;
	}
	elsif ($tag eq 'copyright') {
		$copyright.=$val;
	}
	elsif ($tag eq 'todo') {
		$todo[$#todo].=$val;
	}
	elsif ($tag eq 'item') {
		push @items, $name;
	}
	elsif ($tag eq 'description') {
		if ($tagstack[-2] eq 'group') {
			$groupdesc[$#groups].=$val;
		}
		elsif ($tagstack[-2] eq 'item') {
			$itemdesc[$#groups][$#{$items[$#groups]}].=$val;
		}
		else {
			die "Description illegally nested in $tagstack[-2] tag"; 
		}
	}
	elsif (grep {$tag eq $_} @formats) {
		$data[$#groups][$#{$items[$#groups]}]{$tag}.=$val;
	}
	elsif ($tag eq 'p') {
		$paragraph.=$val;
	}
	elsif ($tag eq 'a') {
		$link.=$val;
	}
	elsif ($tag eq 'footnote') {
		$footnote.=$val;
	}
	elsif ($tag eq 'command') {
		$command.=$val;
	}
	elsif ($tag ne 'pkgcomp' && $tag ne 'group') {
		die "Unknown tag '$tag'";
	}
}

sub _handle_start {
	shift;
	push @tagstack,lc(shift);
	my %attrs=@_;
	
	if ($tagstack[-1] eq 'a') {
		$href=$attrs{href};
		$link='';
	}
	elsif ($tagstack[-1] eq 'group') {
		push @groups, $attrs{name};
	}
	elsif ($tagstack[-1] eq 'item') {
		$items[$#groups][$#{$items[$#groups]}+1] = $attrs{name};
	}
	elsif ($tagstack[-1] eq 'todo') {
		push @todo, '';
	}
	elsif ($tagstack[-1] eq 'p') {
		$paragraph='';
	}
	elsif ($tagstack[-1] eq 'footnote') {
		$footnote='';
	}
	elsif ($tagstack[-1] eq 'command') {
		$command='';
	}
}

sub _handle_end {
	my $old=pop(@tagstack);
	if ($old eq 'p') {
		_handle_char(undef, "<p>$paragraph</p>\n");
	}
	elsif ($old eq 'a') {
		_handle_char(undef, "<a href=\"$href\">$link</a>");
	}
	elsif ($old eq 'footnote') {
		$footnotes{$footnote}=++$num_footnotes unless exists $footnotes{$footnote};
		my $footnum=$footnotes{$footnote};
		_handle_char(undef, "[<a name=\"footref".$footnum.
			"\" href=\"#foot".$footnum."\">".
			$footnum."</a>]");
	}
	elsif ($old eq 'command') {
		_handle_char(undef, "<i>$command</i>");
	}
}

my $parser=XML::Parser->new(Handlers => {Start => \&_handle_start,
					 End   => \&_handle_end,
					 Char  => \&_handle_char});
$parser->parsefile("pkg-comp.xml");

# Now output the page.

# Page header.
print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">
<html>
<head>
<title>$title</title>
</head>
<body>
<h1>$title</h1>
$intro
";

# The table.
print "
<h2>Package format comparison table.</h2>
<table border=1>
<tr><th>feature</th>";
print "<th>$_</th>" foreach @formats;
print "</tr>";
foreach $group (0..$#groups) {
	print "<tr><th colspan=".(scalar(@formats)+1)."><a name=\"grouptab$group\" href=\"#groupdesc$group\">$groups[$group]</a></th></tr>\n";
	foreach $item (0..$#{$items[$group]}) {
		print "<tr><td><a name=\"itemtab$group+$item\" href=\"#itemdesc$group+$item\">$items[$group][$item]</a></td>";
		foreach $tag (@formats) {
			print "<td>$data[$group][$item]{$tag}</td>"
		}
		print "</tr>\n";
	}
}
print "</table>\n";

# Explanations of everything on the table.
print "<h2>What is compared.</h2>\n";
foreach $group (0..$#groups) {
	print "<h3><a name=\"groupdesc$group\" href=\"#grouptab$group\">$groups[$group].</a></h3>\n$groupdesc[$group]\n<dl>\n";
	foreach $item (0..$#{$items[$group]}) {
		print "<dt><a name=\"itemdesc$group+$item\" href=\"#itemtab$group+$item\">$items[$group][$item]</a></dt>\n";
		print "<dd>$itemdesc[$group][$item]</dd>\n";
	}
	print "</dl>\n";
}

# Todo.
print "<h2>Todo.</h2>\n<ul>\n<li>".join("\n<li>", @todo)."</ul>\n"
	if @todo;

# Footnotes.
if (%footnotes) {
	print "<h2>Footnotes.</h2>\n";
	foreach $footnote (sort { $footnotes{$a} <=> $footnotes{$b} } keys %footnotes) {
		my $num = $footnotes{$footnote};
		print "<a href=\"#footref$num\" name=\"foot$num\">$num.</a> ".
		      "$footnote<br>\n";
	}
}

# Page footer.
print "
<hr>
$copyright
<hr>Last modified at ".localtime(time - -M "pkg-comp.xml").";
generated from <a href=pkg-comp.xml>this source XML</a> by 
<a href=pkg-comp.pl>this program</a>.
</body>
</html>
";