 
This document has a standard, validated CSS2 stylesheet, which your browser does not seem to display properly. In a browser supporting web standards, this table of contents would be fixed at the side of the page for easy reference.
anastigmatix home
  PageNest r. 0.1 21, available from 12 October 2005 to
  22 November 2005, could be tripped by a bug in some Adobe interpreters
  where upath can cause a nocurrentpoint error
  contrary to Adobe's documentation. Revision 0.1 24 works around the
  problem.
  Since language level 2, the PostScript language has allowed
  BeginPage and EndPage handlers: a document can
  supply procedures that will be called back by the interpreter at the time of
  setting up the initial graphics state for a page and at the time of
  showpage, respectively. They offer a clear and concise way to set
  up running copy or watermarks, to select only certain pages from a document,
  to apply selective margin shifts, to impose multiple virtual pages on a
  physical page, or do anything else that can be done by PostScript code
  hooked into the setup and showing of pages.
  The trouble was, while BeginPage and EndPage
  are easy to use for any one of those purposes, they were difficult to
  use for any combination of them at the same time. Adobe only allowed for
  a single BeginPage and a single EndPage at a
  time. If you wanted to print a document 4-up on physical pages, and
  print only the recto physical pages, and add a company watermark
  to each of the four virtual pages on each physical page, you could write
  hairy custom BeginPage and EndPage procedures
  that would do all that; what you could not do was grow a collection of
  simple BeginPage and EndPage handlers that do
  those things individually, and combine them as in:
{ 2 mod 0 eq } bind dup select InstallBeginEndPage
4up InstallBeginEndPage
AcmeWatermark InstallBeginEndPage
Now you can. The flexibility of a stack of handlers is apparent when you start playing with the order. Would it look better to have the company watermark once across each physical page instead of on each of the 4-up virtual pages?
{ 2 mod 0 eq } bind dup select InstallBeginEndPage
AcmeWatermark InstallBeginEndPage
4up InstallBeginEndPage
Maybe the intent was really to get every other page of the original document, not every other physical page of the 4-up result:
AcmeWatermark InstallBeginEndPage
4up InstallBeginEndPage
{ 2 mod 0 eq } bind dup select InstallBeginEndPage
  Existing PostScript files sometimes need to be manipulated to select
  particular pages, adapt to different dimensions, or create multipage
  impositions for printing, either because they were created by applications
  that did not offer those options, or the applications belonged to somebody
  else, or just because to learn a particular application's way of doing
  something can be more trouble than to simply produce the output in default
  style and then use a familiar tool that does the trick. An excellent set of
  tools I have used for many years myself can be found in Angus Duggan's
  PSUtils.
  The most general is
  pstops,
  which can select, reorder, shift, scale, and combine pages, for example
  to create arbitrary impositions. It generalizes the simpler tools
  psselect, psbook, and psnup;
  psbook, for example, produces a fixed page ordering for
  one possible quarto imposition, but pstops can do that or
  any other.
  
Those tools are programs written in conventional languages that read PostScript files and write rearranged versions of them without interpreting the PostScript code; they depend on Document Structuring Convention comments in the file, and shuffle the code between them as so much opaque text, a technique that often works quite well for well-formed files that do what their DSC comments say they do.
  A technique implemented in PostScript naturally does not rely on what the
  comments say, but hooks what the PostScript code actually does. For
  manipulating existing PostScript, a solution based on PageNest,
  which may only prepend a prolog to the original file, may work for a more
  general class of input files than DSC-based file rewriting techniques.
  There are tradeoffs, and no need to use only one type of solution or the
  other. A PageNest-based solution for selecting certain pages
  from a PostScript file will transmit and interpret the entire file, discarding
  the unwanted pages; a tool like Duggan's psselect will create
  a new file for transmission containing only the wanted pages, saving
  bandwidth and interpreter time at the expense of an extra step in host
  processing, and possibly disk space. Arranging multiple page images per
  sheet is very easily done with PageNest, but shuffling the
  file's pages into the proper order for folding into signatures may be
  easiest with a tool like psselect, as in general storage space
  will be required to buffer pages, and only some PostScript interpreters
  have attached disks. Hybrid approaches are possible: a tool can achieve part
  of its effect through rewriting of a PostScript file and part by emitting
  the rewritten file with a prolog of PostScript resources to do the rest;
  PageNest can be used in that way too.
  For
  direct PostScript—PostScript as the
  original form of a document
  so that one form is both editable and printable—PageNest
  can offer a very concise way to set up such features as running heads,
  watermarks, multiple columns, or step-and-repeat, without adding complexity
  to the underlying procedures used for setting text. Nested handlers
  responsible for page-level elements and sub-page regions can be a simple
  model for page layout.
  These examples show PageNest—and some other resources,
  like
  Markup,
  MetaPre, and
  Order—in use.
  
  One produces serially-numbered tickets for an obscure appearance by the
  Second Greatest Show on Earth (if there really is such a thing, please do
  not use these tickets to attend).
  
  
  One produces address labels and one
  addresses post cards; both consist of a short file that can simply be stuck
  at the beginning of a file of addresses in a simple format, and the resulting
  file directly printed.
