Commit | Line | Data |
---|---|---|
8340f87c BJ |
1 | .pn 27 |
2 | .ds H T | |
3 | .tr | | |
4 | .tr ~| | |
5 | .de x1 | |
6 | .xx | |
7 | .ftB | |
8 | .in .2i | |
9 | .nf | |
10 | .ne 2.1 | |
11 | .ta 1i | |
12 | .. | |
13 | .de x2 | |
14 | .fi | |
15 | .in0 | |
16 | .ftR | |
17 | .xx | |
18 | .. | |
19 | .br | |
20 | .ce | |
21 | .ftB | |
22 | .rs | |
23 | .sp 0.5i | |
24 | TUTORIAL EXAMPLES | |
25 | .ftR | |
26 | .sp2 | |
27 | .nr p 0 | |
28 | .2C | |
29 | .ns | |
30 | .mh | |
31 | .mk | |
32 | Introduction | |
33 | .pg | |
34 | Although \*(NR and \*(TR | |
35 | have by design a syntax reminiscent | |
36 | of earlier text processors* | |
37 | .fn | |
38 | .xx | |
39 | *For example: | |
40 | P.|A.|Crisman, Ed., | |
41 | .ul | |
42 | The Compatible Time-Sharing System, | |
43 | MIT Press, 1965, Section|AH9.01 | |
44 | (Description of RUNOFF program on MIT's CTSS system). | |
45 | .ef | |
46 | with the intent of easing their use, | |
47 | it is almost always necessary to | |
48 | prepare at least a small set of macro definitions | |
49 | to describe most documents. | |
50 | Such common formatting needs | |
51 | as page margins and footnotes | |
52 | are deliberately not built into \*(NR and \*(TR. | |
53 | Instead, | |
54 | the macro and string definition, number register, diversion, | |
55 | environment switching, page-position trap, and conditional input mechanisms | |
56 | provide the basis for user-defined implementations. | |
57 | .pg | |
58 | The examples to be discussed are intended to be useful and somewhat realistic, | |
59 | but won't necessarily cover all relevant contingencies. | |
60 | Explicit numerical parameters are used | |
61 | in the examples | |
62 | to make them easier to read and to | |
63 | illustrate typical values. | |
64 | In many cases, number registers would really be used | |
65 | to reduce the number of places where numerical | |
66 | information is kept, | |
67 | and to concentrate conditional parameter initialization | |
68 | like that which depends on whether \*(TR or \*(NR is being used. | |
69 | .mh | |
70 | Page Margins | |
71 | .pg | |
72 | As discussed in \(sc3, | |
73 | \fIheader\fR and \fIfooter\fR macros are usually defined | |
74 | to describe the top and bottom page margin areas respectively. | |
75 | A trap is planted at page position 0 for the header, and at | |
76 | \fI\-N\fR (\fIN\fR from the page bottom) for the footer. | |
77 | The simplest such definitions might be | |
78 | .x1 | |
79 | &de hd \e"define header | |
80 | \'sp 1i | |
81 | && \e"end definition | |
82 | &de fo \e"define footer | |
83 | \'bp | |
84 | && \e"end definition | |
85 | &wh 0 hd | |
86 | &wh \-1i fo | |
87 | .x2 | |
88 | which provide blank 1|inch top and bottom margins. | |
89 | The header will occur on the \fIfirst\fR page, | |
90 | only if the definition and trap exist prior to | |
91 | the initial pseudo-page transition (\(sc3). | |
92 | In fill mode, the output line that springs the footer trap | |
93 | was typically forced out because some part or whole word didn't fit on it. | |
94 | If anything in the footer and header that follows causes a \fIbreak\fR, | |
95 | that word or part word will be forced out. | |
96 | In this and other examples, | |
97 | requests like \fBbp\fR and \fBsp\fR that normally cause breaks are invoked using | |
98 | the \fIno-break\fR control character \fB\'\fR | |
99 | to avoid this. | |
100 | When the header\(slfooter design contains material | |
101 | requiring independent text processing, the | |
102 | environment may be switched, avoiding | |
103 | most interaction with the running text. | |
104 | .pg | |
105 | A more realistic example would be | |
106 | .x1 | |
107 | &de hd \e"header | |
108 | &if t .tl \'\|\e(rn\'\'\e(rn\' \e"troff cut mark | |
109 | &if \e\en%>1 \e{\e | |
110 | \'sp ~\|0.5i\-1 \e"tl base at 0.5i | |
111 | &tl \'\'\- % \-\'\' \e"centered page number | |
112 | &ps \e"restore size | |
113 | &ft \e"restore font | |
114 | &vs \e} \e"restore vs | |
115 | \'sp ~\|1.0i \e"space to 1.0i | |
116 | &ns \e"turn on no-space mode | |
117 | && | |
118 | &de fo \e"footer | |
119 | &ps 10 \e"set footer\(slheader size | |
120 | &ft R \e"set font | |
121 | &vs 12p \e"set base-line spacing | |
122 | &if \e\en%=1 \e{\e | |
123 | \'sp ~\|\e\en(.pu\-0.5i\-1 \e"tl base 0.5i up | |
124 | &tl \'\'\- % \-\'\' \e} \e"first page number | |
125 | \'bp | |
126 | && | |
127 | &wh 0 hd | |
128 | &wh \-1i fo | |
129 | .x2 | |
130 | which sets the size, font, and base-line spacing for the | |
131 | header\(slfooter material, and ultimately restores them. | |
132 | The material in this case is a page number at the bottom of the | |
133 | first page and at the top of the remaining pages. | |
134 | If \*(TR is used, a \fIcut mark\fR is drawn in the form | |
135 | of \fIroot-en\fR's at each margin. | |
136 | The \fBsp\fR's refer to absolute positions to avoid | |
137 | dependence on the base-line spacing. | |
138 | Another reason for this in the footer | |
139 | is that the footer is invoked by printing a line whose | |
140 | vertical spacing swept past the trap position by possibly | |
141 | as much as the base-line spacing. | |
142 | The \fIno-space\fR mode is turned on at the end of \fBhd\fR | |
143 | to render ineffective | |
144 | accidental occurrences of \fBsp\fR at the top of the running text. | |
145 | .pg | |
146 | The above method of restoring size, font, etc. presupposes | |
147 | that such requests (that set \fIprevious\fR value) are \fInot\fR | |
148 | used in the running text. | |
149 | A better scheme is save and restore both the current \fIand\fR | |
150 | previous values as shown for size in the following: | |
151 | .x1 | |
152 | &de fo | |
153 | &nr s1 \e\en(.s \e"current size | |
154 | &ps | |
155 | &nr s2 \e\en(.s \e"previous size | |
156 | & --- \e"rest of footer | |
157 | && | |
158 | &de hd | |
159 | & --- \e"header stuff | |
160 | &ps \e\en(s2 \e"restore previous size | |
161 | &ps \e\en(s1 \e"restore current size | |
162 | && | |
163 | .x2 | |
164 | Page numbers may be printed in the bottom margin | |
165 | by a separate macro triggered during the footer's | |
166 | page ejection: | |
167 | .x1 | |
168 | &de bn \e"bottom number | |
169 | &tl \'\'\- % \-\'\' \e"centered page number | |
170 | && | |
171 | &wh \-0.5i\-1v bn \e"tl base 0.5i up | |
172 | .x2 | |
173 | .mh | |
174 | Paragraphs and Headings | |
175 | .pg | |
176 | The housekeeping | |
177 | associated with starting a new paragraph should be collected | |
178 | in a paragraph macro | |
179 | that, for example, | |
180 | does the desired preparagraph spacing, | |
181 | forces the correct font, size, base-line spacing, and indent, | |
182 | checks that enough space remains for \fImore than one\fR line, | |
183 | and | |
184 | requests a temporary indent. | |
185 | .x1 | |
186 | &de pg \e"paragraph | |
187 | &br \e"break | |
188 | &ft R \e"force font, | |
189 | &ps 10 \e"size, | |
190 | &vs 12p \e"spacing, | |
191 | &in 0 \e"and indent | |
192 | &sp 0.4 \e"prespace | |
193 | &ne 1+\e\en(.Vu \e"want more than 1 line | |
194 | &ti 0.2i \e"temp indent | |
195 | && | |
196 | .x2 | |
197 | The first break in \fBpg\fR | |
198 | will force out any previous partial lines, | |
199 | and must occur before the \fBvs\fR. | |
200 | The forcing of font, etc. is | |
201 | partly a defense against prior error and | |
202 | partly to permit | |
203 | things like section heading macros to | |
204 | set parameters only once. | |
205 | The prespacing parameter is suitable for \*(TR; | |
206 | a larger space, at least as big as the output device vertical resolution, would be | |
207 | more suitable in \*(NR. | |
208 | The choice of remaining space to test for in the \fBne\fR | |
209 | is the smallest amount greater than one line | |
210 | (the \fB.V\fR is the available vertical resolution). | |
211 | .pg | |
212 | A macro to automatically number section headings | |
213 | might look like: | |
214 | .x1 | |
215 | &de sc \e"section | |
216 | & --- \e"force font, etc. | |
217 | &sp 0.4 \e"prespace | |
218 | &ne 2.4+\e\en(.Vu \e"want 2.4+ lines | |
219 | .lg 0 | |
220 | &fi | |
221 | .lg | |
222 | \e\en+S. | |
223 | && | |
224 | &nr S 0 1 \e"init S | |
225 | .x2 | |
226 | The usage is \fB.sc\fR, | |
227 | followed by the section heading text, | |
228 | followed by \fB.pg\fR. | |
229 | The \fBne\fR test value includes one line of heading, | |
230 | 0.4 line in the following \fBpg\fR, and | |
231 | one line of the paragraph text. | |
232 | A word consisting of the next section number and a period is | |
233 | produced to begin the heading line. | |
234 | The format of the number may be set by \fBaf\fR (\(sc8). | |
235 | .pg | |
236 | Another common form is the labeled, indented paragraph, | |
237 | where the label protrudes left into the indent space. | |
238 | .x1 | |
239 | &de lp \e"labeled paragraph | |
240 | &pg | |
241 | &in 0.5i \e"paragraph indent | |
242 | &ta 0.2i 0.5i \e"label, paragraph | |
243 | &ti 0 | |
244 | \et\e\e$1\et\ec \e"flow into paragraph | |
245 | && | |
246 | .x2 | |
247 | The intended usage is "\fB.lp\fR \fIlabel\fR\|"; | |
248 | \fIlabel\fR will begin at 0.2\|inch, and | |
249 | cannot exceed a length of 0.3\|inch without intruding into | |
250 | the paragraph. | |
251 | The label could be right adjusted against 0.4\|inch by | |
252 | setting the tabs instead with \fB.ta|0.4iR|0.5i\fR. | |
253 | The last line of \fBlp\fR ends with \fB\ec\fR so that | |
254 | it will become a part of the first line of the text | |
255 | that follows. | |
256 | .mh | |
257 | Multiple Column Output | |
258 | .pg | |
259 | The production of multiple column pages requires | |
260 | the footer macro to decide whether it was | |
261 | invoked by other than the last column, | |
262 | so that it will begin a new column rather than | |
263 | produce the bottom margin. | |
264 | The header can initialize a column register that | |
265 | the footer will increment and test. | |
266 | The following is arranged for two columns, but | |
267 | is easily modified for more. | |
268 | .x1 | |
269 | &de hd \e"header | |
270 | & --- | |
271 | &nr cl 0 1 \e"init column count | |
272 | &mk \e"mark top of text | |
273 | && | |
274 | &de fo \e"footer | |
275 | &ie \e\en+(cl<2 \e{\e | |
276 | &po +3.4i \e"next column; 3.1+0.3 | |
277 | &rt \e"back to mark | |
278 | &ns \e} \e"no-space mode | |
279 | &el \e{\e | |
280 | &po \e\enMu \e"restore left margin | |
281 | & --- | |
282 | \'bp \e} | |
283 | && | |
284 | &ll 3.1i \e"column width | |
285 | &nr M \e\en(.o \e"save left margin | |
286 | .x2 | |
287 | Typically a portion of the top of the first page | |
288 | contains full width text; | |
289 | the request for the narrower line length, | |
290 | as well as another \fB.mk\fR would | |
291 | be made where the two column output was to begin. | |
292 | .mh | |
293 | Footnote Processing | |
294 | .pg | |
295 | The footnote mechanism to be described is used by | |
296 | imbedding the footnotes in the input text at the | |
297 | point of reference, | |
298 | demarcated by an initial \fB.fn\fR and a terminal \fB.ef\fR: | |
299 | .x1 | |
300 | &fn | |
301 | \fIFootnote text and control lines...\fP | |
302 | &ef | |
303 | .x2 | |
304 | In the following, | |
305 | footnotes are processed in a separate environment and diverted | |
306 | for later printing in the space immediately prior to the bottom | |
307 | margin. | |
308 | There is provision for the case where the last collected | |
309 | footnote doesn't completely fit in the available space. | |
310 | .x1 | |
311 | &de hd \e"header | |
312 | & --- | |
313 | &nr x 0 1 \e"init footnote count | |
314 | &nr y 0\-\e\enb \e"current footer place | |
315 | &ch fo \-\e\enbu \e"reset footer trap | |
316 | &if \e\en(dn .fz \e"leftover footnote | |
317 | && | |
318 | &de fo \e"footer | |
319 | &nr dn 0 \e"zero last diversion size | |
320 | &if \e\enx \e{\e | |
321 | &ev 1 \e"expand footnotes in ev1 | |
322 | &nf \e"retain vertical size | |
323 | &FN \e"footnotes | |
324 | &rm FN \e"delete it | |
325 | &if "\e\en(.z"fy" .di \e"end overflow diversion | |
326 | &nr x 0 \e"disable fx | |
327 | &ev \e} \e"pop environment | |
328 | & --- | |
329 | \'bp | |
330 | && | |
331 | &de fx \e"process footnote overflow | |
332 | &if \e\enx .di fy \e"divert overflow | |
333 | && | |
334 | &de fn \e"start footnote | |
335 | &da FN \e"divert (append) footnote | |
336 | &ev 1 \e"in environment 1 | |
337 | &if \e\en+x=1 .fs \e"if first, include separator | |
338 | .lg0 | |
339 | &fi \e"fill mode | |
340 | .lg | |
341 | && | |
342 | &de ef \e"end footnote | |
343 | &br \e"finish output | |
344 | &nr z \e\en(.v \e"save spacing | |
345 | &ev \e"pop ev | |
346 | &di \e"end diversion | |
347 | &nr y \-\e\en(dn \e"new footer position, | |
348 | &if \e\enx=1 .nr y \-(\e\en(.v\-\e\enz) \e | |
349 | \e"uncertainty correction | |
350 | &ch fo \e\enyu \e"y is negative | |
351 | &if (\|\e\en(nl+1v)>(\|\e\en(.p+\e\eny) \e | |
352 | &ch fo \e\en(nlu+1v \e"it didn't fit | |
353 | && | |
354 | &de fs \e"separator | |
355 | \el\'\|1i\' \e"1 inch rule | |
356 | &br | |
357 | && | |
358 | &de fz \e"get leftover footnote | |
359 | &fn | |
360 | &nf \e"retain vertical size | |
361 | &fy \e"where fx put it | |
362 | &ef | |
363 | && | |
364 | &nr b 1.0i \e"bottom margin size | |
365 | &wh 0 hd \e"header trap | |
366 | &wh 12i fo \e"footer trap, temp position | |
367 | &wh \-\e\enbu fx \e"fx at footer position | |
368 | &ch fo \-\e\enbu \e"conceal fx with fo | |
369 | .x2 | |
370 | The header \fBhd\fR initializes a footnote count register \fBx\fR, | |
371 | and sets both the current footer trap position register \fBy\fR and | |
372 | the footer trap itself to a nominal position specified in | |
373 | register \fBb\fR. | |
374 | In addition, if the register \fBdn\fR indicates a leftover footnote, | |
375 | \fBfz\fR is invoked to reprocess it. | |
376 | The footnote start macro \fBfn\fR begins a diversion (append) in environment 1, | |
377 | and increments the count \fBx\fR; if the count is one, the footnote separator \fBfs\fR | |
378 | is interpolated. | |
379 | The separator is kept in a separate macro to permit user redefinition. | |
380 | The footnote end macro \fBef\fR restores | |
381 | the previous environment and ends the diversion after saving the spacing size in register \fBz\fR. | |
382 | \fBy\fR is then decremented by the size of the footnote, available in \fBdn\fR; | |
383 | then on the first footnote, \fBy\fR is further decremented by the difference | |
384 | in vertical base-line spacings of the two environments, to | |
385 | prevent the late triggering the footer trap from causing the last | |
386 | line of the combined footnotes to overflow. | |
387 | The footer trap is then set to the lower (on the page) of \fBy\fR or the current page position (\fBnl\fR) | |
388 | plus one line, to allow for printing the reference line. | |
389 | If indicated by \fBx\fR, the footer \fBfo\fR rereads the footnotes from \fBFN\fR in nofill mode | |
390 | in environment 1, | |
391 | and deletes \fBFN\fR. | |
392 | If the footnotes were too large to fit, the macro \fBfx\fR will be trap-invoked to redivert | |
393 | the overflow into \fBfy\fR, | |
394 | and the register \fBdn\fR will later indicate to the header whether \fBfy\fR is empty. | |
395 | Both \fBfo\fR and \fBfx\fR are planted in the nominal footer trap position in an order | |
396 | that causes \fBfx\fR to be concealed unless the \fBfo\fR trap is moved. | |
397 | The footer then terminates the overflow diversion, if necessary, and | |
398 | zeros \fBx\fR to disable \fBfx\fR, | |
399 | because the uncertainty correction | |
400 | together with a not-too-late triggering of the footer can result | |
401 | in the footnote rereading finishing before reaching the \fBfx\fR trap. | |
402 | .pg | |
403 | A good exercise for the student is to combine the multiple-column and footnote mechanisms. | |
404 | .mh | |
405 | The Last Page | |
406 | .pg | |
407 | After the last input file has ended, \*(NR and \*(TR | |
408 | invoke the \fIend macro\fR (\(sc7), if any, | |
409 | and when it finishes, eject the remainder of the page. | |
410 | During the eject, any traps encountered are processed normally. | |
411 | At the \fIend\fR of this last page, processing terminates | |
412 | \fIunless\fR a partial line, word, or partial word remains. | |
413 | If it is desired that another page be started, the end-macro | |
414 | .x1 | |
415 | &de en \e"end-macro | |
416 | \ec | |
417 | \'bp | |
418 | && | |
419 | &em en | |
420 | .x2 | |
421 | will deposit a null partial word, | |
422 | and effect another last page. |