5 This file is part of groff, the GNU roff type-setting system.
7 Copyright (C) 2005-2018 Free Software Foundation, Inc.
8 written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
10 groff is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
15 groff is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 .\" *****************************************************************
27 .\" * hdtbl - Heidelberger table macros *
28 .\" * Vers. 0.91 December 2005 *
29 .\" *****************************************************************
38 .\" *****************************************************************
39 .\" * default values for some arguments *
40 .\" *****************************************************************
63 .\" defaults for table captions
65 .ds t*cptn "".sp .4" \
68 "\m[\\*[t*fgc]]Table \\n+[t*cptn]:\0\k*\c"\"
73 .\" for better error messages
78 .\" initialization of various registers
79 .nr t*# 0 \" table nesting level
80 .nr t*numb 0 1 \" held table diversion #
85 .\" *****************************************************************
86 .\" * The four base macros and the two optional macros *
87 .\" *****************************************************************
95 .\" predecessor: text, TD or ETB
96 .\" successor: CPTN or TR
98 . ds t*m\\n[t*#] \\n[.m]\"
106 . sp .4 \" XXX: hard-coded value
113 . \" Save current location for error checking at end
117 . t*getarg cols \\$@\" from here string 'args' contains the rest of \\$@
119 . nr t*cols\\n[t*#] \\n[t*cols]
121 . ie \B
\a\\*[cols]
\a \
122 . nr t*cols\\n[t*#] \\*[cols]
124 . tm \\n[.F]:\\n[.c]: Invalid number of columns value '\\*[cols]'.
127 . t*getarg cpd \\*[args] \" cell padding
129 . nr t*cpd\\n[t*#] \\n[t*cpd]
131 . ie \B
\a\\*[cpd]
\a \
132 . nr t*cpd\\n[t*#] \\*[cpd]
134 . tm \\n[.F]:\\n[.c]: Invalid cell padding value '\\*[cpd]'.
137 . t*getarg csp \\*[args] \" cell spacing
139 . nr t*csp\\n[t*#] \\n[t*csp]
141 . ie \B
\a\\*[csp]
\a \
142 . nr t*csp\\n[t*#] \\*[csp]
144 . tm \\n[.F]:\\n[.c]: Invalid cell spacing value '\\*[csp]'.
147 . t*getarg border \\*[args] \" border thickness
148 . ie "\\*[border]"=" \
151 . ie "\\*[border]"" \
152 . nr t*b\\n[t*#] \\n[t*b]
154 . ie \B
\a\\*[border]
\a \
155 . nr t*b\\n[t*#] \\*[border]
157 . tm \\n[.F]:\\n[.c]: Invalid border thickness value '\\*[border]'.
160 . t*getarg bc \\*[args] \" border color
161 . ds t*bc\\n[t*#] \\*[t*bc]\"
164 . ds t*bc\\n[t*#] \\*[bc]\"
167 . ds t*bc\\n[t*#] =\"
169 . tm \\n[.F]:\\n[.c]: Invalid border color '\\*[bc]'.
175 . ds t*bc\\n[t*#] \\*[t*bc]\"
177 . ds t*bc\\n[t*#] \\*[bc]\"
180 . t*getarg width \\*[args] \" table/col widths
181 . if "\\*[width]"=" \
184 . nr b/2\\n[t*#] (\\n[t*b\\n[t*#]] / 2)\" shortcut
185 . nr cscp\\n[t*#] (\\n[t*csp\\n[t*#]] + \\n[t*cpd\\n[t*#]])\" aux. register
187 . t*getarg height \\*[args] \" table outline height
188 . ie "\\*[height]"" \
189 . nr t*height\\n[t*#] 0
191 . ie \B
\a\\*[height]
\a \
192 . nr t*height\\n[t*#] (\\*[height] \
193 - ((2 * \\n[cscp\\n[t*#]]) \
194 + (3 * \\n[b/2\\n[t*#]])))
196 . tm \\n[.F]:\\n[.c]: Invalid height value '\\*[height]'.
199 . t*cl \\*[width] \" get cell widths and offsets
200 . t*args \\n[t*#] \" look for common arguments
202 . t*getarg tal \\*[args] \" table horizontal alignment
204 . ds tal \\*[t*tal]\"
206 . nr in\\n[t*#] \\n[.i]
209 . nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]]/2 + \\n[.i])
212 . nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]] + \\n[.i])
214 . tmc \\n[.F]:\\n[.c]: Invalid horizontal table alignment '\\*[tal]':
215 . tm1 " must be 'l', 'c' or 'r'.
218 . nr t*r#\\n[t*#] 0 \" initialize row index
225 .\" CPTN: optional table caption
232 . if \\n[t*r#\\n[t*#]] \{\
233 . tmc \\n[.F]:\\n[.c]: Invalid placement of '.CPTN';
234 . tm1 " must be called immediately after '.TBL'.
239 . ds args\\n[t*#] "\\*[args]\"
241 . t*index "\\*[args]" .TR
242 . ie \\n[t*index] \{\
243 . ds *a\\n[t*#] "\\*[args]\"
244 . substring args\\n[t*#] 0 \\n[t*index]
245 . substring *a\\n[t*#] \\n[t*index]-2 -1
250 . ie "\\*[val]"b" \{\
252 . *CPTN \\*[args\\n[t*#]]
257 . ll (\\n[ll\\n[t*#]]u + \\n[in\\n[t*#]]u)
258 . in \\n[in\\n[t*#]]u
261 . t*P1 \\*[args\\n[t*#]]
267 . t*P1 \\*[*a\\n[t*#]]
274 .\" predecessor: TBL, CPTN, text, TD or ETB
279 . tm \\n[.F]:\\n[.c]: Table row (.TR) without preceding table start (.TBL).
283 . \" finish previous data cell, if any
284 . if \\n[t*r#\\n[t*#]] \
285 . t*dntr 1 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*]
287 . nr t*r#\\n[t*#] +1 \" row number in this table
288 . ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" table row identifier
290 . nr c#\\*[#t#r] 0 1 \" clear cell counter
291 . nr dntr\\*[#t#r] 0 1 \" clear accumulated row height
293 . t*getarg height \\$@
294 . ie "\\*[height]"" \
295 . nr t*height\\*[#t#r] 0
297 . ie \B
\a\\*[height]
\a \
298 . nr t*height\\*[#t#r] \\*[height]
300 . tm \\n[.F]:\\n[.c]: Invalid table row height '\\*[height]'.
303 . \" If there is a TR with height 'height', the total height of the table
304 . \" is too high by 3/2 b, independent of the number of TR with 'height'.
305 . t*args \\*[#t#r] \\n[t*#] \" look for common arguments
311 .\" TH: optional table header cell
312 .\" predecessor: text, TD or TR
313 .\" successor: text, TD, TR, TBL or ETB
315 .\" cell content bolded and horizontally and vertically centered,
323 . t*getarg val \\*[args]
327 . t*getarg fst \\*[args]
331 . TD hal=\\*[hal] val=\\*[val] fst=\\*[fst] \\*[args]
335 .\" TD: table data cell
336 .\" predecessor: text, TD or TR
337 .\" successor: text, TD, TR, TBL or ETB
340 . \" finish previous data cell -- note the use of \E
341 . t*dntr 0 \\n[c#\\*[#t#r]]-1 \En[c#\\*[#t#r]] \\*[*#trc*]
343 . ds *#trc* \\*[#t#r]*\\n[c#\\*[#t#r]]\" table cell identifier
344 . \" (<level>*<row>*<column>)
346 . t*getarg rowspan \\$@
348 . if !"\\*[rowspan]"" \{\
349 . ie \B
\a\\*[rowspan]
\a \{\
350 . nr rowspan (\\*[rowspan] >? 1)
351 . nr *rsp*\\*[*#trc*] (\\n[rowspan] - 1)
354 . tm \\n[.F]:\\n[.c]: Invalid value of 'rowspan' keyword.
357 . t*getarg colspan \\*[args]
359 . if !"\\*[colspan]"" \{\
360 . ie \B
\a\\*[colspan]
\a \
361 . nr colspan (\\*[colspan] >? 1)
363 . tm \\n[.F]:\\n[.c]: Invalid value of 'colspan' keyword.
366 . t*args \\*[#trc] \\*[#t#r] \" look for common arguments
368 . nr in\\*[#trc] \\n[in\\n[t*#]*\\n[c#\\*[#t#r]]]
369 . nr *cl \\n[cll\\n[t*#]*\\n[c#\\*[#t#r]]]
371 . nr *r \\n[t*r#\\n[t*#]]
373 . if (\\n[rowspan] - 1) \
374 . while (\\n+[*] <= \\n[rowspan]) \{\
375 . nr rspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan]
377 . nr cspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan]
382 . nr *c \\n[c#\\*[#t#r]]
384 . if (\\n[colspan] - 1) \{\
385 . nr vline\\*[*#trc*] 0-1 \" set 'no vl' flag
387 . while (\\n+[*] <= \\n[colspan]) \{\
389 . nr *cl +(2 * \\n[cscp\\n[t*#]] \
391 + \\n[cll\\n[t*#]*\\n[*c]])
396 . if (\\n[c#\\n[t*#]*\\n[t*r#\\n[t*#]]] > \\n[t*cols\\n[t*#]]) \{\
399 . if (\\n[c#\\*[#t#r]] == 1) \{\
403 . tmc \\n[.F]:\\n[.c]: There \\*[*] \\n[c#\\*[#t#r]] table \\*[**] (.TD)
406 . if (\\n[t*cols\\n[t*#]] == 1) \
408 . tm1 " but only \\n[t*cols\\n[t*#]] \\*[*] expected.
411 . length * \\n[.F]:\\n[.c]:
416 . tm1 "\\*[*] Remaining .TDs and its contents are ignored.
418 . di *t*dummy* \" bypass superfluous input
422 . di t*\\*[#trc] \" open cell diversion and set locals
424 . nr cll\\*[#trc] \\n[*cl]
426 . nr *cl\\n[t*#] \\n[.l]
427 . gcolor \\*[t*fgc\\*[#trc]]
428 . ad \\*[t*hal\\*[#trc]]
429 . fam \\*[t*ff\\*[#trc]]
430 . ft \\*[t*fst\\*[#trc]]
431 . t*pv \\*[t*fsz\\*[#trc]]
437 .\" ETB: end of table
438 .\" predecessor: text, TD or ETB
439 .\" successor: text, TD, TR or TBL
442 . if !\\n[t*r#\\n[t*#]] \{\
443 . tmc \\n[.F]:\\n[.c]: Each table (.TBL)
444 . tm1 " should contain at least one table row (.TR)!
447 . tmc \\n[.F]:\\n[.c]: Table end (.ETB)
448 . tm1 " without corresponding table start (.TBL)!
451 . ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier
452 . t*dntr 2 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*]
454 . t*divs \" print this table
456 . sp \\n[b/2\\n[t*#]]u
460 . ll \\n[*cl\\n[t*#]]u \" restore ll outside this table
461 . in 0 \" reset indent
462 . gcolor \\*[t*m\\n[t*#]] \" reset previous fgc
469 . ie "\\*[hold]"" \{\
470 . ie (\\n[.t] - \\n[dn]) \
473 . rn t*tbl0 t*tbl\\n+[t*numb]
474 . ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[dn]\"
478 . rn t*tbl0 t*hold\\n+[t*numb]
479 . tm \\n[.F]:\\n[.c]: Table t*hold\\n[t*numb] held.
480 . ds t*held \\*[t*held] t*hold\\n[t*numb] \\n[dn]\"
483 . ev \" restore previous environment
490 .\" *****************************************************************
491 .\" * Following the definition of five utility macros *
492 .\" * special to hdtbl. *
493 .\" * Other utility macros common to hdtbl and hdgroff *
494 .\" * are defined in the file hdmisc.tmac. *
495 .\" *****************************************************************
499 .\" print the next [n] held table[s].
500 .\" Don't call it within a table!
501 .\" If the table is higher than the remaining space
502 .\" on the page, the table is printed on the next page.
505 . if \\n[t*r#\\n[t*#]] \{\
506 . tmc \\n[.F]:\\n[.c]: Invalid placement of '.t*free' within a table;
507 . tm1 " it must be called outside of any table.
511 . if "\\*[t*held]"" \{\
512 . tm \\n[.F]:\\n[.c]: No held tables.
516 . nr ** (\\$1 >? 1) 1
517 . while !""\\*[t*held]" \{\
521 . ie (\\n[.t] - \\n[*]) \{\
527 . rn \\*[*] t*tbl\\n+[t*numb]
528 . ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[*]\"
531 . if !(\\n-[**] - 1) \
537 .\" The main utility macro for tables:
538 .\" If a table is closed by ETB, this macro is called. It
539 .\" processes one complete table, i.e., all the table cell
540 .\" diversions, paints the cell backgrounds, draws
541 .\" horizontal and vertical table lines and the table border.
543 .\" Nested tables are processed from inside to outside.
546 . ll (\\n[t*l]u + 1c) \" avoid warning 'can't break line'
549 . nr b/2 \\n[b/2\\n[t*#]] \" some abbreviations
550 . nr cscp \\n[cscp\\n[t*#]]
551 . nr cscpb (\\n[b/2] + \\n[cscp])
553 . nr topdiv (\\n[.d] + \\n[b/2] - \\n[cscp])\" top of cell diversion
554 . nr cscpb2 (\\n[b/2] / 2 + \\n[cscp])
557 . \" outer loop for rows
558 . while (\\n+[#r] <= \\n[t*r#\\n[t*#]]) \{\
559 . \" TODO: insert code here for multipage tables
561 . nr topdiv +(\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb])
563 . \" if table still smaller than specified table height, increase it
564 . if ((\\n[#r] == \\n[t*r#\\n[t*#]]) & \\n[t*height\\n[t*#]]) \
565 . nr dntr\\n[t*#]*\\n[#r] (\\n[cscpb] \
566 + \\n[toptbl\\n[t*#]] \
567 + \\n[t*height\\n[t*#]] \
568 - (\\n[topdiv] >? \\n[dntr\\n[t*#]*\\n[#r]]))
571 . \" inner loop for cells
572 . while (\\n+[#c] <= \\n[t*cols\\n[t*#]]) \{\
573 . ds #trc \\n[t*#]*\\n[#r]*\\n[#c]\"
574 . \" continue if the diversion is empty
575 . if !d t*\\*[#trc] \
579 . in (\\n[in\\n[t*#]]u + \\n[in\\*[#trc]]u)\" cell offset
580 . nr $1 \\n[dntr\\n[t*#]*\\n[#r]] \" cell height
582 . \" if we have spanned rows, calculate resulting row height
583 . \" and position of lower horizontal line
584 . if \\n[*rsp*\\*[#trc]] \{\
586 . nr rspan\\*[#trc] 0-1 \" set 'no hl' flag
587 . nr corr (\\n[dn\\*[#trc]] - \\n[dntr\\n[t*#]*\\n[#r]])
589 . \" clear row span flags in following rows and update row height
590 . while \\n[*rsp*\\*[#trc]] \{\
591 . nr *rsp*\\*[#trc] -1
592 . nr rspan\\n[t*#]*\\n+[*]*\\n[#c] 0
593 . nr ** (\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb])
598 . if (\\n-[*] == \\n[t*r#\\n[t*#]]) \
599 . nr $1 ((\\n[t*height\\n[t*#]] \
601 + \\n[toptbl\\n[t*#]] \
604 . nr dntr\\n[t*#]*\\n[*] +(\\n[corr] >? 0)
607 . \" paint cell background
608 . nr * (2 * \\n[t*cpd\\n[t*#]] + \\n[cll\\*[#trc]])\" background width
609 . nr $1 (\\n[$1] >? \\n[dn\\*[#trc]])\" cell height
611 . if !"\\*[t*bgc\\*[#trc]]"=" \{\
612 . nop \h'\\n[t*csp\\n[t*#]]u'\
613 \M[\\*[t*bgc\\*[#trc]]]\
614 \v'(-.67v - \\n[t*cpd\\n[t*#]]u)'\
616 0 (2u * \\n[t*cpd\\n[t*#]]u + \\n[$1]u) \
622 . \" *** horizontal and vertical single or double lines ***
623 . \" double and single lines have the same thickness;
624 . \" the double lines' distance is the line thickness.
626 . \" 'border=x': horizontal/vertical lines x/2 thick, minimum .1n
627 . \" 'border=0': no border; horizontal/vertical lines .1n thick
628 . \" 'border=': neither border nor horizontal/vertical lines
630 . nr *t (.1n >? \\n[b/2]) \" thickness of hl/vl; min. .1n
633 . \" check for vertical and horizontal lines
634 . if (1 + \\n[t*b\\n[t*#]]) \{\
635 . if !"\\*[t*bc\\n[t*#]]"=" \{\
636 . \" draw horizontal line between this cell and the one below
637 . if (\\n[t*r#\\n[t*#]] - \\n[#r] + \\n[rspan\\*[#trc]]) \{\
638 . if !"\\*[t*hl\\*[#trc]]"=" \{\
640 . nr * (\\n[cscp] + \\n[cscpb] + \\n[cll\\*[#trc]])
641 . nop \X'\*[g] 1 setlinecap'\
642 \h'(-\\n[cscpb2]u - \\n[*t]u)'\
643 \v'(\\n[cscpb2]u - .67v)'\
644 \m[\\*[t*bc\\n[t*#]]]\
647 . ie "\\*[t*hl\\*[#trc]]"d" \
654 . nop \D'l \\n[*]u 0'\
657 . sp (-\\n[$1]u - 1v)
660 . nr rspan\\*[#trc] 0
662 . \" draw vertical line between this cell and the one to the right
663 . if (\\n[t*cols\\n[t*#]] - \\n[#c] + \\n[vline\\*[#trc]]) \{\
664 . if !"\\*[t*vl\\*[#trc]]"=" \{\
665 . nop \X'\*[g] 1 setlinecap'\
666 \v'(-\\n[cscpb2]u - .67v)'\
667 \m[\\*[t*bc\\n[t*#]]]\
668 \h'(\\n[cscpb2]u - \\n[*t]u + \\n[cll\\*[#trc]]u)'\c
670 . ie "\\*[t*vl\\*[#trc]]"d" \
673 \D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\
675 \D'l 0 -(2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\
678 . nop \D't \\n[*t]u'\
679 \D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\
684 . nr vline\\*[#trc] 0
686 . \" vert. cell content alignment
689 . ie "\\*[t*val\\*[#trc]]"m" \
690 . nr ** ((\\n[$1] - \\n[dn\\*[#trc]]) / 2)\" val=m
692 . if "\\*[t*val\\*[#trc]]"b" \
693 . nr ** (\\n[$1] - \\n[dn\\*[#trc]])\" val=b
695 . sp \\n[**]u \" vertical content position
697 . \" finally output the diversion
703 . \" draw the box border
704 . in \\n[in\\n[t*#]]u
705 . nr ** (\\n[topdiv] + \\n[dntr\\n[t*#]*\\n-[#r]])
707 . if \\n[t*b\\n[t*#]] \{\
708 . sp |(\\n[toptbl\\n[t*#]]u + \\n[b/2]u)
709 . nr $1 (\\n[toptbl\\n[t*#]] - \\n[**] - \\n[cscp])
710 . nr * (\\n[ll\\n[t*#]] - \\n[t*b\\n[t*#]])
712 . if !"\\*[t*bc\\n[t*#]]"=" \
713 . nop \X'\*[g] 0 setlinejoin 2 setlinecap'\
716 \m[\\*[t*bc\\n[t*#]]]\
717 \D't \\n[t*b\\n[t*#]]u'\
725 . sp |(\\n[**]u + \\n[cscpb]u)
730 .\" Utility macro: .t*cl [width1 [width2 [...]]]
732 .\" Calculate cell widths, table width, and cell offsets.
734 . nr t*cols\\n[t*#] (\\n[.$] >? \\n[t*cols\\n[t*#]])
735 . nr ll\\n[t*#] 0 \" accumulated cell widths
736 . nr ** (\\n[.l] / \\n[t*cols\\n[t*#]])\" width for remaining cells
737 . nr * 0 1 \" counter
739 . \" while-loop: Parse user arguments to get each cell's width.
740 . while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\
742 . if !"\\$[\\n[*]]"" \{\
743 . \" check for '%' pseudo scaling indicator
747 . ds ** \\$[\\n[*]]\"
750 . nr $\\n[*] (\\*[**] * \\n[.l] / 100)
752 . tm \\n[.F]:\\n[.c]: Invalid relative cell width '\\*[**]%'.
755 . ie \B
\a\\$[\\n[*]]
\a \
756 . nr $\\n[*] \\$[\\n[*]]
758 . tm \\n[.F]:\\n[.c]: Invalid cell width '\\$[\\n[*]]'.
761 . nr ll\\n[t*#] +\\n[$\\n[*]]
765 . if (\\n[ll\\n[t*#]] > \\n[.l]) \
766 . tm \\n[.F]:\\n[.c]: Table width larger than column width.
768 . nr ** (0 >? \\n[t*b\\n[t*#]])
771 . \" second while loop: Compute final cell widths.
772 . while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\
773 . \" Remove border width, if any.
774 . if \\n[t*b\\n[t*#]] \{\
775 . \" cell_width := cell_width * (length - 1.5*border) / length
776 . nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2))
777 . nr *** (\\n[ll\\n[t*#]] / 2)
778 . \" avoid multiplication overflow
779 . mult31by31 $\\n[*] #* ****
780 . add31to62 *** **** ****
781 . div62by31 **** ll\\n[t*#] $\\n[*]
784 . \" Get cell widths without padding, spacing, and separator line.
785 . nr cll\\n[t*#]*\\n[*] (\\n[$\\n[*]] \
786 - (2 * \\n[cscp\\n[t*#]]) \
789 . \" Check whether value is non-positive.
790 . if !\\n[cll\\n[t*#]*\\n[*]] \{\
791 . nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2))
792 . nr *** (\\n[#*] / 2)
793 . nr *h (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]])
794 . mult31by31 *h ll\\n[t*#] ****
795 . add31to62 *** **** ****
796 . div62by31 **** #* *h
798 . nr *** (\\n[*] % 10)
799 . if d nth-\\n[***] \
800 . ds * \\n[*]\\*[nth-\\n[***]]\"
801 . tmc \\n[.F]:\\n[.c]: The \\*[*] width value (\\$\\n[*]) is too small.
802 . tm1 " It should be greater than \\n[*h].
805 . nr in\\n[t*#]*\\n[*] \\n[**] \" cell offset
806 . nr ** +\\n[$\\n[*]]
811 .\" Utility macro: .t*dntr <origin> <cell position> ? <cell ID>
813 .\" Close TD diversion, make some calculations, and set
814 .\" some help strings and registers. <origin> is 0, 1,
815 .\" or 2 if the call of .t*dntr occurs in .TD, .TR, or
816 .\" .ETB, respectively.
818 . nr dn 0 \" reset diversion height
819 . br \" finish cell data
821 . if "\\n[.z]"*t*dummy*" \
824 . ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier
826 . if \\n[c#\\*[#t#r]] \{\
827 . di \" close diversion
828 . nr dn\\$4 \\n[dn] \" save height of this cell
829 . if !\\n[rspan\\*[#trc]] \{\
830 . \" update row height if not in a row span
831 . nr dntr\\*[#t#r] (\\n[dntr\\*[#t#r]] >? \\n[dn])
833 . nr dntr\\*[#t#r] ((\\n[t*height\\*[#t#r]] \
834 - (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]])) \
835 >? \\n[dntr\\*[#t#r]])
841 . \" update column span registers
842 . while (\\n+[*] <= \\$3) \{\
843 . if r cspan\\*[#t#r]*\\n[*] \
844 . nr c#\\*[#t#r] +\\n[cspan\\*[#t#r]*\\n[*]]
845 . nr cspan\\*[#t#r]*\\n[*] 0
848 . ds #trc \\*[#t#r]*\\n[c#\\*[#t#r]]\"
850 . \" only check for cell underflow if called by .TR or .ETB
851 . if (\\$1 & (\\n[c#\\*[#t#r]] <= \\n[t*cols\\n[t*#]])) \{\
854 . if (\\n-[c#\\*[#t#r]] == 1) \{\
858 . tmc \\n[.F]:\\n[.c]: There \\*[*] only \\n[c#\\*[#t#r]] \\*[**]
860 . nr * \\n[t*r#\\n[t*#]]
862 . nr *** (\\n[*] % 10)
863 . if d nth-\\n[***] \
864 . ds * \\n[*]\\*[nth-\\n[***]]\"
865 . tmc " in the \\*[*] row
868 . if (\\n[t*cols\\n[t*#]] == 1) \
870 . tm1 " but \\n[t*cols\\n[t*#]] \\*[*] expected.
875 .\" Utility-macro: .t*args level_1 [level_2]
877 .\" Get the arguments common to TBL, TR, and TD for the level
878 .\" in argument 1, using default values from the level in
879 .\" argument 2. If argument 2 is missing, use the global
883 . ds t*bgc\\$1 \\*[t*bgc\\$2]\"
884 . ds t*fgc\\$1 \\*[t*fgc\\$2]\"
885 . ds t*hl\\$1 \\*[t*hl\\$2]\"
886 . ds t*vl\\$1 \\*[t*vl\\$2]\"
887 . ds t*hal\\$1 \\*[t*hal\\$2]\"
888 . ds t*val\\$1 \\*[t*val\\$2]\"
889 . ds t*ff\\$1 \\*[t*ff\\$2]\"
890 . ds t*fst\\$1 \\*[t*fst\\$2]\"
891 . ds t*fsz\\$1 \\*[t*fsz\\$2]\"
896 . t*getarg bgc \\*[args] \" background color
897 . if !"\\*[bgc]"" \{\
899 . ds t*bgc\\$1 \\*[bgc]\"
904 . tm \\n[.F]:\\n[.c]: Invalid background color '\\*[bgc]'.
909 . t*getarg fgc \\*[args] \" foreground color
910 . if !"\\*[fgc]"" \{\
912 . ds t*fgc\\$1 \\*[fgc]\"
917 . tm \\n[.F]:\\n[.c]: Invalid foreground color '\\*[fgc]'.
922 . t*getarg hl \\*[args] \" horizontal line between cells
924 . ds t*hl\\$1 \\*[hl]\"
928 . t*getarg vl \\*[args] \" vertical line between cells
930 . ds t*vl\\$1 \\*[vl]\"
934 . t*getarg hal \\*[args] \" horizontal table cell alignment
935 . if !"\\*[hal]"" \{\
936 . t*index bcrl \\*[hal]
938 . ds t*hal\\$1 \\*[hal]\"
940 . tmc \\n[.F]:\\n[.c]: Invalid horizontal alignment '\\*[hal]':
941 . tm1 " must be 'b', 'c', 'l' or 'r'.
946 . t*getarg val \\*[args] \" vertical table cell alignment
947 . if !"\\*[val]"" \{\
948 . t*index tmb \\*[val]
950 . ds t*val\\$1 \\*[val]\"
952 . tmc \\n[.F]:\\n[.c]: Invalid vertical alignment '\\*[val]':
953 . tm1 " must be 't', 'm' or 'b'.
958 . t*getarg ff \\*[args] \" font family
960 . ds t*ff\\$1 \\*[ff]\"
964 . t*getarg fst \\*[args] \" font style
966 . ds t*fst\\$1 \\*[fst]\"
970 . t*getarg fsz \\*[args] \" font size and spacing factor
972 . ds t*fsz\\$1 \\*[fsz]\"
976 .\" Append to your page header macro ('pg@top' for MS)
977 .\" to enable tables to span pages.
981 . while !""\\*[t*kept]" \{\
984 . if (\\n[*] - \\n[**]) \{\
985 . tm \\n[.F]:\\n[.c]: Table \\*[*] higher than page -- ignored!
989 . if (\\n[*] - \\n[.t]) \{\
990 . ds t*kept \\n[*] \\*[t*kept]\"
991 . ds t*kept \\*[*] \\*[t*kept]\"
992 . tmc \\n[.F]:\\n[.c]: Remaining table(s),
993 . tm1 " because not all fit onto this page.
1002 .\" Local Variables:
1005 .\" vim: filetype=groff: