-*- nroff -*-
s.tmac Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Written by James Clark (jjc@jclark.com) This file is part of groff. groff is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. groff is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with groff; see the file COPYING. If not, write to the Free Software Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. .. . ab The groff ms macros do not work in compatibility mode. Enable warnings (only if none are given on the command line).
You can delete this if you want.
See if already loaded.
.mso devtag.tmac .nr GS 1 .nr need_eo_h 0 .nr need_eo_tl 0 .tm \\n(.F:\\n(.c: macro error: \\$* .. .tm \\n(.F:\\n(.c: macro warning: \\$* .. .ab \\n(.F:\\n(.c: fatal macro error: \\$* .. .@error sorry, \\$0 not implemented .als \\$0 @nop .. .als TM @not-implemented .als CT @not-implemented .. a non-empty environment
.ev ne \c .ev .ev nf 'nf .ev .. .. .. indexing
.tm \\$1\t\\$2\t\\$3\t\\$4 ... \\n[PN] .. print an error message and then try to recover
.@error \\$@ (recovering) .nr *pop-count 0 .while !'\\n(.z'' \{\ . \"@warning automatically terminating diversion \\n(.z . ie d @div-end!\\n(.z .@div-end!\\n(.z . el .*div-end-default . nr *pop-count +1 . \" ensure that we don't loop forever . if \\n[*pop-count]>20 .@fatal recovery failed .\} .while !'\\n[.ev]'0' .ev .par@reset-env .par@reset ..

.di .ev nf .\\*[*last-div] .ev .. ****************************
******** module cov ********
****************************
Cover sheet and first page.
.@error \\$0 is not allowed after the first page has started .. .@error \\$0 is not allowed before TL .. .@error \\$0 is not allowed more than once .. .@error \\$0 is not allowed after first AB, LP, PP, IP, SH or NH .. .als AU cov*err-not-before-tl .als AI cov*err-not-before-tl .als AB cov*err-not-before-tl .par@init .als RP cov*err-not-after-first-page .@init . pg@cs-top . als FS cov*FS . als FE cov*FE .\} . pg@top . als FS @FS . als FE @FE .\} .wh 0 pg@top .CHECK-FOOTER-AND-KEEP .. .wh 0 cov*first-page-init This handles the case where FS occurs before TL or LP.

\\*[FS]\\ .. .nr cov*rp-format 0 .nr cov*rp-no 0 released paper format
.nr cov*rp-format 1 ..

.als TL cov*err-not-again .rn @AB AB .rn @AU AU .rn @AI AI .di cov*tl-div .par@reset .vs +3p .nr cov*n-au 0 VTAG-TL .. .par@reset . br . di .\} .nr cov*n-au +1 .di cov*au-div!\\n[cov*n-au]

. ps (\\n[PS]z / 1000u)
. ps \\n[PS]
..
.par@reset
. br
. di
.\}
. di cov*ai-div!\\n[cov*n-au]
. nf
. ft R
. ie (\\n[PS] >= 1000) \
. ps (\\n[PS]z / 1000u)
. el \
. ps \\n[PS]
.\}
..
. br
. di
.\}

.cov*ab-init .cov*print \\*[\\$0]\\ .. .als IP LP .als PP LP .als XP LP .als QP LP .als RS LP .als NH LP .als SH LP .als MC LP .als RT LP .als XS LP .als cov*ab-init @nop .als LP @LP .als IP @IP .als PP @PP .als XP @XP .als RT @RT .als XS @XS .als SH @SH .als NH @NH .als QP @QP .als RS @RS .als RE @RE .als QS @QS .als QE @QE .als MC @MC .als EQ @EQ .als EN @EN .als TS @TS .als AB cov*err-not-after-ab .als AU par@AU .als AI par@AI .als TL par@TL .. . br . di .\} .cov*ab-init . cov*tl-au-print . als cov*tl-au-print @nop .\} .par@ab-indent .par@reset . if '\*(.T'html' \{\ . nf . sp . \} . ft I . ce 1 \\*[ABSTRACT] . sp . ft R .\} .ns .@PP . cov*tl-au-print . als cov*tl-au-print @nop . par@reset-env . par@reset . cov*print .\} .. . als AE cov*err-not-again .\} . ie '\\n(.z'cov*ab-div' \{\ . als AE cov*err-not-again . br . di nr cov*ab-height \\n[dn]
. par@reset-env . par@reset . cov*print . \} . el .@error AE without AB .\} .. .AE .. .als cov*print @nop . ie \\n[cov*rp-format] .cov*rp-print . el .cov*draft-print .\} . if \\n[cov*rp-format] \{\ . @warning RP format but no TL . bp 1 . als FS @FS . als FE @FE . CHECK-FOOTER-AND-KEEP . \} . br .\} .. .nr cov*page-length \\n[.p] .cov*tl-au-print . if !'\*(.T'html' . nf . cov*ab-div .\} .par@reset \\*[DY]

