6 This file is part of groff, the GNU roff type-setting system.
8 Copyright (C) 2005-2014 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 .\" *****************************************************************
39 .\" *****************************************************************
40 .\" * default values for some arguments *
41 .\" *****************************************************************
64 .\" defaults for table captions
66 .ds t*cptn "".sp .4" \
69 "\m[\\*[t*fgc]]Table \\n+[t*cptn]:\0\c\k*"\"
74 .\" for better error messages
79 .\" initialization of various registers
80 .nr t*# 0 \" table nesting level
81 .nr t*numb 0 1 \" held table diversion #
86 .\" *****************************************************************
87 .\" * The four base macros and the two optional macros *
88 .\" *****************************************************************
96 .\" predecessor: text, TD or ETB
97 .\" successor: CPTN or TR
99 . ds t*m\\n[t*#] \\n[.m]\"
107 . sp .4 \" XXX: hard-coded value
114 . \" Save current location for error checking at end
118 . t*getarg cols \\$@\" from here string `args' contains the rest of \\$@
120 . nr t*cols\\n[t*#] \\n[t*cols]
122 . ie \B
\a\\*[cols]
\a \
123 . nr t*cols\\n[t*#] \\*[cols]
125 . tm \\n[.F]:\\n[.c]: Invalid number of columns value `\\*[cols]'.
128 . t*getarg cpd \\*[args] \" cell padding
130 . nr t*cpd\\n[t*#] \\n[t*cpd]
132 . ie \B
\a\\*[cpd]
\a \
133 . nr t*cpd\\n[t*#] \\*[cpd]
135 . tm \\n[.F]:\\n[.c]: Invalid cell padding value `\\*[cpd]'.
138 . t*getarg csp \\*[args] \" cell spacing
140 . nr t*csp\\n[t*#] \\n[t*csp]
142 . ie \B
\a\\*[csp]
\a \
143 . nr t*csp\\n[t*#] \\*[csp]
145 . tm \\n[.F]:\\n[.c]: Invalid cell spacing value `\\*[csp]'.
148 . t*getarg border \\*[args] \" border thickness
149 . ie "\\*[border]"=" \
152 . ie "\\*[border]"" \
153 . nr t*b\\n[t*#] \\n[t*b]
155 . ie \B
\a\\*[border]
\a \
156 . nr t*b\\n[t*#] \\*[border]
158 . tm \\n[.F]:\\n[.c]: Invalid border thickness value `\\*[border]'.
161 . t*getarg bc \\*[args] \" border color
162 . ds t*bc\\n[t*#] \\*[t*bc]\"
165 . ds t*bc\\n[t*#] \\*[bc]\"
168 . ds t*bc\\n[t*#] =\"
170 . tm \\n[.F]:\\n[.c]: Invalid border color `\\*[bc]'.
176 . ds t*bc\\n[t*#] \\*[t*bc]\"
178 . ds t*bc\\n[t*#] \\*[bc]\"
181 . t*getarg width \\*[args] \" table/col widths
182 . if "\\*[width]"=" \
185 . nr b/2\\n[t*#] (\\n[t*b\\n[t*#]] / 2)\" shortcut
186 . nr cscp\\n[t*#] (\\n[t*csp\\n[t*#]] + \\n[t*cpd\\n[t*#]])\" aux. register
188 . t*getarg height \\*[args] \" table outline height
189 . ie "\\*[height]"" \
190 . nr t*height\\n[t*#] 0
192 . ie \B
\a\\*[height]
\a \
193 . nr t*height\\n[t*#] (\\*[height] \
194 - ((2 * \\n[cscp\\n[t*#]]) \
195 + (3 * \\n[b/2\\n[t*#]])))
197 . tm \\n[.F]:\\n[.c]: Invalid height value `\\*[height]'.
200 . t*cl \\*[width] \" get cell widths and offsets
201 . t*args \\n[t*#] \" look for common arguments
203 . t*getarg tal \\*[args] \" table horizontal alignment
205 . ds tal \\*[t*tal]\"
207 . nr in\\n[t*#] \\n[.i]
210 . nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]]/2 + \\n[.i])
213 . nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]] + \\n[.i])
215 . tmc \\n[.F]:\\n[.c]: Invalid horizontal table alignment `\\*[tal]':
216 . tm1 " must be `l', `c' or `r'.
219 . nr t*r#\\n[t*#] 0 \" initialize row index
226 .\" CPTN: optional table caption
233 . if \\n[t*r#\\n[t*#]] \{\
234 . tmc \\n[.F]:\\n[.c]: Invalid placement of `.CPTN';
235 . tm1 " must be called immediately after `.TBL'.
240 . ds args\\n[t*#] "\\*[args]\"
242 . t*index "\\*[args]" .TR
243 . ie \\n[t*index] \{\
244 . ds *a\\n[t*#] "\\*[args]\"
245 . substring args\\n[t*#] 0 \\n[t*index]
246 . substring *a\\n[t*#] \\n[t*index]-2 -1
251 . ie "\\*[val]"b" \{\
253 . *CPTN \\*[args\\n[t*#]]
258 . ll (\\n[ll\\n[t*#]]u + \\n[in\\n[t*#]]u)
259 . in \\n[in\\n[t*#]]u
262 . t*P1 \\*[args\\n[t*#]]
268 . t*P1 \\*[*a\\n[t*#]]
275 .\" predecessor: TBL, CPTN, text, TD or ETB
280 . tm \\n[.F]:\\n[.c]: Table row (.TR) without preceding table start (.TBL).
284 . \" finish previous data cell, if any
285 . if \\n[t*r#\\n[t*#]] \
286 . t*dntr 1 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*]
288 . nr t*r#\\n[t*#] +1 \" row number in this table
289 . ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" table row identifier
291 . nr c#\\*[#t#r] 0 1 \" clear cell counter
292 . nr dntr\\*[#t#r] 0 1 \" clear accumulated row height
294 . t*getarg height \\$@
295 . ie "\\*[height]"" \
296 . nr t*height\\*[#t#r] 0
298 . ie \B
\a\\*[height]
\a \
299 . nr t*height\\*[#t#r] \\*[height]
301 . tm \\n[.F]:\\n[.c]: Invalid table row height `\\*[height]'.
304 . \" If there is a TR with height `height', the total height of the table
305 . \" is too high by 3/2 b, independent of the number of TR with `height'.
306 . t*args \\*[#t#r] \\n[t*#] \" look for common arguments
312 .\" TH: optional table header cell
313 .\" predecessor: text, TD or TR
314 .\" successor: text, TD, TR, TBL or ETB
316 .\" cell content bolded and horizontally and vertically centered,
324 . t*getarg val \\*[args]
328 . t*getarg fst \\*[args]
332 . TD hal=\\*[hal] val=\\*[val] fst=\\*[fst] \\*[args]
336 .\" TD: table data cell
337 .\" predecessor: text, TD or TR
338 .\" successor: text, TD, TR, TBL or ETB
341 . \" finish previous data cell -- note the use of \E
342 . t*dntr 0 \\n[c#\\*[#t#r]]-1 \En[c#\\*[#t#r]] \\*[*#trc*]
344 . ds *#trc* \\*[#t#r]*\\n[c#\\*[#t#r]]\" table cell identifier
345 . \" (<level>*<row>*<column>)
347 . t*getarg rowspan \\$@
349 . if !"\\*[rowspan]"" \{\
350 . ie \B
\a\\*[rowspan]
\a \{\
351 . nr rowspan (\\*[rowspan] >? 1)
352 . nr *rsp*\\*[*#trc*] (\\n[rowspan] - 1)
355 . tm \\n[.F]:\\n[.c]: Invalid value of `rowspan' keyword.
358 . t*getarg colspan \\*[args]
360 . if !"\\*[colspan]"" \{\
361 . ie \B
\a\\*[colspan]
\a \
362 . nr colspan (\\*[colspan] >? 1)
364 . tm \\n[.F]:\\n[.c]: Invalid value of `colspan' keyword.
367 . t*args \\*[#trc] \\*[#t#r] \" look for common arguments
369 . nr in\\*[#trc] \\n[in\\n[t*#]*\\n[c#\\*[#t#r]]]
370 . nr *cl \\n[cll\\n[t*#]*\\n[c#\\*[#t#r]]]
372 . nr *r \\n[t*r#\\n[t*#]]
374 . if (\\n[rowspan] - 1) \
375 . while (\\n+[*] <= \\n[rowspan]) \{\
376 . nr rspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan]
378 . nr cspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan]
383 . nr *c \\n[c#\\*[#t#r]]
385 . if (\\n[colspan] - 1) \{\
386 . nr vline\\*[*#trc*] 0-1 \" set `no vl' flag
388 . while (\\n+[*] <= \\n[colspan]) \{\
390 . nr *cl +(2 * \\n[cscp\\n[t*#]] \
392 + \\n[cll\\n[t*#]*\\n[*c]])
397 . if (\\n[c#\\n[t*#]*\\n[t*r#\\n[t*#]]] > \\n[t*cols\\n[t*#]]) \{\
400 . if (\\n[c#\\*[#t#r]] == 1) \{\
404 . tmc \\n[.F]:\\n[.c]: There \\*[*] \\n[c#\\*[#t#r]] table \\*[**] (.TD)
407 . if (\\n[t*cols\\n[t*#]] == 1) \
409 . tm1 " but only \\n[t*cols\\n[t*#]] \\*[*] expected.
412 . length * \\n[.F]:\\n[.c]:
417 . tm1 "\\*[*] Remaining .TDs and its contents are ignored.
419 . di *t*dummy* \" bypass superfluous input
423 . di t*\\*[#trc] \" open cell diversion and set locals
425 . nr cll\\*[#trc] \\n[*cl]
427 . nr *cl\\n[t*#] \\n[.l]
428 . gcolor \\*[t*fgc\\*[#trc]]
429 . ad \\*[t*hal\\*[#trc]]
430 . fam \\*[t*ff\\*[#trc]]
431 . ft \\*[t*fst\\*[#trc]]
432 . t*pv \\*[t*fsz\\*[#trc]]
438 .\" ETB: end of table
439 .\" predecessor: text, TD or ETB
440 .\" successor: text, TD, TR or TBL
443 . if !\\n[t*r#\\n[t*#]] \{\
444 . tmc \\n[.F]:\\n[.c]: Each table (.TBL)
445 . tm1 " should contain at least one table row (.TR)!
448 . tmc \\n[.F]:\\n[.c]: Table end (.ETB)
449 . tm1 " without corresponding table start (.TBL)!
452 . ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier
453 . t*dntr 2 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*]
455 . t*divs \" print this table
457 . sp \\n[b/2\\n[t*#]]u
461 . ll \\n[*cl\\n[t*#]]u \" restore ll outside this table
462 . in 0 \" reset indent
463 . gcolor \\*[t*m\\n[t*#]] \" reset previous fgc
470 . ie "\\*[hold]"" \{\
471 . ie (\\n[.t] - \\n[dn]) \
474 . rn t*tbl0 t*tbl\\n+[t*numb]
475 . ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[dn]\"
479 . rn t*tbl0 t*hold\\n+[t*numb]
480 . tm \\n[.F]:\\n[.c]: Table t*hold\\n[t*numb] held.
481 . ds t*held \\*[t*held] t*hold\\n[t*numb] \\n[dn]\"
484 . ev \" restore previous environment
491 .\" *****************************************************************
492 .\" * Following the definition of five utility macros *
493 .\" * special to hdtbl. *
494 .\" * Other utility macros common to hdtbl and hdgroff *
495 .\" * are defined in the file hdmisc.tmac. *
496 .\" *****************************************************************
500 .\" print the next [n] held table[s].
501 .\" Don't call it within a table!
502 .\" If the table is higher than the remaining space
503 .\" on the page, the table is printed on the next page.
506 . if \\n[t*r#\\n[t*#]] \{\
507 . tmc \\n[.F]:\\n[.c]: Invalid placement of `.t*free' within a table;
508 . tm1 " it must be called outside of any table.
512 . if "\\*[t*held]"" \{\
513 . tm \\n[.F]:\\n[.c]: No held tables.
517 . nr ** (\\$1 >? 1) 1
518 . while !""\\*[t*held]" \{\
522 . ie (\\n[.t] - \\n[*]) \{\
528 . rn \\*[*] t*tbl\\n+[t*numb]
529 . ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[*]\"
532 . if !(\\n-[**] - 1) \
538 .\" The main utility macro for tables:
539 .\" If a table is closed by ETB, this macro is called. It
540 .\" processes one complete table, i.e., all the table cell
541 .\" diversions, paints the cell backgrounds, draws
542 .\" horizontal and vertical table lines and the table border.
544 .\" Nested tables are processed from inside to outside.
547 . ll (\\n[t*l]u + 1c) \" avoid warning `can't break line'
550 . nr b/2 \\n[b/2\\n[t*#]] \" some abbreviations
551 . nr cscp \\n[cscp\\n[t*#]]
552 . nr cscpb (\\n[b/2] + \\n[cscp])
554 . nr topdiv (\\n[.d] + \\n[b/2] - \\n[cscp])\" top of cell diversion
555 . nr cscpb2 (\\n[b/2] / 2 + \\n[cscp])
558 . \" outer loop for rows
559 . while (\\n+[#r] <= \\n[t*r#\\n[t*#]]) \{\
560 . \" TODO: insert code here for multipage tables
562 . nr topdiv +(\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb])
564 . \" if table still smaller than specified table height, increase it
565 . if ((\\n[#r] == \\n[t*r#\\n[t*#]]) & \\n[t*height\\n[t*#]]) \
566 . nr dntr\\n[t*#]*\\n[#r] (\\n[cscpb] \
567 + \\n[toptbl\\n[t*#]] \
568 + \\n[t*height\\n[t*#]] \
569 - (\\n[topdiv] >? \\n[dntr\\n[t*#]*\\n[#r]]))
572 . \" inner loop for cells
573 . while (\\n+[#c] <= \\n[t*cols\\n[t*#]]) \{\
574 . ds #trc \\n[t*#]*\\n[#r]*\\n[#c]\"
575 . \" continue if the diversion is empty
576 . if !d t*\\*[#trc] \
580 . in (\\n[in\\n[t*#]]u + \\n[in\\*[#trc]]u)\" cell offset
581 . nr $1 \\n[dntr\\n[t*#]*\\n[#r]] \" cell height
583 . \" if we have spanned rows, calculate resulting row height
584 . \" and position of lower horizontal line
585 . if \\n[*rsp*\\*[#trc]] \{\
587 . nr rspan\\*[#trc] 0-1 \" set `no hl' flag
588 . nr corr (\\n[dn\\*[#trc]] - \\n[dntr\\n[t*#]*\\n[#r]])
590 . \" clear row span flags in following rows and update row height
591 . while \\n[*rsp*\\*[#trc]] \{\
592 . nr *rsp*\\*[#trc] -1
593 . nr rspan\\n[t*#]*\\n+[*]*\\n[#c] 0
594 . nr ** (\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb])
599 . if (\\n-[*] == \\n[t*r#\\n[t*#]]) \
600 . nr $1 ((\\n[t*height\\n[t*#]] \
602 + \\n[toptbl\\n[t*#]] \
605 . nr dntr\\n[t*#]*\\n[*] +(\\n[corr] >? 0)
608 . \" paint cell background
609 . nr * (2 * \\n[t*cpd\\n[t*#]] + \\n[cll\\*[#trc]])\" background width
610 . nr $1 (\\n[$1] >? \\n[dn\\*[#trc]])\" cell height
612 . if !"\\*[t*bgc\\*[#trc]]"=" \{\
613 . nop \h'\\n[t*csp\\n[t*#]]u'\
614 \M[\\*[t*bgc\\*[#trc]]]\
615 \v'(-.67v - \\n[t*cpd\\n[t*#]]u)'\
617 0 (2u * \\n[t*cpd\\n[t*#]]u + \\n[$1]u) \
623 . \" *** horizontal and vertical single or double lines ***
624 . \" double and single lines have the same thickness;
625 . \" the double lines' distance is the line thickness.
627 . \" `border=x': horizontal/vertical lines x/2 thick, minimum .1n
628 . \" `border=0': no border; horizontal/vertical lines .1n thick
629 . \" `border=': neither border nor horizontal/vertical lines
631 . nr *t (.1n >? \\n[b/2]) \" thickness of hl/vl; min. .1n
634 . \" check for vertical and horizontal lines
635 . if (1 + \\n[t*b\\n[t*#]]) \{\
636 . if !"\\*[t*bc\\n[t*#]]"=" \{\
637 . \" draw horizontal line between this cell and the one below
638 . if (\\n[t*r#\\n[t*#]] - \\n[#r] + \\n[rspan\\*[#trc]]) \{\
639 . if !"\\*[t*hl\\*[#trc]]"=" \{\
641 . nr * (\\n[cscp] + \\n[cscpb] + \\n[cll\\*[#trc]])
642 . nop \X'\*[g] 1 setlinecap'\
643 \h'(-\\n[cscpb2]u - \\n[*t]u)'\
644 \v'(\\n[cscpb2]u - .67v)'\
645 \m[\\*[t*bc\\n[t*#]]]\
648 . ie "\\*[t*hl\\*[#trc]]"d" \
655 . nop \D'l \\n[*]u 0'\
658 . sp (-\\n[$1]u - 1v)
661 . nr rspan\\*[#trc] 0
663 . \" draw vertical line between this cell and the one to the right
664 . if (\\n[t*cols\\n[t*#]] - \\n[#c] + \\n[vline\\*[#trc]]) \{\
665 . if !"\\*[t*vl\\*[#trc]]"=" \{\
666 . nop \X'\*[g] 1 setlinecap'\
667 \v'(-\\n[cscpb2]u - .67v)'\
668 \m[\\*[t*bc\\n[t*#]]]\
669 \h'(\\n[cscpb2]u - \\n[*t]u + \\n[cll\\*[#trc]]u)'\c
671 . ie "\\*[t*vl\\*[#trc]]"d" \
674 \D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\
676 \D'l 0 -(2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\
679 . nop \D't \\n[*t]u'\
680 \D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\
685 . nr vline\\*[#trc] 0
687 . \" vert. cell content alignment
690 . ie "\\*[t*val\\*[#trc]]"m" \
691 . nr ** ((\\n[$1] - \\n[dn\\*[#trc]]) / 2)\" val=m
693 . if "\\*[t*val\\*[#trc]]"b" \
694 . nr ** (\\n[$1] - \\n[dn\\*[#trc]])\" val=b
696 . sp \\n[**]u \" vertical content position
698 . \" finally output the diversion
704 . \" draw the box border
705 . in \\n[in\\n[t*#]]u
706 . nr ** (\\n[topdiv] + \\n[dntr\\n[t*#]*\\n-[#r]])
708 . if \\n[t*b\\n[t*#]] \{\
709 . sp |(\\n[toptbl\\n[t*#]]u + \\n[b/2]u)
710 . nr $1 (\\n[toptbl\\n[t*#]] - \\n[**] - \\n[cscp])
711 . nr * (\\n[ll\\n[t*#]] - \\n[t*b\\n[t*#]])
713 . if !"\\*[t*bc\\n[t*#]]"=" \
714 . nop \X'\*[g] 0 setlinejoin 2 setlinecap'\
717 \m[\\*[t*bc\\n[t*#]]]\
718 \D't \\n[t*b\\n[t*#]]u'\
726 . sp |(\\n[**]u + \\n[cscpb]u)
731 .\" Utility macro: .t*cl [width1 [width2 [...]]]
733 .\" Calculate cell widths, table width, and cell offsets.
735 . nr t*cols\\n[t*#] (\\n[.$] >? \\n[t*cols\\n[t*#]])
736 . nr ll\\n[t*#] 0 \" accumulated cell widths
737 . nr ** (\\n[.l] / \\n[t*cols\\n[t*#]])\" width for remaining cells
738 . nr * 0 1 \" counter
740 . \" while-loop: Parse user arguments to get each cell's width.
741 . while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\
743 . if !"\\$[\\n[*]]"" \{\
744 . \" check for `%' pseudo scaling indicator
748 . ds ** \\$[\\n[*]]\"
751 . nr $\\n[*] (\\*[**] * \\n[.l] / 100)
753 . tm \\n[.F]:\\n[.c]: Invalid relative cell width `\\*[**]%'.
756 . ie \B
\a\\$[\\n[*]]
\a \
757 . nr $\\n[*] \\$[\\n[*]]
759 . tm \\n[.F]:\\n[.c]: Invalid cell width `\\$[\\n[*]]'.
762 . nr ll\\n[t*#] +\\n[$\\n[*]]
766 . if (\\n[ll\\n[t*#]] > \\n[.l]) \
767 . tm \\n[.F]:\\n[.c]: Table width larger than column width.
769 . nr ** (0 >? \\n[t*b\\n[t*#]])
772 . \" second while loop: Compute final cell widths.
773 . while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\
774 . \" Remove border width, if any.
775 . if \\n[t*b\\n[t*#]] \{\
776 . \" cell_width := cell_width * (length - 1.5*border) / length
777 . nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2))
778 . nr *** (\\n[ll\\n[t*#]] / 2)
779 . \" avoid multiplication overflow
780 . mult31by31 $\\n[*] #* ****
781 . add31to62 *** **** ****
782 . div62by31 **** ll\\n[t*#] $\\n[*]
785 . \" Get cell widths without padding, spacing, and separator line.
786 . nr cll\\n[t*#]*\\n[*] (\\n[$\\n[*]] \
787 - (2 * \\n[cscp\\n[t*#]]) \
790 . \" Check whether value is non-positive.
791 . if !\\n[cll\\n[t*#]*\\n[*]] \{\
792 . nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2))
793 . nr *** (\\n[#*] / 2)
794 . nr *h (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]])
795 . mult31by31 *h ll\\n[t*#] ****
796 . add31to62 *** **** ****
797 . div62by31 **** #* *h
799 . nr *** (\\n[*] % 10)
800 . if d nth-\\n[***] \
801 . ds * \\n[*]\\*[nth-\\n[***]]\"
802 . tmc \\n[.F]:\\n[.c]: The \\*[*] width value (\\$\\n[*]) is too small.
803 . tm1 " It should be greater than \\n[*h].
806 . nr in\\n[t*#]*\\n[*] \\n[**] \" cell offset
807 . nr ** +\\n[$\\n[*]]
812 .\" Utility macro: .t*dntr <origin> <cell position> ? <cell ID>
814 .\" Close TD diversion, make some calculations, and set
815 .\" some help strings and registers. <origin> is 0, 1,
816 .\" or 2 if the call of .t*dntr occurs in .TD, .TR, or
817 .\" .ETB, respectively.
819 . nr dn 0 \" reset diversion height
820 . br \" finish cell data
822 . if "\\n[.z]"*t*dummy*" \
825 . ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier
827 . if \\n[c#\\*[#t#r]] \{\
828 . di \" close diversion
829 . nr dn\\$4 \\n[dn] \" save height of this cell
830 . if !\\n[rspan\\*[#trc]] \{\
831 . \" update row height if not in a row span
832 . nr dntr\\*[#t#r] (\\n[dntr\\*[#t#r]] >? \\n[dn])
834 . nr dntr\\*[#t#r] ((\\n[t*height\\*[#t#r]] \
835 - (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]])) \
836 >? \\n[dntr\\*[#t#r]])
842 . \" update column span registers
843 . while (\\n+[*] <= \\$3) \{\
844 . if r cspan\\*[#t#r]*\\n[*] \
845 . nr c#\\*[#t#r] +\\n[cspan\\*[#t#r]*\\n[*]]
846 . nr cspan\\*[#t#r]*\\n[*] 0
849 . ds #trc \\*[#t#r]*\\n[c#\\*[#t#r]]\"
851 . \" only check for cell underflow if called by .TR or .ETB
852 . if (\\$1 & (\\n[c#\\*[#t#r]] <= \\n[t*cols\\n[t*#]])) \{\
855 . if (\\n-[c#\\*[#t#r]] == 1) \{\
859 . tmc \\n[.F]:\\n[.c]: There \\*[*] only \\n[c#\\*[#t#r]] \\*[**]
861 . nr * \\n[t*r#\\n[t*#]]
863 . nr *** (\\n[*] % 10)
864 . if d nth-\\n[***] \
865 . ds * \\n[*]\\*[nth-\\n[***]]\"
866 . tmc " in the \\*[*] row
869 . if (\\n[t*cols\\n[t*#]] == 1) \
871 . tm1 " but \\n[t*cols\\n[t*#]] \\*[*] expected.
876 .\" Utility-macro: .t*args level_1 [level_2]
878 .\" Get the arguments common to TBL, TR, and TD for the level
879 .\" in argument 1, using default values from the level in
880 .\" argument 2. If argument 2 is missing, use the global
884 . ds t*bgc\\$1 \\*[t*bgc\\$2]\"
885 . ds t*fgc\\$1 \\*[t*fgc\\$2]\"
886 . ds t*hl\\$1 \\*[t*hl\\$2]\"
887 . ds t*vl\\$1 \\*[t*vl\\$2]\"
888 . ds t*hal\\$1 \\*[t*hal\\$2]\"
889 . ds t*val\\$1 \\*[t*val\\$2]\"
890 . ds t*ff\\$1 \\*[t*ff\\$2]\"
891 . ds t*fst\\$1 \\*[t*fst\\$2]\"
892 . ds t*fsz\\$1 \\*[t*fsz\\$2]\"
897 . t*getarg bgc \\*[args] \" background color
898 . if !"\\*[bgc]"" \{\
900 . ds t*bgc\\$1 \\*[bgc]\"
905 . tm \\n[.F]:\\n[.c]: Invalid background color `\\*[bgc]'.
910 . t*getarg fgc \\*[args] \" foreground color
911 . if !"\\*[fgc]"" \{\
913 . ds t*fgc\\$1 \\*[fgc]\"
918 . tm \\n[.F]:\\n[.c]: Invalid foreground color `\\*[fgc]'.
923 . t*getarg hl \\*[args] \" horizontal line between cells
925 . ds t*hl\\$1 \\*[hl]\"
929 . t*getarg vl \\*[args] \" vertical line between cells
931 . ds t*vl\\$1 \\*[vl]\"
935 . t*getarg hal \\*[args] \" horizontal table cell alignment
936 . if !"\\*[hal]"" \{\
937 . t*index bcrl \\*[hal]
939 . ds t*hal\\$1 \\*[hal]\"
941 . tmc \\n[.F]:\\n[.c]: Invalid horizontal alignment `\\*[hal]':
942 . tm1 " must be `b', `c', `l' or `r'.
947 . t*getarg val \\*[args] \" vertical table cell alignment
948 . if !"\\*[val]"" \{\
949 . t*index tmb \\*[val]
951 . ds t*val\\$1 \\*[val]\"
953 . tmc \\n[.F]:\\n[.c]: Invalid vertical alignment `\\*[val]':
954 . tm1 " must be `t', `m' or `b'.
959 . t*getarg ff \\*[args] \" font family
961 . ds t*ff\\$1 \\*[ff]\"
965 . t*getarg fst \\*[args] \" font style
967 . ds t*fst\\$1 \\*[fst]\"
971 . t*getarg fsz \\*[args] \" font size and spacing factor
973 . ds t*fsz\\$1 \\*[fsz]\"
977 .\" Append to your page header macro ('pg@top' for MS)
978 .\" to enable tables to span pages.
982 . while !""\\*[t*kept]" \{\
985 . if (\\n[*] - \\n[**]) \{\
986 . tm \\n[.F]:\\n[.c]: Table \\*[*] higher than page -- ignored!
990 . if (\\n[*] - \\n[.t]) \{\
991 . ds t*kept \\n[*] \\*[t*kept]\"
992 . ds t*kept \\*[*] \\*[t*kept]\"
993 . tmc \\n[.F]:\\n[.c]: Remaining table(s),
994 . tm1 " because not all fit onto this page.