Quick summary of what this package does, and how to duplicate its
effects if you don't like my code.

A conforming PostScript file, for my purposes, is anything that meets
all of the following requirements:

1) first line must begin with the string '%!PS-Adobe'.
2) Each page must begin with a '%%Page:' line, and the graphics state
   must be the default at that point (no translation, scaling, or
   rotation of the coordinate space can carry over between pages).
   The pages must be numbered starting at 1, which is a bit pedantic
   of me.  It's part of the spec, but it is by no means necessary for
   the code to work.  It's a one-line check, and I'm thinking of just
   scrapping it.
3) There must be a '%%Trailer' line.


As for what I *do* with all this, it's simple:

1) When I see the '%!PS-Adobe' line, I insert the following lines
   (ignoring the old '%!PS' line):
	%!PS-Adobe-2.0
	%%Pages: (atend)
   Page counts in the header are first-comes, first-served, so putting
   mine at the very top will override anything that was in the
   original file (and since the whole idea is to change the number of
   pages, this is 'a good thing').  Since I do everything in one pass,
   I have no idea how many pages there will be, so I defer it until
   the end.
2) When I reach the end of the header comments (signified by the first
   non-%% line or an explicit %%EndComments line), I insert the
   user-defined prolog definitions into their own dictionary.  To
   simplify nesting, I use the current PID as part of the dictionary
   name.  I save the old value of showpage here, and redefine it to
   print nothing.  It looks like this (modulo interpretation of
   variables marked by <>):
	%%BeginProcSet: up_prolog 1 <pid>
	/UpDict<pid> $plines 3 add dict def
	UpDict<pid> begin
	<user prolog>
	/UpShowpage {showpage} bind def
	/UpState {} def
	end
	/showpage {} def
	%%EndProcSet: up_prolog 1 <pid>
3) For every '%%Page:' line, I first delete it, and then, if it is the
   first page on a sheet, I save the current VM state, and insert the
   user-specified scaling, rotation, and translation commands.  It
   looks like this (modulo the interpolation of the variables marked
   by <>):
	%%Page: ? <sheet number>
	UpDict<pid> begin
	save /UpState exch def
	<even/odd>
	<scale, translate, rotate>
	<page positioning>
	end
   For pages that don't start a sheet, I just insert:
	UpDict<pid> begin
	<page positioning>
	end
5) At the end of every sheet, I restore the VM state, and perform a
   real showpage, like so:
	UpDict<pid> begin UpState restore UpShowpage end
6) When I see the '%%Trailer' line, I replace it with:
	UpDict<pid> begin UpState restore UpShowpage end
	%%Trailer
   You might suspect that this causes an error, or the printing of a
   blank page, and if everything I said above were true, you'd be
   right.  The catch is that #5 is a lie.  I detect the end of a sheet
   by finding myself at the beginning of a new one, so the last sheet
   never gets printed, unless it's done just before the trailer.
7) The last bit is simple.  After the very last line of the input is
   printed, the actual sheet count is added.  This has to be this way,
   since the *last* in a series of trailer comments is the one heeded.
   It looks like this:
	%%Pages: <sheet count>


If this isn't entirely clear, here's a before/after.

----------
Conforming PS file, which prints 4 numbered pages (output of "makeup 4"):

%!PS-Adobe-1.0
%%Creator: makeup
%%Title: Page Layout Test
%%CreationDate: Tue Oct 24 02:33:36 EDT 1989
%%Pages: (atend)
%%DocumentFonts: Times-Roman
%%BoundingBox: 0 0 612 792
%%EndComments
/inch {72 mul} def
/Nfont /Times-Roman findfont 5 inch scalefont def
/drawpage {
	2 setlinecap 3 setlinewidth 0 setgray
	Nfont setfont
	dup stringwidth
	11 inch exch sub 2 div
	exch 8.5 inch exch sub 2 div
	exch moveto show
	0.25 inch dup moveto
	8 inch 0 rlineto
	0 10.5 inch rlineto
	-8 inch 0 rlineto
	0 -10.5 inch rlineto
	closepath stroke
	showpage
} def
%%EndProlog
%%Page: ? 1
(1) drawpage
%%Page: ? 2
(2) drawpage
%%Page: ? 3
(3) drawpage
%%Page: ? 4
(4) drawpage
%%Trailer
%%Pages: 4

----------
Previous file, filtered to print two pages per sheet ("up -n 2up"):

%!PS-Adobe-2.0
%%Pages: (atend)
%%Creator: makeup
%%Title: Page Layout Test
%%CreationDate: Tue Oct 24 02:33:36 EDT 1989
%%Pages: (atend)
%%DocumentFonts: Times-Roman
%%BoundingBox: 0 0 612 792
%%EndComments
%%BeginProcSet: up_prolog 1 7482
/UpDict7482 23 3 add dict def
UpDict7482 begin
/inch {72 mul} def
/moveU {0 11 inch translate} def
/moveR {8.5 inch 0 translate} def
/moveD {0 -11 inch translate} def
/moveL {-8.5 inch 0 translate} def
/rotR {-90 rotate} def
/rotL {90 rotate} def
/doSpiral {moveU moveR rotR 0.67 dup scale} def
/moveHU { 0 5.5 inch translate} def
/doRevSpiral {moveHU rotL 0.67 dup scale} def
/UpShowpage {showpage} bind def
/UpState {} def
end
/showpage {} def
%%EndProcSet: up_prolog 1 7482
/inch {72 mul} def
/Nfont /Times-Roman findfont 5 inch scalefont def
/drawpage {
	2 setlinecap 3 setlinewidth 0 setgray
	Nfont setfont
	dup stringwidth
	11 inch exch sub 2 div
	exch 8.5 inch exch sub 2 div
	exch moveto show
	0.25 inch dup moveto
	8 inch 0 rlineto
	0 10.5 inch rlineto
	-8 inch 0 rlineto
	0 -10.5 inch rlineto
	closepath stroke
	showpage
} def
%%EndProlog
%%Page: ? 1
UpDict7482 begin
save /UpState exch def
7.75 inch 0 translate rotL 11 17 div dup scale
end
(1) drawpage
UpDict7482 begin
moveR
end
(2) drawpage
UpDict7482 begin UpState restore UpShowpage end
%%Page: ? 2
UpDict7482 begin
save /UpState exch def
7.75 inch 0 translate rotL 11 17 div dup scale
end
(3) drawpage
UpDict7482 begin
moveR
end
(4) drawpage
UpDict7482 begin UpState restore UpShowpage end
%%Trailer
%%Pages: 2

--
J Greely (jgreely@cis.ohio-state.edu; osu-cis!jgreely)