You may view the examples either in a PostScript previewer or in a plain text editor, according as you would rather see what comes out, or read how it is done. Each example comes in two flavors. Each self-contained file has all the resources it needs included in its prolog, so it will work without any prearrangement on any PostScript printer or viewer.
  If you did this sort of thing a lot, you would probably download or save
  the resources in advance where your printer or viewer could find them, and
  then the bare files would work just as is. The
  reference
  section describes downloading and installing. The self-contained
  files were generated from the bare files by a simple script that
  copies in the resources where the %%IncludeResource comments
  are.
| Bare file | Self-contained file | ||
|---|---|---|---|
| Admission tickets | PostScript view text view | PostScript view text view | PDF view | 
| Address labels | PostScript view text view | PostScript view text view | PDF view | 
| Postcard addressing | PostScript view text view | PostScript view text view | PDF view | 
  As BeginPage and EndPage procedures are defined
  as the PostScript Language Reference Manual, a
  BeginPage procedure is passed a single integer
  on the stack, the page number, and consumes it, returning nothing;
  EndPage
  consumes two integers, page number and a reason code, and returns
  a boolean determining what the PostScript interpreter should do next.
  Without nesting, the interpreter calls BeginPage as its last
  action on any showpage or setpagedevice; the
  number on the stack is the number of the page being begun. (In fact it is
  the count of showpages since the last setpagedevice,
  so the first page is numbered zero; this is a bit confusing as it will
  probably not match the document numbering, and it makes recto pages even
  and verso pages odd, but one gets used to it.) The interpreter calls
  EndPage as its first action on any
  showpage, before marking the medium, passing the same page
  number that was given last to BeginPage, and a reason code
  of zero. If EndPage returns true, the interpreter marks
  the medium, erases raster memory, and restores the initial graphics
  state; if false, the interpreter makes no marks and does not erase
  raster memory, but does restore the initial graphics state. In either case,
  as always, the showpage finishes by calling
  BeginPage with the next page number. Effects such as four-up
  printing could be achieved with an EndPage procedure that
  returns true only every fourth page, and a BeginPage
  that cycles through four regions on the page as it sets up the initial
  transformation matrix.
  The interpreter calls EndPage with the page number and reason
  code 2 at the end of a job, or as the first action of a
  setpagedevice. Ordinarily, an EndPage procedure
  would return false in that case, though something like a four-up
  procedure would want to return true if there has been at least one
  showpage since the last physical page was produced, to emit
  the final partial page. The only other defined reason code, 1, is associated
  with copypage, which is now deprecated and in level 3 has the
  same meaning as showpage.
  How the protocol extends to nested BeginPage is straightforward.
  At every time the interpreter normally calls BeginPage,
  the effect of executing all installed BeginPage
  procedures, in order from the first installed to the most recently, is needed.
  The reason is that the interpreter has always executed
  initgraphics, creating the initial default user space.
  Each BeginPage procedure inherits a user space and may transform
  it before the next, more recently installed, sees it, so re-executing them
  in sequence will establish the proper graphics state. In practice,
  PageNest caches effects on the graphics state, as described
  below, to avoid actually executing any BeginPage more than once
  between calls of its corresponding EndPage.
  The page number passed to the topmost BeginPage procedure is
  zero just after it has been pushed, increments after each interpreter
  callback of EndPage with a reason code other than 2,
  and resets to zero after any EndPage callback with reason
  code 2 (device deactivation).
  The page number passed to
  each older/outer BeginPage is the count of times its
  next inner neighbor's EndPage has returned true.
  When a topmost handler ceases to be topmost, because another has been
  pushed, its current page count is retained.
  PageNest invokes each BeginPage procedure with
  a clean operand stack containing only the page number. An ordinary
  BeginPage procedure will consume the page number and leave
  nothing on the stack, but PageNest allows the procedure to
  leave the stack nonempty. Anything left on the operand stack when a
  BeginPage procedure completes will be cleared from the stack
  and saved for the corresponding EndPage procedure to see later. 
  The extension to EndPage is more interesting. When the
  interpreter calls EndPage, PageNest executes the
  known EndPage handlers, this time in the order from most recent
  to outermost. However, it stops as soon as one returns false. The page
  number passed to an EndPage handler is the same number most
  recently passed to its corresponding BeginPage handler, and is
  then incremented if the handler is topmost or the handler above returned
  true. In other words,
  when a handler h returns true, the
  page number passed to its next outer neighbor h' is the count of times
  h has returned true, not including this time.
  Only if all EndPage handlers return
  true will true be returned to the PostScript interpreter,
  causing a physical page to be marked.
  An exception applies when the reason code is 2. Because the
  device is being deactivated, all EndPage handlers are executed
  in sequence regardless of the values returned, and true is returned
  to the PostScript interpreter if any handler returned true.
  Otherwise, a final partial four-up page, for example, might be lost if
  an outer EndPage handler simply returned false for
  device deactivation, as many do. The page count for the topmost handler
  is reset to zero after a call to EndPage with reason code 2.
  PageNest invokes each EndPage procedure with a
  clean operand stack with the page number and reason code on top; if
  there were items left on the stack by the corresponding
  BeginPage, they are on the stack with the page number and
  reason code pushed just above them. The lowest item on the stack, accessible
  with count 1 sub index, is always
  the cached partial graphics state
  captured after BeginPage, in the form of a procedure that can
  be executed to reinitialize the state; this is explained below.
  The top of the stack
  must contain a boolean when an EndPage procedure completes;
  anything below it on the stack at that point is discarded, so it is
  not necessary for an EndPage handler to explicitly consume
  any of the cached items from BeginPage. An EndPage
  handler can explicitly control the page counter it shares with its
  corresponding BeginPage handler, by pushing an integer on the
  stack above its boolean result. The integer becomes the next value to be
  passed to BeginPage.
  Something like a four-up handler can be constructed by defining an
  EndPage handler that returns true only on every
  fourth call. With such a handler on the stack, any
  outer BeginPage handlers, below it on the stack, are
  conceptually executed
  more than once with the same page number. That would be no problem for
  BeginPage handlers that only set graphics state, but could have
  unexpected results with a handler that makes marks on the page or has other
  side effects. For that reason, PageNest executes any
  BeginPage handler only once between calls of the corresponding
  EndPage handler, and on subsequent callbacks simply resets
  the graphics state with values cached after BeginPage returned.
  Any time the corresponding EndPage executes, regardless of the
  value it returns, the cached result of the corresponding
  BeginPage is invalidated so the next BeginPage
  callback will execute the procedure.
  PageNest does not cache the entire graphics state after
  executing BeginPage, but only exactly those parameters
  that are reset by initgraphics as defined in the PostScript
  Language Reference Manual: CTM, clipping path, current path, color space
  and color, linewidth, linecap, linejoin, miterlimit, and dash pattern.
  The effect can be defined this way: if the handler stack is
  (BP0,EP0)...(BPj,EPj),(BPk,EPk)...(BPn,EPn) with (BPn,EPn) pushed last, and a showpage is executed where
  EPk returns false so that
  EPj...EP0 are not executed,
  then BP0...BPj are not executed,
  BPk...BPn are executed, and the initial
  graphics state seen by BPk is as if the
  initgraphics performed by showpage applied values
  established by BPj rather than defaults for the physical
  device.
  BeginPage handlers should not use outlines from a protected
  font to establish either a current path or a clipping path,
  because PageNest's caching mechanism will fail in that case.
  Adobe's specification for the PostScript language requires that the
  interpreter-managed page counter reset to zero on every change of page
  device or use of the setpagedevice operator. Ghostscript
  has a different behavior, which is documented in
  Ghostscript
  bug #688213, currently tagged as WONTFIX, so Ghostscript and PostScript
  are resolved to be different languages on this point. To facilitate writing
  BeginPage and EndPage handlers with predictable
  behavior on both platforms, PageNest ignores the interpreter's
  page counter and manages its own, according to a simple rule. The counter
  for the topmost handler resets to zero after any
  EndPage with reason code 2; this is the Adobe-specified
  behavior. Counters below the topmost do not automatically reset, a behavior
  closer to Ghostscript and retained for compatibility with earlier versions
  of PageNest (where the interpreter's page count was passed to
  the topmost handler, and PageNest maintained the counts for other
  handlers on the stack). However, PageNest allows a handler to
  obtain strict PostScript or Ghostscript counter behavior in all cases by a
  slight modification to its EndPage procedure.
  EndPage can return an integer that becomes the next value of
  the counter. Strict PostScript behavior is obtained by returning zero on
  any call with reason code 2; Ghostscript behavior by returning the current
  counter value on any call with reason code 2. Other counter
  behaviors can be obtained using the same mechanism.
  When using BeginPage and EndPage handlers to
  rearrange or reposition PostScript generated by applications, you are
  likely before long to run into some PostScript file that in some way or
  other refuses to be manipulated. Some applications generate PostScript
  that falls short of Adobe's recommendations for well-behaved page
  descriptions, and more or less clever workarounds can be needed.
  Many applications generate PostScript that uses a
  save/restore pair around each page.
  Here are two ways to do that:
