I have lots of pdf documents to merge together, so I wrote this code to do it. It works for the case where I only have two pdf documents to merge, but if I give it more than two, the extra documents come out garbled. Can you help me find what’s wrong?
#!/usr/bin/perl
use PDF::API2;
use List::Util qw( reduce );
# Given two pdfs and a page number, appends the given page of the second pdf to the first pdf
sub append_page_to_pdf {
my ( $pdf1, $pdf2, $pg ) = @_;
$pdf1->importpage( $pdf2, $pg );
}
# Given two pdfs, appends the second to the first. Closes pdf2
sub merge_2_pdfs {
my ($pdf1, $pdf2) = @_;
map &append_page_to_pdf( $pdf1, $pdf2, $_ ), 1..$pdf2->pages;
$pdf2->end;
return $pdf1;
}
# does what it says
sub open_pdf {
my $file = $_[0];
my $pdf = PDF::API2->open( $file );
print "Opened pdf ( $file )\n";
return $pdf;
}
# reduces merge_2_pdfs over an array of pdfs
sub merge_pdfs {
my @files = @_;
my $starting_filename = shift @files;
my $start_pdf = &open_pdf( $starting_filename );
my $final_pdf = reduce { &merge_2_pdfs( $a, &open_pdf( $b ) ) } $start_pdf, @files;
return $final_pdf;
}
# Get the arguments ie save_name, file1, file2, file3, ...
my @files = @ARGV;
my $save_name = shift @files;
my $save = &merge_pdfs( @files );
$save->saveas( $save_name );
The actual problem in your code is because you
shiftone of the files off before you merge them.Otherwise, the code actually works, and I didn’t find anything garbled.
A few tips:
use strictanduse warningsThe general practice now is to omit the
&in your subroutine calls. See here for exceptions to that rule.In this case, the subroutines make your code verbose, which made it harder to follow. Here’s something more concise.
A simple loop is a little more straighforward to read than using
reduce.