Gnat suggested PDF. Well I decided to oblige. This turns it into an 80-odd page PDF. Shame it's not sorted in any reasonable order though
#!/usr/bin/perl -w
use strict;
use XML::SAX;
my $writer = XML::SAX::ParserFactory->parser(
Handler => OSCon2PDF->new(Output => "oscon.pdf")
);
warn("Writer is: $writer\n");
$writer->parse_uri("schedule.xml");
package OSCon2PDF;
use PDFLib;
use XML::SAX::Writer;
use strict;
my %alltags;
sub new {
my $class = shift;
my $opt = (@_ == 1) ? { %{shift()} } : {@_};
$opt->{Output} ||= *{STDOUT}{IO};
$opt->{gathered_text} = '';
return bless $opt, $class;
}
sub start_document {
my ($self, $doc) = @_;
warn("start_document\n");
# setup consumer
my $ref = ref $self->{Output};
if ($ref eq 'SCALAR') {
$self->{Consumer} = XML::SAX::Writer::StringConsumer->new($self->{Output});
}
elsif ($ref eq 'ARRAY') {
$self->{Consumer} = XML::SAX::Writer::ArrayConsumer->new($self->{Output});
}
elsif ($ref eq 'GLOB' or UNIVERSAL::isa($self->{Output}, 'IO::Handle')) {
$self->{Consumer} = XML::SAX::Writer::HandleConsumer->new($self->{Output});
}
elsif (not $ref) {
$self->{Consumer} = XML::SAX::Writer::FileConsumer->new($self->{Output})
;
}
elsif (UNIVERSAL::can($self->{Output}, 'output')) {
$self->{Consumer} = $self->{Output};
}
else {
XML::SAX::Writer::Exception->throw({ Message => 'Unknown option for Output' });
}
$self->{Encoder} = XML::SAX::Writer::NullConverter->new;
# create PDF and set defaults
$self->{pdf} = PDFLib->new();
$self->{pdf}->papersize("a4");
$self->{pdf}->set_border_style("solid", 0);
$self->{bookmarks} = [];
$self->{font} = 'Helvetica';
$self->{titlesize} = 24;
$self->{textsize} = 12;
}
sub end_document {
my ($self) = @_;
warn("end_document\n");
$self->{pdf}->finish;
$self->{Consumer}->output( $self->{pdf}->get_buffer );
$self->{Consumer}->finalize;
}
sub push_bookmark {
my $self = shift;
# warn("push_bookmark($_[0]) from ", caller, "\n");
push @{$self->{bookmarks}}, shift;
}
sub top_bookmark {
my $self = shift;
return $self->{bookmarks}[-1];
}
sub pop_bookmark {
my $self = shift;
# warn("pop_bookmark() from ", caller, "\n");
pop @{$self->{bookmarks}};
}
sub start_element {
my ($self, $el) = @_;
my $name = $el->{LocalName};
delete $self->{current_tag};
if ($name eq 'schedule') {
$self->{pdf}->start_page;
$self->{pdf}->set_font(face => $self->{font}, size => $self->{titlesize});
$self->push_bookmark($self->{pdf}->add_bookmark(text => "OSCon Sessions"));
my $bb = $self->{pdf}->new_bounding_box(
x => 5, y => 800, w => 602, h => 50,
align => "centre",
);
$bb->print("OSCon Sessions");
$bb = undef;
$self->{pdf}->set_text_pos(560, 10);
$self->{pdf}->set_font(face => $self->{font}, size => 8);
$self->{pdf}->print("Page ". ++($self->{pageno}));
$self->{pdf}->set_text_pos(50, 770);
}
elsif ($name eq 'session') {
$self->{session} = {};
}
else {
$alltags{$name}++;
$self->{current_tag} = $name;
}
}
sub new_page {
my ($self) = @_;
$self->{pdf}->start_page;
$self->{pdf}->set_font(face => $self->{font}, size => $self->{titlesize});
my $bb = $self->{pdf}->new_bounding_box(
x => 5, y => 800, w => 602, h => 50,
align => "centre",
);
$bb->print("OSCon Sessions");
$bb = undef;
$self->{pdf}->set_text_pos(560, 10);
$self->{pdf}->set_font(face => $self->{font}, size => 8);
$self->{pdf}->print("Page ". ++($self->{pageno}));
$self->{pdf}->set_text_pos(50, 770);
}
sub characters {
my ($self, $el) = @_;
no warnings 'uninitialized';
if ($self->{current_tag}) {
$self->{session}->{$self->{current_tag}}.= $el->{Data};
}
}
sub end_element {
my ($self, $el) = @_;
my $name = $el->{LocalName};
my $pdf = $self->{pdf};
if ($name eq 'session') {
# process session here
use Data::Dumper;
foreach my $k (keys %{$self->{session}}) {
$self->{session}{$k} =~ s/^\s*//;
$self->{session}{$k} =~ s/\s*$//;
}
my ($x, $y) = $pdf->get_text_pos();
$pdf->set_text_pos(50, $y);
my ($lines_left) = $y / 14; # guess?
my $desc_lines = ($self->{session}{description} =~ tr/\n//);
if ($desc_lines > ($lines_left - 6)) {
$self->new_page if $self->{pagedown}++;
}
$pdf->set_font(face => $self->{font}, size => $self->{textsize});
$pdf->print_line("$self->{session}{date} : $self->{session}{start_time_text} to $self->{session}{end_time_text}");
$pdf->print_line("$self->{session}{title} by $self->{session}{p_firstname} $self->{session}{p_lastname}");
$pdf->print_line("Description: ");
($x, $y) = $pdf->get_text_pos();
my $bb = $self->{pdf}->new_bounding_box(
x => ($x + 20), y => $y, w => (552 - $x), h => ($y - 20),
align => "left",
);
for (split(/\n/, $self->{session}{description})) {
$bb->print($_);
$bb->print_line("");
}
}
}
why not use (Score:2)
The Acrobat Webcapture? :) I know, it's not perl, but it works beautifully and I use it for archival docs and such.
Re:why not use (Score:2)
Seriously though - I was just mucking about - I'm not actually going to use this. Its just sometimes useful to write this stuff to reveal bugs in your libraries (PDFLib in this case).