AxPoint is a Perl module - a Perl application - that can take XML presentations and convert them into a PDF presentation that can be viewed with Adobe's Acrobat reader or xpdf (amongst many other tools). As well as producing an open, cross platform, output file, it looks nice too. It's what I used this year to give my talk at YAPC::Europe, and I was very pleased with the results.
In my eyes however, AxPoint's biggest advantage has nothing to do with the output format that it uses - it's the input format. First of all it's very simple to write. It's just text, so I can use my editor, and I can quickly jot down what I want to say without worry too much about the actual presentation at that point. And since it's in text I can also email it to people and they can send me diffs back again, allowing colaberation on presentations very easily.
Of course, the real power of XML is that it's really easy to manipulate the presentation programatically - with Perl, or indeed with any other langage with an XML processing toolkit. This means it's really easy to extend the AxPoint langauge to add your own tags and extensions, as I'll demonstate below.
AxPoint presentations are pretty simple to write. Here's a really simple one:
<?xml version="1.0"?>
<slideshow>
<metadata> <speaker>Mark Fowler</speaker> <email>mark@twoshortplanks.com</email> <organisation>London Perl Mongers</organisation> <background>bg2.png</background> </metadata>
<title>An Example Slideshow</title>
<slide> <title>My Slide</title> <point>This is my slide</point> <point level="2">There are many like it</subpoint> <point level="2">But this is mine</subpoint> <point>I'd like to put it on a CD:</point> <image>cd.png</image> </slide>
</slideshow>
And this is what it looks like
There a lots more features (you can have sections, inlcude source code, include SVG graphics, tables to layout your text, and much more) all of which is covered at length
As AxPoint presentations are nothing more than XML then there's nothing to stop you processing them before they get as far as the XML::Handler for AxPoint - as far as AxPoint is concerned as long as it gets XML in the correct format then everything is fine by it.
Say - for example - you don't like the way that AxPoint forces you to
write <point level="2">
and you'd be happier with something
that simply called <subpoint>
. Well, all you need to do
is make a SAX filter that converts all subpoint>
tags into <point level="2"
tags automatically.
package XML::Filter::SubPoint;
# turn on Perl's safety features use strict; use warnings;
# use the XML::SAX::Base class so that unhandled events # are just passed straight though use base qw(XML::SAX::Base);
# simple constuctor method sub new { my $class = shift; my %options = @_; return bless \%options, $class; }
# implement a method that catches any start tags sub start_element { my $self = shift; # the sax processor my $tag = shift; # the tag itself
# is this a subpoint tag? if ($tag->{Name} eq "subpoint") { # rename it 'point' instead of 'subpoint' $tag->{Name} = "point"; # qualified name $tag->{LocalName} = $tag->{Name}; # unqualified name
# add an attribute for the level and set the properties $tag->{Attributes}{'{}level'} = { LocalName => 'level', Prefix => '', Value => '2', Name => 'level', NamespaceURI => '' }; }
# return the tag (following pipeline conventions) return $self->SUPER::start_element($tag); }
# and a simliar one that catches end tags sub end_element { my $self = shift; # the sax processor my $tag = shift; # the tag itself
# is this a subpoint tag? if ($tag->{Name} eq "subpoint") { # rename it 'point' instead of 'subpoint' $tag->{Name} = "point"; # qualified name $tag->{LocalName} = $tag->{Name}; # unqualified name }
# return the tag (following pipeline conventions) return $self->SUPER::end_element($tag); }
1; # all perl modules need to return "true"
This filter can then be placed in a XML::SAX::Pipeline with a script like this:
#!/usr/bin/perl
# turn on perl's safety features use strict; use warnings;
# load machines, including the Pipeline functiion use XML::SAX::Machines qw(:all);
# set up a xml pipeline to run the xml though my $machine = Pipeline( "XML::Filter::SubPoint", # first through our code "XML::Handler::AxPoint", # then though axpoint, out to STDOUT );
# check we got the correct command line arguments die "didn't specify a xml file to parse" unless @ARGV;
# parse the url (probably just the file) we were # passed on the command line $machine->parse_uri($ARGV[0]);
And voila! There we have it an extension to AxPoint. Now this is a simple example, but there's nothing to stop you going further with your preprocesssing. For example, you could have something that automatically extended entities into full blown text. You could have something that inserted source files. If you're really trying you could create a SVG graph from a table of figures.