* tmac/s.tmac (pg@top): Don't save PO register.
[s-roff.git] / tmac / s.tmac
blob1f028c021ad127cfe6ec1c79e50ccc38f85e0815
1 .\" -*- nroff -*-
2 .ig
4 s.tmac
6 Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002, 2003, 2004
7   Free Software Foundation, Inc.
8      Written by James Clark (jjc@jclark.com)
10 This file is part of groff.
12 groff is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free
14 Software Foundation; either version 2, or (at your option) any later
15 version.
17 groff is distributed in the hope that it will be useful, but WITHOUT ANY
18 WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 for more details.
22 You should have received a copy of the GNU General Public License along
23 with groff; see the file COPYING.  If not, write to the Free Software
24 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 .if !\n(.g .ab These ms macros require groff.
27 .if \n(.C \
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.
33 .if r GS .nx
34 .nr GS 1
35 .de @error
36 .tm \\n(.F:\\n(.c: macro error: \\$*
38 .de @warning
39 .tm \\n(.F:\\n(.c: macro warning: \\$*
41 .de @fatal
42 .ab \\n(.F:\\n(.c: fatal macro error: \\$*
44 .de @not-implemented
45 .@error sorry, \\$0 not implemented
46 .als \\$0 @nop
48 .als TM @not-implemented
49 .als CT @not-implemented
50 .de @nop
52 .de @init
53 .if !rPO .nr PO \\n(.o
54 .\" a non-empty environment
55 .ev ne
57 .ev
58 .ev nf
59 'nf
60 .ev
62 .ds REFERENCES References
63 .ds ABSTRACT ABSTRACT
64 .ds TOC Table of Contents
65 .ds MONTH1 January
66 .ds MONTH2 February
67 .ds MONTH3 March
68 .ds MONTH4 April
69 .ds MONTH5 May
70 .ds MONTH6 June
71 .ds MONTH7 July
72 .ds MONTH8 August
73 .ds MONTH9 September
74 .ds MONTH10 October
75 .ds MONTH11 November
76 .ds MONTH12 December
77 .ds MO \\*[MONTH\n[mo]]
78 .ds DY \n[dy] \*[MO] \n[year]
79 .de ND
80 .if \\n[.$] .ds DY "\\$*
82 .de DA
83 .if \\n[.$] .ds DY "\\$*
84 .ds CF \\*[DY]
86 .\" indexing
87 .de IX
88 .tm \\$1\t\\$2\t\\$3\t\\$4 ... \\n[PN]
90 .\" print an error message and then try to recover
91 .de @error-recover
92 .@error \\$@ (recovering)
93 .nr *pop-count 0
94 .while !'\\n(.z'' \{\
95 .       \"@warning automatically terminating diversion \\n(.z
96 .       ie d @div-end!\\n(.z .@div-end!\\n(.z
97 .       el .*div-end-default
98 .       nr *pop-count +1
99 .       \" ensure that we don't loop forever
100 .       if \\n[*pop-count]>20 .@fatal recovery failed
102 .while !'\\n[.ev]'0' .ev
103 .par@reset-env
104 .par@reset
106 .de *div-end-default
107 .ds *last-div \\n(.z
110 .ev nf
111 .\\*[*last-div]
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 .rm cov*first-page-init
135 .par@init
136 .als RP cov*err-not-after-first-page
137 .@init
138 .ie \\n[cov*rp-format] \{\
139 .       pg@cs-top
140 .       als FS cov*FS
141 .       als FE cov*FE
143 .el \{\
144 .       pg@top
145 .       als FS @FS
146 .       als FE @FE
148 .wh 0 pg@top
149 .CHECK-FOOTER-AND-KEEP
151 .wh 0 cov*first-page-init
152 .\" This handles the case where FS occurs before TL or LP.
153 .de FS
155 \\*[FS]\\
157 .nr cov*rp-format 0
158 .nr cov*rp-no 0
159 .\" released paper format
160 .de RP
161 .nr cov*rp-format 1
162 .if \\n[.$] .if '\\$1'no' .nr cov*rp-no 1
163 .if rPO .po \\n(POu
164 .pn 0
166 .de TL
168 .als TL cov*err-not-again
169 .rn @AB AB
170 .rn @AU AU
171 .rn @AI AI
172 .if !'\*(.T'html' .di cov*tl-div
173 .par@reset
174 .ft B
175 .ps +2
176 .vs +3p
177 .ll (u;\\n[LL]*5/6)
178 .nr cov*n-au 0
179 .HTML-TAG ".tl"
181 .de @AU
182 .par@reset
183 .if !'\\n(.z'' \{\
184 .       br
185 .       di
187 .nr cov*n-au +1
188 .di cov*au-div!\\n[cov*n-au]
190 .ft I
191 .ie (\\n[PS] >= 1000) \
192 .       ps (\\n[PS]z / 1000u)
193 .el \
194 .       ps \\n[PS]
196 .de @AI
197 .if !'\*(.T'html' .par@reset
198 .if !'\\n(.z'' \{\
199 .       br
200 .       di
202 .ie !\\n[cov*n-au] .@error AI before AU
203 .el \{\
204 .       di cov*ai-div!\\n[cov*n-au]
205 .       nf
206 .       ft R
207 .       ie (\\n[PS] >= 1000) \
208 .               ps (\\n[PS]z / 1000u)
209 .       el \
210 .               ps \\n[PS]
213 .de LP
214 .if !'\\n[.z]'' \{\
215 .       br
216 .       di
219 .cov*ab-init
220 .cov*print
221 \\*[\\$0]\\
223 .als IP LP
224 .als PP LP
225 .als XP LP
226 .als QP LP
227 .als RS LP
228 .als NH LP
229 .als SH LP
230 .als MC LP
231 .als RT LP
232 .als XS LP
233 .de cov*ab-init
234 .als cov*ab-init @nop
235 .als LP @LP
236 .als IP @IP
237 .als PP @PP
238 .als XP @XP
239 .als RT @RT
240 .als XS @XS
241 .als SH @SH
242 .als NH @NH
243 .als QP @QP
244 .als RS @RS
245 .als RE @RE
246 .als QS @QS
247 .als QE @QE
248 .als MC @MC
249 .als EQ @EQ
250 .als EN @EN
251 .als TS @TS
252 .als AB cov*err-not-after-ab
253 .als AU par@AU
254 .als AI par@AI
255 .als TL par@TL
257 .de @AB
258 .if !'\\n(.z'' \{\
259 .       br
260 .       di
262 .cov*ab-init
263 .if !'\*(.T'html' .di cov*ab-div
264 .par@ab-indent
265 .par@reset
266 .if !'\\$1'no' \{\
267 .       ft I
268 .       ce 1
269 \\*[ABSTRACT]
270 .       sp
271 .       ft R
274 .@PP
275 .if '\*(.T'html' \{\
276 .       cov*tl-au-print
277 .       als cov*tl-au-print @nop
278 .       par@reset-env
279 .       par@reset
280 .       cov*print
283 .de AE
284 .ie '\*(.T'html' \{\
285 .       als AE cov*err-not-again
287 .el \{\
288 .  ie '\\n(.z'cov*ab-div' \{\
289 .       als AE cov*err-not-again
290 .       br
291 .       di
292 .\"     nr cov*ab-height \\n[dn]
293 .       par@reset-env
294 .       par@reset
295 .       cov*print
296 .  \}
297 .  el .@error AE without AB
300 .de @div-end!cov*ab-div
303 .de cov*print
304 .als cov*print @nop
305 .ie d cov*tl-div \{\
306 .       ie \\n[cov*rp-format] .cov*rp-print
307 .       el .cov*draft-print
309 .el \{\
310 .       if \\n[cov*rp-format] \{\
311 .               @warning RP format but no TL
312 .               bp 1
313 .               als FS @FS
314 .               als FE @FE
315 .               CHECK-FOOTER-AND-KEEP
316 .       \}
317 .       br
320 .de cov*rp-print
321 .nr cov*page-length \\n[.p]
322 .pl 1000i
323 .cov*tl-au-print
324 .sp 3
325 .if d cov*ab-div \{\
326 .  if !'\*(.T'html'  .  nf
327 .       cov*ab-div
329 .sp 3
330 .par@reset
331 \\*[DY]
333 .if \\n[cov*fn-height] \{\
334 .       sp |(u;\\n[cov*page-length]-\\n[FM]\
335 -\\n[cov*fn-height]-\\n[fn@sep-dist]>?\\n[nl])
336 .       fn@print-sep
337 .       ev nf
338 .       cov*fn-div
339 .       ev
340 .       ie \\n[cov*rp-no] .rm cov*fn-div
341 .       el \{\
342 .               rn cov*fn-div fn@overflow-div
343 .               nr fn@have-overflow 1
344 .       \}
346 .als FS @FS
347 .als FE @FE
348 .CHECK-FOOTER-AND-KEEP
349 .\" If anything was printed below where the footer line is normally printed,
350 .\" then that's an overflow.
351 .if -\\n[FM]/2+1v+\\n[cov*page-length]<\\n[nl] .@error cover sheet overflow
352 .pl \\n[cov*page-length]u
353 .bp 1
354 .if !\\n[cov*rp-no] .cov*tl-au-print
356 .sp 1
358 .de cov*draft-print
359 .cov*tl-au-print
360 .if d cov*ab-div \{\
361 .       nf
362 .       sp 2
363 .       cov*ab-div
365 .sp 1
367 .de cov*tl-au-print
368 .par@reset
371 .sp 3
372 .ce 9999
373 .if d cov*tl-div .cov*tl-div
374 .nr cov*i 1
375 .nr cov*sp 1v
376 .while \\n[cov*i]<=\\n[cov*n-au] \{\
377 .       sp \\n[cov*sp]u
378 .       cov*au-div!\\n[cov*i]
379 .       ie d cov*ai-div!\\n[cov*i] \{\
380 .               sp .5v  
381 .               cov*ai-div!\\n[cov*i]
382 .               nr cov*sp 1v
383 .       \}
384 .       el .nr cov*sp .5v
385 .       nr cov*i +1
387 .ce 0
389 .nr cov*fn-height 0
390 .nr cov*in-fn 0
391 .\" start of footnote on cover
392 .de cov*FS
393 .if \\n[cov*in-fn] \{\
394 .       @error nested FS
395 .       FE
397 .nr cov*in-fn 1
398 .ev fn
399 .par@reset-env
400 .da cov*fn-div
401 .if !\\n[cov*fn-height] .ns
402 .ie \\n[.$] .FP "\\$1" no
403 .el .@LP
405 .de @div-end!cov*fn-div
406 .cov*FE
408 .\" end of footnote on cover
409 .de cov*FE
410 .ie '\\n(.z'cov*fn-div' \{\
411 .       br
412 .       ev
413 .       di
414 .       nr cov*in-fn 0
415 .       nr cov*fn-height +\\n[dn]
417 .el .@error FE without matching FS
419 .\" ***************************
420 .\" ******** module pg ********
421 .\" ***************************
422 .\" Page-level formatting.
423 .\" > 0 if we have a footnote on the current page
424 .nr pg@fn-flag 0
425 .nr pg@colw 0
426 .nr pg@fn-colw 0
427 .nr HM 1i
428 .nr FM 1i
429 .ds LF
430 .ds CF
431 .ds RF
432 .ds LH
433 .ds CH -\\n[PN]-
434 .ds RH
435 .ds pg*OH '\\*[LH]'\\*[CH]'\\*[RH]'
436 .ds pg*EH '\\*[LH]'\\*[CH]'\\*[RH]'
437 .ds pg*OF '\\*[LF]'\\*[CF]'\\*[RF]'
438 .ds pg*EF '\\*[LF]'\\*[CF]'\\*[RF]'
439 .de OH
440 .ds pg*\\$0 "\\$*
442 .als EH OH
443 .als OF OH
444 .als EF OH
445 .de PT
446 .ie \\n%=1 .if \\n[pg*P1] .tl \\*[pg*OH]
447 .el \{\
448 .       ie o .tl \\*[pg*OH]
449 .       el .tl \\*[pg*EH]
452 .de BT
453 .ie o .tl \\*[pg*OF]
454 .el .tl \\*[pg*EF]
456 .nr pg*P1 0
457 .de P1
458 .nr pg*P1 1
460 .wh -\n[FM]u pg@bottom
461 .wh -\n[FM]u/2u pg*footer
462 .nr MINGW 2n
463 .nr pg@ncols 1
464 .de @MC
465 .if !'\\n(.z'' .error-recover MC while diversion open
467 .ie \\n[pg@ncols]>1 .pg@super-eject
468 .el \{\
469 .       \" flush out any floating keeps
470 .       while \\n[kp@tail]>\\n[kp@head] \{\
471 .               rs
472 .               bp
473 .       \}
475 .ie !\\n(.$ \{\
476 .       nr pg@colw \\n[LL]*7/15
477 .       nr pg*gutw \\n[LL]-(2*\\n[pg@colw])
478 .       nr pg@ncols 2
480 .el \{\
481 .       nr pg@colw (n;\\$1)<?\\n[LL]
482 .       ie \\n[.$]<2 .nr pg*gutw \\n[MINGW]
483 .       el .nr pg*gutw (n;\\$2)
484 .       nr pg@ncols \\n[LL]-\\n[pg@colw]/(\\n[pg@colw]+\\n[pg*gutw])+1
485 .       ie \\n[pg@ncols]>1 \
486 .               nr pg*gutw \\n[LL]-(\\n[pg@ncols]*\\n[pg@colw])/(\\n[pg@ncols]-1)
487 .       el .nr pg*gutw 0
489 .HTML-TAG ".mc \\n[pg@ncols] \\n[pg@colw] \\n[pg*gutw]"
490 .mk pg*col-top
492 .nr pg*col-num 0
493 .nr pg@fn-colw \\n[pg@colw]*5/6
494 .par@reset
496 .de 2C
499 .de 1C
500 .MC \\n[LL]u
502 .\" top of page macro
503 .de pg@top
504 .ch pg*footer -\\n[FM]u/2u
505 .nr PN \\n%
506 .nr pg*col-num 0
507 .nr pg@fn-bottom-margin 0
508 .po \\n[PO]u
509 .ev h
510 .par@reset
511 .sp (u;\\n[HM]/2)
513 .sp |\\n[HM]u
514 .if d HD .HD
515 .mk pg@header-bottom
517 .mk pg*col-top
518 .pg*start-col
520 .de pg*start-col
521 .\" Handle footnote overflow before floating keeps, because the keep
522 .\" might contain an embedded footnote.
523 .fn@top-hook
524 .kp@top-hook
525 .tbl@top-hook
528 .de pg@cs-top
529 .sp \\n[HM]u
530 .\" move pg@bottom and pg*footer out of the way
531 .ch pg@bottom \\n[.p]u*2u
532 .ch pg*footer \\n[.p]u*2u
535 .de pg@bottom
536 .tbl@bottom-hook
537 .if \\n[pg@fn-flag] .fn@bottom-hook
538 .nr pg*col-num +1
539 .ie \\n[pg*col-num]<\\n[pg@ncols] .pg*end-col
540 .el .pg*end-page
542 .de pg*end-col
543 'sp |\\n[pg*col-top]u
544 .po (u;\\n[PO]+(\\n[pg@colw]+\\n[pg*gutw]*\\n[pg*col-num]))
545 .\"po +(u;\\n[pg@colw]+\\n[pg*gutw])
546 .pg*start-col
548 .de pg*end-page
549 .po \\n[PO]u
550 .\" Make sure we don't exit if there are still floats or footnotes left-over.
551 .ie \\n[kp@head]<\\n[kp@tail]:\\n[fn@have-overflow] \{\
552 .       \" Switching environments ensures that we don't get an unnecessary
553 .       \" blank line at the top of the page.
554 .       ev ne
555 '       bp
556 .       ev
558 .el \{\
559 .       \" If the text has ended and there are no more footnotes or keeps, exit.
560 .       if \\n[pg@text-ended] .ex
561 .       if r pg*next-number \{\
562 .               pn \\n[pg*next-number]
563 .               rr pg*next-number
564 .               if d pg*next-format \{\
565 .                       af PN \\*[pg*next-format]
566 .                       rm pg*next-format
567 .               \}
568 .       \}
569 '       bp
572 .\" pg@begin number format
573 .de pg@begin
574 .ie \\n[.$]>0 \{\
575 .       nr pg*next-number (;\\$1)
576 .       ie \\n[.$]>1 .ds pg*next-format \\$2
577 .       el .rm pg*next-format
579 .el .rr pg*next-number
580 .pg@super-eject
582 .\" print the footer line
583 .de pg*footer
584 .ev h
585 .par@reset
589 .\" flush out any keeps or footnotes
590 .de pg@super-eject
592 .if !'\\n(.z'' .@error-recover diversion open while ejecting page
593 .\" Make sure we stay in the end macro while there is still footnote overflow
594 .\" left, or floating keeps.
595 .while \\n[kp@tail]>\\n[kp@head]:\\n[pg@fn-flag] \{\
596 .       rs
597 .       bp
601 .nr pg@text-ended 0
602 .de pg@end-text
604 .nr pg@text-ended 1
605 .pg@super-eject
607 .em pg@end-text
608 .\" ***************************
609 .\" ******** module fn ********
610 .\" ***************************
611 .\" Footnotes.
612 .nr fn@sep-dist 8p
613 .ev fn
614 .\" Round it vertically
615 .vs \n[fn@sep-dist]u
616 .nr fn@sep-dist \n[.v]
618 .nr fn*text-num 0 1
619 .nr fn*note-num 0 1
620 .ds * \\*[par@sup-start]\En+[fn*text-num]\\*[par@sup-end]
621 .nr fn*open 0
622 .\" normal FS
623 .de @FS
624 .ie \\n[.$] .fn*do-FS "\\$1" no
625 .el \{\
626 .       ie \\n[fn*text-num]>\\n[fn*note-num] .fn*do-FS \\n+[fn*note-num]
627 .       el .fn*do-FS
630 .\" Second argument of `no' means don't embellish the first argument.
631 .de fn*do-FS
632 .if \\n[fn*open] .@error-recover nested FS
633 .nr fn*open 1
634 .if \\n[.u] \{\
635 .       \" Ensure that the first line of the footnote is on the same page
636 .       \" as the reference.  I think this is minimal.
637 .       ev fn
638 .       nr fn*need 1v
639 .       ev
640 .       ie \\n[pg@fn-flag] .nr fn*need +\\n[fn:PD]
641 .       el .nr fn*need +\\n[fn@sep-dist]
642 .       ne \\n[fn*need]u+\\n[.V]u>?0
644 .ev fn
645 .par@reset-env
646 .fn*start-div
647 .par@reset
648 .ie \\n[.$] .FP \\$@
649 .el .@LP
651 .de @FE
652 .ie !\\n[fn*open] .@error FE without FS
653 .el \{\
654 .       nr fn*open 0
655 .       br
656 .       ev
657 .       fn*end-div
660 .nr fn@have-overflow 0
661 .\" called at the top of each column
662 .de fn@top-hook
663 .nr fn*max-width 0
664 .nr fn*page-bottom-pos 0-\\n[FM]-\\n[pg@fn-bottom-margin]
665 .ch pg@bottom \\n[fn*page-bottom-pos]u
666 .if \\n[fn@have-overflow] \{\
667 .       nr fn@have-overflow 0
668 .       fn*start-div
669 .       ev nf
670 .       fn@overflow-div
671 .       ev
672 .       fn*end-div
675 .\" This is called at the bottom of the column if pg@fn-flag is set.
676 .de fn@bottom-hook
677 .nr pg@fn-flag 0
678 .nr fn@have-overflow 0
679 .nr fn@bottom-pos \\n[.p]-\\n[FM]-\\n[pg@fn-bottom-margin]+\\n[.v]
680 .ev fn
681 .nr fn@bottom-pos -\\n[.v]
683 .ie \\n[nl]+\\n[fn@sep-dist]+\n[.V]>\\n[fn@bottom-pos] \{\
684 .       rn fn@div fn@overflow-div
685 .       nr fn@have-overflow 1
687 .el \{\
688 .       if \\n[pg@ncols]>1 \
689 .               if \\n[fn*max-width]>\\n[pg@fn-colw] \
690 .                       nr pg@fn-bottom-margin \\n[.p]-\\n[FM]-\\n[nl]+1v
691 .       wh \\n[fn@bottom-pos]u fn*catch-overflow
692 .       fn@print-sep
693 .       ev nf
694 .       fn@div
695 .       rm fn@div
696 .       ev
697 .       if '\\n(.z'fn@overflow-div' \{\
698 .               di
699 .               nr fn@have-overflow \\n[dn]>0
700 .       \}
701 .       ch fn*catch-overflow
704 .de fn*catch-overflow
705 .di fn@overflow-div
707 .nr fn*embed-count 0
708 .de @div-end!fn@div
710 .if '\\n[.ev]'fn' .ev
711 .fn*end-div
712 .nr fn*open 0
714 .als @div-end!fn*embed-div @div-end!fn@div
715 .de fn*start-div
716 .ie '\\n(.z'' \{\
717 .       da fn@div
718 .       if !\\n[pg@fn-flag] .ns
720 .el .di fn*embed-div
722 .de fn*end-div
723 .ie '\\n(.z'fn@div' \{\
724 .       di
725 .       nr fn*page-bottom-pos -\\n[dn]
726 .       nr fn*max-width \\n[fn*max-width]>?\\n[dl]
727 .       if !\\n[pg@fn-flag] .nr fn*page-bottom-pos -\\n[fn@sep-dist]
728 .       nr pg@fn-flag 1
729 .       nr fn*page-bottom-pos \\n[nl]-\\n[.p]+\n[.V]>?\\n[fn*page-bottom-pos]
730 .       ch pg@bottom \\n[fn*page-bottom-pos]u
732 .el \{\
733 .       ie '\\n(.z'fn*embed-div' \{\
734 .       di
735 .               rn fn*embed-div fn*embed-div!\\n[fn*embed-count]
736 \!.             fn*embed-start \\n[fn*embed-count]
737 .               rs
738 '               sp (u;\\n[dn]+\\n[fn@sep-dist]+\\n[.V])
739 \!.             fn*embed-end
740 .               nr fn*embed-count +1
741 .       \}
742 .       el \{\
743 .               ev fn
744 .               @error-recover unclosed diversion within footnote
745 .       \}
748 .de fn*embed-start
749 .ie '\\n(.z'' \{\
750 .       fn*start-div
751 .       ev nf
752 .       fn*embed-div!\\$1
753 .       rm fn*embed-div!\\$1
754 .       ev
755 .       fn*end-div
756 .       di fn*null
758 .el \{\
759 \!.     fn*embed-start \\$1
760 .       rs
763 .de fn*embed-end
764 .ie '\\n(.z'fn*null' \{\
765 .       di
766 .       rm fn*null
768 .el \!.fn*embed-end
770 .\" It's important that fn@print-sep use up exactly fn@sep-dist vertical space.
771 .de fn@print-sep
772 .ev fn
773 .in 0
774 .vs \\n[fn@sep-dist]u
775 \D'l 1i 0'
779 .\" ***************************
780 .\" ******** module kp ********
781 .\" ***************************
782 .\" Keeps.
783 .de KS
785 .di kp*div
787 .de KF
788 .if !'\\n(.z'' .@error-recover KF while open diversion
789 .di kp*fdiv
790 .ev k
791 .par@reset-env
792 .par@reset
794 .de KE
795 .ie '\\n(.z'kp*div' .kp*end
796 .el \{\
797 .       ie '\\n(.z'kp*fdiv' .kp*fend
798 .       el .@error KE without KS or KF
801 .de @div-end!kp*div
802 .kp*end
804 .de @div-end!kp*fdiv
805 .kp*fend
807 .de kp*need
808 .ie '\\n(.z'' .ds@need \\$1
809 .el \!.kp*need \\$1
811 .\" end non-floating keep
812 .de kp*end
815 .kp*need \\n[dn]
816 .ev nf
817 .kp*div
819 .rm kp*div
821 .\" Floating keeps.
822 .nr kp@head 0
823 .nr kp@tail 0
824 .\" end floating keep
825 .de kp*fend
829 .ie \\n[.t]-(\\n[.k]>0*1v)>\\n[dn] \{\
830 .       br
831 .       ev nf
832 .       kp*fdiv
833 .       rm kp*fdiv
834 .       ev
836 .el \{\
837 .       rn kp*fdiv kp*div!\\n[kp@tail]
838 .       nr kp*ht!\\n[kp@tail] 0\\n[dn]
839 .       nr kp@tail +1
842 .\" top of page processing for KF
843 .nr kp*doing-top 0
844 .de kp@top-hook
845 .if !\\n[kp*doing-top] \{\
846 .       nr kp*doing-top 1
847 .       kp*do-top
848 .       nr kp*doing-top 0
851 .de kp*do-top
852 .\" If the first keep won't fit, only force it out if we haven't had a footnote
853 .\" and we're at the top of the page.
854 .nr kp*force \\n[pg@fn-flag]=0&(\\n[nl]<=\\n[pg@header-bottom])
855 .nr kp*fits 1
856 .while \\n[kp@tail]>\\n[kp@head]&\\n[kp*fits] \{\
857 .       ie \\n[.t]>\\n[kp*ht!\\n[kp@head]]:\\n[kp*force] \{\
858 .               nr kp*force 0
859 .               \" It's important to advance kp@head before bringing
860 .               \" back the keep, so that if the last line of the
861 .               \" last keep springs the bottom of page trap, a new
862 .               \" page will not be started unnecessarily.
863 .               rn kp*div!\\n[kp@head] kp*temp
864 .               nr kp@head +1
865 .               ev nf
866 .               kp*temp
867 .               ev
868 .               rm kp*temp
869 .       \}
870 .       el .nr kp*fits 0
873 .\" ***************************
874 .\" ******** module ds ********
875 .\" ***************************
876 .\" Displays and non-floating keeps.
877 .de DE
878 .ds*end!\\n[\\n[.ev]:ds-type]
879 .nr \\n[.ev]:ds-type 0
881 .als De DE
882 .de ds@auto-end
883 .if \\n[\\n[.ev]:ds-type] \{\
884 .       @error automatically terminating display
885 .       DE
888 .de @div-end!ds*div
889 .ie \\n[\\n[.ev]:ds-type] .DE
890 .el .ds*end!2
892 .de ds*end!0
893 .@error DE without DS, ID, CD, LD or BD
895 .de LD
897 .nr \\n[.ev]:ds-type 1
898 .par@reset
900 .sp \\n[DD]u
902 .de ID
904 .ie \\n[.$] .in +(n;\\$1)
905 .el .in +\\n[DI]u
907 .de CD
909 .ce 9999
911 .de RD
913 .rj 9999
915 .de ds*common-end
916 .par@reset
917 .sp \\n[DD]u
919 .als ds*end!1 ds*common-end
920 .de BD
922 .nr \\n[.ev]:ds-type 2
923 .di ds*div
925 .de ds*end!2
927 .ie '\\n(.z'ds*div' \{\
928 .       di
929 .       nf
930 .       in (u;\\n[.l]-\\n[dl]/2>?0)
931 .       ds*div
932 .       rm ds*div
933 .       ds*common-end
935 .el .@error-recover mismatched DE
937 .de DS
939 .di ds*div
940 .ie '\\$1'B' \{\
941 .       LD
942 .       nr \\n[.ev]:ds-type 4
944 .el \{\
945 .       ie '\\$1'L' .LD
946 .       el \{\
947 .               ie '\\$1'C' .CD
948 .               el \{\
949 .                       ie '\\$1'R' .RD
950 .                       el \{\
951 .                               ie '\\$1'I' .ID \\$2
952 .                               el .ID \\$1
953 .                       \}
954 .               \}
955 .       \}
956 .       nr \\n[.ev]:ds-type 3
959 .als Ds DS
960 .de ds@need
961 .if '\\n(.z'' \{\
962 .       while \\n[.t]<=(\\$1)&(\\n[nl]>\\n[pg@header-bottom]) \{\
963 .               rs
964 '               sp \\n[.t]u
965 .       \}
968 .de ds*end!3
970 .ie '\\n(.z'ds*div' \{\
971 .       di
972 .       ds@need \\n[dn]
973 .       ev nf
974 .       ds*div
975 .       ev
976 .       rm ds*div
977 .       ds*common-end
979 .el .@error-recover mismatched DE
981 .de ds*end!4
982 .ie '\\n(.z'ds*div' \{\
983 .       br
984 .       di
985 .       nf
986 .       in (u;\\n[.l]-\\n[dl]/2>?0)
987 .       ds@need \\n[dn]
988 .       ds*div
989 .       rm ds*div
990 .       ds*common-end
992 .el .@error-recover mismatched DE
994 .\" ****************************
995 .\" ******** module par ********
996 .\" ****************************
997 .\" Paragraph-level formatting.
998 .\" Load time initialization.
999 .de par@load-init
1000 .\" PS and VS might have been set on the command-line
1001 .if !rPS .nr PS 10
1002 .if !rLL .nr LL 6i
1003 .ll \\n[LL]u
1004 .\" don't set LT so that it can be defaulted from LL
1005 .ie rLT .lt \\n[LT]u
1006 .el .lt \\n[LL]u
1007 .ie (\\n[PS] >= 1000) \
1008 .       ps (\\n[PS]z / 1000u)
1009 .el \
1010 .       ps \\n[PS]
1011 .\" don't set VS so that it can be defaulted from PS
1012 .ie rVS \{\
1013 .       ie (\\n[VS] >= 1000) \
1014 .               par*vs "(\\n[VS]p / 1000u)"
1015 .       el \
1016 .               par*vs \\n[VS]
1018 .el \{\
1019 .       ie (\\n[PS] >= 1000) \
1020 .               par*vs "((\\n[PS]p / 1000u) + 2p)"
1021 .       el \
1022 .               par*vs "(\\n[PS] + 2)"
1024 .if dFAM .fam \\*[FAM]
1025 .if !rHY .nr HY 14
1026 .hy \\n[HY]
1028 .CHECK-FOOTER-AND-KEEP
1030 .de par*vs
1031 .\" If it's too big to be in points, treat it as units.
1032 .ie (p;\\$1)>=40p .vs (u;\\$1)
1033 .el .vs (p;\\$1)
1035 .de par@ab-indent
1036 .nr 0:li (u;\\n[LL]/12)
1037 .nr 0:ri \\n[0:li]
1039 .de par*env-init
1040 .aln \\n[.ev]:PS PS
1041 .aln \\n[.ev]:VS VS
1042 .aln \\n[.ev]:LL LL
1043 .aln \\n[.ev]:MCLL LL
1044 .aln \\n[.ev]:LT LT
1045 .aln \\n[.ev]:MCLT LT
1046 .aln \\n[.ev]:PI PI
1047 .aln \\n[.ev]:PD PD
1048 .ad \\n[par*adj]
1049 .par@reset-env
1051 .\" happens when the first page begins
1052 .de par@init
1053 .if !rLT .nr LT \\n[LL]
1054 .if !rFL .nr FL \\n[LL]*5/6
1055 .if !rVS \{\
1056 .       ie (\\n[PS] >= 1000) \
1057 .               nr VS (\\n[PS] + 2000)
1058 .       el \
1059 .               nr VS (\\n[PS] + 2)
1061 .if !rDI .nr DI .5i
1062 .if !rFPS \{\
1063 .       ie (\\n[PS] >= 1000) \
1064 .               nr FPS (\\n[PS] - 2000)
1065 .       el \
1066 .               nr FPS (\\n[PS] - 2)
1068 .if !rFVS \{\
1069 .       ie (\\n[FPS] >= 1000) \
1070 .               nr FVS (\\n[FPS] + 2000)
1071 .       el \
1072 .               nr FVS (\\n[FPS] + 2)
1074 .\" don't change environment 0
1075 .ev h
1076 .ie (\\n[PS] >= 1000) \
1077 .       ps (\\n[PS]z / 1000u)
1078 .el \
1079 .       ps \\n[PS]
1080 .if !rQI .nr QI 5n
1081 .if !rPI .nr PI 5n
1082 .ie (\\n[VS] >= 1000) \
1083 .       par*vs "(\\n[VS]p / 1000u)"
1084 .el \
1085 .       par*vs \\n[VS]
1086 .if !rPD .nr PD .3v>?\n(.V
1087 .if !rDD .nr DD .5v>?\n(.V
1088 .if !rFI .nr FI 2n
1089 .if !rFPD .nr FPD \\n[PD]/2
1091 .if !dFAM .ds FAM \\n[.fam]
1092 .nr par*adj \\n[.j]
1093 .par*env-init
1094 .ev h
1095 .par*env-init
1097 .ev fn
1098 .par*env-init
1100 .ev k
1101 .par*env-init
1103 .aln 0:MCLL pg@colw
1104 .aln 0:MCLT pg@colw
1105 .aln k:MCLL pg@colw
1106 .aln k:MCLT pg@colw
1107 .aln fn:PS FPS
1108 .aln fn:VS FVS
1109 .aln fn:LL FL
1110 .aln fn:LT FL
1111 .aln fn:PI FI
1112 .aln fn:PD FPD
1113 .aln fn:MCLL pg@fn-colw
1114 .aln fn:MCLT pg@fn-colw
1116 .de par@reset-env
1117 .nr \\n[.ev]:il 0
1118 .nr \\n[.ev]:li 0
1119 .nr \\n[.ev]:ri 0
1120 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1121 .nr \\n[.ev]:pli 0
1122 .nr \\n[.ev]:pri 0
1123 .nr \\n[.ev]:ds-type 0
1125 .\" par@reset
1126 .de par@reset
1128 .ce 0
1129 .rj 0
1130 .ul 0
1132 .ie \\n[pg@ncols]>1 \{\
1133 .       ll (u;\\n[\\n[.ev]:MCLL]-\\n[\\n[.ev]:ri]-\\n[\\n[.ev]:pri])
1134 .       lt \\n[\\n[.ev]:MCLT]u
1136 .el \{\
1137 .       ll (u;\\n[\\n[.ev]:LL]-\\n[\\n[.ev]:ri]-\\n[\\n[.ev]:pri])
1138 .       lt \\n[\\n[.ev]:LT]u
1140 .in (u;\\n[\\n[.ev]:li]+\\n[\\n[.ev]:pli])
1141 .ft 1
1142 .fam \\*[FAM]
1143 .ie (\\n[\\n[.ev]:PS] >= 1000) \
1144 .       ps (\\n[\\n[.ev]:PS]z / 1000u)
1145 .el \
1146 .       ps \\n[\\n[.ev]:PS]
1147 .ie (\\n[\\n[.ev]:VS] >= 1000) \
1148 .       par*vs "(\\n[\\n[.ev]:VS]p / 1000u)"
1149 .el \
1150 .       par*vs \\n[\\n[.ev]:VS]
1151 .ls 1
1153 .hy \\n[HY]
1155 .de @RT
1156 .nr \\n[.ev]:pli 0
1157 .nr \\n[.ev]:pri 0
1158 .par@reset
1160 .\" This can be redefined by the user.
1161 .de TA
1162 .ta T 5n
1164 .de par*start
1165 .ds@auto-end
1166 .nr \\n[.ev]:pli \\$1
1167 .nr \\n[.ev]:pri \\$2
1168 .par@reset
1169 .sp \\n[\\n[.ev]:PD]u
1170 .ne 1v+\\n(.Vu
1172 .de par@finish
1173 .nr \\n[.ev]:pli 0
1174 .nr \\n[.ev]:pri 0
1175 .par@reset
1177 .\" normal LP
1178 .de @LP
1179 .par*start 0 0
1180 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1182 .de @PP
1183 .par*start 0 0
1184 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1185 .if !'\*(.T'html' .ti +\\n[\\n[.ev]:ai]u
1187 .de @QP
1188 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1189 .par*start \\n[QI] \\n[QI]
1191 .de @XP
1192 .par*start \\n[\\n[.ev]:PI] 0
1193 .ti -\\n[\\n[.ev]:PI]u
1195 .de @IP
1196 .if \\n[.$]>1 .nr \\n[.ev]:ai (n;\\$2)
1197 .par*start \\n[\\n[.ev]:ai] 0
1198 .if !'\\$1'' \{\
1199 .       \" Divert the label so as to freeze any spaces.
1200 .       di par*label
1201 .       par*push-tag-env
1202 \&\\$1
1203 .       par*pop-tag-env
1204 .       di
1205 .       chop par*label
1206 .       ti -\\n[\\n[.ev]:ai]u
1207 .       ie \\n[dl]+1n<=\\n[\\n[.ev]:ai] \\*[par*label]\h'|\\n[\\n[.ev]:ai]u'\c
1208 .       el \{\
1209 \\*[par*label]
1210 .               br
1211 .       \}
1212 .       rm par*label
1215 .de @IP-html
1216 .if \\n[.$]>1 .nr \\n[.ev]:ai (n;\\$2)
1217 .par*start \\n[\\n[.ev]:ai] 0
1218 .if !'\\$1'' \{\
1219 .       \" Divert the label so as to freeze any spaces.
1220 .       di par*label
1221 .       par*push-tag-env
1222 \&\\$1
1223 .       par*pop-tag-env
1224 .       di
1225 .       chop par*label
1226 .       ti -\\n[\\n[.ev]:ai]u
1227 .       ie \\n[dl]+1n<=\\n[\\n[.ev]:ai] \{\
1228 .               HTML-TAG-NS ".col 1"
1229 \\$1\h'|\\n[\\n[.ev]:ai]u'\c
1230 .               HTML-TAG-NS ".col 2"
1231 .       \}
1232 .       el \{\
1233 \\$1
1234 .               br
1235 .       \}
1236 .       rm par*label
1239 .\" We don't want margin characters to be attached when we divert
1240 .\" the tag.  Since there's no way to save and restore the current
1241 .\" margin character, we have to switch to a new environment, taking
1242 .\" what we need of the old environment with us.
1243 .de par*push-tag-env
1244 .nr par*saved-font \\n[.f]
1245 .nr par*saved-size \\n[.s]z
1246 .nr par*saved-ss \\n[.ss]
1247 .ds par*saved-fam \\n[.fam]
1248 .ev par
1251 .ft \\n[par*saved-font]
1252 .ps \\n[par*saved-size]u
1253 .ss \\n[par*saved-ss]
1254 .fam \\*[par*saved-fam]
1256 .de par*pop-tag-env
1259 .de @RS
1261 .nr \\n[.ev]:li!\\n[\\n[.ev]:il] \\n[\\n[.ev]:li]
1262 .nr \\n[.ev]:ri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ri]
1263 .nr \\n[.ev]:ai!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ai]
1264 .nr \\n[.ev]:pli!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pli]
1265 .nr \\n[.ev]:pri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pri]
1266 .nr \\n[.ev]:il +1
1267 .nr \\n[.ev]:li +\\n[\\n[.ev]:ai]
1268 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1269 .par@reset
1271 .de @RE
1273 .ie \\n[\\n[.ev]:il] \{\
1274 .       nr \\n[.ev]:il -1
1275 .       nr \\n[.ev]:ai \\n[\\n[.ev]:ai!\\n[\\n[.ev]:il]]
1276 .       nr \\n[.ev]:li \\n[\\n[.ev]:li!\\n[\\n[.ev]:il]]
1277 .       nr \\n[.ev]:ri \\n[\\n[.ev]:ri!\\n[\\n[.ev]:il]]
1278 .       nr \\n[.ev]:pli \\n[\\n[.ev]:pli!\\n[\\n[.ev]:il]]
1279 .       nr \\n[.ev]:pri \\n[\\n[.ev]:pri!\\n[\\n[.ev]:il]]
1281 .el .@error unbalanced \\$0
1282 .par@reset
1284 .de @QS
1286 .nr \\n[.ev]:li!\\n[\\n[.ev]:il] \\n[\\n[.ev]:li]
1287 .nr \\n[.ev]:ri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ri]
1288 .nr \\n[.ev]:ai!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ai]
1289 .nr \\n[.ev]:pli!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pli]
1290 .nr \\n[.ev]:pri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pri]
1291 .nr \\n[.ev]:il +1
1292 .nr \\n[.ev]:li +\\n[QI]
1293 .nr \\n[.ev]:ri +\\n[QI]
1294 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI]
1295 .par@reset
1297 .als @QE @RE
1298 .\" start boxed text
1299 .de B1
1301 .HTML-IMAGE
1302 .di par*box-div
1303 .nr \\n[.ev]:li +1n
1304 .nr \\n[.ev]:ri +1n
1305 .nr par*box-in \\n[.in]
1306 .\" remember what 1n is, just in case the point size changes
1307 .nr par*box-n 1n
1308 .in +1n
1309 .ll -1n
1310 .lt -1n
1311 .ti \\n[par*box-in]u+1n
1313 .de @div-end!par*box-div
1316 .\" end boxed text
1317 .\" Postpone the drawing of the box until we're in the top-level diversion,
1318 .\" in case there's a footnote inside the box.
1319 .de B2
1320 .ie '\\n(.z'par*box-div' \{\
1321 .       br
1322 .       if \n[.V]>.25m .sp
1323 .       di
1324 .       if \n[.V]>.25m .sp
1325 .       ds@need \\n[dn]
1326 .       par*box-mark-top
1327 .       ev nf
1328 .       par*box-div
1329 .       ev
1330 .       nr \\n[.ev]:ri -\\n[par*box-n]
1331 .       nr \\n[.ev]:li -\\n[par*box-n]
1332 .       in -\\n[par*box-n]u
1333 .       ll +\\n[par*box-n]u
1334 .       lt +\\n[par*box-n]u
1335 .       par*box-draw \\n[.i]u \\n[.l]u-(\\n[.H]u==1n*1n)
1337 .el .@error B2 without B1
1338 .HTML-IMAGE-END
1340 .de par*box-mark-top
1341 .ie '\\n[.z]'' \{\
1342 .       rs
1343 .       mk par*box-top
1345 .el \!.par*box-mark-top
1347 .de par*box-draw
1348 .ie '\\n[.z]'' \{\
1349 .       nr par*box-in \\n[.i]
1350 .       nr par*box-ll \\n[.l]
1351 .       nr par*box-vpt \\n[.vpt]
1352 .       nr par*box-ad \\n[.j]
1353 .       ad l
1354 .       vpt 0
1355 .       in \\$1
1356 .       ll \\$2
1357 \v'-1v+.25m'\
1358 \D'l (u;\\n[.l]-\\n[.i]) 0'\
1359 \D'l 0 |\\n[par*box-top]u'\
1360 \D'l -(u;\\n[.l]-\\n[.i]) 0'\
1361 \D'l 0 -|\\n[par*box-top]u'
1362 .       br
1363 .       sp -1
1364 .       in \\n[par*box-in]u
1365 .       ll \\n[par*box-ll]u
1366 .       vpt \\n[par*box-vpt]
1367 .       ad \\n[par*box-ad]
1369 .el \!.par*box-draw \\$1 \\$2
1371 .de SH-NO-TAG
1372 .par@finish
1373 .\" Keep together the heading and the first two lines of the next paragraph.
1374 .ne 3v+\\n[\\n[.ev]:PD]u+\\n(.Vu
1375 .sp 1
1376 .ft B
1378 .de @SH
1379 .  SH-NO-TAG
1380 .  HTML-TAG ".SH 1"
1382 .\" TL, AU, and AI are aliased to these in cov*ab-init.
1383 .de par@TL
1384 .par@finish
1385 .sp 1
1386 .ft B
1387 .ps +2
1388 .vs +3p
1389 .ce 9999
1390 .HTML-TAG ".tl"
1392 .de par@AU
1393 .par@finish
1394 .sp 1
1395 .ft I
1396 .ce 9999
1398 .de par@AI
1399 .par@finish
1400 .sp .5
1401 .ce 9999
1403 .\" In paragraph macros.
1404 .de NL
1405 .ie (\\n[\\n[.ev]:PS] >= 1000) \
1406 .       ps (\\n[\\n[.ev]:PS]z / 1000u)
1407 .el \
1408 .       ps \\n[\\n[.ev]:PS]
1410 .de SM
1411 .ps -2
1413 .de LG
1414 .ps +2
1416 .de R
1417 .ft R
1419 .\" par*define-font-macro macro font
1420 .de par*define-font-macro
1421 .de \\$1
1422 .ie \\\\n[.$] \{\
1423 .       nr par*prev-font \\\\n[.f]
1424 \&\\\\$3\f[\\$2]\\\\$1\f[\\\\n[par*prev-font]]\\\\$2
1426 .el .ft \\$2
1427 \\..
1429 .par*define-font-macro B B
1430 .par*define-font-macro I I
1431 .par*define-font-macro BI BI
1432 .par*define-font-macro CW CR
1433 .\" underline a word
1434 .de UL
1435 \Z'\\$1'\v'.25m'\D'l \w'\\$1'u 0'\v'-.25m'\\$2
1437 .\" box a word
1438 .de BX
1439 .nr par*bxw \w'\\$1'+.4m
1440 \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''\
1441 \Z'\h'.2m'\\$1'\
1442 \h'\\n[par*bxw]u'
1444 .\" The first time UX is used, put a registered mark after it.
1445 .ds par*ux-rg \(rg
1446 .de UX
1447 \s[\\n[.s]*8u/10u]UNIX\s0\\$1\\*[par*ux-rg]
1448 .ds par*ux-rg
1450 .ds par@sup-start \v'-.9m\s'\En[.s]*7u/10u'+.7m'
1451 .als { par@sup-start
1452 .ds par@sup-end \v'-.7m\s0+.9m'
1453 .als } par@sup-end
1454 .\" footnote paragraphs
1455 .\" FF is the footnote format
1456 .nr FF 0
1457 .\" This can be redefined. It gets a second argument of `no' if the first
1458 .\" argument was supplied by the user, rather than automatically.
1459 .de FP
1461 .if !d par*fp!\\n[FF] \{\
1462 .       @error unknown footnote format `\\n[FF]'
1463 .       nr FF 0
1465 .ie '\\$2'no' .par*fp!\\n[FF]-no "\\$1"
1466 .el .par*fp!\\n[FF] "\\$1"
1468 .de par*fp!0
1469 .@PP
1470 \&\\*[par@sup-start]\\$1\\*[par@sup-end]\ \c
1472 .de par*fp!0-no
1473 .@PP
1474 \&\\$1\ \c
1476 .de par*fp!1
1477 .@PP
1478 \&\\$1.\ \c
1480 .de par*fp!1-no
1481 .@PP
1482 \&\\$1\ \c
1484 .de par*fp!2
1485 .@LP
1486 \&\\$1.\ \c
1488 .de par*fp!2-no
1489 .@LP
1490 \&\\$1\ \c
1492 .de par*fp!3
1493 .@IP "\\$1." (u;\\n[\\n[.ev]:PI]*2)
1495 .de par*fp!3-no
1496 .@IP "\\$1" (u;\\n[\\n[.ev]:PI]*2)
1498 .\" ***************************
1499 .\" ******** module nh ********
1500 .\" ***************************
1501 .\" Numbered headings.
1502 .\" nh*hl is the level of the last heading
1503 .nr nh*hl 0
1504 .\" numbered heading
1505 .de @NH
1506 .ie '\\$1'S' \{\
1507 .       shift
1508 .       nr nh*hl 0
1509 .       while \\n[.$] \{\
1510 .               nr nh*hl +1
1511 .               nr H\\n[nh*hl] 0\\$1
1512 .               shift
1513 .       \}
1514 .       if !\\n[nh*hl] \{\
1515 .               nr H1 1
1516 .               nr nh*hl 1
1517 .               @error missing arguments to .NH S
1518 .       \}
1520 .el \{\
1521 .       nr nh*ohl \\n[nh*hl]
1522 .       ie \\n[.$] \{\
1523 .               nr nh*hl 0\\$1
1524 .               ie \\n[nh*hl]<=0 \{\
1525 .                       nr nh*ohl 0
1526 .                       nr nh*hl 1
1527 .               \}
1528 .               el \{\
1529 .                       if \\n[nh*hl]-\\n[nh*ohl]>1 \
1530 .                               @warning .NH \\n[nh*ohl] followed by .NH \\n[nh*hl]
1531 .               \}
1532 .       \}
1533 .       el .nr nh*hl 1
1534 .       while \\n[nh*hl]>\\n[nh*ohl] \{\
1535 .               nr nh*ohl +1
1536 .               nr H\\n[nh*ohl] 0
1537 .       \}
1538 .       nr H\\n[nh*hl] +1
1540 .ds SN
1541 .nr nh*i 0
1542 .while \\n[nh*i]<\\n[nh*hl] \{\
1543 .       nr nh*i +1
1544 .       as SN \\n[H\\n[nh*i]].
1546 .SH-NO-TAG
1547 .HTML-TAG ".NH \\$1"
1548 \\*[SN]
1550 .\" ****************************
1551 .\" ******** module toc ********
1552 .\" ****************************
1553 .\" Table of contents generation.
1554 .de @XS
1555 .da toc*div
1556 .ev h
1557 .ie \\n[.$] .XA "\\$1"
1558 .el .XA
1560 .de @div-end!toc*div
1563 .de XA
1564 .ie '\\n(.z'toc*div' \{\
1565 .       if d toc*num .toc*end-entry
1566 .       ie \\n[.$] \{\
1567 .               ie '\\$1'no' .ds toc*num
1568 .               el .ds toc*num "\\$1
1569 .       \}
1570 .       el .ds toc*num \\n[PN]
1571 .       br
1572 .       par@reset
1573 .       na
1574 .       ll -8n
1575 .       in (n;0\\$2)
1577 .el .@error XA without XS
1579 .de XE
1580 .ie '\\n(.z'toc*div' \{\
1581 .       if d toc*num .toc*end-entry
1582 .       ev
1583 .       di
1585 .el .@error XE without XS
1587 .de toc*end-entry
1588 \\a\\t\\*[toc*num]
1590 .rm toc*num
1592 .de PX
1594 .if !'\\$1'no' \{\
1595 .       ce 1
1596 .       ie (\\n[PS] >= 1000) \
1597 .               ps ((\\n[PS]z / 1000u) + 2z)
1598 .       el \
1599 .               ps \\n[PS]+2
1600 .       ft B
1601 \\*[TOC]
1602 .       ft
1603 .       ps
1606 .char \[toc*leader-char] .\h'1m'
1607 .lc \[toc*leader-char]
1608 .ta (u;\\n[.l]-\\n[.i]-\w'000') (u;\\n[.l]-\\n[.i])R
1609 .sp 2
1610 .toc*div
1611 .par@reset
1613 .\" print the table of contents on page i
1614 .de TC
1616 .pg@begin 1 i
1617 .PX \\$1
1619 .\" ****************************
1620 .\" ******** module eqn ********
1621 .\" ****************************
1622 .\" Eqn support.
1623 .de EQ
1625 .de EN
1627 .de @EQ
1629 .ds eqn*num "\\$2
1630 .ie '\\$1'L' .nr eqn*type 0
1631 .el \{\
1632 .       ie '\\$1'I' .nr eqn*type 1
1633 .       el \{\
1634 .               nr eqn*type 2
1635 .               if !'\\$1'C' .ds eqn*num "\\$1
1636 .       \}
1638 .di eqn*div
1639 .in 0
1640 .if \\n[eqn*type]=0 .HTML-IMAGE-LEFT
1641 .if \\n[eqn*type]=1 \{\
1642 .   if '\*(.T'html' .RS
1643 .   HTML-IMAGE-INLINE
1645 .if \\n[eqn*type]=2 .HTML-IMAGE
1646 .if !'\*(.T'html' .nf
1648 .de @div-end!eqn*div
1649 .@EN
1651 .\" Note that geqn mark and lineup work correctly in centered equations.
1652 .de @EN
1653 .ie !'\\n(.z'eqn*div' .@error-recover mismatched EN
1654 .el \{\
1655 .       br
1656 .       di
1657 .       nr eqn*have-num 0
1658 .       if !'\\*[eqn*num]'' .nr eqn*have-num 1
1659 .       ie \\n[dl]:\\n[eqn*have-num] \{\
1660 .               if !'\*(.T'html' .sp \\n[DD]u
1661 .               par@reset
1662 .               ds eqn*tabs \\n[.tabs]
1663 .               nf
1664 .               ie \\n[dl] \{\
1665 .\"                     --fixme-- this really should not be necessary
1666 .\"                     and indicates that there is extra space creeping into
1667 .\"                     an equation when ps4html is enabled..
1668 .                       ie r ps4html .ds@need \\n[dn]u-1v+\n[.V]u+1i
1669 .                       el .ds@need \\n[dn]u-1v+\n[.V]u
1670 .                       chop eqn*div
1671 .                       ie \\n[eqn*type]=0 \{\
1672 .                               ta (u;\\n[.l]-\\n[.i])R
1673 \\*[eqn*div]\t\\*[eqn*num]
1674 .                       \}
1675 .                       el \{\
1676 .                               ie \\n[eqn*type]=1 .ta \\n[DI]u \
1677 (u;\\n[.l]-\\n[.i])R
1678 .                               el .ta (u;\\n[.l]-\\n[.i]/2)C \
1679 (u;\\n[.l]-\\n[.i])R
1680 \t\\*[eqn*div]\t\\*[eqn*num]
1681 .                       \}
1682 .               \}
1683 .               el \{\
1684 .                       ta (u;\\n[.l]-\\n[.i])R
1685 \t\\*[eqn*num]
1686 .               \}
1687 .               if !'\*(.T'html' .sp \\n[DD]u
1688 .               ta \\*[eqn*tabs]
1689 .       \}
1690 .       el \{
1691 .\" must terminate empty equations in html and ps4html as they contain
1692 .\" the HTML-IMAGE-END suppression nodes
1693 .               if \\n[dl] .chop eqn*div
1694 .               if '\*(.T'html' \\*[eqn*div]
1695 .               if r ps4html    \\*[eqn*div]
1696 .       \}
1697 .       if !'\*(.T'html' .fi
1698 .       if \\n[eqn*type]=0 .HTML-IMAGE-END
1699 .       if \\n[eqn*type]=1 \{\
1700 .               HTML-IMAGE-END
1701 .               if '\*(.T'html' .RE
1702 .       \}
1703 .       if \\n[eqn*type]=2 .HTML-IMAGE-END
1706 .\" ****************************
1707 .\" ******** module tbl ********
1708 .\" ****************************
1709 .\" Tbl support.
1710 .nr tbl*have-header 0
1711 .\" This gets called if TS occurs before the first paragraph.
1712 .de TS
1714 .\" cov*ab-init aliases TS to @TS
1715 \\*[TS]\\
1717 .de @TS
1718 .sp \\n[DD]u
1719 .\" .if !'\*(.T'html' .sp \\n[DD]u
1720 .if '\\$1'H' .di tbl*header-div
1721 .HTML-IMAGE
1723 .de tbl@top-hook
1724 .if \\n[tbl*have-header] \{\
1725 .       ie \\n[.t]-\\n[tbl*header-ht]-1v .tbl*print-header
1726 .       el .sp \\n[.t]u
1729 .de tbl*print-header
1730 .ev nf
1731 .tbl*header-div
1733 .mk #T
1735 .de TH
1736 .ie '\\n[.z]'tbl*header-div' \{\
1737 .       nr T. 0
1738 .       T#
1739 .       br
1740 .       di
1741 .       ie \\n[dn]+\\n[FM]+\\n[HM]+2v>=\\n[.p] \{\
1742 .               @error ridiculously long table header
1743 .               ds@need \\n[dn]
1744 .               tbl*print-header
1745 .       \}
1746 .       el \{\
1747 .               nr tbl*header-ht \\n[dn]
1748 .               ds@need \\n[dn]u+1v
1749 .               tbl*print-header
1750 .               nr tbl*have-header 1
1751 .       \}
1753 .el .@error-recover .TH without .TS H
1755 .de @div-end!tbl*header-div
1759 .de TE
1760 .ie '\\n(.z'tbl*header-div' .@error-recover .TS H but no .TH before .TE
1761 .el \{\
1762 .       nr tbl*have-header 0
1763 .       if !'\*(.T'html' .sp \\n[DD]u
1765 .       HTML-IMAGE-END
1766 .\" reset tabs
1769 .de tbl@bottom-hook
1770 .if \\n[tbl*have-header] \{\
1771 .       nr T. 1
1772 .       T#
1775 .de T&
1777 .\" ****************************
1778 .\" ******** module pic ********
1779 .\" ****************************
1780 .\" Pic support.
1781 .\" PS height width
1782 .de PS
1784 .sp \\n[DD]u
1785 .ie \\n[.$]<2 .@error bad arguments to PS (not preprocessed with pic?)
1786 .el \{\
1787 .       ds@need (u;\\$1)+1v
1788 .       in +(u;\\n[.l]-\\n[.i]-\\$2/2>?0)
1790 .HTML-IMAGE
1792 .de PE
1793 .HTML-IMAGE-END
1794 .par@reset
1795 .sp \\n[DD]u+.5m
1797 .\" ****************************
1798 .\" ******** module ref ********
1799 .\" ****************************
1800 .\" Refer support.
1801 .de ]-
1802 .rm [A [B [C [D [E [G [I [J [N [O [P [Q [R [S [T [V
1803 .rm ref*string
1805 .\" Other
1806 .ds ref*spec!0 Q A T1 S V N P I C D O
1807 .\" Journal article
1808 .ds ref*spec!1 Q A T2 J S V N P I C D O
1809 .\" Book
1810 .ds ref*spec!2 Q A T1 S V P I C D O
1811 .\" Article within book
1812 .ds ref*spec!3 Q A T2 B E S V P I C D O
1813 .\" Tech report
1814 .ds ref*spec!4 Q A T2 R G P I C D O
1815 .\" ][ type
1816 .de ][
1817 .if r [T \{\
1818 .       als [T1 [T
1819 .       als [T2 [T
1821 .ie d ref*spec!\\$1 .ref*build \\*[ref*spec!\\$1]
1822 .el \{\
1823 .       @error unknown reference type `\\$1'
1824 .       ref*build \\*[ref*spec!0]
1826 .ref*print
1827 .rm ref*string
1828 .rm [F [T1 [T2
1830 .\" start of reference number
1831 .ds [. \\*[par@sup-start]
1832 .\" end of reference number
1833 .ds .] \\*[par@sup-end]
1834 .\" period before reference
1835 .ds <. .
1836 .\" period after reference
1837 .ds >. \" empty
1838 .\" comma before reference
1839 .ds <, ,
1840 .\" comma after reference
1841 .ds >, \" empty
1842 .\" start collected references
1843 .de ]<
1844 .als ref*print ref*end-print
1846 \&\\*[REFERENCES]
1847 .par@reset
1849 .\" end collected references
1850 .de ]>
1851 .par@finish
1852 .als ref*print ref*normal-print
1854 .de ref*normal-print
1855 .ie d [F .FS "\\*([.\\*([F\\*(.]"
1856 .el .FS \&
1857 \\*[ref*string]
1860 .de ref*end-print
1861 .ie d [F .IP "\\*([F."
1862 .el .XP
1863 \\*[ref*string]
1865 .als ref*print ref*normal-print
1866 .de ref*build
1867 .rm ref*string ref*post-punct
1868 .nr ref*suppress-period 1
1869 .while \\n[.$] \{\
1870 .       if d [\\$1 \{\
1871 .               ie d ref*add-\\$1 .ref*add-\\$1
1872 .               el .ref*add-dflt \\$1
1873 .       \}
1874 .       shift
1876 .\" now add a final period
1877 .ie d ref*string \{\
1878 .       if !\\n[ref*suppress-period] .as ref*string .
1879 .       if d ref*post-punct \{\
1880 .               as ref*string "\\*[ref*post-punct]
1881 .               rm ref*post-punct
1882 .       \}
1884 .el .ds ref*string
1886 .de ref*add-T1
1887 .ref*field T , "\fI" "" "\fP"
1888 .if r [T .nr ref*suppress-period \\n([T
1890 .de ref*add-T2
1891 .ref*field T , "\\*Q" "" "\\*U"
1892 .if r [T .nr ref*suppress-period \\n([T
1894 .de ref*add-P
1895 .ie \\n([P>0 .ref*field P , "pp. "
1896 .el .ref*field P , "p. "
1898 .de ref*add-J
1899 .ref*field J , \fI "" \fP
1901 .de ref*add-D
1902 .ref*field D "" ( )
1904 .de ref*add-E
1905 .ref*field E , "ed. "
1907 .de ref*add-G
1908 .ref*field G "" ( )
1910 .de ref*add-B
1911 .ref*field B "" "in \fI" "" \fP
1913 .de ref*add-O
1914 .ref*field O .
1915 .ie r [O .nr ref*suppress-period \\n([O
1916 .el .nr ref*suppress-period 1
1918 .de ref*add-A
1919 .ref*field A ,
1920 .if r [A .nr ref*suppress-period \\n([A
1922 .de ref*add-dflt
1923 .ref*field \\$1 ,
1925 .\" First argument is the field letter.
1926 .\" Second argument is the punctuation character to use to separate this field
1927 .\" from the previous field.
1928 .\" Third argument is a string with which to prefix this field.
1929 .\" Fourth argument is a string with which to postfix this field.
1930 .\" Fifth argument is a string to add after the punctuation character supplied
1931 .\" by the next field.
1932 .de ref*field
1933 .if d ref*string \{\
1934 .       ie d ref*post-punct \{\
1935 .               as ref*string "\\$2\\*[ref*post-punct] \"
1936 .               rm ref*post-punct
1937 .       \}
1938 .       el .as ref*string "\\$2 \"
1940 .as ref*string "\\$3\\*([\\$1\\$4
1941 .if \\n[.$]>4 .ds ref*post-punct "\\$5
1942 .nr ref*suppress-period 0
1944 .\" ****************************
1945 .\" ******** module acc ********
1946 .\" ****************************
1947 .\" Accents and special characters.
1948 .ds Q \(lq
1949 .ds U \(rq
1950 .ds - \(em
1951 .\" Characters
1952 .\" The idea of this definition is for the top of the 3 to be at the x-height.
1953 .if !c\[yogh] .char \[yogh] \Z'\v'\w'x'*0-\En[rst]u'\s[\En[.s]*8u/10u]\
1954 \v'\w'3'*0+\En[rst]u'3\s0'\h'\w'\s[\En[.s]*8u/10u]3'u'
1955 .\" Accents
1956 .de acc*over-def
1957 .ds \\$1 \Z'\v'(u;\w'x'*0+\En[rst]-\En[.cht])'\
1958 \h'(u;-\En[skw]+(-\En[.w]-\w'\\$2'/2)+\En[.csk])'\\$2'
1960 .de acc*under-def
1961 .ds \\$1 \Z'\v'\En[.cdp]u'\h'(u;-\En[.w]-\w'\\$2'/2)'\\$2'
1963 .de acc*slash-def
1964 .ds \\$1 \Z'\h'(u;-\En[.w]-\w'\\$2'/2)'\
1965 \v'(u;\En[.cdp]-\En[.cht]+\En[rst]+\En[rsb]/2)'\\$2'
1967 .de acc*prefix-def
1968 .ds \\$1 \Z'\h'(u;\w'x'-\w'\\$2'/2)'\\$2'
1970 .acc*prefix-def ' \'
1971 .acc*prefix-def ` \`
1972 .acc*prefix-def ^ ^
1973 .acc*prefix-def , \(ac
1974 .acc*prefix-def : \(ad
1975 .acc*prefix-def ~ ~
1976 .\" improved accent marks
1977 .de AM
1978 .acc*over-def ' \'
1979 .acc*over-def ` \`
1980 .acc*over-def ^ ^
1981 .acc*over-def ~ ~
1982 .acc*over-def : \(ad
1983 .acc*over-def v \(ah
1984 .acc*over-def _ \(a-
1985 .acc*over-def o \(ao
1986 .acc*under-def , \(ac
1987 .acc*under-def . \s[\En[.s]*8u/10u]\v'.2m'.\v'-.2m'\s0
1988 .acc*under-def hook \(ho
1989 .acc*slash-def / /
1990 .char \[hooko] o\\\\*[hook]
1991 .ds q \[hooko]
1992 .ds 3 \[yogh]
1993 .ds D- \(-D\"                   Icelandic uppercase eth
1994 .ds d- \(Sd\"                   Icelandic lowercase eth
1995 .ds Th \(TP\"                   Icelandic uppercase thorn
1996 .ds th \(Tp\"                   Icelandic lowercase thorn
1997 .ds 8 \(ss\"                    German double s
1998 .ds Ae \(AE\"                   AE ligature
1999 .ds ae \(ae\"                   ae ligature
2000 .ds Oe \(OE\"                   OE ligature
2001 .ds oe \(oe\"                   oe ligature
2002 .ds ? \(r?\"                    upside down ?
2003 .ds ! \(r!\"                    upside down !
2005 .de CHECK-FOOTER-AND-KEEP
2006 .\" it might be better to als FS -> B1 and FE -> B2
2007 .\" however this produced wierd results, so I've moved back to a more reliable
2008 .\" but less interesting solution --fixme--
2009 .   if '\*(.T'html' \{\
2010 .       rm KF
2011 .       als KF KS
2012 .       rm FS
2013 .       de FS
2014 .               br
2015 .               HTML-IMAGE
2016 \\..
2017 .       rm FE
2018 .       de FE
2019 .               br
2020 .               HTML-IMAGE-END
2021 \\..
2022 .   \}
2023 .   if r ps4html \{\
2024 .       rm FS
2025 .       de FS
2026 .               br
2027 .               HTML-IMAGE
2028 \\..
2029 .       rm FE
2030 .       de FE
2031 .               br
2032 .               HTML-IMAGE-END
2033 \\..
2034 .   \}
2036 .par@load-init
2037 .if '\*(.T'html' \{\
2038 .  rm @IP
2039 .  als @IP @IP-html
2041 .\" Make sure that no blank lines creep in at the end of this file.