diff options
Diffstat (limited to 'contrib/hdtbl/hdtbl.tmac')
-rw-r--r-- | contrib/hdtbl/hdtbl.tmac | 1003 |
1 files changed, 1003 insertions, 0 deletions
diff --git a/contrib/hdtbl/hdtbl.tmac b/contrib/hdtbl/hdtbl.tmac new file mode 100644 index 0000000..422ede7 --- /dev/null +++ b/contrib/hdtbl/hdtbl.tmac @@ -0,0 +1,1003 @@ +.ig + +hdtbl.tmac + +This file is part of groff, the GNU roff type-setting system. + +Copyright (C) 2005-2020 Free Software Foundation, Inc. +written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>. + +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 d TBL \ +. 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 \ +. tm \\n[.F]:\\n[.c]: Invalid number of columns value '\\*[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 \ +. tm \\n[.F]:\\n[.c]: Invalid cell padding value '\\*[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 \ +. tm \\n[.F]:\\n[.c]: Invalid cell spacing value '\\*[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 \ +. tm \\n[.F]:\\n[.c]: Invalid border thickness 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 \\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 \\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 \\n[.F]:\\n[.c]: Invalid horizontal table alignment '\\*[tal]': +. tm1 " 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 \\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*#] \{\ +. tm \\n[.F]:\\n[.c]: Table row (.TR) without preceding 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 \ +. tm \\n[.F]:\\n[.c]: Invalid table row height '\\*[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 +. 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 \\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 \\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 \\n[.F]:\\n[.c]: There \\*[*] \\n[c#\\*[#t#r]] table \\*[**] (.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 \\n[.F]:\\n[.c]: Each table (.TBL) +. tm1 " should contain at least one table row (.TR)! +. \} +. el \{\ +. tmc \\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 \\n[*cl\\n[t*#]]u \" 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 \\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 \\n[.F]:\\n[.c]: Invalid placement of '.t*free' within a table; +. tm1 " it must be called outside of any table. +. return +. \} +. +. if "\\*[t*held]"" \{\ +. tm \\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 \ +. tm \\n[.F]:\\n[.c]: Invalid relative cell width '\\*[**]%'. +. \} +. el \{\ +. ie \B\\$[\\n[*]] \ +. nr $\\n[*] \\$[\\n[*]] +. el \ +. tm \\n[.F]:\\n[.c]: Invalid cell width '\\$[\\n[*]]'. +. \}\} +. +. nr ll\\n[t*#] +\\n[$\\n[*]] +. nr ** \\n[$\\n[*]] +. \} +. +. if (\\n[ll\\n[t*#]] > \\n[.l]) \ +. tm \\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 \\n[.F]:\\n[.c]: The \\*[*] width value (\\$\\n[*]) is too small. +. tm1 " 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 \\n[.F]:\\n[.c]: There \\*[*] only \\n[c#\\*[#t#r]] \\*[**] +. +. 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 \ +. tm \\n[.F]:\\n[.c]: Invalid background color '\\*[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 \ +. tm \\n[.F]:\\n[.c]: Invalid foreground color '\\*[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 \\n[.F]:\\n[.c]: Invalid horizontal alignment '\\*[hal]': +. tm1 " 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 \\n[.F]:\\n[.c]: Invalid vertical alignment '\\*[val]': +. tm1 " 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[**]) \{\ +. tm \\n[.F]:\\n[.c]: Table \\*[*] higher than page -- ignored! +. break +. \} +. +. if (\\n[*] - \\n[.t]) \{\ +. ds t*kept \\n[*] \\*[t*kept]\" +. ds t*kept \\*[*] \\*[t*kept]\" +. tmc \\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: |