diff --git a/bin/make_pdf_from_pod.pl b/bin/make_pdf_from_pod.pl new file mode 100644 index 0000000000000000000000000000000000000000..96391a2c326ce2f7067769e8b3fc4ec7aa81d011 --- /dev/null +++ b/bin/make_pdf_from_pod.pl @@ -0,0 +1,115 @@ +#!/usr/bin/env perl +use Modern::Perl; + +## script to generate a single PDF file with all POD documentation +## Based on https://gist.github.com/wki/2277444 + +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|pl) \z}xms; + + ## Look for POD tags to skip files without documentation + my $fh = $file->open or die "Failed to open ".$file->basename ; + my $has_pod = 0; + while (<$fh>) { + $has_pod = 1 if (/^=head1/); + } + close $fh; + + return unless ($has_pod); + + 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]);