| The right way | The wrong way | 
|---|---|
| save ... restore showpage | save ... showpage restore | 
  If you've got a PostScript file that was generated the wrong way, then
  it just won't matter how your BeginPage procedure sets up
  the graphics state—except for the first time—because it does
  so as the last step of showpage and no sooner is it done than
  the restore comes along and reinstates the graphics state of
  the previous page.
  To use PageNest successfully with such a file, execute
  InstallRestoreHack as
  part of document setup. This tells PageNest to defer any
  showpage that comes at a deeper level of save
  nesting than the BeginPage call that began the page, and
  installs a wrapper for restore that will execute
  showpage if it is deferred and pending, upon restoring to
  the correct save level.
  PostScript pages generated from PDF documents by Acrobat or Adobe Reader
  can seem to have minds of their own, defying any translation or scaling
  you set up in advance. What they are doing is centering themselves in the
  rectangle that bounds the current clipping path
  (clippath pathbbox) and scaling themselves to just fit.
  If you do not need to crop them, you can get them where you want them if,
  as part of page setup, you establish a clipping path with aspect ratio
  matching the page image and located where you want it. If you want the
  image cropped, there is nothing for it but to cripple the AS
  procedure that has been generated into the file. One easy way that works
  in level 3 PostScript is to include an
  IdiomSet resource that zaps
  out the procedure by idiom recognition. Another approach is to define a
  version of clippath that lies when AS calls it;
  it can tell because a dictionary containing Pllx, Plly, Purx, Pury,
  Dllx, Dlly, Durx, and Dury will be on the lookup stack.
  Versions of Ghostscript before version
  8.31
  fail to process device deactivation, and do not invoke EndPage
  with reason code 2, when normally exiting at the end of a job. This is
  bug #687557
  and can cause, for example, a last incomplete n-up page from the
  tile handler to be lost. If upgrading
  Ghostscript is not an option, deactivation can be forced by arranging to
  execute setpagedevice (even with an empty dictionary:
  0 dict setpagedevice) before exiting at the end of a job.
  This issue is now discussed in
  Page-counter
  management, describing how PageNest provides predictable
  under Ghostscript and PostScript.
  PageNest is a ProcSet
  resource.
  To make it available to your own code, include in the setup section of
  your file:
