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
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
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.
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.
37 .tm \\n(.F:\\n(.c: macro error: \\$*
40 .tm \\n(.F:\\n(.c: macro warning: \\$*
43 .ab \\n(.F:\\n(.c: fatal macro error: \\$*
46 .@error sorry, \\$0 not implemented
49 .als TM @not-implemented
50 .als CT @not-implemented
54 .if !rPO .nr PO \\n(.o
55 .\" a non-empty environment
63 .ds REFERENCES References
65 .ds TOC Table of Contents
78 .ds MO \E*[MONTH\n[mo]]
79 .ds DY \n[dy] \*[MO] \n[year]
81 .if \\n[.$] .ds DY "\\$*
84 .if \\n[.$] .ds DY "\\$*
89 .tm \\$1\t\\$2\t\\$3\t\\$4 ... \\n[PN]
91 .\" print an error message and then try to recover
93 .@error \\$@ (recovering)
96 . \"@warning automatically terminating diversion \\n(.z
97 . ie d @div-end!\\n(.z .@div-end!\\n(.z
98 . el .*div-end-default
100 . \" ensure that we don't loop forever
101 . if \\n[*pop-count]>20 .@fatal recovery failed
103 .while !'\\n[.ev]'0' .ev
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
145 .als RP cov*err-not-after-first-page
147 .ie \\n[cov*rp-format] \{\
158 .CHECK-FOOTER-AND-KEEP
160 .wh 0 cov*first-page-init
161 .\" This handles the case where FS occurs before TL or LP.
168 .\" released paper format
171 .if \\n[.$] .if '\\$1'no' .nr cov*rp-no 1
177 .als TL cov*err-not-again
197 .di cov*au-div!\\n[cov*n-au]
200 .ie (\\n[PS] >= 1000) \
201 . ps (\\n[PS]z / 1000u)
211 .ie !\\n[cov*n-au] .@error AI before AU
213 . di cov*ai-div!\\n[cov*n-au]
216 . ie (\\n[PS] >= 1000) \
217 . ps (\\n[PS]z / 1000u)
246 .als cov*ab-init @nop
264 .als AB cov*err-not-after-ab
278 . als cov*tl-au-print @nop
284 . if '\*(.T'html' \{\
298 . als cov*tl-au-print @nop
306 . als AE cov*err-not-again
309 . ie '\\n(.z'cov*ab-div' \{\
310 . als AE cov*err-not-again
313 .\" nr cov*ab-height \\n[dn]
318 . el .@error AE without AB
321 .de @div-end!cov*ab-div
327 . ie \\n[cov*rp-format] .cov*rp-print
328 . el .cov*draft-print
331 . if \\n[cov*rp-format] \{\
332 . @warning RP format but no TL
336 . CHECK-FOOTER-AND-KEEP
342 .nr cov*page-length \\n[.p]
347 . if !'\*(.T'html' .nf
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])
361 . ie \\n[cov*rp-no] .rm cov*fn-div
363 . rn cov*fn-div fn@overflow-div
364 . nr fn@have-overflow 1
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
375 .if !\\n[cov*rp-no] .cov*tl-au-print
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] \{\
406 . cov*ai-div!\\n[cov*i]
416 .\" start of footnote on cover
418 .if \\n[cov*in-fn] \{\
426 .if !\\n[cov*fn-height] .ns
427 .ie \\n[.$] .FP "\\$1" no
430 .de @div-end!cov*fn-div
433 .\" end of footnote on cover
435 .ie '\\n(.z'cov*fn-div' \{\
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
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]'
471 .ie \\n%=1 .if \\n[pg*P1] .tl \\*[pg*OH]
473 . ie o .tl \\*[pg*OH]
483 .ie r bell_localisms \{\
489 .wh -\n[FM]u pg@bottom
490 .wh -\n[FM]u/2u pg*footer
494 .if !'\\n(.z'' .error-recover MC while diversion open
496 .ie \\n[pg@ncols]>1 .pg@super-eject
498 . \" flush out any floating keeps
499 . while \\n[kp@tail]>\\n[kp@head] \{\
505 . nr pg@colw \\n[LL]*7/15
506 . nr pg*gutw \\n[LL]-(2*\\n[pg@colw])
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)
518 .DEVTAG ".mc \\n[pg@ncols] \\n[pg@colw] \\n[pg*gutw]"
522 .nr pg@fn-colw \\n[pg@colw]*5/6
531 .\" top of page macro
533 .ch pg*footer -\\n[FM]u/2u
536 .nr pg@fn-bottom-margin 0
550 .\" Handle footnote overflow before floating keeps, because the keep
551 .\" might contain an embedded footnote.
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
566 .if \\n[pg@fn-flag] .fn@bottom-hook
568 .ie \\n[pg*col-num]<\\n[pg@ncols] .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])
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.
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]
593 . if d pg*next-format \{\
594 . af PN \\*[pg*next-format]
601 .\" pg@begin number format
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
611 .\" print the footer line
618 .\" flush out any keeps or footnotes
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] \{\
637 .\" ***************************
638 .\" ******** module fn ********
639 .\" ***************************
643 .\" Round it vertically
645 .nr fn@sep-dist \n[.v]
649 .ds * \E*[par@sup-start]\En+[fn*text-num]\E*[par@sup-end]
653 .ie \\n[.$] .fn*do-FS "\\$1" no
655 . ie \\n[fn*text-num]>\\n[fn*note-num] .fn*do-FS \\n+[fn*note-num]
659 .\" Second argument of `no' means don't embellish the first argument.
661 .if \\n[fn*open] .@error-recover nested FS
664 . \" Ensure that the first line of the footnote is on the same page
665 . \" as the reference. I think this is minimal.
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
681 .ie !\\n[fn*open] .@error FE without FS
689 .nr fn@have-overflow 0
690 .\" called at the top of each column
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
704 .\" This is called at the bottom of the column if pg@fn-flag is set.
707 .nr fn@have-overflow 0
708 .nr fn@bottom-pos \\n[.p]-\\n[FM]-\\n[pg@fn-bottom-margin]+\\n[.v]
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
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
726 . if '\\n(.z'fn@overflow-div' \{\
728 . nr fn@have-overflow \\n[dn]>0
730 . ch fn*catch-overflow
733 .de fn*catch-overflow
739 .if '\\n[.ev]'fn' .ev
743 .als @div-end!fn*embed-div @div-end!fn@div
747 . if !\\n[pg@fn-flag] .ns
752 .ie '\\n(.z'fn@div' \{\
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]
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
762 . ie '\\n(.z'fn*embed-div' \{\
764 . rn fn*embed-div fn*embed-div!\\n[fn*embed-count]
765 \!. fn*embed-start \\n[fn*embed-count]
767 ' sp (u;\\n[dn]+\\n[fn@sep-dist]+\\n[.V])
769 . nr fn*embed-count +1
773 . @error-recover unclosed diversion within footnote
782 . rm fn*embed-div!\\$1
788 \!. fn*embed-start \\$1
793 .ie '\\n(.z'fn*null' \{\
799 .\" It's important that fn@print-sep use up exactly fn@sep-dist vertical space.
803 .vs \\n[fn@sep-dist]u
808 .\" ***************************
809 .\" ******** module kp ********
810 .\" ***************************
817 .if !'\\n(.z'' .@error-recover KF while open diversion
824 .ie '\\n(.z'kp*div' .kp*end
826 . ie '\\n(.z'kp*fdiv' .kp*fend
827 . el .@error KE without KS or KF
837 .ie '\\n(.z'' .ds@need \\$1
840 .\" end non-floating keep
853 .\" end floating keep
858 .ie \\n[.t]-(\\n[.k]>0*1v)>\\n[dn] \{\
866 . rn kp*fdiv kp*div!\\n[kp@tail]
867 . nr kp*ht!\\n[kp@tail] 0\\n[dn]
871 .\" top of page processing for KF
874 .if !\\n[kp*doing-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])
885 .while \\n[kp@tail]>\\n[kp@head]&\\n[kp*fits] \{\
886 . ie \\n[.t]>\\n[kp*ht!\\n[kp@head]]:\\n[kp*force] \{\
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
902 .\" ***************************
903 .\" ******** module ds ********
904 .\" ***************************
905 .\" Displays and non-floating keeps.
907 .ds*end!\\n[\\n[.ev]:ds-type]
908 .nr \\n[.ev]:ds-type 0
911 .if \\n[\\n[.ev]:ds-type] \{\
912 . @error automatically terminating display
917 .ie \\n[\\n[.ev]:ds-type] .DE
921 .@error DE without DS, ID, CD, LD or BD
925 .nr \\n[.ev]:ds-type 1
932 .ie \\n[.$] .in +(n;\\$1)
947 .als ds*end!1 ds*common-end
950 .nr \\n[.ev]:ds-type 2
955 .ie '\\n(.z'ds*div' \{\
958 . in (u;\\n[.l]-\\n[dl]/2>?0)
963 .el .@error-recover mismatched DE
970 . nr \\n[.ev]:ds-type 4
979 . ie '\\$1'I' .ID \\$2
984 . nr \\n[.ev]:ds-type 3
989 . while \\n[.t]<=(\\$1)&(\\n[nl]>\\n[pg@header-bottom]) \{\
997 .ie '\\n(.z'ds*div' \{\
1006 .el .@error-recover mismatched DE
1009 .ie '\\n(.z'ds*div' \{\
1013 . in (u;\\n[.l]-\\n[dl]/2>?0)
1019 .el .@error-recover mismatched DE
1021 .\" ****************************
1022 .\" ******** module par ********
1023 .\" ****************************
1024 .\" Paragraph-level formatting.
1025 .\" Load time initialization.
1027 .\" PS and VS might have been set on the command-line
1031 .\" don't set LT so that it can be defaulted from LL
1032 .ie rLT .lt \\n[LT]u
1034 .ie (\\n[PS] >= 1000) \
1035 . ps (\\n[PS]z / 1000u)
1038 .\" don't set VS so that it can be defaulted from PS
1040 . ie (\\n[VS] >= 1000) \
1041 . par*vs "(\\n[VS]p / 1000u)"
1046 . ie (\\n[PS] >= 1000) \
1047 . par*vs "((\\n[PS]p / 1000u) + 2p)"
1049 . par*vs "(\\n[PS] + 2)"
1051 .if dFAM .fam \\*[FAM]
1055 .CHECK-FOOTER-AND-KEEP
1058 .\" If it's too big to be in points, treat it as units.
1059 .ie (p;\\$1)>=40p .vs (u;\\$1)
1063 .nr 0:li (u;\\n[LL]/12)
1070 .aln \\n[.ev]:MCLL LL
1072 .aln \\n[.ev]:MCLT LT
1078 .\" happens when the first page begins
1080 .if !rLT .nr LT \\n[LL]
1081 .if !rFL .nr FL \\n[LL]*5/6
1083 . ie (\\n[PS] >= 1000) \
1084 . nr VS (\\n[PS] + 2000)
1086 . nr VS (\\n[PS] + 2)
1090 . ie (\\n[PS] >= 1000) \
1091 . nr FPS (\\n[PS] - 2000)
1093 . nr FPS (\\n[PS] - 2)
1096 . ie (\\n[FPS] >= 1000) \
1097 . nr FVS (\\n[FPS] + 2000)
1099 . nr FVS (\\n[FPS] + 2)
1101 .\" don't change environment 0
1103 .ie (\\n[PS] >= 1000) \
1104 . ps (\\n[PS]z / 1000u)
1109 .ie (\\n[VS] >= 1000) \
1110 . par*vs "(\\n[VS]p / 1000u)"
1113 .if !rPD .nr PD .3v>?\n(.V
1114 .if !rDD .nr DD .5v>?\n(.V
1116 .if !rFPD .nr FPD \\n[PD]/2
1118 .if !dFAM .ds FAM \\n[.fam]
1140 .aln fn:MCLL pg@fn-colw
1141 .aln fn:MCLT pg@fn-colw
1147 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1150 .nr \\n[.ev]:ds-type 0
1155 .if \\n[need_eo_tl]>0 .DEVTAG-EO-TL
1157 .if \\n[need_eo_h]>0 .DEVTAG-EO-H
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
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])
1174 .ie (\\n[\\n[.ev]:PS] >= 1000) \
1175 . ps (\\n[\\n[.ev]:PS]z / 1000u)
1177 . ps \\n[\\n[.ev]:PS]
1178 .ie (\\n[\\n[.ev]:VS] >= 1000) \
1179 . par*vs "(\\n[\\n[.ev]:VS]p / 1000u)"
1181 . par*vs \\n[\\n[.ev]:VS]
1188 .sp \\n[\\n[.ev]:PD]u
1189 .ne \\n[PORPHANS]v+\\n(.Vu
1191 .\" This can be redefined by the user.
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
1202 .nr \\n[.ev]:pli \\$1
1203 .nr \\n[.ev]:pri \\$2
1215 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1219 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1220 .if !'\*(.T'html' .ti +\\n[\\n[.ev]:ai]u
1223 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1224 .par*start \\n[QI] \\n[QI]
1227 .par*start \\n[\\n[.ev]:PI] 0
1228 .ti -\\n[\\n[.ev]:PI]u
1231 .if \\n[.$]>1 .nr \\n[.ev]:ai (n;\\$2)
1232 .par*start \\n[\\n[.ev]:ai] 0
1234 . \" Divert the label so as to freeze any spaces.
1241 . ti -\\n[\\n[.ev]:ai]u
1242 . ie \\n[dl]+1n<=\\n[\\n[.ev]:ai] \{\
1244 \\*[par*label]\h'|\\n[\\n[.ev]:ai]u'\c
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]
1268 .ft \\n[par*saved-font]
1269 .ps \\n[par*saved-size]u
1270 .ss \\n[par*saved-ss]
1271 .fam \\*[par*saved-fam]
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]
1284 .nr \\n[.ev]:li +\\n[\\n[.ev]:ai]
1285 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1290 .ie \\n[\\n[.ev]:il] \{\
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
1300 .if '\\$0'QE' .par@adjspace
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]
1310 .nr \\n[.ev]:li +\\n[QI]
1311 .nr \\n[.ev]:ri +\\n[QI]
1312 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1317 .\" start boxed text
1324 .nr par*box-in \\n[.in]
1325 .\" remember what 1n is, just in case the point size changes
1330 .ti \\n[par*box-in]u+1n
1332 .de @div-end!par*box-div
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.
1339 .ie '\\n(.z'par*box-div' \{\
1341 . if \n[.V]>.25m .sp
1343 . if \n[.V]>.25m .sp
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
1359 .de par*box-mark-top
1364 .el \!.par*box-mark-top
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]
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'
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
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
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.
1420 . if 0\\$1>0 .nr sh*psincr (\\n[GROWPS]-0\\$1)*\\n[PSINCR]
1423 . if '\*(.T'html' .nr need_eo_h 1
1425 .\" TL, AU, and AI are aliased to these in cov*ab-init.
1447 .\" In paragraph macros.
1449 .ie (\\n[\\n[.ev]:PS] >= 1000) \
1450 . ps (\\n[\\n[.ev]:PS]z / 1000u)
1452 . ps \\n[\\n[.ev]:PS]
1463 .\" par*define-font-macro macro font
1464 .de par*define-font-macro
1467 . nr par*prev-font \En[.f]
1468 \&\E$3\f[\\$2]\E$1\f[\En[par*prev-font]]\E$2
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
1479 \Z'\\$1'\v'.25m'\D'l \w'\\$1'u 0'\v'-.25m'\\$2
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''\
1488 .\" The first time UX is used, put a registered mark after it.
1491 \s[\\n[.s]*8u/10u]UNIX\s0\\$1\\*[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'
1498 .\" footnote paragraphs
1499 .\" FF is the footnote format
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.
1505 .if !d par*fp!\\n[FF] \{\
1506 . @error unknown footnote format `\\n[FF]'
1509 .ie '\\$2'no' .par*fp!\\n[FF]-no "\\$1"
1510 .el .par*fp!\\n[FF] "\\$1"
1514 \&\\*[par@sup-start]\\$1\\*[par@sup-end]\ \c
1537 .@IP "\\$1." (u;\\n[\\n[.ev]:PI]*2)
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
1548 .\" SN-DOT and SN-NO-DOT represent the section number of
1549 .\" the current heading, with and without a terminating 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.
1558 .\" numbered heading
1565 . nr H\\n[nh*hl] 0\\$1
1568 . if !\\n[nh*hl] \{\
1571 . @error missing arguments to .NH S
1575 . nr nh*ohl \\n[nh*hl]
1578 . ie \\n[nh*hl]<=0 \{\
1583 . if \\n[nh*hl]-\\n[nh*ohl]>1 \
1584 . @warning .NH \\n[nh*ohl] followed by .NH \\n[nh*hl]
1588 . while \\n[nh*hl]>\\n[nh*ohl] \{\
1594 .ds SN-NO-DOT \\n(H1
1596 .while \\n[nh*i]<\\n[nh*hl] \{\
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]
1604 . if '\*(.T'html' .nr need_eo_h 1
1607 .\" ****************************
1608 .\" ******** module toc ********
1609 .\" ****************************
1610 .\" Table of contents generation.
1614 .ie \\n[.$] .XA "\\$1"
1617 .de @div-end!toc*div
1621 .ie '\\n(.z'toc*div' \{\
1622 . if d toc*num .toc*end-entry
1624 . ie '\\$1'no' .ds toc*num
1625 . el .ds toc*num "\\$1
1627 . el .ds toc*num \\n[PN]
1634 .el .@error XA without XS
1637 .ie '\\n(.z'toc*div' \{\
1638 . if d toc*num .toc*end-entry
1642 .el .@error XE without XS
1653 . ie (\\n[PS] >= 1000) \
1654 . ps ((\\n[PS]z / 1000u) + 2z)
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
1670 .\" print the table of contents on page i
1676 .\" ****************************
1677 .\" ******** module eqn ********
1678 .\" ****************************
1687 .ie '\\$1'L' .nr eqn*type 0
1689 . ie '\\$1'I' .nr eqn*type 1
1692 . if !'\\$1'C' .ds eqn*num "\\$1
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
1708 .\" Note that geqn mark and lineup work correctly in centered equations.
1710 .ie !'\\n(.z'eqn*div' .@error-recover mismatched EN
1715 . if !'\\*[eqn*num]'' .nr eqn*have-num 1
1716 . ie \\n[dl]:\\n[eqn*have-num] \{\
1719 . ds eqn*tabs \\n[.tabs]
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
1728 . ie \\n[eqn*type]=0 \{\
1729 . ta (u;\\n[.l]-\\n[.i])R
1730 \\*[eqn*div]\t\\*[eqn*num]
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]
1741 . ta (u;\\n[.l]-\\n[.i])R
1744 .\". if !'\*(.T'html' .sp \\n[DD]u
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]
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
1761 . if \\n[eqn*type]=2 .EQN-HTML-IMAGE-END
1765 .\" ****************************
1766 .\" ******** module tbl ********
1767 .\" ****************************
1769 .nr tbl*have-header 0
1770 .\" This gets called if TS occurs before the first paragraph.
1773 .\" cov*ab-init aliases TS to @TS
1778 .if '\\$1'H' .di tbl*header-div
1782 .if \\n[tbl*have-header] \{\
1783 . ie \\n[.t]-\\n[tbl*header-ht]-1v .tbl*print-header
1787 .de tbl*print-header
1794 .ie '\\n[.z]'tbl*header-div' \{\
1799 . ie \\n[dn]+\\n[FM]+\\n[HM]+2v>=\\n[.p] \{\
1800 . @error ridiculously long table header
1805 . nr tbl*header-ht \\n[dn]
1806 . ds@need \\n[dn]u+1v
1808 . nr tbl*have-header 1
1811 .el .@error-recover .TH without .TS H
1813 .de @div-end!tbl*header-div
1818 .ie '\\n(.z'tbl*header-div' .@error-recover .TS H but no .TH before .TE
1820 . nr tbl*have-header 0
1821 . if !'\*(.T'html' .sp \\n[DD]u
1828 .if \\n[tbl*have-header] \{\
1835 .\" ****************************
1836 .\" ******** module pic ********
1837 .\" ****************************
1843 .ie \\n[.$]<2 .@error bad arguments to PS (not preprocessed with pic?)
1845 . ds@need (u;\\$1)+1v
1846 . in +(u;\\n[.l]-\\n[.i]-\\$2/2>?0)
1855 .\" ****************************
1856 .\" ******** module ref ********
1857 .\" ****************************
1860 .rm [A [B [C [D [E [G [I [J [N [O [P [Q [R [S [T [V
1864 .ds ref*spec!0 Q A T1 S V N P I C D O
1866 .ds ref*spec!1 Q A T2 J S V N P I C D O
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
1872 .ds ref*spec!4 Q A T2 R G P I C D O
1879 .ie d ref*spec!\\$1 .ref*build \\*[ref*spec!\\$1]
1881 . @error unknown reference type `\\$1'
1882 . ref*build \\*[ref*spec!0]
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
1894 .\" period after reference
1896 .\" comma before reference
1898 .\" comma after reference
1900 .\" start collected references
1902 .als ref*print ref*end-print
1907 .\" end collected references
1910 .als ref*print ref*normal-print
1912 .de ref*normal-print
1913 .ie d [F .FS "\\*([.\\*([F\\*(.]"
1919 .ie d [F .IP "\\*([F."
1923 .als ref*print ref*normal-print
1925 .rm ref*string ref*post-punct
1926 .nr ref*suppress-period 1
1929 . ie d ref*add-\\$1 .ref*add-\\$1
1930 . el .ref*add-dflt \\$1
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]
1945 .ref*field T , " " "\fI" "" "\fP"
1946 .if r [T .nr ref*suppress-period \\n([T
1949 .ref*field T , " " "\\*Q" "" "\\*U"
1950 .if r [T .nr ref*suppress-period \\n([T
1953 .ie \\n([P>0 .ref*field P , " " "pp. "
1954 .el .ref*field P , " " "p. "
1957 .ref*field J , " " \fI "" \fP
1960 .ref*field D "" " " ( )
1963 .ref*field E , " " "ed. "
1966 .ref*field G "" " " ( )
1969 .ref*field B "" " " "in \fI" "" \fP
1973 .ie r [O .nr ref*suppress-period \\n([O
1974 .el .nr ref*suppress-period 1
1978 .if r [A .nr ref*suppress-period \\n([A
1981 .ref*field V "" " " \fB \fR
1984 .ref*field N "" ( "" ")"
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.
1999 .if d ref*string \{\
2000 . ie d ref*post-punct \{\
2001 . as ref*string "\\$2\\*[ref*post-punct]\\$3\"
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.
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'
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'
2027 .ds \\$1 \Z'\v'\En[.cdp]u'\h'(u;-\En[.w]-\w'\\$2'/2)'\\$2'
2030 .ds \\$1 \Z'\h'(u;-\En[.w]-\w'\\$2'/2)'\
2031 \v'(u;\En[.cdp]-\En[.cht]+\En[rst]+\En[rsb]/2)'\\$2'
2034 .ds \\$1 \Z'\h'(u;\w'x'-\w'\\$2'/2)'\\$2'
2036 .acc*prefix-def ' \'
2037 .acc*prefix-def ` \`
2039 .acc*prefix-def , \(ac
2040 .acc*prefix-def : \(ad
2042 .\" improved accent marks
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
2056 .char \[hooko] o\E*[hook]
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' \{\
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.
2105 .nr bell_localisms 1
2110 .if r bell_localisms \f(CW\\$*\fP
2113 .if r bell_localisms \{\