The basic problem here is that pdfjam
exhibits non-standard behaviour and is rather poorly documented. Since pdfbook
is basically a minimal wrapper for pdfjam
, it inherits these deficiencies while further obscuring the source of problems.
In this case, you can workaround the problem using
pdfbook --paper letter --outfile out.pdf -- in.pdf
Note that the --
before the input pdf is essential. This is not at all normal behaviour for a shell script. pdfjam
is parsing options extremely weirdly. I wouldn't like to say it is dangerous but I wouldn't trust that it is not. However, as long as you don't pass it anything dangerous, it should (hopefully) be reasonably safe.
Figuring this out takes a little detective work. The manual pages for pdfbook
and pdfjam
are not terribly informative. Essentially, I started by reading the script pdfbook
which shows how it invokes pdfjam
. This is relatively straightforward. I then switched to testing pdfjam
directly to try to narrow down the problem.
pdfjam --help
is the most useful source of documentation I found. Part of this includes the following:
Usage: pdfjam [OPTIONS] [--] [FILE1 [SEL1]] [FILE2 [SEL2]]...
and
--paper PAPERSPEC (or simply --PAPERSPEC)
Specify a LaTeX paper size, for example
'--paper a4paper' or simply '--a4paper' for ISO A4 paper.
If the LaTeX 'geometry' package is installed, a wider range
of paper sizes is available. For details see documentation
for LaTeX and/or the 'geometry' package.
[Default for you at this site: paper=a4paper]
--papersize '{WIDTH,HEIGHT}'
Specify a custom paper size, e.g.,
--papersize '{10in,18cm}'
(Note the braces, and the comma!)
If the 'geometry' package is not found, this has no effect.
and
* '--' can be used to signal that there are no more options to come.
What this does not tell you is that the script is parsing options non-standardly and that -- is essential if certain options are passed. Normally, you only need --
if one of the main arguments passed to a shell script might otherwise be mistaken for an option (e.g. a filename begins with -
) or if you wish to prevent misuse (e.g. when a shell is invoked). In the case of pdfjam
, though, if you write
pdfjam --paper letter --outfile out.pdf in.pdf
you will get errors. Debugging with --no-try
shows that the script is passing something like paper letter--outfile
as an optional argument when invoking the PDF merge command offered by pdfpages
. It then tries to merge out.pdf
and in.pdf
. None of which works, obviously.
Turning to pdfjam
itself, you can see how it parses options:
for arg
do
case $arg in
--quiet | -q | --configpath)
verbose=false ;
;;
--version | -V)
echo "$version"
exit 0 ;
;;
--batch)
batch=true ;
;;
--help | -u | -h)
help=true ;
;;
--vanilla)
vanilla=true ;
;;
*)
;;
esac
done
It then parses any remaining options separately later in the file. I'm not entirely sure why it does this but the upshot is that it is essentially unable to tell the difference between an option and an argument. If you don't tell it explicitly that the options are finished, it fails to parse any remaining options correctly. This is actually pretty bad as it is letting arbitrary stuff get passed onto pdfpages
even when it makes no sense. Although I don't know if this could be exploited, it is the kind of thing which can make scripts vulnerable to exploitation.
Moreover, including
* '--' can be used to signal that there are no more options to come.
does not constitute proper documentation of this behaviour because this is a standard behaviour for shell scripts. What is not standard is that this is required even if your first argument proper has a non-weird name i.e. even if in.pdf
has a filename which does not start with -
.
This is buggy behaviour in my view. Shell scripts ought not behave this way. Moreover, it uses /var/tmp
for temporary files. This is also non-standard and problematic. It ought to use /tmp
so that the temporary files it creates are removed on reboot, for example. Although these remain around only if --no-tidy
is passed, the behaviour is still unexpected and, I think, undesirable for a script of this kind.
So I would be careful in using pdfjam
and wrappers such as pdfbook
. For example, I would avoid piping the output of other processes to pdfjam
and only invoke the script or its wrappers manually.
Best Answer
I wrote the
pgfmorepages
(CTAN and github) extension ofpgfpages
for instances such as this.The layout you want isn't predefined, but is straightforward to make.
First page:
Second page: