fa3336171c
current license information and adapted to the FreeBSD build environment before they will build. Approved by: David Taylor <davidt@caldera.com>
120 lines
3.2 KiB
Plaintext
120 lines
3.2 KiB
Plaintext
.\" This module is believed to contain source code proprietary to AT&T.
|
|
.\" Use and redistribution is subject to the Berkeley Software License
|
|
.\" Agreement and your Software Agreement with AT&T (Western Electric).
|
|
.\"
|
|
.\" @(#)tt14 8.1 (Berkeley) 6/8/93
|
|
.\"
|
|
.\" $FreeBSD$
|
|
.NH
|
|
Diversions
|
|
.PP
|
|
There are numerous occasions in page layout when it is necessary to store some text
|
|
for a period of time without actually printing it.
|
|
Footnotes are the most obvious example:
|
|
the text of the footnote usually appears in the input well before the place
|
|
on the page where it is to be printed is reached.
|
|
In fact,
|
|
the place where it is output normally depends on how big it is,
|
|
which implies that there must be a way
|
|
to process the footnote at least
|
|
enough to decide its size
|
|
without printing it.
|
|
.PP
|
|
.UL troff
|
|
provides a mechanism called a diversion
|
|
for doing this processing.
|
|
Any part of the output may be diverted into a macro instead
|
|
of being printed,
|
|
and then at some convenient time the macro may be put back into
|
|
the input.
|
|
.PP
|
|
The command
|
|
.BD .di\ xy
|
|
begins a diversion _ all subsequent output is collected into the macro
|
|
.BD xy
|
|
until the command
|
|
.BD .di
|
|
with no arguments is encountered.
|
|
This terminates the diversion.
|
|
The processed text is available at any time thereafter, simply
|
|
by giving the command
|
|
.P1
|
|
^xy
|
|
.P2
|
|
The vertical size of the last finished diversion is contained in
|
|
the built-in number register
|
|
.BD dn .
|
|
.PP
|
|
As a simple example,
|
|
suppose we want to implement a `keep-release'
|
|
operation,
|
|
so that text between the commands
|
|
.BD .KS
|
|
and
|
|
.BD .KE
|
|
will not be split across a page boundary
|
|
(as for a figure or table).
|
|
Clearly, when a
|
|
.BD .KS
|
|
is encountered, we have to begin diverting
|
|
the output so we can find out how big it is.
|
|
Then when a
|
|
.BD .KE
|
|
is seen, we decide
|
|
whether the diverted text will fit on the current page,
|
|
and print it either there if it fits, or at the top of the next page if it doesn't.
|
|
So:
|
|
.P1 2
|
|
.ta .6i
|
|
^de KS \e" start keep
|
|
^br \e" start fresh line
|
|
^ev 1 \e" collect in new environment
|
|
^fi \e" make it filled text
|
|
^di XX \e" collect in XX
|
|
^^
|
|
.P2
|
|
.P1 2
|
|
.ta .6i
|
|
^de KE \e" end keep
|
|
^br \e" get last partial line
|
|
^di \e" end diversion
|
|
^if \e\en(dn>=\e\en(.t .bp \e" bp if doesn't fit
|
|
^nf \e" bring it back in no-fill
|
|
^XX \e" text
|
|
^ev \e" return to normal environment
|
|
^^
|
|
.P2
|
|
Recall that number register
|
|
.BD nl
|
|
is the current position
|
|
on the output page.
|
|
Since output was being diverted, this remains
|
|
at its value when the diversion started.
|
|
.BD dn
|
|
is the amount of text in the diversion;
|
|
.BD .t
|
|
(another built-in register)
|
|
is the distance to the next trap,
|
|
which we assume is at the bottom margin of the page.
|
|
If the diversion is large enough to go past the trap,
|
|
the
|
|
.BD .if
|
|
is satisfied, and
|
|
a
|
|
.BD .bp
|
|
is issued.
|
|
In either case, the diverted output is then brought back with
|
|
.BD .XX .
|
|
It is essential to bring it back in no-fill mode so
|
|
.UL troff
|
|
will do no further processing on it.
|
|
.PP
|
|
This is not the most general keep-release,
|
|
nor is it robust in the face of all conceivable inputs,
|
|
but it would require more space than we have here to write it
|
|
in full generality.
|
|
This section is not intended
|
|
to teach everything about diversions,
|
|
but to sketch out enough that you can read
|
|
existing macro packages with some comprehension.
|