summaryrefslogtreecommitdiff
path: root/contrib/hdtbl
diff options
context:
space:
mode:
authorwl <wl>2006-05-20 09:20:44 +0000
committerwl <wl>2006-05-20 09:20:44 +0000
commit1ac7b3b556bd975b77424335ac6b05132803c8a2 (patch)
treefca1dd554b11e73b68eb55a45809888ac2667880 /contrib/hdtbl
parentbcfb86bc0ed342601f1fce6b14ba33e6479c9f47 (diff)
downloadgroff-1ac7b3b556bd975b77424335ac6b05132803c8a2.tar.gz
* Import of hdtbl 0.91 (with some further modifications). Still
many rough edges.
Diffstat (limited to 'contrib/hdtbl')
-rw-r--r--contrib/hdtbl/ChangeLog9
-rw-r--r--contrib/hdtbl/README87
-rw-r--r--contrib/hdtbl/examples/chess_board37
-rw-r--r--contrib/hdtbl/examples/col_rowspan_colors55
-rw-r--r--contrib/hdtbl/examples/color_transitions30
-rw-r--r--contrib/hdtbl/examples/colored_boxes23
-rw-r--r--contrib/hdtbl/examples/colored_nested_tables27
-rw-r--r--contrib/hdtbl/examples/colored_table_cells23
-rw-r--r--contrib/hdtbl/examples/fontdumps_n83
-rw-r--r--contrib/hdtbl/examples/fontdumps_x103
-rw-r--r--contrib/hdtbl/examples/mixed_pickles59
-rw-r--r--contrib/hdtbl/examples/rainbow42
-rw-r--r--contrib/hdtbl/examples/short_reference54
-rw-r--r--contrib/hdtbl/groff_hdtbl.man420
-rw-r--r--contrib/hdtbl/hdmisc.tmac531
-rw-r--r--contrib/hdtbl/hdtbl.tmac876
16 files changed, 2459 insertions, 0 deletions
diff --git a/contrib/hdtbl/ChangeLog b/contrib/hdtbl/ChangeLog
new file mode 100644
index 00000000..1181b4b0
--- /dev/null
+++ b/contrib/hdtbl/ChangeLog
@@ -0,0 +1,9 @@
+2006-05-20 Werner LEMBERG <wl@gnu.org>
+
+ * Import of hdtbl 0.91 (with some further modifications). Still
+ many rough edges.
+
+Local Variables:
+version-control: never
+coding: latin-1
+End:
diff --git a/contrib/hdtbl/README b/contrib/hdtbl/README
new file mode 100644
index 00000000..394ef3c5
--- /dev/null
+++ b/contrib/hdtbl/README
@@ -0,0 +1,87 @@
+This is Version 0.91 of hdtbl
+============================
+
+Content:
+--------
+
+ hdtbl.tmac Definition of the 4 base and three optional
+ hdtbl-macros.
+ Definition of internal utility macros.
+ Default settings for macro arguments.
+
+ hdmisc.tmac Some macros from the hdgroff system internally
+ used bei hdtbl.
+ Some further hdgroff macros for the examples.
+
+ groff_hdtbl.7 The hdtbl manpage.
+ groff_hdtbl.7.txt raw text manpage.
+ groff_hdtbl.7.ps PostScript formatted manpage.
+ groff_hdtbl.7.pdf PDF-formatted manpage.
+ groff_hdtbl.7.html HTML-formatted manpage.
+
+ examples directory with 3 subdirectories:
+
+ hdtblgroff: some hdtbl examples
+
+ hdtblps: PS-formatted hdtbl examples
+
+ hdtblpdf: PDF-formatted hdtbl examples
+
+Preparing the use of hdtbl:
+---------------------------
+
+For an easy use of the hdtbl macros you can copy the macro files
+`hdtbl.tmac´ and `hdmisc.tmac´ in the directory `site-tmac´ of groff,
+typical in `/usr/share/groff´ or `/usr/local/share/groff´.
+A place for the man page `groff_hdtbl.7´ could be `/usr/man/man7´,
+`/usr/share/man/man7´ or `/usr/local/man/man7´.
+
+Now you can call `groff -m hdtbl ...´ and `man groff_hdtbl´.
+If you don't have access to the `site-tmac´ directory you can put
+`hdtbl.tmac´ and `hdmisc.tmac´ into a private macro directory `xyz´
+and reference this with the aditional flag `-`M xyz´ when calling groff.
+
+If you like to use hdtbl in conjunction with another macro package,
+e.g. ms, say `groff -m ms ...´ and in your document `.mso hdtbl.tmac´.
+To get the behaviour, that a table, which does not fit on a partially
+filled page, will be printed automatically on the top of the next page
+you must append the little hdtbl utility macro `t*hm´to the page header
+macro of the other macro package, e.g. for the ms macros:
+
+ .am pg@top \" the ms pageheader macro
+ .t*hm
+ ..
+
+hdtbl has builtin pageheader- and pagebottom makros HM and BM. If they
+interfere with your own, replace them with `.rm HM´ and `.rm BM´.
+
+You can change the default settings for hdtbl and the builtin pageheader
+and -bottom macros by overwriting the corresponding registers and strings
+at the beginning of file `hdtbl.tmac´.
+
+HDtbl is clean groff, but some of the examples and additional macros
+in `hdmisc.tmac´ necessary for some examples use system requests via
+`.sy´ and `.pso´. This requires a) to call groff with the `-U´ flag and
+b) to provide for Windows an Unix environment like Cygwin or MinGW.
+
+To Do:
+------
+
+* Macro TOTC (Table Of Table Captions).
+
+* Automatic recognition of the number of columns.
+
+* Optional automatic calculation of the cellwidths from the widths of
+ the first line of the cellcontent instead of the explicit
+ specification with the width argument. This seems to be nontrivial
+ without a preprocessor or additional external calls vial .sy or .pso.
+
+* Handling of pagebreaks in tables.
+
+* Floating text left and/or right from tables.
+
+* Converter hdtbl2html (awk, elisp, perl?); should be easy to write.
+
+* Support for nroff.
+
+Enjoy with hdtbl! \ No newline at end of file
diff --git a/contrib/hdtbl/examples/chess_board b/contrib/hdtbl/examples/chess_board
new file mode 100644
index 00000000..69801f4c
--- /dev/null
+++ b/contrib/hdtbl/examples/chess_board
@@ -0,0 +1,37 @@
+.\" Time-stamp: <ChessBoard.roff: 22.01.2006 10:58:48 x01 - JWalsdorff@compuserve.de>
+.time start
+.nr *x 8
+.de r1
+.TR height=1.6c
+.TD hl= val=m hal=r \\\\n(*x
+.PN 4 ".TD bgc=wheat" ".TD bgc=tan3"
+.TD hl= val=m hal=l \\\\n(*x
+.nr *x -1
+..
+.de r2
+.TR height=1.6c
+.TD hl= val=m hal=r \\\\n(*x
+.PN 4 ".TD bgc=tan3" ".TD bgc=wheat"
+.TD hl= val=m hal=l \\\\n(*x
+.nr *x -1
+..
+.af *y a
+.H Chessboard
+.TBL border=0 csp=.05n bgc= cols=10 width=1.6c tal=c
+.TR vl= hal=c\" height=1c
+.TD hl=
+.nr *y 0
+.PN 8 .TD ".nr *y +1" \\\\n(*y
+.TD hl=
+.PN 4 .r1 .r2
+.TR vl= hal=c
+.TD
+.nr *y 0
+.PN 8 .TD ".nr *y +1" \\\\n(*y
+.TD
+.ETB
+.time
+.\" 466MHz Celeron CPU, 384MB RAM
+.\" WindowsXP/cygwin groff18.1: 1s
+.\" WindowsXP/cygwin groff19.2: 4s
+.\" Suse Linux 9.3 groff19.2: 1s \ No newline at end of file
diff --git a/contrib/hdtbl/examples/col_rowspan_colors b/contrib/hdtbl/examples/col_rowspan_colors
new file mode 100644
index 00000000..4050bd92
--- /dev/null
+++ b/contrib/hdtbl/examples/col_rowspan_colors
@@ -0,0 +1,55 @@
+.\" Time-stamp: <ColRowspanColors.roff: 11.02.2006 23:42:13 x01 - JWalsdorff@compuserve.de>
+.time start
+.de color#
+.nr # +1
+.random#
+.defcolor c\\n# rgb \\*[#random]
+..
+.
+.de brt
+.nr # 0
+.color#
+.if \\n[t*cols\\n[t*#]]/2*2=\\n[t*cols\\n[t*#]] \{ .
+. tmc \\n(.F:\\n(.c: cols was even (\\n[t*cols\\n[t*#]]),
+. nr t*cols\\n[t*#] +1
+. tm increased by one col to \\n[t*cols\\n[t*#]].
+. t*cl \\*[width]
+. ie "\\*[tal]"r" .nr in\\n[t*#] -\\*[width]\" recalculate cell widths etc.
+. el .if "\\*[tal]"c" .nr in\\n[t*#] -\\*[width]/2
+.\}
+.nr N \\n[t*cols\\n[t*#]]-1 \" N must be even
+.nr W 1c\"\\*[width]
+.ds html "".TR height=\\nW" ".TD bgc=c\\n#"
+.nr I 0 2
+.while \\nN>=\\n+I \{ .
+. ds help "\\*[html]
+. pops * help
+. color#
+. ds html "".TR height=\\nW" ".TD colspan=\\nI bgc=c\\n#"
+. color#
+. as html " ".TD rowspan=\\nI bgc=c\\n#"
+. color#
+. as html " ".TR height=\\nW" ".TD rowspan=\\nI bgc=c\\n#"
+. color#
+. as html " \\*[help] ".TR height=\\nW" ".TD colspan=\\nI bgc=c\\n#"
+.\}
+.P1 \\*[html]
+..
+.
+.pv 1.2 1.2 "" x
+.PN 10 Text before table.
+.in 1c
+.PN 8 Indented text before table.
+*** *** ***
+.TBL width=90% border=1n csp=1n cpd=1n bgc=wheat tal=c .TR .TD
+.TBL border= cols=10 width=1c tal=c csp=0 cpd=0 \"cols must be odd
+.CPTN val=b Random Colored Table Cells with Colspan/\%Rowspan
+.brt
+.ETB .ETB
+.PN 15 Text behind the table.
+.time
+.date
+.\" 466MHz Celeron CPU, 384MB RAM
+.\" WindowsXP/cygwin groff18.1: 4s
+.\" WindowsXP/cygwin groff19.2: 7s
+.\" Suse Linux 9.3 groff19.2: 1s \ No newline at end of file
diff --git a/contrib/hdtbl/examples/color_transitions b/contrib/hdtbl/examples/color_transitions
new file mode 100644
index 00000000..fca86030
--- /dev/null
+++ b/contrib/hdtbl/examples/color_transitions
@@ -0,0 +1,30 @@
+.\" Time-stamp: <ColorTransitions.roff: 25.12.2005 18:38:51 x01 - JWalsdorff@compuserve.de>
+.time start
+.de ctab
+.nr #cc 0
+.PN 21 ".nr #cc +.05f" ".defcolor \En[t*#] rgb \\$1 \\$2 \\$3" ".TBL border= csp=0 cpd=.5n bgc=\\\\n[t*#] bc=" .TR .TD
+.PN 21 .ETB
+..
+.PN 30 Before table.
+.TBL cols=3 width=33% border= csp=0 cpd=0 bgc=
+.CPTN val=b Color Transitions
+.TR
+.TD ".ctab 0+\En[#cc]u \En[#cc]u \En[#cc]u" \" schwarz -> weiß
+.TD ".ctab 1f-\En[#cc]u 1f-\En[#cc]u 1f-\En[#cc]u"\" weiß -> schwarz
+.TD ".ctab 1f \En[#cc]u \En[#cc]u" \" rot -> weiß
+.TR
+.TD ".ctab 0 1f-\En[#cc]u \En[#cc]u" \" grün -> blau
+.TD ".ctab 1f 1f-\En[#cc]u 1f" \" weiß -> magenta
+.TD ".ctab 1f \En[#cc]u 1f" \" magenta -> weiß
+.TR
+.TD ".ctab 0+\En[#cc]u \En[#cc]u 1f-\En[#cc]u" \" blau -> gelb
+.TD ".ctab 1f-\En[#cc]u 1f-\En[#cc]u \En[#cc]u" \" gelb -> blau
+.TD ".ctab 1f 0+\En[#cc]u 0" \" rot -> gelb
+.xTD ".ctab 0+\En[#cc]u 1f-\En[#cc]u 1f-\En[#cc]u"\" cyan -> rot
+.ETB
+.PN 30 Behind table.
+.time
+.\" 466MHz Celeron CPU, 384MB RAM
+.\" WindowsXP/cygwin groff18.1: 3s
+.\" WindowsXP/cygwin groff19.2: 20s
+.\" Suse Linux 9.3 groff19.2 3s \ No newline at end of file
diff --git a/contrib/hdtbl/examples/colored_boxes b/contrib/hdtbl/examples/colored_boxes
new file mode 100644
index 00000000..69e2515c
--- /dev/null
+++ b/contrib/hdtbl/examples/colored_boxes
@@ -0,0 +1,23 @@
+.\" Time-stamp: <ColoredBoxes.roff: 17.02.2006 14:13:39 x01 - JWalsdorff@compuserve.de>
+.time start
+.H Horizontal Rules and Boxes .br with Random Colored Border and Background
+.PN 25 Text before horizontal rule.
+.TBL border=.5n bc=green bgc=red width=7c tal=c csp=.2n cpd=.3n .TR .TD .ETB
+.PN 10 Text after horizontal rule and before Table.
+.de ctab
+.nr ? 0 1
+.PN 5 .random# ".defcolor color\En+? rgb \E*[#random]"
+.TD ".TBL border=1c bc=color1 csp=0 cpd=0 height=3c bgc=color2" .TR .TD .ETB
+..
+.
+.TBL tal=c border= csp=0 cpd=0 cols=5 width=3c
+.PN 2 .TR ".PN 5 .ctab"
+.ETB
+.PN 15 Text behind table.
+.TBL border=.5n bc=color1 bgc=color2 width=15c tal=c csp=.2n cpd=.3n .TR .TD .ETB
+.PN 25 Text behind horizontal rule.
+.time
+.\" 466MHz Celeron CPU, 384MB RAM
+.\" WindowsXP/cygwin groff18.1: 10s
+.\" WindowsXP/cygwin groff19.2: 14s
+.\" Suse Linux 9.3 groff19.2: 1s \ No newline at end of file
diff --git a/contrib/hdtbl/examples/colored_nested_tables b/contrib/hdtbl/examples/colored_nested_tables
new file mode 100644
index 00000000..ed328f53
--- /dev/null
+++ b/contrib/hdtbl/examples/colored_nested_tables
@@ -0,0 +1,27 @@
+.\" Time-stamp: <ColoredNestedTables.roff: 12.02.2006 10:34:44 x01 - JWalsdorff@compuserve.de>
+.time start
+.PN 15 Text before first table.
+.nr # 0 1
+*****
+.PN 39 .random# ".defcolor c\\n[#] rgb \\\\*[#random] " \
+".TBL csp=0 cpd=0 border=1n bc=c\\n[#]" \
+".if \\\\n+#=1 .CPTN val=b Nested Tables with Random Colored Border" \
+.TR .TD
+.PN 39 .ETB
+.PN 15 Text behind first table.
+.time
+.time start
+.PN 15 Text before second table.
+*****
+.nr # 0 1
+.PN 39 .random# ".defcolor c\\n[#] rgb \\\\*[#random] " \
+".TBL csp=0 cpd=1n border= bgc=c\\n[#]" \
+".if \\\\n+#=1 .CPTN val=b Nested Tables with Random Colored Background" \
+.TR .TD
+.PN 39 .ETB
+.PN 25 Text behind second table.
+.time
+.\" 466MHz Celeron CPU, 384MB RAM
+.\" WindowsXP/cygwin groff18.1: 9/9s
+.\" WindowsXP/cygwin groff19.2: 14/14s
+.\" Suse Linux 9.3 groff19.2: 1/1s \ No newline at end of file
diff --git a/contrib/hdtbl/examples/colored_table_cells b/contrib/hdtbl/examples/colored_table_cells
new file mode 100644
index 00000000..84dcff47
--- /dev/null
+++ b/contrib/hdtbl/examples/colored_table_cells
@@ -0,0 +1,23 @@
+.\" Time-stamp: <ColoredTableCells.roff: 24.03.2006 21:53:32 x01 - JWalsdorff@compuserve.de>
+.time start
+.H Horizontal Rules and Random Colored Tablecells
+.PN 15 Text before HR.
+.TBL border=.5n bc=green bgc=red width=7c tal=c csp=.2n cpd=.3n .TR .TD .ETB
+.PN 10 Text after HR and before Table.
+.
+.nr ? 0 1
+.de ctab
+.TR height=\nl/10
+.PN 8 .random# ".defcolor c\\\\n+? rgb \E*[#random]" ".TD bgc=c\\\\n?"
+..
+.TBL tal=c border= csp=0 cpd=0 cols=8 width=\nl/10
+.PN 8 .ctab
+.ETB
+.PN 10 Text behind table.
+.TBL border=.5n bc=c1 bgc=c2 width=15c tal=c csp=.2n cpd=.3n .TR .TD .ETB
+.PN 15 Text behind HR.
+.time
+.\" 466MHz Celeron CPU, 384MB RAM
+.\" WindowsXP/cygwin groff18.1: 14s
+.\" WindowsXP/cygwin groff19.2: 18s
+.\" Suse Linux 9.3 groff19.2: 1s \ No newline at end of file
diff --git a/contrib/hdtbl/examples/fontdumps_n b/contrib/hdtbl/examples/fontdumps_n
new file mode 100644
index 00000000..4e242d66
--- /dev/null
+++ b/contrib/hdtbl/examples/fontdumps_n
@@ -0,0 +1,83 @@
+.\" -*- roff -*-
+.\" Time-stamp: <FontdumpsN.roff: 17.02.2006 14:25:41 x01 - JWalsdorff@compuserve.de>
+.\" ******************************************************************
+.\" ** Groff-Fontglyphs vs Charactercode: **
+.\" ** .fontdump [font1 font2 ... ] **
+.\" ** Print glyphs of font1 font2 ... versus **
+.\" ** charactercode. **
+.\" ** `all´ as fontname prints all fonts in the **
+.\" ** specified fontpath `*fontpath´. **
+.\" ** without arg: glyps/codes of active font. **
+.\" ******************************************************************
+.time start
+.ds *fontpath /usr/local/share/groff/1.19.3/font
+.\"ds *fontpath /usr/share/groff/1.18.1/font
+.
+.de fontdump
+.ie \\n(.$ .ds *args \\$*
+.el .ds *args \\n[.fn]
+.pso bash -c \
+"echo -n .ds *f\ ;ls --color=never \\*[*fontpath]/dev\*(.T | tr [:cntrl:] ' '"
+.\" this dummy-line is necessary while eaten by the preceding line
+.while !"\\*[*args]"" \{ .
+. pops *$1 *args
+. if "\\*[*$1]"all" \{ .
+. ds *args \\*(*f \\*[*args]
+. pops *$1 *args
+. nr *all 1
+. \}
+. if \\n[*all] \{ .
+. if "\\*[*$1]"." .nr *all 0
+. if !F \\*[*$1] .continue
+. \}
+. index "\\*(*f" \\*[*$1]
+. ie \\n(.y>18 .if !F \\*[*$1] \{ .
+. tm \\n(.F:\\n(.c: Font \\*[*$1] not found.
+. continue
+. \}
+. el \{ .
+. if !\\n[index] \{ .
+. tm \\n(.F:\\n(.c: Font \\*[*$1] not found.
+. continue
+. \}
+. nr * \\n(.f
+. ft \\*[*$1]
+. nr ** \\n(.f
+. ft
+. if \\n(**=\\n* .continue
+. \}
+. if \\n[t*cptn] .bp
+. TBL border=.1n bc=red cpd=0 csp=.1n bgc=
+. CPTN Groff-Font \\*[*$1] .br val=b ".pso grep -e internalname \
+ \\*[*fontpath]/dev\*(.T/\\*[*$1]"
+. TR
+. TD
+. TBL cols=12 border=.1n bc=red csp=.1n cpd=.2n fgc=red4 bgc=beige hal=c \
+ "fsz=1.2 1.2" fst=\\*[*$1]
+. nr c# 0-1 1
+. nr y# 0-1 1
+. TR fst=HB fgc=blue
+. TD
+. nr x# 0-1 1
+. \" following 4 `PN´s instead of 4 while-loops as in FontdumpX.roff;
+. \" short and easy to write, but a little bit slower.
+. PN 10 .TD \&..\\\\n+[x#]
+. TD
+. PN 27 .TR ".TD fgc=blue fst=HB \\\\n+[y#]." ".PN 10 .TD \N'\En+(c#'" \
+ ".TD fgc=blue fst=HB \\\\n[y#]."
+. TR fst=HB fgc=blue
+. TD
+. nr x# 0-1 1
+. PN 10 .TD \&..\\\\n+[x#]
+. TD
+. ETB
+. ETB
+.\}
+..
+.fontdump all
+.time
+.date
+.\" 466MHz Celeron CPU, 384MB RAM
+.\" WindowsXP/cygwin groff18.1: 115s
+.\" WindowsXP/cygwin groff19.2: 450s
+.\" Suse Linux 9.3 groff19.2: 76s \ No newline at end of file
diff --git a/contrib/hdtbl/examples/fontdumps_x b/contrib/hdtbl/examples/fontdumps_x
new file mode 100644
index 00000000..babf3357
--- /dev/null
+++ b/contrib/hdtbl/examples/fontdumps_x
@@ -0,0 +1,103 @@
+.\" -*- roff -*-
+.\" Time-stamp: <FontdumpsX.roff: 17.02.2006 14:34:56 x01 - JWalsdorff@compuserve.de>
+.\" ******************************************************************
+.\" ** Groff-Fontglyphs vs Charactercode: **
+.\" ** .fontdump [font1 font2 ... ] **
+.\" ** Print glyphs of font1 font2 ... versus **
+.\" ** charactercode. **
+.\" ** `all´ as fontname prints all fonts in the **
+.\" ** specified fontpath `*fontpath´. **
+.\" ** without arg: glyps/codes of active font. **
+.\" ******************************************************************
+.time start
+.ds *fontpath /usr/local/share/groff/1.19.3/font
+.\"ds *fontpath /usr/share/groff/1.18.1/font
+.
+.de fontdump
+.ie \\n(.$ .ds *args \\$*
+.el .ds *args \\n[.fn]
+.pso bash -c \
+"echo -n .ds *f\ ;ls --color=never \\*[*fontpath]/dev\*(.T | tr [:cntrl:] ' '"
+.\" this dummy-line is necessary; the preceding line eats it.
+.while !"\\*[*args]"" \{ .
+. pops *$1 *args
+. if "\\*[*$1]"all" \{ .
+. ds *args \\*(*f \\*[*args]
+. pops *$1 *args
+. nr *all 1
+. \}
+. if \\n[*all] \{ .
+. if "\\*[*$1]"." .nr *all 0
+. if !F \\*[*$1] .continue
+. \}
+. index "\\*(*f" \\*[*$1]
+. ie \\n(.y>18 .if !F \\*[*$1] \{ .
+. tm \\n(.F:\\n(.c: Font \\*[*$1] not found.
+. continue
+. \}
+. el \{ .
+. if !\\n[index] \{ .
+. tm \\n(.F:\\n(.c: Font \\*[*$1] not found.
+. continue
+. \}
+. nr * \\n(.f
+. ft \\*[*$1]
+. nr ** \\n(.f
+. ft
+. if \\n(**=\\n* .continue
+. \}
+. if \\n[t*cptn] .bp
+. TBL border=.1n bc=red cpd=0 csp=.1n bgc=
+. CPTN Groff-Font \\*[*$1] .br val=b ".pso grep -e internalname \
+ \\*[*fontpath]/dev\*(.T/\\*[*$1]"
+. TR
+. TD
+. TBL cols=18 border=.1n bc=red csp=.1n cpd=.2n fgc=red4 bgc=beige hal=c \
+ fsz='1.2 1.7' fst=\\*[*$1]
+. nr c# 0-1 1
+. nr y# 0 1
+. TR fst=HB fgc=blue
+. TD
+. nr x# 0-1 1
+. while \\n+[x#]<16 \{ .
+. d2x \\n[x#]
+. TD
+. nop \&.\\*[hex#]
+. \}
+. TD
+. nr y# -1
+. while \\n+(y#<17 \{ .
+. TR
+. TD fgc=blue fst=HB
+. d2x \\n(y#
+. nop \\*[hex#].
+. nr x# 0-1 1
+. while \\n+(x#<16 \{ .
+. TD
+. nop \N'\\n+(c#'
+. \}
+. TD fgc=blue fst=HB
+. d2x \\n(y#
+. nop \\*[hex#].
+. \}
+. TR fst=HB fgc=blue
+. TD
+. nr x# 0-1 1
+. while \\n+[x#]<16 \{ .
+. d2x \\n[x#]
+. TD
+. nop \&..\\*[hex#]
+. \}
+. TD
+. ETB
+. ETB
+.\}
+..
+.
+.fontdump all
+.time
+.date
+.\" 466MHz Celeron CPU, 384MB RAM
+.\" WindowsXP/cygwin groff18.1: 107s
+.\" WindowsXP/cygwin groff19.2: 390s
+.\" Suse Linux 9.3 groff19.2: 66s \ No newline at end of file
diff --git a/contrib/hdtbl/examples/mixed_pickles b/contrib/hdtbl/examples/mixed_pickles
new file mode 100644
index 00000000..26e89cb7
--- /dev/null
+++ b/contrib/hdtbl/examples/mixed_pickles
@@ -0,0 +1,59 @@
+.\" Time-stamp: <MixedPickles.roff: 18.01.2006 09:28:55 x01 - JWalsdorff@compuserve.de>
+.time start
+.H Table with Mixed Content: .br eps Image, eqn Equation, tbl Table and pic Picture
+Call groff with -tbl -eqn -pic!
+.TBL width=90% tal=c csp=.2n cpd=0 .TR .TD
+.TBL width='25% 75%' csp=.5n cpd=.5n hal=c
+.TR
+.TD hl=d vl=d rowspan=2 bgc=red4 fgc=linen fsz=1.2 fst=HB val=m
+.xPSPIC -I -3m Java.eps
+.PSPIC -I -\\n(.lu/2u Java.eps
+.sp .5
+eps-Image with \f2.PSPIC\fP
+.TD bgc=linen
+.EQ
+int from 0 to 1 {(ln x) sup 2} over {sqrt {1 - x sup 2}} dx approx 0.245
+.EN
+\0\0\0\0\0Equation with \f2eqn\fP
+.TR .TD hl=d
+.TS
+tab(@), center, doublebox;
+c c c | c c c
+r rI lB | r rI lB.
+Bit@Code@Warning@Bit@Code@Warning
+=
+0@1@char@10@1024@reg
+1@2@number@11@2048@tab
+2@4@break@12@4096@right-brace
+3@8@delim@13@8192@missing
+4@16@el@14@16384@input
+5@32@schale@15@32768@escape
+6@64@range@16@65536@space
+7@128@syntax@17@131072@font
+8@256@di@18@262144@ig
+9@512@mac@19@524288@color
+.TE
+.sp .5
+Table with \f2tbl\fP
+.TR
+.TD colspan=2 bgc=azure2 fgc=blue4
+.PS
+ellipse "document";
+arrow;
+box width 0.6 "\fIgpic\/\fP(1)"
+arrow;
+box width 1.1 "\fIgtbl\/\fP(1) or \fIgeqn\/\fP(1)" "(optional)" dashed;
+arrow;
+box width 0.6 "\fIgtroff\/\fP(1)";
+arrow;
+ellipse "PostScript"
+.PE
+.sp .5
+Picture with \f2pic\fP
+.xTD
+.ETB .ETB
+.time
+.\" 466MHz Celeron CPU, 384MB RAM
+.\" WindowsXP/cygwin groff18.1: 1s
+.\" WindowsXP/cygwin groff19.2: 2s
+.\" Suse Linux 9.3 groff19.2: 1s \ No newline at end of file
diff --git a/contrib/hdtbl/examples/rainbow b/contrib/hdtbl/examples/rainbow
new file mode 100644
index 00000000..d676742c
--- /dev/null
+++ b/contrib/hdtbl/examples/rainbow
@@ -0,0 +1,42 @@
+.\" Time-stamp: <Rainbow.roff: 13.07.2005 13:08:35 x01 - JWalsdorff@compuserve.de
+.time start
+.nr *n 25
+.nr *# 0 1
+.de ctab
+.nr #cc 0
+.PN \\$1 ".nr #cc +1f/\\$1" ".defcolor \En[t*#] rgb \\$2 \\$3 \\$4" \
+".TBL csp=\nl/(12*\\$1+2) border= cpd=0 bgc=\\\\n[t*#] bc=" \
+".if \\\\n+(*#=1 .CPTN Rainbow Colors \(em Nested Tables with Colored \
+Backgrounds val=b" .TR .TD
+..
+.ctab \n(*n 1 0 \En[#cc]u \" rot -> magenta
+.ctab \n(*n 1-\En[#cc]u 0 1 \" magenta -> blau
+.ctab \n(*n 0 \En[#cc]u 1 \" blau -> cyan
+.ctab \n(*n 0 1 1-\En[#cc]u \" cyan -> grün
+.ctab \n(*n \En[#cc]u 1 0 \" grün -> gelb
+.ctab \n(*n 1 1-\En[#cc]u 0 \" gelb -> rot
+.PN 6*\n(*n .ETB
+.time end
+.bp
+.time start
+.nr *n 25
+.nr *# 0 1
+.de ctab
+.nr #cc 0
+.PN \\$1 ".nr #cc +1f/\\$1" ".defcolor \En[t*#] rgb \\$2 \\$3 \\$4" \
+".TBL border=\nl/(12*\\$1+2) csp=0 cpd=0 bc=\\\\n[t*#] bgc=" \
+".if \\\\n+(*#=1 .CPTN Rainbow Colors \(em Nested Tables with Colored Borders \
+ val=b" .TR .TD
+..
+.ctab \n(*n 1 \En[#cc]u 0 \" rot -> gelb
+.ctab \n(*n 1-\En[#cc]u 1 0 \" gelb -> grün
+.ctab \n(*n 0 1 \En[#cc]u \" grün -> cyan
+.ctab \n(*n 0 1-\En[#cc]u 1 \" cyan -> blau
+.ctab \n(*n \En[#cc]u 0 1 \" blau -> magenta
+.ctab \n(*n 1 0 1-\En[#cc]u \" magenta -> rot
+.PN 6*\n(*n .ETB
+.time end
+.\" 466MHz Celeron CPU, 384MB RAM
+.\" WindowsXP/cygwin groff18.1: 11/10s
+.\" WindowsXP/cygwin groff19.2: 57/55s
+.\" Suse Linux 9.3 groff19.2: 8/8s \ No newline at end of file
diff --git a/contrib/hdtbl/examples/short_reference b/contrib/hdtbl/examples/short_reference
new file mode 100644
index 00000000..99950526
--- /dev/null
+++ b/contrib/hdtbl/examples/short_reference
@@ -0,0 +1,54 @@
+.\" Time-stamp: <ShortReference.roff: 30.11.2005 14:49:16 x01 - JWalsdorff@compuserve.de>
+.time start
+.pv 1.2 1.2 "" x
+.H Short Reference for the HDtbl-Macros
+This Short Reference shortly describes the Heidelberger Table Macros
+using these macros themselves.
+.br
+.nr t*csp .3n
+.nr t*cpd .3n
+.ds t*ff HN
+.ds t*val m
+.ds t*hal l
+.xig
+.TBL "width=10% 40% 25% 25%" border= "fsz=1 .8"
+.CPTN Base- Optional- and Utility-Macros val=b
+.TR
+.TH Macro .TH Description .TH Predecessors .TH Successors
+.TR
+.TD \&.TBL .TD Begin a new table .TD \&.TD \&.TH \%.ETB cellcontent
+.TD \&.CPTN \&.TR
+.TR
+.TD \&.CPTN .TD Optional numbered or unnumbered table caption
+.TD \&.TBL .TD \&.TR
+.TR
+.TD \&.TR .TD Begin a new table row .TD \&.TBL \&.CPTN cellcontent
+.TD \&.TD \&.TR
+.TR
+.TD \&.TH .TD Optional begin table header cell
+.TD \&.TR \&.TD \&.TH \%.ETB cellcontent
+.TD \&.TD \&.TH \&.TR \%.ETB cellcontent
+.TR
+.TD \&.TH .TD Begin table data cell .TD \&.TR \&.TD \&.TH \%.ETB cellcontent
+.TD \&.TD \&.TH \&.TR \%.ETB cellcontent
+.TR
+.TD \&.ETB .TD Finish and pront table. .TD \&.TD \&.TH \%.ETB cellcontent
+.TD \&.TBL \&.TR \&.TD \&.TH \%.ETB cellcontent
+.TR
+.TD \&.t*free
+.TD colspan=3 val=t Utility macro to free held tables. Use it outside any table.
+.ETB
+.bp
+.x.
+.TBL "fsz=1 .8" "width=20% 32% 8% 8% 8% 8% 8% 8%" border=
+.TR
+.TH Argument .TH Value .TH \&.TBL .TH \&.CPT .TH \&.TR .TH \&.TH .TH \&.TD .TH \&.ETB
+.TR
+.TD border=\fI[n]\fP
+.TD border thickness .TD .ce X .TD .TD .TD .TD .TD
+.TR
+.TD bc=\fI[c]\fP
+.TD color of border and cellseperatorlines .TD .ce X .TD .TD .ce X .TD .ce X .TD .ce X .TD
+.ETB
+.H ------ incomplete -------
+.time end \ No newline at end of file
diff --git a/contrib/hdtbl/groff_hdtbl.man b/contrib/hdtbl/groff_hdtbl.man
new file mode 100644
index 00000000..f0ea5f0d
--- /dev/null
+++ b/contrib/hdtbl/groff_hdtbl.man
@@ -0,0 +1,420 @@
+.\" Time-stamp: <groff_hdtbl.7: 28.12.2005 14:03:43 x01 - JWalsdorff@compuserve.de>
+.ig
+groff_hdtbl.7
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being this .ig-section and AUTHORS, with no
+Front-Cover Texts, and with no Back-Cover Texts.
+
+A copy of the Free Documentation License is included as a file called
+FDL in the main directory of the groff source package.
+..
+.mso www.tmac
+.xgcolor navy
+.BCL #800000 #f5f5dc
+.nr S 12
+.TH groff_hdtbl 7 "December 2005" HDgroff "Version 0.91"
+.nr IN 3n \" doesn't work before TH!
+.\"
+.\" some simple formatting macros
+.\"
+.ie FCR \{ .
+.fp 5 CR
+.fp 6 CI
+.fp 7 CB
+.fp 8 CBI
+.\}
+.el \{ .
+.fp 5 R
+.fp 6 I
+.fp 7 B
+.fp 8 BI
+.\}
+.
+.de A
+.PP
+.xin 2u*\\n(INu
+.ta 4u*\\n(INu
+\&\s+1\f7\\$1\fP\0\f8\\$2\fP\s-1\t\c
+.shift
+.shift
+\\$*
+..
+.
+.de B
+.in 3u*\\n(INu
+.sp .2
+.ds * \\$1
+.ie !"\*(.T"html" .ta 5u*\\n(INu
+.el .ta 7u*\\n(INu
+.shift
+\&\fB\\**\fP\t\f5\\$*\fP
+..
+.de AA
+.sp .2
+.ne 2
+.in 3u*\\n(INu
+.ds * \\n[.f]
+\&\f5\\$1\f6\\$2\f\\**
+.ie "\\*(.T"html" .in 4u*\\n(INu
+.el \{ 'in 4u*\\n(INu
+\(em\
+.\}
+..
+.
+.de DEF
+.br
+.ds * \\n[.f]
+\fBDefault:\fP
+.if !\\n(.$ .return
+\&\f5\\$1\fP\f6\\$2\f\\**
+..
+.
+.SH NAME
+\fBhdtbl\fP \(em seven \fBgroff\fP-macros for simple but mighty table
+processing
+.SH DESCRIPTION
+\fBhdtbl\fP is a set of four base and three optional macros,
+controlled by about twenty arguments. The syntax is simple and similar
+to the \fBHTML\fP table model and nearly as free: you can write
+sequences of tokens (macro calls with their arguments and content
+data), seperated with blancs and beginning with a macro call, into the
+same line to get compact and clearly arrranged input. Since the
+\fBhdtbl\fP-macros are pure \fBgroff\fP, \fBhdtbl\fP works without a
+preprocessor, and the user doesn't need to learn the peculiar
+\fBtbl\fP-syntax. On the other hand table processing with \fBhdtbl\fP
+is slower as with the classical \fBroff\fP tableprocessor
+\fBtbl\fP. Because of its relationship \fBhdtbl\fP could be easily
+translated into the \fBHTML\fP table format. So for some users who
+would like the new features of \fBhdtbl\fP and especially for new
+ones, \fBhdtbl\fP could be an alternative to the tableprocessing with
+\fBtbl\fP.
+.SH USAGE
+The simpliest wellformed table consists of just one call to the four
+base table macros in the right order \(em the table with only one
+cell:
+.PP
+.nf
+.in +\n(INu
+\&\f5.TBL
+\&.TR
+\&.TD\fP
+\f6content of the table cell\fP
+\&\f5.ETB\fP
+.fi
+.PP
+Equivalent is the notaion:
+.PP
+.in +\n(INu
+\&\f5.TBL .TR .TD\fP \f6content of the table cell\fP \f5.ETB\fP
+.PP
+By default and if the remaining place on the page is sufficient, the
+formatted table is inserted in the surrounding text at the place of
+its definition, else at the top of the next page. Tables can also be
+held and inserted delayed at a place of the users choice.
+.PP
+A table with two columns and two rows (cellcontents in this example
+are \f6rownumber*columnnumber\fP) is written as:
+.PP
+.in +\n(INu
+\&\f5.TBL cols=2 .TR .TD\fP \f61*1\fP \f5.TD\fP \f61*2\fP \f5.TR .TD\fP \f62*1\fP \f5.TD\fP \f62*2\fP \f5.ETB\fP
+.PP
+Here we see a difference with \fBHTML\fP tables: at the time the
+number of columns must be specified explicitly via \f5cols=\fP\f6m\fP (or
+indirectly via the \f5width\fP-argument, see later).
+.PP
+The content of a tablecell is arbitrary, and can be again a table and
+so on, without restriction in the nesting depth. To get a special
+table layout you have, like with \fBHTML\fP tables, the choice between
+suitable nested tables or by using the arguments for column- and/or
+rowspanning (see these arguments for \f5\&.TD/.TH\fP). The following
+tables
+.PP
+.in +\n(INu
+.nf
+\&\fC.TBL .TR .TD\fP \f61*1 1*2\fP
+\fC. TR .TD ".TBL cols=2" .TR .TD\fP \f62*1\fP \fC.TD\fP \f62*2\fP \fC.ETB .ETB\fP
+.fi
+.PP
+and
+.PP
+.in +\n(INu
+.nf
+\&\fC.TBL cols=2 .TR ".TD colspan=2"\fP \f61*1 1*2\fP
+\fC. TR .TD\fP \f62*1\fP \fC.TD\fP \f62*2\fP \fC.ETB\fP
+.fi
+.PP
+are \fIsimilar\fP. But tables with column- and/or rowspanning can
+never look \fIidentically\fP like nested tables.
+.PP
+If a macro with argument(s) is not the first one in a line, it must be
+enclosed in double quotes.
+.SH MACROS and ARGUMENTS
+The order of macro calls and other tokens must agree with the
+\fBHTML\fP content model. In the following is listed, which tokens may
+precede or succeed each other legally.
+.PP
+Macro arguments are seperated with blancs. The order of arguments is
+arbitrary. They are of the form \f5key=\fP\f6value\fP or
+\f5key='\fP\f6value1 value2 ...\fP\f5'\fP, with the only exception of
+the \f5.ETB\fP-argument \f5hold\fP, which is the value
+itself. Optionally you can write \f5"key=\fP\f6value1 value2 ...\fP\f5"\fP,
+but only if the macro is the first one in the line and not already
+enclosed in double quotes. Argument values specified
+as \f6c\fP are predefined \fBgroff\fP-colors or colors defined by the
+user with the \fBgroff\fP request \f5.defcolor\fP. Argument values
+\f6d\fP are decimal numbers with or without decimal point. Argument
+values \f6m\fP are natural numbers. Argument values \f6n\fP are
+numerical with the usual \fBgroff\fP scaling indicators. Some of the
+arguments are specific to one or two macros, but most of them can be
+specified with the \f5.TBL\fP-, \f5.TR\fP- and
+\f5.TD/.TH\fP-macro. These common arguments are explained after the
+following macro descriptions. Most of the argument default values can
+be changed by the user by setting corresponding default registers or
+strings, see below.
+.\" TBL
+.A .TBL [args] Begin a new table.
+.B predecessor: .TD/.TH, .ETB
+or \f6cellcontent\fP
+.B successor: .CPTN
+or \f5\&.TR\fP
+.B arguments:
+.AA border= [n]
+thickness of the surrounding boxborder. \f5border=\fP (no value)
+means no surrounding boxborder nor any horizontal or vertical
+seperator lines between the table rows/cells. \f5border=\fP\f60\fP:
+no surrounding boxborder, but possibly seperator lines between cells
+and rows.
+.DEF border= .1n
+(register \f5t*b\fP)
+.AA bc= c
+color of the border.
+.DEF bc= red4
+(string \f5t*bc\fP)
+.AA cols= m
+the number of tablecolumns. Necessary if more then one column, or the
+\f5width\fP-argument must have explicit width-settings for every
+column.
+.DEF cols= 1
+(register \f5t*cols\fP)
+.AA cpd= n
+cellpadding, i.e. extra space between the cellspace border and
+the cellcontent.
+.DEF cpd= .5n
+(register \f5t*cpd\fP)
+.AA csp= n
+cellspacing, i.e. extra space between the table border or
+vertical or horizontal lines between cells and the cellspace.
+.DEF csp= .5n
+(register \f5t*csp\fP)
+.AA tal= l|c|r
+horizontal alignment of the table, if it is smaller then the
+linewidth. \f5tal=\fP\f6l\fP: left alignment. \f5tal=\fP\f6c\fP:
+centered alignment. \f5tal=\fP\f6r\fP: right alignment.
+.DEF tal= l
+(register \f5t*tal\fP)
+.AA width= "'w1 w2 ...'"
+widths of the tablecells. The \f6w\fP are numbers like the \f6n\fP
+and/or natural numbers with the scaling indicator \f6%\fP with the
+meaning \(lqpercent of the actual linelengt (resp. columnlength for
+inner tables)\(rq. If there are less \f6w\fP then tablecols, the last
+\f6w\fP is used for the remaining cells. \f5width=\fP'\f61.5i
+10%\fP' for example means, the first column is 1.5\0inch wide and
+the remaining columns 1/10 of the columnlength.
+.DEF
+the table width equals the outer linelength/columnlength; the columns
+are equal width.
+.AA height= n
+height of the table. If the table with its content is lower then
+\f6n\fP, the table (resp. the last row) is stretched to this value.
+.\" CPTN
+.ad l
+.A .CPTN "[args] text of caption"
+'in 2u*\n(INu+\n[.tabs]u
+The (optional numbered) table caption. \f5.CPTN\fP is optional.
+.in
+.ad
+.B predecessor: .TBL
+.B successor: .TR
+.B arguments:
+.AA val= t|b
+vertical alignment of the table caption. \f5val=\fP\f6t\fP: caption
+above the table. \f5val=\fP\f6b\fP: caption beneath the table.
+.DEF val= t
+.br
+For CPTN-default settings see the string
+\f5t*cptn\fP.
+.\" TR
+.A .TR [args] Begin a new table row.
+.B predecessor: .TBL, .CPTN,
+.TD/.TH, .ETB
+or \f6cellcontent\fP
+.B successor: .TD/.TH
+.B arguments:
+.AA height= n
+the height of the row. If a cell in the row is higher then \f6n\fP,
+this value is ignored; otherwise the row height is stretched to
+\f6n\fP.
+.\" TH, TD
+.A .TD "[args cellcontent]" \0\0Begin a table data cell.
+.sp -.4
+.A .TH "[args cellcontent]" \0\0Begin a table header cell.
+.in 3u*\n(INu
+Arguments and cellcontent can be mixed. \fC\&.TH\fP is not really
+necessary and differs from \fC.TD\fP only in three default settings
+(like the HTML-\fC<TH>\fP-tag from the \fC<TD>\fP-tag): The content of
+\fC.TH\fP is horizontally and vertically centered and bolded.
+.in
+.B predecessor: .TR, .TD/.TH, .ETB
+or \f6cellcontent\fP
+.B successor: .TD/.TH, .TR, .ETB
+or \f6cellcontent\fP
+.B arguments:
+.AA colspan= m
+the width of this cell is the sum of widths of the \f6m\fP cells above
+or below this row.
+.AA rowspan= m
+the height of this cell is the sum of heights of the \f6m\fP cells
+beside this column.
+.br
+\fBRemark:\fP overlapping of col- and rowspanning, as in the following
+table fragment (overlap at position \f62*2\fP) is illegal and the
+result incorrect:
+.in +\n(INu
+.nf
+\fC.TR .TD\fP \f61*1\fP "\fC.TD\fP \f61*2\fP \fCrowspan=2" .TD\fP \f61*3\fP
+\fC.TR ".TD\fP \f62*1\fP \fCcolspan=2" .TD\fP \f62*3\fP
+.in
+.fi
+.\" ETB
+.A .ETB [hold] End of the table.
+'in 2u*\n(INu+\n[.tabs]
+Finishs the table; one of the following happens:
+.RS 3u*\n(INu
+.IP \(bu 3
+if the \f5hold\fP-argument (see below) is given, the table is held,
+until it is freed by calling the macro \f5.t*free\fP (see below), and
+is then printed immediately or, if it's higher then the remaining
+place on the page, at the top of the next page.
+.IP \(bu
+else if the table is higher then the remaining place on the page,
+it is printed at the top of the next page.
+.IP \(bu
+else the table is printed immediately at the place of its definition.
+.RE
+.PP
+.B predecessor: .TD/.TH, .ETB
+or \f6cellcontent\fP
+.B successor: .TBL, .TR, .TD/.TH, .ETB
+or \f6cellcontent\fP
+.B arguments:
+.AA hold
+prevent the table from beeing printed until it is freed by calling the
+macro \f5\&.t*free\fP. This argument is ignored for inner (nested)
+tables.
+.\" .t*free
+.A .t*free [n] Free the next or \f5n\fP held table(s).
+'in 2u*\n(INu+\n[.tabs]
+Call this utility macro to print tables held by the
+\f5hold\fP-argument of \f5.ETB\fP.
+.
+.in \n[IN]u
+.SS Arguments common to \f7.TBL\fP, \f7.TR\fP and \f7.TD/.TH\fP
+Though these arguments can be specified with the \f5.TBL\fP- and
+\f5.TR\fP-macros, they work lastly on the table cells. If not
+specified the defaults take place, which the user can change by
+setting the corresponding default registers or strings, see below. Setting
+an argument with the \f5\&.TBL\fP-macro has the same effect as setting
+it for all rows in the table. Setting an argument with a
+\f5\&.TR\fP-macro has the same effect as setting it for all the
+\f5.TH/.TD\fPs in this row.
+.AA bgc= [c]
+the background color of the tablecells, i.e. the area inside
+\fCcsp\fP. \f5bgc=\fP (no value): no background color,
+i.e. transparent background.
+.DEF bgc= bisque
+(string \f5t*bgc\fP)
+.AA fgc= c
+the foreground color of the cellcontent.
+.DEF fgc= red4
+(string \f5t*fgc\fP)
+.AA ff= name
+font family for the table. \f6name\fP is one of the groff font
+families, for example \f6A\fP for the AvantGarde fonts or \f6HN\fP for
+Helvetica-Narrow.
+.DEF
+the font family found before the table (string \f5t*ff\fP)
+.AA fst= style
+the font style for the table. One of \f6R\fP, \f6I\fP, \f6B\fP or
+\f6BI\fP for roman, \fBbold\fP, \fIitalic\fP or \f(BIbold italic\fP.
+As with the roff \f5.ft\fP-request you can specify with the
+\f5fst\fP-argument the font family and font style together, for
+example \f5fst=\fP\f6HNBI\fP instead of \f5ff=\fP\f6HN\fP and
+\f5fst=\fP\f6BI\fP\c \&.
+.DEF
+the font style found before the table (string \f5t*fst\fP)
+.AA fsz= "'d1 [d2]'"
+a decimal (optional fractional) multiplier \f6d1\fP\, by which the
+pointsize for the table is changed, and \f6d2\fP\, by which the
+vertical linespacing is changed. If \f6d2\fP\ is omitted, value
+\f6d1\fP\ is taken for both.
+.DEF fsz= "'1.0 1.0'"
+(string \f5t*fsz\fP)
+.AA hal= l|c|b|r
+horizontal alignment of the cellcontents in the table.
+\f5hal=\fP\f6l\fP: left alignment. \f5hal=\fP\f6c\fP: centered
+alignment. \f5hal=\fP\f6b\fP: both (left \fIand\fP right) alignment.
+\f5hal=\fP\f6r\fP: right alignment.
+.DEF hal= b
+(string \f5t*hal\fP)
+.AA val= t|m|b
+vertical alignment of the cellcontents in the table for cells lower
+then the row. \f5val=\fP\f6t\fP: alignment beneath the top of the
+cell. \f5val=\fP\f6m\fP: alignment in the middle of the cell.
+\f5val=\fP\f6b\fP: alignment above the cellbottom.
+.DEF val= t
+(string \f5t*val\fP)
+.AA hl= [s|d]
+horizontal line between the rows. (If specified with \f5.TD/.TH\fP a
+seperator line to the cell below.) \f5hl=\fP (no value): no seperator
+line. \f5hl=\fP\f6s\fP: a single seperator line between the
+rows. \f5hl=\fP\f6d\fP: a double seperator line.
+.br
+The thickness of the seperator lines is half the borderthickness, but
+at least \f60.1n\fP. The distance between the double lines is equal
+the line thickness. \fBRemark:\fP Together with \f5border=\fP\f60\fP
+for proper formatting the value of \f5csp\fP must be at least
+\f6.05n\fP for single seperator lines and \f6.15n\fP for double seperator
+lines.
+.DEF hl= s
+(string \f5t*hl\fP)
+.AA vl= [s|d]
+vertical seperator line between the cells. (If specified with
+\f5.TD/.TH\fP a seperator line to the cell on the right.)
+\f5vl=\fP\f6s\fP: a single seperator line between the cells.
+\f5vl=\fP\f6d\fP: a double seperator line. \f5vl=\fP (no value): no
+vertical cellseperator lines. For further description see at \f5hl\fP
+above.
+.DEF vl= s
+(string \f5t*vl\fP)
+.
+.SH AUTHOR
+.ie "\*(.T"html" .MTO Joachim.Walsdorff@urz.uni-heidelberg.de "Joachim Walsdorff" .
+.el Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
+.SH BUGS and SUGGESTIONS
+Please send your commments to the
+.ie "\*(.T"html" .MTO groff@gnu.org "groff-list"
+.el groff-list <groff@gnu.org>
+or directly to the Author.
+.xSH SEE ALSO
+.xBR hdgroff (1),
+.xBR groff_hdd (7),
+.xBR groff_hdmacros (7)
diff --git a/contrib/hdtbl/hdmisc.tmac b/contrib/hdtbl/hdmisc.tmac
new file mode 100644
index 00000000..121a4402
--- /dev/null
+++ b/contrib/hdtbl/hdmisc.tmac
@@ -0,0 +1,531 @@
+.\" -*- mode: roff -*-
+.ig
+
+hdmisc.tmac
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2005, 2006 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 2, 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 groff; see the file COPYING. If not, write to the Free
+Software Foundation, 51 Franklin St - Fifth Floor, Boston, MA
+02110-1301, USA.
+
+..
+.
+.
+.\" %beginstrip%
+.
+.if (\n[?] == 1) \
+. tm HDroff: loading misc. macros file \n[.F].
+.
+.nr *miscs 1
+.
+.
+.\" ******************************************************************
+.\" ** Some macros and default settings needed by hdtbl **
+.\" ******************************************************************
+.\"
+.\" ******************************************************************
+.\" ** Macro getarg: process macro arguments **
+.\" ** **
+.\" ** getarg argname targetname a1=v1 key1 **
+.\" ** a2=v2 key2 ..., mixed **
+.\" ** returns value of arg as string in target. **
+.\" ** arg without value returns the argname. **
+.\" ** `arg=' returns `='. **
+.\" ** after return string `args' contains the remaining args. **
+.\" ******************************************************************
+.de getarg
+. ds \\$1
+. ds args
+.
+. if (\\n[.$] < 2) \
+. return \" speeds up significantly
+.
+. ds $1 \\$1
+. shift
+.
+. length * \\*[$1]
+. \" Change escape char to avoid conflicts with escapes in args.
+. \" Note that it is expected that trailing comments are stripped
+. \" before executing the HDtbl macros.
+. ec 
+. while n[.$] {
+. ds * "$1\"
+. ds ** "$1\"
+. shift
+. substring * 0 (n[*] - 1)
+. ie !"*[$1]"*[*]" {
+. as args " "*[**]"\" arg not found, repeat
+. continue
+. }
+. el {
+. ie "*[**]"*[$1]" 
+. ds *[$1] *[$1]\" return bare arg name as string
+. el {
+. ie "*[**]"*[$1]=" 
+. ds *[$1] =\" return value `=' as string
+. el {
+. substring ** (n[*] + 1) -1
+. ds * *[**]\"
+. substring * 0 0
+.
+. if "*[*]"'" {
+. substring ** 1 -1 \" remove 1st char from arg (')
+. ds * *[**]\"
+. substring * -1 -1 \" remove 2nd char also (')
+.
+. ie "*[*]"'" 
+. substring ** 0 -2 \" yes, skip next clause
+. el {
+. as *[$1] *[**] \" no, append this arg
+.
+. while 1 {
+. ds ** $1\" get next arg
+. ds * $1\"
+. shift
+. substring * -1 -1
+.
+. if "*[*]"'" {
+. substring ** 0 -2
+. break \" leave loop if last char isn't '
+. }
+.
+. as *[$1] *[**] \" otherwise append arg and repeat
+. }
+. }}
+.
+. as *[$1] *[**]
+. }
+.
+. as args " $@
+. }}
+.
+. ec
+. return
+. \} \" end of while
+. ec
+..
+.
+.
+.\"
+.\" ******************************************************************
+.\" ** .index string1 string2 **
+.\" ** returns in reg `index' the index **
+.\" ** of string2 in string1 or 0 **
+.\" ** without string2 reg `index' is -999 **
+.\" ******************************************************************
+.de index
+. if "\\$2"" \{\
+. nr index -999
+. return
+. \}
+.
+. length ** \\$1
+. length $2 \\$2
+. nr * 0-1 1
+.
+. while (\\n+[*] < \\n[**]) \{\
+. ds * \\$1\"
+. substring * \\n[*] (\\n[*] + \\n[$2] - 1)
+. if "\\*[*]"\\$2" \
+. break
+. \}
+.
+. ie (\\n[*] == \\n[**]) \
+. nr index 0
+. el \
+. nr index (\\n[*] + 1)
+..
+.
+.
+.\" ******************************************************************
+.\" ******** non-accumulating space .SP [v] **********
+.\" ** **
+.\" ** nl vor erster Seite -1, oben auf Seite 0 resp. tH **
+.\" ** .k nach .sp oder .br 0, **
+.\" ** sonst Laenge der angefangenen Zeile **
+.\" ** Der Merker M# fuer vorangegangenes .SP wird in .HM am **
+.\" ** Seitenanfang zurueckgesetzt. **
+.\" ** ganz richtig ist .sp + .br = .br + .sp = .sp **
+.\" ******************************************************************
+.de SP
+. if (\\n[nl] < 0) \
+. br \" start very first page
+. nr * \\n[.p] \" save current page length
+.
+. ie "\\$1"" \
+. pl +1 \" without arg increase page length by 1v
+. el \
+. pl +\\$1 \" otherwise use \\$1
+.
+. nr ** (\\n[.p] - \\n[*]) \" ** now holds arg for .SP in base units
+. pl \\n[*]u \" restore page length
+.
+. \" we do nothing at start of new page or column
+. if ((\\n[nl] - \\n[tH]) & (\\n[nl] - \\n[<<]) : \\n[.k]) \{\
+. ie ((\\n[.d] - \\n[M#]) : \\n[.k]) \{\
+. sp \\n[**]u \" execute .sp
+. nr S# \\n[**] \" store ** in S#
+. \}
+. el \{\
+. if (\\n[**] - \\n[S#]) \{\
+. sp (\\n[**]u - \\n[S#]u)\" emit difference to previous .SP
+. nr S# \\n[**] \" store ** in S#
+. \}\}
+.
+. nr M# \\n[.d] \" store vertical position .d in M#
+. \}
+..
+.
+.
+.\" ******************************************************************
+.\" ** Perform all arguments once **
+.\" ** P1 is nestable **
+.\" ******************************************************************
+.de P1
+. \" `while' command is about five times faster than recursion!
+. while \\n[.$] \{\
+. nop \\$1
+. shift
+. \}
+..
+.
+.
+.\" ******************************************************************
+.\" ** Hilfsmakro zum Einstellen von Schriftgroesse und **
+.\" ** Zeilenabstand, bezogen auf Anfangswerte \n[s] und \n[v] **
+.\" ** sowie fuer Hyphenation: **
+.\" ** .pv s v hy# hart; macht .br **
+.\" ** Bei 4. Argument setzen der Register s und v und hy. **
+.\" ** Fuer angefangene Zeile die vorgefundenen Einstellungen **
+.\" ******************************************************************
+.de pv
+. br
+.
+. if \\n[.$] \
+. ps (\\n[s]u * \\$1p / 1p)
+.
+. ie (\\n[.$] - 1) \
+. vs (\\n[v]u * \\$2p / 1p)
+. el \{\
+. vs (\\n[v]u * \\$1p / 1p)
+. return
+. \}
+.
+. if !""\\$3" \
+. hy \\$3
+.
+. if !""\\$4" \{\
+. nr v \\n[.v]
+. nr s \\n[.s]p
+. nr hy \\n[.hy]
+. \}
+..
+.
+.
+.\" ******************************************************************
+.\" ** Hilfsmakros pop/pops/popr (pop stackelement): **
+.\" ** pop or popr: pop register **
+.\" ** pops: pop string **
+.\" ** .pop[s|r] reg|string stackname **
+.\" ** reg|string: name of reg/string to get the **
+.\" ** popped element **
+.\" ** stack: name of stack **
+.\" ******************************************************************
+.de *pop
+. ie "\\$1"pops" \
+. ds \\$2 \\$4\" pop first stackelement
+. el \
+. nr \\$2 \\$4
+.
+. ds $3 \\$3\" remember stackname
+. shift 4 \" shift four args
+.
+. ds \\*[$3] "\\$@\" fill stack with remaining elements
+..
+.
+.de pop
+. *pop \\$0 \\$1 \\$2 \\*[\\$2]
+..
+.
+.als popr pop
+.als pops pop
+.
+.
+.\" ******************************************************************
+.\" ** processs diversion **
+.\" ******************************************************************
+.de DI
+. nr * \\n[.u]
+. nf \" diversion is already formatted - output it unchanged
+. \\$1 \" output the diversion ...
+. rm \\$1 \" ... and remove it
+. if \\n[*] \
+. fi \" reactivate formatting
+..
+.
+.
+.\" ******************************************************************
+.\" ** Some macros and the page setup used by the examples **
+.\" ******************************************************************
+.
+.\" ******************************************************************
+.\" ** some of the following macros use system commands **
+.\" ** and are therefore `unsafe': they need the `-U' argument **
+.\" ** when calling groff/troff **
+.\" ******************************************************************
+.
+.ie n \
+. ds g tty:
+.el \
+. ds g ps: exec
+.
+.
+.\" ******************************************************************
+.\" ** Header macro for the examples **
+.\" ******************************************************************
+.de H
+. nr *w* (17 * \w\\$* / 10 + 4n)
+. TBL border=1n \
+ bc=yellow \
+ bgc=red4 \
+ fgc=yellow \
+ csp=0 \
+ fst=TB \
+ "fsz=1.7 1.5" \
+ hal=c \
+ tal=c \
+ "width=(\\n[*w*]+4n)<?\n[.l]"
+. TR .TD
+. P1 \\$*
+. ETB
+. SP
+..
+.
+.
+.\" ******************************************************************
+.\" ** Utility macro for the date, requires UNIX date. **
+.\" ** after return string *date contains the date in the **
+.\" ** standard form of the Unix date-command, **
+.\" ** for example "Sun Dec 5 22:27:57 2004" **
+.\" ******************************************************************
+.de date
+. pso bash -c "echo -n .ds *date\ ;date"
+. tm \\*[*date] ***
+..
+.
+.
+.\" ******************************************************************
+.\" ** Utility macro for time measurement, requires UNIX date **
+.\" ** .time s[tart]|[end] **
+.\" ** .time start: **
+.\" ** reg *time gets the start-time (seconds) **
+.\" ** .time [end]: **
+.\" ** reg *time gets the difference of the **
+.\" ** end- and start-time (seconds) **
+.\" ******************************************************************
+.de time
+. ds * \\$1\"
+. substring * 0 0
+. ie "\\*[*]"s" \
+. pso bash -c "echo -n .nr *time 0+;date +%s"
+. el \{\
+. pso bash -c "echo -n .nr *time -;date +%s"
+. nr *time 0-\\n[*time]
+. tm elapsed time: \\n[*time] seconds
+. \}
+..
+.
+.
+.\" ******************************************************************
+.\" ** Perform n-times all the arbitrary arguments **
+.\" ** .PN n a2 a3 ... **
+.\" ** PN is nestable **
+.\" ******************************************************************
+.de PN
+. nr *pn +1
+. nr PN\\n[*pn] (\\$1 + 1) 1
+. shift
+.
+. while \\n-[PN\\n[*pn]] \
+. P1 \\$@
+.
+. nr *pn -1
+..
+.
+.
+.de dzx \" help macro for d2x - adds next hex item
+. nr * (\\$1 + 1) 1
+. while \\n-[*] \
+. shift
+. as hex# \\$1
+..
+.
+.
+.\" ******************************************************************
+.\" ** Utility macro; converts decimal number to another base **
+.\" ** and puts result into a string. **
+.\" ** usage: .d2x decimal_number [base [string name]] **
+.\" ** second arg: base; default: 16 **
+.\" ** third arg: name of the string, **
+.\" ** default name: hex# **
+.\" ******************************************************************
+.de d2x
+. if "\\$1"" \{\
+. tm \\n[.F]:\\n[.c]: missing argument.
+. tm1 " usage: `.d2x decimal_number [base [string_name]]'
+. return
+. \}
+.
+. nr i# (-1) 1
+. nr j# 1
+. ds hex#
+. nr dec# (\\$1) 1
+.
+. if !\\$1 \
+. nr dec# (-\\n[dec#])
+.
+. ie !"\\$2"" \
+. nr b# \\$2
+. el \
+. nr b# 16
+.
+. nr xb# 1
+.
+. ie ((\\n[b#] - 1) == 0) \
+. while (\\n-[dec#] + 1) \
+. as hex# |\" bei base=1 Strichliste
+. el \{\
+. while (\\n[dec#] - \\n[xb#]) \{\
+. nr xb# (\\n[xb#] * \\n[b#])
+. nr j# +1
+. \}
+.
+. while (\\n+[i#] < \\n[j#]) \{\
+. nr ** (\\n[dec#] / \\n[xb#])
+. dzx \\n[**] 1 2 3 4 5 6 7 8 9 A B C D E F
+. nr dec# (\\n[dec#] - (\\n[xb#] * \\n[**]))
+. nr xb# (\\n[xb#] / \\n[b#])
+. \}
+. \}
+.
+. \" leading 0 before 1 is suppressed! Why?
+. ds * \\*[hex#]\" if leading zero, strip it
+. substring * 0 0
+. if "\\*[*]"0" \
+. substring hex# 1 -1
+.
+. if (\\$1 < 0) \
+. ds hex# -\\*[hex#]\"
+.
+. if !"\\$3"" \
+. ds \\$3 \\*[hex#]\"
+..
+.
+.
+.\" ******************************************************************
+.\" ** random#: (uses the BASH-variable $RANDOM) **
+.\" ** after completion: _string_ #random contains **
+.\" ** a triple of two-digit-hexnumbers **
+.\" ** (three random numbers 0...255) **
+.\" ******************************************************************
+.de random#
+. pso bash -c "echo -e .ds ss \\\\$RANDOM \\\\$RANDOM \\\\$RANDOM"
+.
+. popr *1 ss
+. nr * (\\n[*1] / 128)
+. d2x \\n[*] 16 $1
+. length * \\*[$1]
+. if (2 - \\n[*]) \
+. ds $1 0\\*[$1]\"
+.
+. popr *2 ss
+. nr * (\\n[*2] / 128)
+. d2x \\n[*] 16 $2
+. length * \\*[$2]
+. if (2 - \\n[*]) \
+. ds $2 0\\*[$2]\"
+.
+. popr *3 ss
+. nr * (\\n[*3] / 128)
+. d2x \\n[*] 16 $3
+. length * \\*[$3]
+. if (2 - \\n[*]) \
+. ds $3 0\\*[$3]\"
+.
+. ds #random #\\*[$1]\\*[$2]\\*[$3]\"
+..
+.
+.
+.\" ******************************************************************
+.\" ** minimal Page setup **
+.\" ******************************************************************
+.nr s \n[.s]p
+.nr v \n[.v]
+.pv 1.2 1.2 "" X
+.nr l 6.6i
+.ll \n[l]u
+.nr o 2c
+.po \n[o]u
+.nr p 29.7c \" pagelength A4
+.pl \n[p]u
+.nr tH 1i
+.sp |\n[tH]u \" text start on the first page
+.
+.ev 99
+.lt \n[l]u
+.ev
+.
+.
+.de HM
+. sp |.5i
+. tl \\*[t*HM]
+. sp |\\n[tH]u
+. ev
+..
+.
+.
+.de BM
+. ev 99
+. sp |(\\n[p]u - .5i)
+. tl \\*[t*BM]
+. bp
+..
+.
+.
+.de EM
+. rm BM \" no page number at bottom of last page
+.
+. if !""\\*[t*kept]" \
+. tm HDroff: kept table left over; add `.bp' at the end of your document.
+. if !""\\*[t*held]" \
+. tm HDroff: held table left over; add `.t*free' at the end of your document.
+. if \\n[t*#] \
+. tm HDrofff: unclosed table (TBL).
+..
+.
+.
+.em EM
+.
+.if "\n[.m]"" \
+. gcolor black
+.if "\n[.M]"" \
+. fcolor white
+.if !\n[*hdtbl] \
+. mso hdtbl.tmac\" load table macros
+.
+.\" EOF
diff --git a/contrib/hdtbl/hdtbl.tmac b/contrib/hdtbl/hdtbl.tmac
new file mode 100644
index 00000000..c352e41f
--- /dev/null
+++ b/contrib/hdtbl/hdtbl.tmac
@@ -0,0 +1,876 @@
+.\" -*- roff -*-
+.ig
+
+hdtbl.tmac
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2005, 2006 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 2, 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 groff; see the file COPYING. If not, write to the Free
+Software Foundation, 51 Franklin St - Fifth Floor, Boston, MA
+02110-1301, USA.
+
+..
+.
+.
+.\" *****************************************************************
+.\" * hdtbl - Heidelberger table macros *
+.\" * Vers. 0.91 December 2005 *
+.\" *****************************************************************
+.
+.if (\n[?] == 1) \
+. tm HDroff: loading table macros file \n[.F].
+.
+.nr *hdtbl 1
+.
+.if !\n[*miscs] \
+. mso hdmisc.tmac
+.
+.wh 0 HM \" comment this, if a page header macro exists
+.wh -1i BM \" comment this, if a bottom margin macro exists
+.
+.\" replace `HM' with the name of your pageheader macro, e.g., `pg@top' for MS
+.am HM
+. t*hm
+..
+.
+.
+.\" *****************************************************************
+.\" * 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
+.
+.
+.\" defaults for table captions
+.nr t*cptn 0 1
+.ds t*cptn "".sp .4" \
+ ".pv 1.4 1.4" \
+ ".ad l" \
+ "\m[\\*[t*fgc]]Table \\n+[t*cptn]:\0\c\k*"\"
+.
+.
+.\" Running title, running footer
+.ds t*HM //arbitrary text for pageheader, except on the first page//\"
+.ds t*BM //arbitrary text for pagefooter, except on the last page/\\n[%]/\"
+.
+.
+.\" %beginstrip%
+.
+.nr t*numb 0 1 \" held table diversion #
+.
+.
+.\" *****************************************************************
+.\" * The four base macros and the two optional macros *
+.\" *****************************************************************
+.
+.\" 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
+. nr t*i \\n[.i]
+. ll -\\n[.i]u
+. in 0
+. \}
+. nr t*# +1
+.
+. ds width
+. nr t*height\\n[t*#] 0
+.
+. getarg cols \\$@\" from here string `args' contains the rest of \\$@
+. ie "\\*[cols]"" \
+. nr t*cols\\n[t*#] \\n[t*cols]
+. el \
+. nr t*cols\\n[t*#] \\*[cols]
+.
+. getarg cpd \\*[args] \" cellpadding
+. ie "\\*[cpd]"" \
+. nr t*cpd\\n[t*#] \\n[t*cpd]
+. el \
+. nr t*cpd\\n[t*#] \\*[cpd]
+.
+. getarg csp \\*[args] \" cellspacing
+. ie "\\*[csp]"" \
+. nr t*csp\\n[t*#] \\n[t*csp]
+. el \
+. nr t*csp\\n[t*#] \\*[csp]
+.
+. getarg border \\*[args] \" border
+. ie "\\*[border]"=" \
+. nr t*b\\n[t*#] 0-1
+. el \{\
+. ie "\\*[border]"" \
+. nr t*b\\n[t*#] \\n[t*b]
+. el \
+. nr t*b\\n[t*#] \\*[border]
+. \}
+.
+. nr b/2\\n[t*#] (\\n[t*b\\n[t*#]] / 2)\" shortcut
+.
+. 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]\"
+. \}
+.
+. getarg width \\*[args] \" table/col widths
+. if "\\*[width]"=" \
+. ds width
+.
+. nr cscp\\n[t*#] (\\n[t*csp\\n[t*#]] + \\n[t*cpd\\n[t*#]])\" aux. register
+.
+. getarg height \\*[args] \" table outline height
+. if !"\\*[height]"" \
+. nr t*height\\n[t*#] (\\*[height] - \
+ ((2 * \\n[cscp\\n[t*#]]) + (3 * \\n[b/2\\n[t*#]])))
+. t*cl \\*[width] \" calculate cellwidths and indents
+. t*args \\n[t*#] \" look for common arguments
+.
+. 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 \
+. tm \\n[.F]:\\n[.c]: invalid tal-value `\\*[tal]': must be l, c or r
+. \}\}
+.
+. nr t*r#\\n[t*#] 0 1 \" rowindex in TBL
+. mk toptbl\\n[t*#]
+.
+. P1 \\*[args]
+.\" \\.. \" XXX
+..
+.
+.
+.\" 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
+. \}
+.
+. getarg val \\$@
+. ds args\\n[t*#] "\\*[args]\"
+.
+. index "\\*[args]" .TR
+. ie \\n[index] \{\
+. ds *a\\n[t*#] "\\*[args]
+. substring args\\n[t*#] 0 \\n[index]
+. substring *a\\n[t*#] \\n[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
+. P1 \\*[t*cptn]
+' in +\\n[*]u
+. P1 \\*[args\\n[t*#]]
+. pv 1 1
+. in
+. mk toptbl\\n[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).
+.
+. 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# of this table
+. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\"
+. nr c#\\*[#t#r] 0 1 \" clear cellcounter
+. nr dntr\\*[#t#r] 0 1 \" clear accumulated row height1
+.
+. getarg height \\$@
+. ie "\\*[height]"" \
+. nr t*height\\*[#t#r] 0
+. el \
+. nr t*height\\*[#t#r] \\*[height]
+.
+. \" Wenn ein TR mit height ist die Gesamthöhe der Tabelle um 3/2 b zu hoch,
+. \" unabhängig von der Zahl der TR mit height.
+. t*args \\*[#t#r] \\n[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
+. TD val=m hal=c fst=B \\$@
+..
+.
+.
+.\" TD: table data cell
+.\" predecessor: text, TD or TR
+.\" successor: text, TD, TR, TBL or ETB
+.de TD
+. ft 1
+. t*dntr 0 \\n[c#\\*[#t#r]]-1 \\\\n[c#\\*[#t#r]] \\*[*#trc*]\" four backslashes!
+.
+. ds *#trc* \\*[#t#r]*\\n[c#\\*[#t#r]]\"
+.
+. getarg rowspan \\$@
+. nr rowspan (\\*[rowspan] >? 1)
+.
+. getarg colspan \\*[args]
+. nr colspan (\\*[colspan] >? 1)
+.
+. 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*#]]
+.
+. while ((\\n[rowspan] - 1) & (\\n+[*] <= \\n[rowspan])) \{\
+. nr rsp\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan]
+. if (\\n[*] > 1) \
+. nr csp\\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 vl\\*[*#trc*] 0-1 \" 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*#]]) \{\
+. tmc \\n[.F]:\\n[.c]: \\n[c#\\*[#t#r]] table cols (.TD);
+. tm1 " only \\n[t*cols\\n[t*#]] were defined.
+. 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]]
+. pv \\*[t*fsz\\*[#trc]]
+.
+. 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 tablestart (.TBL)!
+. \}
+.
+. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh #t#r
+. 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
+.
+. getarg hold \\$@
+. if !\\n[t*#] \{\
+. sp .5
+. di
+. in \\n[t*i]u
+. ie "\\*[hold]"" \{\
+. ie \\n[.t]-\\n[dn] \
+. 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
+. \}
+.
+. 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)
+. while !""\\*[t*held]" \{\
+. pops * t*held
+. popr * t*held
+.
+. ie (\\n[.t] - \\n[*]) \{\
+. ev t*tbl
+. 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[l]u + 1c) \" avoid warning `can't break line'
+. nf
+. nr #r 0 1
+.
+. nr b/2 \\n[b/2\\n[t*#]] \" some abbrevs.
+. 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])
+.
+. \" outer loop for rows
+. while (\\n+[#r] <= \\n[t*r#\\n[t*#]]) \{\
+. \" hier code für mehrseitige Tabellen einfügen
+. nr * (\\n[#r] - 1)
+. nr topdiv +(\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb])
+.
+. \" if table still lower 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]\"
+. if !dt*\\*[#trc] \
+. continue
+.
+. sp |\\n[topdiv]u
+. in (\\n[in\\n[t*#]]u + \\n[in\\*[#trc]]u) \" cell indent
+. nr $1 \\n[dntr\\n[t*#]*\\n[#r]] \" cell height
+.
+. \" if spanned rows calculate resulting row height and lower hl position
+. nr * \\n[#r] 1
+. if \\n[rsp\\*[#trc]] \{\
+. nr rsp\\*[#trc] 0-1 \" set no hl flag
+. nr corr (\\n[dn\\*[#trc]] - \\n[dntr\\n[t*#]*\\n[#r]])
+.
+. while \\n[rsp\\n[t*#]*\\n+[*]*\\n[#c]] \{\
+. nr rsp\\n[t*#]*\\n[*]*\\n[#c] 0 \" clear rsp's in following rows
+. 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]]) \" backgrond 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=n: horizontal/vertical lines n/2 thick, minimum .1n.
+. \" border=0: no border; horizontal/vertical lines .1n thick.
+. \" border= : neither border nor hl/vl's.
+.
+. nr *t (.1n >? \\n[b/2]) \" thickness of hl/vl minimum .1n
+. in +\\n[cscp]u
+.
+. if (1 + \\n[t*b\\n[t*#]]) \{\
+. if !"\\*[t*bc\\n[t*#]]"=" \{\
+. \" possibly hl/vl's:
+. \" draw horizontal line between this and the following table cell
+. if (\\n[t*r#\\n[t*#]] - \\n[#r] + \\n[rsp\\*[#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 rsp\\*[#trc] 0
+.
+. \" draw vertical line between this and the next (right) cell
+. if (\\n[t*cols\\n[t*#]] - \\n[#c] + \\n[vl\\*[#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 vl\\*[#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]
+. \} \" end of while loop for cols
+. \} \" and rows
+.
+. \" 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: calculate cellwidths, tablewidth and indents
+.de t*cl
+. nr t*cols\\n[t*#] (\\n[.$] >? \\n[t*cols\\n[t*#]])
+. nr ll\\n[t*#] 0 1
+. nr ** (\\n[.l] / \\n[t*cols\\n[t*#]])
+. nr * 0 1
+.
+. \" while-loop: calculate
+. while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\
+. ie "\\$[\\n[*]]"" \
+. nr $\\n[*] \\n[**] \" gross width of cells $\n[*] and
+. el \{\
+. ds * \\$\\n[*]\" accumulate table width ll\n[t*#]
+. substring * -1 -1
+. ds ** \\$[\\n[*]]\"
+. substring ** 0 -2
+. ie "\\*[*]"%" \
+. nr $\\n[*] (\\*[**] * \\n[.l] / 100)
+. el \
+. nr $\\n[*] \\$[\\n[*]]
+. \}
+.
+. nr ll\\n[t*#] +\\n[$\\n[*]] \" accumulated tablewidth
+. 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: calculate
+. while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\
+. \" net cellwidths and indents.
+. if \\n[t*b\\n[t*#]] \{\
+. \" avoid multiplication overflow
+. nr #* (1000 * \\n[ll\\n[t*#]] / \\n[t*b\\n[t*#]])
+. nr $\\n[*] (\\n[$\\n[*]] - (1500 * \\n[$\\n[*]] / \\n[#*]))
+. \}
+.
+. \" VVV cellwidth
+. nr cll\\n[t*#]*\\n[*] (\\n[$\\n[*]] \
+ - (2 * \\n[cscp\\n[t*#]]) \
+ - \\n[b/2\\n[t*#]])
+.
+. if !\\n[cll\\n[t*#]*\\n[*]] \{\
+. nr *h ((1000 \
+ * \\n[ll\\n[t*#]] \
+ / (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2)) \
+ * (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]]) \
+ / 1000 \
+ + 50) / 10 * 10)
+. tmc \\n[.F]:\\n[.c]: the \\n[*]th width value (\\$\\n[*]) is too small.
+. tm1 " It should be greater than \\n[*h].
+. \}
+.
+. nr in\\n[t*#]*\\n[*] \\n[**] \" cell indent
+. nr ** +\\n[$\\n[*]]
+. \}
+..
+.
+.
+.\" Utility macro: close TD-diversion, make some calculations and set
+.\" some help strings and registers
+.de t*dntr
+. nr dn 0 \" dn must be reset!
+. br \" finish last div
+.
+. if "\\n[.z]"*t*dummy*" \
+. return
+.
+. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh #t#r
+.
+. if \\n[c#\\*[#t#r]] \{\
+. di
+. nr dn\\$4 \\n[dn] \" height of this cell
+. if !\\n[rsp\\*[#trc]] \{\
+. 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
+.
+. while (\\n+[*] <= \\$3) \{\
+. nr c#\\*[#t#r] +\\n[csp\\*[#t#r]*\\n[*]]
+. nr csp\\*[#t#r]*\\n[*] 0
+. \}
+.
+. ds #trc \\*[#t#r]*\\n[c#\\*[#t#r]]\"
+.
+. if (\\$1 & (\\n[c#\\*[#t#r]] <= \\n[t*cols\\n[t*#]])) \{\
+. tmc \\n[.F]:\\n[.c]: only \\n-[c#\\*[#t#r]] cols in the \\n[t*r#\\n[t*#]]th row;
+. tm1 \\n[t*cols\\n[t*#]] were defined.
+. \}
+..
+.
+.
+.\" Utility-macro: get the arguments common for TBL, TR and TD
+.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
+.
+. 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
+.
+. 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
+.
+. getarg hl \\*[args] \" horizontal line between cells ...
+. if !"\\*[hl]"" \
+. ds t*hl\\$1 \\*[hl]\"
+. if "\\*[args]"" \
+. return
+.
+. getarg vl \\*[args] \" vertical line between cells ...
+. if !"\\*[vl]"" \
+. ds t*vl\\$1 \\*[vl]\"
+. if "\\*[args]"" \
+. return
+.
+. getarg hal \\*[args]
+. if !"\\*[hal]"" \{\
+. index bcrl \\*[hal]
+. ie \\n[index] \
+. ds t*hal\\$1 \\*[hal]\"
+. el \{\
+. tmc \\n[.F]:\\n[.c]: invalid hal-value `\\*[t*hal\\$1]':
+. tm1 " must be b, c, l or r.
+. \}\}
+.
+. if "\\*[args]"" \
+. return
+.
+. getarg val \\*[args] \" vertical table cell alignment
+. if !"\\*[val]"" \{\
+. index tmb \\*[val]
+. ie \\n[index] \
+. ds t*val\\$1 \\*[val]\"
+. el \{\
+. tmc \\n[.F]:\\n[.c]: invalid val-value `\\*[t*val]':
+. tm1 must be t, m or b.
+. \}\}
+.
+. if "\\*[args]"" \
+. return
+.
+. getarg ff \\*[args]
+. if !"\\*[ff]"" \
+. ds t*ff\\$1 \\*[ff]\"
+. if "\\*[args]"" \
+. return
+.
+. getarg fst \\*[args]
+. if !"\\*[fst]"" \
+. ds t*fst\\$1 \\*[fst]\"
+. if "\\*[args]"" \
+. return
+.
+. getarg fsz \\*[args]
+. if !"\\*[fsz]"" \
+. ds t*fsz\\$1 \\*[fsz]\"
+..
+.
+.
+.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
+. \}
+.
+. DI \\*[*]
+. \}
+. ev
+..
+.
+.\" EOF