| 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. |