Skip to content

Instantly share code, notes, and snippets.

@vshymanskyy
Created November 21, 2012 18:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vshymanskyy/4126856 to your computer and use it in GitHub Desktop.
Save vshymanskyy/4126856 to your computer and use it in GitHub Desktop.
pdfsplit is a Perl script that cuts each page in pdf file into half.
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
use Pod::Usage;
use PDF::API2;
sub parseBox {
my ($box) = @_;
if ($box =~ /^\s*([\-\.\d]+)\s+([\-\.\d]+)\s+([\-\.\d]+)\s+([\-\.\d]+)\s*$/) {
return ($1, $2, $3, $4);
} else {
if ($box =~ /^\s*([\-\.\d]+)\s+([\-\.\d]+)\s*$/) {
return ($1, $2, $1, $2);
} else {
if ($box =~ /^\s*([\-\.\d]+)\s*$/) {
return ($1, $1, $1, $1);
} else {
die "Crop option parse error!";
}
}
}
return (0,0,0,0);
}
# Default option values
($::opt_man, $::opt_help, $::opt_overwrite, $::opt_vertical) = (0, 0, 0, 0);
($::opt_start, $::opt_pages) = (1, 0);
($::opt_rotate, $::opt_crop) = (-1, '0 0 0 0');
# Get command-line option values
GetOptions(
"man", "help|?", "overwrite", "vertical",
"start=i", "pages|n=i",
"rotate=i", "crop=s",
) or pod2usage({ -verbose => 1, -exitval => 1 });
# Help and manuals
pod2usage({ -verbose => 1, -exitval => 0 }) if $::opt_help;
pod2usage({ -verbose => 99, -exitval => 0 }) if $::opt_man;
my ($ct,$cl,$cr,$cb) = parseBox($::opt_crop);
# Check option values
@ARGV == 2 or pod2usage("Input and output files should be specified");
die "Invalid starting page" if $::opt_start < 1;
die "Will not overwrite existing $ARGV[1]" if -e $ARGV[1] and not $::opt_overwrite;
# Start processing
print "Opening $ARGV[0]\n";
my $pdf = PDF::API2->open($ARGV[0]) or die;
my $pdfout = PDF::API2->new();
die "Invalid page range" if ($::opt_start+$::opt_pages-1) > $pdf->pages();
my $pagesQty = ($::opt_pages==0)?($pdf->pages()-$::opt_start+1):$::opt_pages;
$|++; # autoflush
for (my $i = 0; $i < $pagesQty; $i++) {
# First half
$pdfout->importpage($pdf, $::opt_start+$i);
my $page = $pdfout->openpage();
my @box = $page->get_cropbox;
$box[0] += $cl; # llx
$box[1] += $cb; # lly
$box[2] -= $cr; # urx
$box[3] -= $ct; # ury
if ($::opt_vertical) {
$page->cropbox($box[0], $box[1], ($box[2]+$box[0])/2, $box[3]);
} else {
$page->cropbox($box[0], ($box[1]+$box[3])/2, $box[2], $box[3]);
}
$page->rotate($::opt_rotate) if $::opt_rotate;
# Second half (reuses same original cropbox)
$pdfout->importpage($pdf, $::opt_start+$i);
$page = $pdfout->openpage();
if ($::opt_vertical) {
$page->cropbox(($box[0]+$box[2])/2, $box[1], $box[2], $box[3]);
} else {
$page->cropbox($box[0], $box[1], $box[2], ($box[3]+$box[1])/2);
}
$page->rotate($::opt_rotate) if $::opt_rotate;
# Print progress
printf("Splitting: %2.1f%%\r", 100*($i+1)/$pagesQty);
}
$|--; # no autoflush
die "Will not overwrite existing $ARGV[1]" if -e $ARGV[1] and not $::opt_overwrite;
print "\nSaving $ARGV[1]\n";
$pdfout->saveas($ARGV[1]);
$pdfout->end();
$pdf->end();
__END__
=head1 NAME
pdfsplit - Split pages of the PDF file in the middle and rotate
=head1 SYNOPSIS
pdfsplit --help
pdfsplit --man
pdfsplit [--overwrite] [--start=N] [--pages=N] [--vertical] [--rotate=DEG] [--crop='T L R B'] in.pdf out.pdf
or
pdfsplit [-o] [-s N] [-n N] [-v] [-r DEG] [-c 'T L R B'] in.pdf out.pdf
=head1 OPTIONS
=over 12
=item B<-help>
Print a brief help message and exits.
=item B<-man>
Prints the manual page and exits.
=item B<-overwrite>
Overwrite output file
=item B<-start>
Starting page in the input file.
=item B<-pages>
Number of pages to process.
=item B<-vertical>
Perform vertical split
=item B<-rotate>
Page rotation: 0, 90, -90, 180, 270 (only multiple of 90)
=item B<-crop>
Crop borders: 'top left right bottom'
=back
=head1 DESCRIPTION
B<pdfsplit> will read the given input PDF file, crop the borders,
split each page in the middle, rotate the halves, and save the result in the output file.
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment