UAZU-Up-

Script for printing postscript documents onto A5 paper

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.



UAZU-Up- These pages and files, including applets and artwork, are Copyright (c) 1997-2016 Jim Peters unless otherwise stated. Please contact me if you'd like to use anything not explicitly released, or if you have something interesting to discuss.