Sync: tmac/fallbacks.tmac: import, adjust troffrc
[s-roff.git] / tmac / s.tmac
blobd5094a995bc93ac650b31940b8629b9246895859
1 .ig
2 @ s.tmac
4 Copyright (c) 2014 Steffen (Daode) Nurpmeso <sdaoden@users.sf.net>.
6 Copyright (C) 1989 - 1992, 2001 - 2004, 2006, 2007
7   Free Software Foundation, Inc.
8      Written by James Clark (jjc@jclark.com)
10 This is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 2, or (at your option) any later
13 version.
15 This is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 for more details.
20 You should have received a copy of the GNU General Public License along
21 with groff; see the file COPYING.  If not, write to the Free Software
22 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA.
24 .if !\n(.g .ab These ms macros require groff / compatible.
25 .if \n(.C \
26 .       ab The groff ms macros do not work in compatibility mode.
27 .\" Enable warnings (only if none are given on the command line).
28 .\" You can delete this if you want.
29 .if (\n[.warn] == 65543) .warn
30 .\" See if already loaded.
31 .if r GS .nx
32 .mso devtag.tmac
33 .nr GS 1
34 .nr need_eo_h 0
35 .nr need_eo_tl 0
36 .de @error
37 .tm \\n(.F:\\n(.c: macro error: \\$*
39 .de @warning
40 .tm \\n(.F:\\n(.c: macro warning: \\$*
42 .de @fatal
43 .ab \\n(.F:\\n(.c: fatal macro error: \\$*
45 .de @not-implemented
46 .@error sorry, \\$0 not implemented
47 .als \\$0 @nop
49 .als TM @not-implemented
50 .als CT @not-implemented
51 .de @nop
53 .de @init
54 .if !rPO .nr PO \\n(.o
55 .\" a non-empty environment
56 .ev ne
58 .ev
59 .ev nf
60 'nf
61 .ev
63 .ds REFERENCES References
64 .ds ABSTRACT ABSTRACT
65 .ds TOC Table of Contents
66 .ds MONTH1 January
67 .ds MONTH2 February
68 .ds MONTH3 March
69 .ds MONTH4 April
70 .ds MONTH5 May
71 .ds MONTH6 June
72 .ds MONTH7 July
73 .ds MONTH8 August
74 .ds MONTH9 September
75 .ds MONTH10 October
76 .ds MONTH11 November
77 .ds MONTH12 December
78 .ds MO \E*[MONTH\n[mo]]
79 .ds DY \n[dy] \*[MO] \n[year]
80 .de ND
81 .if \\n[.$] .ds DY "\\$*
83 .de DA
84 .if \\n[.$] .ds DY "\\$*
85 .ds CF \\*[DY]
87 .\" indexing
88 .de IX
89 .tm \\$1\t\\$2\t\\$3\t\\$4 ... \\n[PN]
91 .\" print an error message and then try to recover
92 .de @error-recover
93 .@error \\$@ (recovering)
94 .nr *pop-count 0
95 .while !'\\n(.z'' \{\
96 .       \"@warning automatically terminating diversion \\n(.z
97 .       ie d @div-end!\\n(.z .@div-end!\\n(.z
98 .       el .*div-end-default
99 .       nr *pop-count +1
100 .       \" ensure that we don't loop forever
101 .       if \\n[*pop-count]>20 .@fatal recovery failed
103 .while !'\\n[.ev]'0' .ev
104 .par@reset-env
105 .par@reset
107 .de *div-end-default
108 .ds *last-div \\n(.z
111 .ev nf
112 .\\*[*last-div]
115 .\" ****************************
116 .\" ******** module cov ********
117 .\" ****************************
118 .\" Cover sheet and first page.
119 .de cov*err-not-after-first-page
120 .@error \\$0 is not allowed after the first page has started
122 .de cov*err-not-before-tl
123 .@error \\$0 is not allowed before TL
125 .de cov*err-not-again
126 .@error \\$0 is not allowed more than once
128 .de cov*err-not-after-ab
129 .@error \\$0 is not allowed after first AB, LP, PP, IP, SH or NH
131 .als AU cov*err-not-before-tl
132 .als AI cov*err-not-before-tl
133 .als AB cov*err-not-before-tl
134 .de cov*first-page-init
135 .\" Invoked by `.wh 0' trap on first page.
136 .\" We should not come here again, but at short page length,
137 .\" recursion may occur; remove trap and macro to avoid it.
138 .ch cov*first-page-init
139 .rm cov*first-page-init
140 .if !'\\n[.ev]'0' \{\
141 .       @error must be in top-level environment, not `\\n[.ev]',
142 .       @error when first page is started
144 .par@init
145 .als RP cov*err-not-after-first-page
146 .@init
147 .ie \\n[cov*rp-format] \{\
148 .       pg@cs-top
149 .       als FS cov*FS
150 .       als FE cov*FE
152 .el \{\
153 .       pg@top
154 .       als FS @FS
155 .       als FE @FE
157 .wh 0 pg@top
158 .CHECK-FOOTER-AND-KEEP
160 .wh 0 cov*first-page-init
161 .\" This handles the case where FS occurs before TL or LP.
162 .de FS
164 \\*[FS]\\
166 .nr cov*rp-format 0
167 .nr cov*rp-no 0
168 .\" released paper format
169 .de RP
170 .nr cov*rp-format 1
171 .if \\n[.$] .if '\\$1'no' .nr cov*rp-no 1
172 .if rPO .po \\n(POu
173 .pn 0
175 .de TL
177 .als TL cov*err-not-again
178 .rn @AB AB
179 .rn @AU AU
180 .rn @AI AI
181 .di cov*tl-div
182 .par@reset
183 .ft B
184 .ps +2
185 .vs +3p
186 .ll (u;\\n[LL]*5/6)
187 .nr cov*n-au 0
188 .DEVTAG-TL
190 .de @AU
191 .par@reset
192 .if !'\\n(.z'' \{\
193 .       br
194 .       di
196 .nr cov*n-au +1
197 .di cov*au-div!\\n[cov*n-au]
199 .ft I
200 .ie (\\n[PS] >= 1000) \
201 .       ps (\\n[PS]z / 1000u)
202 .el \
203 .       ps \\n[PS]
205 .de @AI
206 .par@reset
207 .if !'\\n(.z'' \{\
208 .       br
209 .       di
211 .ie !\\n[cov*n-au] .@error AI before AU
212 .el \{\
213 .       di cov*ai-div!\\n[cov*n-au]
214 .       nf
215 .       ft R
216 .       ie (\\n[PS] >= 1000) \
217 .               ps (\\n[PS]z / 1000u)
218 .       el \
219 .               ps \\n[PS]
223 .de LP
224 .if !'\\n[.z]'' \{\
225 .       br
226 .       di
229 .cov*ab-init
230 .cov*print
231 .nop \\*[\\$0]\\
234 .als IP LP
235 .als PP LP
236 .als XP LP
237 .als QP LP
238 .als RS LP
239 .als NH LP
240 .als SH LP
241 .als MC LP
242 .als RT LP
243 .als XS LP
245 .de cov*ab-init
246 .als cov*ab-init @nop
247 .als LP @LP
248 .als IP @IP
249 .als PP @PP
250 .als XP @XP
251 .als RT @RT
252 .als XS @XS
253 .als SH @SH
254 .als NH @NH
255 .als QP @QP
256 .als RS @RS
257 .als RE @RE
258 .als QS @QS
259 .als QE @QE
260 .als MC @MC
261 .als EQ @EQ
262 .als EN @EN
263 .als TS @TS
264 .als AB cov*err-not-after-ab
265 .als AU par@AU
266 .als AI par@AI
267 .als TL par@TL
270 .de @AB
271 .if !'\\n(.z'' \{\
272 .       br
273 .       di
275 .cov*ab-init
276 .ie '\*(.T'html' \{\
277 .       cov*tl-au-print
278 .       als cov*tl-au-print @nop
280 .el .di cov*ab-div
281 .par@ab-indent
282 .par@reset
283 .if !'\\$1'no' \{\
284 .       if '\*(.T'html'  \{\
285 .               nf
286 .               sp
287 .       \}
288 .       ft I
289 .       ce 1
290 \\*[ABSTRACT]
291 .       sp
292 .       ft R
295 .@PP
296 .if '\*(.T'html' \{\
297 .       cov*tl-au-print
298 .       als cov*tl-au-print @nop
299 .       par@reset-env
300 .       par@reset
301 .       cov*print
304 .de AE
305 .ie '\*(.T'html' \{\
306 .       als AE cov*err-not-again
308 .el \{\
309 .  ie '\\n(.z'cov*ab-div' \{\
310 .       als AE cov*err-not-again
311 .       br
312 .       di
313 .\"     nr cov*ab-height \\n[dn]
314 .       par@reset-env
315 .       par@reset
316 .       cov*print
317 .  \}
318 .  el .@error AE without AB
321 .de @div-end!cov*ab-div
324 .de cov*print
325 .als cov*print @nop
326 .ie d cov*tl-div \{\
327 .       ie \\n[cov*rp-format] .cov*rp-print
328 .       el .cov*draft-print
330 .el \{\
331 .       if \\n[cov*rp-format] \{\
332 .               @warning RP format but no TL
333 .               bp 1
334 .               als FS @FS
335 .               als FE @FE
336 .               CHECK-FOOTER-AND-KEEP
337 .       \}
338 .       br
341 .de cov*rp-print
342 .nr cov*page-length \\n[.p]
343 .pl 1000i
344 .cov*tl-au-print
345 .sp 3
346 .if d cov*ab-div \{\
347 .  if !'\*(.T'html'  .nf
348 .       cov*ab-div
350 .sp 3
351 .par@reset
352 \\*[DY]
354 .if \\n[cov*fn-height] \{\
355 .       sp |(u;\\n[cov*page-length]-\\n[FM]\
356 -\\n[cov*fn-height]-\\n[fn@sep-dist]>?\\n[nl])
357 .       fn@print-sep
358 .       ev nf
359 .       cov*fn-div
360 .       ev
361 .       ie \\n[cov*rp-no] .rm cov*fn-div
362 .       el \{\
363 .               rn cov*fn-div fn@overflow-div
364 .               nr fn@have-overflow 1
365 .       \}
367 .als FS @FS
368 .als FE @FE
369 .CHECK-FOOTER-AND-KEEP
370 .\" If anything was printed below where the footer line is normally printed,
371 .\" then that's an overflow.
372 .if -\\n[FM]/2+1v+\\n[cov*page-length]<\\n[nl] .@error cover sheet overflow
373 .pl \\n[cov*page-length]u
374 .bp 1
375 .if !\\n[cov*rp-no] .cov*tl-au-print
377 .sp 1
379 .de cov*draft-print
380 .cov*tl-au-print
381 .if d cov*ab-div \{\
382 .       nf
383 .       sp 2
384 .       cov*ab-div
386 .sp 1
388 .de cov*tl-au-print
389 .par@reset
392 .sp 3
393 .ce 9999
394 .if d cov*tl-div \{\
395 .    cov*tl-div
396 .    DEVTAG-EO-TL
398 .nr cov*i 1
399 .nr cov*sp 1v
400 .while \\n[cov*i]<=\\n[cov*n-au] \{\
401 .       ie '\*(.T'html' .br
402 .       el .sp \\n[cov*sp]u
403 .       cov*au-div!\\n[cov*i]
404 .       ie d cov*ai-div!\\n[cov*i] \{\
405 .               sp .5v
406 .               cov*ai-div!\\n[cov*i]
407 .               nr cov*sp 1v
408 .       \}
409 .       el .nr cov*sp .5v
410 .       nr cov*i +1
412 .ce 0
414 .nr cov*fn-height 0
415 .nr cov*in-fn 0
416 .\" start of footnote on cover
417 .de cov*FS
418 .if \\n[cov*in-fn] \{\
419 .       @error nested FS
420 .       FE
422 .nr cov*in-fn 1
423 .ev fn
424 .par@reset-env
425 .da cov*fn-div
426 .if !\\n[cov*fn-height] .ns
427 .ie \\n[.$] .FP "\\$1" no
428 .el .@LP
430 .de @div-end!cov*fn-div
431 .cov*FE
433 .\" end of footnote on cover
434 .de cov*FE
435 .ie '\\n(.z'cov*fn-div' \{\
436 .       br
437 .       ev
438 .       di
439 .       nr cov*in-fn 0
440 .       nr cov*fn-height +\\n[dn]
442 .el .@error FE without matching FS
444 .\" ***************************
445 .\" ******** module pg ********
446 .\" ***************************
447 .\" Page-level formatting.
448 .\" > 0 if we have a footnote on the current page
449 .nr pg@fn-flag 0
450 .nr pg@colw 0
451 .nr pg@fn-colw 0
452 .nr HM 1i
453 .nr FM 1i
454 .ds LF
455 .ds CF
456 .ds RF
457 .ds LH
458 .ds CH -\En[PN]-
459 .ds RH
460 .ds pg*OH '\E*[LH]'\E*[CH]'\E*[RH]'
461 .ds pg*EH '\E*[LH]'\E*[CH]'\E*[RH]'
462 .ds pg*OF '\E*[LF]'\E*[CF]'\E*[RF]'
463 .ds pg*EF '\E*[LF]'\E*[CF]'\E*[RF]'
464 .de OH
465 .ds pg*\\$0 "\\$*
467 .als EH OH
468 .als OF OH
469 .als EF OH
470 .de PT
471 .ie \\n%=1 .if \\n[pg*P1] .tl \\*[pg*OH]
472 .el \{\
473 .       ie o .tl \\*[pg*OH]
474 .       el .tl \\*[pg*EH]
477 .de BT
478 .ie o .tl \\*[pg*OF]
479 .el .tl \\*[pg*EF]
481 .nr pg*P1 0
482 .de P1
483 .ie r bell_localisms \{\
484 .       DS L
485 .       ft CW
487 .el .nr pg*P1 1
489 .wh -\n[FM]u pg@bottom
490 .wh -\n[FM]u/2u pg*footer
491 .nr MINGW 2n
492 .nr pg@ncols 1
493 .de @MC
494 .if !'\\n(.z'' .error-recover MC while diversion open
496 .ie \\n[pg@ncols]>1 .pg@super-eject
497 .el \{\
498 .       \" flush out any floating keeps
499 .       while \\n[kp@tail]>\\n[kp@head] \{\
500 .               rs
501 .               bp
502 .       \}
504 .ie !\\n(.$ \{\
505 .       nr pg@colw \\n[LL]*7/15
506 .       nr pg*gutw \\n[LL]-(2*\\n[pg@colw])
507 .       nr pg@ncols 2
509 .el \{\
510 .       nr pg@colw (n;\\$1)<?\\n[LL]
511 .       ie \\n[.$]<2 .nr pg*gutw \\n[MINGW]
512 .       el .nr pg*gutw (n;\\$2)
513 .       nr pg@ncols \\n[LL]-\\n[pg@colw]/(\\n[pg@colw]+\\n[pg*gutw])+1
514 .       ie \\n[pg@ncols]>1 \
515 .               nr pg*gutw \\n[LL]-(\\n[pg@ncols]*\\n[pg@colw])/(\\n[pg@ncols]-1)
516 .       el .nr pg*gutw 0
518 .DEVTAG ".mc \\n[pg@ncols] \\n[pg@colw] \\n[pg*gutw]"
519 .mk pg*col-top
521 .nr pg*col-num 0
522 .nr pg@fn-colw \\n[pg@colw]*5/6
523 .par@reset
525 .de 2C
528 .de 1C
529 .MC \\n[LL]u
531 .\" top of page macro
532 .de pg@top
533 .ch pg*footer -\\n[FM]u/2u
534 .nr PN \\n%
535 .nr pg*col-num 0
536 .nr pg@fn-bottom-margin 0
537 .po \\n[PO]u
538 .ev h
539 .par@reset
540 .sp (u;\\n[HM]/2)
542 .sp |\\n[HM]u
543 .if d HD .HD
544 .mk pg@header-bottom
546 .mk pg*col-top
547 .pg*start-col
549 .de pg*start-col
550 .\" Handle footnote overflow before floating keeps, because the keep
551 .\" might contain an embedded footnote.
552 .fn@top-hook
553 .kp@top-hook
554 .tbl@top-hook
557 .de pg@cs-top
558 .sp \\n[HM]u
559 .\" move pg@bottom and pg*footer out of the way
560 .ch pg@bottom \\n[.p]u*2u
561 .ch pg*footer \\n[.p]u*2u
564 .de pg@bottom
565 .tbl@bottom-hook
566 .if \\n[pg@fn-flag] .fn@bottom-hook
567 .nr pg*col-num +1
568 .ie \\n[pg*col-num]<\\n[pg@ncols] .pg*end-col
569 .el .pg*end-page
571 .de pg*end-col
572 'sp |\\n[pg*col-top]u
573 .po (u;\\n[PO]+(\\n[pg@colw]+\\n[pg*gutw]*\\n[pg*col-num]))
574 .\"po +(u;\\n[pg@colw]+\\n[pg*gutw])
575 .pg*start-col
577 .de pg*end-page
578 .po \\n[PO]u
579 .\" Make sure we don't exit if there are still floats or footnotes left-over.
580 .ie \\n[kp@head]<\\n[kp@tail]:\\n[fn@have-overflow] \{\
581 .       \" Switching environments ensures that we don't get an unnecessary
582 .       \" blank line at the top of the page.
583 .       ev ne
584 '       bp
585 .       ev
587 .el \{\
588 .       \" If the text has ended and there are no more footnotes or keeps, exit.
589 .       if \\n[pg@text-ended] .ex
590 .       if r pg*next-number \{\
591 .               pn \\n[pg*next-number]
592 .               rr pg*next-number
593 .               if d pg*next-format \{\
594 .                       af PN \\*[pg*next-format]
595 .                       rm pg*next-format
596 .               \}
597 .       \}
598 '       bp
601 .\" pg@begin number format
602 .de pg@begin
603 .ie \\n[.$]>0 \{\
604 .       nr pg*next-number (;\\$1)
605 .       ie \\n[.$]>1 .ds pg*next-format \\$2
606 .       el .rm pg*next-format
608 .el .rr pg*next-number
609 .pg@super-eject
611 .\" print the footer line
612 .de pg*footer
613 .ev h
614 .par@reset
618 .\" flush out any keeps or footnotes
619 .de pg@super-eject
621 .if !'\\n(.z'' .@error-recover diversion open while ejecting page
622 .\" Make sure we stay in the end macro while there is still footnote overflow
623 .\" left, or floating keeps.
624 .while \\n[kp@tail]>\\n[kp@head]:\\n[pg@fn-flag] \{\
625 .       rs
626 .       bp
630 .nr pg@text-ended 0
631 .de pg@end-text
633 .nr pg@text-ended 1
634 .pg@super-eject
636 .em pg@end-text
637 .\" ***************************
638 .\" ******** module fn ********
639 .\" ***************************
640 .\" Footnotes.
641 .nr fn@sep-dist 8p
642 .ev fn
643 .\" Round it vertically
644 .vs \n[fn@sep-dist]u
645 .nr fn@sep-dist \n[.v]
647 .nr fn*text-num 0 1
648 .nr fn*note-num 0 1
649 .ds * \E*[par@sup-start]\En+[fn*text-num]\E*[par@sup-end]
650 .nr fn*open 0
651 .\" normal FS
652 .de @FS
653 .ie \\n[.$] .fn*do-FS "\\$1" no
654 .el \{\
655 .       ie \\n[fn*text-num]>\\n[fn*note-num] .fn*do-FS \\n+[fn*note-num]
656 .       el .fn*do-FS
659 .\" Second argument of `no' means don't embellish the first argument.
660 .de fn*do-FS
661 .if \\n[fn*open] .@error-recover nested FS
662 .nr fn*open 1
663 .if \\n[.u] \{\
664 .       \" Ensure that the first line of the footnote is on the same page
665 .       \" as the reference.  I think this is minimal.
666 .       ev fn
667 .       nr fn*need 1v
668 .       ev
669 .       ie \\n[pg@fn-flag] .nr fn*need +\\n[fn:PD]
670 .       el .nr fn*need +\\n[fn@sep-dist]
671 .       ne \\n[fn*need]u+\\n[.V]u>?0
673 .ev fn
674 .par@reset-env
675 .fn*start-div
676 .par@reset
677 .ie \\n[.$] .FP \\$@
678 .el .@LP
680 .de @FE
681 .ie !\\n[fn*open] .@error FE without FS
682 .el \{\
683 .       nr fn*open 0
684 .       br
685 .       ev
686 .       fn*end-div
689 .nr fn@have-overflow 0
690 .\" called at the top of each column
691 .de fn@top-hook
692 .nr fn*max-width 0
693 .nr fn*page-bottom-pos 0-\\n[FM]-\\n[pg@fn-bottom-margin]
694 .ch pg@bottom \\n[fn*page-bottom-pos]u
695 .if \\n[fn@have-overflow] \{\
696 .       nr fn@have-overflow 0
697 .       fn*start-div
698 .       ev nf
699 .       fn@overflow-div
700 .       ev
701 .       fn*end-div
704 .\" This is called at the bottom of the column if pg@fn-flag is set.
705 .de fn@bottom-hook
706 .nr pg@fn-flag 0
707 .nr fn@have-overflow 0
708 .nr fn@bottom-pos \\n[.p]-\\n[FM]-\\n[pg@fn-bottom-margin]+\\n[.v]
709 .ev fn
710 .nr fn@bottom-pos -\\n[.v]
712 .ie \\n[nl]+\\n[fn@sep-dist]+\n[.V]>\\n[fn@bottom-pos] \{\
713 .       rn fn@div fn@overflow-div
714 .       nr fn@have-overflow 1
716 .el \{\
717 .       if \\n[pg@ncols]>1 \
718 .               if \\n[fn*max-width]>\\n[pg@fn-colw] \
719 .                       nr pg@fn-bottom-margin \\n[.p]-\\n[FM]-\\n[nl]+1v
720 .       wh \\n[fn@bottom-pos]u fn*catch-overflow
721 .       fn@print-sep
722 .       ev nf
723 .       fn@div
724 .       rm fn@div
725 .       ev
726 .       if '\\n(.z'fn@overflow-div' \{\
727 .               di
728 .               nr fn@have-overflow \\n[dn]>0
729 .       \}
730 .       ch fn*catch-overflow
733 .de fn*catch-overflow
734 .di fn@overflow-div
736 .nr fn*embed-count 0
737 .de @div-end!fn@div
739 .if '\\n[.ev]'fn' .ev
740 .fn*end-div
741 .nr fn*open 0
743 .als @div-end!fn*embed-div @div-end!fn@div
744 .de fn*start-div
745 .ie '\\n(.z'' \{\
746 .       da fn@div
747 .       if !\\n[pg@fn-flag] .ns
749 .el .di fn*embed-div
751 .de fn*end-div
752 .ie '\\n(.z'fn@div' \{\
753 .       di
754 .       nr fn*page-bottom-pos -\\n[dn]
755 .       nr fn*max-width \\n[fn*max-width]>?\\n[dl]
756 .       if !\\n[pg@fn-flag] .nr fn*page-bottom-pos -\\n[fn@sep-dist]
757 .       nr pg@fn-flag 1
758 .       nr fn*page-bottom-pos \\n[nl]-\\n[.p]+\n[.V]>?\\n[fn*page-bottom-pos]
759 .       ch pg@bottom \\n[fn*page-bottom-pos]u
761 .el \{\
762 .       ie '\\n(.z'fn*embed-div' \{\
763 .       di
764 .               rn fn*embed-div fn*embed-div!\\n[fn*embed-count]
765 \!.             fn*embed-start \\n[fn*embed-count]
766 .               rs
767 '               sp (u;\\n[dn]+\\n[fn@sep-dist]+\\n[.V])
768 \!.             fn*embed-end
769 .               nr fn*embed-count +1
770 .       \}
771 .       el \{\
772 .               ev fn
773 .               @error-recover unclosed diversion within footnote
774 .       \}
777 .de fn*embed-start
778 .ie '\\n(.z'' \{\
779 .       fn*start-div
780 .       ev nf
781 .       fn*embed-div!\\$1
782 .       rm fn*embed-div!\\$1
783 .       ev
784 .       fn*end-div
785 .       di fn*null
787 .el \{\
788 \!.     fn*embed-start \\$1
789 .       rs
792 .de fn*embed-end
793 .ie '\\n(.z'fn*null' \{\
794 .       di
795 .       rm fn*null
797 .el \!.fn*embed-end
799 .\" It's important that fn@print-sep use up exactly fn@sep-dist vertical space.
800 .de fn@print-sep
801 .ev fn
802 .in 0
803 .vs \\n[fn@sep-dist]u
804 \D'l 1i 0'
808 .\" ***************************
809 .\" ******** module kp ********
810 .\" ***************************
811 .\" Keeps.
812 .de KS
814 .di kp*div
816 .de KF
817 .if !'\\n(.z'' .@error-recover KF while open diversion
818 .di kp*fdiv
819 .ev k
820 .par@reset-env
821 .par@reset
823 .de KE
824 .ie '\\n(.z'kp*div' .kp*end
825 .el \{\
826 .       ie '\\n(.z'kp*fdiv' .kp*fend
827 .       el .@error KE without KS or KF
830 .de @div-end!kp*div
831 .kp*end
833 .de @div-end!kp*fdiv
834 .kp*fend
836 .de kp*need
837 .ie '\\n(.z'' .ds@need \\$1
838 .el \!.kp*need \\$1
840 .\" end non-floating keep
841 .de kp*end
844 .kp*need \\n[dn]
845 .ev nf
846 .kp*div
848 .rm kp*div
850 .\" Floating keeps.
851 .nr kp@head 0
852 .nr kp@tail 0
853 .\" end floating keep
854 .de kp*fend
858 .ie \\n[.t]-(\\n[.k]>0*1v)>\\n[dn] \{\
859 .       br
860 .       ev nf
861 .       kp*fdiv
862 .       rm kp*fdiv
863 .       ev
865 .el \{\
866 .       rn kp*fdiv kp*div!\\n[kp@tail]
867 .       nr kp*ht!\\n[kp@tail] 0\\n[dn]
868 .       nr kp@tail +1
871 .\" top of page processing for KF
872 .nr kp*doing-top 0
873 .de kp@top-hook
874 .if !\\n[kp*doing-top] \{\
875 .       nr kp*doing-top 1
876 .       kp*do-top
877 .       nr kp*doing-top 0
880 .de kp*do-top
881 .\" If the first keep won't fit, only force it out if we haven't had a footnote
882 .\" and we're at the top of the page.
883 .nr kp*force \\n[pg@fn-flag]=0&(\\n[nl]<=\\n[pg@header-bottom])
884 .nr kp*fits 1
885 .while \\n[kp@tail]>\\n[kp@head]&\\n[kp*fits] \{\
886 .       ie \\n[.t]>\\n[kp*ht!\\n[kp@head]]:\\n[kp*force] \{\
887 .               nr kp*force 0
888 .               \" It's important to advance kp@head before bringing
889 .               \" back the keep, so that if the last line of the
890 .               \" last keep springs the bottom of page trap, a new
891 .               \" page will not be started unnecessarily.
892 .               rn kp*div!\\n[kp@head] kp*temp
893 .               nr kp@head +1
894 .               ev nf
895 .               kp*temp
896 .               ev
897 .               rm kp*temp
898 .       \}
899 .       el .nr kp*fits 0
902 .\" ***************************
903 .\" ******** module ds ********
904 .\" ***************************
905 .\" Displays and non-floating keeps.
906 .de DE
907 .ds*end!\\n[\\n[.ev]:ds-type]
908 .nr \\n[.ev]:ds-type 0
910 .de ds@auto-end
911 .if \\n[\\n[.ev]:ds-type] \{\
912 .       @error automatically terminating display
913 .       DE
916 .de @div-end!ds*div
917 .ie \\n[\\n[.ev]:ds-type] .DE
918 .el .ds*end!2
920 .de ds*end!0
921 .@error DE without DS, ID, CD, LD or BD
923 .de LD
925 .nr \\n[.ev]:ds-type 1
926 .par@reset
928 .sp \\n[DD]u
930 .de ID
932 .ie \\n[.$] .in +(n;\\$1)
933 .el .in +\\n[DI]u
935 .de CD
937 .ce 9999
939 .de RD
941 .rj 9999
943 .de ds*common-end
944 .par@reset
945 .sp \\n[DD]u
947 .als ds*end!1 ds*common-end
948 .de BD
950 .nr \\n[.ev]:ds-type 2
951 .di ds*div
953 .de ds*end!2
955 .ie '\\n(.z'ds*div' \{\
956 .       di
957 .       nf
958 .       in (u;\\n[.l]-\\n[dl]/2>?0)
959 .       ds*div
960 .       rm ds*div
961 .       ds*common-end
963 .el .@error-recover mismatched DE
965 .de DS
967 .di ds*div
968 .ie '\\$1'B' \{\
969 .       LD
970 .       nr \\n[.ev]:ds-type 4
972 .el \{\
973 .       ie '\\$1'L' .LD
974 .       el \{\
975 .               ie '\\$1'C' .CD
976 .               el \{\
977 .                       ie '\\$1'R' .RD
978 .                       el \{\
979 .                               ie '\\$1'I' .ID \\$2
980 .                               el .ID \\$1
981 .                       \}
982 .               \}
983 .       \}
984 .       nr \\n[.ev]:ds-type 3
987 .de ds@need
988 .if '\\n(.z'' \{\
989 .       while \\n[.t]<=(\\$1)&(\\n[nl]>\\n[pg@header-bottom]) \{\
990 .               rs
991 '               sp \\n[.t]u
992 .       \}
995 .de ds*end!3
997 .ie '\\n(.z'ds*div' \{\
998 .       di
999 .       ds@need \\n[dn]
1000 .       ev nf
1001 .       ds*div
1002 .       ev
1003 .       rm ds*div
1004 .       ds*common-end
1006 .el .@error-recover mismatched DE
1008 .de ds*end!4
1009 .ie '\\n(.z'ds*div' \{\
1010 .       br
1011 .       di
1012 .       nf
1013 .       in (u;\\n[.l]-\\n[dl]/2>?0)
1014 .       ds@need \\n[dn]
1015 .       ds*div
1016 .       rm ds*div
1017 .       ds*common-end
1019 .el .@error-recover mismatched DE
1021 .\" ****************************
1022 .\" ******** module par ********
1023 .\" ****************************
1024 .\" Paragraph-level formatting.
1025 .\" Load time initialization.
1026 .de par@load-init
1027 .\" PS and VS might have been set on the command-line
1028 .if !rPS .nr PS 10
1029 .if !rLL .nr LL 6i
1030 .ll \\n[LL]u
1031 .\" don't set LT so that it can be defaulted from LL
1032 .ie rLT .lt \\n[LT]u
1033 .el .lt \\n[LL]u
1034 .ie (\\n[PS] >= 1000) \
1035 .       ps (\\n[PS]z / 1000u)
1036 .el \
1037 .       ps \\n[PS]
1038 .\" don't set VS so that it can be defaulted from PS
1039 .ie rVS \{\
1040 .       ie (\\n[VS] >= 1000) \
1041 .               par*vs "(\\n[VS]p / 1000u)"
1042 .       el \
1043 .               par*vs \\n[VS]
1045 .el \{\
1046 .       ie (\\n[PS] >= 1000) \
1047 .               par*vs "((\\n[PS]p / 1000u) + 2p)"
1048 .       el \
1049 .               par*vs "(\\n[PS] + 2)"
1051 .if dFAM .fam \\*[FAM]
1052 .if !rHY .nr HY 14
1053 .hy \\n[HY]
1055 .CHECK-FOOTER-AND-KEEP
1057 .de par*vs
1058 .\" If it's too big to be in points, treat it as units.
1059 .ie (p;\\$1)>=40p .vs (u;\\$1)
1060 .el .vs (p;\\$1)
1062 .de par@ab-indent
1063 .nr 0:li (u;\\n[LL]/12)
1064 .nr 0:ri \\n[0:li]
1066 .de par*env-init
1067 .aln \\n[.ev]:PS PS
1068 .aln \\n[.ev]:VS VS
1069 .aln \\n[.ev]:LL LL
1070 .aln \\n[.ev]:MCLL LL
1071 .aln \\n[.ev]:LT LT
1072 .aln \\n[.ev]:MCLT LT
1073 .aln \\n[.ev]:PI PI
1074 .aln \\n[.ev]:PD PD
1075 .ad \\n[par*adj]
1076 .par@reset-env
1078 .\" happens when the first page begins
1079 .de par@init
1080 .if !rLT .nr LT \\n[LL]
1081 .if !rFL .nr FL \\n[LL]*5/6
1082 .if !rVS \{\
1083 .       ie (\\n[PS] >= 1000) \
1084 .               nr VS (\\n[PS] + 2000)
1085 .       el \
1086 .               nr VS (\\n[PS] + 2)
1088 .if !rDI .nr DI .5i
1089 .if !rFPS \{\
1090 .       ie (\\n[PS] >= 1000) \
1091 .               nr FPS (\\n[PS] - 2000)
1092 .       el \
1093 .               nr FPS (\\n[PS] - 2)
1095 .if !rFVS \{\
1096 .       ie (\\n[FPS] >= 1000) \
1097 .               nr FVS (\\n[FPS] + 2000)
1098 .       el \
1099 .               nr FVS (\\n[FPS] + 2)
1101 .\" don't change environment 0
1102 .ev h
1103 .ie (\\n[PS] >= 1000) \
1104 .       ps (\\n[PS]z / 1000u)
1105 .el \
1106 .       ps \\n[PS]
1107 .if !rQI .nr QI 5n
1108 .if !rPI .nr PI 5n
1109 .ie (\\n[VS] >= 1000) \
1110 .       par*vs "(\\n[VS]p / 1000u)"
1111 .el \
1112 .       par*vs \\n[VS]
1113 .if !rPD .nr PD .3v>?\n(.V
1114 .if !rDD .nr DD .5v>?\n(.V
1115 .if !rFI .nr FI 2n
1116 .if !rFPD .nr FPD \\n[PD]/2
1118 .if !dFAM .ds FAM \\n[.fam]
1119 .nr par*adj \\n[.j]
1120 .par*env-init
1121 .ev h
1122 .par*env-init
1124 .ev fn
1125 .par*env-init
1127 .ev k
1128 .par*env-init
1130 .aln 0:MCLL pg@colw
1131 .aln 0:MCLT pg@colw
1132 .aln k:MCLL pg@colw
1133 .aln k:MCLT pg@colw
1134 .aln fn:PS FPS
1135 .aln fn:VS FVS
1136 .aln fn:LL FL
1137 .aln fn:LT FL
1138 .aln fn:PI FI
1139 .aln fn:PD FPD
1140 .aln fn:MCLL pg@fn-colw
1141 .aln fn:MCLT pg@fn-colw
1143 .de par@reset-env
1144 .nr \\n[.ev]:il 0
1145 .nr \\n[.ev]:li 0
1146 .nr \\n[.ev]:ri 0
1147 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1148 .nr \\n[.ev]:pli 0
1149 .nr \\n[.ev]:pri 0
1150 .nr \\n[.ev]:ds-type 0
1152 .\" par@reset
1153 .de par@reset
1155 .if \\n[need_eo_tl]>0 .DEVTAG-EO-TL
1156 .nr need_eo_tl 0
1157 .if \\n[need_eo_h]>0 .DEVTAG-EO-H
1158 .nr need_eo_h 0
1159 .ce 0
1160 .rj 0
1161 .ul 0
1163 .ie \\n[pg@ncols]>1 \{\
1164 .       ll (u;\\n[\\n[.ev]:MCLL]-\\n[\\n[.ev]:ri]-\\n[\\n[.ev]:pri])
1165 .       lt \\n[\\n[.ev]:MCLT]u
1167 .el \{\
1168 .       ll (u;\\n[\\n[.ev]:LL]-\\n[\\n[.ev]:ri]-\\n[\\n[.ev]:pri])
1169 .       lt \\n[\\n[.ev]:LT]u
1171 .in (u;\\n[\\n[.ev]:li]+\\n[\\n[.ev]:pli])
1172 .ft 1
1173 .fam \\*[FAM]
1174 .ie (\\n[\\n[.ev]:PS] >= 1000) \
1175 .       ps (\\n[\\n[.ev]:PS]z / 1000u)
1176 .el \
1177 .       ps \\n[\\n[.ev]:PS]
1178 .ie (\\n[\\n[.ev]:VS] >= 1000) \
1179 .       par*vs "(\\n[\\n[.ev]:VS]p / 1000u)"
1180 .el \
1181 .       par*vs \\n[\\n[.ev]:VS]
1182 .ls 1
1184 .hy \\n[HY]
1186 .de @RT
1187 .nr \\n[.ev]:pli 0
1188 .nr \\n[.ev]:pri 0
1189 .par@reset
1191 .\" This can be redefined by the user.
1192 .de TA
1193 .ta T 5n
1195 .\" \n[PORPHANS] sets number of initial lines of any paragraph,
1196 .\" which must be kept together, without any included page break.
1197 .\" Initialise to reproduce original behaviour; user may adjust it.
1198 .if !rPORPHANS .nr PORPHANS 1
1200 .de par*start
1201 .ds@auto-end
1202 .nr \\n[.ev]:pli \\$1
1203 .nr \\n[.ev]:pri \\$2
1204 .par@reset
1205 .sp \\n[\\n[.ev]:PD]u
1206 .ne \\n[PORPHANS]v+\\n(.Vu
1208 .de par@finish
1209 .nr \\n[.ev]:pli 0
1210 .nr \\n[.ev]:pri 0
1211 .par@reset
1213 .\" normal LP
1214 .de @LP
1215 .par*start 0 0
1216 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1218 .de @PP
1219 .par*start 0 0
1220 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1221 .if !'\*(.T'html' .ti +\\n[\\n[.ev]:ai]u
1223 .de @QP
1224 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1225 .par*start \\n[QI] \\n[QI]
1227 .de @XP
1228 .par*start \\n[\\n[.ev]:PI] 0
1229 .ti -\\n[\\n[.ev]:PI]u
1231 .de @IP
1232 .if \\n[.$]>1 .nr \\n[.ev]:ai (n;\\$2)
1233 .par*start \\n[\\n[.ev]:ai] 0
1234 .if !'\\$1'' \{\
1235 .       \" Divert the label so as to freeze any spaces.
1236 .       di par*label
1237 .       par*push-tag-env
1238 \&\\$1
1239 .       par*pop-tag-env
1240 .       di
1241 .       chop par*label
1242 .       ti -\\n[\\n[.ev]:ai]u
1243 .       ie \\n[dl]+1n<=\\n[\\n[.ev]:ai] \{\
1244 .               DEVTAG-COL 1
1245 \\*[par*label]\h'|\\n[\\n[.ev]:ai]u'\c
1246 .               DEVTAG-COL 2
1247 .       \}
1248 .       el \{\
1249 .               DEVTAG-COL 1
1250 \\*[par*label]
1251 .               DEVTAG-COL-NEXT 2
1252 .               br
1253 .       \}
1254 .       rm par*label
1257 .\" We don't want margin characters to be attached when we divert
1258 .\" the tag.  Since there's no way to save and restore the current
1259 .\" margin character, we have to switch to a new environment, taking
1260 .\" what we need of the old environment with us.
1261 .de par*push-tag-env
1262 .nr par*saved-font \\n[.f]
1263 .nr par*saved-size \\n[.s]z
1264 .nr par*saved-ss \\n[.ss]
1265 .ds par*saved-fam \\n[.fam]
1266 .ev par
1269 .ft \\n[par*saved-font]
1270 .ps \\n[par*saved-size]u
1271 .ss \\n[par*saved-ss]
1272 .fam \\*[par*saved-fam]
1274 .de par*pop-tag-env
1277 .de @RS
1279 .nr \\n[.ev]:li!\\n[\\n[.ev]:il] \\n[\\n[.ev]:li]
1280 .nr \\n[.ev]:ri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ri]
1281 .nr \\n[.ev]:ai!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ai]
1282 .nr \\n[.ev]:pli!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pli]
1283 .nr \\n[.ev]:pri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pri]
1284 .nr \\n[.ev]:il +1
1285 .nr \\n[.ev]:li +\\n[\\n[.ev]:ai]
1286 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1287 .par@reset
1289 .de @RE
1291 .ie \\n[\\n[.ev]:il] \{\
1292 .       nr \\n[.ev]:il -1
1293 .       nr \\n[.ev]:ai \\n[\\n[.ev]:ai!\\n[\\n[.ev]:il]]
1294 .       nr \\n[.ev]:li \\n[\\n[.ev]:li!\\n[\\n[.ev]:il]]
1295 .       nr \\n[.ev]:ri \\n[\\n[.ev]:ri!\\n[\\n[.ev]:il]]
1296 .       nr \\n[.ev]:pli \\n[\\n[.ev]:pli!\\n[\\n[.ev]:il]]
1297 .       nr \\n[.ev]:pri \\n[\\n[.ev]:pri!\\n[\\n[.ev]:il]]
1299 .el .@error unbalanced \\$0
1300 .par@reset
1302 .de @QS
1304 .nr \\n[.ev]:li!\\n[\\n[.ev]:il] \\n[\\n[.ev]:li]
1305 .nr \\n[.ev]:ri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ri]
1306 .nr \\n[.ev]:ai!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ai]
1307 .nr \\n[.ev]:pli!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pli]
1308 .nr \\n[.ev]:pri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pri]
1309 .nr \\n[.ev]:il +1
1310 .nr \\n[.ev]:li +\\n[QI]
1311 .nr \\n[.ev]:ri +\\n[QI]
1312 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1313 .par@reset
1315 .als @QE @RE
1316 .\" start boxed text
1317 .de B1
1319 .HTML-IMAGE
1320 .di par*box-div
1321 .nr \\n[.ev]:li +1n
1322 .nr \\n[.ev]:ri +1n
1323 .nr par*box-in \\n[.in]
1324 .\" remember what 1n is, just in case the point size changes
1325 .nr par*box-n 1n
1326 .in +1n
1327 .ll -1n
1328 .lt -1n
1329 .ti \\n[par*box-in]u+1n
1331 .de @div-end!par*box-div
1334 .\" end boxed text
1335 .\" Postpone the drawing of the box until we're in the top-level diversion,
1336 .\" in case there's a footnote inside the box.
1337 .de B2
1338 .ie '\\n(.z'par*box-div' \{\
1339 .       br
1340 .       if \n[.V]>.25m .sp
1341 .       di
1342 .       if \n[.V]>.25m .sp
1343 .       ds@need \\n[dn]
1344 .       par*box-mark-top
1345 .       ev nf
1346 .       par*box-div
1347 .       ev
1348 .       nr \\n[.ev]:ri -\\n[par*box-n]
1349 .       nr \\n[.ev]:li -\\n[par*box-n]
1350 .       in -\\n[par*box-n]u
1351 .       ll +\\n[par*box-n]u
1352 .       lt +\\n[par*box-n]u
1353 .       par*box-draw \\n[.i]u \\n[.l]u-(\\n[.H]u==1n*1n)
1355 .el .@error B2 without B1
1356 .HTML-IMAGE-END
1358 .de par*box-mark-top
1359 .ie '\\n[.z]'' \{\
1360 .       rs
1361 .       mk par*box-top
1363 .el \!.par*box-mark-top
1365 .de par*box-draw
1366 .ie '\\n[.z]'' \{\
1367 .       nr par*box-in \\n[.i]
1368 .       nr par*box-ll \\n[.l]
1369 .       nr par*box-vpt \\n[.vpt]
1370 .       nr par*box-ad \\n[.j]
1371 .       ad l
1372 .       vpt 0
1373 .       in \\$1
1374 .       ll \\$2
1375 \v'-1v+.25m'\
1376 \D'l (u;\\n[.l]-\\n[.i]) 0'\
1377 \D'l 0 |\\n[par*box-top]u'\
1378 \D'l -(u;\\n[.l]-\\n[.i]) 0'\
1379 \D'l 0 -|\\n[par*box-top]u'
1380 .       br
1381 .       sp -1
1382 .       in \\n[par*box-in]u
1383 .       ll \\n[par*box-ll]u
1384 .       vpt \\n[par*box-vpt]
1385 .       ad \\n[par*box-ad]
1387 .el \!.par*box-draw \\$1 \\$2
1389 .\" \n[HORPHANS] sets how many lines of the following paragraph must be
1390 .\" kept together, with a preceding section header.  Initialise it,
1391 .\" to reproduce original behaviour; user may change it.
1392 .if !rHORPHANS .nr HORPHANS 1
1394 .\" \n[GROWPS] and \n[PSINCR] cause auto-increment of header point size.
1395 .\" Initialise them, so they have no effect, unless explicitly set by the user.
1396 .if !rGROWPS .nr GROWPS 0
1397 .if !rPSINCR .nr PSINCR 1p
1399 .de SH-NO-TAG
1400 .par@finish
1401 .\" Keep the heading and the first few lines of the next paragraph together.
1402 .\" (\n[HORPHANS] defines "first few" -- default = 1; user may redefine it).
1403 .nr sh*minvs \\n[HORPHANS]v
1404 .if \\n[sh*psincr]<0 .nr sh*psincr 0
1405 .ie \\n(VS<1000 .par*vs \\n(VSp+\\n[sh*psincr]u
1406 .el .par*vs \\n(VSp/1000u+\\n[sh*psincr]u
1407 .ne 2v+\\n[sh*minvs]u+\\n[\\n[.ev]:PD]u+\\n(.Vu
1408 .\" Adjust point size for heading text, as specified by \n[GROWPS] and \n[PSINCR].
1409 .ie \\n(PS<1000 .ps \\n(PS+\\n[sh*psincr]u
1410 .el .ps \\n(PSz/1000u+\\n[sh*psincr]u
1411 .sp 1
1412 .ft B
1414 .de @SH
1415 .\" Standard ms implementation does not expect an argument,
1416 .\" but allow ".SH n" to make heading point size match ".NH n",
1417 .\" for same "n", when \n[GROWPS] and \n[PSINCR] are set.
1418 .  nr sh*psincr 0
1419 .  if 0\\$1>0 .nr sh*psincr (\\n[GROWPS]-0\\$1)*\\n[PSINCR]
1420 .  SH-NO-TAG
1421 .  DEVTAG-SH 1
1422 .  if '\*(.T'html' .nr need_eo_h 1
1424 .\" TL, AU, and AI are aliased to these in cov*ab-init.
1425 .de par@TL
1426 .par@finish
1427 .sp 1
1428 .ft B
1429 .ps +2
1430 .vs +3p
1431 .ce 9999
1432 .DEVTAG-TL
1433 .nr need_eo_tl 1
1435 .de par@AU
1436 .par@finish
1437 .sp 1
1438 .ft I
1439 .ce 9999
1441 .de par@AI
1442 .par@finish
1443 .sp .5
1444 .ce 9999
1446 .\" In paragraph macros.
1447 .de NL
1448 .ie (\\n[\\n[.ev]:PS] >= 1000) \
1449 .       ps (\\n[\\n[.ev]:PS]z / 1000u)
1450 .el \
1451 .       ps \\n[\\n[.ev]:PS]
1453 .de SM
1454 .ps -2
1456 .de LG
1457 .ps +2
1459 .de R
1460 .ft R
1462 .\" par*define-font-macro macro font
1463 .de par*define-font-macro
1464 .de \\$1
1465 .ie \En[.$] \{\
1466 .       nr par*prev-font \En[.f]
1467 \&\E$3\f[\\$2]\E$1\f[\En[par*prev-font]]\E$2
1469 .el .ft \\$2
1470 \\..
1472 .par*define-font-macro B B
1473 .par*define-font-macro I I
1474 .par*define-font-macro BI BI
1475 .par*define-font-macro CW CR
1476 .\" underline a word
1477 .de UL
1478 \Z'\\$1'\v'.25m'\D'l \w'\\$1'u 0'\v'-.25m'\\$2
1480 .\" box a word
1481 .de BX
1482 .nr par*bxw \w'\\$1'+.4m
1483 \Z'\v'.25m'\D'l 0 -1m'\D'l \\n[par*bxw]u 0'\D'l 0 1m'\D'l -\\n[par*bxw]u 0''\
1484 \Z'\h'.2m'\\$1'\
1485 \h'\\n[par*bxw]u'
1487 .\" The first time UX is used, put a registered mark after it.
1488 .ds par*ux-rg \(rg
1489 .de UX
1490 \s[\\n[.s]*8u/10u]UNIX\s0\\$1\\*[par*ux-rg]
1491 .ds par*ux-rg
1493 .ds par@sup-start \v'-.9m\s'\En[.s]*7u/10u'+.7m'
1494 .als { par@sup-start
1495 .ds par@sup-end \v'-.7m\s0+.9m'
1496 .als } par@sup-end
1497 .\" footnote paragraphs
1498 .\" FF is the footnote format
1499 .nr FF 0
1500 .\" This can be redefined. It gets a second argument of `no' if the first
1501 .\" argument was supplied by the user, rather than automatically.
1502 .de FP
1504 .if !d par*fp!\\n[FF] \{\
1505 .       @error unknown footnote format `\\n[FF]'
1506 .       nr FF 0
1508 .ie '\\$2'no' .par*fp!\\n[FF]-no "\\$1"
1509 .el .par*fp!\\n[FF] "\\$1"
1511 .de par*fp!0
1512 .@PP
1513 \&\\*[par@sup-start]\\$1\\*[par@sup-end]\ \c
1515 .de par*fp!0-no
1516 .@PP
1517 \&\\$1\ \c
1519 .de par*fp!1
1520 .@PP
1521 \&\\$1.\ \c
1523 .de par*fp!1-no
1524 .@PP
1525 \&\\$1\ \c
1527 .de par*fp!2
1528 .@LP
1529 \&\\$1.\ \c
1531 .de par*fp!2-no
1532 .@LP
1533 \&\\$1\ \c
1535 .de par*fp!3
1536 .@IP "\\$1." (u;\\n[\\n[.ev]:PI]*2)
1538 .de par*fp!3-no
1539 .@IP "\\$1" (u;\\n[\\n[.ev]:PI]*2)
1541 .\" ***************************
1542 .\" ******** module nh ********
1543 .\" ***************************
1544 .\" Numbered headings.
1545 .\" nh*hl is the level of the last heading
1546 .nr nh*hl 0
1547 .\" SN-DOT and SN-NO-DOT represent the section number of
1548 .\" the current heading, with and without a terminating dot.
1549 .ds SN-DOT
1550 .ds SN-NO-DOT
1551 .\" SN-STYLE sets the statement numbering style used in headings
1552 .\" (either SN-DOT or SN-NO-DOT); for backward compatibility with
1553 .\" earlier ms versions, the default is SN-DOT
1554 .als SN-STYLE SN-DOT
1555 .\" Also for backward compatibility, let SN represent SN-DOT.
1556 .als SN SN-DOT
1557 .\" numbered heading
1558 .de @NH
1559 .ie '\\$1'S' \{\
1560 .       shift
1561 .       nr nh*hl 0
1562 .       while \\n[.$] \{\
1563 .               nr nh*hl +1
1564 .               nr H\\n[nh*hl] 0\\$1
1565 .               shift
1566 .       \}
1567 .       if !\\n[nh*hl] \{\
1568 .               nr H1 1
1569 .               nr nh*hl 1
1570 .               @error missing arguments to .NH S
1571 .       \}
1573 .el \{\
1574 .       nr nh*ohl \\n[nh*hl]
1575 .       ie \\n[.$] \{\
1576 .               nr nh*hl 0\\$1
1577 .               ie \\n[nh*hl]<=0 \{\
1578 .                       nr nh*ohl 0
1579 .                       nr nh*hl 1
1580 .               \}
1581 .               el \{\
1582 .                       if \\n[nh*hl]-\\n[nh*ohl]>1 \
1583 .                               @warning .NH \\n[nh*ohl] followed by .NH \\n[nh*hl]
1584 .               \}
1585 .       \}
1586 .       el .nr nh*hl 1
1587 .       while \\n[nh*hl]>\\n[nh*ohl] \{\
1588 .               nr nh*ohl +1
1589 .               nr H\\n[nh*ohl] 0
1590 .       \}
1591 .       nr H\\n[nh*hl] +1
1593 .ds SN-NO-DOT \\n(H1
1594 .nr nh*i 1
1595 .while \\n[nh*i]<\\n[nh*hl] \{\
1596 .       nr nh*i +1
1597 .       as SN-NO-DOT .\\n[H\\n[nh*i]]
1599 .ds SN-DOT \\*[SN-NO-DOT].
1600 .nr sh*psincr (\\n[GROWPS]-\\n[nh*hl])*\\n[PSINCR]
1601 .SH-NO-TAG
1602 .DEVTAG-NH "\\$1"
1603 .  if '\*(.T'html' .nr need_eo_h 1
1604 \\*[SN-STYLE]
1606 .\" ****************************
1607 .\" ******** module toc ********
1608 .\" ****************************
1609 .\" Table of contents generation.
1610 .de @XS
1611 .da toc*div
1612 .ev h
1613 .ie \\n[.$] .XA "\\$1"
1614 .el .XA
1616 .de @div-end!toc*div
1619 .de XA
1620 .ie '\\n(.z'toc*div' \{\
1621 .       if d toc*num .toc*end-entry
1622 .       ie \\n[.$] \{\
1623 .               ie '\\$1'no' .ds toc*num
1624 .               el .ds toc*num "\\$1
1625 .       \}
1626 .       el .ds toc*num \\n[PN]
1627 .       br
1628 .       par@reset
1629 .       na
1630 .       ll -8n
1631 .       in (n;0\\$2)
1633 .el .@error XA without XS
1635 .de XE
1636 .ie '\\n(.z'toc*div' \{\
1637 .       if d toc*num .toc*end-entry
1638 .       ev
1639 .       di
1641 .el .@error XE without XS
1643 .de toc*end-entry
1644 \\a\\t\\*[toc*num]
1646 .rm toc*num
1648 .de PX
1650 .if !'\\$1'no' \{\
1651 .       ce 1
1652 .       ie (\\n[PS] >= 1000) \
1653 .               ps ((\\n[PS]z / 1000u) + 2z)
1654 .       el \
1655 .               ps \\n[PS]+2
1656 .       ft B
1657 \\*[TOC]
1658 .       ft
1659 .       ps
1662 .char \[toc*leader-char] .\h'1m'
1663 .lc \[toc*leader-char]
1664 .ta (u;\\n[.l]-\\n[.i]-\w'000') (u;\\n[.l]-\\n[.i])R
1665 .sp 2
1666 .toc*div
1667 .par@reset
1669 .\" print the table of contents on page i
1670 .de TC
1672 .pg@begin 1 i
1673 .PX \\$1
1675 .\" ****************************
1676 .\" ******** module eqn ********
1677 .\" ****************************
1678 .\" Eqn support.
1679 .de EQ
1681 .de EN
1683 .de @EQ
1685 .ds eqn*num "\\$2
1686 .ie '\\$1'L' .nr eqn*type 0
1687 .el \{\
1688 .       ie '\\$1'I' .nr eqn*type 1
1689 .       el \{\
1690 .               nr eqn*type 2
1691 .               if !'\\$1'C' .ds eqn*num "\\$1
1692 .       \}
1694 .di eqn*div
1695 .in 0
1696 .if \\n[eqn*type]=0 .EQN-HTML-IMAGE-LEFT
1697 .if \\n[eqn*type]=1 \{\
1698 .   if '\*(.T'html' .RS
1699 .EQN-HTML-IMAGE-INLINE
1701 .if \\n[eqn*type]=2 .EQN-HTML-IMAGE
1704 .de @div-end!eqn*div
1705 .@EN
1707 .\" Note that geqn mark and lineup work correctly in centered equations.
1708 .de @EN
1709 .ie !'\\n(.z'eqn*div' .@error-recover mismatched EN
1710 .el \{\
1711 .       br
1712 .       di
1713 .       nr eqn*have-num 0
1714 .       if !'\\*[eqn*num]'' .nr eqn*have-num 1
1715 .       ie \\n[dl]:\\n[eqn*have-num] \{\
1716 .               sp \\n[DD]u
1717 .               par@reset
1718 .               ds eqn*tabs \\n[.tabs]
1719 .               nf
1720 .               ie \\n[dl] \{\
1721 .\"                     --fixme-- this really should not be necessary
1722 .\"                     and indicates that there is extra space creeping into
1723 .\"                     an equation when ps4html is enabled..
1724 .                       ie r ps4html .ds@need \\n[dn]u-1v+\n[.V]u+1i
1725 .                       el .ds@need \\n[dn]u-1v+\n[.V]u
1726 .                       chop eqn*div
1727 .                       ie \\n[eqn*type]=0 \{\
1728 .                               ta (u;\\n[.l]-\\n[.i])R
1729 \\*[eqn*div]\t\\*[eqn*num]
1730 .                       \}
1731 .                       el \{\
1732 .                               ie \\n[eqn*type]=1 .ta \\n[DI]u \
1733 (u;\\n[.l]-\\n[.i])R
1734 .                               el .ta (u;\\n[.l]-\\n[.i]/2)C \
1735 (u;\\n[.l]-\\n[.i])R
1736 \t\\*[eqn*div]\t\\*[eqn*num]
1737 .                       \}
1738 .               \}
1739 .               el \{\
1740 .                       ta (u;\\n[.l]-\\n[.i])R
1741 \t\\*[eqn*num]
1742 .               \}
1743 .\".            if !'\*(.T'html' .sp \\n[DD]u
1744 .               sp \\n[DD]u
1745 .               ta \\*[eqn*tabs]
1746 .       \}
1747 .       el \{
1748 .\" must terminate empty equations in html and ps4html as they contain
1749 .\" the EQN-HTML-IMAGE-END suppression nodes
1750 .               if \\n[dl] .chop eqn*div
1751 .               if '\*(.T'html' \\*[eqn*div]
1752 .               if r ps4html    \\*[eqn*div]
1753 .       \}
1754 .       if !'\*(.T'html' .fi
1755 .       if \\n[eqn*type]=0 .EQN-HTML-IMAGE-END
1756 .       if \\n[eqn*type]=1 \{\
1757 .               EQN-HTML-IMAGE-END
1758 .               if '\*(.T'html' .RE
1759 .       \}
1760 .       if \\n[eqn*type]=2 .EQN-HTML-IMAGE-END
1764 .\" ****************************
1765 .\" ******** module tbl ********
1766 .\" ****************************
1767 .\" Tbl support.
1768 .nr tbl*have-header 0
1769 .\" This gets called if TS occurs before the first paragraph.
1770 .de TS
1772 .\" cov*ab-init aliases TS to @TS
1773 \\*[TS]\\
1775 .de @TS
1776 .sp \\n[DD]u
1777 .if '\\$1'H' .di tbl*header-div
1778 .HTML-IMAGE
1780 .de tbl@top-hook
1781 .if \\n[tbl*have-header] \{\
1782 .       ie \\n[.t]-\\n[tbl*header-ht]-1v .tbl*print-header
1783 .       el .sp \\n[.t]u
1786 .de tbl*print-header
1787 .ev nf
1788 .tbl*header-div
1790 .mk #T
1792 .de TH
1793 .ie '\\n[.z]'tbl*header-div' \{\
1794 .       nr T. 0
1795 .       T#
1796 .       br
1797 .       di
1798 .       ie \\n[dn]+\\n[FM]+\\n[HM]+2v>=\\n[.p] \{\
1799 .               @error ridiculously long table header
1800 .               ds@need \\n[dn]
1801 .               tbl*print-header
1802 .       \}
1803 .       el \{\
1804 .               nr tbl*header-ht \\n[dn]
1805 .               ds@need \\n[dn]u+1v
1806 .               tbl*print-header
1807 .               nr tbl*have-header 1
1808 .       \}
1810 .el .@error-recover .TH without .TS H
1812 .de @div-end!tbl*header-div
1816 .de TE
1817 .ie '\\n(.z'tbl*header-div' .@error-recover .TS H but no .TH before .TE
1818 .el \{\
1819 .       nr tbl*have-header 0
1820 .       if !'\*(.T'html' .sp \\n[DD]u
1822 .HTML-IMAGE-END
1823 .\" reset tabs
1826 .de tbl@bottom-hook
1827 .if \\n[tbl*have-header] \{\
1828 .       nr T. 1
1829 .       T#
1832 .de T&
1834 .\" ****************************
1835 .\" ******** module pic ********
1836 .\" ****************************
1837 .\" Pic support.
1838 .\" PS height width
1839 .de PS
1841 .sp \\n[DD]u
1842 .ie \\n[.$]<2 .@error bad arguments to PS (not preprocessed with pic?)
1843 .el \{\
1844 .       ds@need (u;\\$1)+1v
1845 .       in +(u;\\n[.l]-\\n[.i]-\\$2/2>?0)
1847 .HTML-IMAGE
1849 .de PE
1850 .HTML-IMAGE-END
1851 .par@reset
1852 .sp \\n[DD]u+.5m
1854 .\" ****************************
1855 .\" ******** module ref ********
1856 .\" ****************************
1857 .\" Refer support.
1858 .de ]-
1859 .rm [A [B [C [D [E [G [I [J [N [O [P [Q [R [S [T [V
1860 .rm ref*string
1862 .\" Other
1863 .ds ref*spec!0 Q A T1 S V N P I C D O
1864 .\" Journal article
1865 .ds ref*spec!1 Q A T2 J S V N P I C D O
1866 .\" Book
1867 .ds ref*spec!2 Q A T1 S V P I C D O
1868 .\" Article within book
1869 .ds ref*spec!3 Q A T2 B E S V P I C D O
1870 .\" Tech report
1871 .ds ref*spec!4 Q A T2 R G P I C D O
1872 .\" ][ type
1873 .de ][
1874 .if r [T \{\
1875 .       als [T1 [T
1876 .       als [T2 [T
1878 .ie d ref*spec!\\$1 .ref*build \\*[ref*spec!\\$1]
1879 .el \{\
1880 .       @error unknown reference type `\\$1'
1881 .       ref*build \\*[ref*spec!0]
1883 .ref*print
1884 .rm ref*string
1885 .rm [F [T1 [T2
1887 .\" start of reference number
1888 .ds [. \E*[par@sup-start]
1889 .\" end of reference number
1890 .ds .] \E*[par@sup-end]
1891 .\" period before reference
1892 .ds <. .
1893 .\" period after reference
1894 .ds >. \" empty
1895 .\" comma before reference
1896 .ds <, ,
1897 .\" comma after reference
1898 .ds >, \" empty
1899 .\" start collected references
1900 .de ]<
1901 .als ref*print ref*end-print
1903 \&\\*[REFERENCES]
1904 .par@reset
1906 .\" end collected references
1907 .de ]>
1908 .par@finish
1909 .als ref*print ref*normal-print
1911 .de ref*normal-print
1912 .ie d [F .FS "\\*([.\\*([F\\*(.]"
1913 .el .FS \&
1914 \\*[ref*string]
1917 .de ref*end-print
1918 .ie d [F .IP "\\*([F."
1919 .el .XP
1920 \\*[ref*string]
1922 .als ref*print ref*normal-print
1923 .de ref*build
1924 .rm ref*string ref*post-punct
1925 .nr ref*suppress-period 1
1926 .while \\n[.$] \{\
1927 .       if d [\\$1 \{\
1928 .               ie d ref*add-\\$1 .ref*add-\\$1
1929 .               el .ref*add-dflt \\$1
1930 .       \}
1931 .       shift
1933 .\" now add a final period
1934 .ie d ref*string \{\
1935 .       if !\\n[ref*suppress-period] .as ref*string .
1936 .       if d ref*post-punct \{\
1937 .               as ref*string "\\*[ref*post-punct]
1938 .               rm ref*post-punct
1939 .       \}
1941 .el .ds ref*string
1943 .de ref*add-T1
1944 .ref*field T , " " "\fI" "" "\fP"
1945 .if r [T .nr ref*suppress-period \\n([T
1947 .de ref*add-T2
1948 .ref*field T , " " "\\*Q" "" "\\*U"
1949 .if r [T .nr ref*suppress-period \\n([T
1951 .de ref*add-P
1952 .ie \\n([P>0 .ref*field P , " " "pp. "
1953 .el .ref*field P , " " "p. "
1955 .de ref*add-J
1956 .ref*field J , " " \fI "" \fP
1958 .de ref*add-D
1959 .ref*field D "" " " ( )
1961 .de ref*add-E
1962 .ref*field E , " " "ed. "
1964 .de ref*add-G
1965 .ref*field G "" " " ( )
1967 .de ref*add-B
1968 .ref*field B "" " " "in \fI" "" \fP
1970 .de ref*add-O
1971 .ref*field O . " "
1972 .ie r [O .nr ref*suppress-period \\n([O
1973 .el .nr ref*suppress-period 1
1975 .de ref*add-A
1976 .ref*field A , " "
1977 .if r [A .nr ref*suppress-period \\n([A
1979 .de ref*add-V
1980 .ref*field V "" " " \fB \fR
1982 .de ref*add-N
1983 .ref*field N "" ( "" ")"
1985 .de ref*add-dflt
1986 .ref*field \\$1 , " "
1988 .\" First argument is the field letter.
1989 .\" Second argument is the punctuation character to use to separate this field
1990 .\" from the previous field.
1991 .\" Third argument is a string to insert after the punctuation character of
1992 .\" the previous field (normally a space)
1993 .\" Fourth argument is a string with which to prefix this field.
1994 .\" Fifth argument is a string with which to postfix this field.
1995 .\" Sixth argument is a string to add after the punctuation character supplied
1996 .\" by the next field.
1997 .de ref*field
1998 .if d ref*string \{\
1999 .       ie d ref*post-punct \{\
2000 .               as ref*string "\\$2\\*[ref*post-punct]\\$3\"
2001 .               rm ref*post-punct
2002 .       \}
2003 .       el .as ref*string "\\$2\\$3\"
2005 .as ref*string "\\$4\\*([\\$1\\$5
2006 .if \\n[.$]>5 .ds ref*post-punct "\\$6
2007 .nr ref*suppress-period 0
2009 .\" ****************************
2010 .\" ******** module acc ********
2011 .\" ****************************
2012 .\" Accents and special characters.
2013 .ds Q \(lq
2014 .ds U \(rq
2015 .ds - \(em
2016 .\" Characters
2017 .\" The idea of this definition is for the top of the 3 to be at the x-height.
2018 .if !c\[yogh] .char \[yogh] \Z'\v'\w'x'*0-\En[rst]u'\s[\En[.s]*8u/10u]\
2019 \v'\w'3'*0+\En[rst]u'3\s0'\h'\w'\s[\En[.s]*8u/10u]3'u'
2020 .\" Accents
2021 .de acc*over-def
2022 .ds \\$1 \Z'\v'(u;\w'x'*0+\En[rst]-\En[.cht])'\
2023 \h'(u;-\En[skw]+(-\En[.w]-\w'\\$2'/2)+\En[.csk])'\\$2'
2025 .de acc*under-def
2026 .ds \\$1 \Z'\v'\En[.cdp]u'\h'(u;-\En[.w]-\w'\\$2'/2)'\\$2'
2028 .de acc*slash-def
2029 .ds \\$1 \Z'\h'(u;-\En[.w]-\w'\\$2'/2)'\
2030 \v'(u;\En[.cdp]-\En[.cht]+\En[rst]+\En[rsb]/2)'\\$2'
2032 .de acc*prefix-def
2033 .ds \\$1 \Z'\h'(u;\w'x'-\w'\\$2'/2)'\\$2'
2035 .acc*prefix-def ' \'
2036 .acc*prefix-def ` \`
2037 .acc*prefix-def ^ ^
2038 .acc*prefix-def , \(ac
2039 .acc*prefix-def : \(ad
2040 .acc*prefix-def ~ ~
2041 .\" improved accent marks
2042 .de AM
2043 .acc*over-def ' \'
2044 .acc*over-def ` \`
2045 .acc*over-def ^ ^
2046 .acc*over-def ~ ~
2047 .acc*over-def : \(ad
2048 .acc*over-def v \(ah
2049 .acc*over-def _ \(a-
2050 .acc*over-def o \(ao
2051 .acc*under-def , \(ac
2052 .acc*under-def . \s[\En[.s]*8u/10u]\v'.2m'.\v'-.2m'\s0
2053 .acc*under-def hook \(ho
2054 .acc*slash-def / /
2055 .char \[hooko] o\E*[hook]
2056 .ds q \[hooko]
2057 .ds 3 \[yogh]
2058 .ds D- \(-D\"                   Icelandic uppercase eth
2059 .ds d- \(Sd\"                   Icelandic lowercase eth
2060 .ds Th \(TP\"                   Icelandic uppercase thorn
2061 .ds th \(Tp\"                   Icelandic lowercase thorn
2062 .ds 8 \(ss\"                    German double s
2063 .ds Ae \(AE\"                   AE ligature
2064 .ds ae \(ae\"                   ae ligature
2065 .ds Oe \(OE\"                   OE ligature
2066 .ds oe \(oe\"                   oe ligature
2067 .ds ? \(r?\"                    upside down ?
2068 .ds ! \(r!\"                    upside down !
2070 .de CHECK-FOOTER-AND-KEEP
2071 .if '\*(.T'html' \{\
2072 .   rm KF
2073 .   als KF KS
2075 .   rm FS
2076 .   de FS
2077 .      sp
2078 .      HTML-NS <cite>
2079 \\..
2080 .   rm FE
2081 .   de FE
2082 .      HTML-NS </cite>
2083 .      sp
2084 \\..
2087 .par@load-init
2088 .\" ****************************
2089 .\" ******** module bell ********
2090 .\" ****************************
2091 .\" Emulate Bell Labs localisms. Note, (a) they're not documented, and
2092 .\" (b) the .P1 and .UC macros collide with different ones in Berkeley ms.
2093 .\" We hack around this by conditionalizing the behavior of P1; UC was
2094 .\" not defined by groff and will be a no-op if called Berkeley style
2095 .\" with no arguments, so there is no problem with hijacking it here.
2097 .\" What's done here is sufficient to give back the Guide to EQN (1976) its
2098 .\" section headings and restore some text that had gone missing as macro
2099 .\" arguments; no warranty express or implied is given as to how well the
2100 .\" typographic details these produce match the original Bell Labs macros.
2102 .\" P1 is now defined in module pg.
2103 .de SC
2104 .nr bell_localisms 1
2106 \\$*
2108 .de UC
2109 .if r bell_localisms \f(CW\\$*\fP
2111 .de P2
2112 .if r bell_localisms \{\
2113 .       ft
2114 .       DE
2117 .\" s-ts-mode