/net.anastigmatix.PageNest /ProcSet findresource
  The findresource will succeed, leaving a dictionary on the
  operand stack, if you have made
  the
  PageNest
  resource file [download]
  available in any of these ways:
findresource (which belongs in the
      setup section)%%DocumentNeededResources and
      %%IncludeResource DSC comments, you include these comments at
      the right position in your file to specify that it needs
      net.anastigmatix.PageNest, your document manager software is configured to
      automatically insert needed resources in files being printed, and you have
      put the PageNest resource file where your document manager can find
      it.
  PageNest relies on another resource,
  MetaPre.
  You will need that file also. If you use the first method, you should
  include both files in the prolog of your document, MetaPre
  first. The other methods should Just Work as long as both files are where
  they need to be. In any case, your document only needs the single
  findresource line shown above. A
  findresource for MetaPre is not needed unless you
  also use MetaPre features in your own document. You pay no
  penalty to do so, as the resource must be there anyway.
The resource files are in a compact form. That is for efficiency, not to keep you from viewing them; there is a script for that on the resource packaging page.
  The PageNest dictionary may be placed on the lookup stack (with
  begin) for convenient access to the definitions in it, without
  the bother of get and exec. The dictionary is
  read-only, so before creating any
  definitions, you will want either userdict begin or your
  own dict begin so that you have a writable dictionary on top
  of the dictionary stack.
  This section describes the contents of the read-only dictionary that is
  returned by /net.anastigmatix.PageNest /ProcSet findresource.