. sp |(u;\\n[cov*page-length]-\\n[FM]\ -\\n[cov*fn-height]-\\n[fn@sep-dist]>?\\n[nl]) . fn@print-sep . ev nf . cov*fn-div . ev . ie \\n[cov*rp-no] .rm cov*fn-div . el \{\ . rn cov*fn-div fn@overflow-div . nr fn@have-overflow 1 . \} .\} .als FS @FS .als FE @FE .CHECK-FOOTER-AND-KEEP If anything was printed below where the footer line is normally printed,
then that's an overflow.
.bp 1 .rs .. .cov*tl-au-print . nf . sp 2 . cov*ab-div .\} .. .par@reset

.rs

9999 . cov*tl-div . DEVTAG-EO-TL .\} .nr cov*i 1 .nr cov*sp 1v .while \\n[cov*i]<=\\n[cov*n-au] \{\ . ie '\*(.T'html' .br . el .sp \\n[cov*sp]u . cov*au-div!\\n[cov*i] . ie d cov*ai-div!\\n[cov*i] \{\ . sp .5v . cov*ai-div!\\n[cov*i] . nr cov*sp 1v . \} . el .nr cov*sp .5v . nr cov*i +1 .\}

0 .. .nr cov*fn-height 0 .nr cov*in-fn 0 start of footnote on cover
. @error nested FS . FE .\} .nr cov*in-fn 1 .ev fn .par@reset-env .da cov*fn-div .. .cov*FE .. end of footnote on cover
. br . ev . di . nr cov*in-fn 0 . nr cov*fn-height +\\n[dn] .\} .. ***************************
******** module pg ********
***************************
Page-level formatting.
> 0 if we have a footnote on the current page
.nr pg@fn-flag 0 .nr pg@colw 0 .nr pg@fn-colw 0 .nr HM 1i .nr FM 1i .. .als EH OH .als OF OH .als EF OH . ie o .tl \\*[pg*OH] . el .tl \\*[pg*EH] .\} .. .. .nr pg*P1 0 .nr pg*P1 1 .. .wh -\n[FM]u pg@bottom .wh -\n[FM]u/2u pg*footer .nr MINGW 2n .nr pg@ncols 1

. \" flush out any floating keeps . while \\n[kp@tail]>\\n[kp@head] \{\ . rs . bp . \} .\} . nr pg@colw \\n[LL]*7/15 . nr pg*gutw \\n[LL]-(2*\\n[pg@colw]) . nr pg@ncols 2 .\} . nr pg@colw (n;\\$1)<?\\n[LL] . ie \\n[.$]<2 .nr pg*gutw \\n[MINGW] . el .nr pg*gutw (n;\\$2) . nr pg@ncols \\n[LL]-\\n[pg@colw]/(\\n[pg@colw]+\\n[pg*gutw])+1 . ie \\n[pg@ncols]>1 \ . nr pg*gutw \\n[LL]-(\\n[pg@ncols]*\\n[pg@colw])/(\\n[pg@ncols]-1) . el .nr pg*gutw 0 .\} VTAG ".mc \\n[pg@ncols] \\n[pg@colw] \\n[pg*gutw]"

pg*col-top .ns .nr pg*col-num 0 .nr pg@fn-colw \\n[pg@colw]*5/6 .par@reset .. .MC .. .MC \\n[LL]u .. top of page macro
.ch pg*footer -\\n[FM]u/2u .nr PN \\n% .nr pg*col-num 0 .nr pg@fn-bottom-margin 0 .po \\n[PO]u .ev h .par@reset

T

pg@header-bottom .ev

pg*col-top .pg*start-col .. Handle footnote overflow before floating keeps, because the keep
might contain an embedded footnote.
.fn@top-hook .kp@top-hook .tbl@top-hook .ns .. move pg@bottom and pg*footer out of the way
.ch pg@bottom \\n[.p]u*2u .ch pg*footer \\n[.p]u*2u .ns .. .tbl@bottom-hook .nr pg*col-num +1 .. 'sp |\\n[pg*col-top]u .po (u;\\n[PO]+(\\n[pg@colw]+\\n[pg*gutw]*\\n[pg*col-num])) po +(u;\\n[pg@colw]+\\n[pg*gutw])
.pg*start-col .. .po \\n[PO]u Make sure we don't exit if there are still floats or footnotes left-over.
. \" Switching environments ensures that we don't get an unnecessary . \" blank line at the top of the page. . ev ne ' bp . ev .\} . \" If the text has ended and there are no more footnotes or keeps, exit. . if \\n[pg@text-ended] .ex . if r pg*next-number \{\ . pn \\n[pg*next-number] . rr pg*next-number . if d pg*next-format \{\ . af PN \\*[pg*next-format] . rm pg*next-format . \} . \} ' bp .\} .. pg@begin number format
. nr pg*next-number (;\\$1) . ie \\n[.$]>1 .ds pg*next-format \\$2 . el .rm pg*next-format .\} .pg@super-eject .. print the footer line
.ev h .par@reset T .ev .. flush out any keeps or footnotes

