20

While reading about packages that allow to hook macros to certain events, I came across this command, \shipout. Searching on the internet didn't help a lot but if I'm not so wrong it's somehow related to creating new pages (or is it?).

My question is, what is exactly \shipout, what does it do and how it does what it does? (i.e. what is happening on the low-level in the background)

1
  • \shipout is apparently primitive, because \show\shipout produces > \shipout=\shipout. Dec 27, 2013 at 12:54

2 Answers 2

21

This is quite easy: \shipout is a primitive. Its syntax is

\shipout ⟨box⟩

where ⟨box⟩ is completely specified at page 278 of the TeXbook:

⟨box⟩ → \box⟨8-bit number⟩ | \copy⟨8-bit number⟩
  | \lastbox | \vsplit⟨8-bit number⟩ to ⟨dimen⟩
  | \hbox⟨box specification⟩{⟨horizontal mode material⟩}
  | \vbox⟨box specification⟩{⟨vertical mode material⟩}
  | \vtop⟨box specification⟩{⟨vertical mode material⟩}
⟨box specification⟩ → to ⟨dimen⟩⟨filler⟩ | spread ⟨dimen⟩⟨filler⟩ | ⟨filler⟩

One could, for example, say

\shipout\hbox{Hello world}

and one page in the DVI or PDF file will be created. Of course nobody wants to use \shipout this way. Its main usage is in the output routine that is called when TeX decides it has sufficient material for ejecting a full page. The current main vertical list is split at the chosen page break and its contents is packaged into \box255, which the output routine can act on. For example, the Plain TeX output routine does

\shipout\vbox{
  \makeheadline
  \pagebody
  \makefootline
}
\advancepageno
\ifnum\outputpenalty>-\@MM
\else
  \dosupereject
\fi

so a full page, adorned with headers and footers is shipped out. The contents of \box255 is massaged by \pagebody. The output routine in LaTeX is much more complicated.

What one can do is redefining \shipout so it does other jobs. The oldest macro set that did something like this was quire.tex (still available on CTAN and TeX Live)

\def\q_init
   {\global\q_sheetnr=0\global\q_qnr=0
    \global\let\q_oldship=\shipout
    \global\let\shipout=\q_boat
    \xdef\q_cycles{\the\deadcycles}%
    \global\let\endquire=\q_endquire
   }

It saves the primitive meaning of \shipout in the command \q_oldship (the macros use _ as a ‘private’ marker) and redefines it to be \q_boat, which will do some jobs and eventually call \q_oldship. For instance it could be set up for placing two output pages on the same physical page, or for making sixteen page quires (whence the package name).

The package atbegshi does similarly. It redefines \shipout so that it can hook between the call of \shipout and the actual page ship out.

What precisely the primitive \shipout does is transforming the vertical list it's fed with into low level printing instructions (DVI or PDF format, according to the value of \pdfoutput if pdftex or luatex is used, XDV if xetex is used, only DVI for Knuth TeX). Meanwhile it executes all delayed \write operations, expanding tokens as it goes: in this way references to the page number are guaranteed to be correct, because they are computed when the page is being shipped out.

11

From TeXbook, Chapter 23: Output Routines, page 254:

TeX’s primitive command \shipout<box> is what actually causes output. It sends the contents of the box to the dvi file, which is TeX’s main output file; after TeX has finished, the dvi file will contain a compact device-independent encoding of instructions that specify exactly what should be printed. When a box is shipped out, TeX displays the values of \count0 through \count9 on your terminal, as explained in Chapter 15; these ten counters are also recorded in the dvi file, where they can be used to identify the page. All of the \openout, \closeout, and \write commands that appear inside of the box are performed in their natural order as that box is being shipped out. Since a \write command expands macros, as explained in Chapter 21, TeX’s scanning mechanism might detect syntax errors while a \shipout is in progress. If \tracingoutput is nonzero at the time of a \shipout, the contents of the box being shipped are written into your log file in symbolic form. You can say \shipout anywhere, not only in an output routine.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .