#!/usr/bin/perl

use XML::Parser;

$prolog = qq{%!PS-Adobe-3.0
%%Orientation: landscape
%%Pages: (atend)
%%BeginProlog
/inch { 72 mul } def
statusdict /manualfeed true put
% fonts and font sizes
/font /Times-Bold findfont def
/ttfont /Courier-Bold findfont def
/headersize 30 def
/rawsize 24 def
/bodysize 40 def
/lead 5 def
/bodylead bodysize lead add def
/rawlead rawsize 3 add def
/headerfont { font headersize scalefont setfont } def
/ttheaderfont { ttfont rawsize scalefont setfont } def
/bodyfont { font bodysize scalefont setfont } def
/rawfont { font rawsize scalefont setfont } def
% page layout
% /pageborder { 0 0 moveto 8.5 inch 0 lineto 8.5 inch 11 inch lineto 0 inch 11 inch lineto 0 0 lineto stroke } def
/pagetop 8 inch def
/pagewidth 10 inch def
/pagebase pagetop bodylead sub def
/headerindent .25 inch def
/itemindent .5 inch def
/topline { 0 inch pagetop lead lead add sub moveto 
	   2 setlinewidth
	   pagewidth headerindent add  0 inch rlineto stroke  } def
/showtitle { 90 rotate 0.5 inch -8.5 inch translate
	     headerfont 0 inch pagetop moveto show
	     topline
	     /itemy pagebase bodylead sub def } def
/showsection { headerfont headerindent pagebase moveto show  } def
/showpageno { headerfont pagewidth pagetop moveto show  } def
/showitem { headerfont itemindent itemy moveto show
	    /itemy itemy bodylead sub def } def
/showurl { ttheaderfont itemindent itemy moveto show
	    /itemy itemy bodylead sub def } def
/showraw { rawfont itemindent itemy moveto show
	    /itemy itemy rawlead sub def } def
/finishpage { showpage } def
%%EndProlog
};

$epilog=qq{%%Trailer
%%Pages: _
%%EOF
};

sub inittag { $lastcdata = ""; }
sub print_prolog { 
    print $prolog; 
    &inittag; 
    $pageno = 1;
}
sub print_epilog {     
    $epilog =~ s/_/$pageno/;
    print $epilog; 
}

sub handle_eps {
    my @bbox, $llx, $lly, $urx, $ury, $wx, $wy;
    my $bbline, $content, $filename;
    # cheat, for now $lastcdata is the filename
    # output qq{($lastcdata) showurl\n};
    $debug && print STDERR  "GOT EPS:{{$lastcdata}}\n";
    $filename = $lastcdata;
    # strip out postscript comments
    $content = `sed -e 's/%.*$//' $filename`;
    # but grab the bounding box directly
    $bbline = `grep %%BoundingBox $filename`;
    @bbox = ($bbline =~ m/%%BoundingBox: (\d+) (\d+) (\d+) (\d+)/);
    ($llx, $lly, $urx, $ury) = @bbox;
    $wx = $urx - $llx;
    $wy = $ury - $lly;
    $debug && print STDERR "GOT bbox:{{".join(",",@bbox)."}}\n";
    # having extracted that, seems we should strip out all the other
    # comments, at least in xv output, but perhaps that's because it is
    # only weakly EPSF? Perhaps cheat and do it in the `cat` above?
    #
    # from EPSF Format, V3.0, appendix H of the PostScript LRM 2nd ed.
    print "save\n";
    print "itemindent $llx sub itemy $ury sub translate\n";
    print "userdict dup maxlength dict copy begin\n";
    print "/showpage { } def\n";
    print "0 setgray 0 setlinecap 1 setlinewidth\n";
    print "0 setlinejoin 10 setmiterlimit [] 0 setdash newpath\n";
    print "%%BeginDocument $filename\n";
    print $content;
    print "%%EndDocument\n";
    print "end\n";
    print "restore\n";
    print "/itemy itemy $ury sub def\n"; # update itemy for later lines
};

sub handle_start {
    # Start          (Expat, Element [, Attr, Val [,...]])
    my ($expat, $elem) = @_;
    if ($elem =~ /^slideshow$/) {
	&inittag;
    } elsif ($elem =~ /^title$/) {
	&inittag;
    } elsif ($elem =~ /^author$/) {
	&inittag;
    } elsif ($elem =~ /^date$/) {
	&inittag;
    } elsif ($elem =~ /^section$/) {
	&inittag;
    } elsif ($elem =~ /^sectitle$/) {
	&inittag;
    } elsif ($elem =~ /^slide$/) {
	if ($pageno == 1) {
	    # print slide 0...
	    print "%%Page: 0\n";
	    print "($savetitle) showtitle\n";
	    print "($savetitle) showsection\n";
	    print qq{(     $saveauthor) showitem\n} if ($saveauthor);
	    print qq{(     $savedate) showitem\n} if ($savedate);
	    print "finishpage\n";
	}

	&inittag;
	print "%%Page: $pageno\n";
	print "($savetitle) showtitle\n";
	print "($pageno) showpageno\n"; $pageno++;
    } elsif ($elem =~ /^header$/) {
	&inittag;
    } elsif ($elem =~ /^bullet$/) {
	&inittag;
    } elsif ($elem =~ /^subbullet$/) {
	&inittag;
    } elsif ($elem =~ /^url$/) {
	&inittag;
    } elsif ($elem =~ /^raw$/) {
	&inittag;
    } elsif ($elem =~ /^eps$/) {
	&inittag;
    }
}

sub handle_end {
    my ($expat, $elem) = @_;
    if ($elem =~ /^slideshow$/) {
    } elsif ($elem =~ /^title$/) {
	$savetitle = $lastcdata;
    } elsif ($elem =~ /^author$/) {
	$saveauthor = $lastcdata;
    } elsif ($elem =~ /^date$/) {
	$savedate = $lastcdata;
    } elsif ($elem =~ /^section$/) {
	print qq{($lastcdata) showline\n};
    } elsif ($elem =~ /^sectitle$/) {
	print qq{($lastcdata) showsectitle\n};
    } elsif ($elem =~ /^slide$/) {
	print "finishpage\n";
    } elsif ($elem =~ /^header$/) {
	print qq{($lastcdata) showsection\n};
    } elsif ($elem =~ /^bullet$/) {
	print qq{(·$lastcdata) showitem\n};
    } elsif ($elem =~ /^subbullet$/) {
	print qq{(  $lastcdata) showitem\n};
    } elsif ($elem =~ /^url$/) {
	print qq{($lastcdata) showurl\n};
    } elsif ($elem =~ /^raw$/) {
	$lastcdata =~ s/([(\\)])/\\\1/g; 
	print qq{($lastcdata) showraw\n};
    } elsif ($elem =~ /^eps$/) {
	&handle_eps;
    }
}

sub handle_cdata {
    my ($expat, $string) = @_;
    $lastcdata .= $string;
}

$parser = new XML::Parser(Handlers => {
    Init => \&print_prolog,
    Final => \&print_epilog,
    Start => \&handle_start,
    End => \&handle_end,
    Char => \&handle_cdata
    });

$parser->parsefile($ARGV[0]);