Make sure we stay in the end macro while there is still footnote overflow
left, or floating keeps.
.while \\n[kp@tail]>\\n[kp@head]:\\n[pg@fn-flag] \{\ . rs . bp .\} .bp .. .nr pg@text-ended 0

.nr pg@text-ended 1 .pg@super-eject .. .em pg@end-text ***************************
******** module fn ********
***************************
Footnotes.
.nr fn@sep-dist 8p .ev fn Round it vertically
.vs \n[fn@sep-dist]u .nr fn@sep-dist \n[.v] .ev .nr fn*text-num 0 1 .nr fn*note-num 0 1 .nr fn*open 0 normal FS
. ie \\n[fn*text-num]>\\n[fn*note-num] .fn*do-FS \\n+[fn*note-num] . el .fn*do-FS .\} .. Second argument of `no' means don't embellish the first argument.
.nr fn*open 1 . \" Ensure that the first line of the footnote is on the same page . \" as the reference. I think this is minimal. . ev fn . nr fn*need 1v . ev . ie \\n[pg@fn-flag] .nr fn*need +\\n[fn:PD] . el .nr fn*need +\\n[fn@sep-dist] . ne \\n[fn*need]u+\\n[.V]u>?0 .\} .ev fn .par@reset-env .fn*start-div .par@reset .. . nr fn*open 0 . br . ev . fn*end-div .\} .. .nr fn@have-overflow 0 called at the top of each column
.nr fn*max-width 0 .nr fn*page-bottom-pos 0-\\n[FM]-\\n[pg@fn-bottom-margin] .ch pg@bottom \\n[fn*page-bottom-pos]u . nr fn@have-overflow 0 . fn*start-div . ev nf . fn@overflow-div . ev . fn*end-div .\} .. This is called at the bottom of the column if pg@fn-flag is set.
.nr pg@fn-flag 0 .nr fn@have-overflow 0 .nr fn@bottom-pos \\n[.p]-\\n[FM]-\\n[pg@fn-bottom-margin]+\\n[.v] .ev fn .nr fn@bottom-pos -\\n[.v] .ev . rn fn@div fn@overflow-div . nr fn@have-overflow 1 .\} . if \\n[pg@ncols]>1 \ . if \\n[fn*max-width]>\\n[pg@fn-colw] \ . nr pg@fn-bottom-margin \\n[.p]-\\n[FM]-\\n[nl]+1v . wh \\n[fn@bottom-pos]u fn*catch-overflow . fn@print-sep . ev nf . fn@div . rm fn@div . ev . if '\\n(.z'fn@overflow-div' \{\ . di . nr fn@have-overflow \\n[dn]>0 . \} . ch fn*catch-overflow .\} .. .di fn@overflow-div .. .nr fn*embed-count 0

.fn*end-div .nr fn*open 0 .. .als @div-end!fn*embed-div @div-end!fn@div . da fn@div . if !\\n[pg@fn-flag] .ns .\} .. . di . nr fn*page-bottom-pos -\\n[dn] . nr fn*max-width \\n[fn*max-width]>?\\n[dl] . if !\\n[pg@fn-flag] .nr fn*page-bottom-pos -\\n[fn@sep-dist] . nr pg@fn-flag 1 . nr fn*page-bottom-pos \\n[nl]-\\n[.p]+\n[.V]>?\\n[fn*page-bottom-pos] . ch pg@bottom \\n[fn*page-bottom-pos]u .\} . ie '\\n(.z'fn*embed-div' \{\ . di . rn fn*embed-div fn*embed-div!\\n[fn*embed-count] \!. fn*embed-start \\n[fn*embed-count] . rs ' sp (u;\\n[dn]+\\n[fn@sep-dist]+\\n[.V]) \!. fn*embed-end . nr fn*embed-count +1 . \} . el \{\ . ev fn . @error-recover unclosed diversion within footnote . \} .\} .. . fn*start-div . ev nf . fn*embed-div!\\$1 . rm fn*embed-div!\\$1 . ev . fn*end-div . di fn*null .\} \!. fn*embed-start \\$1 . rs .\} .. . di . rm fn*null .\} .. It's important that fn@print-sep use up exactly fn@sep-dist vertical space.
.ev fn .vs \\n[fn@sep-dist]u \D'l 1i 0'

.ev .. ***************************
******** module kp ********
***************************
Keeps.

.di kp*div .. .di kp*fdiv .ev k .par@reset-env .par@reset .. . ie '\\n(.z'kp*fdiv' .kp*fend . el .@error KE without KS or KF .\} .. .kp*end .. .kp*fend .. .. end non-floating keep

.di .kp*need \\n[dn] .ev nf .kp*div .ev .. Floating keeps.
.nr kp@head 0 .nr kp@tail 0 end floating keep

.ev .di . br . ev nf . kp*fdiv . rm kp*fdiv . ev .\} . rn kp*fdiv kp*div!\\n[kp@tail] . nr kp*ht!\\n[kp@tail] 0\\n[dn] . nr kp@tail +1 .\} .. top of page processing for KF
.nr kp*doing-top 0 . nr kp*doing-top 1 . kp*do-top . nr kp*doing-top 0 .\} .. If the first keep won't fit, only force it out if we haven't had a footnote
and we're at the top of the page.
.nr kp*force \\n[pg@fn-flag]=0&(\\n[nl]<=\\n[pg@header-bottom]) .nr kp*fits 1 .while \\n[kp@tail]>\\n[kp@head]&\\n[kp*fits] \{\ . ie \\n[.t]>\\n[kp*ht!\\n[kp@head]]:\\n[kp*force] \{\ . nr kp*force 0 . \" It's important to advance kp@head before bringing . \" back the keep, so that if the last line of the . \" last keep springs the bottom of page trap, a new . \" page will not be started unnecessarily. . rn kp*div!\\n[kp@head] kp*temp . nr kp@head +1 . ev nf . kp*temp . ev . rm kp*temp . \} . el .nr kp*fits 0 .\} .. ***************************
******** module ds ********
***************************
Displays and non-floating keeps.
.nr \\n[.ev]:ds-type 0 .. . @error automatically terminating display . DE .\} .. .. .@error DE without DS, ID, CD, LD or BD ..

.nr \\n[.ev]:ds-type 1 .par@reset

..

..

9999 .. .rj 9999 .. .par@reset .. .als ds*end!1 ds*common-end .nr \\n[.ev]:ds-type 2 .di ds*div ..

. di . nf . in (u;\\n[.l]-\\n[dl]/2>?0) . ds*div . rm ds*div . ds*common-end .\} ..

.di ds*div . LD . nr \\n[.ev]:ds-type 4 .\} . ie '\\$1'L' .LD . el \{\ . ie '\\$1'C' .CD . el \{\ . ie '\\$1'R' .RD . el \{\ . ie '\\$1'I' .ID \\$2 . el .ID \\$1 . \} . \} . \} . nr \\n[.ev]:ds-type 3 .\} .. . while \\n[.t]<=(\\$1)&(\\n[nl]>\\n[pg@header-bottom]) \{\ . rs ' sp \\n[.t]u . \} .\} ..

. di . ds@need \\n[dn] . ev nf . ds*div . ev . rm ds*div . ds*common-end .\} .. . br . di . nf . in (u;\\n[.l]-\\n[dl]/2>?0) . ds@need \\n[dn] . ds*div . rm ds*div . ds*common-end .\} .. ****************************
******** module par ********
****************************
Paragraph-level formatting.
Load time initialization.
PS and VS might have been set on the command-line
don't set LT so that it can be defaulted from LL
. ps (\\n[PS]z / 1000u) . ps \\n[PS] don't set VS so that it can be defaulted from PS
. ie (\\n[VS] >= 1000) \ . par*vs "(\\n[VS]p / 1000u)" . el \ . par*vs \\n[VS] .\} . ie (\\n[PS] >= 1000) \ . par*vs "((\\n[PS]p / 1000u) + 2p)" . el \ . par*vs "(\\n[PS] + 2)" .\} .TA .CHECK-FOOTER-AND-KEEP .. If it's too big to be in points, treat it as units.
.. .nr 0:li (u;\\n[LL]/12) .nr 0:ri \\n[0:li] .. .aln \\n[.ev]:PS PS .aln \\n[.ev]:VS VS .aln \\n[.ev]:LL LL .aln \\n[.ev]:MCLL LL .aln \\n[.ev]:LT LT .aln \\n[.ev]:MCLT LT .aln \\n[.ev]:PI PI .aln \\n[.ev]:PD PD .par@reset-env .. happens when the first page begins
. ie (\\n[PS] >= 1000) \ . nr VS (\\n[PS] + 2000) . el \ . nr VS (\\n[PS] + 2) .\} . ie (\\n[PS] >= 1000) \ . nr FPS (\\n[PS] - 2000) . el \ . nr FPS (\\n[PS] - 2) .\} . ie (\\n[FPS] >= 1000) \ . nr FVS (\\n[FPS] + 2000) . el \ . nr FVS (\\n[FPS] + 2) .\} don't change environment 0
.ev h . ps (\\n[PS]z / 1000u) . ps \\n[PS] . par*vs "(\\n[VS]p / 1000u)" . par*vs \\n[VS] .ev .nr par*adj \\n[.j] .par*env-init .ev h .par*env-init .ev .ev fn .par*env-init .ev .ev k .par*env-init .ev .aln 0:MCLL pg@colw .aln 0:MCLT pg@colw .aln k:MCLL pg@colw .aln k:MCLT pg@colw .aln fn:PS FPS .aln fn:VS FVS .aln fn:LL FL .aln fn:LT FL .aln fn:PI FI .aln fn:PD FPD .aln fn:MCLL pg@fn-colw .aln fn:MCLT pg@fn-colw .. .nr \\n[.ev]:il 0 .nr \\n[.ev]:li 0 .nr \\n[.ev]:ri 0 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI] .nr \\n[.ev]:pli 0 .nr \\n[.ev]:pri 0 .nr \\n[.ev]:ds-type 0 .. par@reset

.nr need_eo_tl 0 .nr need_eo_h 0

0 .rj 0 .ul 0

. ll (u;\\n[\\n[.ev]:MCLL]-\\n[\\n[.ev]:ri]-\\n[\\n[.ev]:pri]) . lt \\n[\\n[.ev]:MCLT]u .\} . ll (u;\\n[\\n[.ev]:LL]-\\n[\\n[.ev]:ri]-\\n[\\n[.ev]:pri]) . lt \\n[\\n[.ev]:LT]u .\} .fam \\*[FAM] . ps (\\n[\\n[.ev]:PS]z / 1000u) . ps \\n[\\n[.ev]:PS] . par*vs "(\\n[\\n[.ev]:VS]p / 1000u)" . par*vs \\n[\\n[.ev]:VS] .ls 1 .TA .. .nr \\n[.ev]:pli 0 .nr \\n[.ev]:pri 0 .par@reset .. This can be redefined by the user.
.. \n[PORPHANS] sets number of initial lines of any paragraph,
which must be kept together, without any included page break.
Initialise to reproduce original behaviour; user may adjust it.
. .nr \\n[.ev]:pli \\$1 .nr \\n[.ev]:pri \\$2 .par@reset .. .nr \\n[.ev]:pli 0 .nr \\n[.ev]:pri 0 .par@reset .. normal LP
.par*start 0 0 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI] .. .par*start 0 0 .nr \\n[.ev]:ai \\n[\\n[.ev]:PI] .. .nr \\n[.ev]:ai \\n[\\n[.ev]:PI] .par*start \\n[QI] \\n[QI] .. .par*start \\n[\\n[.ev]:PI] 0 .. .par*start \\n[\\n[.ev]:ai] 0 . \" Divert the label so as to freeze any spaces. . di par*label . par*push-tag-env \\$1 . par*pop-tag-env . di . chop par*label . ti -\\n[\\n[.ev]:ai]u . ie \\n[dl]+1n<=\\n[\\n[.ev]:ai] \{\ . DEVTAG-COL 1 \\*[par*label]\h'|\\n[\\n[.ev]:ai]u'\c . DEVTAG-COL 2 . \} . el \{\ . DEVTAG-COL 1 \\*[par*label] . DEVTAG-COL-NEXT 2 . br . \} . rm par*label .\} .. We don't want margin characters to be attached when we divert
the tag. Since there's no way to save and restore the current
margin character, we have to switch to a new environment, taking
what we need of the old environment with us.
.nr par*saved-font \\n[.f] .nr par*saved-size \\n[.s]z .nr par*saved-ss \\n[.ss] .ev par
.TA
.ss \\n[par*saved-ss]
.fam \\*[par*saved-fam]
..
.ev
..

.nr \\n[.ev]:li!\\n[\\n[.ev]:il] \\n[\\n[.ev]:li] .nr \\n[.ev]:ri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ri] .nr \\n[.ev]:ai!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ai] .nr \\n[.ev]:pli!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pli] .nr \\n[.ev]:pri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pri] .nr \\n[.ev]:il +1 .nr \\n[.ev]:li +\\n[\\n[.ev]:ai] .nr \\n[.ev]:ai \\n[\\n[.ev]:PI] .par@reset ..

. nr \\n[.ev]:il -1 . nr \\n[.ev]:ai \\n[\\n[.ev]:ai!\\n[\\n[.ev]:il]] . nr \\n[.ev]:li \\n[\\n[.ev]:li!\\n[\\n[.ev]:il]] . nr \\n[.ev]:ri \\n[\\n[.ev]:ri!\\n[\\n[.ev]:il]] . nr \\n[.ev]:pli \\n[\\n[.ev]:pli!\\n[\\n[.ev]:il]] . nr \\n[.ev]:pri \\n[\\n[.ev]:pri!\\n[\\n[.ev]:il]] .\} .par@reset ..

.nr \\n[.ev]:li!\\n[\\n[.ev]:il] \\n[\\n[.ev]:li] .nr \\n[.ev]:ri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ri] .nr \\n[.ev]:ai!\\n[\\n[.ev]:il] \\n[\\n[.ev]:ai] .nr \\n[.ev]:pli!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pli] .nr \\n[.ev]:pri!\\n[\\n[.ev]:il] \\n[\\n[.ev]:pri] .nr \\n[.ev]:il +1 .nr \\n[.ev]:li +\\n[QI] .nr \\n[.ev]:ri +\\n[QI] .nr \\n[.ev]:ai \\n[\\n[.ev]:PI] .par@reset .. .als @QE @RE start boxed text

.HTML-IMAGE .di par*box-div .nr \\n[.ev]:li +1n .nr \\n[.ev]:ri +1n .nr par*box-in \\n[.in] remember what 1n is, just in case the point size changes
.nr par*box-n 1n .lt -1n .. 2 .. end boxed text
Postpone the drawing of the box until we're in the top-level diversion,
in case there's a footnote inside the box.
. br . if \n[.V]>.25m .sp . di . if \n[.V]>.25m .sp . ds@need \\n[dn] . par*box-mark-top . ev nf . par*box-div . ev . nr \\n[.ev]:ri -\\n[par*box-n] . nr \\n[.ev]:li -\\n[par*box-n] . in -\\n[par*box-n]u . ll +\\n[par*box-n]u . lt +\\n[par*box-n]u . par*box-draw \\n[.i]u \\n[.l]u-(\\n[.H]u==1n*1n) .\} .HTML-IMAGE-END .. . rs . mk par*box-top .\} .. . nr par*box-in \\n[.i] . nr par*box-ll \\n[.l] . nr par*box-vpt \\n[.vpt] . nr par*box-ad \\n[.j] . ad l . vpt 0 . in \\$1 . ll \\$2 \v'-1v+.25m'\ \D'l (u;\\n[.l]-\\n[.i]) 0'\ \D'l 0 |\\n[par*box-top]u'\ \D'l -(u;\\n[.l]-\\n[.i]) 0'\ \D'l 0 -|\\n[par*box-top]u' . br . sp -1 . in \\n[par*box-in]u . ll \\n[par*box-ll]u . vpt \\n[par*box-vpt] . ad \\n[par*box-ad] .\} .. \n[HORPHANS] sets how many lines of the following paragraph must be
kept together, with a preceding section header. Initialise it,
to reproduce original behaviour; user may change it.
. \n[GROWPS] and \n[PSINCR] cause auto-increment of header point size.
Initialise them, so they have no effect, unless explicitly set by the user.
. .par@finish Keep the heading and the first few lines of the next paragraph together.
(\n[HORPHANS] defines "first few" -- default = 1; user may redefine it).
.nr sh*minvs \\n[HORPHANS]v Adjust point size for heading text, as specified by \n[GROWPS] and \n[PSINCR].
.. Standard ms implementation does not expect an argument,
but allow ".SH n" to make heading point size match ".NH n",
for same "n", when \n[GROWPS] and \n[PSINCR] are set.
. nr sh*psincr 0 . if 0\\$1>0 .nr sh*psincr (\\n[GROWPS]-0\\$1)*\\n[PSINCR] . SH-NO-TAG . DEVTAG-SH 1 . if '\*(.T'html' .nr need_eo_h 1 .. TL, AU, and AI are aliased to these in cov*ab-init.
.par@finish .vs +3p

9999 VTAG-TL .nr need_eo_tl 1 .. .par@finish

9999 .. .par@finish

9999 .. In paragraph macros.
. ps (\\n[\\n[.ev]:PS]z / 1000u) . ps \\n[\\n[.ev]:PS] .. .. .. .. par*define-font-macro macro font
. nr par*prev-font \\\\n[.f] \\\\$3\f[\\$2]\\\\$1\f[\\\\n[par*prev-font]]\\\\$2 .\} \\.. .. .par*define-font-macro B B .par*define-font-macro I I .par*define-font-macro BI BI .par*define-font-macro CW CR underline a word
\Z'\\$1'\v'.25m'\D'l \w'\\$1'u 0'\v'-.25m'\\$2 .. box a word
.nr par*bxw \w'\\$1'+.4m \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''\ \Z'\h'.2m'\\$1'\ \h'\\n[par*bxw]u' .. The first time UX is used, put a registered mark after it.
\s[\\n[.s]*8u/10u]UNIX\s0\\$1\\*[par*ux-rg] .. .als { par@sup-start .als } par@sup-end footnote paragraphs
FF is the footnote format
.nr FF 0 This can be redefined. It gets a second argument of `no' if the first
argument was supplied by the user, rather than automatically.

