6 Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002, 2003, 2004, 2006, 2007,
8 Free Software Foundation, Inc.
9 Written by James Clark (jjc@jclark.com)
11 This file is part of groff.
13 groff is free software; you can redistribute it and/or modify it under
14 the terms of the GNU General Public License as published by the Free
15 Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
18 groff is distributed in the hope that it will be useful, but WITHOUT ANY
19 WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 .if !\n(.g .ab These ms macros require groff.
28 . ab The groff ms macros do not work in compatibility mode.
29 .\" Enable warnings (only if none are given on the command line).
30 .\" You can delete this if you want.
31 .if (\n[.warn] == 65543) .warn
32 .\" See if already loaded.
39 .tm \\n(.F:\\n(.c: macro error: \\$*
42 .tm \\n(.F:\\n(.c: macro warning: \\$*
45 .ab \\n(.F:\\n(.c: fatal macro error: \\$*
48 .@error sorry, \\$0 not implemented
51 .als TM @not-implemented
52 .als CT @not-implemented
56 .if !rPO .nr PO \\n(.o
57 .\" a non-empty environment
65 .ds REFERENCES References
67 .ds TOC Table of Contents
80 .ds MO \E*[MONTH\n[mo]]
81 .ds DY \n[dy] \*[MO] \n[year]
83 .if \\n[.$] .ds DY "\\$*
86 .if \\n[.$] .ds DY "\\$*
91 .tm \\$1\t\\$2\t\\$3\t\\$4 ... \\n[PN]
93 .\" print an error message and then try to recover
95 .@error \\$@ (recovering)
98 . \"@warning automatically terminating diversion \\n(.z
99 . ie d @div-end!\\n(.z .@div-end!\\n(.z
100 . el .*div-end-default
102 . \" ensure that we don't loop forever
103 . if \\n[*pop-count]>20 .@fatal recovery failed
105 .while !'\\n[.ev]'0' .ev
117 .\" ****************************
118 .\" ******** module cov ********
119 .\" ****************************
120 .\" Cover sheet and first page.
121 .de cov*err-not-after-first-page
122 .@error \\$0 is not allowed after the first page has started
124 .de cov*err-not-before-tl
125 .@error \\$0 is not allowed before TL
127 .de cov*err-not-again
128 .@error \\$0 is not allowed more than once
130 .de cov*err-not-after-ab
131 .@error \\$0 is not allowed after first AB, LP, PP, IP, SH or NH
133 .als AU cov*err-not-before-tl
134 .als AI cov*err-not-before-tl
135 .als AB cov*err-not-before-tl
136 .de cov*first-page-init
137 .\" Invoked by `.wh 0' trap on first page.
138 .\" We should not come here again, but at short page length,
139 .\" recursion may occur; remove trap and macro to avoid it.
140 .ch cov*first-page-init
141 .rm cov*first-page-init
142 .if !'\\n[.ev]'0' \{\
143 . @error must be in top-level environment, not `\\n[.ev]',
144 . @error when first page is started
147 .als RP cov*err-not-after-first-page
149 .ie \\n[cov*rp-format] \{\
160 .CHECK-FOOTER-AND-KEEP
162 .wh 0 cov*first-page-init
163 .\" This handles the case where FS occurs before TL or LP.
170 .\" released paper format
173 .if \\n[.$] .if '\\$1'no' .nr cov*rp-no 1
179 .als TL cov*err-not-again
199 .di cov*au-div!\\n[cov*n-au]
202 .ie (\\n[PS] >= 1000) \
203 . ps (\\n[PS]z / 1000u)
213 .ie !\\n[cov*n-au] .@error AI before AU
215 . di cov*ai-div!\\n[cov*n-au]
218 . ie (\\n[PS] >= 1000) \
219 . ps (\\n[PS]z / 1000u)
248 .als cov*ab-init @nop
266 .als AB cov*err-not-after-ab
280 . als cov*tl-au-print @nop
286 . if '\*(.T'html' \{\
300 . als cov*tl-au-print @nop
308 . als AE cov*err-not-again
311 . ie '\\n(.z'cov*ab-div' \{\
312 . als AE cov*err-not-again
315 .\" nr cov*ab-height \\n[dn]
320 . el .@error AE without AB
323 .de @div-end!cov*ab-div
329 . ie \\n[cov*rp-format] .cov*rp-print
330 . el .cov*draft-print
333 . if \\n[cov*rp-format] \{\
334 . @warning RP format but no TL
338 . CHECK-FOOTER-AND-KEEP
344 .nr cov*page-length \\n[.p]
349 . if !'\*(.T'html' .nf
356 .if \\n[cov*fn-height] \{\
357 . sp |(u;\\n[cov*page-length]-\\n[FM]\
358 -\\n[cov*fn-height]-\\n[fn@sep-dist]>?\\n[nl])
363 . ie \\n[cov*rp-no] .rm cov*fn-div
365 . rn cov*fn-div fn@overflow-div
366 . nr fn@have-overflow 1
371 .CHECK-FOOTER-AND-KEEP
372 .\" If anything was printed below where the footer line is normally printed,
373 .\" then that's an overflow.
374 .if -\\n[FM]/2+1v+\\n[cov*page-length]<\\n[nl] .@error cover sheet overflow
375 .pl \\n[cov*page-length]u
377 .if !\\n[cov*rp-no] .cov*tl-au-print
402 .while \\n[cov*i]<=\\n[cov*n-au] \{\
403 . ie '\*(.T'html' .br
404 . el .sp \\n[cov*sp]u
405 . cov*au-div!\\n[cov*i]
406 . ie d cov*ai-div!\\n[cov*i] \{\
408 . cov*ai-div!\\n[cov*i]
418 .\" start of footnote on cover
420 .if \\n[cov*in-fn] \{\
428 .if !\\n[cov*fn-height] .ns
429 .ie \\n[.$] .FP "\\$1" no
432 .de @div-end!cov*fn-div
435 .\" end of footnote on cover
437 .ie '\\n(.z'cov*fn-div' \{\
442 . nr cov*fn-height +\\n[dn]
444 .el .@error FE without matching FS
446 .\" ***************************
447 .\" ******** module pg ********
448 .\" ***************************
449 .\" Page-level formatting.
450 .\" > 0 if we have a footnote on the current page
462 .ds pg*OH '\E*[LH]'\E*[CH]'\E*[RH]'
463 .ds pg*EH '\E*[LH]'\E*[CH]'\E*[RH]'
464 .ds pg*OF '\E*[LF]'\E*[CF]'\E*[RF]'
465 .ds pg*EF '\E*[LF]'\E*[CF]'\E*[RF]'
473 .ie \\n%=1 .if \\n[pg*P1] .tl \\*[pg*OH]
475 . ie o .tl \\*[pg*OH]
485 .ie r bell_localisms \{\
491 .wh -\n[FM]u pg@bottom
492 .wh -\n[FM]u/2u pg*footer
496 .if !'\\n(.z'' .error-recover MC while diversion open
498 .ie \\n[pg@ncols]>1 .pg@super-eject
500 . \" flush out any floating keeps
501 . while \\n[kp@tail]>\\n[kp@head] \{\
507 . nr pg@colw \\n[LL]*7/15
508 . nr pg*gutw \\n[LL]-(2*\\n[pg@colw])
512 . nr pg@colw (n;\\$1)<?\\n[LL]
513 . ie \\n[.$]<2 .nr pg*gutw \\n[MINGW]
514 . el .nr pg*gutw (n;\\$2)
515 . nr pg@ncols \\n[LL]-\\n[pg@colw]/(\\n[pg@colw]+\\n[pg*gutw])+1
516 . ie \\n[pg@ncols]>1 \
517 . nr pg*gutw \\n[LL]-(\\n[pg@ncols]*\\n[pg@colw])/(\\n[pg@ncols]-1)
520 .DEVTAG ".mc \\n[pg@ncols] \\n[pg@colw] \\n[pg*gutw]"
524 .nr pg@fn-colw \\n[pg@colw]*5/6
533 .\" top of page macro
535 .ch pg*footer -\\n[FM]u/2u
538 .nr pg@fn-bottom-margin 0
552 .\" Handle footnote overflow before floating keeps, because the keep
553 .\" might contain an embedded footnote.
561 .\" move pg@bottom and pg*footer out of the way
562 .ch pg@bottom \\n[.p]u*2u
563 .ch pg*footer \\n[.p]u*2u
568 .if \\n[pg@fn-flag] .fn@bottom-hook
570 .ie \\n[pg*col-num]<\\n[pg@ncols] .pg*end-col
574 'sp |\\n[pg*col-top]u
575 .po (u;\\n[PO]+(\\n[pg@colw]+\\n[pg*gutw]*\\n[pg*col-num]))
576 .\"po +(u;\\n[pg@colw]+\\n[pg*gutw])
581 .\" Make sure we don't exit if there are still floats or footnotes left-over.
582 .ie \\n[kp@head]<\\n[kp@tail]:\\n[fn@have-overflow] \{\
583 . \" Switching environments ensures that we don't get an unnecessary
584 . \" blank line at the top of the page.
590 . \" If the text has ended and there are no more footnotes or keeps, exit.
591 . if \\n[pg@text-ended] .ex
592 . if r pg*next-number \{\
593 . pn \\n[pg*next-number]
595 . if d pg*next-format \{\
596 . af PN \\*[pg*next-format]
603 .\" pg@begin number format
606 . nr pg*next-number (;\\$1)
607 . ie \\n[.$]>1 .ds pg*next-format \\$2
608 . el .rm pg*next-format
610 .el .rr pg*next-number
613 .\" print the footer line
620 .\" flush out any keeps or footnotes
623 .if !'\\n(.z'' .@error-recover diversion open while ejecting page
624 .\" Make sure we stay in the end macro while there is still footnote overflow
625 .\" left, or floating keeps.
626 .while \\n[kp@tail]>\\n[kp@head]:\\n[pg@fn-flag] \{\
639 .\" ***************************
640 .\" ******** module fn ********
641 .\" ***************************
645 .\" Round it vertically
647 .nr fn@sep-dist \n[.v]
651 .ds * \E*[par@sup-start]\En+[fn*text-num]\E*[par@sup-end]
655 .ie \\n[.$] .fn*do-FS "\\$1" no
657 . ie \\n[fn*text-num]>\\n[fn*note-num] .fn*do-FS \\n+[fn*note-num]
661 .\" Second argument of `no' means don't embellish the first argument.
663 .if \\n[fn*open] .@error-recover nested FS
666 . \" Ensure that the first line of the footnote is on the same page
667 . \" as the reference. I think this is minimal.
671 . ie \\n[pg@fn-flag] .nr fn*need +\\n[fn:PD]
672 . el .nr fn*need +\\n[fn@sep-dist]
673 . ne \\n[fn*need]u+\\n[.V]u>?0
683 .ie !\\n[fn*open] .@error FE without FS
691 .nr fn@have-overflow 0
692 .\" called at the top of each column
695 .nr fn*page-bottom-pos 0-\\n[FM]-\\n[pg@fn-bottom-margin]
696 .ch pg@bottom \\n[fn*page-bottom-pos]u
697 .if \\n[fn@have-overflow] \{\
698 . nr fn@have-overflow 0
706 .\" This is called at the bottom of the column if pg@fn-flag is set.
709 .nr fn@have-overflow 0
710 .nr fn@bottom-pos \\n[.p]-\\n[FM]-\\n[pg@fn-bottom-margin]+\\n[.v]
712 .nr fn@bottom-pos -\\n[.v]
714 .ie \\n[nl]+\\n[fn@sep-dist]+\n[.V]>\\n[fn@bottom-pos] \{\
715 . rn fn@div fn@overflow-div
716 . nr fn@have-overflow 1
719 . if \\n[pg@ncols]>1 \
720 . if \\n[fn*max-width]>\\n[pg@fn-colw] \
721 . nr pg@fn-bottom-margin \\n[.p]-\\n[FM]-\\n[nl]+1v
722 . wh \\n[fn@bottom-pos]u fn*catch-overflow
728 . if '\\n(.z'fn@overflow-div' \{\
730 . nr fn@have-overflow \\n[dn]>0
732 . ch fn*catch-overflow
735 .de fn*catch-overflow
741 .if '\\n[.ev]'fn' .ev
745 .als @div-end!fn*embed-div @div-end!fn@div
749 . if !\\n[pg@fn-flag] .ns
754 .ie '\\n(.z'fn@div' \{\
756 . nr fn*page-bottom-pos -\\n[dn]
757 . nr fn*max-width \\n[fn*max-width]>?\\n[dl]
758 . if !\\n[pg@fn-flag] .nr fn*page-bottom-pos -\\n[fn@sep-dist]
760 . nr fn*page-bottom-pos \\n[nl]-\\n[.p]+\n[.V]>?\\n[fn*page-bottom-pos]
761 . ch pg@bottom \\n[fn*page-bottom-pos]u
764 . ie '\\n(.z'fn*embed-div' \{\
766 . rn fn*embed-div fn*embed-div!\\n[fn*embed-count]
767 \!. fn*embed-start \\n[fn*embed-count]
769 ' sp (u;\\n[dn]+\\n[fn@sep-dist]+\\n[.V])
771 . nr fn*embed-count +1
775 . @error-recover unclosed diversion within footnote
784 . rm fn*embed-div!\\$1
790 \!. fn*embed-start \\$1
795 .ie '\\n(.z'fn*null' \{\
801 .\" It's important that fn@print-sep use up exactly fn@sep-dist vertical space.
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 footnote
884 .\" 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
1306 .nr \\n[.ev]:li!\\n[\\n[.ev]:il] \\n[\\n[.ev]:li]
1307 .nr \\n[.ev]:ri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ri]
1308 .nr \\n[.ev]:ai!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ai]
1309 .nr \\n[.ev]:pli!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pli]
1310 .nr \\n[.ev]:pri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pri]
1312 .nr \\n[.ev]:li +\\n[QI]
1313 .nr \\n[.ev]:ri +\\n[QI]
1314 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1318 .\" start boxed text
1325 .nr par*box-in \\n[.in]
1326 .\" remember what 1n is, just in case the point size changes
1331 .ti \\n[par*box-in]u+1n
1333 .de @div-end!par*box-div
1337 .\" Postpone the drawing of the box until we're in the top-level diversion,
1338 .\" in case there's a footnote inside the box.
1340 .ie '\\n(.z'par*box-div' \{\
1342 . if \n[.V]>.25m .sp
1344 . if \n[.V]>.25m .sp
1350 . nr \\n[.ev]:ri -\\n[par*box-n]
1351 . nr \\n[.ev]:li -\\n[par*box-n]
1352 . in -\\n[par*box-n]u
1353 . ll +\\n[par*box-n]u
1354 . lt +\\n[par*box-n]u
1355 . par*box-draw \\n[.i]u \\n[.l]u-(\\n[.H]u==1n*1n)
1357 .el .@error B2 without B1
1360 .de par*box-mark-top
1365 .el \!.par*box-mark-top
1369 . nr par*box-in \\n[.i]
1370 . nr par*box-ll \\n[.l]
1371 . nr par*box-vpt \\n[.vpt]
1372 . nr par*box-ad \\n[.j]
1378 \D'l (u;\\n[.l]-\\n[.i]) 0'\
1379 \D'l 0 |\\n[par*box-top]u'\
1380 \D'l -(u;\\n[.l]-\\n[.i]) 0'\
1381 \D'l 0 -|\\n[par*box-top]u'
1384 . in \\n[par*box-in]u
1385 . ll \\n[par*box-ll]u
1386 . vpt \\n[par*box-vpt]
1387 . ad \\n[par*box-ad]
1389 .el \!.par*box-draw \\$1 \\$2
1391 .\" \n[HORPHANS] sets how many lines of the following paragraph must be
1392 .\" kept together, with a preceding section header. Initialise it,
1393 .\" to reproduce original behaviour; user may change it.
1394 .if !rHORPHANS .nr HORPHANS 1
1396 .\" \n[GROWPS] and \n[PSINCR] cause auto-increment of header point size.
1397 .\" Initialise them, so they have no effect, unless explicitly set by the user.
1398 .if !rGROWPS .nr GROWPS 0
1399 .if !rPSINCR .nr PSINCR 1p
1403 .\" Keep the heading and the first few lines of the next paragraph together.
1404 .\" (\n[HORPHANS] defines "first few" -- default = 1; user may redefine it).
1405 .nr sh*minvs \\n[HORPHANS]v
1406 .if \\n[sh*psincr]<0 .nr sh*psincr 0
1407 .ie \\n(VS<1000 .par*vs \\n(VSp+\\n[sh*psincr]u
1408 .el .par*vs \\n(VSp/1000u+\\n[sh*psincr]u
1409 .ne 2v+\\n[sh*minvs]u+\\n[\\n[.ev]:PD]u+\\n(.Vu
1410 .\" Adjust point size for heading text, as specified by \n[GROWPS] and \n[PSINCR].
1411 .ie \\n(PS<1000 .ps \\n(PS+\\n[sh*psincr]u
1412 .el .ps \\n(PSz/1000u+\\n[sh*psincr]u
1417 .\" Standard ms implementation does not expect an argument,
1418 .\" but allow ".SH n" to make heading point size match ".NH n",
1419 .\" for same "n", when \n[GROWPS] and \n[PSINCR] are set.
1421 . if 0\\$1>0 .nr sh*psincr (\\n[GROWPS]-0\\$1)*\\n[PSINCR]
1424 . if '\*(.T'html' .nr need_eo_h 1
1426 .\" TL, AU, and AI are aliased to these in cov*ab-init.
1448 .\" In paragraph macros.
1450 .ie (\\n[\\n[.ev]:PS] >= 1000) \
1451 . ps (\\n[\\n[.ev]:PS]z / 1000u)
1453 . ps \\n[\\n[.ev]:PS]
1464 .\" par*define-font-macro macro font
1465 .de par*define-font-macro
1468 . nr par*prev-font \En[.f]
1469 \&\E$3\f[\\$2]\E$1\f[\En[par*prev-font]]\E$2
1474 .par*define-font-macro B B
1475 .par*define-font-macro I I
1476 .par*define-font-macro BI BI
1477 .par*define-font-macro CW CR
1478 .\" underline a word
1480 \Z'\\$1'\v'.25m'\D'l \w'\\$1'u 0'\v'-.25m'\\$2
1484 .nr par*bxw \w'\\$1'+.4m
1485 \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''\
1489 .\" The first time UX is used, put a registered mark after it.
1492 \s[\\n[.s]*8u/10u]UNIX\s0\\$1\\*[par*ux-rg]
1495 .ds par@sup-start \v'-.9m\s'\En[.s]*7u/10u'+.7m'
1496 .als { par@sup-start
1497 .ds par@sup-end \v'-.7m\s0+.9m'
1499 .\" footnote paragraphs
1500 .\" FF is the footnote format
1502 .\" This can be redefined. It gets a second argument of `no' if the first
1503 .\" argument was supplied by the user, rather than automatically.
1506 .if !d par*fp!\\n[FF] \{\
1507 . @error unknown footnote format `\\n[FF]'
1510 .ie '\\$2'no' .par*fp!\\n[FF]-no "\\$1"
1511 .el .par*fp!\\n[FF] "\\$1"
1515 \&\\*[par@sup-start]\\$1\\*[par@sup-end]\ \c
1538 .@IP "\\$1." (u;\\n[\\n[.ev]:PI]*2)
1541 .@IP "\\$1" (u;\\n[\\n[.ev]:PI]*2)
1543 .\" ***************************
1544 .\" ******** module nh ********
1545 .\" ***************************
1546 .\" Numbered headings.
1547 .\" nh*hl is the level of the last heading
1549 .\" SN-DOT and SN-NO-DOT represent the section number of
1550 .\" the current heading, with and without a terminating dot.
1553 .\" SN-STYLE sets the statement numbering style used in headings
1554 .\" (either SN-DOT or SN-NO-DOT); for backward compatibility with
1555 .\" earlier ms versions, the default is SN-DOT
1556 .als SN-STYLE SN-DOT
1557 .\" Also for backward compatibility, let SN represent SN-DOT.
1559 .\" numbered heading
1566 . nr H\\n[nh*hl] 0\\$1
1569 . if !\\n[nh*hl] \{\
1572 . @error missing arguments to .NH S
1576 . nr nh*ohl \\n[nh*hl]
1579 . ie \\n[nh*hl]<=0 \{\
1584 . if \\n[nh*hl]-\\n[nh*ohl]>1 \
1585 . @warning .NH \\n[nh*ohl] followed by .NH \\n[nh*hl]
1589 . while \\n[nh*hl]>\\n[nh*ohl] \{\
1595 .ds SN-NO-DOT \\n(H1
1597 .while \\n[nh*i]<\\n[nh*hl] \{\
1599 . as SN-NO-DOT .\\n[H\\n[nh*i]]
1601 .ds SN-DOT \\*[SN-NO-DOT].
1602 .nr sh*psincr (\\n[GROWPS]-\\n[nh*hl])*\\n[PSINCR]
1605 . if '\*(.T'html' .nr need_eo_h 1
1608 .\" ****************************
1609 .\" ******** module toc ********
1610 .\" ****************************
1611 .\" Table of contents generation.
1615 .ie \\n[.$] .XA "\\$1"
1618 .de @div-end!toc*div
1622 .ie '\\n(.z'toc*div' \{\
1623 . if d toc*num .toc*end-entry
1625 . ie '\\$1'no' .ds toc*num
1626 . el .ds toc*num "\\$1
1628 . el .ds toc*num \\n[PN]
1635 .el .@error XA without XS
1638 .ie '\\n(.z'toc*div' \{\
1639 . if d toc*num .toc*end-entry
1643 .el .@error XE without XS
1654 . ie (\\n[PS] >= 1000) \
1655 . ps ((\\n[PS]z / 1000u) + 2z)
1664 .char \[toc*leader-char] .\h'1m'
1665 .lc \[toc*leader-char]
1666 .ta (u;\\n[.l]-\\n[.i]-\w'000') (u;\\n[.l]-\\n[.i])R
1671 .\" print the table of contents on page i
1677 .\" ****************************
1678 .\" ******** module eqn ********
1679 .\" ****************************
1688 .ie '\\$1'L' .nr eqn*type 0
1690 . ie '\\$1'I' .nr eqn*type 1
1693 . if !'\\$1'C' .ds eqn*num "\\$1
1698 .if '\*(.T'html' \{\
1702 .if \\n[eqn*type]=0 .EQN-HTML-IMAGE-LEFT
1703 .if \\n[eqn*type]=1 \{\
1704 . if '\*(.T'html' .RS
1705 .EQN-HTML-IMAGE-INLINE
1707 .if \\n[eqn*type]=2 .EQN-HTML-IMAGE
1710 .de @div-end!eqn*div
1713 .\" Note that geqn mark and lineup work correctly in centered equations.
1715 .ie !'\\n(.z'eqn*div' .@error-recover mismatched EN
1720 . if !'\\*[eqn*num]'' .nr eqn*have-num 1
1721 . ie \\n[dl]:\\n[eqn*have-num] \{\
1724 . ds eqn*tabs \\n[.tabs]
1727 .\" --fixme-- this really should not be necessary
1728 .\" and indicates that there is extra space creeping into
1729 .\" an equation when ps4html is enabled..
1730 . ie r ps4html .ds@need \\n[dn]u-1v+\n[.V]u+1i
1731 . el .ds@need \\n[dn]u-1v+\n[.V]u
1733 . ie \\n[eqn*type]=0 \{\
1734 . ta (u;\\n[.l]-\\n[.i])R
1735 \\*[eqn*div]\t\\*[eqn*num]
1738 . ie \\n[eqn*type]=1 .ta \\n[DI]u \
1739 (u;\\n[.l]-\\n[.i])R
1740 . el .ta (u;\\n[.l]-\\n[.i]/2)C \
1741 (u;\\n[.l]-\\n[.i])R
1742 \t\\*[eqn*div]\t\\*[eqn*num]
1746 . ta (u;\\n[.l]-\\n[.i])R
1749 .\". if !'\*(.T'html' .sp \\n[DD]u
1754 .\" must terminate empty equations in html and ps4html as they contain
1755 .\" the EQN-HTML-IMAGE-END suppression nodes
1756 . if \\n[dl] .chop eqn*div
1757 . if '\*(.T'html' \\*[eqn*div]
1758 . if r ps4html \\*[eqn*div]
1760 . if !'\*(.T'html' .fi
1761 . if \\n[eqn*type]=0 .EQN-HTML-IMAGE-END
1762 . if \\n[eqn*type]=1 \{\
1763 . EQN-HTML-IMAGE-END
1764 . if '\*(.T'html' .RE
1766 . if \\n[eqn*type]=2 .EQN-HTML-IMAGE-END
1772 .\" ****************************
1773 .\" ******** module tbl ********
1774 .\" ****************************
1776 .nr tbl*have-header 0
1777 .\" This gets called if TS occurs before the first paragraph.
1780 .\" cov*ab-init aliases TS to @TS
1785 .if '\\$1'H' .di tbl*header-div
1786 .if '\*(.T'html' \{\
1793 .if \\n[tbl*have-header] \{\
1794 . ie \\n[.t]-\\n[tbl*header-ht]-1v .tbl*print-header
1798 .de tbl*print-header
1805 .ie '\\n[.z]'tbl*header-div' \{\
1810 . ie \\n[dn]+\\n[FM]+\\n[HM]+2v>=\\n[.p] \{\
1811 . @error ridiculously long table header
1816 . nr tbl*header-ht \\n[dn]
1817 . ds@need \\n[dn]u+1v
1819 . nr tbl*have-header 1
1822 .el .@error-recover .TH without .TS H
1824 .de @div-end!tbl*header-div
1829 .ie '\\n(.z'tbl*header-div' .@error-recover .TS H but no .TH before .TE
1831 . nr tbl*have-header 0
1832 . if !'\*(.T'html' .sp \\n[DD]u
1841 .if \\n[tbl*have-header] \{\
1848 .\" ****************************
1849 .\" ******** module pic ********
1850 .\" ****************************
1856 .ie \\n[.$]<2 .@error bad arguments to PS (not preprocessed with pic?)
1858 . ds@need (u;\\$1)+1v
1859 . in +(u;\\n[.l]-\\n[.i]-\\$2/2>?0)
1868 .\" ****************************
1869 .\" ******** module ref ********
1870 .\" ****************************
1873 .rm [A [B [C [D [E [G [I [J [N [O [P [Q [R [S [T [V
1877 .ds ref*spec!0 Q A T1 S V N P I C D O
1879 .ds ref*spec!1 Q A T2 J S V N P I C D O
1881 .ds ref*spec!2 Q A T1 S V P I C D O
1882 .\" Article within book
1883 .ds ref*spec!3 Q A T2 B E S V P I C D O
1885 .ds ref*spec!4 Q A T2 R G P I C D O
1892 .ie d ref*spec!\\$1 .ref*build \\*[ref*spec!\\$1]
1894 . @error unknown reference type `\\$1'
1895 . ref*build \\*[ref*spec!0]
1901 .\" start of reference number
1902 .ds [. \E*[par@sup-start]
1903 .\" end of reference number
1904 .ds .] \E*[par@sup-end]
1905 .\" period before reference
1907 .\" period after reference
1909 .\" comma before reference
1911 .\" comma after reference
1913 .\" start collected references
1915 .als ref*print ref*end-print
1920 .\" end collected references
1923 .als ref*print ref*normal-print
1925 .de ref*normal-print
1926 .ie d [F .FS "\\*([.\\*([F\\*(.]"
1932 .ie d [F .IP "\\*([F."
1936 .als ref*print ref*normal-print
1938 .rm ref*string ref*post-punct
1939 .nr ref*suppress-period 1
1942 . ie d ref*add-\\$1 .ref*add-\\$1
1943 . el .ref*add-dflt \\$1
1947 .\" now add a final period
1948 .ie d ref*string \{\
1949 . if !\\n[ref*suppress-period] .as ref*string .
1950 . if d ref*post-punct \{\
1951 . as ref*string "\\*[ref*post-punct]
1958 .ref*field T , " " "\fI" "" "\fP"
1959 .if r [T .nr ref*suppress-period \\n([T
1962 .ref*field T , " " "\\*Q" "" "\\*U"
1963 .if r [T .nr ref*suppress-period \\n([T
1966 .ie \\n([P>0 .ref*field P , " " "pp. "
1967 .el .ref*field P , " " "p. "
1970 .ref*field J , " " \fI "" \fP
1973 .ref*field D "" " " ( )
1976 .ref*field E , " " "ed. "
1979 .ref*field G "" " " ( )
1982 .ref*field B "" " " "in \fI" "" \fP
1986 .ie r [O .nr ref*suppress-period \\n([O
1987 .el .nr ref*suppress-period 1
1991 .if r [A .nr ref*suppress-period \\n([A
1994 .ref*field V "" " " \fB \fR
1997 .ref*field N "" ( "" ")"
2000 .ref*field \\$1 , " "
2002 .\" First argument is the field letter.
2003 .\" Second argument is the punctuation character to use to separate this field
2004 .\" from the previous field.
2005 .\" Third argument is a string to insert after the punctuation character of
2006 .\" the previous field (normally a space)
2007 .\" Fourth argument is a string with which to prefix this field.
2008 .\" Fifth argument is a string with which to postfix this field.
2009 .\" Sixth argument is a string to add after the punctuation character supplied
2010 .\" by the next field.
2012 .if d ref*string \{\
2013 . ie d ref*post-punct \{\
2014 . as ref*string "\\$2\\*[ref*post-punct]\\$3\"
2017 . el .as ref*string "\\$2\\$3\"
2019 .as ref*string "\\$4\\*([\\$1\\$5
2020 .if \\n[.$]>5 .ds ref*post-punct "\\$6
2021 .nr ref*suppress-period 0
2023 .\" ****************************
2024 .\" ******** module acc ********
2025 .\" ****************************
2026 .\" Accents and special characters.
2031 .\" The idea of this definition is for the top of the 3 to be at the x-height.
2032 .if !c\[yogh] .char \[yogh] \Z'\v'\w'x'*0-\En[rst]u'\s[\En[.s]*8u/10u]\
2033 \v'\w'3'*0+\En[rst]u'3\s0'\h'\w'\s[\En[.s]*8u/10u]3'u'
2036 .ds \\$1 \Z'\v'(u;\w'x'*0+\En[rst]-\En[.cht])'\
2037 \h'(u;-\En[skw]+(-\En[.w]-\w'\\$2'/2)+\En[.csk])'\\$2'
2040 .ds \\$1 \Z'\v'\En[.cdp]u'\h'(u;-\En[.w]-\w'\\$2'/2)'\\$2'
2043 .ds \\$1 \Z'\h'(u;-\En[.w]-\w'\\$2'/2)'\
2044 \v'(u;\En[.cdp]-\En[.cht]+\En[rst]+\En[rsb]/2)'\\$2'
2047 .ds \\$1 \Z'\h'(u;\w'x'-\w'\\$2'/2)'\\$2'
2049 .acc*prefix-def ' \'
2050 .acc*prefix-def ` \`
2052 .acc*prefix-def , \(ac
2053 .acc*prefix-def : \(ad
2055 .\" improved accent marks
2061 .acc*over-def : \(ad
2062 .acc*over-def v \(ah
2063 .acc*over-def _ \(a-
2064 .acc*over-def o \(ao
2065 .acc*under-def , \(ac
2066 .acc*under-def . \s[\En[.s]*8u/10u]\v'.2m'.\v'-.2m'\s0
2067 .acc*under-def hook \(ho
2069 .char \[hooko] o\E*[hook]
2072 .ds D- \(-D\" Icelandic uppercase eth
2073 .ds d- \(Sd\" Icelandic lowercase eth
2074 .ds Th \(TP\" Icelandic uppercase thorn
2075 .ds th \(Tp\" Icelandic lowercase thorn
2076 .ds 8 \(ss\" German double s
2077 .ds Ae \(AE\" AE ligature
2078 .ds ae \(ae\" ae ligature
2079 .ds Oe \(OE\" OE ligature
2080 .ds oe \(oe\" oe ligature
2081 .ds ? \(r?\" upside down ?
2082 .ds ! \(r!\" upside down !
2084 .de CHECK-FOOTER-AND-KEEP
2085 .if '\*(.T'html' \{\
2102 .\" ****************************
2103 .\" ******** module bell ********
2104 .\" ****************************
2105 .\" Emulate Bell Labs localisms. Note, (a) they're not documented, and
2106 .\" (b) the .P1 and .UC macros collide with different ones in Berkeley ms.
2107 .\" We hack around this by conditionalizing the behavior of P1; UC was
2108 .\" not defined by groff and will be a no-op if called Berkeley style
2109 .\" with no arguments, so there is no problem with hijacking it here.
2111 .\" What's done here is sufficient to give back the Guide to EQN (1976) its
2112 .\" section headings and restore some text that had gone missing as macro
2113 .\" arguments; no warranty express or implied is given as to how well the
2114 .\" typographic details these produce match the original Bell Labs macros.
2116 .\" P1 is now defined in module pg.
2118 .nr bell_localisms 1
2123 .if r bell_localisms \f(CW\\$*\fP
2126 .if r bell_localisms \{\
2131 .\" Make sure that no blank lines creep in at the end of this file.