Merge branch 'topic/sync-to-go-2'
[s-roff.git] / tmac / s.tmac
blob66b7d5aea6e39069c1fae3dd8a565e2457c638b4
1 .ig
2 @ s.tmac
4 Copyright (c) 2014 - 2017 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
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 .als @RT par@finish
1187 .de par@adjspace
1188 .sp \\n[\\n[.ev]:PD]u
1189 .ne \\n[PORPHANS]v+\\n(.Vu
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 .par@adjspace
1207 .de par@finish
1208 .nr \\n[.ev]:pli 0
1209 .nr \\n[.ev]:pri 0
1210 .par@reset
1212 .\" normal LP
1213 .de @LP
1214 .par*start 0 0
1215 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1217 .de @PP
1218 .par*start 0 0
1219 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1220 .if !'\*(.T'html' .ti +\\n[\\n[.ev]:ai]u
1222 .de @QP
1223 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1224 .par*start \\n[QI] \\n[QI]
1226 .de @XP
1227 .par*start \\n[\\n[.ev]:PI] 0
1228 .ti -\\n[\\n[.ev]:PI]u
1230 .de @IP
1231 .if \\n[.$]>1 .nr \\n[.ev]:ai (n;\\$2)
1232 .par*start \\n[\\n[.ev]:ai] 0
1233 .if !'\\$1'' \{\
1234 .       \" Divert the label so as to freeze any spaces.
1235 .       di par*label
1236 .       par*push-tag-env
1237 \&\\$1
1238 .       par*pop-tag-env
1239 .       di
1240 .       chop par*label
1241 .       ti -\\n[\\n[.ev]:ai]u
1242 .       ie \\n[dl]+1n<=\\n[\\n[.ev]:ai] \{\
1243 .               DEVTAG-COL 1
1244 \\*[par*label]\h'|\\n[\\n[.ev]:ai]u'\c
1245 .               DEVTAG-COL 2
1246 .       \}
1247 .       el \{\
1248 .               DEVTAG-COL 1
1249 \\*[par*label]
1250 .               DEVTAG-COL-NEXT 2
1251 .               br
1252 .       \}
1253 .       rm par*label
1256 .\" We don't want margin characters to be attached when we divert
1257 .\" the tag.  Since there's no way to save and restore the current
1258 .\" margin character, we have to switch to a new environment, taking
1259 .\" what we need of the old environment with us.
1260 .de par*push-tag-env
1261 .nr par*saved-font \\n[.f]
1262 .nr par*saved-size \\n[.s]z
1263 .nr par*saved-ss \\n[.ss]
1264 .ds par*saved-fam \\n[.fam]
1265 .ev par
1268 .ft \\n[par*saved-font]
1269 .ps \\n[par*saved-size]u
1270 .ss \\n[par*saved-ss]
1271 .fam \\*[par*saved-fam]
1273 .de par*pop-tag-env
1276 .de @RS
1278 .nr \\n[.ev]:li!\\n[\\n[.ev]:il] \\n[\\n[.ev]:li]
1279 .nr \\n[.ev]:ri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ri]
1280 .nr \\n[.ev]:ai!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ai]
1281 .nr \\n[.ev]:pli!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pli]
1282 .nr \\n[.ev]:pri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pri]
1283 .nr \\n[.ev]:il +1
1284 .nr \\n[.ev]:li +\\n[\\n[.ev]:ai]
1285 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1286 .par@reset
1288 .de @RE
1290 .ie \\n[\\n[.ev]:il] \{\
1291 .       nr \\n[.ev]:il -1
1292 .       nr \\n[.ev]:ai \\n[\\n[.ev]:ai!\\n[\\n[.ev]:il]]
1293 .       nr \\n[.ev]:li \\n[\\n[.ev]:li!\\n[\\n[.ev]:il]]
1294 .       nr \\n[.ev]:ri \\n[\\n[.ev]:ri!\\n[\\n[.ev]:il]]
1295 .       nr \\n[.ev]:pli \\n[\\n[.ev]:pli!\\n[\\n[.ev]:il]]
1296 .       nr \\n[.ev]:pri \\n[\\n[.ev]:pri!\\n[\\n[.ev]:il]]
1298 .el .@error unbalanced \\$0
1299 .par@reset
1300 .if '\\$0'QE' .par@adjspace
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
1314 .par@adjspace
1316 .als @QE @RE
1317 .\" start boxed text
1318 .de B1
1320 .HTML-IMAGE
1321 .di par*box-div
1322 .nr \\n[.ev]:li +1n
1323 .nr \\n[.ev]:ri +1n
1324 .nr par*box-in \\n[.in]
1325 .\" remember what 1n is, just in case the point size changes
1326 .nr par*box-n 1n
1327 .in +1n
1328 .ll -1n
1329 .lt -1n
1330 .ti \\n[par*box-in]u+1n
1332 .de @div-end!par*box-div
1335 .\" end boxed text
1336 .\" Postpone the drawing of the box until we're in the top-level diversion,
1337 .\" in case there's a footnote inside the box.
1338 .de B2
1339 .ie '\\n(.z'par*box-div' \{\
1340 .       br
1341 .       if \n[.V]>.25m .sp
1342 .       di
1343 .       if \n[.V]>.25m .sp
1344 .       ds@need \\n[dn]
1345 .       par*box-mark-top
1346 .       ev nf
1347 .       par*box-div
1348 .       ev
1349 .       nr \\n[.ev]:ri -\\n[par*box-n]
1350 .       nr \\n[.ev]:li -\\n[par*box-n]
1351 .       in -\\n[par*box-n]u
1352 .       ll +\\n[par*box-n]u
1353 .       lt +\\n[par*box-n]u
1354 .       par*box-draw \\n[.i]u \\n[.l]u-(\\n[.H]u==1n*1n)
1356 .el .@error B2 without B1
1357 .HTML-IMAGE-END
1359 .de par*box-mark-top
1360 .ie '\\n[.z]'' \{\
1361 .       rs
1362 .       mk par*box-top
1364 .el \!.par*box-mark-top
1366 .de par*box-draw
1367 .ie '\\n[.z]'' \{\
1368 .       nr par*box-in \\n[.i]
1369 .       nr par*box-ll \\n[.l]
1370 .       nr par*box-vpt \\n[.vpt]
1371 .       nr par*box-ad \\n[.j]
1372 .       ad l
1373 .       vpt 0
1374 .       in \\$1
1375 .       ll \\$2
1376 \v'-1v+.25m'\
1377 \D'l (u;\\n[.l]-\\n[.i]) 0'\
1378 \D'l 0 |\\n[par*box-top]u'\
1379 \D'l -(u;\\n[.l]-\\n[.i]) 0'\
1380 \D'l 0 -|\\n[par*box-top]u'
1381 .       br
1382 .       sp -1
1383 .       in \\n[par*box-in]u
1384 .       ll \\n[par*box-ll]u
1385 .       vpt \\n[par*box-vpt]
1386 .       ad \\n[par*box-ad]
1388 .el \!.par*box-draw \\$1 \\$2
1390 .\" \n[HORPHANS] sets how many lines of the following paragraph must be
1391 .\" kept together, with a preceding section header.  Initialise it,
1392 .\" to reproduce original behaviour; user may change it.
1393 .if !rHORPHANS .nr HORPHANS 1
1395 .\" \n[GROWPS] and \n[PSINCR] cause auto-increment of header point size.
1396 .\" Initialise them, so they have no effect, unless explicitly set by the user.
1397 .if !rGROWPS .nr GROWPS 0
1398 .if !rPSINCR .nr PSINCR 1p
1400 .de SH-NO-TAG
1401 .par@finish
1402 .\" Keep the heading and the first few lines of the next paragraph together.
1403 .\" (\n[HORPHANS] defines "first few" -- default = 1; user may redefine it).
1404 .nr sh*minvs \\n[HORPHANS]v
1405 .if \\n[sh*psincr]<0 .nr sh*psincr 0
1406 .ie \\n(VS<1000 .par*vs \\n(VSp+\\n[sh*psincr]u
1407 .el .par*vs \\n(VSp/1000u+\\n[sh*psincr]u
1408 .ne 2v+\\n[sh*minvs]u+\\n[\\n[.ev]:PD]u+\\n(.Vu
1409 .\" Adjust point size for heading text, as specified by \n[GROWPS] and \n[PSINCR].
1410 .ie \\n(PS<1000 .ps \\n(PS+\\n[sh*psincr]u
1411 .el .ps \\n(PSz/1000u+\\n[sh*psincr]u
1412 .sp 1
1413 .ft B
1415 .de @SH
1416 .\" Standard ms implementation does not expect an argument,
1417 .\" but allow ".SH n" to make heading point size match ".NH n",
1418 .\" for same "n", when \n[GROWPS] and \n[PSINCR] are set.
1419 .  nr sh*psincr 0
1420 .  if 0\\$1>0 .nr sh*psincr (\\n[GROWPS]-0\\$1)*\\n[PSINCR]
1421 .  SH-NO-TAG
1422 .  DEVTAG-SH 1
1423 .  if '\*(.T'html' .nr need_eo_h 1
1425 .\" TL, AU, and AI are aliased to these in cov*ab-init.
1426 .de par@TL
1427 .par@finish
1428 .sp 1
1429 .ft B
1430 .ps +2
1431 .vs +3p
1432 .ce 9999
1433 .DEVTAG-TL
1434 .nr need_eo_tl 1
1436 .de par@AU
1437 .par@finish
1438 .sp 1
1439 .ft I
1440 .ce 9999
1442 .de par@AI
1443 .par@finish
1444 .sp .5
1445 .ce 9999
1447 .\" In paragraph macros.
1448 .de NL
1449 .ie (\\n[\\n[.ev]:PS] >= 1000) \
1450 .       ps (\\n[\\n[.ev]:PS]z / 1000u)
1451 .el \
1452 .       ps \\n[\\n[.ev]:PS]
1454 .de SM
1455 .ps -2
1457 .de LG
1458 .ps +2
1460 .de R
1461 .ft R
1463 .\" par*define-font-macro macro font
1464 .de par*define-font-macro
1465 .de \\$1
1466 .ie \En[.$] \{\
1467 .       nr par*prev-font \En[.f]
1468 \&\E$3\f[\\$2]\E$1\f[\En[par*prev-font]]\E$2
1470 .el .ft \\$2
1471 \\..
1473 .par*define-font-macro B B
1474 .par*define-font-macro I I
1475 .par*define-font-macro BI BI
1476 .par*define-font-macro CW CR
1477 .\" underline a word
1478 .de UL
1479 \Z'\\$1'\v'.25m'\D'l \w'\\$1'u 0'\v'-.25m'\\$2
1481 .\" box a word
1482 .de BX
1483 .nr par*bxw \w'\\$1'+.4m
1484 \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''\
1485 \Z'\h'.2m'\\$1'\
1486 \h'\\n[par*bxw]u'
1488 .\" The first time UX is used, put a registered mark after it.
1489 .ds par*ux-rg \(rg
1490 .de UX
1491 \s[\\n[.s]*8u/10u]UNIX\s0\\$1\\*[par*ux-rg]
1492 .ds par*ux-rg
1494 .ds par@sup-start \v'-.9m\s'\En[.s]*7u/10u'+.7m'
1495 .als { par@sup-start
1496 .ds par@sup-end \v'-.7m\s0+.9m'
1497 .als } par@sup-end
1498 .\" footnote paragraphs
1499 .\" FF is the footnote format
1500 .nr FF 0
1501 .\" This can be redefined. It gets a second argument of `no' if the first
1502 .\" argument was supplied by the user, rather than automatically.
1503 .de FP
1505 .if !d par*fp!\\n[FF] \{\
1506 .       @error unknown footnote format `\\n[FF]'
1507 .       nr FF 0
1509 .ie '\\$2'no' .par*fp!\\n[FF]-no "\\$1"
1510 .el .par*fp!\\n[FF] "\\$1"
1512 .de par*fp!0
1513 .@PP
1514 \&\\*[par@sup-start]\\$1\\*[par@sup-end]\ \c
1516 .de par*fp!0-no
1517 .@PP
1518 \&\\$1\ \c
1520 .de par*fp!1
1521 .@PP
1522 \&\\$1.\ \c
1524 .de par*fp!1-no
1525 .@PP
1526 \&\\$1\ \c
1528 .de par*fp!2
1529 .@LP
1530 \&\\$1.\ \c
1532 .de par*fp!2-no
1533 .@LP
1534 \&\\$1\ \c
1536 .de par*fp!3
1537 .@IP "\\$1." (u;\\n[\\n[.ev]:PI]*2)
1539 .de par*fp!3-no
1540 .@IP "\\$1" (u;\\n[\\n[.ev]:PI]*2)
1542 .\" ***************************
1543 .\" ******** module nh ********
1544 .\" ***************************
1545 .\" Numbered headings.
1546 .\" nh*hl is the level of the last heading
1547 .nr nh*hl 0
1548 .\" SN-DOT and SN-NO-DOT represent the section number of
1549 .\" the current heading, with and without a terminating dot.
1550 .ds SN-DOT
1551 .ds SN-NO-DOT
1552 .\" SN-STYLE sets the statement numbering style used in headings
1553 .\" (either SN-DOT or SN-NO-DOT); for backward compatibility with
1554 .\" earlier ms versions, the default is SN-DOT
1555 .als SN-STYLE SN-DOT
1556 .\" Also for backward compatibility, let SN represent SN-DOT.
1557 .als SN SN-DOT
1558 .\" numbered heading
1559 .de @NH
1560 .ie '\\$1'S' \{\
1561 .       shift
1562 .       nr nh*hl 0
1563 .       while \\n[.$] \{\
1564 .               nr nh*hl +1
1565 .               nr H\\n[nh*hl] 0\\$1
1566 .               shift
1567 .       \}
1568 .       if !\\n[nh*hl] \{\
1569 .               nr H1 1
1570 .               nr nh*hl 1
1571 .               @error missing arguments to .NH S
1572 .       \}
1574 .el \{\
1575 .       nr nh*ohl \\n[nh*hl]
1576 .       ie \\n[.$] \{\
1577 .               nr nh*hl 0\\$1
1578 .               ie \\n[nh*hl]<=0 \{\
1579 .                       nr nh*ohl 0
1580 .                       nr nh*hl 1
1581 .               \}
1582 .               el \{\
1583 .                       if \\n[nh*hl]-\\n[nh*ohl]>1 \
1584 .                               @warning .NH \\n[nh*ohl] followed by .NH \\n[nh*hl]
1585 .               \}
1586 .       \}
1587 .       el .nr nh*hl 1
1588 .       while \\n[nh*hl]>\\n[nh*ohl] \{\
1589 .               nr nh*ohl +1
1590 .               nr H\\n[nh*ohl] 0
1591 .       \}
1592 .       nr H\\n[nh*hl] +1
1594 .ds SN-NO-DOT \\n(H1
1595 .nr nh*i 1
1596 .while \\n[nh*i]<\\n[nh*hl] \{\
1597 .       nr nh*i +1
1598 .       as SN-NO-DOT .\\n[H\\n[nh*i]]
1600 .ds SN-DOT \\*[SN-NO-DOT].
1601 .nr sh*psincr (\\n[GROWPS]-\\n[nh*hl])*\\n[PSINCR]
1602 .SH-NO-TAG
1603 .DEVTAG-NH "\\$1"
1604 .  if '\*(.T'html' .nr need_eo_h 1
1605 \\*[SN-STYLE]
1607 .\" ****************************
1608 .\" ******** module toc ********
1609 .\" ****************************
1610 .\" Table of contents generation.
1611 .de @XS
1612 .da toc*div
1613 .ev h
1614 .ie \\n[.$] .XA "\\$1"
1615 .el .XA
1617 .de @div-end!toc*div
1620 .de XA
1621 .ie '\\n(.z'toc*div' \{\
1622 .       if d toc*num .toc*end-entry
1623 .       ie \\n[.$] \{\
1624 .               ie '\\$1'no' .ds toc*num
1625 .               el .ds toc*num "\\$1
1626 .       \}
1627 .       el .ds toc*num \\n[PN]
1628 .       br
1629 .       par@reset
1630 .       na
1631 .       ll -8n
1632 .       in (n;0\\$2)
1634 .el .@error XA without XS
1636 .de XE
1637 .ie '\\n(.z'toc*div' \{\
1638 .       if d toc*num .toc*end-entry
1639 .       ev
1640 .       di
1642 .el .@error XE without XS
1644 .de toc*end-entry
1645 \\a\\t\\*[toc*num]
1647 .rm toc*num
1649 .de PX
1651 .if !'\\$1'no' \{\
1652 .       ce 1
1653 .       ie (\\n[PS] >= 1000) \
1654 .               ps ((\\n[PS]z / 1000u) + 2z)
1655 .       el \
1656 .               ps \\n[PS]+2
1657 .       ft B
1658 \\*[TOC]
1659 .       ft
1660 .       ps
1663 .char \[toc*leader-char] .\h'1m'
1664 .lc \[toc*leader-char]
1665 .ta (u;\\n[.l]-\\n[.i]-\w'000') (u;\\n[.l]-\\n[.i])R
1666 .sp 2
1667 .toc*div
1668 .par@reset
1670 .\" print the table of contents on page i
1671 .de TC
1673 .pg@begin 1 i
1674 .PX \\$1
1676 .\" ****************************
1677 .\" ******** module eqn ********
1678 .\" ****************************
1679 .\" Eqn support.
1680 .de EQ
1682 .de EN
1684 .de @EQ
1686 .ds eqn*num "\\$2
1687 .ie '\\$1'L' .nr eqn*type 0
1688 .el \{\
1689 .       ie '\\$1'I' .nr eqn*type 1
1690 .       el \{\
1691 .               nr eqn*type 2
1692 .               if !'\\$1'C' .ds eqn*num "\\$1
1693 .       \}
1695 .di eqn*div
1696 .in 0
1697 .if \\n[eqn*type]=0 .EQN-HTML-IMAGE-LEFT
1698 .if \\n[eqn*type]=1 \{\
1699 .   if '\*(.T'html' .RS
1700 .EQN-HTML-IMAGE-INLINE
1702 .if \\n[eqn*type]=2 .EQN-HTML-IMAGE
1705 .de @div-end!eqn*div
1706 .@EN
1708 .\" Note that geqn mark and lineup work correctly in centered equations.
1709 .de @EN
1710 .ie !'\\n(.z'eqn*div' .@error-recover mismatched EN
1711 .el \{\
1712 .       br
1713 .       di
1714 .       nr eqn*have-num 0
1715 .       if !'\\*[eqn*num]'' .nr eqn*have-num 1
1716 .       ie \\n[dl]:\\n[eqn*have-num] \{\
1717 .               sp \\n[DD]u
1718 .               par@reset
1719 .               ds eqn*tabs \\n[.tabs]
1720 .               nf
1721 .               ie \\n[dl] \{\
1722 .\"                     --fixme-- this really should not be necessary
1723 .\"                     and indicates that there is extra space creeping into
1724 .\"                     an equation when ps4html is enabled..
1725 .                       ie r ps4html .ds@need \\n[dn]u-1v+\n[.V]u+1i
1726 .                       el .ds@need \\n[dn]u-1v+\n[.V]u
1727 .                       chop eqn*div
1728 .                       ie \\n[eqn*type]=0 \{\
1729 .                               ta (u;\\n[.l]-\\n[.i])R
1730 \\*[eqn*div]\t\\*[eqn*num]
1731 .                       \}
1732 .                       el \{\
1733 .                               ie \\n[eqn*type]=1 .ta \\n[DI]u \
1734 (u;\\n[.l]-\\n[.i])R
1735 .                               el .ta (u;\\n[.l]-\\n[.i]/2)C \
1736 (u;\\n[.l]-\\n[.i])R
1737 \t\\*[eqn*div]\t\\*[eqn*num]
1738 .                       \}
1739 .               \}
1740 .               el \{\
1741 .                       ta (u;\\n[.l]-\\n[.i])R
1742 \t\\*[eqn*num]
1743 .               \}
1744 .\".            if !'\*(.T'html' .sp \\n[DD]u
1745 .               sp \\n[DD]u
1746 .               ta \\*[eqn*tabs]
1747 .       \}
1748 .       el \{
1749 .\" must terminate empty equations in html and ps4html as they contain
1750 .\" the EQN-HTML-IMAGE-END suppression nodes
1751 .               if \\n[dl] .chop eqn*div
1752 .               if '\*(.T'html' \\*[eqn*div]
1753 .               if r ps4html    \\*[eqn*div]
1754 .       \}
1755 .       if !'\*(.T'html' .fi
1756 .       if \\n[eqn*type]=0 .EQN-HTML-IMAGE-END
1757 .       if \\n[eqn*type]=1 \{\
1758 .               EQN-HTML-IMAGE-END
1759 .               if '\*(.T'html' .RE
1760 .       \}
1761 .       if \\n[eqn*type]=2 .EQN-HTML-IMAGE-END
1765 .\" ****************************
1766 .\" ******** module tbl ********
1767 .\" ****************************
1768 .\" Tbl support.
1769 .nr tbl*have-header 0
1770 .\" This gets called if TS occurs before the first paragraph.
1771 .de TS
1773 .\" cov*ab-init aliases TS to @TS
1774 \\*[TS]\\
1776 .de @TS
1777 .sp \\n[DD]u
1778 .if '\\$1'H' .di tbl*header-div
1779 .HTML-IMAGE
1781 .de tbl@top-hook
1782 .if \\n[tbl*have-header] \{\
1783 .       ie \\n[.t]-\\n[tbl*header-ht]-1v .tbl*print-header
1784 .       el .sp \\n[.t]u
1787 .de tbl*print-header
1788 .ev nf
1789 .tbl*header-div
1791 .mk #T
1793 .de TH
1794 .ie '\\n[.z]'tbl*header-div' \{\
1795 .       nr T. 0
1796 .       T#
1797 .       br
1798 .       di
1799 .       ie \\n[dn]+\\n[FM]+\\n[HM]+2v>=\\n[.p] \{\
1800 .               @error ridiculously long table header
1801 .               ds@need \\n[dn]
1802 .               tbl*print-header
1803 .       \}
1804 .       el \{\
1805 .               nr tbl*header-ht \\n[dn]
1806 .               ds@need \\n[dn]u+1v
1807 .               tbl*print-header
1808 .               nr tbl*have-header 1
1809 .       \}
1811 .el .@error-recover .TH without .TS H
1813 .de @div-end!tbl*header-div
1817 .de TE
1818 .ie '\\n(.z'tbl*header-div' .@error-recover .TS H but no .TH before .TE
1819 .el \{\
1820 .       nr tbl*have-header 0
1821 .       if !'\*(.T'html' .sp \\n[DD]u
1823 .HTML-IMAGE-END
1824 .\" reset tabs
1827 .de tbl@bottom-hook
1828 .if \\n[tbl*have-header] \{\
1829 .       nr T. 1
1830 .       T#
1833 .de T&
1835 .\" ****************************
1836 .\" ******** module pic ********
1837 .\" ****************************
1838 .\" Pic support.
1839 .\" PS height width
1840 .de PS
1842 .sp \\n[DD]u
1843 .ie \\n[.$]<2 .@error bad arguments to PS (not preprocessed with pic?)
1844 .el \{\
1845 .       ds@need (u;\\$1)+1v
1846 .       in +(u;\\n[.l]-\\n[.i]-\\$2/2>?0)
1848 .HTML-IMAGE
1850 .de PE
1851 .HTML-IMAGE-END
1852 .par@reset
1853 .sp \\n[DD]u+.5m
1855 .\" ****************************
1856 .\" ******** module ref ********
1857 .\" ****************************
1858 .\" Refer support.
1859 .de ]-
1860 .rm [A [B [C [D [E [G [I [J [N [O [P [Q [R [S [T [V
1861 .rm ref*string
1863 .\" Other
1864 .ds ref*spec!0 Q A T1 S V N P I C D O
1865 .\" Journal article
1866 .ds ref*spec!1 Q A T2 J S V N P I C D O
1867 .\" Book
1868 .ds ref*spec!2 Q A T1 S V P I C D O
1869 .\" Article within book
1870 .ds ref*spec!3 Q A T2 B E S V P I C D O
1871 .\" Tech report
1872 .ds ref*spec!4 Q A T2 R G P I C D O
1873 .\" ][ type
1874 .de ][
1875 .if r [T \{\
1876 .       als [T1 [T
1877 .       als [T2 [T
1879 .ie d ref*spec!\\$1 .ref*build \\*[ref*spec!\\$1]
1880 .el \{\
1881 .       @error unknown reference type `\\$1'
1882 .       ref*build \\*[ref*spec!0]
1884 .ref*print
1885 .rm ref*string
1886 .rm [F [T1 [T2
1888 .\" start of reference number
1889 .ds [. \E*[par@sup-start]
1890 .\" end of reference number
1891 .ds .] \E*[par@sup-end]
1892 .\" period before reference
1893 .ds <. .
1894 .\" period after reference
1895 .ds >. \" empty
1896 .\" comma before reference
1897 .ds <, ,
1898 .\" comma after reference
1899 .ds >, \" empty
1900 .\" start collected references
1901 .de ]<
1902 .als ref*print ref*end-print
1904 \&\\*[REFERENCES]
1905 .par@reset
1907 .\" end collected references
1908 .de ]>
1909 .par@finish
1910 .als ref*print ref*normal-print
1912 .de ref*normal-print
1913 .ie d [F .FS "\\*([.\\*([F\\*(.]"
1914 .el .FS \&
1915 \\*[ref*string]
1918 .de ref*end-print
1919 .ie d [F .IP "\\*([F."
1920 .el .XP
1921 \\*[ref*string]
1923 .als ref*print ref*normal-print
1924 .de ref*build
1925 .rm ref*string ref*post-punct
1926 .nr ref*suppress-period 1
1927 .while \\n[.$] \{\
1928 .       if d [\\$1 \{\
1929 .               ie d ref*add-\\$1 .ref*add-\\$1
1930 .               el .ref*add-dflt \\$1
1931 .       \}
1932 .       shift
1934 .\" now add a final period
1935 .ie d ref*string \{\
1936 .       if !\\n[ref*suppress-period] .as ref*string .
1937 .       if d ref*post-punct \{\
1938 .               as ref*string "\\*[ref*post-punct]
1939 .               rm ref*post-punct
1940 .       \}
1942 .el .ds ref*string
1944 .de ref*add-T1
1945 .ref*field T , " " "\fI" "" "\fP"
1946 .if r [T .nr ref*suppress-period \\n([T
1948 .de ref*add-T2
1949 .ref*field T , " " "\\*Q" "" "\\*U"
1950 .if r [T .nr ref*suppress-period \\n([T
1952 .de ref*add-P
1953 .ie \\n([P>0 .ref*field P , " " "pp. "
1954 .el .ref*field P , " " "p. "
1956 .de ref*add-J
1957 .ref*field J , " " \fI "" \fP
1959 .de ref*add-D
1960 .ref*field D "" " " ( )
1962 .de ref*add-E
1963 .ref*field E , " " "ed. "
1965 .de ref*add-G
1966 .ref*field G "" " " ( )
1968 .de ref*add-B
1969 .ref*field B "" " " "in \fI" "" \fP
1971 .de ref*add-O
1972 .ref*field O . " "
1973 .ie r [O .nr ref*suppress-period \\n([O
1974 .el .nr ref*suppress-period 1
1976 .de ref*add-A
1977 .ref*field A , " "
1978 .if r [A .nr ref*suppress-period \\n([A
1980 .de ref*add-V
1981 .ref*field V "" " " \fB \fR
1983 .de ref*add-N
1984 .ref*field N "" ( "" ")"
1986 .de ref*add-dflt
1987 .ref*field \\$1 , " "
1989 .\" First argument is the field letter.
1990 .\" Second argument is the punctuation character to use to separate this field
1991 .\" from the previous field.
1992 .\" Third argument is a string to insert after the punctuation character of
1993 .\" the previous field (normally a space)
1994 .\" Fourth argument is a string with which to prefix this field.
1995 .\" Fifth argument is a string with which to postfix this field.
1996 .\" Sixth argument is a string to add after the punctuation character supplied
1997 .\" by the next field.
1998 .de ref*field
1999 .if d ref*string \{\
2000 .       ie d ref*post-punct \{\
2001 .               as ref*string "\\$2\\*[ref*post-punct]\\$3\"
2002 .               rm ref*post-punct
2003 .       \}
2004 .       el .as ref*string "\\$2\\$3\"
2006 .as ref*string "\\$4\\*([\\$1\\$5
2007 .if \\n[.$]>5 .ds ref*post-punct "\\$6
2008 .nr ref*suppress-period 0
2010 .\" ****************************
2011 .\" ******** module acc ********
2012 .\" ****************************
2013 .\" Accents and special characters.
2014 .ds Q \(lq
2015 .ds U \(rq
2016 .ds - \(em
2017 .\" Characters
2018 .\" The idea of this definition is for the top of the 3 to be at the x-height.
2019 .if !c\[yogh] .char \[yogh] \Z'\v'\w'x'*0-\En[rst]u'\s[\En[.s]*8u/10u]\
2020 \v'\w'3'*0+\En[rst]u'3\s0'\h'\w'\s[\En[.s]*8u/10u]3'u'
2021 .\" Accents
2022 .de acc*over-def
2023 .ds \\$1 \Z'\v'(u;\w'x'*0+\En[rst]-\En[.cht])'\
2024 \h'(u;-\En[skw]+(-\En[.w]-\w'\\$2'/2)+\En[.csk])'\\$2'
2026 .de acc*under-def
2027 .ds \\$1 \Z'\v'\En[.cdp]u'\h'(u;-\En[.w]-\w'\\$2'/2)'\\$2'
2029 .de acc*slash-def
2030 .ds \\$1 \Z'\h'(u;-\En[.w]-\w'\\$2'/2)'\
2031 \v'(u;\En[.cdp]-\En[.cht]+\En[rst]+\En[rsb]/2)'\\$2'
2033 .de acc*prefix-def
2034 .ds \\$1 \Z'\h'(u;\w'x'-\w'\\$2'/2)'\\$2'
2036 .acc*prefix-def ' \'
2037 .acc*prefix-def ` \`
2038 .acc*prefix-def ^ ^
2039 .acc*prefix-def , \(ac
2040 .acc*prefix-def : \(ad
2041 .acc*prefix-def ~ ~
2042 .\" improved accent marks
2043 .de AM
2044 .acc*over-def ' \'
2045 .acc*over-def ` \`
2046 .acc*over-def ^ ^
2047 .acc*over-def ~ ~
2048 .acc*over-def : \(ad
2049 .acc*over-def v \(ah
2050 .acc*over-def _ \(a-
2051 .acc*over-def o \(ao
2052 .acc*under-def , \(ac
2053 .acc*under-def . \s[\En[.s]*8u/10u]\v'.2m'.\v'-.2m'\s0
2054 .acc*under-def hook \(ho
2055 .acc*slash-def / /
2056 .char \[hooko] o\E*[hook]
2057 .ds q \[hooko]
2058 .ds 3 \[yogh]
2059 .ds D- \(-D\"                   Icelandic uppercase eth
2060 .ds d- \(Sd\"                   Icelandic lowercase eth
2061 .ds Th \(TP\"                   Icelandic uppercase thorn
2062 .ds th \(Tp\"                   Icelandic lowercase thorn
2063 .ds 8 \(ss\"                    German double s
2064 .ds Ae \(AE\"                   AE ligature
2065 .ds ae \(ae\"                   ae ligature
2066 .ds Oe \(OE\"                   OE ligature
2067 .ds oe \(oe\"                   oe ligature
2068 .ds ? \(r?\"                    upside down ?
2069 .ds ! \(r!\"                    upside down !
2071 .de CHECK-FOOTER-AND-KEEP
2072 .if '\*(.T'html' \{\
2073 .   rm KF
2074 .   als KF KS
2076 .   rm FS
2077 .   de FS
2078 .      sp
2079 .      HTML-NS <cite>
2080 \\..
2081 .   rm FE
2082 .   de FE
2083 .      HTML-NS </cite>
2084 .      sp
2085 \\..
2088 .par@load-init
2089 .\" ****************************
2090 .\" ******** module bell ********
2091 .\" ****************************
2092 .\" Emulate Bell Labs localisms. Note, (a) they're not documented, and
2093 .\" (b) the .P1 and .UC macros collide with different ones in Berkeley ms.
2094 .\" We hack around this by conditionalizing the behavior of P1; UC was
2095 .\" not defined by groff and will be a no-op if called Berkeley style
2096 .\" with no arguments, so there is no problem with hijacking it here.
2098 .\" What's done here is sufficient to give back the Guide to EQN (1976) its
2099 .\" section headings and restore some text that had gone missing as macro
2100 .\" arguments; no warranty express or implied is given as to how well the
2101 .\" typographic details these produce match the original Bell Labs macros.
2103 .\" P1 is now defined in module pg.
2104 .de SC
2105 .nr bell_localisms 1
2107 \\$*
2109 .de UC
2110 .if r bell_localisms \f(CW\\$*\fP
2112 .de P2
2113 .if r bell_localisms \{\
2114 .       ft
2115 .       DE
2118 .\" s-ts-mode