#!/usr/bin/perl -w # # gutxmlintro.cgi converts the intro of a gutenberg xml # book into html. A quick demo of XML::Twig. # use strict; use XML::Twig; use CGI qw(:standard); (my $file = path_info) =~ s{^/}{}; # If calling URL is # http://some.org//gutxmlintro/file.xml # then this sets $file='file.xml'. $file = 'darwin.xml' unless $file; my $twig; my $filetype; if (param('xml')) { $filetype = 'text/plain'; $twig = new XML::Twig( TwigRoots => {frontmatter => 1} ); } else { $filetype = 'text/html'; $twig = new XML::Twig( # Only keep 'frontmatter' elements and ancestors. TwigRoots => { frontmatter => 1 }, TwigHandlers => { gutbook => sub { setgi('html', @_)}, frontmatter => \&frontmatter, para => sub { setgi('p', @_) }, title => sub { setgi('h1', @_) }, subtitle => sub { setgi('h2', @_) }, author => sub { setgi('p', @_) }, # "erase" replaces and element with its kids. titlepage => sub { $_[1]->erase; }, epigraph => sub { $_[1]->erase; }, attrib => sub { setgi('i', @_) }, deflist => sub { setgi('ol', @_) }, item => sub { setgi('li', @_) }, desc => sub { setgi('i', @_) }, def => sub { setgi('p', @_) }, htitlepage => \&htitlepage, introduction => sub { setgi('hr', @_) }, } ); } $twig->parsefile($file); $twig->set_pretty_print('indented'); print header($filetype); # The xml thingies apparently converts ' chars to ' . # This converts them back, by hand. (my $output = $twig->sprint) =~ s/'/'/g; #' print $output; # - subroutines ----------------------------- # Convert the htitlepage element to a table, moving its children # down deeper into elements. sub htitlepage { my ($t, $elt) = @_; $elt->set_gi('table'); # Change this to 'table' $elt->set_atts( { align=>'center' } ); # Set an attribute my @kids = $elt->children(); # Save list of its children my $tr = new XML::Twig::Elt('tr'); # Two new elements my $td = new XML::Twig::Elt('td'); $elt->set_content($tr); # Replace contents of 'table' $tr->set_content($td); # Replace contents of 'tr' $td->set_content(@kids); # Put all children in 'td' } # Convert this element to a "body" tag. sub frontmatter { my ($t, $elt) = @_; $elt->set_gi('body'); $elt->set_atts( {bgcolor => 'white'} ); } # Change the "gi" (i.e. name) of an element. sub setgi { my ($newgi, $t, $elt) = @_; $elt->set_gi($newgi); }