The dictionary contains three procedures for managing the stack of handlers.
    
      passes dict, a setpagedevice parameter dictionary, to
      setpagedevice, with special treatment for BeginPage and
      EndPage entries if present. BeginPage and EndPage
      entries are pushed on PageNest's own stack, on top of any
      pushed by earlier uses of InstallBeginEndPage. They are removed
      from the dictionary before it is passed on to setpagedevice,
      which handles normally any other parameters that may be present. On the
      first use, any existing BeginPage/EndPage handlers
      returned by currentpagedevice are placed on PageNest's
      stack—before those in dict—and
      PageNest's own handlers are placed in the dictionary to
      register them with setpagedevice.
    
BeginPage and EndPage handlers are always pushed in pairs. If dict includes only one, a default procedure is pushed for the other. As described in the PostScript Language Reference Manual, the default for BeginPage has no effect but to consume its operand, and the default EndPage consumes its operands and produces true for reason codes 0 or 1, false for 2.
Every use of InstallBeginEndPage results in a setpagedevice. The setpagedevice will call every currently registered EndPage handler, not including the new one from dict, in order from most recent to oldest, with a reason code of 2 (device deactivation). It will then execute erasepage and initgraphics, erasing the entire current physical page, and call every registered BeginPage handler, including the new one, in order from oldest to most recent.
    
      Because InstallBeginEndPage calls setpagedevice and so
      inevitably affects the entire physical page, it is useful for setting
      up running elements, watermarks, and impositions either at the start
      of a job or at places known to be physical page breaks. For the more
      general problem of defining arbitrary sub-“pages” on
      individual pages, or of nesting jobs that use PageNest,
      an alternative PushBeginEndPage is provided that does not call
      setpagedevice.
    
    
The handler stack is subject to save and restore. If restore is executed and a handler has been added with InstallBeginEndPage since the corresponding save, the interpreter will see a change of page device and perform an EndPage callback with reason code 2 before popping the handler. This does not happen if the handler was added with PushBeginEndPage instead (unless some pagedevice update was also made since the corresponding save).
    
      As for InstallBeginEndPage except that setpagedevice is
      never called, dict must contain no entries other than
      BeginPage and EndPage, and the operation fails if
      InstallBeginEndPage has not been called at least once to
      activate PageNest itself. After installing the new
      handlers, executes initgraphics and then the stack of
      BeginPage handlers in the usual way; the usual effect will
      be that the new BeginPage handler executes in the restored
      graphics environment set up by the previously topmost. No EndPage
      handler is called and no page counter or page content is disturbed.
    
    
