Back in 2005, my mother wanted to print a 8.5”x11” booklet by printing it on tabloid paper, stapling down the middle, and folding. While this is an extremely easy process from a publishing perspective, actually printing the 11”x22” pages properly is not. Having just learned shell scripting, I decided to tackle the problem in the UNIX fashion by using a couple of already-made utilities (pdftk and pdfjam) and a shell script.
A few years later, the need for this script came up again and I vastly simplified the process by rewriting the script in perl and using the pdfpages
package in $\LaTeX$ directly. The perl script can be found here:
#! /usr/bin/perl
# Copyright (c) 2010 Faith Ekstrand
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to the
# following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
# NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
# USE OR OTHER DEALINGS IN THE SOFTWARE.
use strict;
my $help_string = <<END;
Usage:
paginate.pl [options] input.pdf
Options:
-v verbose mode
-k keep the first page and the last page as the first and last
pages. (Good if the first and last pages are the front and back
cover.)
-h prints this help screen
-o file specifies the output file (default: out.pdf)
END
my $ver = 0;
my $keep = 0;
my $ifile;
my $ofile;
if (not @ARGV) {
print $help_string;
exit;
}
while (my $arg = shift) {
if ($arg eq '-v') {
$ver = 1;
} elsif ($arg eq '-k') {
$keep = 1;
} elsif ($arg eq '-o') {
$ofile = shift;
} elsif ($arg eq '-h') {
print $help_string;
exit;
} else {
$ifile = $arg;
}
}
if (not $ofile) {
$ofile = 'out.pdf';
}
`cp $ifile /tmp/paginate-$$-initial.pdf`;
my $pages = `pdfinfo $ifile |grep Pages`;
$pages =~ /Pages:\s*([0-9]*)/ || die "pdfinfo failed\n";
$pages = $1;
my $blanks = $pages % 4;
if ($blanks) {
$blanks = 4 - $blanks;
}
my $sheets = ($pages + $blanks) / 4;
if ($ver) {
print "The new document will contain:\n";
print "$pages Pages\n";
print "$blanks Blank Pages\n";
print "$sheets Sheets\n";
}
my @pages_list = 1..($pages - 1);
if ($keep) {
for my $i (1..$blanks) {
push @pages_list, '{}';
}
push @pages_list, $pages;
} else {
push @pages_list, $pages;
for my $i (1..$blanks) {
push @pages_list, '{}';
}
}
$pages += $blanks;
$ver and print "Initial Page List:\n@pages_list\n";
($#pages_list + 1) == ($sheets * 4) or die "Page count wrong\n";
my @final_pages;
for my $i (0..($sheets - 1)) {
push @final_pages, (
$pages_list[$pages - ($i * 2) - 1],
$pages_list[$i * 2],
$pages_list[($i * 2) + 1],
$pages_list[$pages - ($i * 2) - 2]);
}
$ver and print "Final Page List:\n@final_pages\n";
$ver and print "Creating Tex File...\n";
$" = ',';
my $texfile = "/tmp/paginate-$$.tex";
open TEXFILE, '>', $texfile or die "Could not open tex file\n";
print TEXFILE <<END;
\\documentclass{article}
\\usepackage[papersize={17in,11in}]{geometry}
\\usepackage{pdfpages}
\\begin{document}
\\includepdf[
pages={@final_pages},
nup=2x1,
frame=false,
fitpaper=false,
trim=0 0 0 0,
delta=0 0,
offset=0 0,
scale=1.00,
turn=true,
noautoscale=false,
column=false,
columnstrict=false,
openright=false
]{/tmp/paginate-$$-initial.pdf}
\\end{document}
END
$" = ' ';
$ver and print "Running pdflatex...\n";
`pdflatex -output-directory /tmp $texfile`;
`cp /tmp/paginate-$$.pdf $ofile`;
`rm /tmp/paginate-$$*`;