Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
create single PDF from many .pod or .pm files
#!/usr/bin/env perl
use Modern::Perl;
BEGIN {
if (@ARGV != 2) {
print STDERR "usage: $0 DIR OUTPUT\n";
exit 1;
}
}
{
# a simple class that uses App::pod2pdf to create pdfs containing many pod files
# The hierarchical outline is generated on the fly while traversing directories
package MultiPDF;
use Moose;
use Path::Class;
use App::pod2pdf;
has parser => (
is => 'ro',
isa => 'App::pod2pdf',
lazy => 1,
default => sub { App::pod2pdf->new },
);
has pdf => (
is => 'ro',
isa => 'PDF::API2',
lazy => 1,
builder => '_build_pdf',
);
sub _build_pdf {
my $self = shift;
$self->parser->{pdf},
}
sub process_file {
my $self = shift;
my $file = shift;
say "processing file: $file";
$self->parser->parse_from_file($file->stringify);
$self->parser->formfeed;
return $self;
}
sub process_dir {
my $self = shift;
my $dir = Path::Class::Dir->new(shift);
my %structure; # { _outline => PDF::API2::Outline }
$dir->recurse(
depthfirst => 1,
callback => sub {
my $file = shift;
return if !-f $file || $file->basename !~ m{[.](?:pm|pod) \z}xms;
my $nr_pages = $self->pdf->pages;
$self->process_file($file);
my $name = $file->basename;
$name =~ s{[.]\w+ \z}{}xms;
my $tree = \%structure;
my $outline = $structure{_outline} ||= $self->pdf->outlines->outline;
foreach my $part (grep { $_ ne '.' } $file->relative($dir)->dir->dir_list, $name) {
$tree = $tree->{$part} ||= { _outline => $outline->outline };
$outline = $tree->{_outline};
$outline->title($part);
}
$outline->dest($self->pdf->openpage($nr_pages));
}
);
return $self;
}
sub print {
my $self = shift;
$self->parser->output;
}
sub save_as {
my $self = shift;
my $path = shift;
$self->pdf->saveas($path);
}
}
MultiPDF->new
->process_dir($ARGV[0])
->save_as($ARGV[1]);
@mlawren

Hi Wolfgang,

I like the idea. I got this running on v5.10.1 by dropping the '2012' argument to Modern::Perl and it generates pages for each file found, but did not generate an outline. I don't know anything about PDF::API2 to know why this is the case.

For usability I also added the following (inside a BEGIN block because I hate waiting for Moose to start up when arguments are missing):

BEGIN {
    unless @ARGV == 2 {
        print STDERR "usage: $0 DIR OUTPUT\n";
        exit 1;
    }
}

And this at the bottom:

MultiPDF->new
    ->process_dir($ARGV[0])
    ->save_as($ARGV[1]);

Regards,
Mark.

@wki
Owner
wki commented

Mark,

you are absolutely right. There is no need to force usage of Perl 5.14. There are more things to improve like handling .pm versus .pod files, omitting files without any documentation and maybe much more cases not handled right now. But for a first try I think it is not that bad.

I will try to operate with different versions of Perl in order to find out why outlines seem to work unreliably. The outline handling in PDF::API2 by itself is available since 2005 if I correctly read the 'Changes' file. So it looks like I did not handle this part right.

Thanks for your feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.