6 This file is part of groff, the GNU roff type-setting system.
8 Copyright (C) 2005, 2006, 2009 Free Software Foundation, Inc.
9 written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
11 groff is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 groff is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 .\" *****************************************************************
28 .\" * hdtbl - Heidelberger table macros *
29 .\" * Vers. 0.91 December 2005 *
30 .\" *****************************************************************
38 .wh 0 HM \" comment this out if a page header macro exists
39 .wh -1i BM \" comment this out if a bottom margin macro exists
41 .\" replace `HM' with the name of your pageheader macro, e.g., `pg@top' for MS
47 .\" *****************************************************************
48 .\" * default values for some arguments *
49 .\" *****************************************************************
68 .\" defaults for table captions
70 .ds t*cptn "".sp .4" \
73 "\m[\\*[t*fgc]]Table \\n+[t*cptn]:\0\c\k*"\"
76 .\" Running title, running footer
77 .ds t*HM //arbitrary text for pageheader, except on the first page//\"
78 .ds t*BM //arbitrary text for pagefooter, except on the last page/\\n[%]/\"
83 .\" for better error messages
88 .\" initialization of various registers
89 .nr t*# 0 \" table nesting level
90 .nr t*numb 0 1 \" held table diversion #
95 .\" *****************************************************************
96 .\" * The four base macros and the two optional macros *
97 .\" *****************************************************************
105 .\" predecessor: text, TD or ETB
106 .\" successor: CPTN or TR
108 . ds t*m\\n[t*#] \\n[.m]\"
116 . sp .4 \" XXX: hard-coded value
123 . getarg cols \\$@\" from here string `args' contains the rest of \\$@
125 . nr t*cols\\n[t*#] \\n[t*cols]
127 . ie \B
\a\\*[cols]
\a \
128 . nr t*cols\\n[t*#] \\*[cols]
130 . tm \\n[.F]:\\n[.c]: Invalid number of columns value `\\*[cols]'.
133 . getarg cpd \\*[args] \" cell padding
135 . nr t*cpd\\n[t*#] \\n[t*cpd]
137 . ie \B
\a\\*[cpd]
\a \
138 . nr t*cpd\\n[t*#] \\*[cpd]
140 . tm \\n[.F]:\\n[.c]: Invalid cell padding value `\\*[cpd]'.
143 . getarg csp \\*[args] \" cell spacing
145 . nr t*csp\\n[t*#] \\n[t*csp]
147 . ie \B
\a\\*[csp]
\a \
148 . nr t*csp\\n[t*#] \\*[csp]
150 . tm \\n[.F]:\\n[.c]: Invalid cell spacing value `\\*[csp]'.
153 . getarg border \\*[args] \" border thickness
154 . ie "\\*[border]"=" \
157 . ie "\\*[border]"" \
158 . nr t*b\\n[t*#] \\n[t*b]
160 . ie \B
\a\\*[border]
\a \
161 . nr t*b\\n[t*#] \\*[border]
163 . tm \\n[.F]:\\n[.c]: Invalid border thickness value `\\*[border]'.
166 . getarg bc \\*[args] \" border color
167 . ds t*bc\\n[t*#] \\*[t*bc]\"
170 . ds t*bc\\n[t*#] \\*[bc]\"
173 . ds t*bc\\n[t*#] =\"
175 . tm \\n[.F]:\\n[.c]: Invalid border color `\\*[bc]'.
181 . ds t*bc\\n[t*#] \\*[t*bc]\"
183 . ds t*bc\\n[t*#] \\*[bc]\"
186 . getarg width \\*[args] \" table/col widths
187 . if "\\*[width]"=" \
190 . nr b/2\\n[t*#] (\\n[t*b\\n[t*#]] / 2)\" shortcut
191 . nr cscp\\n[t*#] (\\n[t*csp\\n[t*#]] + \\n[t*cpd\\n[t*#]])\" aux. register
193 . getarg height \\*[args] \" table outline height
194 . ie "\\*[height]"" \
195 . nr t*height\\n[t*#] 0
197 . ie \B
\a\\*[height]
\a \
198 . nr t*height\\n[t*#] (\\*[height] \
199 - ((2 * \\n[cscp\\n[t*#]]) \
200 + (3 * \\n[b/2\\n[t*#]])))
202 . tm \\n[.F]:\\n[.c]: Invalid height value `\\*[height]'.
205 . t*cl \\*[width] \" get cell widths and offsets
206 . t*args \\n[t*#] \" look for common arguments
208 . getarg tal \\*[args] \" table horizontal alignment
210 . ds tal \\*[t*tal]\"
212 . nr in\\n[t*#] \\n[.i]
215 . nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]]/2 + \\n[.i])
218 . nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]] + \\n[.i])
220 . tmc \\n[.F]:\\n[.c]: Invalid horizontal table alignment `\\*[tal]':
221 . tm1 " must be `l', `c' or `r'.
224 . nr t*r#\\n[t*#] 0 \" initialize row index
231 .\" CPTN: optional table caption
238 . if \\n[t*r#\\n[t*#]] \{\
239 . tmc \\n[.F]:\\n[.c]: Invalid placement of `.CPTN';
240 . tm1 " must be called immediately after `.TBL'.
245 . ds args\\n[t*#] "\\*[args]\"
247 . index "\\*[args]" .TR
249 . ds *a\\n[t*#] "\\*[args]\"
250 . substring args\\n[t*#] 0 \\n[index]
251 . substring *a\\n[t*#] \\n[index]-2 -1
256 . ie "\\*[val]"b" \{\
258 . *CPTN \\*[args\\n[t*#]]
263 . ll (\\n[ll\\n[t*#]]u + \\n[in\\n[t*#]]u)
264 . in \\n[in\\n[t*#]]u
267 . P1 \\*[args\\n[t*#]]
280 .\" predecessor: TBL, CPTN, text, TD or ETB
285 . tm \\n[.F]:\\n[.c]: Table row (.TR) without preceding table start (.TBL).
289 . \" finish previous data cell, if any
290 . if \\n[t*r#\\n[t*#]] \
291 . t*dntr 1 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*]
293 . nr t*r#\\n[t*#] +1 \" row number in this table
294 . ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" table row identifier
296 . nr c#\\*[#t#r] 0 1 \" clear cell counter
297 . nr dntr\\*[#t#r] 0 1 \" clear accumulated row height
300 . ie "\\*[height]"" \
301 . nr t*height\\*[#t#r] 0
303 . ie \B
\a\\*[height]
\a \
304 . nr t*height\\*[#t#r] \\*[height]
306 . tm \\n[.F]:\\n[.c]: Invalid table row height `\\*[height]'.
309 . \" If there is a TR with height `height', the total height of the table
310 . \" is too high by 3/2 b, independent of the number of TR with `height'.
311 . t*args \\*[#t#r] \\n[t*#] \" look for common arguments
317 .\" TH: optional table header cell
318 .\" predecessor: text, TD or TR
319 .\" successor: text, TD, TR, TBL or ETB
321 .\" cell content bolded and horizontally and vertically centered,
329 . getarg val \\*[args]
333 . getarg fst \\*[args]
337 . TD hal=\\*[hal] val=\\*[val] fst=\\*[fst] \\*[args]
341 .\" TD: table data cell
342 .\" predecessor: text, TD or TR
343 .\" successor: text, TD, TR, TBL or ETB
346 . \" finish previous data cell -- note the use of \E
347 . t*dntr 0 \\n[c#\\*[#t#r]]-1 \En[c#\\*[#t#r]] \\*[*#trc*]
349 . ds *#trc* \\*[#t#r]*\\n[c#\\*[#t#r]]\" table cell identifier
350 . \" (<level>*<row>*<column>)
352 . getarg rowspan \\$@
354 . if !"\\*[rowspan]"" \{\
355 . ie \B
\a\\*[rowspan]
\a \{\
356 . nr rowspan (\\*[rowspan] >? 1)
357 . nr *rsp*\\*[*#trc*] (\\n[rowspan] - 1)
360 . tm \\n[.F]:\\n[.c]: Invalid value of `rowspan' keyword.
363 . getarg colspan \\*[args]
365 . if !"\\*[colspan]"" \{\
366 . ie \B
\a\\*[colspan]
\a \
367 . nr colspan (\\*[colspan] >? 1)
369 . tm \\n[.F]:\\n[.c]: Invalid value of `colspan' keyword.
372 . t*args \\*[#trc] \\*[#t#r] \" look for common arguments
374 . nr in\\*[#trc] \\n[in\\n[t*#]*\\n[c#\\*[#t#r]]]
375 . nr *cl \\n[cll\\n[t*#]*\\n[c#\\*[#t#r]]]
377 . nr *r \\n[t*r#\\n[t*#]]
379 . if (\\n[rowspan] - 1) \
380 . while (\\n+[*] <= \\n[rowspan]) \{\
381 . nr rspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan]
383 . nr cspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan]
388 . nr *c \\n[c#\\*[#t#r]]
390 . if (\\n[colspan] - 1) \{\
391 . nr vline\\*[*#trc*] 0-1 \" set `no vl' flag
393 . while (\\n+[*] <= \\n[colspan]) \{\
395 . nr *cl +(2 * \\n[cscp\\n[t*#]] \
397 + \\n[cll\\n[t*#]*\\n[*c]])
402 . if (\\n[c#\\n[t*#]*\\n[t*r#\\n[t*#]]] > \\n[t*cols\\n[t*#]]) \{\
405 . if (\\n[c#\\*[#t#r]] == 1) \{\
409 . tmc \\n[.F]:\\n[.c]: There \\*[*] \\n[c#\\*[#t#r]] table \\*[**] (.TD)
412 . if (\\n[t*cols\\n[t*#]] == 1) \
414 . tm1 " but only \\n[t*cols\\n[t*#]] \\*[*] expected.
417 . length * \\n[.F]:\\n[.c]:
422 . tm1 "\\*[*] Remaining .TDs and its contents are ignored.
424 . di *t*dummy* \" bypass superfluous input
428 . di t*\\*[#trc] \" open cell diversion and set locals
430 . nr cll\\*[#trc] \\n[*cl]
432 . nr *cl\\n[t*#] \\n[.l]
433 . gcolor \\*[t*fgc\\*[#trc]]
434 . ad \\*[t*hal\\*[#trc]]
435 . fam \\*[t*ff\\*[#trc]]
436 . ft \\*[t*fst\\*[#trc]]
437 . pv \\*[t*fsz\\*[#trc]]
443 .\" ETB: end of table
444 .\" predecessor: text, TD or ETB
445 .\" successor: text, TD, TR or TBL
448 . if !\\n[t*r#\\n[t*#]] \{\
449 . tmc \\n[.F]:\\n[.c]: Each table (.TBL)
450 . tm1 " should contain at least one table row (.TR)!
453 . tmc \\n[.F]:\\n[.c]: Table end (.ETB)
454 . tm1 " without corresponding table start (.TBL)!
457 . ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier
458 . t*dntr 2 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*]
460 . t*divs \" print this table
462 . sp \\n[b/2\\n[t*#]]u
466 . ll \\n[*cl\\n[t*#]]u \" restore ll outside this table
467 . in 0 \" reset indent
468 . gcolor \\*[t*m\\n[t*#]] \" reset previous fgc
475 . ie "\\*[hold]"" \{\
476 . ie (\\n[.t] - \\n[dn]) \
479 . rn t*tbl0 t*tbl\\n[t*numb]
480 . ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[dn]\"
484 . rn t*tbl0 t*hold\\n+[t*numb]
485 . tm \\n[.F]:\\n[.c]: Table t*hold\\n[t*numb] held.
486 . ds t*held \\*[t*held] t*hold\\n[t*numb] \\n[dn]\"
489 . ev \" restore previous environment
496 .\" *****************************************************************
497 .\" * Following the definition of five utility macros *
498 .\" * special to hdtbl. *
499 .\" * Other utility macros common to hdtbl and hdgroff *
500 .\" * are defined in the file hdmisc.tmac. *
501 .\" *****************************************************************
505 .\" print the next [n] held table[s].
506 .\" Don't call it within a table!
507 .\" If the table is higher than the remaining space
508 .\" on the page, the table is printed on the next page.
511 . if \\n[t*r#\\n[t*#]] \{\
512 . tmc \\n[.F]:\\n[.c]: Invalid placement of `.t*free' within a table;
513 . tm1 " it must be called outside of any table.
517 . if "\\*[t*held]"" \{\
518 . tm \\n[.F]:\\n[.c]: No held tables.
523 . while !""\\*[t*held]" \{\
527 . ie (\\n[.t] - \\n[*]) \{\
533 . rn \\*[*] t*tbl\\n+[t*numb]
534 . ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[*]\"
537 . if !(\\n-[**] - 1) \
543 .\" The main utility macro for tables:
544 .\" If a table is closed by ETB, this macro is called. It
545 .\" processes one complete table, i.e., all the table cell
546 .\" diversions, paints the cell backgrounds, draws
547 .\" horizontal and vertical table lines and the table border.
549 .\" Nested tables are processed from inside to outside.
552 . ll (\\n[l]u + 1c) \" avoid warning `can't break line'
555 . nr b/2 \\n[b/2\\n[t*#]] \" some abbreviations
556 . nr cscp \\n[cscp\\n[t*#]]
557 . nr cscpb (\\n[b/2] + \\n[cscp])
559 . nr topdiv (\\n[.d] + \\n[b/2] - \\n[cscp])\" top of cell diversion
560 . nr cscpb2 (\\n[b/2] / 2 + \\n[cscp])
563 . \" outer loop for rows
564 . while (\\n+[#r] <= \\n[t*r#\\n[t*#]]) \{\
565 . \" TODO: insert code here for multipage tables
567 . nr topdiv +(\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb])
569 . \" if table still smaller than specified table height, increase it
570 . if ((\\n[#r] == \\n[t*r#\\n[t*#]]) & \\n[t*height\\n[t*#]]) \
571 . nr dntr\\n[t*#]*\\n[#r] (\\n[cscpb] \
572 + \\n[toptbl\\n[t*#]] \
573 + \\n[t*height\\n[t*#]] \
574 - (\\n[topdiv] >? \\n[dntr\\n[t*#]*\\n[#r]]))
577 . \" inner loop for cells
578 . while (\\n+[#c] <= \\n[t*cols\\n[t*#]]) \{\
579 . ds #trc \\n[t*#]*\\n[#r]*\\n[#c]\"
580 . \" continue if the diversion is empty
581 . if !d t*\\*[#trc] \
585 . in (\\n[in\\n[t*#]]u + \\n[in\\*[#trc]]u)\" cell offset
586 . nr $1 \\n[dntr\\n[t*#]*\\n[#r]] \" cell height
588 . \" if we have spanned rows, calculate resulting row height
589 . \" and position of lower horizontal line
590 . if \\n[*rsp*\\*[#trc]] \{\
592 . nr rspan\\*[#trc] 0-1 \" set `no hl' flag
593 . nr corr (\\n[dn\\*[#trc]] - \\n[dntr\\n[t*#]*\\n[#r]])
595 . \" clear row span flags in following rows and update row height
596 . while \\n[*rsp*\\*[#trc]] \{\
597 . nr *rsp*\\*[#trc] -1
598 . nr rspan\\n[t*#]*\\n+[*]*\\n[#c] 0
599 . nr ** (\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb])
604 . if (\\n-[*] == \\n[t*r#\\n[t*#]]) \
605 . nr $1 ((\\n[t*height\\n[t*#]] \
607 + \\n[toptbl\\n[t*#]] \
610 . nr dntr\\n[t*#]*\\n[*] +(\\n[corr] >? 0)
613 . \" paint cell background
614 . nr * (2 * \\n[t*cpd\\n[t*#]] + \\n[cll\\*[#trc]])\" background width
615 . nr $1 (\\n[$1] >? \\n[dn\\*[#trc]])\" cell height
617 . if !"\\*[t*bgc\\*[#trc]]"=" \{\
618 . nop \h'\\n[t*csp\\n[t*#]]u'\
619 \M[\\*[t*bgc\\*[#trc]]]\
620 \v'(-.67v - \\n[t*cpd\\n[t*#]]u)'\
622 0 (2u * \\n[t*cpd\\n[t*#]]u + \\n[$1]u) \
628 . \" *** horizontal and vertical single or double lines ***
629 . \" double and single lines have the same thickness;
630 . \" the double lines' distance is the line thickness.
632 . \" `border=x': horizontal/vertical lines x/2 thick, minimum .1n
633 . \" `border=0': no border; horizontal/vertical lines .1n thick
634 . \" `border=': neither border nor horizontal/vertical lines
636 . nr *t (.1n >? \\n[b/2]) \" thickness of hl/vl; min. .1n
639 . \" check for vertical and horizontal lines
640 . if (1 + \\n[t*b\\n[t*#]]) \{\
641 . if !"\\*[t*bc\\n[t*#]]"=" \{\
642 . \" draw horizontal line between this cell and the one below
643 . if (\\n[t*r#\\n[t*#]] - \\n[#r] + \\n[rspan\\*[#trc]]) \{\
644 . if !"\\*[t*hl\\*[#trc]]"=" \{\
646 . nr * (\\n[cscp] + \\n[cscpb] + \\n[cll\\*[#trc]])
647 . nop \X'\*[g] 1 setlinecap'\
648 \h'(-\\n[cscpb2]u - \\n[*t]u)'\
649 \v'(\\n[cscpb2]u - .67v)'\
650 \m[\\*[t*bc\\n[t*#]]]\
653 . ie "\\*[t*hl\\*[#trc]]"d" \
660 . nop \D'l \\n[*]u 0'\
663 . sp (-\\n[$1]u - 1v)
666 . nr rspan\\*[#trc] 0
668 . \" draw vertical line between this cell and the one to the right
669 . if (\\n[t*cols\\n[t*#]] - \\n[#c] + \\n[vline\\*[#trc]]) \{\
670 . if !"\\*[t*vl\\*[#trc]]"=" \{\
671 . nop \X'\*[g] 1 setlinecap'\
672 \v'(-\\n[cscpb2]u - .67v)'\
673 \m[\\*[t*bc\\n[t*#]]]\
674 \h'(\\n[cscpb2]u - \\n[*t]u + \\n[cll\\*[#trc]]u)'\c
676 . ie "\\*[t*vl\\*[#trc]]"d" \
679 \D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\
681 \D'l 0 -(2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\
684 . nop \D't \\n[*t]u'\
685 \D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\
690 . nr vline\\*[#trc] 0
692 . \" vert. cell content alignment
695 . ie "\\*[t*val\\*[#trc]]"m" \
696 . nr ** ((\\n[$1] - \\n[dn\\*[#trc]]) / 2)\" val=m
698 . if "\\*[t*val\\*[#trc]]"b" \
699 . nr ** (\\n[$1] - \\n[dn\\*[#trc]])\" val=b
701 . sp \\n[**]u \" vertical content position
703 . \" finally output the diversion
709 . \" draw the box border
710 . in \\n[in\\n[t*#]]u
711 . nr ** (\\n[topdiv] + \\n[dntr\\n[t*#]*\\n-[#r]])
713 . if \\n[t*b\\n[t*#]] \{\
714 . sp |(\\n[toptbl\\n[t*#]]u + \\n[b/2]u)
715 . nr $1 (\\n[toptbl\\n[t*#]] - \\n[**] - \\n[cscp])
716 . nr * (\\n[ll\\n[t*#]] - \\n[t*b\\n[t*#]])
718 . if !"\\*[t*bc\\n[t*#]]"=" \
719 . nop \X'\*[g] 0 setlinejoin 2 setlinecap'\
722 \m[\\*[t*bc\\n[t*#]]]\
723 \D't \\n[t*b\\n[t*#]]u'\
731 . sp |(\\n[**]u + \\n[cscpb]u)
736 .\" Utility macro: .t*cl [width1 [width2 [...]]]
738 .\" Calculate cell widths, table width, and cell offsets.
740 . nr t*cols\\n[t*#] (\\n[.$] >? \\n[t*cols\\n[t*#]])
741 . nr ll\\n[t*#] 0 \" accumulated cell widths
742 . nr ** (\\n[.l] / \\n[t*cols\\n[t*#]])\" width for remaining cells
743 . nr * 0 1 \" counter
745 . \" while-loop: Parse user arguments to get each cell's width.
746 . while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\
748 . if !"\\$[\\n[*]]"" \{\
749 . \" check for `%' pseudo scaling indicator
753 . ds ** \\$[\\n[*]]\"
756 . nr $\\n[*] (\\*[**] * \\n[.l] / 100)
758 . tm \\n[.F]:\\n[.c]: Invalid relative cell width `\\*[**]%'.
761 . ie \B
\a\\$[\\n[*]]
\a \
762 . nr $\\n[*] \\$[\\n[*]]
764 . tm \\n[.F]:\\n[.c]: Invalid cell width `\\$[\\n[*]]'.
767 . nr ll\\n[t*#] +\\n[$\\n[*]]
771 . if (\\n[ll\\n[t*#]] > \\n[.l]) \
772 . tm \\n[.F]:\\n[.c]: Table width larger than column width.
774 . nr ** (0 >? \\n[t*b\\n[t*#]])
777 . \" second while loop: Compute final cell widths.
778 . while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\
779 . \" Remove border width, if any.
780 . if \\n[t*b\\n[t*#]] \{\
781 . \" cell_width := cell_width * (length - 1.5*border) / length
782 . nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2))
783 . nr *** (\\n[ll\\n[t*#]] / 2)
784 . \" avoid multiplication overflow
785 . mult31by31 $\\n[*] #* ****
786 . add31to62 *** **** ****
787 . div62by31 **** ll\\n[t*#] $\\n[*]
790 . \" Get cell widths without padding, spacing, and separator line.
791 . nr cll\\n[t*#]*\\n[*] (\\n[$\\n[*]] \
792 - (2 * \\n[cscp\\n[t*#]]) \
795 . \" Check whether value is non-positive.
796 . if !\\n[cll\\n[t*#]*\\n[*]] \{\
797 . nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2))
798 . nr *** (\\n[#*] / 2)
799 . nr *h (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]])
800 . mult31by31 *h ll\\n[t*#] ****
801 . add31to62 *** **** ****
802 . div62by31 **** #* *h
804 . nr *** (\\n[*] % 10)
805 . if d nth-\\n[***] \
806 . ds * \\n[*]\\*[nth-\\n[***]]\"
807 . tmc \\n[.F]:\\n[.c]: The \\*[*] width value (\\$\\n[*]) is too small.
808 . tm1 " It should be greater than \\n[*h].
811 . nr in\\n[t*#]*\\n[*] \\n[**] \" cell offset
812 . nr ** +\\n[$\\n[*]]
817 .\" Utility macro: .t*dntr <origin> <cell position> ? <cell ID>
819 .\" Close TD diversion, make some calculations, and set
820 .\" some help strings and registers. <origin> is 0, 1,
821 .\" or 2 if the call of .t*dntr occurs in .TD, .TR, or
822 .\" .ETB, respectively.
824 . nr dn 0 \" reset diversion height
825 . br \" finish cell data
827 . if "\\n[.z]"*t*dummy*" \
830 . ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier
832 . if \\n[c#\\*[#t#r]] \{\
833 . di \" close diversion
834 . nr dn\\$4 \\n[dn] \" save height of this cell
835 . if !\\n[rspan\\*[#trc]] \{\
836 . \" update row height if not in a row span
837 . nr dntr\\*[#t#r] (\\n[dntr\\*[#t#r]] >? \\n[dn])
839 . nr dntr\\*[#t#r] ((\\n[t*height\\*[#t#r]] \
840 - (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]])) \
841 >? \\n[dntr\\*[#t#r]])
847 . \" update column span registers
848 . while (\\n+[*] <= \\$3) \{\
849 . if r cspan\\*[#t#r]*\\n[*] \
850 . nr c#\\*[#t#r] +\\n[cspan\\*[#t#r]*\\n[*]]
851 . nr cspan\\*[#t#r]*\\n[*] 0
854 . ds #trc \\*[#t#r]*\\n[c#\\*[#t#r]]\"
856 . \" only check for cell underflow if called by .TR or .ETB
857 . if (\\$1 & (\\n[c#\\*[#t#r]] <= \\n[t*cols\\n[t*#]])) \{\
860 . if (\\n-[c#\\*[#t#r]] == 1) \{\
864 . tmc \\n[.F]:\\n[.c]: There \\*[*] only \\n[c#\\*[#t#r]] \\*[**]
866 . nr * \\n[t*r#\\n[t*#]]
868 . nr *** (\\n[*] % 10)
869 . if d nth-\\n[***] \
870 . ds * \\n[*]\\*[nth-\\n[***]]\"
871 . tmc " in the \\*[*] row
874 . if (\\n[t*cols\\n[t*#]] == 1) \
876 . tm1 " but \\n[t*cols\\n[t*#]] \\*[*] expected.
881 .\" Utility-macro: .t*args level_1 [level_2]
883 .\" Get the arguments common to TBL, TR, and TD for the level
884 .\" in argument 1, using default values from the level in
885 .\" argument 2. If argument 2 is missing, use the global
889 . ds t*bgc\\$1 \\*[t*bgc\\$2]\"
890 . ds t*fgc\\$1 \\*[t*fgc\\$2]\"
891 . ds t*hl\\$1 \\*[t*hl\\$2]\"
892 . ds t*vl\\$1 \\*[t*vl\\$2]\"
893 . ds t*hal\\$1 \\*[t*hal\\$2]\"
894 . ds t*val\\$1 \\*[t*val\\$2]\"
895 . ds t*ff\\$1 \\*[t*ff\\$2]\"
896 . ds t*fst\\$1 \\*[t*fst\\$2]\"
897 . ds t*fsz\\$1 \\*[t*fsz\\$2]\"
902 . getarg bgc \\*[args] \" background color
903 . if !"\\*[bgc]"" \{\
905 . ds t*bgc\\$1 \\*[bgc]\"
910 . tm \\n[.F]:\\n[.c]: Invalid background color `\\*[bgc]'.
915 . getarg fgc \\*[args] \" foreground color
916 . if !"\\*[fgc]"" \{\
918 . ds t*fgc\\$1 \\*[fgc]\"
923 . tm \\n[.F]:\\n[.c]: Invalid foreground color `\\*[fgc]'.
928 . getarg hl \\*[args] \" horizontal line between cells
930 . ds t*hl\\$1 \\*[hl]\"
934 . getarg vl \\*[args] \" vertical line between cells
936 . ds t*vl\\$1 \\*[vl]\"
940 . getarg hal \\*[args] \" horizontal table cell alignment
941 . if !"\\*[hal]"" \{\
942 . index bcrl \\*[hal]
944 . ds t*hal\\$1 \\*[hal]\"
946 . tmc \\n[.F]:\\n[.c]: Invalid horizontal alignment `\\*[hal]':
947 . tm1 " must be `b', `c', `l' or `r'.
952 . getarg val \\*[args] \" vertical table cell alignment
953 . if !"\\*[val]"" \{\
956 . ds t*val\\$1 \\*[val]\"
958 . tmc \\n[.F]:\\n[.c]: Invalid vertical alignment `\\*[val]':
959 . tm1 " must be `t', `m' or `b'.
964 . getarg ff \\*[args] \" font family
966 . ds t*ff\\$1 \\*[ff]\"
970 . getarg fst \\*[args] \" font style
972 . ds t*fst\\$1 \\*[fst]\"
976 . getarg fsz \\*[args] \" font size and spacing factor
978 . ds t*fsz\\$1 \\*[fsz]\"
985 . while !""\\*[t*kept]" \{\
988 . if (\\n[*] - \\n[**]) \{\
989 . tm \\n[.F]:\\n[.c]: Table \\*[*] higher than page -- ignored!
993 . if (\\n[*] - \\n[.t]) \{\
994 . ds t*kept \\n[*] \\*[t*kept]\"
995 . ds t*kept \\*[*] \\*[t*kept]\"
996 . tmc \\n[.F]:\\n[.c]: Remaining table(s),
997 . tm1 " because not all fit onto this page.