Jens Nöckel's Homepage

Computer notes home

n-up PDF conversion

While making handouts for my lecture, I found myself needing to convert a PDF file to an n-up layout, specifically an arrangement of 2×2 original pages per output page. On Mac OS X Leopard, I couldn't find a good tool that does this job with the flexibility of "PDF Nup Maker" (which doesn't seem to be maintained anymore). There is in fact a nice shell script pdfnup that can be installed via fink, but I also made my own script to do the job, based on the LaTeX package pdfpages. The only thing my version does that the other one doesn't, is to let you choose an alternate background color for the output.

The script shown below takes any PDF file and creates a new file with three new properties:

Usage example

pdfnup -n 2x2 -d -30x-30 file.pdf
The output will have a 2×2 page layout. Here the rows and columns are moved closer together by making the offset -30x-30 negative in the x and y directions.

Source code

#!/bin/tcsh
#
#   Save this file under any name (e.g., pdfnup) and make it executable in your PATH.
#   Usage instructions are displayed when invoking the command without arguments.
#
#   Created Oct 11, 2007 by J.U.Noeckel (originally called pdfbgcolor, only used to change background color)
#   Modified March 30, 2009 by J.U.Noeckel (added n-up functionality because no such tool seemed to exist for Leopard)

alias printHelp 'printf "Usage: "`basename $0`" [-c HTML-color] [-n ROWSxCOLUMNS] [-d DELTA_XxDELTA_Y] filename\n\n";\\
    printf  "HTML-color:\n"; \\
    printf  "hexadecimal RGB number in capitals, RRGGBB\n"; \\
    printf  "The background of the file filename is changed to color HTML-color\n"; \\
    printf  "Default color: white\n\n";\\
    printf  "ROWSxCOLUMNS:\n"; \\
    printf  "two integers separated by x sepcifying the number of rows and columns to\nprint per physical page (e.g., 2x2)\n\n"; \\
    printf  "DELTA_XxDELTA_Y:\n"; \\
    printf  "two floats separated by x sepcifying the offset in points between rows and\ncolumns (may be negative)\n\n"; \\
    printf  "Output PDF is written to filename-converted.pdf\n"'

alias cleanup 'rm -Rf $TMPNAME*'

if ("$#" == 0) then
   echo "**** Input file name required"
   printHelp
   exit 1
endif

set WD0 = $PWD
set TMPNAME = `mktemp -dt`
# Default background color is white:
set COLOR = "FFFFFF"
set NUP = ","
set DELTA = ""
set ARGS = `getopt hd:n:c: $*`

# Arguments preceding the special "--" are command-line options:
while ("$ARGS[1]" != "--") 

  switch ("$ARGS[1]")
#    Check if a color option is given:
     case "-c": 
             set COLOR = $ARGS[2]
             shift ARGS
             breaksw
#    Check if an n-up option is given:
     case "-n": 
             set NUP = ",nup="$ARGS[2]
             shift ARGS
             breaksw
#    Check if an offset option is given:
     case "-d": 
             set DELTA = ",delta="$ARGS[2]:s/x/ /
             shift ARGS
             breaksw
     default:
             printHelp
             exit 0
             breaksw
  endsw

  shift ARGS
end
shift ARGS
if (-f "$ARGS[1]") then
    cd `dirname "$ARGS[1]"`
else
    echo  "**** Invalid filename ""$ARGS[1]"
    printHelp
    cleanup
    exit 1
endif

# Get the full path of the input file:
set INFILE = `pwd`/`basename "$ARGS[1]"`
set OUTFILE = {$INFILE:r}-converted.pdf 
if (-f $OUTFILE) then
    echo -n $OUTFILE" exists. Overwrite ? [yes/no]"
    set overwrite = "$<"
    if ( $overwrite != "yes" ) then
      echo "NOT OVERWRITING"
      rm -Rf $TMPNAME*
      exit 1
    endif
endif
cp "$INFILE" "$TMPNAME"/input.pdf
echo '\documentclass{minimal}\usepackage{xcolor}\pagecolor[HTML]{'$COLOR'}\usepackage{pdfpages}\begin{document}\includepdf[pages=-'$NUP$DELTA',frame=false]{input.pdf}\end{document}' > $TMPNAME/converted.tex
cd $TMPNAME
pdflatex -interaction nonstopmode converted.tex
if ( -f converted.pdf) then
    mv converted.pdf {$INFILE:r}-converted.pdf 
    echo "Output written to "{$INFILE:r}-converted.pdf 
else
    echo "**** Couldn't convert: ""$ARGS[1]"
endif
# Return to original working directory:
cd $WD0
cleanup


noeckel@uoregon.edu
Last modified: Fri Apr 10 22:32:19 PDT 2009