. @error unknown footnote format `\\n[FF]' . nr FF 0 .\} .. .@PP \\*[par@sup-start]\\$1\\*[par@sup-end] \c .. .@PP \\$1 \c .. .@PP \\$1. \c .. .@PP \\$1 \c .. .@LP \\$1. \c .. .@LP \\$1 \c .. .@IP "\\$1." (u;\\n[\\n[.ev]:PI]*2) .. .@IP "\\$1" (u;\\n[\\n[.ev]:PI]*2) .. ***************************
******** module nh ********
***************************
Numbered headings.
nh*hl is the level of the last heading
.nr nh*hl 0 numbered heading
. shift . nr nh*hl 0 . while \\n[.$] \{\ . nr nh*hl +1 . nr H\\n[nh*hl] 0\\$1 . shift . \} . if !\\n[nh*hl] \{\ . nr H1 1 . nr nh*hl 1 . @error missing arguments to .NH S . \} .\} . nr nh*ohl \\n[nh*hl] . ie \\n[.$] \{\ . nr nh*hl 0\\$1 . ie \\n[nh*hl]<=0 \{\ . nr nh*ohl 0 . nr nh*hl 1 . \} . el \{\ . if \\n[nh*hl]-\\n[nh*ohl]>1 \ . @warning .NH \\n[nh*ohl] followed by .NH \\n[nh*hl] . \} . \} . el .nr nh*hl 1 . while \\n[nh*hl]>\\n[nh*ohl] \{\ . nr nh*ohl +1 . nr H\\n[nh*ohl] 0 . \} . nr H\\n[nh*hl] +1 .\} .nr nh*i 1 .while \\n[nh*i]<\\n[nh*hl] \{\ . nr nh*i +1 . as SN-NO-DOT .\\n[H\\n[nh*i]] .\} .nr sh*psincr (\\n[GROWPS]-\\n[nh*hl])*\\n[PSINCR]

-NO-TAG
VTAG-NH "\\$1" . if '\*(.T'html' .nr need_eo_h 1 \\*[SN-DOT] .. ****************************
******** module toc ********
****************************
Table of contents generation.
.da toc*div .ev h .. .XE .. . if d toc*num .toc*end-entry . ie \\n[.$] \{\ . ie '\\$1'no' .ds toc*num . el .ds toc*num "\\$1 . \} . el .ds toc*num \\n[PN] . br . par@reset . na . ll -8n . in (n;0\\$2) .\} .. . if d toc*num .toc*end-entry . ev . di .\} .. \\a\\t\\*[toc*num]

.. .1C . ce 1 . ie (\\n[PS] >= 1000) \ . ps ((\\n[PS]z / 1000u) + 2z) . el \ . ps \\n[PS]+2 . ft B \\*[TOC] . ft . ps .\}

.char \[toc*leader-char] .\h'1m'
.lc \[toc*leader-char]
.toc*div
.par@reset
..
 print the table of contents on page i

1 .pg@begin 1 i

X \\$1 .. ****************************
******** module eqn ********
****************************
Eqn support.
.. ..

. ie '\\$1'I' .nr eqn*type 1 . el \{\ . nr eqn*type 2 . if !'\\$1'C' .ds eqn*num "\\$1 . \} .\} .di eqn*div . if '\*(.T'html' .RS . HTML-IMAGE-INLINE .\}

..
.@EN
..
 Note that geqn mark and lineup work correctly in centered equations.
. br . di . nr eqn*have-num 0 . if !'\\*[eqn*num]'' .nr eqn*have-num 1 . ie \\n[dl]:\\n[eqn*have-num] \{\ . sp \\n[DD]u . par@reset . ds eqn*tabs \\n[.tabs] . nf . ie \\n[dl] \{\ --fixme-- this really should not be necessary
and indicates that there is extra space creeping into
an equation when ps4html is enabled..
. ie r ps4html .ds@need \\n[dn]u-1v+\n[.V]u+1i . el .ds@need \\n[dn]u-1v+\n[.V]u . chop eqn*div . ie \\n[eqn*type]=0 \{\ . ta (u;\\n[.l]-\\n[.i])R \\*[eqn*div]\t\\*[eqn*num] . \} . el \{\ . ie \\n[eqn*type]=1 .ta \\n[DI]u \ (u;\\n[.l]-\\n[.i])R . el .ta (u;\\n[.l]-\\n[.i]/2)C \ (u;\\n[.l]-\\n[.i])R \t\\*[eqn*div]\t\\*[eqn*num] . \} . \} . el \{\ . ta (u;\\n[.l]-\\n[.i])R \t\\*[eqn*num] . \} . if !'\*(.T'html' .sp \\n[DD]u
. sp \\n[DD]u . ta \\*[eqn*tabs] . \} . el \{ must terminate empty equations in html and ps4html as they contain
the HTML-IMAGE-END suppression nodes
. if \\n[dl] .chop eqn*div . if '\*(.T'html' \\*[eqn*div] . if r ps4html \\*[eqn*div] . \} . if !'\*(.T'html' .fi . if \\n[eqn*type]=0 .HTML-IMAGE-END . if \\n[eqn*type]=1 \{\ . HTML-IMAGE-END . if '\*(.T'html' .RE . \} . if \\n[eqn*type]=2 .HTML-IMAGE-END .\} .. ****************************
******** module tbl ********
****************************
Tbl support.
.nr tbl*have-header 0 This gets called if TS occurs before the first paragraph.

cov*ab-init aliases TS to @TS
\\*[TS]\\ .. .HTML-IMAGE .. . ie \\n[.t]-\\n[tbl*header-ht]-1v .tbl*print-header . el .sp \\n[.t]u .\} .. .ev nf .tbl*header-div .ev

#T .. . nr T. 0 . T# . br . di . ie \\n[dn]+\\n[FM]+\\n[HM]+2v>=\\n[.p] \{\ . @error ridiculously long table header . ds@need \\n[dn] . tbl*print-header . \} . el \{\ . nr tbl*header-ht \\n[dn] . ds@need \\n[dn]u+1v . tbl*print-header . nr tbl*have-header 1 . \} .\} ..

.TE .. . nr tbl*have-header 0 . if !'\*(.T'html' .sp \\n[DD]u .\} . HTML-IMAGE-END reset tabs
.TA .. . nr T. 1 . T# .\} .. .. ****************************
******** module pic ********
****************************
Pic support.
PS height width

. ds@need (u;\\$1)+1v . in +(u;\\n[.l]-\\n[.i]-\\$2/2>?0) .\} .HTML-IMAGE .. .HTML-IMAGE-END .par@reset .. ****************************
******** module ref ********
****************************
Refer support.
.. Other
Journal article
Book
Article within book
Tech report
][ type
. als [T1 [T . als [T2 [T .\} . @error unknown reference type `\\$1' . ref*build \\*[ref*spec!0] .\} .ref*print .. start of reference number
end of reference number
period before reference
period after reference
comma before reference
comma after reference
start collected references
.als ref*print ref*end-print

