Galley Proofs

A galley proof is a printout of a document in which the margins are especially large. The idea is that you can read over what you have printed and have room for writing comments. This system was important in the days of manuscripts and lead-cast type, because the layout of your document was under the control of the publisher’s typesetter. You would receive a galley proof from your publisher and make comments about mistakes or changes to be made.

When you have control of the typesetting, galley proofs are not so important, but you may still want to have them. Many systems will not let you make a galley proof, but fortunately it is not hard to do.

The main idea is that you want to scale each page down (to make room for the extra big margins) and then translate the document up and to the right.

Let us say that we want to give ourselves an extra inch of margin on the vertical margins (and scale the horizontals to keep the proportions correct). Here is the PostScript code to do that:

        gsave
          8.5 6.5 sub 2 div inch               % Center page horizontally...
          11 11 6.5 8.5 div mul sub 2 div inch %  and vertically
          translate
          6.5 8.5 div               % Scale page horizontally...
          dup                       %  and vertically
          scale
          % original page code here...
        grestore

Here is a slightly faster version. Here, we allow the post-processor to do the math for us. This will print more quickly, since each page does not need to do its own division.

        gsave
          72 93 translate
          .7647 .7647 scale
          % original page code here...
        grestore

Why the gsave and grestore? Well, a good rule of thumb is to always save the graphics state before you go about changing it (and remember to restore it when you are done). Also, one of the rules of the document structuring convention is that each page should restore the state of the system to what it was when the page was about to start. In other words, the code to layout a page should not alter the permanent state of the system (graphics or otherwise). This assures that pages can be reordered after the PostScript has been generated.

The Hard Part

The hard part of all of this is knowing where to insert the new code. Where does one page begin and another end? You could look for calls to showpage, but many programs define their own versions of this operator (in the code that is generated by dvips, for instance, it is called eop).

So, how do we go about recognizing pages? The document structuring conventions provide us with some handy comments for flagging page information. The most important is the %%Page: comment. This comment specifies that the next piece of code is the first one for the new page (in fact, it also tells you which page it is). The end of the document should also be marked with a %%Trailer: comment and a %%EOF comment. The %%Trailer: comment specifies that code to be run at the end of the document is about to be given (so, we are done with the pages). The %%EOF comment specifies that we are done with the file. Again, this specifies that we have processed the last page.

So, using these comments, how can we add the needed PostScript? Well, we can start by looking for the first %%Page: comment. When we find it, we insert the translate and scale commands right after it. Thereafter, we will proceed each %%Page: with a grestore and insert the translate and scale code after the comment. This process continues until we find either a %%Trailer: or a %%EOF comment. The first of these we find is proceeded by a grestore.

This is all we need to do. To make things a bit more concrete, here is a PERL script to do the job (to make things a bit more interesting, I have added a light line around the original page’s image, so you can know how big it is):

#!/usr/local/bin/perl
$flag = 0;
while (<>) {
    if (/^%%Page:/) {
        if ($flag) {
            print "grestore\n";
        }
        $flag = 1;
        print $_;
        print "gsave 72 93 translate .7647 .7647 scale\n";
        print "gsave .75 setgray newpath -1 -1 moveto 614 0 rlineto\n";
        print "0 794 rlineto -614 0 rlineto closepath stroke grestore\n";
    } elsif (/^%%Trail/) {
        if ($flag) {
            print "grestore\n";
        }
        print $_;
        $flag = 0;
    } elsif (/^%%EOF/) {
        if ($flag) {
            print "grestore\n";
        }
        print $_;
        $flag = 0;
    } else {
        print;
    }
}

Now, this script is not perfect. Many PostScript files do not conform as they should. This script can, however, serve as a starting point for your own, more robust code.