The handler stack is subject to save and restore. If restore is executed and a handler has been added with PushBeginEndPage since the corresponding save, the handler is simply popped and its EndPage is not executed (unless some pagedevice update was also made since the corresponding save). This behavior differs from that of InstallBeginEndPage and could lead to surprises. PopBeginEndPage can be used to pop the topmost handler and ensure that its EndPage is executed.
      removes the most recent BeginPage/EndPage handler pair
      from PageNest's stack. Does not execute
      setpagedevice. Executes the popped EndPage handler with
      a reason code of 2 (device deactivation), as if by
      setpagedevice and, if that handler returns true, executes
      showpage, causing the remaining stack of handlers to be executed
      with reason code 0 in the usual way.
    
Four procedures conveniently construct handler dictionaries that can be passed to InstallBeginEndPage.
constructs a dictionary containing a do-nothing BeginPage handler. While it will have no other effect, if pushed as the last handler on the stack, it will ensure that the handler below it sees a steadily cumulative page count rather than one that resets to zero with each use of setpagedevice.
constructs a dictionary containing BeginPage and EndPage handlers to select pages for printing based on the procedures image and advance. Each procedure is executed with a page number on the stack and expected to consume the number and produce a boolean. BeginPage calls image to determine if the page should be imaged at all; if false, BeginPage sets a degenerate clipping path for the page. EndPage calls advance to determine if a page should have been “produced”; if false, EndPage returns false to suppress the page.
When both image and advance return true, a normal page is produced; when both return false, a page is suppressed entirely. When image returns false and advance returns true, a blank page is produced at that position. When image returns true and advance false, the page and the next will be superimposed.
constructs a dictionary containing BeginPage and EndPage handlers to sequentially number pages. EndPage will restore the graphics state saved by BeginPage and then execute paintproc with a single integer on the stack, the sequence number to be painted on the page. These are simple procedures intended for producing strictly serial-numbered tickets or documents, not for the more flexible page numbering of general text processing.
If nup is 1, then if faceup is false, the number passed to paintproc is simply the page number passed to EndPage plus start, and if faceup is true, it is the page number subtracted from start+n-1; the point is to leave the lowest-numbered piece on top of the output stack.
When nup is greater than one, seqnumbered assumes its BeginPage/EndPage procedures are to be pushed over procedures that combine multiple pieces on a physical page (see tile). Naturally, nup should match the number of pieces arranged per page by the lower procedures. In this case, the numbers passed to paintproc are in an order such that the resulting stack of sheets can be cut into nup stacks of consecutively numbered pieces. The stacks can be put one atop another in the obvious way to get a single ordered stack. As always, the value of faceup adjusts the order to match the paper delivery.
If n is not a multiple of nup, each small stack may need to have a single unprinted piece removed from the top or the bottom before the small stacks are put together.
There is no problem giving nup as 1 even if pieces are being combined by an underlying handler; you will simply get pieces numbered consecutively within sheets rather than down stacks.
The value of n is unimportant if nup is 1 and faceup is false: if more than n showpages are executed, numbers will just keep increasing as you would expect. If faceup is true, they will continue decreasing below the value of start. If nup is greater than 1 and more than n showpages are executed,the resulting numbers will have a messy pattern and repeat numbers already generated.
constructs a dictionary containing BeginPage and EndPage handlers to arrange n virtual pages on each page produced, where n is the number of elements in array. Each element is an executable array containing a transformation matrix and four numbers defining a clipping rectangle as with rectclip. BeginPage reduces the current page number modulo n and executes the corresponding element, followed by rectclip concatmatrix—note that the clipping rectangle is installed before the matrix is applied, so its coordinates are not in the new virtual page's coordinate system but that of the enclosing page. EndPage returns false except when ending every nth page, except on device deactivation, reason code 2, where it returns true unless the current page number is zero mod n.
Because tile accepts an array of arbitrary transformation matrices and clip rectangles, it is not limited to pure tiling, but simply arranges n virtual areas on a page, whether tiled, overlapping, or superimposed. Utility procedures are provided (described in the next section) to construct array for common cases of tiling that come up in step-and-repeat or page imposition.
Several utility procedures are provided to simplify setting up virtual pages that tile a larger page, with orientations that can vary (as in a page imposition for signatures that will be folded).
Computes the largest scale factor at which the matter (with dimensions mw mh) will just fit in a region of dimensions rw rh: the smaller of rw/mw and rh/mh. Signs are ignored on the widths and heights; factor is never negative.
concatenates either a single matrix to each of a list of matrices, or corresponding elements of two lists of matrices. The matrices in the right-hand list are updated in place. The right hand may be a simple array of matrices, or an array of executable arrays each having a matrix as its first element (the data structure produced by origins and used by tile).
given an array whose length is a multiple of 3, taken as a sequence of orient ix iy triples, and region width and height rw and rh, construct an array of the form used by tile, where each matk is a translation to ikxrw ikyrh and reorientation as specified by orientk, and each cliprectk has width and height rw rh and lower left corner ikxrw ikyrh. Each orientk is a procedure that takes rw rh on the stack and produces a transformation matrix. The eight obvious ones are named and described below. The simple way to use them is to use executable-array syntax for the {orient ix iy...} array, and immediate-name form for the orientations, which will ensure the procedures are copied into the array and not prematurely executed:
     % a possible quarto imposition for landscape pages on sheet run portrait:
     { //ruul 0 1 //ruul 0 0 //rdur 1 1 //rdur 1 0 } pw 2 div ph 2 div origins
     
  produces an array usable as input to origins for the simple case of a grid of rows rows and cols columns and the same orientation for each region. rowmaj varies the column indices faster than the row indices, and colmaj does the reverse. If either rows or cols is negative, the corresponding indices will run downward (from the absolute value less one, down to zero).
 
Eight named procedures provide the obvious orientations for rectangular matter being placed in a rectangular region. I always spend more time than I should making hand gestures in the air while setting up a rotation and translation, so these procedures have names chosen to be concise and descriptive. Each name is four letters. The first and third refer to the upper and right edges of the matter, the second and fourth to the corresponding edges of the region. So, uurr is the identity orientation (up to up and right to right), udrl is 180 degree rotation, and rdur means the matter is rotated 90 degrees clockwise to be placed in the region. The names in which u comes first are those where the aspect ratios of the matter and region match (zero and 180 rotations); r comes first for those that invert the aspect ratio (90 and 270 rotations). The names that involve mirroring, for example UURL, are capitalized.
Each procedure takes the region width and height on the stack and returns a transformation matrix.
    
      executes a moveto to the point xfrac yfrac relative to the
      current clip region's bounding rectangle (clippath pathbbox).
      That is, 0 1 onclip moves to the top left corner,
      0.5 1 onclip to the top center, and so on.
    
    
onclip can be convenient to use in a BeginPage procedure that establishes an initial current point for direct PostScript typesetting, for example. The code below will set the current point initially for every page, one inch below and right of the top left corner:
<< /BeginPage {0 1 onclip 72 72 rmoveto} bind >> InstallBeginEndPage
    
      The reference to onclip in that procedure will require
      PageNest's dictionary to be on the lookup stack at all times.
      If you replace onclip with //onclip exec, you will be able
      to end the PageNest dictionary once you have defined
      the procedure.
    
executes scale and translate to just fit the given bounding box llx lly urx ury, preserving aspect ratio, in a region of dimensions rw rh, with the lower left corner at the (prior) origin. That is, the scaling is by urx-llx ury-lly rw rh minscale, and the translation is by -llx -lly. Signs are ignored for rw and rh.
orfit's behavior is completely determined by its arguments. It makes no attempt to query or account for the current graphics state, so it will not defeat cropping or scaling effects set up in advance (as the earlier-described Acrobat auto-adjustment can).
One procedure is provided to enable the workaround for misplaced save and restore described earlier:
    
      sets an internal flag requiring PageNest's
      begin- and end-page handlers to observe the current
      save/restore level, and to defer any showpage
      executed at a save level more deeply nested than that recorded by
      BeginPage. Adds to dict a definition for
      restore that executes restore followed immediately by
      showpage if one was pending and the save level after
      restore is not greater than the recorded level.
      InstallRestoreHack uses setpagedevice to register
      PageNest's own begin- and end-page handlers, only if
      they have not been registered already.
    
    
    
      The simple userdict InstallRestoreHack will solve the
      misplaced save/restore problem in many cases. It can fail, though,
      with code that relies on the definition of restore
      being an operator (the substitute version is a procedure), or that
      looks for it in systemdict explicitly. Those complications are
      not unheard of; even InstallRestoreHack itself currently relies
      on the (prior) definition of restore being an operator.