\\*[REFERENCES] .par@reset .. end collected references
.par@finish .als ref*print ref*normal-print .. \\*[ref*string] .FE .. \\*[ref*string] .. .als ref*print ref*normal-print .nr ref*suppress-period 1 .while \\n[.$] \{\ . if d [\\$1 \{\ . ie d ref*add-\\$1 .ref*add-\\$1 . el .ref*add-dflt \\$1 . \} . shift .\} now add a final period
. if !\\n[ref*suppress-period] .as ref*string . . if d ref*post-punct \{\ . as ref*string "\\*[ref*post-punct] . rm ref*post-punct . \} .\} .. .ref*field T , "" "" "" .. .ref*field T , "\\*Q" "" "\\*U" .. .. .ref*field J , "" .. .ref*field D "" ( ) .. .ref*field E , "ed. " .. .ref*field G "" ( ) .. .ref*field B "" "in " "" .. .ref*field O . .. .ref*field A , .. .ref*field V "" .. .ref*field N \z( "" ")" .. .ref*field \\$1 , .. First argument is the field letter.
Second argument is the punctuation character to use to separate this field
from the previous field.
Third argument is a string with which to prefix this field.
Fourth argument is a string with which to postfix this field.
Fifth argument is a string to add after the punctuation character supplied
by the next field.
. ie d ref*post-punct \{\ . as ref*string "\\$2\\*[ref*post-punct] \" . rm ref*post-punct . \} . el .as ref*string "\\$2 \" .\} .as ref*string "\\$3\\*([\\$1\\$4 .nr ref*suppress-period 0 .. ****************************
******** module acc ********
****************************
Accents and special characters.
Characters
The idea of this definition is for the top of the 3 to be at the x-height.
\v'\w'3'*0+\En[rst]u'3\s0'\h'\w'\s[\En[.s]*8u/10u]3'u' Accents
\h'(u;-\En[skw]+(-\En[.w]-\w'\\$2'/2)+\En[.csk])'\\$2' .. .. \v'(u;\En[.cdp]-\En[.cht]+\En[rst]+\En[rsb]/2)'\\$2' .. .. .acc*prefix-def ' \' .acc*prefix-def ` \` .acc*prefix-def ^ ^ .acc*prefix-def , \(ac .acc*prefix-def : \(ad .acc*prefix-def ~ ~ improved accent marks
.acc*over-def ' \' .acc*over-def ` \` .acc*over-def ^ ^ .acc*over-def ~ ~ .acc*over-def : \(ad .acc*over-def v \(ah .acc*over-def _ \(a- .acc*over-def o \(ao .acc*under-def , \(ac .acc*under-def . \s[\En[.s]*8u/10u]\v'.2m'.\v'-.2m'\s0 .acc*under-def hook \(ho .acc*slash-def / / .char \[hooko] o\\\\*[hook] .. it might be better to als FS -> B1 and FE -> B2
however this produced wierd results, so I've moved back to a more reliable
but less interesting solution --fixme--
. if '\*(.T'html' \{\ . rm KF . als KF KS . rm FS . de FS . br . HTML-IMAGE \\.. . rm FE . de FE . br . HTML-IMAGE-END \\.. . \} . if r ps4html \{\ . rm FS . de FS . br . HTML-IMAGE \\.. . rm FE . de FE . br . HTML-IMAGE-END \\.. . \} .. .par@load-init Make sure that no blank lines creep in at the end of this file.