#!/bin/perl -w
use strict;
use XML::Twig;
my $h2_nb=0;
my $h3_nb=0;
my $h4_nb=0;
my $title;
my $info;
my @toc;
my %example;
my $t= XML::Twig->new( twig_roots => { h2 => \&h2_first_pass },);
if( $ARGV[0]) { $t->parsefile( $ARGV[0]); } # process the twig
else { $t->parse( \*STDIN); }
$t= XML::Twig->new
( twig_handlers =>
{ h1 => \&h1,
author => sub { $info = "
by " . $_->text . ""; },
date => sub { $info .= "
updated ".$_->text."
"; },
h2 => \&h2,
h3 => \&h3,
h4 => \&h4,
example => \&example,
br => \&process_empty,
hr => \&process_empty,
td => \&td,
section => \§ion,
tutorial => \&tutorial,
method => \&method,
pre => \&pre,
},
);
if( $ARGV[0]) { $t->parsefile( $ARGV[0]); } # process the twig
else { $t->parse( \*STDIN); }
sub h2_first_pass
{ my( $t, $h2)= @_;
$h2_nb++;
my $filename= filename( $h2_nb);
my $section_title= "$h2_nb. " . $h2->text;
push @toc, { file => $filename, title => $section_title};
}
sub h1
{ my( $t, $h1)= @_;
$h2_nb=0;
$title= $h1->text;
}
sub h2
{ my( $t, $h2)= @_;
$h2_nb++;
$h3_nb=0;
$h2->prefix( "$h2_nb. ");
}
sub h3
{ my( $t, $h3)= @_;
$h3_nb++;
$h4_nb=0;
$h3->prefix( "$h2_nb.$h3_nb ");
}
sub h4
{ my( $t, $h4)= @_;
$h4_nb++;
$h4->prefix( "$h2_nb.$h3_nb.$h4_nb ");
}
sub pre
{ my( $t, $pre)= @_;
$pre->remove_cdata;
}
sub example
{ my( $t, $example)= @_;
# first get the included file
my $file= $example->text;
open( EXAMPLE, "<$file") or die "cannot open file $file: $!";
local undef $/;
my $text= ;
my $parser= $t->{twig_parser};
my $table= XML::Twig::Elt->new( 'table', $text);
my $p= $example->parent;
$table->paste( 'after', $p);
$table->insert( 'tr', 'td', 'pre');
$table->set_att( border => 1);
$table->set_att( width => "100%");
$table->set_att( bgcolor => "#00FFFF");
$example->set_gi( 'a');
$example->set_att( href => $file);
if( $example->att( 'class') && ($example->att( 'class') eq 'code') )
{ $example{$file}= $example->att( 'desc');
$example->del_att( 'desc');
$example->del_att( 'class');
}
}
sub process_empty
{ my( $t, $empty)= @_;
my $html_empty= XML::Twig::Elt->new( PCDATA, "<" . $empty->gi . ">");
$html_empty->paste( 'before', $empty);
$empty->cut;
}
sub td
{ my( $t, $td)= @_;
$td->set_text( ' ') unless( $td->text);
}
sub method
{ my( $t, $method)= @_;
$method->set_gi( 'tt');
my $a= $method->insert( 'a');
my $class= $method->att( 'class');
if( $class=~ /^twig/)
{ $class= ucfirst $class; }
elsif( $class=~ /^elt/)
{ $class= 'Twig_' . ucfirst $class; }
my $item= $method->text;
$method->del_att( 'class');
$a->set_att( href => "../twig_dev.html#METHODS_XML_$class\_$item");
}
sub section
{ my( $t, $section)= @_;
my $filename="yapc_twig_s$h2_nb.html";
warn "creating section $h2_nb\n";
open( SECTION, ">$filename") or die "cannot open $filename: $!";
select SECTION;
my $body= $section->insert( 'body');
$body->set_att( bgcolor => "#FFFFFF");
my $head= XML::Twig::Elt->new( 'head');
$head->paste( $section);
my $title= XML::Twig::Elt->new( 'title', "Processing XMl efficiently with XML::Twig - Section $h2_nb");
$title->paste( $head);
$head->insert_new_elt( last_child => meta => { content => "main", name => "template"});
my $top_links= links( $h2_nb);
my $bottom_links= $top_links->copy;
$top_links->paste( $body);
my $hr= XML::Twig::Elt->new( hr => '#EMPTY');
$hr->paste( after => $top_links);
$bottom_links->paste( 'last_child', $body);
$hr= XML::Twig::Elt->new( hr => '#EMPTY');
$hr->paste( before => $bottom_links);
$section->set_gi( 'html');
$section->print;
$t->purge;
close SECTION;
}
sub tutorial
{ my $filename="index.html";
open( INDEX, ">$filename") or die "cannot open $filename: $!";
select INDEX;
print "\n$title\n";
print "$title
\n";
print $info;
print "
\n";
print "Table of Content
\n\n";
print "Code Examples
\n";
foreach my $file ( sort keys %example)
{ print "$file: $example{$file}
\n"; }
print "
\n";
print "";
close INDEX;
}
sub filename
{ my $section= shift;
return "yapc_twig_s$section.html";
}
sub links
{ my $section = shift;
my $current = $section-1;
my $previous = $current-1;
my $next = $current+1;
my $table= XML::Twig::Elt->new( 'table');
$table->set_att( width => "100%" );
my $tr= $table->insert( 'tr');
my $td= $tr->insert( 'td');
$td->set_atts( { align => "left", width => "33%" });
unless( $previous == -1)
{ my $a= $td->insert( 'a');
$a->set_att( href => $toc[$previous]->{file});
my $img= $a->insert( 'img');
$img->set_atts( { src => "previous.gif", alt => "Previous", border => "0" });
my $text= XML::Twig::Elt->new( PCDATA, { '#ASIS' => 1}, "
" . $toc[$previous]->{title});
$text->paste( 'last_child', $a);
}
else
{ my $nbsp= XML::Twig::Elt->new( PCDATA, "");
$nbsp->paste( $td);
}
$td= XML::Twig::Elt->new( 'td', { '#ASIS' => 1}, ''.
'
' .
'
Table of Content'); $td->set_asis;
$td->set_atts( { align => "center", width => "34%" });
$td->paste( 'last_child', $tr);
$td= XML::Twig::Elt->new( 'td');
$td->set_atts( { align => "right", width => "33%" });
unless( $next > $#toc)
{ my $a= $td->insert( 'a');
$a->set_att( href => $toc[$next]->{file});
my $img= $a->insert( 'img');
$img->set_atts( { src => "next.gif", alt => "Next", border => "0"});
my $text= XML::Twig::Elt->new( '#PCDATA' => {'#ASIS' => 1}, "
" . $toc[$next]->{title});
$text->paste( 'last_child', $a);
}
else
{ my $nbsp= XML::Twig::Elt->new( PCDATA, {'#ASIS' => 1}, "");
$nbsp->paste( $td);
}
$td->paste( 'last_child', $tr);
return $table;
}