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.