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