1062 lines
28 KiB
Text
1062 lines
28 KiB
Text
.ig
|
|
Copyright 2005-2020 Free Software Foundation, Inc.
|
|
2025 G. Branden Robinson
|
|
|
|
Written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>
|
|
Enhanced by Werner Lemberg <wl@gnu.org>
|
|
|
|
This file is part of hdtbl.
|
|
|
|
hdtbl is distributed with groff, the GNU roff typesetting system.
|
|
|
|
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 3 of the License, 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
..
|
|
.
|
|
.
|
|
.\" *****************************************************************
|
|
.\" * hdtbl - Heidelberger table macros *
|
|
.\" * Vers. 0.91 December 2005 *
|
|
.\" *****************************************************************
|
|
.
|
|
.if !\n(.g \{\
|
|
. tm groff hdtbl macros require groff extensions; cannot load package
|
|
. nx
|
|
.\}
|
|
.
|
|
.if \n(.C \{\
|
|
. tm groff hdtbl macros do not work in compatibility mode; cannot \
|
|
load package
|
|
. nx
|
|
.\}
|
|
.
|
|
.if d TBL \
|
|
. nx
|
|
.
|
|
.ds hdtbl hdtbl.tmac\"
|
|
.
|
|
.\" Check for name space collisions with full-service macro packages.
|
|
.
|
|
.if d TD \{\
|
|
. tm \*[hdtbl]: cannot load package; macro 'TD' is already defined
|
|
. nx
|
|
.\}
|
|
.
|
|
.if d TH \{\
|
|
. tm \*[hdtbl]: cannot load package; macro 'TH' is already defined
|
|
. nx
|
|
.\}
|
|
.
|
|
.if d TR \{\
|
|
. tm \*[hdtbl]: cannot load package; macro 'TR' is already defined
|
|
. nx
|
|
.\}
|
|
.
|
|
.
|
|
.mso hdmisc.tmac
|
|
.mso 62bit.tmac
|
|
.
|
|
.
|
|
.\" *****************************************************************
|
|
.\" * default values for some arguments *
|
|
.\" *****************************************************************
|
|
.
|
|
.ds t*hl s\"
|
|
.ds t*vl s\"
|
|
.ds t*tal l\"
|
|
.ds t*hal b\"
|
|
.ds t*val t\"
|
|
.ds t*ff \\n[.fam]\"
|
|
.ds t*fst \\n[.f]\"
|
|
.ds t*fsz 1 1\"
|
|
.ds t*fgc red4\"
|
|
.ds t*bgc bisque\"
|
|
.ds t*bc red4\"
|
|
.nr t*cpd .5n
|
|
.nr t*csp .5n
|
|
.nr t*b .1n
|
|
.nr t*cols 1
|
|
.nr t*v \n[.v]
|
|
.nr t*s \n[.ps]
|
|
.nr t*hy \n[.hy]
|
|
.nr t*l \n[.ll]
|
|
.
|
|
.
|
|
.\" defaults for table captions
|
|
.nr t*cptn 0 1
|
|
.ds t*cptn "".sp .4" \
|
|
".t*pv 1.0 1.0" \
|
|
".ad l" \
|
|
"\m[\\*[t*fgc]]Table \\n+[t*cptn]:\0\k*\c"\"
|
|
.
|
|
.
|
|
.\" for better error messages
|
|
.ds nth-1 st\"
|
|
.ds nth-2 nd\"
|
|
.ds nth-3 rd\"
|
|
.
|
|
.\" initialization of various registers
|
|
.nr t*# 0 \" table nesting level
|
|
.nr t*numb 0 1 \" held table diversion #
|
|
.
|
|
.ds *#trc*
|
|
.
|
|
.
|
|
.\" *****************************************************************
|
|
.\" * The four base macros and the two optional macros *
|
|
.\" *****************************************************************
|
|
.
|
|
.ie n \
|
|
. ds g tty:\"
|
|
.el \
|
|
. ds g ps: exec\"
|
|
.
|
|
.\" TBL: table start
|
|
.\" predecessor: text, TD or ETB
|
|
.\" successor: CPTN or TR
|
|
.de TBL
|
|
. ds t*m\\n[t*#] \\n[.m]\"
|
|
. ie \\n[t*#] \
|
|
. br
|
|
. el \{\
|
|
. ds * \\n[.ev]\"
|
|
. ev t*tbl
|
|
. evc \\*[*]
|
|
. di t*tbl0
|
|
. sp .4 \" XXX: hard-coded value
|
|
. nr t*i \\n[.i]
|
|
. ll -\\n[.i]u
|
|
. in 0
|
|
. \}
|
|
. nr t*# +1
|
|
.
|
|
. \" Save current location for error checking at end
|
|
. ds t*FN \\[.F]\"
|
|
. ds t*LN \\[.c]\"
|
|
.
|
|
. t*getarg cols \\$@\" from here string 'args' contains the rest of \\$@
|
|
. ie "\\*[cols]"" \
|
|
. nr t*cols\\n[t*#] \\n[t*cols]
|
|
. el \{\
|
|
. ie \B"\\*[cols]" \
|
|
. nr t*cols\\n[t*#] \\*[cols]
|
|
. el \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid number of columns value
|
|
. tm1 " '\\*[cols]'.
|
|
. \}
|
|
. \}
|
|
.
|
|
. t*getarg cpd \\*[args] \" cell padding
|
|
. ie "\\*[cpd]"" \
|
|
. nr t*cpd\\n[t*#] \\n[t*cpd]
|
|
. el \{\
|
|
. ie \B"\\*[cpd]" \
|
|
. nr t*cpd\\n[t*#] \\*[cpd]
|
|
. el \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid cell padding value
|
|
. tm1 " '\\*[cpd]'.
|
|
. \}
|
|
. \}
|
|
.
|
|
. t*getarg csp \\*[args] \" cell spacing
|
|
. ie "\\*[csp]"" \
|
|
. nr t*csp\\n[t*#] \\n[t*csp]
|
|
. el \{\
|
|
. ie \B"\\*[csp]" \
|
|
. nr t*csp\\n[t*#] \\*[csp]
|
|
. el \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid cell spacing value
|
|
. tm1 " '\\*[csp]'.
|
|
. \}
|
|
. \}
|
|
.
|
|
. t*getarg border \\*[args] \" border thickness
|
|
. ie "\\*[border]"=" \
|
|
. nr t*b\\n[t*#] 0-1
|
|
. el \{\
|
|
. ie "\\*[border]"" \
|
|
. nr t*b\\n[t*#] \\n[t*b]
|
|
. el \{\
|
|
. ie \B"\\*[border]" \
|
|
. nr t*b\\n[t*#] \\*[border]
|
|
. el \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid border thickness
|
|
. tm1 " value '\\*[border]'.
|
|
. \}
|
|
. \}\}
|
|
.
|
|
. t*getarg bc \\*[args] \" border color
|
|
. ds t*bc\\n[t*#] \\*[t*bc]\"
|
|
. if !"\\*[bc]"" \{\
|
|
. ie m\\*[bc] \
|
|
. ds t*bc\\n[t*#] \\*[bc]\"
|
|
. el \{\
|
|
. ie "\\*[bc]"=" \
|
|
. ds t*bc\\n[t*#] =\"
|
|
. el \
|
|
. tm \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid border color '\\*[bc]'.
|
|
. \}\}
|
|
. ie "\\*[bc]"=" \
|
|
. ds t*bc\\n[t*#]
|
|
. el \{\
|
|
. ie "\\*[bc]"" \
|
|
. ds t*bc\\n[t*#] \\*[t*bc]\"
|
|
. el \
|
|
. ds t*bc\\n[t*#] \\*[bc]\"
|
|
. \}
|
|
.
|
|
. t*getarg width \\*[args] \" table/col widths
|
|
. if "\\*[width]"=" \
|
|
. ds width
|
|
.
|
|
. nr b/2\\n[t*#] (\\n[t*b\\n[t*#]] / 2)\" shortcut
|
|
. nr cscp\\n[t*#] (\\n[t*csp\\n[t*#]] + \\n[t*cpd\\n[t*#]])\" aux. register
|
|
.
|
|
. t*getarg height \\*[args] \" table outline height
|
|
. ie "\\*[height]"" \
|
|
. nr t*height\\n[t*#] 0
|
|
. el \{\
|
|
. ie \B"\\*[height]" \
|
|
. nr t*height\\n[t*#] (\\*[height] \
|
|
- ((2 * \\n[cscp\\n[t*#]]) \
|
|
+ (3 * \\n[b/2\\n[t*#]])))
|
|
. el \
|
|
. tm \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid height value '\\*[height]'.
|
|
. \}
|
|
.
|
|
. t*cl \\*[width] \" get cell widths and offsets
|
|
. t*args \\n[t*#] \" look for common arguments
|
|
.
|
|
. t*getarg tal \\*[args] \" table horizontal alignment
|
|
. if "\\*[tal]"" \
|
|
. ds tal \\*[t*tal]\"
|
|
. ie "\\*[tal]"l" \
|
|
. nr in\\n[t*#] \\n[.i]
|
|
. el \{\
|
|
. ie "\\*[tal]"c" \
|
|
. nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]]/2 + \\n[.i])
|
|
. el \{\
|
|
. ie "\\*[tal]"r" \
|
|
. nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]] + \\n[.i])
|
|
. el \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid horizontal table
|
|
. tm1 " alignment '\\*[tal]': must be 'l', 'c' or 'r'.
|
|
. \}\}\}
|
|
.
|
|
. nr t*r#\\n[t*#] 0 \" initialize row index
|
|
. mk toptbl\\n[t*#]
|
|
.
|
|
. t*P1 \\*[args]
|
|
..
|
|
.
|
|
.
|
|
.\" CPTN: optional table caption
|
|
.\" predecessor: TBL
|
|
.\" successor: TR
|
|
.de CPTN
|
|
. ft 1
|
|
.
|
|
. if "\\$0"CPTN" \
|
|
. if \\n[t*r#\\n[t*#]] \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid placement of '.CPTN';
|
|
. tm1 " must be called immediately after '.TBL'.
|
|
. return
|
|
. \}
|
|
.
|
|
. t*getarg val \\$@
|
|
. ds args\\n[t*#] "\\*[args]\"
|
|
.
|
|
. t*index "\\*[args]" .TR
|
|
. ie \\n[t*index] \{\
|
|
. ds *a\\n[t*#] "\\*[args]\"
|
|
. substring args\\n[t*#] 0 \\n[t*index]
|
|
. substring *a\\n[t*#] \\n[t*index]-2 -1
|
|
. \}
|
|
. el \
|
|
. ds *a\\n[t*#]
|
|
.
|
|
. ie "\\*[val]"b" \{\
|
|
. de t*cptn\\n[t*#]
|
|
. *CPTN \\*[args\\n[t*#]]
|
|
. rm t*cptn\\n[t*#]
|
|
\\..
|
|
. \}
|
|
. el \{\
|
|
. ll (\\n[ll\\n[t*#]]u + \\n[in\\n[t*#]]u)
|
|
. in \\n[in\\n[t*#]]u
|
|
. t*P1 \\*[t*cptn]
|
|
' in +\\n[*]u
|
|
. t*P1 \\*[args\\n[t*#]]
|
|
. t*pv 1 1
|
|
. in
|
|
. mk toptbl\\n[t*#]
|
|
. \}
|
|
.
|
|
. t*P1 \\*[*a\\n[t*#]]
|
|
..
|
|
.
|
|
.als *CPTN CPTN
|
|
.
|
|
.
|
|
.\" TR: table row
|
|
.\" predecessor: TBL, CPTN, text, TD or ETB
|
|
.\" successor: TD
|
|
.de TR
|
|
. ft 1
|
|
. if !\\n[t*#] \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Table row (.TR) without preceding
|
|
. tm1 " table start (.TBL).
|
|
. return
|
|
. \}
|
|
.
|
|
. \" finish previous data cell, if any
|
|
. if \\n[t*r#\\n[t*#]] \
|
|
. t*dntr 1 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*]
|
|
.
|
|
. nr t*r#\\n[t*#] +1 \" row number in this table
|
|
. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" table row identifier
|
|
. \" (<level>*<row>)
|
|
. nr c#\\*[#t#r] 0 1 \" clear cell counter
|
|
. nr dntr\\*[#t#r] 0 1 \" clear accumulated row height
|
|
.
|
|
. t*getarg height \\$@
|
|
. ie "\\*[height]"" \
|
|
. nr t*height\\*[#t#r] 0
|
|
. el \{\
|
|
. ie \B"\\*[height]" \
|
|
. nr t*height\\*[#t#r] \\*[height]
|
|
. el \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid table row height
|
|
. tm1 " '\\*[height]'.
|
|
. \}
|
|
. \}
|
|
.
|
|
. \" If there is a TR with height 'height', the total height of the table
|
|
. \" is too high by 3/2 b, independent of the number of TR with 'height'.
|
|
. t*args \\*[#t#r] \\n[t*#] \" look for common arguments
|
|
.
|
|
. t*P1 \\*[args]
|
|
..
|
|
.
|
|
.
|
|
.\" TH: optional table header cell
|
|
.\" predecessor: text, TD or TR
|
|
.\" successor: text, TD, TR, TBL or ETB
|
|
.\"
|
|
.\" cell content bolded and horizontally and vertically centered,
|
|
.\" else like .TD
|
|
.de TH
|
|
. ft 1
|
|
. if !\\n[t*#] \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Table heading (.TH) without
|
|
. tm1 " preceding table start (.TBL).
|
|
. return
|
|
. \}
|
|
. t*getarg hal \\$@
|
|
. if "\\*[hal]"" \
|
|
. ds hal c\"
|
|
.
|
|
. t*getarg val \\*[args]
|
|
. if "\\*[val]"" \
|
|
. ds val m\"
|
|
.
|
|
. t*getarg fst \\*[args]
|
|
. if "\\*[fst]"" \
|
|
. ds fst B\"
|
|
.
|
|
. TD hal=\\*[hal] val=\\*[val] fst=\\*[fst] \\*[args]
|
|
..
|
|
.
|
|
.
|
|
.\" TD: table data cell
|
|
.\" predecessor: text, TD or TR
|
|
.\" successor: text, TD, TR, TBL or ETB
|
|
.de TD
|
|
. ft 1
|
|
. \" finish previous data cell -- note the use of \E
|
|
. t*dntr 0 \\n[c#\\*[#t#r]]-1 \En[c#\\*[#t#r]] \\*[*#trc*]
|
|
.
|
|
. ds *#trc* \\*[#t#r]*\\n[c#\\*[#t#r]]\" table cell identifier
|
|
. \" (<level>*<row>*<column>)
|
|
.
|
|
. t*getarg rowspan \\$@
|
|
. nr rowspan 1
|
|
. if !"\\*[rowspan]"" \{\
|
|
. ie \B"\\*[rowspan]" \{\
|
|
. nr rowspan (\\*[rowspan] >? 1)
|
|
. nr *rsp*\\*[*#trc*] (\\n[rowspan] - 1)
|
|
. \}
|
|
. el \
|
|
. tm \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid value of 'rowspan' keyword.
|
|
. \}
|
|
.
|
|
. t*getarg colspan \\*[args]
|
|
. nr colspan 1
|
|
. if !"\\*[colspan]"" \{\
|
|
. ie \B"\\*[colspan]" \
|
|
. nr colspan (\\*[colspan] >? 1)
|
|
. el \
|
|
. tm \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid value of 'colspan' keyword.
|
|
. \}
|
|
.
|
|
. t*args \\*[#trc] \\*[#t#r] \" look for common arguments
|
|
.
|
|
. nr in\\*[#trc] \\n[in\\n[t*#]*\\n[c#\\*[#t#r]]]
|
|
. nr *cl \\n[cll\\n[t*#]*\\n[c#\\*[#t#r]]]
|
|
. nr * 0 1
|
|
. nr *r \\n[t*r#\\n[t*#]]
|
|
.
|
|
. if (\\n[rowspan] - 1) \
|
|
. while (\\n+[*] <= \\n[rowspan]) \{\
|
|
. nr rspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan]
|
|
. if (\\n[*] > 1) \
|
|
. nr cspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan]
|
|
. nr *r +1
|
|
. \}
|
|
.
|
|
. nr * 1 1
|
|
. nr *c \\n[c#\\*[#t#r]]
|
|
.
|
|
. if (\\n[colspan] - 1) \{\
|
|
. nr vline\\*[*#trc*] 0-1 \" set 'no vl' flag
|
|
.
|
|
. while (\\n+[*] <= \\n[colspan]) \{\
|
|
. nr *c +1
|
|
. nr *cl +(2 * \\n[cscp\\n[t*#]] \
|
|
+ \\n[b/2\\n[t*#]] \
|
|
+ \\n[cll\\n[t*#]*\\n[*c]])
|
|
. nr c#\\*[#t#r] +1
|
|
. \}
|
|
. \}
|
|
.
|
|
. if (\\n[c#\\n[t*#]*\\n[t*r#\\n[t*#]]] > \\n[t*cols\\n[t*#]]) \{\
|
|
. ds * are\"
|
|
. ds ** columns\"
|
|
. if (\\n[c#\\*[#t#r]] == 1) \{\
|
|
. ds * is\"
|
|
. ds ** column\"
|
|
. \}
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: There \\*[*] \\n[c#\\*[#t#r]] table
|
|
. tm1 " \*[**] (.TD)
|
|
.
|
|
. ds * are\"
|
|
. if (\\n[t*cols\\n[t*#]] == 1) \
|
|
. ds * is\"
|
|
. tm1 " but only \\n[t*cols\\n[t*#]] \\*[*] expected.
|
|
.
|
|
. ds *
|
|
. length * \\n[.F]:\\n[.c]:
|
|
.
|
|
. while \\n-[*] \
|
|
. ds * " \\*[*]\"
|
|
.
|
|
. tm1 "\\*[*] Remaining .TDs and its contents are ignored.
|
|
.
|
|
. di *t*dummy* \" bypass superfluous input
|
|
. return
|
|
. \}
|
|
.
|
|
. di t*\\*[#trc] \" open cell diversion and set locals
|
|
. in 0
|
|
. nr cll\\*[#trc] \\n[*cl]
|
|
. ll \\n[*cl]u
|
|
. nr *cl\\n[t*#] \\n[.l]
|
|
. gcolor \\*[t*fgc\\*[#trc]]
|
|
. ad \\*[t*hal\\*[#trc]]
|
|
. fam \\*[t*ff\\*[#trc]]
|
|
. ft \\*[t*fst\\*[#trc]]
|
|
. t*pv \\*[t*fsz\\*[#trc]]
|
|
.
|
|
. t*P1 \\*[args]
|
|
..
|
|
.
|
|
.
|
|
.\" ETB: end of table
|
|
.\" predecessor: text, TD or ETB
|
|
.\" successor: text, TD, TR or TBL
|
|
.de ETB
|
|
. ie \\n[t*#] \
|
|
. if !\\n[t*r#\\n[t*#]] \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Each table (.TBL)
|
|
. tm1 " should contain at least one table row (.TR)!
|
|
. \}
|
|
. el \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Table end (.ETB)
|
|
. tm1 " without corresponding table start (.TBL)!
|
|
. \}
|
|
.
|
|
. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier
|
|
. t*dntr 2 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*]
|
|
.
|
|
. t*divs \" print this table
|
|
.
|
|
. sp \\n[b/2\\n[t*#]]u
|
|
. t*cptn\\n[t*#]
|
|
. nr t*# -1
|
|
.
|
|
. ll (u;\\n[.H]>?\\n[*cl\\n[t*#]]) \" restore ll outside this table
|
|
. in 0 \" reset indent
|
|
. gcolor \\*[t*m\\n[t*#]] \" reset previous fgc
|
|
.
|
|
. t*getarg hold \\$@
|
|
. if !\\n[t*#] \{\
|
|
. sp .5
|
|
. di
|
|
. in \\n[t*i]u
|
|
. ie "\\*[hold]"" \{\
|
|
. ie (\\n[.t] - \\n[dn]) \
|
|
. t*DI t*tbl0
|
|
. el \{\
|
|
. rn t*tbl0 t*tbl\\n+[t*numb]
|
|
. ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[dn]\"
|
|
. \}
|
|
. \}
|
|
. el \{\
|
|
. rn t*tbl0 t*hold\\n+[t*numb]
|
|
. tm \*[hdtbl]:\\n[.F]:\\n[.c]: Table t*hold\\n[t*numb] held.
|
|
. ds t*held \\*[t*held] t*hold\\n[t*numb] \\n[dn]\"
|
|
. \}
|
|
.
|
|
. ev \" restore previous environment
|
|
. \}
|
|
.
|
|
. t*P1 \\*[args]
|
|
..
|
|
.
|
|
.
|
|
.\" *****************************************************************
|
|
.\" * Following the definition of five utility macros *
|
|
.\" * special to hdtbl. *
|
|
.\" * Other utility macros common to hdtbl and hdgroff *
|
|
.\" * are defined in the file hdmisc.tmac. *
|
|
.\" *****************************************************************
|
|
.
|
|
.
|
|
.\" .t*free [n]
|
|
.\" print the next [n] held table[s].
|
|
.\" Don't call it within a table!
|
|
.\" If the table is higher than the remaining space
|
|
.\" on the page, the table is printed on the next page.
|
|
.de t*free
|
|
. if "\\$0"CPTN" \
|
|
. if \\n[t*r#\\n[t*#]] \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid placement of '.t*free'
|
|
. tm1 " within a table; it must be called outside of any table.
|
|
. return
|
|
. \}
|
|
.
|
|
. if "\\*[t*held]"" \{\
|
|
. tm \*[hdtbl]:\\n[.F]:\\n[.c]: No held tables.
|
|
. return
|
|
. \}
|
|
.
|
|
. nr ** (\\$1 >? 1) 1
|
|
. while !""\\*[t*held]" \{\
|
|
. pops * t*held
|
|
. popr * t*held
|
|
.
|
|
. ie (\\n[.t] - \\n[*]) \{\
|
|
. ev t*tbl
|
|
. t*DI \\*[*]
|
|
. ev
|
|
. \}
|
|
. el \{\
|
|
. rn \\*[*] t*tbl\\n+[t*numb]
|
|
. ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[*]\"
|
|
. \}
|
|
.
|
|
. if !(\\n-[**] - 1) \
|
|
. return
|
|
. \}
|
|
..
|
|
.
|
|
.
|
|
.\" The main utility macro for tables:
|
|
.\" If a table is closed by ETB, this macro is called. It
|
|
.\" processes one complete table, i.e., all the table cell
|
|
.\" diversions, paints the cell backgrounds, draws
|
|
.\" horizontal and vertical table lines and the table border.
|
|
.\"
|
|
.\" Nested tables are processed from inside to outside.
|
|
.
|
|
.de t*divs
|
|
. ll (\\n[t*l]u + 1c) \" avoid warning 'can't break line'
|
|
. nf
|
|
.
|
|
. nr b/2 \\n[b/2\\n[t*#]] \" some abbreviations
|
|
. nr cscp \\n[cscp\\n[t*#]]
|
|
. nr cscpb (\\n[b/2] + \\n[cscp])
|
|
.
|
|
. nr topdiv (\\n[.d] + \\n[b/2] - \\n[cscp])\" top of cell diversion
|
|
. nr cscpb2 (\\n[b/2] / 2 + \\n[cscp])
|
|
.
|
|
. nr #r 0 1
|
|
. \" outer loop for rows
|
|
. while (\\n+[#r] <= \\n[t*r#\\n[t*#]]) \{\
|
|
. \" TODO: insert code here for multipage tables
|
|
. nr * (\\n[#r] - 1)
|
|
. nr topdiv +(\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb])
|
|
.
|
|
. \" if table still smaller than specified table height, increase it
|
|
. if ((\\n[#r] == \\n[t*r#\\n[t*#]]) & \\n[t*height\\n[t*#]]) \
|
|
. nr dntr\\n[t*#]*\\n[#r] (\\n[cscpb] \
|
|
+ \\n[toptbl\\n[t*#]] \
|
|
+ \\n[t*height\\n[t*#]] \
|
|
- (\\n[topdiv] >? \\n[dntr\\n[t*#]*\\n[#r]]))
|
|
.
|
|
. nr #c 0 1
|
|
. \" inner loop for cells
|
|
. while (\\n+[#c] <= \\n[t*cols\\n[t*#]]) \{\
|
|
. ds #trc \\n[t*#]*\\n[#r]*\\n[#c]\"
|
|
. \" continue if the diversion is empty
|
|
. if !d t*\\*[#trc] \
|
|
. continue
|
|
.
|
|
. sp |\\n[topdiv]u
|
|
. in (\\n[in\\n[t*#]]u + \\n[in\\*[#trc]]u)\" cell offset
|
|
. nr $1 \\n[dntr\\n[t*#]*\\n[#r]] \" cell height
|
|
.
|
|
. \" if we have spanned rows, calculate resulting row height
|
|
. \" and position of lower horizontal line
|
|
. if \\n[*rsp*\\*[#trc]] \{\
|
|
. nr * \\n[#r] 1
|
|
. nr rspan\\*[#trc] 0-1 \" set 'no hl' flag
|
|
. nr corr (\\n[dn\\*[#trc]] - \\n[dntr\\n[t*#]*\\n[#r]])
|
|
.
|
|
. \" clear row span flags in following rows and update row height
|
|
. while \\n[*rsp*\\*[#trc]] \{\
|
|
. nr *rsp*\\*[#trc] -1
|
|
. nr rspan\\n[t*#]*\\n+[*]*\\n[#c] 0
|
|
. nr ** (\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb])
|
|
. nr corr -\\n[**]
|
|
. nr $1 +\\n[**]
|
|
. \}
|
|
.
|
|
. if (\\n-[*] == \\n[t*r#\\n[t*#]]) \
|
|
. nr $1 ((\\n[t*height\\n[t*#]] \
|
|
- \\n[.d] \
|
|
+ \\n[toptbl\\n[t*#]] \
|
|
+ \\n[cscpb]) \
|
|
>? \\n[$1])
|
|
. nr dntr\\n[t*#]*\\n[*] +(\\n[corr] >? 0)
|
|
. \}
|
|
.
|
|
. \" paint cell background
|
|
. nr * (2 * \\n[t*cpd\\n[t*#]] + \\n[cll\\*[#trc]])\" background width
|
|
. nr $1 (\\n[$1] >? \\n[dn\\*[#trc]])\" cell height
|
|
.
|
|
. if !"\\*[t*bgc\\*[#trc]]"=" \{\
|
|
. nop \h'\\n[t*csp\\n[t*#]]u'\
|
|
\M[\\*[t*bgc\\*[#trc]]]\
|
|
\v'(-.67v - \\n[t*cpd\\n[t*#]]u)'\
|
|
\D'P \\n[*]u 0 \
|
|
0 (2u * \\n[t*cpd\\n[t*#]]u + \\n[$1]u) \
|
|
-\\n[*]u 0'\
|
|
\M[]
|
|
. sp -1
|
|
. \}
|
|
.
|
|
. \" *** horizontal and vertical single or double lines ***
|
|
. \" double and single lines have the same thickness;
|
|
. \" the double lines' distance is the line thickness.
|
|
. \"
|
|
. \" 'border=x': horizontal/vertical lines x/2 thick, minimum .1n
|
|
. \" 'border=0': no border; horizontal/vertical lines .1n thick
|
|
. \" 'border=': neither border nor horizontal/vertical lines
|
|
.
|
|
. nr *t (.1n >? \\n[b/2]) \" thickness of hl/vl; min. .1n
|
|
. in +\\n[cscp]u
|
|
.
|
|
. \" check for vertical and horizontal lines
|
|
. if (1 + \\n[t*b\\n[t*#]]) \{\
|
|
. if !"\\*[t*bc\\n[t*#]]"=" \{\
|
|
. \" draw horizontal line between this cell and the one below
|
|
. if (\\n[t*r#\\n[t*#]] - \\n[#r] + \\n[rspan\\*[#trc]]) \{\
|
|
. if !"\\*[t*hl\\*[#trc]]"=" \{\
|
|
. sp \\n[$1]u
|
|
. nr * (\\n[cscp] + \\n[cscpb] + \\n[cll\\*[#trc]])
|
|
. nop \X'\*[g] 1 setlinecap'\
|
|
\h'(-\\n[cscpb2]u - \\n[*t]u)'\
|
|
\v'(\\n[cscpb2]u - .67v)'\
|
|
\m[\\*[t*bc\\n[t*#]]]\
|
|
\D't \\n[*t]u'\c
|
|
.
|
|
. ie "\\*[t*hl\\*[#trc]]"d" \
|
|
. nop \v'-\\n[*t]u'\
|
|
\D'l \\n[*]u 0'\
|
|
\v'(2u * \\n[*t]u)'\
|
|
\D'l -\\n[*]u 0'\
|
|
\D't 0'
|
|
. el \
|
|
. nop \D'l \\n[*]u 0'\
|
|
\D't 0'
|
|
.
|
|
. sp (-\\n[$1]u - 1v)
|
|
. \}\}
|
|
.
|
|
. nr rspan\\*[#trc] 0
|
|
.
|
|
. \" draw vertical line between this cell and the one to the right
|
|
. if (\\n[t*cols\\n[t*#]] - \\n[#c] + \\n[vline\\*[#trc]]) \{\
|
|
. if !"\\*[t*vl\\*[#trc]]"=" \{\
|
|
. nop \X'\*[g] 1 setlinecap'\
|
|
\v'(-\\n[cscpb2]u - .67v)'\
|
|
\m[\\*[t*bc\\n[t*#]]]\
|
|
\h'(\\n[cscpb2]u - \\n[*t]u + \\n[cll\\*[#trc]]u)'\c
|
|
.
|
|
. ie "\\*[t*vl\\*[#trc]]"d" \
|
|
. nop \h'-\\n[*t]u'\
|
|
\D't \\n[*t]u'\
|
|
\D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\
|
|
\h'(2u * \\n[*t]u)'\
|
|
\D'l 0 -(2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\
|
|
\D't 0'
|
|
. el \
|
|
. nop \D't \\n[*t]u'\
|
|
\D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\
|
|
\D't 0'
|
|
. sp -1
|
|
. \}\}\}\}
|
|
.
|
|
. nr vline\\*[#trc] 0
|
|
.
|
|
. \" vert. cell content alignment
|
|
. nr ** 0
|
|
.
|
|
. ie "\\*[t*val\\*[#trc]]"m" \
|
|
. nr ** ((\\n[$1] - \\n[dn\\*[#trc]]) / 2)\" val=m
|
|
. el \
|
|
. if "\\*[t*val\\*[#trc]]"b" \
|
|
. nr ** (\\n[$1] - \\n[dn\\*[#trc]])\" val=b
|
|
.
|
|
. sp \\n[**]u \" vertical content position
|
|
.
|
|
. \" finally output the diversion
|
|
. t*\\*[#trc]
|
|
. rm t*\\*[#trc]
|
|
. \}
|
|
. \}
|
|
.
|
|
. \" draw the box border
|
|
. in \\n[in\\n[t*#]]u
|
|
. nr ** (\\n[topdiv] + \\n[dntr\\n[t*#]*\\n-[#r]])
|
|
.
|
|
. if \\n[t*b\\n[t*#]] \{\
|
|
. sp |(\\n[toptbl\\n[t*#]]u + \\n[b/2]u)
|
|
. nr $1 (\\n[toptbl\\n[t*#]] - \\n[**] - \\n[cscp])
|
|
. nr * (\\n[ll\\n[t*#]] - \\n[t*b\\n[t*#]])
|
|
.
|
|
. if !"\\*[t*bc\\n[t*#]]"=" \
|
|
. nop \X'\*[g] 0 setlinejoin 2 setlinecap'\
|
|
\v'-.67v'\
|
|
\h'-\\n[b/2]u'\
|
|
\m[\\*[t*bc\\n[t*#]]]\
|
|
\D't \\n[t*b\\n[t*#]]u'\
|
|
\D'l \\n[*]u 0'\
|
|
\D'l 0 -\\n[$1]u'\
|
|
\D'l -\\n[*]u 0'\
|
|
\D'l 0 \\n[$1]u'\
|
|
\D't 0'
|
|
. \}
|
|
.
|
|
. sp |(\\n[**]u + \\n[cscpb]u)
|
|
. fi
|
|
..
|
|
.
|
|
.
|
|
.\" Utility macro: .t*cl [width1 [width2 [...]]]
|
|
.\"
|
|
.\" Calculate cell widths, table width, and cell offsets.
|
|
.de t*cl
|
|
. nr t*cols\\n[t*#] (\\n[.$] >? \\n[t*cols\\n[t*#]])
|
|
. nr ll\\n[t*#] 0 \" accumulated cell widths
|
|
. nr ** (\\n[.l] / \\n[t*cols\\n[t*#]])\" width for remaining cells
|
|
. nr * 0 1 \" counter
|
|
.
|
|
. \" while-loop: Parse user arguments to get each cell's width.
|
|
. while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\
|
|
. nr $\\n[*] \\n[**]
|
|
. if !"\\$[\\n[*]]"" \{\
|
|
. \" check for '%' pseudo scaling indicator
|
|
. ds * \\$\\n[*]\"
|
|
. substring * -1 -1
|
|
. ie "\\*[*]"%" \{\
|
|
. ds ** \\$[\\n[*]]\"
|
|
. substring ** 0 -2
|
|
. ie \B"\\*[**]" \
|
|
. nr $\\n[*] (\\*[**] * \\n[.l] / 100)
|
|
. el \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid relative cell width
|
|
. tm1 " '\\*[**]%'.
|
|
. \}
|
|
. \}
|
|
. el \{\
|
|
. ie \B"\\$[\\n[*]]" \
|
|
. nr $\\n[*] \\$[\\n[*]]
|
|
. el \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid cell width
|
|
. tm1 " '\\$[\\n[*]]'.
|
|
. \}
|
|
. \}\}
|
|
.
|
|
. nr ll\\n[t*#] +\\n[$\\n[*]]
|
|
. nr ** \\n[$\\n[*]]
|
|
. \}
|
|
.
|
|
. if (\\n[ll\\n[t*#]] > \\n[.l]) \
|
|
. tm \*[hdtbl]:\\n[.F]:\\n[.c]: Table width larger than column width.
|
|
.
|
|
. nr ** (0 >? \\n[t*b\\n[t*#]])
|
|
. nr * 0 1
|
|
.
|
|
. \" second while loop: Compute final cell widths.
|
|
. while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\
|
|
. \" Remove border width, if any.
|
|
. if \\n[t*b\\n[t*#]] \{\
|
|
. \" cell_width := cell_width * (length - 1.5*border) / length
|
|
. nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2))
|
|
. nr *** (\\n[ll\\n[t*#]] / 2)
|
|
. \" avoid multiplication overflow
|
|
. mult31by31 $\\n[*] #* ****
|
|
. add31to62 *** **** ****
|
|
. div62by31 **** ll\\n[t*#] $\\n[*]
|
|
. \}
|
|
.
|
|
. \" Get cell widths without padding, spacing, and separator line.
|
|
. nr cll\\n[t*#]*\\n[*] (\\n[$\\n[*]] \
|
|
- (2 * \\n[cscp\\n[t*#]]) \
|
|
- \\n[b/2\\n[t*#]])
|
|
.
|
|
. \" Check whether value is non-positive.
|
|
. if !\\n[cll\\n[t*#]*\\n[*]] \{\
|
|
. nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2))
|
|
. nr *** (\\n[#*] / 2)
|
|
. nr *h (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]])
|
|
. mult31by31 *h ll\\n[t*#] ****
|
|
. add31to62 *** **** ****
|
|
. div62by31 **** #* *h
|
|
. ds * \\n[*]th\"
|
|
. nr *** (\\n[*] % 10)
|
|
. if d nth-\\n[***] \
|
|
. ds * \\n[*]\\*[nth-\\n[***]]\"
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: The \\*[*] width value (\\$\\n[*])
|
|
. tm1 " is too small. It should be greater than \\n[*h].
|
|
. \}
|
|
.
|
|
. nr in\\n[t*#]*\\n[*] \\n[**] \" cell offset
|
|
. nr ** +\\n[$\\n[*]]
|
|
. \}
|
|
..
|
|
.
|
|
.
|
|
.\" Utility macro: .t*dntr <origin> <cell position> ? <cell ID>
|
|
.\"
|
|
.\" Close TD diversion, make some calculations, and set
|
|
.\" some help strings and registers. <origin> is 0, 1,
|
|
.\" or 2 if the call of .t*dntr occurs in .TD, .TR, or
|
|
.\" .ETB, respectively.
|
|
.de t*dntr
|
|
. nr dn 0 \" reset diversion height
|
|
. br \" finish cell data
|
|
.
|
|
. if "\\n[.z]"*t*dummy*" \
|
|
. return
|
|
.
|
|
. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier
|
|
.
|
|
. if \\n[c#\\*[#t#r]] \{\
|
|
. di \" close diversion
|
|
. nr dn\\$4 \\n[dn] \" save height of this cell
|
|
. if !\\n[rspan\\*[#trc]] \{\
|
|
. \" update row height if not in a row span
|
|
. nr dntr\\*[#t#r] (\\n[dntr\\*[#t#r]] >? \\n[dn])
|
|
. if \\$2 \
|
|
. nr dntr\\*[#t#r] ((\\n[t*height\\*[#t#r]] \
|
|
- (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]])) \
|
|
>? \\n[dntr\\*[#t#r]])
|
|
. \}\}
|
|
.
|
|
. nr c#\\*[#t#r] +1
|
|
. nr * \\$2
|
|
.
|
|
. \" update column span registers
|
|
. while (\\n+[*] <= \\$3) \{\
|
|
. if r cspan\\*[#t#r]*\\n[*] \
|
|
. nr c#\\*[#t#r] +\\n[cspan\\*[#t#r]*\\n[*]]
|
|
. nr cspan\\*[#t#r]*\\n[*] 0
|
|
. \}
|
|
.
|
|
. ds #trc \\*[#t#r]*\\n[c#\\*[#t#r]]\"
|
|
.
|
|
. \" only check for cell underflow if called by .TR or .ETB
|
|
. if (\\$1 & (\\n[c#\\*[#t#r]] <= \\n[t*cols\\n[t*#]])) \{\
|
|
. ds * are\"
|
|
. ds ** columns\"
|
|
. if (\\n-[c#\\*[#t#r]] == 1) \{\
|
|
. ds * is\"
|
|
. ds ** column\"
|
|
. \}
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: There \\*[*] only \\n[c#\\*[#t#r]]
|
|
. tm1 " \\*[**]
|
|
.
|
|
. nr * \\n[t*r#\\n[t*#]]
|
|
. ds * \\n[*]th\"
|
|
. nr *** (\\n[*] % 10)
|
|
. if d nth-\\n[***] \
|
|
. ds * \\n[*]\\*[nth-\\n[***]]\"
|
|
. tmc " in the \\*[*] row
|
|
.
|
|
. ds * are\"
|
|
. if (\\n[t*cols\\n[t*#]] == 1) \
|
|
. ds * is\"
|
|
. tm1 " but \\n[t*cols\\n[t*#]] \\*[*] expected.
|
|
. \}
|
|
..
|
|
.
|
|
.
|
|
.\" Utility-macro: .t*args level_1 [level_2]
|
|
.\"
|
|
.\" Get the arguments common to TBL, TR, and TD for the level
|
|
.\" in argument 1, using default values from the level in
|
|
.\" argument 2. If argument 2 is missing, use the global
|
|
.\" default values.
|
|
.\"
|
|
.de t*args
|
|
. ds t*bgc\\$1 \\*[t*bgc\\$2]\"
|
|
. ds t*fgc\\$1 \\*[t*fgc\\$2]\"
|
|
. ds t*hl\\$1 \\*[t*hl\\$2]\"
|
|
. ds t*vl\\$1 \\*[t*vl\\$2]\"
|
|
. ds t*hal\\$1 \\*[t*hal\\$2]\"
|
|
. ds t*val\\$1 \\*[t*val\\$2]\"
|
|
. ds t*ff\\$1 \\*[t*ff\\$2]\"
|
|
. ds t*fst\\$1 \\*[t*fst\\$2]\"
|
|
. ds t*fsz\\$1 \\*[t*fsz\\$2]\"
|
|
.
|
|
. if "\\*[args]"" \
|
|
. return
|
|
.
|
|
. t*getarg bgc \\*[args] \" background color
|
|
. if !"\\*[bgc]"" \{\
|
|
. ie m\\*[bgc] \
|
|
. ds t*bgc\\$1 \\*[bgc]\"
|
|
. el \{\
|
|
. ie "\\*[bgc]"=" \
|
|
. ds t*bgc\\$1 =\"
|
|
. el \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid background color
|
|
. tm1 " '\\*[bgc]'.
|
|
. \}
|
|
. \}\}
|
|
. if "\\*[args]"" \
|
|
. return
|
|
.
|
|
. t*getarg fgc \\*[args] \" foreground color
|
|
. if !"\\*[fgc]"" \{\
|
|
. ie m\\*[fgc] \
|
|
. ds t*fgc\\$1 \\*[fgc]\"
|
|
. el \{\
|
|
. ie "\\*[fgc]"=" \
|
|
. ds t*fgc\\$1 =\"
|
|
. el \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid foreground color
|
|
. tm1 " '\\*[fgc]'.
|
|
. \}
|
|
. \}\}
|
|
. if "\\*[args]"" \
|
|
. return
|
|
.
|
|
. t*getarg hl \\*[args] \" horizontal line between cells
|
|
. if !"\\*[hl]"" \
|
|
. ds t*hl\\$1 \\*[hl]\"
|
|
. if "\\*[args]"" \
|
|
. return
|
|
.
|
|
. t*getarg vl \\*[args] \" vertical line between cells
|
|
. if !"\\*[vl]"" \
|
|
. ds t*vl\\$1 \\*[vl]\"
|
|
. if "\\*[args]"" \
|
|
. return
|
|
.
|
|
. t*getarg hal \\*[args] \" horizontal table cell alignment
|
|
. if !"\\*[hal]"" \{\
|
|
. t*index bcrl \\*[hal]
|
|
. ie \\n[t*index] \
|
|
. ds t*hal\\$1 \\*[hal]\"
|
|
. el \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid horizontal alignment
|
|
. tm1 " '\\*[hal]': must be 'b', 'c', 'l' or 'r'.
|
|
. \}\}
|
|
. if "\\*[args]"" \
|
|
. return
|
|
.
|
|
. t*getarg val \\*[args] \" vertical table cell alignment
|
|
. if !"\\*[val]"" \{\
|
|
. t*index tmb \\*[val]
|
|
. ie \\n[t*index] \
|
|
. ds t*val\\$1 \\*[val]\"
|
|
. el \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Invalid vertical alignment
|
|
. tm1 " '\\*[val]': must be 't', 'm' or 'b'.
|
|
. \}\}
|
|
. if "\\*[args]"" \
|
|
. return
|
|
.
|
|
. t*getarg ff \\*[args] \" font family
|
|
. if !"\\*[ff]"" \
|
|
. ds t*ff\\$1 \\*[ff]\"
|
|
. if "\\*[args]"" \
|
|
. return
|
|
.
|
|
. t*getarg fst \\*[args] \" font style
|
|
. if !"\\*[fst]"" \
|
|
. ds t*fst\\$1 \\*[fst]\"
|
|
. if "\\*[args]"" \
|
|
. return
|
|
.
|
|
. t*getarg fsz \\*[args] \" font size and spacing factor
|
|
. if !"\\*[fsz]"" \
|
|
. ds t*fsz\\$1 \\*[fsz]\"
|
|
..
|
|
.
|
|
.
|
|
.\" Append to your page header macro ('pg@top' for MS)
|
|
.\" to enable tables to span pages.
|
|
.de t*hm
|
|
. ev t*tbl
|
|
. nr ** \\n[.t]
|
|
. while !""\\*[t*kept]" \{\
|
|
. pops * t*kept
|
|
. popr * t*kept
|
|
. if (\\n[*] - \\n[**]) \{\
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Table \\*[*] higher than page --
|
|
. tm1 " ignored!
|
|
. break
|
|
. \}
|
|
.
|
|
. if (\\n[*] - \\n[.t]) \{\
|
|
. ds t*kept \\n[*] \\*[t*kept]\"
|
|
. ds t*kept \\*[*] \\*[t*kept]\"
|
|
. tmc \*[hdtbl]:\\n[.F]:\\n[.c]: Remaining table(s),
|
|
. tm1 " because not all fit onto this page.
|
|
. break
|
|
. \}
|
|
.
|
|
. t*DI \\*[*]
|
|
. \}
|
|
. ev
|
|
..
|
|
.
|
|
.\" Local Variables:
|
|
.\" mode: nroff
|
|
.\" End:
|
|
.\" vim: filetype=groff:
|