Deferring Output (The GNU Troff Manual)

### 5.27 Deferring Output

A few `roff` language elements are generally not used in simple documents, but arise as page layouts become more sophisticated and demanding. Environments collect formatting parameters like line length and typeface. A diversion stores formatted output for later use. A trap is a condition on the input or output, tested automatically by the formatter, that is associated with a macro, causing it to be called when that condition is fulfilled.

Footnote support often exercises all three of the foregoing features. A simple implementation might work as follows. A pair of macros is defined: one starts a footnote and the other ends it. The author calls the first macro where a footnote marker is desired. The macro establishes a diversion so that the footnote text is collected at the place in the body text where its corresponding marker appears. An environment is created for the footnote so that it is set at a smaller typeface. The footnote text is formatted in the diversion using that environment, but it does not yet appear in the output. The document author calls the footnote end macro, which returns to the previous environment and ends the diversion. Later, after much more body text in the document, a trap, set a small distance above the page bottom, is sprung. The macro called by the trap draws a line across the page and emits the stored diversion. Thus, the footnote is rendered.

Diversions and traps make the text formatting process non-linear. Let us imagine a set of text lines or paragraphs labelled ‘`A`’, ‘`B`’, and so on. If we set up a trap that produces text ‘`T`’ (as a page footer, say), and we also use a diversion to store the formatted text ‘`D`’, then a document with input text in the order ‘`A B C D E F`’ might render as ‘`A B C E T F`’. The diversion ‘`D`’ will never be output if we do not call for it.

Environments of themselves are not a source of non-linearity in document formatting: environment switches have immediate effect. One could always write a macro to change as many formatting parameters as desired with a single convenient call. But because diversions can be nested and macros called by traps that are sprung by other trap-called macros, they may be called upon in varying contexts. For example, consider a page header that is always to be set in Helvetica. A document that uses Times for most of its body text, but Courier for displayed code examples, poses a challenge if a page break occurs in the middle of a code display; if the header trap assumes that the “previous font” is always Times, the rest of the example will be formatted in the wrong typeface. One could carefully save all formatting parameters upon entering the trap and restore them upon leaving it, but this is verbose, error-prone, and not future-proof as the `groff` language develops. Environments save us considerable effort.