Printing instruction manuals, how to reorder postscript files

Today I had to solve the following quite interesting mostly mathematical problem:

I received an instruction manual with continuous pages (1, 2, …, n), where n is a multiple of 4.

I wanted to print them as DIN A5 on a DIN A4 sheet, two-sided. Usually, this means printing [ (1, 2), (3, 4) ], …, [ (n-3), (n-2), (n-1, n)] each of these pairs (“tuples”) on a side of a sheet. The [ … ] represents a DIN A4 sheet.

In my special case however, I wanted to stack all of the DIN A4 papers, fold them in the middle and staple them to stick together. Just pull out a random technical manual and you’ll see what I mean: The outer DIN A4 sheet contains the front and back cover, and the first and last inner page, the inner-next sheet contains the second and third, and penultimate and pre-penultimate inner page.

When the manual is closed, all the DIN A4 pages will be nested.

Since no office software I knew offered this special feature, I was stuck.

The required steps were:
1) Reorder the pages (1, …, n). The resulting ordered set (called n-tuple, which will contain all numbers between 1 and n) could look like (…, 1, …, n, …).
2) Print the reordered pages on a duplex printer.

That’s how I realized 1)

a) Consider the correct permutation. You’ll soon find out that for the outer side of the outer sheet, you’ll need (n, 1). This is because an open book viewed from the back has its back on the left side and its front on the right side.

For the inner side of the cover, you’ll need (2, n-1), then you’ll need (n-2, 3) and so on until you’re finished, i.e. you’ve reached (n/2, n/2+1).

I wrote a little python permutation algorithm as a proof of concept that also explains the algorithm.

#!/usr/bin/python

# reorder the numbers between 1 and n (argv[1]) according to the
# "alternating cut-zip sorting" algorithm, used for printing
# continuous pages (resized) to pages of twice the original size,
# in an order appropriate for instruction manuals that
# consist of nested sheets.
#
# I just called this algorithm "alternating cut-zip sorting" algorithm,
# feel free to correct me if there is another name for it!
#
# We have n pages, n must be even, and should be divisible by 4 to yield
# proper results. If it is not divisible by 4, you'll need a blank front
# and back page.
#
# Example:
#   Assuming n=8, we previously had DIN A5 pages as an n-tuple
#   (1, 2, 3, 4, 5, 6, 7, 8)
#   Now, we want to print this in duplex mode on DIN A4 paper like
#
#    sheet 1: [(Page 8 | Page 1), (Page 2 | Page 7)]
#    sheet 2: [(Page 6 | Page 3), (Page 4 | Page 5)]
#
#   This algorithm will arrange for the (8, 1, 2, 7, 6, 3, 4, 5)
#   order, and the printer driver just has to print the new document
#   duplex 2-on-1 resized on DIN A4 paper.
#
# Construction of this permutation:
#  We 'cut' the original tuple in the middle,
#  count up in one half and count down in the other half,
#  and in each iteration glue a pair together, swapping order
#  (greater number left, smaller number left) in each iteration.
#
#  The swapping is required because once you turn over pages, you'll
#  jump from the left half of a DIN A4 page to the right half and vice
#  versa.
#
# General pattern for new page order (spaces added for better readability):
#  n, 1,   2, n-1,   n-2, 3,   4, n-3,   , ..., ...,   (n/2), (n/2)+1

import sys

n = int (sys.argv[1])

if n % 2:
  print "expected even number, but " + str(n) + " is not even! Aborting."
  sys.exit(1)

for i in range(1, n/2+1):
  if i != 1:
    sys.stdout.write (' ')

  if i % 2:
    sys.stdout.write (str(n+1-i) + ' ' + str(i))
  else:
    sys.stdout.write (str(i) + ' ' + str(n+1-i))

sys.stdout.write ('\n')
sys.exit (0)

b) Modify an existing python script that extracts pages from a PostScript file and reverses them to use the permutation algorithm.

c) Use the modified script to reorder the pages of a PDF file.

This is done by converting the original PDF file with acroread, using

acroread -toPostScript -size A5 myfile.pdf

We use acroread because it yields way smaller compressed PS files than pdf2ps can ever produce due to usage of patented algorithms.

Now, the PS pages are reordered with the modified script, and converted back:

ps2pdf -sPAPERSIZE=a5 myreorderedfile.ps

Now proceed to step 2) and you have a pretty instruction manual.

Update

The comments on this article yielded some interesting comments: My python script could have been shorter and more elegant, the psutils package offers similar functionality and OpenOffice.org offers brochure printing which seems to be exactly what I’m looking for. Thanks for all your feedback.

nautilus-open-terminal 0.8 is out

Get it from ftp.gnome.org. Spread it by voting for it.

This is the first release that is distributed through the ftp.gnome.org server. Thanks to Davyd for making it happen.

Unfortunately, a pal of mine behind cluecoder.org that was used to host the old packages is still in clinch with the old hoster so I can’t access my old tarballs and some privare data.

nautilus-open-terminal 0.8
==========================
"Alive"

        * Dedicated to Klaus Kreuzeder, an excellent Saxophonist. http://www.trick-music.de/klaus_kreuzeder.htm

        * Depend on Nautilus 2.17.2
        * Use activation URI of selected files for determining URI. This allows to use the extension for your Desktop bookmarks.
        * Also deal with "ssh" URIs and treat them like "sftp" URIs.
        * Use open() and cwd() to change directories. Should fix trouble with blocked media ejection.

        * Added translations
                ar      Khaled Hosny                    
                bn_IN   Runa Bhattacharjee              
                be      Ihar Hrachyshka                 
                da      Peter Bach                      
                dz      sonam pelden
                et      Ivar Smolin                     
                gu      Ankit Patel                     
                ka      Vladimer Sichinava              
                ml      Ani Peter                       
                sl      Matej Urbančič                  

        * Updated translations
                ca      Gil Forcada                     
                en_GB   David Lodge                     
                ne      Mahesh subedi                   
                nl      Wouter Bolsterlee