This is my "book-a5" script. I don't guarantee that it is 100% bug-free, but I have refined it as I've encountered problems, and it works well for me. If you are nervous, you can check the temporary PostScript files before they are printed out using gv or GhostView or whatever.
The script takes an input PS file, and handles the whole process of printing, including splitting into batches and feeding the pages back into the printer for printing on the other side. Run it as "book-a5 document.ps" for A4-sized input, or "book-a5 -l document.ps" for Letter-sized. You should also adjust the gs commands to suit your particular printer's protocol and resolution. The script may also need adjusting to your particular printer's mechanism (i.e. does the printer take pages from the front or back of the feeder, and in which order are they stacked at the other end) -- look for the psselect commands to fix problems connected with this.
Note that you will need to have installed GhostScript and the psutils package for this to work:
#!/bin/bash # # Converts A4 or letter-sized pages into landscape A5 pages, and # splits them into approx 40-sheet chunks of odd and even pages # for printing. Prompts user throughout process of printing. # # Copyright (c) 2000-2003 Jim Peters <http://uazu.net/> # This is FREE SOFTWARE, released under the GNU GPL version 2 # FROM=A4 MAP='0L@0.707107(21cm,0)' [ "$1" == "-l" ] && { shift FROM=Letter MAP='0L@0.687456(20.1cm,0)' } BLOCK_SIZE=40 [ "$1" == "-b" ] && { shift BLOCK_SIZE="$1" shift } xx="$1" TEMP="tmp-book-a5" shift sheets="$*" [ -z "$xx" ] && [ -f out.ps ] && { xx=out.ps; echo "Using 'out.ps'"; } if [ -z "$xx" ] || [ ! -f "$xx" ] then echo "Usage: book-a5 [-l] [-b ##] [input-file] [sheet-numbers]" echo " \`-l' converts from Letter-sized paper instead of from A4" echo " \`-b ##' uses ## pages a block instead of the default of 40" exit 1 fi echo "Renumbering pages and converting $FROM to A5 ..." perl <$xx -e ' $page= 1; $lev= 0; while (<>) { if (/^%%Pages:/) { next; } if (/^%%Page:/) { next if ($lev > 0); $_= "%%Page: $page $page\n"; $page++; } if (/^%%Trailer/ && $lev == 0 && ($page & 1) == 0) { $_= "%%Page: $page $page\nshowpage\n$_"; $page++; } if (/^%%EOF/) { next; } if (/^%%BeginDocument/ || /^%%BeginData/) { $lev++; } if (/^%%EndDocument/ || /^%%EndData/) { $lev--; $lev= 0 if ($lev < 0); } print; } if (($page & 1) == 0) { print "%%Page: $page $page\n"; print "showpage\n"; $page++; } $shcnt= ($page-1)/2; print STDERR "OK $shcnt"; ' >$TEMP-1.ps 2>$TEMP-perl-out pstops "$MAP" <$TEMP-1.ps | sed 's/^%%DocumentMedia.*$/%%DocumentMedia: A5-LS 595 421 75 white ()/' >$TEMP.ps rm $TEMP-1.ps set `cat $TEMP-perl-out` XX [ "$1" != "OK" ] && exit 1 shcnt="$2" echo "" echo "Found $((shcnt*2)) pages => $shcnt sheets" # # Printing specific sheets (for recovery) # if [ ! -z "$sheets" ] then list= for xx in $sheets do let x1=(xx*2-1) let x2=(x1+1) list="$list,$x1,$x2" done list=${list#,} echo "" echo "Printing odd pages of sheets: $sheets" psselect -o -r -p$list <$TEMP.ps >$TEMP-out.ps || exit 1 while : do echo -n "Enter 'O' when ready: " read xx case "$xx" in [oO]) break;; *) ;; esac done echo "Outputting to HL-760, A5 landscape pages, 600dpi ..." gs -q -g4958x3508 -sDEVICE=ljet4 -r600 -dNOPAUSE -sOutputFile=/dev/lp -- $TEMP-out.ps || exit 1 echo "" echo "*** REINSERT PAGES, TURNING THE OTHER WAY UP, LIKE A BOOK ***" echo "" echo "Printing even pages of sheets: $sheets" psselect -e -r -p$list <$TEMP.ps >$TEMP-out.ps || exit 1 while : do echo -n "Enter 'E' when ready: " read xx case "$xx" in [eE]) break;; *) ;; esac done echo "Outputting to HL-760, A5 landscape pages, 600dpi ..." gs -q -g4958x3508 -sDEVICE=ljet4 -r600 -dNOPAUSE -sOutputFile=/dev/lp -- $TEMP-out.ps || exit 1 rm -f $TEMP.ps $TEMP-out.ps $TEMP-perl-out echo "" echo "FINISHED" exit 0 fi # # Printing in blocks # size=$BLOCK_SIZE let 'blks=(shcnt+(size/2))/size' let 'blks=(blks>0)?blks:1' let 'blksh=((shcnt-1)/blks)+1' echo "Printing in $blks blocks of approx $blksh sheets each" let bno=0 let shno=1 while : do let sh1=shno let sh2=shno+blksh-1 let 'sh2=(sh2>shcnt)?shcnt:sh2' let shno=sh2+1 let bno=bno+1 echo "" echo "Printing block $bno, odd pages, $((sh2-sh1+1)) sheets ($sh1 to $sh2)" psselect -o -r -p$((sh1*2-1))-$((sh2*2)) <$TEMP.ps >$TEMP-out.ps || exit 1 while : do echo -n "Enter 'O' when ready: " read xx case "$xx" in [oO]) break;; *) ;; esac done echo "Outputting to HL-760, A5 landscape pages, 600dpi ..." gs -q -g4958x3508 -sDEVICE=ljet4 -r600 -dNOPAUSE -sOutputFile=/dev/lp -- $TEMP-out.ps || exit 1 echo "" echo "*** REINSERT PAGES, TURNING THE OTHER WAY UP, LIKE A BOOK ***" echo "" echo "Printing block $bno, even pages, $((sh2-sh1+1)) sheets ($sh1 to $sh2)" psselect -e -r -p$((sh1*2-1))-$((sh2*2)) <$TEMP.ps >$TEMP-out.ps || exit 1 while : do echo -n "Enter 'E' when ready: " read xx case "$xx" in [eE]) break;; *) ;; esac done echo "Outputting to HL-760, A5 landscape pages, 600dpi ..." gs -q -g4958x3508 -sDEVICE=ljet4 -r600 -dNOPAUSE -sOutputFile=/dev/lp -- $TEMP-out.ps || exit 1 if [ $shno -gt $shcnt ] then break fi done rm -f $TEMP.ps $TEMP-out.ps $TEMP-perl-out echo "" echo "FINISHED" echo "" echo "Note: to reprint specific sheets, run again as: book-a5 xx.ps sheet-numbers..." ## END ##
Also, Colin Marquardt has provided a patched version of this script, which might be easier to adapt to your printer, but which I haven't had a chance to test fully yet.