5 Copyright (C) 1989-2018 Free Software Foundation, Inc.
6 Written by James Clark (jjc@jclark.com)
8 This file is part of groff.
10 groff 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 3 of the License, or
13 (at your option) any later version.
15 groff 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
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 .if !\n(.g .ab These ms macros require groff.
25 . ab The groff ms macros do not work in compatibility mode.
26 .\" Enable warnings (only if none are given on the command line).
27 .\" You can delete this if you want.
28 .if (\n[.warn] == 65543) .warn
29 .\" See if already loaded.
36 .tm \\n(.F:\\n(.c: macro error: \\$*
39 .tm \\n(.F:\\n(.c: macro warning: \\$*
42 .ab \\n(.F:\\n(.c: fatal macro error: \\$*
45 .@error sorry, \\$0 not implemented
48 .als TM @not-implemented
49 .als CT @not-implemented
53 .if !rPO .nr PO \\n(.o
54 .\" a non-empty environment
62 .ds REFERENCES References
64 .ds TOC Table of Contents
77 .ds MO \E*[MONTH\n[mo]]
78 .ds DY \n[dy] \*[MO] \n[year]
80 .if \\n[.$] .ds DY "\\$*
83 .if \\n[.$] .ds DY "\\$*
88 .tm \\$1\t\\$2\t\\$3\t\\$4 ... \\n[PN]
90 .\" print an error message and then try to recover
92 .@error \\$@ (recovering)
95 . \"@warning automatically terminating diversion \\n(.z
96 . ie d @div-end!\\n(.z .@div-end!\\n(.z
97 . el .*div-end-default
99 . \" ensure that we don't loop forever
100 . if \\n[*pop-count]>20 .@fatal recovery failed
102 .while !'\\n[.ev]'0' .ev
114 .\" ****************************
115 .\" ******** module cov ********
116 .\" ****************************
117 .\" Cover sheet and first page.
118 .de cov*err-not-after-first-page
119 .@error \\$0 is not allowed after the first page has started
121 .de cov*err-not-before-tl
122 .@error \\$0 is not allowed before TL
124 .de cov*err-not-again
125 .@error \\$0 is not allowed more than once
127 .de cov*err-not-after-ab
128 .@error \\$0 is not allowed after first AB, LP, PP, IP, SH or NH
130 .als AU cov*err-not-before-tl
131 .als AI cov*err-not-before-tl
132 .als AB cov*err-not-before-tl
133 .de cov*first-page-init
134 .\" Invoked by '.wh 0' trap on first page.
135 .\" We should not come here again, but at short page length,
136 .\" recursion may occur; remove trap and macro to avoid it.
137 .ch cov*first-page-init
138 .rm cov*first-page-init
139 .if !'\\n[.ev]'0' \{\
140 . @error must be in top-level environment, not '\\n[.ev]',
141 . @error when first page is started
144 .als RP cov*err-not-after-first-page
146 .ie \\n[cov*rp-format] \{\
157 .CHECK-FOOTER-AND-KEEP
159 .wh 0 cov*first-page-init
160 .\" This handles the case where FS occurs before TL or LP.
167 .\" released paper format
170 .if \\n[.$] .if '\\$1'no' .nr cov*rp-no 1
176 .als TL cov*err-not-again
196 .di cov*au-div!\\n[cov*n-au]
199 .ie (\\n[PS] >= 1000) \
200 . ps (\\n[PS]z / 1000u)
210 .ie !\\n[cov*n-au] .@error AI before AU
212 . di cov*ai-div!\\n[cov*n-au]
215 . ie (\\n[PS] >= 1000) \
216 . ps (\\n[PS]z / 1000u)
245 .als cov*ab-init @nop
263 .als AB cov*err-not-after-ab
277 . als cov*tl-au-print @nop
283 . if '\*(.T'html' \{\
297 . als cov*tl-au-print @nop
305 . als AE cov*err-not-again
308 . ie '\\n(.z'cov*ab-div' \{\
309 . als AE cov*err-not-again
312 .\" nr cov*ab-height \\n[dn]
317 . el .@error AE without AB
320 .de @div-end!cov*ab-div
326 . ie \\n[cov*rp-format] .cov*rp-print
327 . el .cov*draft-print
330 . if \\n[cov*rp-format] \{\
331 . @warning RP format but no TL
335 . CHECK-FOOTER-AND-KEEP
341 .nr cov*page-length \\n[.p]
346 . if !'\*(.T'html' .nf
353 .if \\n[cov*fn-height] \{\
354 . sp |(u;\\n[cov*page-length]-\\n[FM]\
355 -\\n[cov*fn-height]-\\n[fn@sep-dist]>?\\n[nl])
360 . ie \\n[cov*rp-no] .rm cov*fn-div
362 . rn cov*fn-div fn@overflow-div
363 . nr fn@have-overflow 1
368 .CHECK-FOOTER-AND-KEEP
369 .\" If anything was printed below where the footer line is normally
370 .\" printed, then that's an overflow.
371 .if -\\n[FM]/2+1v+\\n[cov*page-length]<\\n[nl] .@error cover sheet overflow
372 .pl \\n[cov*page-length]u
374 .if !\\n[cov*rp-no] .cov*tl-au-print
399 .while \\n[cov*i]<=\\n[cov*n-au] \{\
400 . ie '\*(.T'html' .br
401 . el .sp \\n[cov*sp]u
402 . cov*au-div!\\n[cov*i]
403 . ie d cov*ai-div!\\n[cov*i] \{\
405 . cov*ai-div!\\n[cov*i]
415 .\" start of footnote on cover
417 .if \\n[cov*in-fn] \{\
425 .if !\\n[cov*fn-height] .ns
426 .ie \\n[.$] .FP "\\$1" no
429 .de @div-end!cov*fn-div
432 .\" end of footnote on cover
434 .ie '\\n(.z'cov*fn-div' \{\
439 . nr cov*fn-height +\\n[dn]
441 .el .@error FE without matching FS
443 .\" ***************************
444 .\" ******** module pg ********
445 .\" ***************************
446 .\" Page-level formatting.
447 .\" > 0 if we have a footnote on the current page
459 .ds pg*OH '\E*[LH]'\E*[CH]'\E*[RH]'
460 .ds pg*EH '\E*[LH]'\E*[CH]'\E*[RH]'
461 .ds pg*OF '\E*[LF]'\E*[CF]'\E*[RF]'
462 .ds pg*EF '\E*[LF]'\E*[CF]'\E*[RF]'
470 .ie \\n%=1 .if \\n[pg*P1] .tl \\*[pg*OH]
472 . ie o .tl \\*[pg*OH]
482 .ie r bell_localisms \{\
488 .wh -\n[FM]u pg@bottom
489 .wh -\n[FM]u/2u pg*footer
493 .if !'\\n(.z'' .error-recover MC while diversion open
495 .ie \\n[pg@ncols]>1 .pg@super-eject
497 . \" flush out any floating keeps
498 . while \\n[kp@tail]>\\n[kp@head] \{\
504 . nr pg@colw \\n[LL]*7/15
505 . nr pg*gutw \\n[LL]-(2*\\n[pg@colw])
509 . nr pg@colw (n;\\$1)<?\\n[LL]
510 . ie \\n[.$]<2 .nr pg*gutw \\n[MINGW]
511 . el .nr pg*gutw (n;\\$2)
512 . nr pg@ncols \\n[LL]-\\n[pg@colw]/(\\n[pg@colw]+\\n[pg*gutw])+1
513 . ie \\n[pg@ncols]>1 \
514 . nr pg*gutw \\n[LL]-(\\n[pg@ncols]*\\n[pg@colw])/(\\n[pg@ncols]-1)
517 .DEVTAG ".mc \\n[pg@ncols] \\n[pg@colw] \\n[pg*gutw]"
520 .nr pg@fn-colw \\n[pg@colw]*5/6
530 .\" top of page macro
532 .ch pg*footer -\\n[FM]u/2u
535 .nr pg@fn-bottom-margin 0
549 .\" Handle footnote overflow before floating keeps, because the keep
550 .\" might contain an embedded footnote.
558 .\" move pg@bottom and pg*footer out of the way
559 .ch pg@bottom \\n[.p]u*2u
560 .ch pg*footer \\n[.p]u*2u
565 .if \\n[pg@fn-flag] .fn@bottom-hook
567 .ie \\n[pg*col-num]<\\n[pg@ncols] .pg*end-col
571 'sp |\\n[pg*col-top]u
572 .po (u;\\n[PO]+(\\n[pg@colw]+\\n[pg*gutw]*\\n[pg*col-num]))
573 .\"po +(u;\\n[pg@colw]+\\n[pg*gutw])
578 .\" Make sure we don't exit if there are still floats or footnotes
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
590 . if \\n[pg@text-ended] .ex
591 . if r pg*next-number \{\
592 . pn \\n[pg*next-number]
594 . if d pg*next-format \{\
595 . af PN \\*[pg*next-format]
602 .\" pg@begin number format
605 . nr pg*next-number (;\\$1)
606 . ie \\n[.$]>1 .ds pg*next-format \\$2
607 . el .rm pg*next-format
609 .el .rr pg*next-number
612 .\" print the footer line
619 .\" flush out any keeps or footnotes
622 .if !'\\n(.z'' .@error-recover diversion open while ejecting page
623 .\" Make sure we stay in the end macro while there is still footnote
624 .\" overflow left, or floating keeps.
625 .while \\n[kp@tail]>\\n[kp@head]:\\n[pg@fn-flag] \{\
638 .\" ***************************
639 .\" ******** module fn ********
640 .\" ***************************
644 .\" Round it vertically
646 .nr fn@sep-dist \n[.v]
650 .ds * \E*[par@sup-start]\En+[fn*text-num]\E*[par@sup-end]
654 .ie \\n[.$] .fn*do-FS "\\$1" no
656 . ie \\n[fn*text-num]>\\n[fn*note-num] .fn*do-FS \\n+[fn*note-num]
660 .\" Second argument of 'no' means don't embellish the first argument.
662 .if \\n[fn*open] .@error-recover nested FS
665 . \" Ensure that the first line of the footnote is on the same page
666 . \" as the reference. I think this is minimal.
670 . ie \\n[pg@fn-flag] .nr fn*need +\\n[fn:PD]
671 . el .nr fn*need +\\n[fn@sep-dist]
672 . ne \\n[fn*need]u+\\n[.V]u>?0
682 .ie !\\n[fn*open] .@error FE without FS
690 .nr fn@have-overflow 0
691 .\" called at the top of each column
694 .nr fn*page-bottom-pos 0-\\n[FM]-\\n[pg@fn-bottom-margin]
695 .ch pg@bottom \\n[fn*page-bottom-pos]u
696 .if \\n[fn@have-overflow] \{\
697 . nr fn@have-overflow 0
705 .\" This is called at the bottom of the column if pg@fn-flag is set.
708 .nr fn@have-overflow 0
709 .nr fn@bottom-pos \\n[.p]-\\n[FM]-\\n[pg@fn-bottom-margin]+\\n[.v]
711 .nr fn@bottom-pos -\\n[.v]
713 .ie \\n[nl]+\\n[fn@sep-dist]+\n[.V]>\\n[fn@bottom-pos] \{\
714 . rn fn@div fn@overflow-div
715 . nr fn@have-overflow 1
718 . if \\n[pg@ncols]>1 \
719 . if \\n[fn*max-width]>\\n[pg@fn-colw] \
720 . nr pg@fn-bottom-margin \\n[.p]-\\n[FM]-\\n[nl]+1v
721 . wh \\n[fn@bottom-pos]u fn*catch-overflow
727 . if '\\n(.z'fn@overflow-div' \{\
729 . nr fn@have-overflow \\n[dn]>0
731 . ch fn*catch-overflow
734 .de fn*catch-overflow
740 .if '\\n[.ev]'fn' .ev
744 .als @div-end!fn*embed-div @div-end!fn@div
748 . if !\\n[pg@fn-flag] .ns
753 .ie '\\n(.z'fn@div' \{\
755 . nr fn*page-bottom-pos -\\n[dn]
756 . nr fn*max-width \\n[fn*max-width]>?\\n[dl]
757 . if !\\n[pg@fn-flag] .nr fn*page-bottom-pos -\\n[fn@sep-dist]
759 . nr fn*page-bottom-pos \\n[nl]-\\n[.p]+\n[.V]>?\\n[fn*page-bottom-pos]
760 . ch pg@bottom \\n[fn*page-bottom-pos]u
763 . ie '\\n(.z'fn*embed-div' \{\
765 . rn fn*embed-div fn*embed-div!\\n[fn*embed-count]
766 \!. fn*embed-start \\n[fn*embed-count]
768 ' sp (u;\\n[dn]+\\n[fn@sep-dist]+\\n[.V])
770 . nr fn*embed-count +1
774 . @error-recover unclosed diversion within footnote
783 . rm fn*embed-div!\\$1
789 \!. fn*embed-start \\$1
794 .ie '\\n(.z'fn*null' \{\
800 .\" It's important that fn@print-sep use up exactly fn@sep-dist vertical
805 .vs \\n[fn@sep-dist]u
810 .\" ***************************
811 .\" ******** module kp ********
812 .\" ***************************
819 .if !'\\n(.z'' .@error-recover KF while open diversion
826 .ie '\\n(.z'kp*div' .kp*end
828 . ie '\\n(.z'kp*fdiv' .kp*fend
829 . el .@error KE without KS or KF
839 .ie '\\n(.z'' .ds@need \\$1
842 .\" end non-floating keep
855 .\" end floating keep
860 .ie \\n[.t]-(\\n[.k]>0*1v)>\\n[dn] \{\
868 . rn kp*fdiv kp*div!\\n[kp@tail]
869 . nr kp*ht!\\n[kp@tail] 0\\n[dn]
873 .\" top of page processing for KF
876 .if !\\n[kp*doing-top] \{\
883 .\" If the first keep won't fit, only force it out if we haven't had a
884 .\" footnote and we're at the top of the page.
885 .nr kp*force \\n[pg@fn-flag]=0&(\\n[nl]<=\\n[pg@header-bottom])
887 .while \\n[kp@tail]>\\n[kp@head]&\\n[kp*fits] \{\
888 . ie \\n[.t]>\\n[kp*ht!\\n[kp@head]]:\\n[kp*force] \{\
890 . \" It's important to advance kp@head before bringing
891 . \" back the keep, so that if the last line of the
892 . \" last keep springs the bottom of page trap, a new
893 . \" page will not be started unnecessarily.
894 . rn kp*div!\\n[kp@head] kp*temp
904 .\" ***************************
905 .\" ******** module ds ********
906 .\" ***************************
907 .\" Displays and non-floating keeps.
909 .ds*end!\\n[\\n[.ev]:ds-type]
910 .nr \\n[.ev]:ds-type 0
913 .if \\n[\\n[.ev]:ds-type] \{\
914 . @error automatically terminating display
919 .ie \\n[\\n[.ev]:ds-type] .DE
923 .@error DE without DS, ID, CD, LD or BD
927 .nr \\n[.ev]:ds-type 1
934 .ie \\n[.$] .in +(n;\\$1)
949 .als ds*end!1 ds*common-end
952 .nr \\n[.ev]:ds-type 2
957 .ie '\\n(.z'ds*div' \{\
960 . in (u;\\n[.l]-\\n[dl]/2>?0)
965 .el .@error-recover mismatched DE
972 . nr \\n[.ev]:ds-type 4
981 . ie '\\$1'I' .ID \\$2
986 . nr \\n[.ev]:ds-type 3
991 . while \\n[.t]<=(\\$1)&(\\n[nl]>\\n[pg@header-bottom]) \{\
999 .ie '\\n(.z'ds*div' \{\
1008 .el .@error-recover mismatched DE
1011 .ie '\\n(.z'ds*div' \{\
1015 . in (u;\\n[.l]-\\n[dl]/2>?0)
1021 .el .@error-recover mismatched DE
1023 .\" ****************************
1024 .\" ******** module par ********
1025 .\" ****************************
1026 .\" Paragraph-level formatting.
1027 .\" Load time initialization.
1029 .\" PS and VS might have been set on the command line
1033 .\" don't set LT so that it can be defaulted from LL
1034 .ie rLT .lt \\n[LT]u
1036 .ie (\\n[PS] >= 1000) \
1037 . ps (\\n[PS]z / 1000u)
1040 .\" don't set VS so that it can be defaulted from PS
1042 . ie (\\n[VS] >= 1000) \
1043 . par*vs "(\\n[VS]p / 1000u)"
1048 . ie (\\n[PS] >= 1000) \
1049 . par*vs "((\\n[PS]p / 1000u) + 2p)"
1051 . par*vs "(\\n[PS] + 2)"
1053 .if dFAM .fam \\*[FAM]
1057 .CHECK-FOOTER-AND-KEEP
1060 .\" If it's too big to be in points, treat it as units.
1061 .ie (p;\\$1)>=40p .vs (u;\\$1)
1065 .nr 0:li (u;\\n[LL]/12)
1072 .aln \\n[.ev]:MCLL LL
1074 .aln \\n[.ev]:MCLT LT
1080 .\" happens when the first page begins
1082 .if !rLT .nr LT \\n[LL]
1083 .if !rFL .nr FL \\n[LL]*5/6
1085 . ie (\\n[PS] >= 1000) \
1086 . nr VS (\\n[PS] + 2000)
1088 . nr VS (\\n[PS] + 2)
1092 . ie (\\n[PS] >= 1000) \
1093 . nr FPS (\\n[PS] - 2000)
1095 . nr FPS (\\n[PS] - 2)
1098 . ie (\\n[FPS] >= 1000) \
1099 . nr FVS (\\n[FPS] + 2000)
1101 . nr FVS (\\n[FPS] + 2)
1103 .\" don't change environment 0
1105 .ie (\\n[PS] >= 1000) \
1106 . ps (\\n[PS]z / 1000u)
1111 .ie (\\n[VS] >= 1000) \
1112 . par*vs "(\\n[VS]p / 1000u)"
1115 .if !rPD .nr PD .3v>?\n(.V
1116 .if !rDD .nr DD .5v>?\n(.V
1118 .if !rFPD .nr FPD \\n[PD]/2
1120 .if !dFAM .ds FAM \\n[.fam]
1142 .aln fn:MCLL pg@fn-colw
1143 .aln fn:MCLT pg@fn-colw
1149 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1152 .nr \\n[.ev]:ds-type 0
1157 .if \\n[need_eo_tl]>0 .DEVTAG-EO-TL
1159 .if \\n[need_eo_h]>0 .DEVTAG-EO-H
1165 .ie \\n[pg@ncols]>1 \{\
1166 . ll (u;\\n[\\n[.ev]:MCLL]-\\n[\\n[.ev]:ri]-\\n[\\n[.ev]:pri])
1167 . lt \\n[\\n[.ev]:MCLT]u
1170 . ll (u;\\n[\\n[.ev]:LL]-\\n[\\n[.ev]:ri]-\\n[\\n[.ev]:pri])
1171 . lt \\n[\\n[.ev]:LT]u
1173 .in (u;\\n[\\n[.ev]:li]+\\n[\\n[.ev]:pli])
1176 .ie (\\n[\\n[.ev]:PS] >= 1000) \
1177 . ps (\\n[\\n[.ev]:PS]z / 1000u)
1179 . ps \\n[\\n[.ev]:PS]
1180 .ie (\\n[\\n[.ev]:VS] >= 1000) \
1181 . par*vs "(\\n[\\n[.ev]:VS]p / 1000u)"
1183 . par*vs \\n[\\n[.ev]:VS]
1193 .\" This can be redefined by the user.
1197 .\" \n[PORPHANS] sets number of initial lines of any paragraph,
1198 .\" which must be kept together, without any included page break.
1199 .\" Initialise to reproduce original behaviour; user may adjust it.
1200 .if !rPORPHANS .nr PORPHANS 1
1204 .nr \\n[.ev]:pli \\$1
1205 .nr \\n[.ev]:pri \\$2
1207 .sp \\n[\\n[.ev]:PD]u
1208 .ne \\n[PORPHANS]v+\\n(.Vu
1218 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1222 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1223 .if !'\*(.T'html' .ti +\\n[\\n[.ev]:ai]u
1226 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1227 .par*start \\n[QI] \\n[QI]
1230 .par*start \\n[\\n[.ev]:PI] 0
1231 .ti -\\n[\\n[.ev]:PI]u
1234 .if \\n[.$]>1 .nr \\n[.ev]:ai (n;\\$2)
1235 .par*start \\n[\\n[.ev]:ai] 0
1237 . \" Divert the label so as to freeze any spaces.
1244 . ti -\\n[\\n[.ev]:ai]u
1245 . ie \\n[dl]+1n<=\\n[\\n[.ev]:ai] \{\
1247 \\*[par*label]\h'|\\n[\\n[.ev]:ai]u'\c
1259 .\" We don't want margin characters to be attached when we divert
1260 .\" the tag. Since there's no way to save and restore the current
1261 .\" margin character, we have to switch to a new environment, taking
1262 .\" what we need of the old environment with us.
1263 .de par*push-tag-env
1264 .nr par*saved-font \\n[.f]
1265 .nr par*saved-size \\n[.s]z
1266 .nr par*saved-ss \\n[.ss]
1267 .ds par*saved-fam \\n[.fam]
1271 .ft \\n[par*saved-font]
1272 .ps \\n[par*saved-size]u
1273 .ss \\n[par*saved-ss]
1274 .fam \\*[par*saved-fam]
1281 .nr \\n[.ev]:li!\\n[\\n[.ev]:il] \\n[\\n[.ev]:li]
1282 .nr \\n[.ev]:ri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ri]
1283 .nr \\n[.ev]:ai!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ai]
1284 .nr \\n[.ev]:pli!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pli]
1285 .nr \\n[.ev]:pri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pri]
1287 .nr \\n[.ev]:li +\\n[\\n[.ev]:ai]
1288 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1293 .ie \\n[\\n[.ev]:il] \{\
1295 . nr \\n[.ev]:ai \\n[\\n[.ev]:ai!\\n[\\n[.ev]:il]]
1296 . nr \\n[.ev]:li \\n[\\n[.ev]:li!\\n[\\n[.ev]:il]]
1297 . nr \\n[.ev]:ri \\n[\\n[.ev]:ri!\\n[\\n[.ev]:il]]
1298 . nr \\n[.ev]:pli \\n[\\n[.ev]:pli!\\n[\\n[.ev]:il]]
1299 . nr \\n[.ev]:pri \\n[\\n[.ev]:pri!\\n[\\n[.ev]:il]]
1301 .el .@error unbalanced \\$0
1302 .ie '\\$0'QE' .par*start 0 0
1307 .nr \\n[.ev]:li!\\n[\\n[.ev]:il] \\n[\\n[.ev]:li]
1308 .nr \\n[.ev]:ri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ri]
1309 .nr \\n[.ev]:ai!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ai]
1310 .nr \\n[.ev]:pli!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pli]
1311 .nr \\n[.ev]:pri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pri]
1313 .nr \\n[.ev]:li +\\n[QI]
1314 .nr \\n[.ev]:ri +\\n[QI]
1315 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1319 .\" start boxed text
1326 .nr par*box-in \\n[.in]
1327 .\" remember what 1n is, just in case the point size changes
1332 .ti \\n[par*box-in]u+1n
1334 .de @div-end!par*box-div
1338 .\" Postpone the drawing of the box until we're in the top-level
1339 .\" diversion, in case there's a footnote inside the box.
1341 .ie '\\n(.z'par*box-div' \{\
1343 . if \n[.V]>.25m .sp
1345 . if \n[.V]>.25m .sp
1351 . nr \\n[.ev]:ri -\\n[par*box-n]
1352 . nr \\n[.ev]:li -\\n[par*box-n]
1353 . in -\\n[par*box-n]u
1354 . ll +\\n[par*box-n]u
1355 . lt +\\n[par*box-n]u
1356 . par*box-draw \\n[.i]u \\n[.l]u-(\\n[.H]u==1n*1n)
1358 .el .@error B2 without B1
1361 .de par*box-mark-top
1366 .el \!.par*box-mark-top
1370 . nr par*box-in \\n[.i]
1371 . nr par*box-ll \\n[.l]
1372 . nr par*box-vpt \\n[.vpt]
1373 . nr par*box-ad \\n[.j]
1379 \D'l (u;\\n[.l]-\\n[.i]) 0'\
1380 \D'l 0 |\\n[par*box-top]u'\
1381 \D'l -(u;\\n[.l]-\\n[.i]) 0'\
1382 \D'l 0 -|\\n[par*box-top]u'
1385 . in \\n[par*box-in]u
1386 . ll \\n[par*box-ll]u
1387 . vpt \\n[par*box-vpt]
1388 . ad \\n[par*box-ad]
1390 .el \!.par*box-draw \\$1 \\$2
1392 .\" \n[HORPHANS] sets how many lines of the following paragraph must be
1393 .\" kept together, with a preceding section header. Initialise it,
1394 .\" to reproduce original behaviour; user may change it.
1395 .if !rHORPHANS .nr HORPHANS 1
1397 .\" \n[GROWPS] and \n[PSINCR] cause auto-increment of header point size.
1398 .\" Initialise them, so they have no effect, unless explicitly set by
1400 .if !rGROWPS .nr GROWPS 0
1401 .if !rPSINCR .nr PSINCR 1p
1405 .\" Keep the heading and the first few lines of the next paragraph
1406 .\" together. (\n[HORPHANS] defines "first few" -- default = 1; user
1407 .\" may redefine it).
1408 .nr sh*minvs \\n[HORPHANS]v
1409 .if \\n[sh*psincr]<0 .nr sh*psincr 0
1410 .ie \\n(VS<1000 .par*vs \\n(VSp+\\n[sh*psincr]u
1411 .el .par*vs \\n(VSp/1000u+\\n[sh*psincr]u
1412 .ne 2v+\\n[sh*minvs]u+\\n[\\n[.ev]:PD]u+\\n(.Vu
1413 .\" Adjust point size for heading text, as specified by \n[GROWPS] and
1415 .ie \\n(PS<1000 .ps \\n(PS+\\n[sh*psincr]u
1416 .el .ps \\n(PSz/1000u+\\n[sh*psincr]u
1421 .\" Standard ms implementation does not expect an argument,
1422 .\" but allow ".SH n" to make heading point size match ".NH n",
1423 .\" for same "n", when \n[GROWPS] and \n[PSINCR] are set.
1425 . if 0\\$1>0 .nr sh*psincr (\\n[GROWPS]-0\\$1)*\\n[PSINCR]
1428 . if '\*(.T'html' .nr need_eo_h 1
1430 .\" TL, AU, and AI are aliased to these in cov*ab-init.
1452 .\" In paragraph macros.
1454 .ie (\\n[\\n[.ev]:PS] >= 1000) \
1455 . ps (\\n[\\n[.ev]:PS]z / 1000u)
1457 . ps \\n[\\n[.ev]:PS]
1468 .\" par*define-font-macro macro font
1469 .de par*define-font-macro
1472 . nr par*prev-font \En[.f]
1473 \&\E$3\f[\\$2]\E$1\f[\En[par*prev-font]]\E$2
1478 .par*define-font-macro B B
1479 .par*define-font-macro I I
1480 .par*define-font-macro BI BI
1481 .par*define-font-macro CW CR
1482 .\" underline a word
1484 \Z'\\$1'\v'.25m'\D'l \w'\\$1'u 0'\v'-.25m'\\$2
1488 .nr par*bxw \w'\\$1'+.4m
1489 \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''\
1493 .\" The first time UX is used, put a registered mark after it.
1496 \s[\\n[.s]*8u/10u]UNIX\s0\\$1\\*[par*ux-rg]
1499 .ds par@sup-start \v'-.9m\s'\En[.s]*7u/10u'+.7m'
1500 .als { par@sup-start
1501 .ds par@sup-end \v'-.7m\s0+.9m'
1503 .\" footnote paragraphs
1504 .\" FF is the footnote format
1506 .\" This can be redefined. It gets a second argument of 'no' if the
1507 .\" first argument was supplied by the user, rather than automatically.
1510 .if !d par*fp!\\n[FF] \{\
1511 . @error unknown footnote format '\\n[FF]'
1514 .ie '\\$2'no' .par*fp!\\n[FF]-no "\\$1"
1515 .el .par*fp!\\n[FF] "\\$1"
1519 \&\\*[par@sup-start]\\$1\\*[par@sup-end]\ \c
1542 .@IP "\\$1." (u;\\n[\\n[.ev]:PI]*2)
1545 .@IP "\\$1" (u;\\n[\\n[.ev]:PI]*2)
1547 .\" ***************************
1548 .\" ******** module nh ********
1549 .\" ***************************
1550 .\" Numbered headings.
1551 .\" nh*hl is the level of the last heading
1553 .\" SN-DOT and SN-NO-DOT represent the section number of
1554 .\" the current heading, with and without a terminating dot.
1557 .\" SN-STYLE sets the statement numbering style used in headings
1558 .\" (either SN-DOT or SN-NO-DOT); for backward compatibility with
1559 .\" earlier ms versions, the default is SN-DOT
1560 .als SN-STYLE SN-DOT
1561 .\" Also for backward compatibility, let SN represent SN-DOT.
1563 .\" numbered heading
1570 . nr H\\n[nh*hl] 0\\$1
1573 . if !\\n[nh*hl] \{\
1576 . @error missing arguments to .NH S
1580 . nr nh*ohl \\n[nh*hl]
1583 . ie \\n[nh*hl]<=0 \{\
1588 . if \\n[nh*hl]-\\n[nh*ohl]>1 \
1589 . @warning .NH \\n[nh*ohl] followed by .NH \\n[nh*hl]
1593 . while \\n[nh*hl]>\\n[nh*ohl] \{\
1599 .ds SN-NO-DOT \\n(H1
1601 .while \\n[nh*i]<\\n[nh*hl] \{\
1603 . as SN-NO-DOT .\\n[H\\n[nh*i]]
1605 .ds SN-DOT \\*[SN-NO-DOT].
1606 .nr sh*psincr (\\n[GROWPS]-\\n[nh*hl])*\\n[PSINCR]
1609 . if '\*(.T'html' .nr need_eo_h 1
1612 .\" ****************************
1613 .\" ******** module toc ********
1614 .\" ****************************
1615 .\" Table of contents generation.
1619 .ie \\n[.$] .XA "\\$1"
1622 .de @div-end!toc*div
1626 .ie '\\n(.z'toc*div' \{\
1627 . if d toc*num .toc*end-entry
1629 . ie '\\$1'no' .ds toc*num
1630 . el .ds toc*num "\\$1
1632 . el .ds toc*num \\n[PN]
1639 .el .@error XA without XS
1642 .ie '\\n(.z'toc*div' \{\
1643 . if d toc*num .toc*end-entry
1647 .el .@error XE without XS
1658 . ie (\\n[PS] >= 1000) \
1659 . ps ((\\n[PS]z / 1000u) + 2z)
1668 .char \[toc*leader-char] .\h'1m'
1669 .lc \[toc*leader-char]
1670 .ta (u;\\n[.l]-\\n[.i]-\w'000') (u;\\n[.l]-\\n[.i])R
1675 .\" print the table of contents on page i
1681 .\" ****************************
1682 .\" ******** module eqn ********
1683 .\" ****************************
1692 .ie '\\$1'L' .nr eqn*type 0
1694 . ie '\\$1'I' .nr eqn*type 1
1697 . if !'\\$1'C' .ds eqn*num "\\$1
1702 .if '\*(.T'html' \{\
1706 .if \\n[eqn*type]=0 .EQN-HTML-IMAGE-LEFT
1707 .if \\n[eqn*type]=1 \{\
1708 . if '\*(.T'html' .RS
1709 .EQN-HTML-IMAGE-INLINE
1711 .if \\n[eqn*type]=2 .EQN-HTML-IMAGE
1714 .de @div-end!eqn*div
1717 .\" Note that geqn mark and lineup work correctly in centered equations.
1719 .ie !'\\n(.z'eqn*div' .@error-recover mismatched EN
1724 . if !'\\*[eqn*num]'' .nr eqn*have-num 1
1725 . ie \\n[dl]:\\n[eqn*have-num] \{\
1728 . ds eqn*tabs \\n[.tabs]
1731 .\" --fixme-- this really should not be necessary
1732 .\" and indicates that there is extra space creeping
1733 .\" into an equation when ps4html is enabled..
1734 . ie r ps4html .ds@need \\n[dn]u-1v+\n[.V]u+1i
1735 . el .ds@need \\n[dn]u-1v+\n[.V]u
1737 . ie \\n[eqn*type]=0 \{\
1738 . ta (u;\\n[.l]-\\n[.i])R
1739 \\*[eqn*div]\t\\*[eqn*num]
1742 . ie \\n[eqn*type]=1 .ta \\n[DI]u \
1743 (u;\\n[.l]-\\n[.i])R
1744 . el .ta (u;\\n[.l]-\\n[.i]/2)C \
1745 (u;\\n[.l]-\\n[.i])R
1746 \t\\*[eqn*div]\t\\*[eqn*num]
1750 . ta (u;\\n[.l]-\\n[.i])R
1753 .\". if !'\*(.T'html' .sp \\n[DD]u
1758 .\" must terminate empty equations in html and ps4html as they contain
1759 .\" the EQN-HTML-IMAGE-END suppression nodes
1760 . if \\n[dl] .chop eqn*div
1761 . if '\*(.T'html' \\*[eqn*div]
1762 . if r ps4html \\*[eqn*div]
1764 . if !'\*(.T'html' .fi
1765 . if \\n[eqn*type]=0 .EQN-HTML-IMAGE-END
1766 . if \\n[eqn*type]=1 \{\
1767 . EQN-HTML-IMAGE-END
1768 . if '\*(.T'html' .RE
1770 . if \\n[eqn*type]=2 .EQN-HTML-IMAGE-END
1776 .\" ****************************
1777 .\" ******** module tbl ********
1778 .\" ****************************
1780 .nr tbl*have-header 0
1781 .\" This gets called if TS occurs before the first paragraph.
1784 .\" cov*ab-init aliases TS to @TS
1789 .if '\\$1'H' .di tbl*header-div
1790 .if '\*(.T'html' \{\
1797 .if \\n[tbl*have-header] \{\
1798 . ie \\n[.t]-\\n[tbl*header-ht]-1v .tbl*print-header
1802 .de tbl*print-header
1809 .ie '\\n[.z]'tbl*header-div' \{\
1814 . ie \\n[dn]+\\n[FM]+\\n[HM]+2v>=\\n[.p] \{\
1815 . @error ridiculously long table header
1820 . nr tbl*header-ht \\n[dn]
1821 . ds@need \\n[dn]u+1v
1823 . nr tbl*have-header 1
1826 .el .@error-recover .TH without .TS H
1828 .de @div-end!tbl*header-div
1833 .ie '\\n(.z'tbl*header-div' .@error-recover .TS H but no .TH before .TE
1835 . nr tbl*have-header 0
1836 . if !'\*(.T'html' .sp \\n[DD]u
1845 .if \\n[tbl*have-header] \{\
1852 .\" ****************************
1853 .\" ******** module pic ********
1854 .\" ****************************
1860 .ie \\n[.$]<2 .@error bad arguments to PS (not preprocessed with pic?)
1862 . ds@need (u;\\$1)+1v
1863 . in +(u;\\n[.l]-\\n[.i]-\\$2/2>?0)
1872 .\" ****************************
1873 .\" ******** module ref ********
1874 .\" ****************************
1877 .\" ****************************
1878 .\" ******** module acc ********
1879 .\" ****************************
1880 .\" Accents and special characters.
1885 .\" The idea of this definition is for the top of the 3 to be at the
1887 .if !c\[yogh] .char \[yogh] \Z'\v'\w'x'*0-\En[rst]u'\s[\En[.s]*8u/10u]\
1888 \v'\w'3'*0+\En[rst]u'3\s0'\h'\w'\s[\En[.s]*8u/10u]3'u'
1891 .ds \\$1 \Z'\v'(u;\w'x'*0+\En[rst]-\En[.cht])'\
1892 \h'(u;-\En[skw]+(-\En[.w]-\w'\\$2'/2)+\En[.csk])'\\$2'
1895 .ds \\$1 \Z'\v'\En[.cdp]u'\h'(u;-\En[.w]-\w'\\$2'/2)'\\$2'
1898 .ds \\$1 \Z'\h'(u;-\En[.w]-\w'\\$2'/2)'\
1899 \v'(u;\En[.cdp]-\En[.cht]+\En[rst]+\En[rsb]/2)'\\$2'
1902 .ds \\$1 \Z'\h'(u;\w'x'-\w'\\$2'/2)'\\$2'
1904 .acc*prefix-def ' \'
1905 .acc*prefix-def ` \`
1907 .acc*prefix-def , \(ac
1908 .acc*prefix-def : \(ad
1910 .\" improved accent marks
1916 .acc*over-def : \(ad
1917 .acc*over-def v \(ah
1918 .acc*over-def _ \(a-
1919 .acc*over-def o \(ao
1920 .acc*under-def , \(ac
1921 .acc*under-def . \s[\En[.s]*8u/10u]\v'.2m'.\v'-.2m'\s0
1922 .acc*under-def hook \(ho
1924 .char \[hooko] o\E*[hook]
1927 .ds D- \(-D\" Icelandic uppercase eth
1928 .ds d- \(Sd\" Icelandic lowercase eth
1929 .ds Th \(TP\" Icelandic uppercase thorn
1930 .ds th \(Tp\" Icelandic lowercase thorn
1931 .ds 8 \(ss\" German double s
1932 .ds Ae \(AE\" AE ligature
1933 .ds ae \(ae\" ae ligature
1934 .ds Oe \(OE\" OE ligature
1935 .ds oe \(oe\" oe ligature
1936 .ds ? \(r?\" upside down ?
1937 .ds ! \(r!\" upside down !
1939 .de CHECK-FOOTER-AND-KEEP
1940 .if '\*(.T'html' \{\
1957 .\" ****************************
1958 .\" ******** module bell ********
1959 .\" ****************************
1960 .\" Emulate Bell Labs localisms. Note, (a) they're not documented, and
1961 .\" (b) the .P1 and .UC macros collide with different ones in Berkeley
1962 .\" ms. We hack around this by conditionalizing the behavior of P1; UC
1963 .\" was not defined by groff and will be a no-op if called Berkeley
1964 .\" style with no arguments, so there is no problem with hijacking it
1967 .\" What's done here is sufficient to give back the Guide to EQN (1976)
1968 .\" its section headings and restore some text that had gone missing as
1969 .\" macro arguments; no warranty express or implied is given as to how
1970 .\" well the typographic details these produce match the original Bell
1973 .\" P1 is now defined in module pg.
1975 .nr bell_localisms 1
1980 .if r bell_localisms \f(CW\\$*\fP
1983 .if r bell_localisms \{\
1988 .\" ====================================================================
1990 .\" ====================================================================
1992 .\" Local Variables:
1996 .\" vim: set filetype=groff textwidth=72: