Printing duplex, again

This posting is mostly here to remind myself about printing duplex on a Mac. Without some tool to help it is almost impossible for me to remember how to allways be successful manually printing duplex on a simplex printer. Not finding a good tool, I wrote the following script. Place this script in your "$HOME/Library/PDF Services" directory as, for example, "Process for Duplex" and now your "PDF" menu in the Print dialog box will have a "Process for Duplex" option. When you select this option it runs this script.

What this script does is to separate out each page of the original PDF into its own file. It then joins all the odd pages together in ascending order (eg, 1, 3, 5, 7) into an "odd pages" PDF. It then joins all the even pages together in descending order (eg, 6, 4, 2) into an "even pages" PDF. Further, if there are an odd number of pages then the first even numbered page is a blank page (eg, blank, 6, 4, 2). This blank page is needed to force the last odd pages to be printed with a blank "back". The script then opens the odd and even pages documents in Preview for review and normal printing.

To print the document first print the odd pages. Take the printed pages as a group and place them so that the blank side is up and the top edge is placed at the head of the printer tray. (I have a Dell B1163w laser printer and it prints on the face up page in the tray in starting at the head. Your printer is likely to be different.

#!/bin/bash

function split() {
   file="$1"
   dir="$2"
   odd="$3"
   even="$4"
   pages=$(/usr/local/bin/pdfinfo "$file" | perl -ne 'print "$1" if /^Pages:\s+(\d+)/')

   /usr/local/bin/pdfseparate "$file" "$dir/p-%d.pdf"

   # prepare the list of odd pages in assending
   for o in $(seq 1 2 $pages)
   do
      f="$dir/p-$o.pdf"
      O="$O $f"
   done
   # join the odd pages into one file
   /usr/local/bin/pdfunite $O "$odd"

   if [ $((pages % 2)) == 1 ]
   then  
      # add a blank page to for the "back" of the last page
      f="$dir/p-blank.pdf"
      base64 --decode --output "$f" <<EOH
JVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAgUiAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAErVAgEAAHnAOMKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjExCmVuZG9iagoyIDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMyAwIFIgL1Jlc291cmNlcyA2IDAgUiAvQ29udGVudHMgNCAwIFIgL01lZGlhQm94IFswIDAgNjEyIDc5Ml0KPj4KZW5kb2JqCjYgMCBvYmoKPDwgL1Byb2NTZXQgWyAvUERGIF0gPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9NZWRpYUJveCBbMCAwIDYxMiA3OTJdIC9Db3VudCAxIC9LaWRzIFsgMiAwIFIgXSA+PgplbmRvYmoKNyAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMyAwIFIgPj4KZW5kb2JqCjggMCBvYmoKKE1hYyBPUyBYIDEwLjkuNSBRdWFydHogUERGQ29udGV4dCkKZW5kb2JqCjkgMCBvYmoKKEQ6MjAxNTA5MDgxNjUwMjFaMDAnMDAnKQplbmRvYmoKMSAwIG9iago8PCAvUHJvZHVjZXIgOCAwIFIgL0NyZWF0aW9uRGF0ZSA5IDAgUiAvTW9kRGF0ZSA5IDAgUiA+PgplbmRvYmoKeHJlZgowIDEwCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDQ5MiAwMDAwMCBuIAowMDAwMDAwMTI1IDAwMDAwIG4gCjAwMDAwMDAyNjggMDAwMDAgbiAKMDAwMDAwMDAyMiAwMDAwMCBuIAowMDAwMDAwMTA3IDAwMDAwIG4gCjAwMDAwMDAyMjkgMDAwMDAgbiAKMDAwMDAwMDM1MSAwMDAwMCBuIAowMDAwMDAwNDAwIDAwMDAwIG4gCjAwMDAwMDA0NTEgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSAxMCAvUm9vdCA3IDAgUiAvSW5mbyAxIDAgUiAvSUQgWyA8ZGFlMDQ3ZjU2ZmRhMjA1ZmViYzNkYmE4NmViNjZlYjg+CjxkYWUwNDdmNTZmZGEyMDVmZWJjM2RiYTg2ZWI2NmViOD4gXSA+PgpzdGFydHhyZWYKNTY0CiUlRU9GCg==
EOH
      E=$f
      pages=$((pages -1))
   fi
   # prepare the list of even pages in descending/reverse order
   for e in $(seq $pages -2 2)
   do
      f="$dir/p-$e.pdf"
      E="$E $f"
   done
   # join the even pages into one file
   /usr/local/bin/pdfunite $E "$even"

   # remove the intermediary files
   rm -f $O $E
}

# remove title and printer settings
shift 2

for f in "$@"
do
   dir=$(mktemp -d "/tmp/duplex-XXXX")
   split "$f" "$dir" "$dir/odd.pdf" "$dir/even.pdf"
   open "$dir/even.pdf"
   open "$dir/odd.pdf"
done

# END

Update: Matt points out that monochrome, duplex laser printers are under $100 and so you really don't have to manually handle the paper. He is right. I just happen to have an almost new printer and so can't justify replacing it yet.