date and time created 80/10/30 00:35:38 by mckusick
[unix-history] / .ref-BSD-3 / usr / doc / trofftut / tt14
CommitLineData
8340f87c
BJ
1.NH
2Diversions
3.PP
4There are numerous occasions in page layout when it is necessary to store some text
5for a period of time without actually printing it.
6Footnotes are the most obvious example:
7the text of the footnote usually appears in the input well before the place
8on the page where it is to be printed is reached.
9In fact,
10the place where it is output normally depends on how big it is,
11which implies that there must be a way
12to process the footnote at least
13enough to decide its size
14without printing it.
15.PP
16.UL troff
17provides a mechanism called a diversion
18for doing this processing.
19Any part of the output may be diverted into a macro instead
20of being printed,
21and then at some convenient time the macro may be put back into
22the input.
23.PP
24The command
25.BD .di\ xy
26begins a diversion _ all subsequent output is collected into the macro
27.BD xy
28until the command
29.BD .di
30with no arguments is encountered.
31This terminates the diversion.
32The processed text is available at any time thereafter, simply
33by giving the command
34.P1
35^xy
36.P2
37The vertical size of the last finished diversion is contained in
38the built-in number register
39.BD dn .
40.PP
41As a simple example,
42suppose we want to implement a `keep-release'
43operation,
44so that text between the commands
45.BD .KS
46and
47.BD .KE
48will not be split across a page boundary
49(as for a figure or table).
50Clearly, when a
51.BD .KS
52is encountered, we have to begin diverting
53the output so we can find out how big it is.
54Then when a
55.BD .KE
56is seen, we decide
57whether the diverted text will fit on the current page,
58and print it either there if it fits, or at the top of the next page if it doesn't.
59So:
60.P1 2
61.ta .6i
62^de KS \e" start keep
63^br \e" start fresh line
64^ev 1 \e" collect in new environment
65^fi \e" make it filled text
66^di XX \e" collect in XX
67^^
68.P2
69.P1 2
70.ta .6i
71^de KE \e" end keep
72^br \e" get last partial line
73^di \e" end diversion
74^if \e\en(dn>=\e\en(.t .bp \e" bp if doesn't fit
75^nf \e" bring it back in no-fill
76^XX \e" text
77^ev \e" return to normal environment
78^^
79.P2
80Recall that number register
81.BD nl
82is the current position
83on the output page.
84Since output was being diverted, this remains
85at its value when the diversion started.
86.BD dn
87is the amount of text in the diversion;
88.BD .t
89(another built-in register)
90is the distance to the next trap,
91which we assume is at the bottom margin of the page.
92If the diversion is large enough to go past the trap,
93the
94.BD .if
95is satisfied, and
96a
97.BD .bp
98is issued.
99In either case, the diverted output is then brought back with
100.BD .XX .
101It is essential to bring it back in no-fill mode so
102.UL troff
103will do no further processing on it.
104.PP
105This is not the most general keep-release,
106nor is it robust in the face of all conceivable inputs,
107but it would require more space than we have here to write it
108in full generality.
109This section is not intended
110to teach everything about diversions,
111but to sketch out enough that you can read
112existing macro packages with some comprehension.