summaryrefslogtreecommitdiffstats
path: root/contrib/hdtbl
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/hdtbl')
-rw-r--r--contrib/hdtbl/ChangeLog548
-rw-r--r--contrib/hdtbl/TODO21
-rw-r--r--contrib/hdtbl/examples/chess_board.roff64
-rw-r--r--contrib/hdtbl/examples/col_rowspan_colors.roff82
-rw-r--r--contrib/hdtbl/examples/color_boxes.roff52
-rw-r--r--contrib/hdtbl/examples/color_nested_tables.roff60
-rw-r--r--contrib/hdtbl/examples/color_table_cells.roff54
-rw-r--r--contrib/hdtbl/examples/color_transitions.roff58
-rw-r--r--contrib/hdtbl/examples/common.roff295
-rw-r--r--contrib/hdtbl/examples/fonts_n.in149
-rw-r--r--contrib/hdtbl/examples/fonts_x.in160
-rw-r--r--contrib/hdtbl/examples/mixed_pickles.roff104
-rw-r--r--contrib/hdtbl/examples/rainbow.roff86
-rw-r--r--contrib/hdtbl/examples/short_reference.roff86
-rw-r--r--contrib/hdtbl/examples/test-hdtbl.sh.in47
-rw-r--r--contrib/hdtbl/groff_hdtbl.7.man1346
-rw-r--r--contrib/hdtbl/hdmisc.tmac327
-rw-r--r--contrib/hdtbl/hdtbl.am136
-rw-r--r--contrib/hdtbl/hdtbl.tmac1003
19 files changed, 4678 insertions, 0 deletions
diff --git a/contrib/hdtbl/ChangeLog b/contrib/hdtbl/ChangeLog
new file mode 100644
index 0000000..a0a1e8d
--- /dev/null
+++ b/contrib/hdtbl/ChangeLog
@@ -0,0 +1,548 @@
+2022-06-21 G. Branden Robinson <g.branden.robinson@gmail.com>
+
+ * hdtbl.am (HDTBLPROCESSEDEXAMPLEFILES): Add dependency on
+ grops.
+
+2022-05-01 G. Branden Robinson <g.branden.robinson@gmail.com>
+
+ * hdtbl.am (HDTBLPROCESSEDEXAMPLEFILES): Add dependency on devps
+ stamp file since the files' target rule generates PostScript
+ with groff.
+
+2022-04-12 Ingo Schwarze <schwarze@openbsd.org>
+
+ Delete the harmful, ill-designed, buggy, and essentially
+ unmaintained and untested --with-doc option of the configure
+ script. See the NEWS file for more details on the rationale.
+
+ * hdtbl.am: Delete two BUILD_EXAMPLES conditionals.
+
+2022-03-30 G. Branden Robinson <g.branden.robinson@gmail.com>
+
+ * hdtbl.am: Eliminate `HDTBL_TFLAG` and `HDTBL_PFLAG` Make
+ macros; they were expanded in only one place.
+ (HDTBLGROFF): Track rename of Make macro `TFLAG` to `MFLAG`.
+
+2022-03-30 G. Branden Robinson <g.branden.robinson@gmail.com>
+
+ * examples/mixed_pickles.ms: Die horribly if `PSPIC` call fails.
+
+2022-03-26 G. Branden Robinson <g.branden.robinson@gmail.com>
+
+ * hdtbl.am (nodist_hdtblexample_DATA,
+ HDTBLPROCESSEDEXAMPLEFILES): Replace hard-coded "gnu.eps" file
+ name with expansion of `DOC_GNU_EPS`.
+ (HDTBLPROCESSEDEXAMPLEFILES): Pass `-I` option to `HDTBLGROFF`
+ to enable location of "gnu.eps" file (for "mixedpickles.roff"
+ document).
+
+2021-10-21 G. Branden Robinson <g.branden.robinson@gmail.com>
+
+ * hdtbl.am:
+ (hdtbl_test_template): Pull file name into a new variable.
+ (EXTRA_DIST, contrib/hdtbl/examples/test-hdtbl.sh): Use it.
+ (contrib/hdtbl/examples/test-hdtbl.sh): Build more quietly;
+ prefix rule with `$(AM_V_GEN)`. Also run `chmod` conditionally.
+
+2021-07-11 G. Branden Robinson <g.branden.robinson@gmail.com>
+
+ * hdtbl.am: Remove unnecessary Make variable.
+ (hdtbl_builddir): Delete.
+ (HDTBL_TFLAG): Remove `-M$(hdtbl_builddir)` option; it's no
+ longer needed for hdtbl example document generation needed now
+ that hdtbl is no longer stripped.
+
+2021-07-01 G. Branden Robinson <g.branden.robinson@gmail.com>
+
+ Skip the stripper, part 2/3 ("hdtbl").
+
+ * hdmisc.tmac-u: Rename to...
+ * hdmisc.tmac: ...this.
+
+ * hdtbl.tmac-u: Rename to...
+ * hdtbl.tmac: ...this.
+
+ * hdtbl.am (HDSTRIPFILES): Rename to...
+ (HDTBLTMACFILES): ...this.
+ (hdtbltmac_DATA): Rename to...
+ (dist_hdtbltmac_DATA): ...this.
+ (MOSTLYCLEANFILES): Drop $(HDTBLSTRIPFILES).
+ ($(HDTBLSTRIPFILES)): Drop target.
+
+2018-12-26 Ingo Schwarze <schwarze@openbsd.org>
+
+ A missing prerequisite could cause parallel builds to fail.
+
+ * hdtbl.am (HDTBLPROCESSEDEXAMPLEFILES): requires eqn
+ because the .roff.ps target runs HDTBLGROFF =
+ GROFFBIN ... HDTBL_PFLAG = groff ... -t -p -e -U
+ which includes -e.
+
+2018-12-06 Ingo Schwarze <schwarze@openbsd.org>
+
+ * examples/fonts_n.in, examples/fonts_x.in:
+ Make the shell script in the .pso request more portable:
+ 1. POSIX requires "echo -n" to print "-n" followed by
+ a newline character, so use printf(1) instead.
+ 2. According to POSIX, behaviour of tr(1) is undefined
+ if string2 contains fewer characters than string1,
+ and on Oracle Solaris, the excess characters in string1
+ are not translated. So make sure string2 contains
+ a sufficient number of characters.
+
+2018-12-05 Bertrand Garrigues <bertrand.garrigues@laposte.net>
+
+ Skip tests if needed config is missing.
+
+ * examples/test-hdtbl.sh.in: exit 77 (indicates automake
+ to skip the result) if 'gs' is missing.
+
+ * hdtbl.am: flag correctly test program generation.
+
+2018-11-25 Bertrand Garrigues <bertrand.garrigues@laposte.net>
+
+ Clean hdtbl.am
+
+ * hdtbl.am (MOSTLYCLEANFILES): Remove 'hdmisc.tmac-s'
+ and 'hdtbl.tmac-s' (these files are no longer present).
+
+ Fixes https://savannah.gnu.org/bugs/index.php?55083, reported by
+ Bjarni Ingi Gislason <bjarniig@rhi.hi.is>.
+
+2018-11-13 G. Branden Robinson <g.branden.robinson@gmail.com>
+
+ Don't clean other people's unit tests.
+
+ * hdtbl.am: test-hdtbl.sh is generated from an .in file,
+ so while we can add it to $(TESTS), we shouldn't then add
+ $(TESTS) to $(MOSTLYCLEANFILES) or we will clobber all tests
+ that ever get defined. This clobbered gdiffmk's test script on
+ in-tree builds. Give it its own variable, $(hdtbl_TESTS).
+ Now it clobbers no more.
+
+ Fixes <https://savannah.gnu.org/bugs/index.php?55020>.
+
+2018-11-12 G. Branden Robinson <g.branden.robinson@gmail.com>
+
+ * hdtbl.am: Remove examples/test-hdtbl.sh on 'make distclean'.
+
+2018-11-07 Bertrand Garrigues <bertrand.garrigues@laposte.net>
+
+ Add a sanity check on 2 examples.
+
+ * examples/test-hdtbl.sh.in: new test script that uses 'gs'
+ to check the number of pages of 'fonts_x.ps' and 'fonts_n.ps'.
+
+ * hdtbl.am: connect 'test-hdtbl.sh' to 'make check'
+
+2018-08-09 Ingo Schwarze <schwarze@openbsd.org>
+
+ * examples/common.roff: Remove more dead code
+ since the date and time are no longer used.
+
+ Reported by Bjarni Ingi Gislason in Savannah bug #54461.
+
+2018-08-09 Ingo Schwarze <schwarze@openbsd.org>
+
+ * examples/common.roff, examples/col_rowspan_colors.roff,
+ examples/short_reference.roff: do forgotten renamings .pv -> .t*pv
+
+ Fixing it improves the formatting of all hdtbl examples.
+ Reported by Bjarni Ingi Gislason in Savannah bug #54470.
+
+2018-08-04 Ingo Schwarze <schwarze@openbsd.org>
+
+ * examples/*: delete the date and time macros
+ * examples/hdtbl.am: run groff without -U option
+
+2018-03-11 Colin Watson <cjwatson@debian.org>
+
+ Remove unnecessary randomness from example output.
+
+ The examples don't need good randomness, as they're only
+ example output; removing the process ID from consideration
+ allows better integration with reproducible builds.
+
+ * examples/common.roff (random-s1): Remove process ID.
+
+2018-02-28 Werner LEMBERG <wl@gnu.org>
+
+ * hdtbl.am (.roff.ps, .in.roff): Use $(GROFF_V) and $(AM_V_GEN).
+
+2017-11-30 G. Branden Robinson <g.branden.robinson@gmail.com>
+
+ * examples/common.roff:
+ * examples/fonts_n.in:
+ * examples/fonts_x.in:
+ Make writers to stderr identify themselves.
+
+2017-11-19 G. Branden Robinson <g.branden.robinson@gmail.com>
+
+ * examples/*.roff: Seed RNG.
+
+ * examples/col_rowspan_colors.roff:
+ * examples/color_boxes.roff:
+ * examples/color_nested_tables.roff:
+ * examples/color_table_cells.roff:
+ Support reproducible builds by seeding hdtbl's random
+ number generator (in examples/common.roff).
+
+ Fix issue https://savannah.gnu.org/bugs/?52462.
+
+2017-11-01 Bjarni Ingi Gislason <bjarniig@rhi.hi.is>
+
+ hdtbl.tmac-u: Fix ignored escape sequence.
+
+ The escape '\c' ignores everything after it, except "\R...".
+
+ Fix bug https://savannah.gnu.org/bugs/?51609.
+
+2015-08-22 Bernd Warken <groff-bernd.warken-72@web.de>
+
+ * groff_hdtbl.7.man: Rename `groff_hdtbl.man'.
+
+ * hdtbl.am: Include renaming.
+
+2015-08-05 Bernd Warken <groff-bernd.warken-72@web.de>
+
+ * hdtbl.am: Add `Last update'. Setup Emacs mode.
+
+2015-04-03 Werner LEMBERG <wl@gnu.org>
+
+ Fix Savannah bug #44798.
+
+ * examples/fonts_n.in, examples/fonts_x.in: Use @EGREP@.
+
+ * hdtbl.am (.in.roff): Handle @EGREP@.
+
+2015-04-03 Werner LEMBERG <wl@gnu.org>
+
+ * groff_hdtbl.man: Make it work in compatibility mode.
+
+2013-09-03 Bernd Warken <groff-bernd.warken-72@web.de>
+
+ * all files in groff_hdtbl: Copying and Emacs setup.
+
+2014-03-29 Steffen Nurpmeso <sdaoden@yandex.com>
+
+ * Makefile.sub: Handle examples separately, controlled by
+ $(make{_,_install_,_uninstall_}examples).
+
+2013-02-06 Werner LEMBERG <wl@gnu.org>
+
+ * groff_hdtbl.man: Correct details on loading hdtbl.tmac.
+
+2013-02-04 Werner LEMBERG <wl@gnu.org>
+
+ * groff_hdtbl.man: Revised.
+
+2013-02-03 Bernd Warken <groff-bernd.warken-72@web.de>
+
+ * groff_hdtbl.man: Correct and extend this man-page.
+
+2012-09-20 Werner LEMBERG <wl@gnu.org>
+
+ Simplify environment handling.
+
+ Suggested by Ivan Shmakov <oneingray@gmail.com>.
+
+ * Makefile.sub (GROFF): Don't use export.
+
+2011-01-17 Werner LEMBERG <wl@gnu.org>
+
+ * examples/color_nested_tables.roff: Fix output.
+
+ Problem reported by Ulrich Spörlein <uqs@spoerlein.net>.
+
+2011-01-17 Ulrich Spörlein <uqs@spoerlein.net>
+
+ Don't make examples depend on bash.
+
+ * examples/common.roff, examples/fonts_n.in, examples/fonts_x.in:
+ s/bash/sh/.
+
+2010-02-09 Werner LEMBERG <wl@gnu.org>
+
+ Make example compilation work again if srcdir != builddir.
+
+ * Makefile.sub (.roff.ps): Define `sopath' groff string.
+
+ * examples/*.roff, examples/*.in: Use it so that .so finds its input
+ file.
+
+2010-02-08 Werner LEMBEARG <wl@gnu.org>
+
+ Fix handling of `common.roff'.
+
+ * Makefile.sub (MOSTLYCLEANADD): Don't handle `common.roff'.
+ (EXAMPLEFILES): Handle `common.roff'.
+
+2010-02-08 Larry Kollar <kollar@alltel.net>
+
+ Fix last patch and use `t*' prefix for all non-public stuff.
+ Other minor fixes.
+
+ * hdmisc.tmac (getarg, index, SP, P1, \n[s], \n[v], \n[hy], pv, DI):
+ Rename to...
+ (t*getarg, t*index, t*SP, t*P1, \n[t*s], \n[t*v], \n[t*hy], t*pv,
+ t*DI): This.
+ Update all callers.
+ (t*EM): New auxiliary macro (using stuff from
+ `examples/common.roff'.
+
+ * hdtbl.tmac (\n[t*v], \n[t*s], \n[t*hy], \n[t*l]): Initialize.
+ (\n[t*FN], \n[t*LN]): New number registers.
+
+ * examples/*.roff: Updated.
+ * examples/common.roff: Load `hdtbl.tmac' earlier.
+ Reinstall `HM' and `BM' traps.
+ Provide `SP' macros if not defined by other macro package.
+ (\n[p], \n[o]): Initialize.
+ (\*[t*HM], \*[t*BM]): Initialize.
+ (EM): Use `t*EM'.
+ Updated.
+
+ * examples/fonts_n.in, examples/fonts_x.in: Load
+ `examples/common.roff'.
+ Updated.
+
+ * groff_hdtbl.man: Document setup of default values.
+ Document `t*EM'.
+
+2010-01-23 Larry Kollar <kollar@alltel.net>
+
+ Break out example formatting to a separate file.
+
+ * hdmisc.tmac: Move example formatting stuff to...
+ * examples/common.roff: This new file.
+
+ * hdtbl.tmac (HM, t*HM, BM, t*BM): Remove.
+
+ * examples/*.roff: Include `common.roff'.
+
+ * groff_hdtbl.man: Remove references to `HM' and `BM'.
+
+ * Makefile.sub: Handle `examples/common.roff'.
+
+2009-04-05 Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>
+
+ * hdtbl.tmac (ETB, t*free): Correct two typos, fixing register
+ incrementation.
+
+2009-01-04 Werner LEMBERG <wl@gnu.org>
+
+ * Makefile.sub (CLEANADD): Add hdmisc.tmac-s and hdtbl.tmac-s.
+
+2009-01-03 Werner LEMBERG <wl@gnu.org>
+
+ * README: Renamed to...
+ * TODO: This, removing most of its contents.
+
+ * groff_hdtbl.man: Add customization info which was in file README.
+
+2008-01-04 Werner LEMBERG <wl@gnu.org>
+
+ * groff_hdtbl.man: Replace .MTO with .MT/.ME.
+ Don't include www.tmac.
+
+2006-11-17 Werner LEMBERG <wl@gnu.org>
+
+ * Makefile.sub (install_data): Depend on gnu.eps also.
+ (uninstall_sub): Remove gnu.eps also.
+
+2006-11-17 Werner LEMBERG <wl@gnu.org>
+
+ * hdmisc.tmac: Avoid loading itself more than once.
+ Load hdtbl.tmac unconditionally.
+ (\n[?], \n[*miscs]): Remove.
+ (random-s1): Use only 9 digits.
+
+ * hdtbl.tmac: Avoid loading itself more than once.
+ Load hdmisc.tmac unconditionally.
+ Load 62bit.tmac
+ (\n[*hdtbl]): Removed.
+ (t*cl): Prevent scaling overflow by using routines from 62bit.tmac.
+
+2006-11-15 Werner LEMBERG <wl@gnu.org>
+
+ * hdmisc.tmac (d2x): Use string array instead of `dzx' macro.
+ Improve error handling.
+ (dzx): Removed.
+ (random#): Rewrite to generate random numbers by itself instead of
+ using an external command.
+
+2006-11-06 Joachim Walsdorff <JWalsdorff@compuserve.de>
+
+ * hdmisc.tmac (\*[g]): Move definition back to...
+ * hdtbl.tmac: This file.
+ (TD, t*divs): Fix a bug with consecutive groups of spanned rows by
+ introducing string *rsp*\\*[#trc]. Reported by Barry Nisly.
+ (TH): Add arguments `hal', `val', and `fst'.
+
+2006-11-01 Werner LEMBERG <wl@gnu.org>
+
+ * hdtbl.tmac (t*divs): Fix a bug which causes incorrect table cell
+ heights if the `rowspan' keyword is used. This problem has been
+ introduced during the beautification process by introducing
+ incorrect parentheses.
+ Other minor modifications.
+ (\n[rsp...]): Array renamed to...
+ (\n[rspan...]): This.
+ (\n[csp...]): Array renamed to...
+ (\n[cspan...]): This.
+ (\n[vl...]): Array renamed to...
+ (\n[vline...]): This.
+
+2006-10-27 Werner LEMBERG <wl@gnu.org>
+
+ * hdmisc.tmac (EM): Improve warning messages.
+
+ * hdtbl.tmac (TD): Move constant comparison out of while loop.
+
+2006-10-26 Werner LEMBERG <wl@gnu.org>
+
+ * hdmisc.tmac: Add `\"' at various places to protect against
+ trailing spaces.
+ (getarg): Don't use a different escape character but
+ `\?' escapes to protect against incomplete input.
+ Improve documentation.
+
+ * hdtbl.tmac: Improve various warning messages.
+ (TR): Add validity check for `height' keyword.
+ (TD): Don't use `\\\\' but `\E'.
+ (\*[*#trc*]): Initialize.
+ (t*dntr): Avoid undefined register warning.
+
+2006-10-23 Werner LEMBERG <wl@gnu.org>
+
+ * hdtbl.tmac (\n[t*#]): Initialize.
+ (TBL): Don't initialize `\*[width]'.
+ Add validity checks for all keywords.
+ (TD): Add validity checks for `rowspan' and `colspan' keywords.
+ (t*cl): Add validity checks for cell widths.
+
+2006-09-13 Werner LEMBERG <wl@gnu.org>
+
+ * examples/fontdumps_n.in, examples/fontdumps_x.in: Renamed to...
+ * examples/fonts_n.in, examples/fonts_x.in: This.
+
+ * examples/colored_boxes.roff, examples/colored_nested_tables.roff,
+ examples/colored_table_cells.roff: Renamed to...
+ * examples/color_boxes.roff, examples/color_nested_tables.roff,
+ examples/color_table_cells.roff: This.
+
+ * Makefile.sub: Updated.
+
+2006-06-21 Werner LEMBERG <wl@gnu.org>
+
+ * examples/fontdumps_n.roff, examples/fontdumps_x.roff: Renamed
+ to...
+ * example/fontdumps_n.in, example/fontdumps_x_in: This.
+ Rename `*fontpath' to `fontpath' and define it conditionally (using
+ `@fontdir@') so that it can be overridden on the command line.
+
+ * Makefile.sub (GENFILES, GENFILES_): New variables for
+ fontdumps*.roff.
+ (EXAMPLEFILES): Remove fontdumps.roff.
+ (CLEANADD): Add GENFILES.
+ (.in.roff): New rule.
+ (.SUFFIXES): Add `.in'.
+ (install_data, uninstall_sub): Updated.
+
+2006-06-14 Werner LEMBERG <wl@gnu.org>
+
+ * hdmisc.tmac: Fix test for \n[?] to avoid warning message.
+ s/\n[.s]p/\n[.ps]/.
+ (pv): Use `z' scaling indicator.
+
+ * hdtbl.tmac: Fix test for \n[?] and \n[*miscs] to avoid warning
+ messages.
+
+2006-06-11 Werner LEMBERG <wl@gnu.org>
+
+ * groff_hdtbl.man: Use `.ig' block after NAME section to make mandb
+ happy.
+
+2006-06-05 Werner LEMBERG <wl@gnu.org>
+
+ * hdmisc.tmac (index): Use `\?' to emulate string comparison.
+
+2006-06-04 Werner LEMBERG <wl@gnu.org>
+
+ * hdtbl.tmac: Improve error messages. In particular, handle
+ singular and plural correctly by using a pseudo array `nth-{1,2,3}'.
+
+ * examples/rainbow.roff: Add copyright notice. Formatting.
+
+2006-05-31 Werner LEMBERG <wl@gnu.org>
+
+ * examples/fontdumps_x.roff, examples/fontdumps_n.roff: Protect
+ argument of `tr' command in `.pso' call.
+
+2006-05-30 Werner LEMBERG <wl@gnu.org>
+
+ * examples/fontdumps_x.roff: Remove warnings about
+ non-existent glyphs.
+ Add copyright notice.
+ Formatting.
+
+ * hdtbl.tmac: Replace character >= 0x80.
+
+2006-05-29 Werner LEMBERG <wl@gnu.org>
+
+ * Makefile.sub: New file.
+ * examples/*: Replace characters >= 0x80.
+ Add final newlines.
+ Use UNIX line end convention only.
+ * examples/mixed-pickles.roff: Use gnu.eps.
+ Add copyright notice.
+ Adjust pic image.
+ Other minor fixes.
+ Formatting.
+ * examples/fontdumps_n.roff: Remove warnings about
+ non-existent glyphs.
+ Add copyright notice.
+ Formatting.
+
+2006-05-25 Werner LEMBERG <wl@gnu.org>
+
+ * examples/*: Rename to...
+ * examples/*.roff: This.
+
+2006-05-24 Werner LEMBERG <wl@gnu.org>
+
+ * groff_hdtbl.man: Simplify macros for switching from and to the `C'
+ font family, as suggested by Tadziu Hoffmann.
+
+2006-05-22 Werner LEMBERG <wl@gnu.org>
+
+ * groff_hdtbl.man: Completely revised again.
+ `Normalize' font usage: Add macros similar to `.B' and `.BI' for
+ switching from and to the `C' font family, instead of using \f.
+ Fix appearance of macro syntax descriptions.
+ Add more quotation characters.
+
+2006-05-21 Werner LEMBERG <wl@gnu.org>
+
+ * groff_hdtbl.man: Completely revised.
+
+2006-05-20 Werner LEMBERG <wl@gnu.org>
+
+ * Import of hdtbl 0.91 (with some further modifications). Still
+ many rough edges.
+
+________________________________________________________________________
+
+Copyright 2006-2020 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+coding: latin-1
+fill-column: 72
+mode: change-log
+version-control: never
+End:
+vim:set autoindent textwidth=72:
diff --git a/contrib/hdtbl/TODO b/contrib/hdtbl/TODO
new file mode 100644
index 0000000..a3684e5
--- /dev/null
+++ b/contrib/hdtbl/TODO
@@ -0,0 +1,21 @@
+TODO
+----
+
+* Macro TOTC (Table Of Table Captions).
+
+* Automatic recognition of the number of columns.
+
+* Optional automatic calculation of the cell widths from the widths of the
+ first line of the cell content instead of the explicit specification with
+ the width argument. This seems to be non-trivial without a preprocessor
+ or additional external calls via .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.
+
+* Support for -Thtml.
diff --git a/contrib/hdtbl/examples/chess_board.roff b/contrib/hdtbl/examples/chess_board.roff
new file mode 100644
index 0000000..171d95e
--- /dev/null
+++ b/contrib/hdtbl/examples/chess_board.roff
@@ -0,0 +1,64 @@
+.ig
+chess_board.roff
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2005-2020 Free Software Foundation, Inc.
+written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+..
+.
+.if !d sopath \
+. ds sopath
+.
+.so \*[sopath]examples/common.roff
+.
+.
+.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
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" fill-column: 72
+.\" End:
+.\" vim: set filetype=groff textwidth=72:
diff --git a/contrib/hdtbl/examples/col_rowspan_colors.roff b/contrib/hdtbl/examples/col_rowspan_colors.roff
new file mode 100644
index 0000000..90f2e7a
--- /dev/null
+++ b/contrib/hdtbl/examples/col_rowspan_colors.roff
@@ -0,0 +1,82 @@
+.ig
+col_rowspan_colors.roff
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2005-2020 Free Software Foundation, Inc.
+written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+..
+.
+.if !d sopath \
+. ds sopath
+.
+.so \*[sopath]examples/common.roff
+.
+.\" Seed the random number generator for reproducible builds.
+.random-seed 131545532 19201711
+.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
+. tm1 " 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#"
+.\}
+.t*P1 \\*[html]
+..
+.
+.t*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=11 width=1c tal=c csp=0 cpd=0 \"cols must be odd
+.CPTN val=b Randomly Colored Table Cells with Colspan/\%Rowspan
+.brt
+.ETB .ETB
+.PN 15 Text after table.
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" fill-column: 72
+.\" End:
+.\" vim: set filetype=groff textwidth=72:
diff --git a/contrib/hdtbl/examples/color_boxes.roff b/contrib/hdtbl/examples/color_boxes.roff
new file mode 100644
index 0000000..65538a7
--- /dev/null
+++ b/contrib/hdtbl/examples/color_boxes.roff
@@ -0,0 +1,52 @@
+.ig
+color_boxes.roff
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2005-2020 Free Software Foundation, Inc.
+written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+..
+.
+.if !d sopath \
+. ds sopath
+.
+.so \*[sopath]examples/common.roff
+.
+.\" Seed the random number generator for reproducible builds.
+.random-seed 131545532 19201711
+.
+.H Horizontal Rules and Boxes .br with Randomly 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 after table.
+.TBL border=.5n bc=color1 bgc=color2 width=15c tal=c csp=.2n cpd=.3n .TR .TD .ETB
+.PN 25 Text after horizontal rule.
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" fill-column: 72
+.\" End:
+.\" vim: set filetype=groff textwidth=72:
diff --git a/contrib/hdtbl/examples/color_nested_tables.roff b/contrib/hdtbl/examples/color_nested_tables.roff
new file mode 100644
index 0000000..946d297
--- /dev/null
+++ b/contrib/hdtbl/examples/color_nested_tables.roff
@@ -0,0 +1,60 @@
+.ig
+
+color_nested_tables.roff
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2005-2020 Free Software Foundation, Inc.
+written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+..
+.
+.if !d sopath \
+. ds sopath
+.
+.so \*[sopath]examples/common.roff
+.
+.
+.\" Seed the random number generator for reproducible builds.
+.random-seed 131545532 19201711
+.
+.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 Randomly Colored Border" \
+ .TR .TD
+.PN 39 .ETB
+.PN 15 Text after first table.
+.
+.bp
+.
+.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 Randomly Colored Background" \
+ .TR .TD
+.PN 39 .ETB
+.PN 25 Text after second table.
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" fill-column: 72
+.\" End:
+.\" vim: set filetype=groff textwidth=72:
diff --git a/contrib/hdtbl/examples/color_table_cells.roff b/contrib/hdtbl/examples/color_table_cells.roff
new file mode 100644
index 0000000..65489cb
--- /dev/null
+++ b/contrib/hdtbl/examples/color_table_cells.roff
@@ -0,0 +1,54 @@
+.ig
+
+color_table_cells.roff
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2005-2020 Free Software Foundation, Inc.
+written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+..
+.
+.if !d sopath \
+. ds sopath
+.
+.so \*[sopath]examples/common.roff
+.
+.\" Seed the random number generator for reproducible builds.
+.random-seed 131545532 19201711
+.
+.H Horizontal Rules and Randomly Colored Table Cells
+.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 after table.
+.TBL border=.5n bc=c1 bgc=c2 width=15c tal=c csp=.2n cpd=.3n .TR .TD .ETB
+.PN 15 Text after HR.
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" fill-column: 72
+.\" End:
+.\" vim: set filetype=groff textwidth=72:
diff --git a/contrib/hdtbl/examples/color_transitions.roff b/contrib/hdtbl/examples/color_transitions.roff
new file mode 100644
index 0000000..be69b7c
--- /dev/null
+++ b/contrib/hdtbl/examples/color_transitions.roff
@@ -0,0 +1,58 @@
+.ig
+
+color_transitions.roff
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2005-2020 Free Software Foundation, Inc.
+written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+..
+.
+.if !d sopath \
+. ds sopath
+.
+.so \*[sopath]examples/common.roff
+.
+.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" \" black -> white
+.TD ".ctab 1f-\En[#cc]u 1f-\En[#cc]u 1f-\En[#cc]u"\" white -> black
+.TD ".ctab 1f \En[#cc]u \En[#cc]u" \" red -> white
+.TR
+.TD ".ctab 0 1f-\En[#cc]u \En[#cc]u" \" green -> blue
+.TD ".ctab 1f 1f-\En[#cc]u 1f" \" white -> magenta
+.TD ".ctab 1f \En[#cc]u 1f" \" magenta -> white
+.TR
+.TD ".ctab 0+\En[#cc]u \En[#cc]u 1f-\En[#cc]u" \" blue -> yellow
+.TD ".ctab 1f-\En[#cc]u 1f-\En[#cc]u \En[#cc]u" \" yellow -> blue
+.TD ".ctab 1f 0+\En[#cc]u 0" \" red -> yellow
+.xTD ".ctab 0+\En[#cc]u 1f-\En[#cc]u 1f-\En[#cc]u"\" cyan -> red
+.ETB
+.PN 30 After table.
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" fill-column: 72
+.\" End:
+.\" vim: set filetype=groff textwidth=72:
diff --git a/contrib/hdtbl/examples/common.roff b/contrib/hdtbl/examples/common.roff
new file mode 100644
index 0000000..a9c02a0
--- /dev/null
+++ b/contrib/hdtbl/examples/common.roff
@@ -0,0 +1,295 @@
+.ig
+
+common.roff
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2010-2020 Free Software Foundation, Inc.
+written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+..
+.
+.
+.ds common common.roff\" name for diagnostic messages
+.mso hdtbl.tmac\" load table macros
+.
+.\" ******************************************************************
+.\" ** Some macros and the page setup used by the examples **
+.\" ******************************************************************
+.
+.\" ******************************************************************
+.\" ** 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
+. t*P1 \\$*
+. ETB
+. SP
+..
+.
+.
+.\" ******************************************************************
+.\" ** 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]] \
+. t*P1 \\$@
+.
+. nr *pn -1
+..
+.
+.
+.\" Utility macro: .d2x decimal_number [base [string_name]]
+.\"
+.\" Convert 'decimal_number' to another base 'base' (in the
+.\" range 1..16) and store the result in string 'string_name'.
+.\" If 'base' is missing or empty, convert to a hexadecimal
+.\" number. If 'string_name' is missing or empty, return value
+.\" in string 'hex#', otherwise return the value in both
+.\" 'string_name' and 'hex#'.
+.\"
+.\" The base value 1 is handled specially: The returned
+.\" string contains the character '|' 'decimal_number' times
+.\" (for example, input value 4 yields '||||').
+.ds d2x-0 0\"
+.ds d2x-1 1\"
+.ds d2x-2 2\"
+.ds d2x-3 3\"
+.ds d2x-4 4\"
+.ds d2x-5 5\"
+.ds d2x-6 6\"
+.ds d2x-7 7\"
+.ds d2x-8 8\"
+.ds d2x-9 9\"
+.ds d2x-10 A\"
+.ds d2x-11 B\"
+.ds d2x-12 C\"
+.ds d2x-13 D\"
+.ds d2x-14 E\"
+.ds d2x-15 F\"
+.
+.
+.de d2x
+. if !\B\\$1 \{\
+. tmc \\*[common]: \\n[.F]:\\n[.c]: d2x: invalid or missing first
+. tm argument
+. tm \\*[common]: 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"" \{\
+. ie !\B\\$2 \
+. tm \\*[common]: \\n[.F]:\\n[.c]: d2x: invalid base '\\$2'
+. el \
+. ie ((\\$2 < 1) : (\\$2 > 16)) \
+. tm \\*[common]: \\n[.F]:\\n[.c]: d2x: invalid base '\\$2'
+. el \
+. nr b# \\$2
+. \}\}
+. el \
+. nr b# 16
+.
+. nr xb# 1
+.
+. ie (\\n[b#] == 1) \{\
+. nr dec# +1
+. while \\n-[dec#] \
+. as hex# |\"
+. \}
+. 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#])
+. as hex# \\*[d2x-\\n[**]]\"
+. nr dec# (\\n[dec#] - (\\n[xb#] * \\n[**]))
+. nr xb# (\\n[xb#] / \\n[b#])
+. \}
+. \}
+.
+. \" strip leading zero, if any
+. ds * \\*[hex#]\"
+. substring * 0 0
+. if "\\*[*]"0" \
+. substring hex# 1 -1
+.
+. if (\\$1 < 0) \
+. ds hex# -\\*[hex#]\"
+.
+. if !"\\$3"" \{\
+. ie !\A\\$3 \
+. tm \\*[common]: \\n[.F]:\\n[.c]: d2x: invalid string name '\\$3'
+. el \
+. ds \\$3 \\*[hex#]\"
+. \}
+..
+.
+.
+.\" Utility macro: .random#
+.\" .random-seed seed1 seed2
+.\"
+.\" Return pseudo-random numbers in the range 0..0xFFFFFF,
+.\" represented as the concatenation of '#' and six
+.\" hexadecimal digits, in the string '#random'. The
+.\" macro 'random-seed' can be used to set seed values,
+.\" which should be integers in the range 1..2147483562 and
+.\" 1..2147483398 for 'seed1' and 'seed2', respectively
+.\" (the macro applies a modulo operation to assure this
+.\" range). If 'random-seed' isn't called the registers
+.\" start at some constant, arbitrary values.
+.\"
+.\" The used generator is presented in L'Ecuyer's 1988 paper
+.\" 'Efficient and Portable Combined Random Number
+.\" Generators', which combines two Multiplicative Linear
+.\" Congruential Generators (MLCGs) to achieve a period of
+.\" 2.3*10^18.
+.\"
+.\" Since this just generates example output,
+.\" we don't need good randomness.
+.
+.de random-seed
+. if !(\\n[.$] == 2) \{\
+. tm \\*[common]: random-seed: Invalid number of arguments.
+. tm \\*[common]: usage: '.random-seed seed1 seed2'
+. return
+. \}
+.
+. nr random-s1 (\\$1 % 2147483562)
+. nr random-s2 (\\$2 % 2147483398)
+..
+.random-seed 131545532 19201711
+.
+.
+.de random#
+. nr * (\\n[random-s1] / 53668)
+. nr random-s1 (40014 * (\\n[random-s1] - (\\n[*] * 53668)) \
+ - (\\n[*] * 12211))
+. if !\\n[random-s1] \
+. nr random-s1 +2147483563
+.
+. nr * (\\n[random-s2] / 52774)
+. nr random-s2 (40692 * (\\n[random-s2] - (\\n[*] * 52774)) \
+ - (\\n[*] * 3791))
+. if !\\n[random-s2] \
+. nr random-s2 +2147483399
+.
+. nr * (\\n[random-s1] - \\n[random-s2])
+. if (\\n[*] < 1) \
+. nr * +2147483562
+.
+. \" reduce the result to the leftmost 24 bits
+. nr * (\\n[*] / 128)
+.
+. d2x \\n[*]
+. ds hex# 000000\\*[hex#]\"
+. substring hex# -6
+. ds #random #\\*[hex#]\"
+..
+.
+.
+.\" ******************************************************************
+.\" ** minimal Page setup **
+.\" ******************************************************************
+.
+.nr s \n[.ps]
+.nr v \n[.v]
+.nr p \n[.p]
+.nr o \n[.o]
+.nr l 6.6i \" set text width
+.ll \n[t*l]u
+.nr o 2c \" set offset
+.po \n[o]u
+.nr p 29.7c \" set paper length (A4)
+.pl \n[p]u
+.nr tH 1i \" set top margin
+.sp |\n[tH]u
+.
+.ds t*HM //arbitrary text for page header, except on the first page//\"
+.ds t*BM //arbitrary text for page footer, except on the last page/\\n[%]/\"
+.
+.ev 99
+.lt \n[t*l]u
+.ev
+.
+.
+.de HM
+. sp |.5i \" print header in top margin
+. tl \\*[t*HM]
+. sp |\\n[tH]u
+. ev
+..
+.
+.
+.de BM
+. ev 99
+. sp |(\\n[p]u - .5i) \" print footer in bottom margin
+. tl \\*[t*BM]
+. bp
+..
+.
+.
+.de EM
+. rm BM \" no page number at bottom of last page
+. t*EM
+..
+.
+.
+.wh 0 HM
+.wh 0-1.5i BM
+.em EM
+.
+.\" Some packages (-mm) define their own .SP macro.
+.\" Use ours if another one isn't already available.
+.if !d SP .als SP t*SP
+.
+.if "\n[.m]"" \
+. gcolor black
+.if "\n[.M]"" \
+. fcolor white
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" fill-column: 72
+.\" End:
+.\" vim: set filetype=groff textwidth=72:
diff --git a/contrib/hdtbl/examples/fonts_n.in b/contrib/hdtbl/examples/fonts_n.in
new file mode 100644
index 0000000..c953fa4
--- /dev/null
+++ b/contrib/hdtbl/examples/fonts_n.in
@@ -0,0 +1,149 @@
+.ig
+
+font_n.roff
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2005-2020 Free Software Foundation, Inc.
+written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+..
+.
+.
+.\" ******************************************************************
+.\" ** groff glyphs vs. character codes: **
+.\" ** .fontdump [font1 font2 ...] **
+.\" ** Print glyphs of font1, font2, ..., versus **
+.\" ** character code. **
+.\" ** 'all' as fontname prints all fonts in the **
+.\" ** specified string 'fontpath'. **
+.\" ** without arg: glyphs and codes of active font. **
+.\" ******************************************************************
+.
+.ds fonts_n fonts_n.roff\" name for diagnostic messages
+.
+.if !d sopath \
+. ds sopath
+.
+.so \*[sopath]examples/common.roff
+.
+.if !d fontpath \
+. ds fontpath @fontdir@
+.
+.tm \*[fonts_n]: listing fonts in \*[fontpath]/dev\*[.T]
+.
+.de fontdump
+. ie \\n[.$] \
+. ds *args \\$*
+. el \
+. ds *args \\n[.fn]
+.
+. pso sh -c \
+ "printf '%s' '.ds *f ' ; \
+ ls \\*[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
+. \}
+.
+. t*index "\\*[*f]" \\*[*$1]
+.
+. ie (\\n[.y] > 18) \
+. if !F \\*[*$1] \{\
+. tm \\*[fonts_n]: \\n[.F]:\\n[.c]: Font \\*[*$1] not found.
+. continue
+. \}
+. el \{\
+. if !\\n[t*index] \{\
+. tm \\*[fonts_n]: \\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
+.
+. tm \\*[fonts_n]: listing font '\\*[*$1]'...
+.
+. TBL border=.1n bc=red cpd=0 csp=.1n bgc=
+. CPTN groff font \\*[*$1] \
+ .br \
+ val=b ".pso @EGREP@ 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
+. \" font_x.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 \
+ "".if c \N'\En+[c#]' \
+ \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
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" fill-column: 72
+.\" End:
+.\" vim: set filetype=groff textwidth=72:
diff --git a/contrib/hdtbl/examples/fonts_x.in b/contrib/hdtbl/examples/fonts_x.in
new file mode 100644
index 0000000..c183c7c
--- /dev/null
+++ b/contrib/hdtbl/examples/fonts_x.in
@@ -0,0 +1,160 @@
+.ig
+
+font_x.roff
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2005-2020 Free Software Foundation, Inc.
+written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+..
+.
+.
+.\" ******************************************************************
+.\" ** groff glyphs vs. character codes: **
+.\" ** .fontdump [font1 font2 ...] **
+.\" ** Print glyphs of font1, font2, ..., versus **
+.\" ** character code. **
+.\" ** 'all' as fontname prints all fonts in the **
+.\" ** specified string 'fontpath'. **
+.\" ** without arg: glyphs and codes of active font. **
+.\" ******************************************************************
+.
+.ds fonts_x fonts_x.roff\" name for diagnostic messages
+.
+.if !d sopath \
+. ds sopath
+.
+.so \*[sopath]examples/common.roff
+.
+.if !d fontpath \
+. ds fontpath @fontdir@
+.
+.tm \*[fonts_x]: listing fonts in \*[fontpath]/dev\*[.T]
+.
+.de fontdump
+. ie \\n[.$] \
+. ds *args \\$*
+. el \
+. ds *args \\n[.fn]
+.
+. pso sh -c \
+ "printf '%s' '.ds *f ' ; \
+ ls \\*[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
+. \}
+.
+. t*index "\\*[*f]" \\*[*$1]
+.
+. ie (\\n[.y] > 18) \
+. if !F \\*[*$1] \{\
+. tm \\*[fonts_x]: \\n[.F]:\\n[.c]: Font \\*[*$1] not found.
+. continue
+. \}
+. el \{\
+. if !\\n[t*index] \{\
+. tm \\*[fonts_x]: \\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
+.
+. tm \\*[fonts_x]: listing font '\\*[*$1]'...
+.
+. TBL border=.1n bc=red cpd=0 csp=.1n bgc=
+. CPTN groff font \\*[*$1] \
+ .br \
+ val=b ".pso @EGREP@ 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
+. if c \N'\\n+[c#]' \
+. 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
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" fill-column: 72
+.\" End:
+.\" vim: set filetype=groff textwidth=72:
diff --git a/contrib/hdtbl/examples/mixed_pickles.roff b/contrib/hdtbl/examples/mixed_pickles.roff
new file mode 100644
index 0000000..1c909e9
--- /dev/null
+++ b/contrib/hdtbl/examples/mixed_pickles.roff
@@ -0,0 +1,104 @@
+.ig
+
+mixed_pickles.roff
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2005-2020 Free Software Foundation, Inc.
+written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+..
+.
+.am pspic*error-hook
+. ab \\n[.F]:\\n[.c]: fatal error: PSPIC failed to include '\\$1'
+..
+.
+.if !d sopath \
+. ds sopath
+.
+.so \*[sopath]examples/common.roff
+.
+.H Table with Mixed Content: \
+ .br \
+ EPS Image, eqn Equation, tbl Table, and pic Picture
+.
+Call groff with options \-t, \-e, and \-p!
+.
+.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
+. PSPIC -I -\\n[.l]u gnu.eps
+. sp .5
+. nop eps image with \fI.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
+.
+. nop \0\0\0\0\0equation with \fIeqn\fP
+.
+. TR
+. TD hl=d
+.
+.TS
+tab(@), center, doublebox, nospaces;
+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 @ scale @ 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
+. nop table with \fItbl\fP
+. TR
+. TD colspan=2 bgc=azure2 fgc=blue4
+.
+.PS
+ellipse "document";
+arrow 0.42;
+box width 0.6 "\fIgpic\/\fP(1)"
+arrow 0.42;
+box width 1.25 "\fIgtbl\/\fP(1) or \fIgeqn\/\fP(1)" "(optional)" dashed;
+arrow 0.42;
+box width 0.65 "\fIgtroff\/\fP(1)";
+arrow 0.42;
+ellipse "PostScript"
+.PE
+.
+. sp .5
+. nop picture with \fIpic\fP
+. ETB
+.ETB
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" fill-column: 72
+.\" End:
+.\" vim: set filetype=groff textwidth=72:
diff --git a/contrib/hdtbl/examples/rainbow.roff b/contrib/hdtbl/examples/rainbow.roff
new file mode 100644
index 0000000..ecd59f5
--- /dev/null
+++ b/contrib/hdtbl/examples/rainbow.roff
@@ -0,0 +1,86 @@
+.ig
+
+rainbow.roff
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2005-2020 Free Software Foundation, Inc.
+written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+..
+.
+.if !d sopath \
+. ds sopath
+.
+.so \*[sopath]examples/common.roff
+.
+.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=\n[t*l]/(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 -> blue
+.ctab \n[*n] 0 \En[#cc]u 1 \" blue -> cyan
+.ctab \n[*n] 0 1 1-\En[#cc]u \" cyan -> green
+.ctab \n[*n] \En[#cc]u 1 0 \" green -> yellow
+.ctab \n[*n] 1 1-\En[#cc]u 0 \" yellow -> red
+.
+.PN 6*\n[*n] .ETB
+.
+.bp
+.
+.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=\n[t*l]/(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 \" red -> yellow
+.ctab \n[*n] 1-\En[#cc]u 1 0 \" yellow -> green
+.ctab \n[*n] 0 1 \En[#cc]u \" green -> cyan
+.ctab \n[*n] 0 1-\En[#cc]u 1 \" cyan -> blue
+.ctab \n[*n] \En[#cc]u 0 1 \" blue -> magenta
+.ctab \n[*n] 1 0 1-\En[#cc]u \" magenta -> red
+.
+.PN 6*\n[*n] .ETB
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" fill-column: 72
+.\" End:
+.\" vim: set filetype=groff textwidth=72:
diff --git a/contrib/hdtbl/examples/short_reference.roff b/contrib/hdtbl/examples/short_reference.roff
new file mode 100644
index 0000000..62b3bcd
--- /dev/null
+++ b/contrib/hdtbl/examples/short_reference.roff
@@ -0,0 +1,86 @@
+.ig
+
+short_reference.roff
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2005-2020 Free Software Foundation, Inc.
+written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+..
+.
+.if !d sopath \
+. ds sopath
+.
+.so \*[sopath]examples/common.roff
+.
+.t*pv 1.2 1.2 "" x
+.H Short Reference for the HDtbl-Macros
+This Short Reference describes the Heidelberger Table Macros
+using the 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 cell content
+.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 cell content
+.TD \&.TD \&.TR
+.TR
+.TD \&.TH .TD Optional begin table header cell
+.TD \&.TR \&.TD \&.TH \%.ETB cell content
+.TD \&.TD \&.TH \&.TR \%.ETB cell content
+.TR
+.TD \&.TD .TD Begin table data cell .TD \&.TR \&.TD \&.TH \%.ETB cell content
+.TD \&.TD \&.TH \&.TR \%.ETB cell content
+.TR
+.TD \&.ETB .TD Finish and print table .TD \&.TD \&.TH \%.ETB cell content
+.TD \&.TBL \&.TR \&.TD \&.TH \%.ETB cell content
+.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 -------
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" fill-column: 72
+.\" End:
+.\" vim: set filetype=groff textwidth=72:
diff --git a/contrib/hdtbl/examples/test-hdtbl.sh.in b/contrib/hdtbl/examples/test-hdtbl.sh.in
new file mode 100644
index 0000000..5e81bf7
--- /dev/null
+++ b/contrib/hdtbl/examples/test-hdtbl.sh.in
@@ -0,0 +1,47 @@
+#!/bin/sh
+#
+# Copyright (C) 2018- Free Software Foundation, Inc.
+#
+# This file is part of groff.
+#
+# groff is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# groff is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Test generated files 'font_n.ps' and 'font_x.ps'. Both should have
+# 38 pages.
+
+builddir="@abs_top_builddir@"
+gs_program="@GHOSTSCRIPT@"
+ret=0
+
+if test "$gs_program" = "missing"; then
+ echo "ghostscript program missing, can't check hdtbl examples"
+ exit 77
+fi
+
+# $1 file, $2 expected number of pages
+check_number_pages()
+{
+ echo "Checking $1"
+ res=`$gs_program -o /dev/null/ -sDEVICE=bbox "$1" 2>&1 | grep HiResBoundingBox | wc -l`
+ if test $res != $2; then
+ echo " Error: expected $2 pages, found $res pages"
+ ret=255
+ fi
+}
+
+check_number_pages $builddir/contrib/hdtbl/examples/fonts_n.ps 38
+check_number_pages $builddir/contrib/hdtbl/examples/fonts_x.ps 38
+
+exit $ret
diff --git a/contrib/hdtbl/groff_hdtbl.7.man b/contrib/hdtbl/groff_hdtbl.7.man
new file mode 100644
index 0000000..af5ab87
--- /dev/null
+++ b/contrib/hdtbl/groff_hdtbl.7.man
@@ -0,0 +1,1346 @@
+.TH groff_hdtbl @MAN7EXT@ "@MDATE@" "groff @VERSION@"
+.SH Name
+groff_hdtbl \- Heidelberger table macros for GNU
+.I roff
+.
+.
+.\" ====================================================================
+.\" Legal Terms
+.\" ====================================================================
+.\"
+.\" Copyright (C) 2005-2020 Free Software Foundation, Inc.
+.\"
+.\" This file is part of groff, the GNU roff type-setting system.
+.\"
+.\" Permission is granted to copy, distribute and/or modify this
+.\" document under the terms of the GNU Free Documentation License,
+.\" Version 1.3 or any later version published by the Free Software
+.\" Foundation; with no Invariant Sections, 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.
+.
+.
+.\" Save and disable compatibility mode (for, e.g., Solaris 10/11).
+.do nr *groff_groff_hdtbl_7_man_C \n[.cp]
+.cp 0
+.
+.\" Define fallback for groff 1.23's MR macro if the system lacks it.
+.nr do-fallback 0
+.if !\n(.f .nr do-fallback 1 \" mandoc
+.if \n(.g .if !d MR .nr do-fallback 1 \" older groff
+.if !\n(.g .nr do-fallback 1 \" non-groff *roff
+.if \n[do-fallback] \{\
+. de MR
+. ie \\n(.$=1 \
+. I \%\\$1
+. el \
+. IR \%\\$1 (\\$2)\\$3
+. .
+.\}
+.rr do-fallback
+.
+.
+.ig
+ Some simple formatting macros. Note that we use '.ig' here and not a
+ comment to make 'mandb' 2.4.1 (and probably more recent versions also)
+ happy; otherwise the '.char' lines and the stuff which follows is
+ included in the 'whatis' database.
+..
+.
+.
+.char \[lB] \F[\n[.fam]]\f[R][
+.char \[rB] \F[\n[.fam]]\f[R]]
+.
+.char \[or] \F[\n[.fam]]\f[R]\||\|
+.char \[ell] \F[\n[.fam]]\f[R].\|.\|.
+.
+.char \[oq] \F[\n[.fam]]\f[R]\[oq]
+.char \[cq] \F[\n[.fam]]\f[R]\[cq]
+.
+.
+.ie F CR \{\
+.
+. \" We have to solve the following problem. In this code
+. \"
+. \" foo
+. \" .CR bar
+. \" foo
+. \"
+. \" the space immediately after 'bar' should not be taken from the 'C'
+. \" family. At the same time, this
+. \"
+. \" foo
+. \" .CR bar\c
+. \" foo
+. \"
+. \" should work also. To fulfill both constraints we emit the
+. \" family changing commands both as escapes and macro calls.
+.
+. de make-C-macro
+. de C\\$1
+. ds old-fam \\\\n[.fam]
+. fam C
+. \\$2 \&\\\\$*\F[]\F[\\\\*[old-fam]]
+. fam
+. rm old-fam
+\\..
+. .
+.
+. make-C-macro R nop
+. make-C-macro B B
+. make-C-macro I I
+.
+. de make-C-macro
+. de C\\$1
+. ds old-fam \\\\n[.fam]
+. fam C
+. \\$1 \\\\$@ \F[]\F[\\\\*[old-fam]]
+. fam
+. rm old-fam
+\\..
+. .
+.
+. make-C-macro BI
+. make-C-macro IB
+. make-C-macro RI
+. make-C-macro IR
+. make-C-macro BR
+. make-C-macro RB
+.\}
+.el \{\
+. ftr CR R
+. ftr CI I
+. ftr CB B
+. ftr CBI BI
+.
+. de CR
+. nop \&\\$*
+. .
+. als CB B
+. als CI I
+.
+. als CBI BI
+. als CIB IB
+. als CRI RI
+. als CIR IR
+. als CBR BR
+. als CRB RB
+.\}
+.
+.
+.
+.de XB
+. B "\\$1"
+. shift
+. CR "\\$1\c"
+. shift
+. while \\n[.$] \{\
+. nop ,
+. CR "\\$1\c"
+. shift
+. \}
+. br
+..
+.
+.
+.de XAA
+. TQ
+. ie (\\n[.$] < 2) \
+. CR \\$@
+. el \
+. CRI \\$@
+..
+.
+.
+.de XDEF
+. br
+. B Default:
+. if !\\n[.$] \
+. return
+. CRI "\\$1" "\\$2"
+..
+.
+.
+.de XDEFR
+. br
+. B Default:
+. CR "\[oq]\\$1\[cq]"
+. nop (register
+. CR "\[oq]\\$2\[cq]\c"
+. nop ).
+..
+.
+.
+.de XDEFS
+. br
+. B Default:
+. CR "\[oq]\\$1\[cq]"
+. nop (string
+. CR "\[oq]\\$2\[cq]\c"
+. nop ).
+..
+.
+.\" ====================================================================
+.SH Description
+.\" ====================================================================
+.
+The
+.I hdtbl
+macros consist of four base and three optional macros,
+controlled by about twenty arguments.
+.
+The syntax is simple and similar to the HTML table model and nearly as
+flexible:
+you can write sequences of tokens
+(macro calls with their arguments and content data),
+separated by blanks and beginning with a macro call,
+into the same line to get compact and cleanly arrranged input.
+.
+An advantage of
+.I hdtbl
+is that the tables are constructed without calling a preprocessor;
+this means that
+.MR groff @MAN7EXT@ 's
+full macro capabilities are available.
+.
+On the other hand,
+table processing with
+.I hdtbl
+is much slower than using the
+.MR @g@tbl @MAN1EXT@
+preprocessor.
+.
+A further advantage is that the HTML-like syntax of
+.I hdtbl
+will be easily converted to HTML;
+this is not implemented yet.
+.
+.
+.\" ====================================================================
+.SH Usage
+.\" ====================================================================
+.
+In this and the next section, we present examples to help users
+understand the basic workflow of
+.IR hdtbl .
+.
+First of all, you must load the
+.I hdtbl.tmac
+file.
+.
+As with nearly all other
+.I groff
+macro packages,
+there are two possibilities to do so:
+.
+Either add the line
+.
+.
+.PP
+.RS
+.EX
+\&.mso hdtbl.tmac
+.EE
+.RE
+.
+.
+.PP
+to your
+.I roff
+file before using any macros of the
+.I hdtbl
+package, or add the option
+.
+.PP
+.RS
+.EX
+\-m hdtbl
+.EE
+.RE
+.
+.
+.PP
+to the command line of groff (before the document file which contains
+.I hdtbl
+macros).
+.
+Then you can include on or more tables in your document, where each one
+must be started and ended with the
+.CR .TBL
+and
+.CR .ETB
+macros, respectively.
+.
+.
+.PP
+In this man page,
+we approximate the result of each example as terminal output to be as
+generic as possible since
+.I hdtbl
+currently only supports the
+.B ps
+and
+.B pdf
+output drivers.
+.
+.
+.PP
+The simplest well-formed table consists of just single calls to the
+four base table macros in the right order.
+.
+Here we construct a table with only one cell.
+.
+.
+.PP
+.RS
+.EX
+\&.TBL
+\&.TR
+\&.TD
+.I contents of the table cell
+\&.ETB
+.EE
+.RE
+.
+.
+.PP
+A terminal representation is
+.
+.
+.PP
+.if t .ne 3v
+.RS
+.EX
+.tr -\-
++------------------------------------------------------+
+.\" That's 27 spaces below.
+.RI "| " contents-of-the-table-cell " |"
++------------------------------------------------------+
+.tr --
+.EE
+.RE
+.
+.
+.PP
+Equivalent to the above is the following notation.
+.
+.
+.PP
+.RS
+.EX
+.RI ".TBL .TR .TD \[dq]" "contents of the table cell" "\[dq] .ETB"
+.EE
+.RE
+.
+.
+.PP
+By default, the formatted table is inserted into the surrounding text
+at the place of its definition.
+.
+If the vertical space isn't sufficient, it is placed at the top of
+the next page.
+.
+Tables can also be stored for later insertion.
+.
+.
+.PP
+Using
+.CIR \[oq]row-number * column-number\[cq]
+as the data for the table cells, a table with two rows and two columns
+can be written as
+.
+.
+.PP
+.RS
+.EX
+\&.TBL cols=2
+\&.\& TR .TD 1*1 .TD 1*2
+\&.\& TR .TD 2*1 .TD 2*2
+\&.ETB
+.EE
+.RE
+.
+.
+.PP
+A terminal representation is
+.
+.
+.PP
+.if t .ne 5v
+.RS
+.EX
+.tr -\-
++--------------------------+---------------------------+
+| 1*1 | 1*2 |
++--------------------------+---------------------------+
+| 2*1 | 2*2 |
++--------------------------+---------------------------+
+.tr --
+.EE
+.RE
+.
+.
+.PP
+Here we see a difference from HTML tables: The number of columns must be
+explicitly specified using the
+.CRI \[oq]cols= m\[cq]
+argument (or indirectly via the
+.CR \[oq]width\[cq]
+argument, see below).
+.
+.
+.PP
+The contents of a table cell is arbitrary;
+for example,
+it can be another table,
+without restriction to the nesting depth.
+.
+A given table layout can be either constructed with suitably nested
+tables or with proper arguments to
+.CR .TD
+and
+.CR .TH\c
+, controlling column and row spanning.
+.
+Note, however, that this table
+.
+.
+.PP
+.RS
+.EX
+\&.TBL
+\&.\& TR
+\&.\& TD
+\&.\& nop 1*1 1*2
+\&.\& TR
+\&.\& TD
+\&.\& TBL cols=2 border=
+\&.\& TR
+\&.\& TD
+\&.\& nop 2*1
+\&.\& TD
+\&.\& nop 2*2
+\&.\& ETB
+\&.ETB
+.EE
+.RE
+.
+.
+.PP
+and this table
+.
+.
+.PP
+.RS
+.EX
+\&.TBL cols=2
+\&.\& TR
+\&.\& TD colspan=2
+\&.\& nop 1*1 1*2
+\&.\& TR
+\&.\& TD
+\&.\& nop 2*1
+\&.\& TD
+\&.\& nop 2*2
+\&.ETB
+.EE
+.RE
+.
+.
+.PP
+are similar but not identical (the use of
+.CR .nop
+is purely cosmetic to get proper indentation).
+.
+.
+.PP
+The first table looks like
+.
+.PP
+.if t .ne 7v
+.RS
+.EX
+.tr -\-
++------------------------------------------------------+
+| 1*1 1*2 |
++------------------------------------------------------+
+| |
+| 2*1 2*2 |
+| |
++------------------------------------------------------+
+.tr --
+.EE
+.RE
+.
+.
+.PP
+and the second one like
+.
+.
+.PP
+.if t .ne 5v
+.RS
+.EX
+.tr -\-
++------------------------------------------------------+
+| 1*1 1*2 |
++---------------------------+--------------------------+
+| 2*1 | 2*2 |
++---------------------------+--------------------------+
+.tr --
+.EE
+.RE
+.
+.
+.PP
+Here is the latter table in a more compact form.
+.
+.PP
+.RS
+.EX
+\&.TBL cols=2 .TR \[dq].TD colspan=2\[dq] 1*1 1*2
+\&.\& TR .TD 2*1 .TD 2*2 .ETB
+.EE
+.RE
+.
+.
+.PP
+If a macro has one or more arguments
+(see below),
+and it is not starting a line,
+everything belonging to this macro including the macro itself must be
+enclosed in double quotes.
+.
+.
+.\" ====================================================================
+.SH "Macros and arguments"
+.\" ====================================================================
+.
+The order of macro calls and other tokens follows the HTML model.
+.
+In the following list, valid predecessors and successors of all
+.I hdtbl
+macros are given, together with the possible arguments.
+.
+.PP
+Macro arguments are separated by blanks.
+.
+The order of arguments is arbitrary; they are of the form
+.
+.PP
+.RS
+.CRI key= value
+.RE
+.
+.PP
+or
+.
+.PP
+.RS
+.CRI key=\[aq] "value1 \[lB]value2 \[lB]\[ell]\[rB]\[rB]" \[aq]
+.RE
+.
+.PP
+with the only exception of the optional argument of the macro
+.CR .ETB\c
+, which is the string
+.CR \[oq]hold\[cq]\c
+\&.
+.
+Another possible form is
+.
+.PP
+.RS
+.CRI \[dq]key= "value1 \[lB]value2 \[lB]\[ell]\[rB]\[rB]" \[dq]
+.RE
+.
+.
+.PP
+However,
+this is limited to the case where the macro is the first one in the line
+and not already enclosed in double quotes.
+.
+.
+.PP
+Argument values specified below as\~\c
+.CI c
+are colors predefined by
+.I groff
+or colors defined by the user with the
+.CR .defcolor
+request.
+.
+Argument values\~\c
+.CI d
+are decimal numbers with or without decimal point.
+.
+Argument values\~\c
+.CI m
+are natural numbers.
+.
+Argument values\~\c
+.CI n
+are numerical values with the usual
+.I groff
+scaling indicators.
+.
+Some of the arguments are specific to one or two macros, but most of
+them can be specified with
+.CR .TBL\c
+,
+.CR .TR\c
+,
+.CR .TD\c
+, and
+.CR .TH\
+\&.
+.
+These common arguments are explained in the next subsection.
+.
+.
+.PP
+Most of the argument default values can be changed by the user by
+setting corresponding default registers or strings, as listed below.
+.
+.\"==================================================================
+.
+.TP
+.CBI ".TBL " \[lB]args\[rB]
+Begin a new table.
+.
+.IP
+.RS
+.XB predecessor: .TD .TH .ETB "cell contents"
+.XB successor: .CPTN .TR
+.XB arguments:
+.
+.RS
+.XAA border= \[lB]n\[rB]
+Thickness of the surrounding box border.
+.
+.CR \%\[oq]border=\[cq]
+(no value) means neither a surrounding box border nor any horizontal or
+vertical separator lines between the table rows and cells.
+.
+.CR \%\[oq]border=0\[cq]
+suppresses the surrounding box border, but still allows separator lines
+between cells and rows.
+.
+.XDEFR border=.1n t*b
+.
+.XAA bc= c
+Border color.
+.
+.XDEFS bc=red4 t*bc
+.
+.XAA cols= m
+Number of table columns.
+.
+This argument is necessary if more than one column is in the table and
+no
+.CR \[oq]width\[cq]
+arguments are present.
+.
+.XDEFR cols=1 t*cols
+.
+.XAA cpd= n
+Cell padding, i.e., the extra space between the cell space border and
+the cell contents.
+.
+.XDEFR cpd=.5n t*cpd
+.
+.XAA csp= n
+Cell spacing, i.e., the extra space between the table border or
+vertical or horizontal lines between cells and the cellspace.
+.
+.XDEFR csp=.5n t*csp
+.
+.XAA tal=l\[or]c\[or]r
+Horizontal alignment of the table, if it is smaller than the line width.
+.
+.CR \[oq]tal=l\[cq]\c
+: left alignment.
+.
+.CR \[oq]tal=c\[cq]\c
+: centered alignment.
+.
+.CR \[oq]tal=r\[cq]\c
+: right alignment.
+.
+.XDEFR tal=l t*tal
+.
+.XAA "width=\[aq]" "w1 \[lB]w2 \[lB]\[ell]\[rB]\[rB]" \[aq]
+Widths of table cells.
+.
+.CI w1\c
+.RI , ""
+.CI w2\c
+.RI , ""
+\[ell] are either numbers of type\~\c
+.CI n
+or natural numbers with the pseudo-scaling indicator
+.CR \[oq]%\[cq]\c
+, with the meaning \[lq]percent of the actual line length
+(or column length for inner tables,
+respectively)\[rq].
+.
+If there are less width values than table columns,
+the last width value is used for the remaining cells.
+.
+The argument
+.
+.RS
+.IP
+.CR width=\[aq]1.5i 10%\[aq]
+.RE
+.
+.IP
+for example indicates that the first column is 1.5\~inches wide; the
+remaining columns take 1/10 of the column length each.
+.
+.XDEF
+The table width equals the outer line length or column length;
+the columns have equal widths.
+.
+.XAA height= n
+Height of the table.
+.
+If the table with its contents is lower than\~\c
+.CI n\c
+.RI , ""
+the last row is stretched to this value.
+.RE
+.RE
+.
+.\"==================================================================
+.
+.TP
+.CBI ".CPTN " \[lB]args\[rB]
+Text of caption.
+.
+.IP
+The (optionally numbered) table caption.
+.
+.CR .CPTN
+is optional.
+.
+.IP
+.RS
+.XB predecessor: .TBL
+.XB successor: .TR
+.XB arguments:
+.
+.RS
+.XAA val=t\[or]b
+Vertical alignment of the table caption.
+.
+.CR \[oq]val=t\[cq]\c
+: The caption is placed above the table.
+.
+.CR \[oq]val=b\[cq]\c
+: The caption is placed below the table.
+.
+.XDEFS val=t t*cptn
+.RE
+.RE
+.
+.\"==================================================================
+.
+.TP
+.CBI ".TR " \[lB]args\[rB]
+Begin a new table row.
+.
+.IP
+.RS
+.XB predecessor: .TBL .CPTN .TD .TH .ETB "cell contents"
+.XB successor: .TD .TH
+.XB arguments:
+.
+.RS
+.XAA height= n
+The height of the row.
+.
+If a cell in the row is higher than\~\c
+.CI n\c
+.RI , ""
+this value is ignored;
+otherwise the row height is stretched to\~\c
+.CI n\c
+.RI . ""
+.RE
+.RE
+.
+.\"==================================================================
+.
+.TP
+.CBI ".TD " "\[lB]args \[lB]cell contents\[rB]\[rB]"
+Begin a table data cell.
+.TQ
+.CBI ".TH " "\[lB]args \[lB]cell contents\[rB]\[rB]"
+Begin a table header cell.
+.
+.IP
+Arguments and cell contents can be mixed.
+.
+The macro
+.CR .TH
+is not really necessary and differs from
+.CR .TD
+only in three default settings, similar to the
+.CR <TH>
+and
+.CR <TD>
+HTML tags: The contents of
+.CR .TH
+is horizontally and vertically centered and typeset in boldface.
+.
+.IP
+.RS
+.XB predecessor: .TR .TD .TH .ETB "cell contents"
+.XB successor: .TD .TH .TR .ETB "cell contents"
+.XB arguments:
+.
+.RS
+.XAA colspan= m
+The width of this cell is the sum of the widths of the\~\c
+.CI m
+cells above and below this row.
+.
+.XAA rowspan= m
+The height of this cell is the sum of the heights of the
+.CI m
+cells left and right of this column.
+.
+.IP
+.B Remark:
+Overlapping of column and row spanning,
+as in the following table fragment
+(the overlapping happens in the second cell in the second row),
+is invalid and causes incorrect results.
+.
+.
+.RS
+.IP
+.EX
+\&.TR .TD 1*1 \[dq].TD 1*2 rowspan=2\[dq] .TD 1*3
+\&.TR \[dq].TD 2*1 colspan=2\[dq] .TD 2*3
+.EE
+.RE
+.
+.
+.PP
+A working example for headers and cells with
+.B colspan
+is
+.
+.
+.PP
+.RS
+.EX
+\&.TBL cols=3
+\&.\& TR \[dq].TH colspan=2\[dq] header1+2 .TH header3
+\&.\& TR .TD 1*1 .TD 1*2 .TD 1*3
+\&.\& TR .TD 2*1 \[dq].TD colspan=2\[dq] 2*2+3
+\&.ETB
+.EE
+.RE
+.
+.
+.PP
+This looks like
+.
+.
+.PP
+.if t .ne 7v
+.RS
+.EX
+.tr -\-
++------------------------------+---------------+
+| header1+2 | header3 |
++--------------+---------------+---------------+
+| 1*1 | 1*2 | 1*3 |
++--------------+---------------+---------------+
+| 2*1 | 2*2+3 |
++--------------+-------------------------------+
+.tr --
+.EE
+.RE
+.
+.
+.PP
+A working example with
+.B rowspan
+is
+.
+.
+.PP
+.RS
+.EX
+\&.TBL cols=3
+\&.\& TR
+\&.\& TD 1*1
+\&.\& TD rowspan=2 1+2*2
+\&.\& TD 1*3
+\&.\&
+\&.\& TR
+\&.\& TD 2*1
+\&.\& TD 2*3
+\&.ETB
+.EE
+.RE
+.
+.
+.PP
+which looks like
+.
+.
+.PP
+.if t .ne 5v
+.RS
+.EX
+.tr -\-
++--------------+---------------+---------------+
+| 1*1 | 1+2*2 | 1*3 |
++--------------+ +---------------+
+| 2*1 | | 2*3 |
++--------------+---------------+---------------+
+.tr --
+.EE
+.RE
+.RE
+.RE
+.
+.\"==================================================================
+.
+.
+.TP
+.CB ".ETB \[lB]hold\[rB]"
+End of the table.
+.
+.IP
+This macro finishes a table.
+.
+It causes one of the following actions.
+.
+.RS
+.IP \[bu] 3
+If the argument
+.CR \[oq]hold\[cq]
+is given, the table is held until it is freed by calling the macro
+.CR .t*free\c
+, which in turn prints the table immediately,
+either at the current position or at the top of the next page if its
+height is larger than the remaining space on the page.
+.
+.IP \[bu] 3
+Otherwise, if the table is higher than the remaining space on the page,
+it is printed at the top of the next page.
+.
+.IP \[bu] 3
+If neither of the two above constraints hold, the table is printed
+immediately at the place of its definition.
+.RE
+.
+.IP
+.RS
+.XB predecessor: .TD .TH .ETB "cell contents"
+.XB successor: .TBL .TR .TD .TH .ETB "cell contents"
+.XB arguments:
+.
+.RS
+.XAA hold
+Prevent the table from being printed until it is freed by calling the
+macro
+.CR .t*free\c
+\&.
+.
+This argument is ignored for inner (nested) tables.
+.RE
+.RE
+.
+.\"==================================================================
+.
+.TP
+.CBI ".t*free " \[lB]n\[rB]
+Free the next held table or
+.CI n\~\c
+.RI held ""
+tables.
+.
+Call this utility macro to print tables which are held by using the
+.CR \[oq]hold\[cq]
+argument of the
+.CR .ETB
+macro.
+.
+.
+.\" ====================================================================
+.SS "Arguments common to \f[CB].TBL\f[], \f[CB].TR\f[], \f[CB].TD\f[], \
+and \f[CB].TH\f[]"
+.\" ====================================================================
+.
+The arguments described in this section can be specified with the
+.CR .TBL
+and
+.CR .TR
+macros, but they are eventually passed on to the table cells.
+.
+If omitted,
+the defaults take place,
+which the user can change by setting the corresponding default registers
+or strings,
+as documented below.
+.
+Setting an argument with the
+.CR .TBL
+macro has the same effect as setting it for all rows in the table.
+.
+Setting an argument with a
+.CR .TR
+macro has the same effect as setting it for all the
+.CR .TH
+or
+.CR .TD
+macro in this row.
+.
+.IP
+.XAA bgc= \[lB]c\[rB]
+The background color of the table cells.
+.
+This includes the area specified with the
+.CR \[oq]csp\[cq]
+argument.
+.
+The argument
+.CR \[oq]bgc=\[cq]
+(no value) suppresses a background color; this makes the background
+transparent.
+.
+.XDEFS bgc=bisque t*bgc
+.
+.XAA fgc= c
+The foreground color of the cell contents.
+.
+.XDEFS fgc=red4 t*fgc
+.
+.XAA ff= name
+The font family for the table.
+.
+.CI name
+is a
+.I groff
+font family identifier,
+such as
+.CR A
+for Avant Garde or
+.CR HN
+for Helvetica Narrow.
+.
+.XDEF
+The font family found before the table (string
+.CR \[oq]t*ff\[cq]\c
+).
+.
+.XAA fst= style
+The font style for the table.
+.
+One of
+.CR R\c
+,
+.CR B\c
+,
+.CR I\c
+, or
+.CR BI
+for roman,
+.BR bold ,
+.IR italic ,
+or \f[BI]bold italic\f[], \" \f[BI] is not portable man(7)
+respectively.
+.
+As with
+.IR roff 's
+.B .ft
+request,
+the
+.CR \[oq]fst\[cq]
+argument can be used to specify the font family and font style together,
+for example
+.CR \[oq]fst=HNBI\[cq]
+instead of
+.CR \[oq]ff=HN\[cq]
+and
+.CR \[oq]fst=BI\[cq]\c
+\&.
+.
+.XDEF
+The font style in use right before the table (string
+.CR \[oq]t*fst\[cq]\c
+).
+.
+.XAA "fsz=\[aq]" "d1 \[lB]d2\[rB]" \[aq]
+A decimal or fractional factor
+.CI d1\c
+.RI , ""
+by which the point size for the table is changed, and
+.CI d2\c
+.RI , ""
+by which the vertical line spacing is changed.
+.
+If
+.CI d2
+is omitted, value
+.CI d1
+is taken for both.
+.
+.XDEFS "fsz=\[aq]1.0 1.0\[aq]" t*fsz
+.
+.XAA hal=l\[or]c\[or]b\[or]r
+Horizontal alignment of the cell contents in the table.
+.
+.CR \[oq]hal=l\[cq]\c
+: left alignment.
+.
+.CR \[oq]hal=c\[cq]\c
+: centered alignment.
+.
+.CR \[oq]hal=b\[cq]\c
+: both (left and right) alignment.
+.
+.CR \[oq]hal=r\[cq]\c
+: right alignment.
+.
+.XDEFS hal=b t*hal
+.
+.XAA val=t\[or]m\[or]b
+Vertical alignment of the cell contents in the table for cells lower
+than the current row.
+.
+.CR \[oq]val=t\[cq]\c
+: alignment below the top of the cell.
+.
+.CR \[oq]val=m\[cq]\c
+: alignment in the middle of the cell.
+.
+.CR \[oq]val=b\[cq]\c
+: alignment above the cell bottom.
+.
+.XDEFS val=t t*val
+.
+.XAA hl=\[lB]s\[or]d\[rB]
+Horizontal line between the rows.
+.
+If specified with
+.CR .TD
+or
+.CR .TH
+this is a separator line to the cell below.
+.
+.CR \[oq]hl=\[cq]
+(no value): no separator line.
+.
+.CR \[oq]hl=s\[cq]\c
+: a single separator line between the rows.
+.
+.CR \[oq]hl=d\[cq]\c
+: a double separator line.
+.
+.IP
+The thickness of the separator lines is the half of the border
+thickness,
+but at least 0.1\~inches.
+.
+The distance between the double lines is equal to the line thickness.
+.
+.IP
+.B Remark:
+Together with
+.CR \[oq]border=0\[cq]
+for proper formatting the value of
+.CR \[oq]csp\[cq]
+must be at least \&.05\~inches for single separator lines and
+\&.15\~inches for double separator lines.
+.
+.XDEFS hl=s t*hl
+.
+.XAA vl=\[lB]s\[or]d\[rB]
+Vertical separator line between the cells.
+.
+If specified with
+.CR .TD
+or
+.CR .TH
+this is a separator line to the cell on the right.
+.
+.CR \[oq]vl=s\[cq]\c
+: a single separator line between the cells.
+.
+.CR \[oq]vl=d\[cq]\c
+: a double separator line.
+.
+.CR \[oq]vl=\[cq]
+(no value): no vertical cell separator lines.
+.
+For more information see the documentation of the
+.CR \[oq]hl\[cq]
+argument above.
+.
+.XDEFS vl=s t*vl
+.
+.
+.\" ====================================================================
+.SH "\f[I]hdtbl\f[] customization"
+.\" ====================================================================
+.
+.PP
+Before creating the first table, you should configure default values
+to minimize the markup needed in each table.
+.
+The following example sets up defaults suitable for typical papers:
+.
+.
+.PP
+.RS
+.EX
+\&.ds t*bgc white\[rs]\[dq] background color
+\&.ds t*fgc black\[rs]\[dq] foreground color
+\&.ds t*bc black\[rs]\[dq] border color
+\&.nr t*cpd 0.1n\[rs]\[dq] cell padding
+.EE
+.RE
+.
+.
+.PP
+The file
+.I @EXAMPLEDIR@/\:hdtbl/\:\%common\:.roff
+provides another example setup
+in the \[lq]minimal Page setup\[rq] section.
+.
+.
+.PP
+A table which does not fit on a partially filled page is printed
+automatically on the top of the next page if you append the little
+utility macro
+.CR t*hm
+to the page header macro of your document's main macro package.
+.
+For example, say
+.
+.
+.PP
+.RS
+.EX
+\&.am pg@top
+\&.\& t*hm
+\&..
+.EE
+.RE
+.
+.
+.PP
+if you use the
+.I ms
+macro package.
+.
+.
+.PP
+The macro
+.CR t*EM
+checks for held or kept tables,
+and for missing
+.CR ETB
+macros (table not closed).
+.
+You can call this macro by appending it the to end-of-input macro of
+the main,
+or \[lq]full-service\[rq],
+macro package your document uses.
+.
+For example,
+try
+.
+.
+.RS
+.EX
+\&.am pg@end\-text
+\&.\& t*EM
+\&..
+.EE
+.RE
+.
+if you use the
+.I ms
+package.
+.
+.
+.\" ====================================================================
+.SH "Bugs and suggestions"
+.\" ====================================================================
+.
+Please send your comments to the
+.MT groff@\:gnu\:.org
+.I groff
+mailing list
+.ME
+or directly to the author.
+.
+.
+.\" ====================================================================
+.SH Authors
+.\" ====================================================================
+.
+The
+.I hdtbl
+macro package was written by
+.MT Joachim\:.Walsdorff@\:urz\:.uni\-heidelberg\:.de
+Joachim Walsdorff
+.ME .
+.
+.
+.\" ====================================================================
+.SH "See also"
+.\" ====================================================================
+.
+.TP
+.MR groff @MAN1EXT@
+provides an overview of GNU
+.I roff
+and details how to invoke
+.I groff
+at the command line.
+.
+.
+.TP
+.MR groff @MAN7EXT@
+summarizes the
+.I roff
+language and GNU extensions to it.
+.
+.
+.TP
+.MR @g@tbl @MAN1EXT@
+describes the traditional
+.I roff
+preprocessor for tables.
+.
+.
+.\" Unwind (some of) the stuff we've done.
+.rchar \[lB]
+.rchar \[rB]
+.rchar \[or]
+.rchar \[ell]
+.rchar \[oq]
+.rchar \[cq]
+.
+.\" Restore compatibility mode (for, e.g., Solaris 10/11).
+.cp \n[*groff_groff_hdtbl_7_man_C]
+.do rr *groff_groff_hdtbl_7_man_C
+.
+.
+.\" Local Variables:
+.\" fill-column: 72
+.\" mode: nroff
+.\" End:
+.\" vim: set filetype=groff textwidth=72:
diff --git a/contrib/hdtbl/hdmisc.tmac b/contrib/hdtbl/hdmisc.tmac
new file mode 100644
index 0000000..9709bd8
--- /dev/null
+++ b/contrib/hdtbl/hdmisc.tmac
@@ -0,0 +1,327 @@
+.ig
+
+hdmisc.tmac
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2005-2020 Free Software Foundation, Inc.
+written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+..
+.
+.
+.if d t*getarg \
+. nx
+.
+.
+.\" ******************************************************************
+.\" ** Some macros and default settings needed by hdtbl **
+.\" ******************************************************************
+.
+.
+.\" Utility macro: .getarg <key> ...
+.\"
+.\" Get macro argument. This macro searches <key> in the
+.\" remaining arguments and assigns its value to a string
+.\" register named <key>. The following syntax forms are
+.\" recognized.
+.\"
+.\" <key>=<val> Assign <val> to string <key>.
+.\" <val> must not contain spaces.
+.\" <key>='<val>' Assign <val> to string <key>.
+.\" <val> can contain spaces.
+.\" <key>= Assign '=' to string <key>.
+.\" <key> Assign 'key' to string <key>.
+.\"
+.\" After return, the string 'args' contains the remaining
+.\" arguments.
+.\"
+.\" Example: With the definition of string 'foo' as
+.\"
+.\" .ds foo aaa=xxx bbb ccc='yyy zzz' ddd= eee
+.\"
+.\" a call to 'getarg' with
+.\"
+.\" .getarg ccc \*[foo]
+.\"
+.\" sets string 'ccc' to value 'yyy zzz'. The string 'args'
+.\" now contains 'aaa=xxx bbb ddd= eee'. An additional call
+.\" like
+.\"
+.\" .getarg ddd \*[args]
+.\"
+.\" sets string 'ddd' to value '=', and 'args' contains
+.\" 'aaa=xxx bbb eee'.
+.de t*getarg
+. ds \\$1
+. ds args
+.
+. if (\\n[.$] < 2) \
+. return
+.
+. ds $1 \\$1\"
+. shift
+.
+. length * \\*[$1]
+. while \\n[.$] \{\
+. ds * "\\$1\"
+. ds ** "\\$1\"
+. length ** \\*[**]
+. shift
+. if (\\n[*] > \\n[**]) \{\
+. as args " "\\*[**]"\" value too short, repeat
+. continue
+. \}
+. substring * 0 (\\n[*] - 1)
+. \" The surrounding \? escapes emulate string comparison.
+. ie !"\?\\*[$1]\?"\?\\*[*]\?" \{\
+. as args " "\\*[**]"\" key not found, repeat
+. continue
+. \}
+. el \{\
+. ie "\?\\*[**]\?"\?\\*[$1]\?" \
+. ds \\*[$1] \\*[$1]\" return key as string
+. el \{\
+. ie "\?\\*[**]\?"\?\\*[$1]=\?" \
+. ds \\*[$1] =\" return '='
+. el \{\
+. substring ** (\\n[*] + 1) -1
+. ds * \\*[**]\"
+. substring * 0 0
+.
+. \" check whether value starts with quote
+. if "\?\\*[*]\?"\?'\?" \{\
+. substring ** 1 -1
+. ds * \\*[**]\"
+. substring * -1 -1
+.
+. \" search final quote
+. ie "\?\\*[*]\?"\?'\?" \
+. substring ** 0 -2
+. el \{\
+. as \\*[$1] \\*[**] \" not found, append argument
+.
+. while 1 \{\
+. ds ** \\$1\" get next argument
+. ds * \\$1\"
+. shift
+. substring * -1 -1
+.
+. if "\?\\*[*]\?"\?'\?" \{\
+. substring ** 0 -2
+. break \" break if no final quote
+. \}
+.
+. as \\*[$1] \\*[**] \" otherwise append and repeat
+. \}
+. \}\}
+.
+. as \\*[$1] \\*[**]\"
+. \}
+.
+. as args " \\$@\"
+. \}\}
+.
+. return
+. \}
+..
+.
+.
+.\" Utility macro: .index <string1> <string2>
+.\"
+.\" Check whether <string2> is a substring of <string1> and
+.\" return its position in number register 't*index', starting
+.\" with 1. If not found, return 0. If <string2> is empty,
+.\" set 't*index' to -999.
+.de t*index
+. if "\\$2"" \{\
+. nr t*index -999
+. return
+. \}
+.
+. length ** \\$1
+. length $2 \\$2
+. nr * 0-1 1
+.
+. while (\\n+[*] < \\n[**]) \{\
+. ds * \\$1\"
+. substring * \\n[*] (\\n[*] + \\n[$2] - 1)
+. \" The surrounding \? escapes emulate string comparison.
+. if "\?\\*[*]\?"\?\\$2\?" \
+. break
+. \}
+.
+. ie (\\n[*] == \\n[**]) \
+. nr t*index 0
+. el \
+. nr t*index (\\n[*] + 1)
+..
+.
+.
+.\" ******************************************************************
+.\" ******** non-accumulating space .t*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 .t*SP wird in .HM am **
+.\" ** Seitenanfang zurueckgesetzt. **
+.\" ** ganz richtig ist .sp + .br = .br + .sp = .sp **
+.\" ******************************************************************
+.de t*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 .t*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 .t*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 t*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[t*s] **
+.\" ** und \n[t*v] sowie fuer Hyphenation: **
+.\" ** .t*pv s v hy# hart; macht .br **
+.\" ** Bei 4. Argument setzen der Register s und v und hy. **
+.\" ** Fuer angefangene Zeile die vorgefundenen Einstellungen **
+.\" ** **
+.\" ** Auxiliary macro to set internal registers for font size **
+.\" ** and line spacing, relative to initial values \n[t*s] and **
+.\" ** \n[t*v]. Optionally sets hyphenation. A fourth argument **
+.\" ** initializes internal registers to global default values. **
+.\" ******************************************************************
+.de t*pv
+. br
+.
+. if \\n[.$] \
+. ps (\\n[t*s]u * \\$1z / 1z)
+.
+. ie (\\n[.$] - 1) \
+. vs (\\n[t*v]u * \\$2p / 1p)
+. el \{\
+. vs (\\n[t*v]u * \\$1p / 1p)
+. return
+. \}
+.
+. if !""\\$3" \
+. hy \\$3
+.
+. if !""\\$4" \{\
+. nr t*v \\n[.v]
+. nr t*s \\n[.ps]
+. nr t*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
+.
+.
+.\" ******************************************************************
+.\" ** process diversion **
+.\" ******************************************************************
+.de t*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
+..
+.
+.\" ******************************************************************
+.\" ** error checking at end **
+.\" ******************************************************************
+.de t*EM
+.
+. if !"\\*[t*kept]"" \{\
+. tm1 "hdtbl: Not all tables have been printed.
+. tm1 " Add '.bp' at the end of your document.
+. \}
+. if !"\\*[t*held]"" \{\
+. tm1 "hdtbl: There are held tables which haven't been printed.
+. tm1 " Add '.t*free' at the end of your document.
+. \}
+. if \\n[t*#] \
+. tm hdtbl: Missing '.ETB' macro; last .TBL in \\*[t*FN] at line \\*[t*LN].
+..
+.
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" fill-column: 72
+.\" End:
+.\" vim: set filetype=groff textwidth=72:
diff --git a/contrib/hdtbl/hdtbl.am b/contrib/hdtbl/hdtbl.am
new file mode 100644
index 0000000..3dd60cf
--- /dev/null
+++ b/contrib/hdtbl/hdtbl.am
@@ -0,0 +1,136 @@
+# Copyright (C) 2006-2020 Free Software Foundation, Inc.
+# Written by Werner Lemberg <wl@gnu.org>
+# Automake migration by Bertrand Garrigues
+# <bertrand.garrigues@laposte.net>
+#
+# This file is part of groff.
+#
+# groff is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# groff is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+hdtbl_srcdir = $(top_srcdir)/contrib/hdtbl
+
+man7_MANS += contrib/hdtbl/groff_hdtbl.7
+
+# Groff command used to generate .ps files
+HDTBLGROFF = \
+ GROFF_COMMAND_PREFIX= \
+ GROFF_BIN_PATH="$(GROFF_BIN_PATH)" \
+ $(GROFFBIN) $(FFLAG) $(MFLAG) -M$(hdtbl_srcdir) -t -p -e -U
+
+HDTBLTMACFILES = \
+ contrib/hdtbl/hdtbl.tmac \
+ contrib/hdtbl/hdmisc.tmac
+hdtbltmacdir = $(tmacdir)
+dist_hdtbltmac_DATA = $(HDTBLTMACFILES)
+
+hdtbl_test_template = contrib/hdtbl/examples/test-hdtbl.sh.in
+
+# Files installed in $(exampledir)/hdtbl. HDTBLEXAMPLEFILES are
+# located in the source tree, while HDTBLPROCESSEDEXAMPLEFILES are
+# generated in the build tree.
+
+# These files are handled by the '.in.roff' rule.
+HDTBLGENFILES = \
+ contrib/hdtbl/examples/fonts_n.roff \
+ contrib/hdtbl/examples/fonts_x.roff
+EXTRA_DIST += \
+ contrib/hdtbl/examples/fonts_n.in \
+ contrib/hdtbl/examples/fonts_x.in \
+ $(hdtbl_test_template)
+
+HDTBLEXAMPLEFILES = \
+ contrib/hdtbl/examples/common.roff \
+ contrib/hdtbl/examples/chess_board.roff \
+ contrib/hdtbl/examples/color_boxes.roff \
+ contrib/hdtbl/examples/color_nested_tables.roff \
+ contrib/hdtbl/examples/color_table_cells.roff \
+ contrib/hdtbl/examples/color_transitions.roff \
+ contrib/hdtbl/examples/col_rowspan_colors.roff \
+ contrib/hdtbl/examples/mixed_pickles.roff \
+ contrib/hdtbl/examples/rainbow.roff \
+ contrib/hdtbl/examples/short_reference.roff
+
+HDTBLPROCESSEDEXAMPLEFILES = \
+ contrib/hdtbl/examples/chess_board.ps \
+ contrib/hdtbl/examples/color_boxes.ps \
+ contrib/hdtbl/examples/color_nested_tables.ps \
+ contrib/hdtbl/examples/color_table_cells.ps \
+ contrib/hdtbl/examples/color_transitions.ps \
+ contrib/hdtbl/examples/col_rowspan_colors.ps \
+ contrib/hdtbl/examples/fonts_n.ps \
+ contrib/hdtbl/examples/fonts_x.ps \
+ contrib/hdtbl/examples/mixed_pickles.ps \
+ contrib/hdtbl/examples/rainbow.ps \
+ contrib/hdtbl/examples/short_reference.ps
+
+hdtblexampledir = $(exampledir)/hdtbl
+dist_hdtblexample_DATA = $(HDTBLEXAMPLEFILES)
+nodist_hdtblexample_DATA = \
+ $(HDTBLGENFILES) \
+ $(HDTBLPROCESSEDEXAMPLEFILES) \
+ $(DOC_GNU_EPS)
+
+$(hdtblexample_DATA): $(HDTBLTMACFILES)
+
+MOSTLYCLEANFILES += $(HDTBLGENFILES) $(HDTBLPROCESSEDEXAMPLEFILES)
+
+EXTRA_DIST += \
+ contrib/hdtbl/ChangeLog \
+ contrib/hdtbl/TODO \
+ contrib/hdtbl/groff_hdtbl.7.man
+
+hdtbl_TESTS = contrib/hdtbl/examples/test-hdtbl.sh
+TESTS += $(hdtbl_TESTS)
+contrib/hdtbl/examples/test-hdtbl.sh: \
+ $(top_builddir)/config.status \
+ $(HDTBLPROCESSEDEXAMPLEFILES) \
+ $(top_srcdir)/$(hdtbl_test_template)
+ $(AM_V_GEN)sed \
+ -e "s|[@]abs_top_builddir[@]|$(abs_top_builddir)|g" \
+ -e "s|[@]GHOSTSCRIPT[@]|$(GHOSTSCRIPT)|g" \
+ $(top_srcdir)/$(hdtbl_test_template) > $@ \
+ && chmod +x $@
+MOSTLYCLEANFILES += $(hdtbl_TESTS)
+
+# Rule to generate ps and roff files
+SUFFIXES += .roff .in .ps
+
+.roff.ps:
+ $(GROFF_V)$(MKDIR_P) `dirname $@` \
+ && $(HDTBLGROFF) -I $(doc_builddir) -I $(doc_srcdir) -Tps \
+ -dfontpath=$(top_srcdir)/font \
+ -dsopath=$(hdtbl_srcdir)/ \
+ -mhdtbl $< >$@
+
+.in.roff:
+ $(AM_V_GEN)$(MKDIR_P) `dirname $@` \
+ && sed -e "s|[@]fontdir[@]|$(fontdir)|" \
+ -e "s|[@]EGREP[@]|$(EGREP)|" $< >$@
+
+
+$(HDTBLPROCESSEDEXAMPLEFILES): $(DOC_GNU_EPS) groff troff eqn pic tbl \
+ grops font/devps/stamp contrib/hdtbl/examples/common.roff
+
+uninstall_groffdirs: uninstall-hdtbl-hook
+uninstall-hdtbl-hook:
+ if test -d $(DESTDIR)$(hdtblexampledir); then \
+ rmdir $(DESTDIR)$(hdtblexampledir); \
+ fi
+
+
+# Local Variables:
+# mode: makefile-automake
+# fill-column: 72
+# End:
+# vim: set autoindent filetype=automake textwidth=72:
diff --git a/contrib/hdtbl/hdtbl.tmac b/contrib/hdtbl/hdtbl.tmac
new file mode 100644
index 0000000..422ede7
--- /dev/null
+++ b/contrib/hdtbl/hdtbl.tmac
@@ -0,0 +1,1003 @@
+.ig
+
+hdtbl.tmac
+
+This file is part of groff, the GNU roff type-setting system.
+
+Copyright (C) 2005-2020 Free Software Foundation, Inc.
+written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+..
+.
+.
+.\" *****************************************************************
+.\" * hdtbl - Heidelberger table macros *
+.\" * Vers. 0.91 December 2005 *
+.\" *****************************************************************
+.
+.if d TBL \
+. nx
+.
+.mso hdmisc.tmac
+.mso 62bit.tmac
+.
+.
+.\" *****************************************************************
+.\" * default values for some arguments *
+.\" *****************************************************************
+.
+.ds t*hl s\"
+.ds t*vl s\"
+.ds t*tal l\"
+.ds t*hal b\"
+.ds t*val t\"
+.ds t*ff \\n[.fam]\"
+.ds t*fst \\n[.f]\"
+.ds t*fsz 1 1\"
+.ds t*fgc red4\"
+.ds t*bgc bisque\"
+.ds t*bc red4\"
+.nr t*cpd .5n
+.nr t*csp .5n
+.nr t*b .1n
+.nr t*cols 1
+.nr t*v \n[.v]
+.nr t*s \n[.ps]
+.nr t*hy \n[.hy]
+.nr t*l \n[.ll]
+.
+.
+.\" defaults for table captions
+.nr t*cptn 0 1
+.ds t*cptn "".sp .4" \
+ ".t*pv 1.0 1.0" \
+ ".ad l" \
+ "\m[\\*[t*fgc]]Table \\n+[t*cptn]:\0\k*\c"\"
+.
+.
+.\" for better error messages
+.ds nth-1 st\"
+.ds nth-2 nd\"
+.ds nth-3 rd\"
+.
+.\" initialization of various registers
+.nr t*# 0 \" table nesting level
+.nr t*numb 0 1 \" held table diversion #
+.
+.ds *#trc*
+.
+.
+.\" *****************************************************************
+.\" * The four base macros and the two optional macros *
+.\" *****************************************************************
+.
+.ie n \
+. ds g tty:\"
+.el \
+. ds g ps: exec\"
+.
+.\" TBL: table start
+.\" predecessor: text, TD or ETB
+.\" successor: CPTN or TR
+.de TBL
+. ds t*m\\n[t*#] \\n[.m]\"
+. ie \\n[t*#] \
+. br
+. el \{\
+. ds * \\n[.ev]\"
+. ev t*tbl
+. evc \\*[*]
+. di t*tbl0
+. sp .4 \" XXX: hard-coded value
+. nr t*i \\n[.i]
+. ll -\\n[.i]u
+. in 0
+. \}
+. nr t*# +1
+.
+. \" Save current location for error checking at end
+. ds t*FN \\[.F]\"
+. ds t*LN \\[.c]\"
+.
+. t*getarg cols \\$@\" from here string 'args' contains the rest of \\$@
+. ie "\\*[cols]"" \
+. nr t*cols\\n[t*#] \\n[t*cols]
+. el \{\
+. ie \B\\*[cols] \
+. nr t*cols\\n[t*#] \\*[cols]
+. el \
+. tm \\n[.F]:\\n[.c]: Invalid number of columns value '\\*[cols]'.
+. \}
+.
+. t*getarg cpd \\*[args] \" cell padding
+. ie "\\*[cpd]"" \
+. nr t*cpd\\n[t*#] \\n[t*cpd]
+. el \{\
+. ie \B\\*[cpd] \
+. nr t*cpd\\n[t*#] \\*[cpd]
+. el \
+. tm \\n[.F]:\\n[.c]: Invalid cell padding value '\\*[cpd]'.
+. \}
+.
+. t*getarg csp \\*[args] \" cell spacing
+. ie "\\*[csp]"" \
+. nr t*csp\\n[t*#] \\n[t*csp]
+. el \{\
+. ie \B\\*[csp] \
+. nr t*csp\\n[t*#] \\*[csp]
+. el \
+. tm \\n[.F]:\\n[.c]: Invalid cell spacing value '\\*[csp]'.
+. \}
+.
+. t*getarg border \\*[args] \" border thickness
+. ie "\\*[border]"=" \
+. nr t*b\\n[t*#] 0-1
+. el \{\
+. ie "\\*[border]"" \
+. nr t*b\\n[t*#] \\n[t*b]
+. el \{\
+. ie \B\\*[border] \
+. nr t*b\\n[t*#] \\*[border]
+. el \
+. tm \\n[.F]:\\n[.c]: Invalid border thickness value '\\*[border]'.
+. \}\}
+.
+. t*getarg bc \\*[args] \" border color
+. ds t*bc\\n[t*#] \\*[t*bc]\"
+. if !"\\*[bc]"" \{\
+. ie m\\*[bc] \
+. ds t*bc\\n[t*#] \\*[bc]\"
+. el \{\
+. ie "\\*[bc]"=" \
+. ds t*bc\\n[t*#] =\"
+. el \
+. tm \\n[.F]:\\n[.c]: Invalid border color '\\*[bc]'.
+. \}\}
+. ie "\\*[bc]"=" \
+. ds t*bc\\n[t*#]
+. el \{\
+. ie "\\*[bc]"" \
+. ds t*bc\\n[t*#] \\*[t*bc]\"
+. el \
+. ds t*bc\\n[t*#] \\*[bc]\"
+. \}
+.
+. t*getarg width \\*[args] \" table/col widths
+. if "\\*[width]"=" \
+. ds width
+.
+. nr b/2\\n[t*#] (\\n[t*b\\n[t*#]] / 2)\" shortcut
+. nr cscp\\n[t*#] (\\n[t*csp\\n[t*#]] + \\n[t*cpd\\n[t*#]])\" aux. register
+.
+. t*getarg height \\*[args] \" table outline height
+. ie "\\*[height]"" \
+. nr t*height\\n[t*#] 0
+. el \{\
+. ie \B\\*[height] \
+. nr t*height\\n[t*#] (\\*[height] \
+ - ((2 * \\n[cscp\\n[t*#]]) \
+ + (3 * \\n[b/2\\n[t*#]])))
+. el \
+. tm \\n[.F]:\\n[.c]: Invalid height value '\\*[height]'.
+. \}
+.
+. t*cl \\*[width] \" get cell widths and offsets
+. t*args \\n[t*#] \" look for common arguments
+.
+. t*getarg tal \\*[args] \" table horizontal alignment
+. if "\\*[tal]"" \
+. ds tal \\*[t*tal]\"
+. ie "\\*[tal]"l" \
+. nr in\\n[t*#] \\n[.i]
+. el \{\
+. ie "\\*[tal]"c" \
+. nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]]/2 + \\n[.i])
+. el \{\
+. ie "\\*[tal]"r" \
+. nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]] + \\n[.i])
+. el \{\
+. tmc \\n[.F]:\\n[.c]: Invalid horizontal table alignment '\\*[tal]':
+. tm1 " must be 'l', 'c' or 'r'.
+. \}\}\}
+.
+. nr t*r#\\n[t*#] 0 \" initialize row index
+. mk toptbl\\n[t*#]
+.
+. t*P1 \\*[args]
+..
+.
+.
+.\" CPTN: optional table caption
+.\" predecessor: TBL
+.\" successor: TR
+.de CPTN
+. ft 1
+.
+. if "\\$0"CPTN" \
+. if \\n[t*r#\\n[t*#]] \{\
+. tmc \\n[.F]:\\n[.c]: Invalid placement of '.CPTN';
+. tm1 " must be called immediately after '.TBL'.
+. return
+. \}
+.
+. t*getarg val \\$@
+. ds args\\n[t*#] "\\*[args]\"
+.
+. t*index "\\*[args]" .TR
+. ie \\n[t*index] \{\
+. ds *a\\n[t*#] "\\*[args]\"
+. substring args\\n[t*#] 0 \\n[t*index]
+. substring *a\\n[t*#] \\n[t*index]-2 -1
+. \}
+. el \
+. ds *a\\n[t*#]
+.
+. ie "\\*[val]"b" \{\
+. de t*cptn\\n[t*#]
+. *CPTN \\*[args\\n[t*#]]
+. rm t*cptn\\n[t*#]
+\\..
+. \}
+. el \{\
+. ll (\\n[ll\\n[t*#]]u + \\n[in\\n[t*#]]u)
+. in \\n[in\\n[t*#]]u
+. t*P1 \\*[t*cptn]
+' in +\\n[*]u
+. t*P1 \\*[args\\n[t*#]]
+. t*pv 1 1
+. in
+. mk toptbl\\n[t*#]
+. \}
+.
+. t*P1 \\*[*a\\n[t*#]]
+..
+.
+.als *CPTN CPTN
+.
+.
+.\" TR: table row
+.\" predecessor: TBL, CPTN, text, TD or ETB
+.\" successor: TD
+.de TR
+. ft 1
+. if !\\n[t*#] \{\
+. tm \\n[.F]:\\n[.c]: Table row (.TR) without preceding table start (.TBL).
+. return
+. \}
+.
+. \" finish previous data cell, if any
+. if \\n[t*r#\\n[t*#]] \
+. t*dntr 1 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*]
+.
+. nr t*r#\\n[t*#] +1 \" row number in this table
+. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" table row identifier
+. \" (<level>*<row>)
+. nr c#\\*[#t#r] 0 1 \" clear cell counter
+. nr dntr\\*[#t#r] 0 1 \" clear accumulated row height
+.
+. t*getarg height \\$@
+. ie "\\*[height]"" \
+. nr t*height\\*[#t#r] 0
+. el \{\
+. ie \B\\*[height] \
+. nr t*height\\*[#t#r] \\*[height]
+. el \
+. tm \\n[.F]:\\n[.c]: Invalid table row height '\\*[height]'.
+. \}
+.
+. \" If there is a TR with height 'height', the total height of the table
+. \" is too high by 3/2 b, independent of the number of TR with 'height'.
+. t*args \\*[#t#r] \\n[t*#] \" look for common arguments
+.
+. t*P1 \\*[args]
+..
+.
+.
+.\" TH: optional table header cell
+.\" predecessor: text, TD or TR
+.\" successor: text, TD, TR, TBL or ETB
+.\"
+.\" cell content bolded and horizontally and vertically centered,
+.\" else like .TD
+.de TH
+. ft 1
+. t*getarg hal \\$@
+. if "\\*[hal]"" \
+. ds hal c\"
+.
+. t*getarg val \\*[args]
+. if "\\*[val]"" \
+. ds val m\"
+.
+. t*getarg fst \\*[args]
+. if "\\*[fst]"" \
+. ds fst B\"
+.
+. TD hal=\\*[hal] val=\\*[val] fst=\\*[fst] \\*[args]
+..
+.
+.
+.\" TD: table data cell
+.\" predecessor: text, TD or TR
+.\" successor: text, TD, TR, TBL or ETB
+.de TD
+. ft 1
+. \" finish previous data cell -- note the use of \E
+. t*dntr 0 \\n[c#\\*[#t#r]]-1 \En[c#\\*[#t#r]] \\*[*#trc*]
+.
+. ds *#trc* \\*[#t#r]*\\n[c#\\*[#t#r]]\" table cell identifier
+. \" (<level>*<row>*<column>)
+.
+. t*getarg rowspan \\$@
+. nr rowspan 1
+. if !"\\*[rowspan]"" \{\
+. ie \B\\*[rowspan] \{\
+. nr rowspan (\\*[rowspan] >? 1)
+. nr *rsp*\\*[*#trc*] (\\n[rowspan] - 1)
+. \}
+. el \
+. tm \\n[.F]:\\n[.c]: Invalid value of 'rowspan' keyword.
+. \}
+.
+. t*getarg colspan \\*[args]
+. nr colspan 1
+. if !"\\*[colspan]"" \{\
+. ie \B\\*[colspan] \
+. nr colspan (\\*[colspan] >? 1)
+. el \
+. tm \\n[.F]:\\n[.c]: Invalid value of 'colspan' keyword.
+. \}
+.
+. t*args \\*[#trc] \\*[#t#r] \" look for common arguments
+.
+. nr in\\*[#trc] \\n[in\\n[t*#]*\\n[c#\\*[#t#r]]]
+. nr *cl \\n[cll\\n[t*#]*\\n[c#\\*[#t#r]]]
+. nr * 0 1
+. nr *r \\n[t*r#\\n[t*#]]
+.
+. if (\\n[rowspan] - 1) \
+. while (\\n+[*] <= \\n[rowspan]) \{\
+. nr rspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan]
+. if (\\n[*] > 1) \
+. nr cspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan]
+. nr *r +1
+. \}
+.
+. nr * 1 1
+. nr *c \\n[c#\\*[#t#r]]
+.
+. if (\\n[colspan] - 1) \{\
+. nr vline\\*[*#trc*] 0-1 \" set 'no vl' flag
+.
+. while (\\n+[*] <= \\n[colspan]) \{\
+. nr *c +1
+. nr *cl +(2 * \\n[cscp\\n[t*#]] \
+ + \\n[b/2\\n[t*#]] \
+ + \\n[cll\\n[t*#]*\\n[*c]])
+. nr c#\\*[#t#r] +1
+. \}
+. \}
+.
+. if (\\n[c#\\n[t*#]*\\n[t*r#\\n[t*#]]] > \\n[t*cols\\n[t*#]]) \{\
+. ds * are\"
+. ds ** columns\"
+. if (\\n[c#\\*[#t#r]] == 1) \{\
+. ds * is\"
+. ds ** column\"
+. \}
+. tmc \\n[.F]:\\n[.c]: There \\*[*] \\n[c#\\*[#t#r]] table \\*[**] (.TD)
+.
+. ds * are\"
+. if (\\n[t*cols\\n[t*#]] == 1) \
+. ds * is\"
+. tm1 " but only \\n[t*cols\\n[t*#]] \\*[*] expected.
+.
+. ds *
+. length * \\n[.F]:\\n[.c]:
+.
+. while \\n-[*] \
+. ds * " \\*[*]\"
+.
+. tm1 "\\*[*] Remaining .TDs and its contents are ignored.
+.
+. di *t*dummy* \" bypass superfluous input
+. return
+. \}
+.
+. di t*\\*[#trc] \" open cell diversion and set locals
+. in 0
+. nr cll\\*[#trc] \\n[*cl]
+. ll \\n[*cl]u
+. nr *cl\\n[t*#] \\n[.l]
+. gcolor \\*[t*fgc\\*[#trc]]
+. ad \\*[t*hal\\*[#trc]]
+. fam \\*[t*ff\\*[#trc]]
+. ft \\*[t*fst\\*[#trc]]
+. t*pv \\*[t*fsz\\*[#trc]]
+.
+. t*P1 \\*[args]
+..
+.
+.
+.\" ETB: end of table
+.\" predecessor: text, TD or ETB
+.\" successor: text, TD, TR or TBL
+.de ETB
+. ie \\n[t*#] \
+. if !\\n[t*r#\\n[t*#]] \{\
+. tmc \\n[.F]:\\n[.c]: Each table (.TBL)
+. tm1 " should contain at least one table row (.TR)!
+. \}
+. el \{\
+. tmc \\n[.F]:\\n[.c]: Table end (.ETB)
+. tm1 " without corresponding table start (.TBL)!
+. \}
+.
+. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier
+. t*dntr 2 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*]
+.
+. t*divs \" print this table
+.
+. sp \\n[b/2\\n[t*#]]u
+. t*cptn\\n[t*#]
+. nr t*# -1
+.
+. ll \\n[*cl\\n[t*#]]u \" restore ll outside this table
+. in 0 \" reset indent
+. gcolor \\*[t*m\\n[t*#]] \" reset previous fgc
+.
+. t*getarg hold \\$@
+. if !\\n[t*#] \{\
+. sp .5
+. di
+. in \\n[t*i]u
+. ie "\\*[hold]"" \{\
+. ie (\\n[.t] - \\n[dn]) \
+. t*DI t*tbl0
+. el \{\
+. rn t*tbl0 t*tbl\\n+[t*numb]
+. ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[dn]\"
+. \}
+. \}
+. el \{\
+. rn t*tbl0 t*hold\\n+[t*numb]
+. tm \\n[.F]:\\n[.c]: Table t*hold\\n[t*numb] held.
+. ds t*held \\*[t*held] t*hold\\n[t*numb] \\n[dn]\"
+. \}
+.
+. ev \" restore previous environment
+. \}
+.
+. t*P1 \\*[args]
+..
+.
+.
+.\" *****************************************************************
+.\" * Following the definition of five utility macros *
+.\" * special to hdtbl. *
+.\" * Other utility macros common to hdtbl and hdgroff *
+.\" * are defined in the file hdmisc.tmac. *
+.\" *****************************************************************
+.
+.
+.\" .t*free [n]
+.\" print the next [n] held table[s].
+.\" Don't call it within a table!
+.\" If the table is higher than the remaining space
+.\" on the page, the table is printed on the next page.
+.de t*free
+. if "\\$0"CPTN" \
+. if \\n[t*r#\\n[t*#]] \{\
+. tmc \\n[.F]:\\n[.c]: Invalid placement of '.t*free' within a table;
+. tm1 " it must be called outside of any table.
+. return
+. \}
+.
+. if "\\*[t*held]"" \{\
+. tm \\n[.F]:\\n[.c]: No held tables.
+. return
+. \}
+.
+. nr ** (\\$1 >? 1) 1
+. while !""\\*[t*held]" \{\
+. pops * t*held
+. popr * t*held
+.
+. ie (\\n[.t] - \\n[*]) \{\
+. ev t*tbl
+. t*DI \\*[*]
+. ev
+. \}
+. el \{\
+. rn \\*[*] t*tbl\\n+[t*numb]
+. ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[*]\"
+. \}
+.
+. if !(\\n-[**] - 1) \
+. return
+. \}
+..
+.
+.
+.\" The main utility macro for tables:
+.\" If a table is closed by ETB, this macro is called. It
+.\" processes one complete table, i.e., all the table cell
+.\" diversions, paints the cell backgrounds, draws
+.\" horizontal and vertical table lines and the table border.
+.\"
+.\" Nested tables are processed from inside to outside.
+.
+.de t*divs
+. ll (\\n[t*l]u + 1c) \" avoid warning 'can't break line'
+. nf
+.
+. nr b/2 \\n[b/2\\n[t*#]] \" some abbreviations
+. nr cscp \\n[cscp\\n[t*#]]
+. nr cscpb (\\n[b/2] + \\n[cscp])
+.
+. nr topdiv (\\n[.d] + \\n[b/2] - \\n[cscp])\" top of cell diversion
+. nr cscpb2 (\\n[b/2] / 2 + \\n[cscp])
+.
+. nr #r 0 1
+. \" outer loop for rows
+. while (\\n+[#r] <= \\n[t*r#\\n[t*#]]) \{\
+. \" TODO: insert code here for multipage tables
+. nr * (\\n[#r] - 1)
+. nr topdiv +(\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb])
+.
+. \" if table still smaller than specified table height, increase it
+. if ((\\n[#r] == \\n[t*r#\\n[t*#]]) & \\n[t*height\\n[t*#]]) \
+. nr dntr\\n[t*#]*\\n[#r] (\\n[cscpb] \
+ + \\n[toptbl\\n[t*#]] \
+ + \\n[t*height\\n[t*#]] \
+ - (\\n[topdiv] >? \\n[dntr\\n[t*#]*\\n[#r]]))
+.
+. nr #c 0 1
+. \" inner loop for cells
+. while (\\n+[#c] <= \\n[t*cols\\n[t*#]]) \{\
+. ds #trc \\n[t*#]*\\n[#r]*\\n[#c]\"
+. \" continue if the diversion is empty
+. if !d t*\\*[#trc] \
+. continue
+.
+. sp |\\n[topdiv]u
+. in (\\n[in\\n[t*#]]u + \\n[in\\*[#trc]]u)\" cell offset
+. nr $1 \\n[dntr\\n[t*#]*\\n[#r]] \" cell height
+.
+. \" if we have spanned rows, calculate resulting row height
+. \" and position of lower horizontal line
+. if \\n[*rsp*\\*[#trc]] \{\
+. nr * \\n[#r] 1
+. nr rspan\\*[#trc] 0-1 \" set 'no hl' flag
+. nr corr (\\n[dn\\*[#trc]] - \\n[dntr\\n[t*#]*\\n[#r]])
+.
+. \" clear row span flags in following rows and update row height
+. while \\n[*rsp*\\*[#trc]] \{\
+. nr *rsp*\\*[#trc] -1
+. nr rspan\\n[t*#]*\\n+[*]*\\n[#c] 0
+. nr ** (\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb])
+. nr corr -\\n[**]
+. nr $1 +\\n[**]
+. \}
+.
+. if (\\n-[*] == \\n[t*r#\\n[t*#]]) \
+. nr $1 ((\\n[t*height\\n[t*#]] \
+ - \\n[.d] \
+ + \\n[toptbl\\n[t*#]] \
+ + \\n[cscpb]) \
+ >? \\n[$1])
+. nr dntr\\n[t*#]*\\n[*] +(\\n[corr] >? 0)
+. \}
+.
+. \" paint cell background
+. nr * (2 * \\n[t*cpd\\n[t*#]] + \\n[cll\\*[#trc]])\" background width
+. nr $1 (\\n[$1] >? \\n[dn\\*[#trc]])\" cell height
+.
+. if !"\\*[t*bgc\\*[#trc]]"=" \{\
+. nop \h'\\n[t*csp\\n[t*#]]u'\
+\M[\\*[t*bgc\\*[#trc]]]\
+\v'(-.67v - \\n[t*cpd\\n[t*#]]u)'\
+\D'P \\n[*]u 0 \
+ 0 (2u * \\n[t*cpd\\n[t*#]]u + \\n[$1]u) \
+ -\\n[*]u 0'\
+\M[]
+. sp -1
+. \}
+.
+. \" *** horizontal and vertical single or double lines ***
+. \" double and single lines have the same thickness;
+. \" the double lines' distance is the line thickness.
+. \"
+. \" 'border=x': horizontal/vertical lines x/2 thick, minimum .1n
+. \" 'border=0': no border; horizontal/vertical lines .1n thick
+. \" 'border=': neither border nor horizontal/vertical lines
+.
+. nr *t (.1n >? \\n[b/2]) \" thickness of hl/vl; min. .1n
+. in +\\n[cscp]u
+.
+. \" check for vertical and horizontal lines
+. if (1 + \\n[t*b\\n[t*#]]) \{\
+. if !"\\*[t*bc\\n[t*#]]"=" \{\
+. \" draw horizontal line between this cell and the one below
+. if (\\n[t*r#\\n[t*#]] - \\n[#r] + \\n[rspan\\*[#trc]]) \{\
+. if !"\\*[t*hl\\*[#trc]]"=" \{\
+. sp \\n[$1]u
+. nr * (\\n[cscp] + \\n[cscpb] + \\n[cll\\*[#trc]])
+. nop \X'\*[g] 1 setlinecap'\
+\h'(-\\n[cscpb2]u - \\n[*t]u)'\
+\v'(\\n[cscpb2]u - .67v)'\
+\m[\\*[t*bc\\n[t*#]]]\
+\D't \\n[*t]u'\c
+.
+. ie "\\*[t*hl\\*[#trc]]"d" \
+. nop \v'-\\n[*t]u'\
+\D'l \\n[*]u 0'\
+\v'(2u * \\n[*t]u)'\
+\D'l -\\n[*]u 0'\
+\D't 0'
+. el \
+. nop \D'l \\n[*]u 0'\
+\D't 0'
+.
+. sp (-\\n[$1]u - 1v)
+. \}\}
+.
+. nr rspan\\*[#trc] 0
+.
+. \" draw vertical line between this cell and the one to the right
+. if (\\n[t*cols\\n[t*#]] - \\n[#c] + \\n[vline\\*[#trc]]) \{\
+. if !"\\*[t*vl\\*[#trc]]"=" \{\
+. nop \X'\*[g] 1 setlinecap'\
+\v'(-\\n[cscpb2]u - .67v)'\
+\m[\\*[t*bc\\n[t*#]]]\
+\h'(\\n[cscpb2]u - \\n[*t]u + \\n[cll\\*[#trc]]u)'\c
+.
+. ie "\\*[t*vl\\*[#trc]]"d" \
+. nop \h'-\\n[*t]u'\
+\D't \\n[*t]u'\
+\D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\
+\h'(2u * \\n[*t]u)'\
+\D'l 0 -(2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\
+\D't 0'
+. el \
+. nop \D't \\n[*t]u'\
+\D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\
+\D't 0'
+. sp -1
+. \}\}\}\}
+.
+. nr vline\\*[#trc] 0
+.
+. \" vert. cell content alignment
+. nr ** 0
+.
+. ie "\\*[t*val\\*[#trc]]"m" \
+. nr ** ((\\n[$1] - \\n[dn\\*[#trc]]) / 2)\" val=m
+. el \
+. if "\\*[t*val\\*[#trc]]"b" \
+. nr ** (\\n[$1] - \\n[dn\\*[#trc]])\" val=b
+.
+. sp \\n[**]u \" vertical content position
+.
+. \" finally output the diversion
+. t*\\*[#trc]
+. rm t*\\*[#trc]
+. \}
+. \}
+.
+. \" draw the box border
+. in \\n[in\\n[t*#]]u
+. nr ** (\\n[topdiv] + \\n[dntr\\n[t*#]*\\n-[#r]])
+.
+. if \\n[t*b\\n[t*#]] \{\
+. sp |(\\n[toptbl\\n[t*#]]u + \\n[b/2]u)
+. nr $1 (\\n[toptbl\\n[t*#]] - \\n[**] - \\n[cscp])
+. nr * (\\n[ll\\n[t*#]] - \\n[t*b\\n[t*#]])
+.
+. if !"\\*[t*bc\\n[t*#]]"=" \
+. nop \X'\*[g] 0 setlinejoin 2 setlinecap'\
+\v'-.67v'\
+\h'-\\n[b/2]u'\
+\m[\\*[t*bc\\n[t*#]]]\
+\D't \\n[t*b\\n[t*#]]u'\
+\D'l \\n[*]u 0'\
+\D'l 0 -\\n[$1]u'\
+\D'l -\\n[*]u 0'\
+\D'l 0 \\n[$1]u'\
+\D't 0'
+. \}
+.
+. sp |(\\n[**]u + \\n[cscpb]u)
+. fi
+..
+.
+.
+.\" Utility macro: .t*cl [width1 [width2 [...]]]
+.\"
+.\" Calculate cell widths, table width, and cell offsets.
+.de t*cl
+. nr t*cols\\n[t*#] (\\n[.$] >? \\n[t*cols\\n[t*#]])
+. nr ll\\n[t*#] 0 \" accumulated cell widths
+. nr ** (\\n[.l] / \\n[t*cols\\n[t*#]])\" width for remaining cells
+. nr * 0 1 \" counter
+.
+. \" while-loop: Parse user arguments to get each cell's width.
+. while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\
+. nr $\\n[*] \\n[**]
+. if !"\\$[\\n[*]]"" \{\
+. \" check for '%' pseudo scaling indicator
+. ds * \\$\\n[*]\"
+. substring * -1 -1
+. ie "\\*[*]"%" \{\
+. ds ** \\$[\\n[*]]\"
+. substring ** 0 -2
+. ie \B\\*[**] \
+. nr $\\n[*] (\\*[**] * \\n[.l] / 100)
+. el \
+. tm \\n[.F]:\\n[.c]: Invalid relative cell width '\\*[**]%'.
+. \}
+. el \{\
+. ie \B\\$[\\n[*]] \
+. nr $\\n[*] \\$[\\n[*]]
+. el \
+. tm \\n[.F]:\\n[.c]: Invalid cell width '\\$[\\n[*]]'.
+. \}\}
+.
+. nr ll\\n[t*#] +\\n[$\\n[*]]
+. nr ** \\n[$\\n[*]]
+. \}
+.
+. if (\\n[ll\\n[t*#]] > \\n[.l]) \
+. tm \\n[.F]:\\n[.c]: Table width larger than column width.
+.
+. nr ** (0 >? \\n[t*b\\n[t*#]])
+. nr * 0 1
+.
+. \" second while loop: Compute final cell widths.
+. while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\
+. \" Remove border width, if any.
+. if \\n[t*b\\n[t*#]] \{\
+. \" cell_width := cell_width * (length - 1.5*border) / length
+. nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2))
+. nr *** (\\n[ll\\n[t*#]] / 2)
+. \" avoid multiplication overflow
+. mult31by31 $\\n[*] #* ****
+. add31to62 *** **** ****
+. div62by31 **** ll\\n[t*#] $\\n[*]
+. \}
+.
+. \" Get cell widths without padding, spacing, and separator line.
+. nr cll\\n[t*#]*\\n[*] (\\n[$\\n[*]] \
+ - (2 * \\n[cscp\\n[t*#]]) \
+ - \\n[b/2\\n[t*#]])
+.
+. \" Check whether value is non-positive.
+. if !\\n[cll\\n[t*#]*\\n[*]] \{\
+. nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2))
+. nr *** (\\n[#*] / 2)
+. nr *h (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]])
+. mult31by31 *h ll\\n[t*#] ****
+. add31to62 *** **** ****
+. div62by31 **** #* *h
+. ds * \\n[*]th\"
+. nr *** (\\n[*] % 10)
+. if d nth-\\n[***] \
+. ds * \\n[*]\\*[nth-\\n[***]]\"
+. tmc \\n[.F]:\\n[.c]: The \\*[*] width value (\\$\\n[*]) is too small.
+. tm1 " It should be greater than \\n[*h].
+. \}
+.
+. nr in\\n[t*#]*\\n[*] \\n[**] \" cell offset
+. nr ** +\\n[$\\n[*]]
+. \}
+..
+.
+.
+.\" Utility macro: .t*dntr <origin> <cell position> ? <cell ID>
+.\"
+.\" Close TD diversion, make some calculations, and set
+.\" some help strings and registers. <origin> is 0, 1,
+.\" or 2 if the call of .t*dntr occurs in .TD, .TR, or
+.\" .ETB, respectively.
+.de t*dntr
+. nr dn 0 \" reset diversion height
+. br \" finish cell data
+.
+. if "\\n[.z]"*t*dummy*" \
+. return
+.
+. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier
+.
+. if \\n[c#\\*[#t#r]] \{\
+. di \" close diversion
+. nr dn\\$4 \\n[dn] \" save height of this cell
+. if !\\n[rspan\\*[#trc]] \{\
+. \" update row height if not in a row span
+. nr dntr\\*[#t#r] (\\n[dntr\\*[#t#r]] >? \\n[dn])
+. if \\$2 \
+. nr dntr\\*[#t#r] ((\\n[t*height\\*[#t#r]] \
+ - (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]])) \
+ >? \\n[dntr\\*[#t#r]])
+. \}\}
+.
+. nr c#\\*[#t#r] +1
+. nr * \\$2
+.
+. \" update column span registers
+. while (\\n+[*] <= \\$3) \{\
+. if r cspan\\*[#t#r]*\\n[*] \
+. nr c#\\*[#t#r] +\\n[cspan\\*[#t#r]*\\n[*]]
+. nr cspan\\*[#t#r]*\\n[*] 0
+. \}
+.
+. ds #trc \\*[#t#r]*\\n[c#\\*[#t#r]]\"
+.
+. \" only check for cell underflow if called by .TR or .ETB
+. if (\\$1 & (\\n[c#\\*[#t#r]] <= \\n[t*cols\\n[t*#]])) \{\
+. ds * are\"
+. ds ** columns\"
+. if (\\n-[c#\\*[#t#r]] == 1) \{\
+. ds * is\"
+. ds ** column\"
+. \}
+. tmc \\n[.F]:\\n[.c]: There \\*[*] only \\n[c#\\*[#t#r]] \\*[**]
+.
+. nr * \\n[t*r#\\n[t*#]]
+. ds * \\n[*]th\"
+. nr *** (\\n[*] % 10)
+. if d nth-\\n[***] \
+. ds * \\n[*]\\*[nth-\\n[***]]\"
+. tmc " in the \\*[*] row
+.
+. ds * are\"
+. if (\\n[t*cols\\n[t*#]] == 1) \
+. ds * is\"
+. tm1 " but \\n[t*cols\\n[t*#]] \\*[*] expected.
+. \}
+..
+.
+.
+.\" Utility-macro: .t*args level_1 [level_2]
+.\"
+.\" Get the arguments common to TBL, TR, and TD for the level
+.\" in argument 1, using default values from the level in
+.\" argument 2. If argument 2 is missing, use the global
+.\" default values.
+.\"
+.de t*args
+. ds t*bgc\\$1 \\*[t*bgc\\$2]\"
+. ds t*fgc\\$1 \\*[t*fgc\\$2]\"
+. ds t*hl\\$1 \\*[t*hl\\$2]\"
+. ds t*vl\\$1 \\*[t*vl\\$2]\"
+. ds t*hal\\$1 \\*[t*hal\\$2]\"
+. ds t*val\\$1 \\*[t*val\\$2]\"
+. ds t*ff\\$1 \\*[t*ff\\$2]\"
+. ds t*fst\\$1 \\*[t*fst\\$2]\"
+. ds t*fsz\\$1 \\*[t*fsz\\$2]\"
+.
+. if "\\*[args]"" \
+. return
+.
+. t*getarg bgc \\*[args] \" background color
+. if !"\\*[bgc]"" \{\
+. ie m\\*[bgc] \
+. ds t*bgc\\$1 \\*[bgc]\"
+. el \{\
+. ie "\\*[bgc]"=" \
+. ds t*bgc\\$1 =\"
+. el \
+. tm \\n[.F]:\\n[.c]: Invalid background color '\\*[bgc]'.
+. \}\}
+. if "\\*[args]"" \
+. return
+.
+. t*getarg fgc \\*[args] \" foreground color
+. if !"\\*[fgc]"" \{\
+. ie m\\*[fgc] \
+. ds t*fgc\\$1 \\*[fgc]\"
+. el \{\
+. ie "\\*[fgc]"=" \
+. ds t*fgc\\$1 =\"
+. el \
+. tm \\n[.F]:\\n[.c]: Invalid foreground color '\\*[fgc]'.
+. \}\}
+. if "\\*[args]"" \
+. return
+.
+. t*getarg hl \\*[args] \" horizontal line between cells
+. if !"\\*[hl]"" \
+. ds t*hl\\$1 \\*[hl]\"
+. if "\\*[args]"" \
+. return
+.
+. t*getarg vl \\*[args] \" vertical line between cells
+. if !"\\*[vl]"" \
+. ds t*vl\\$1 \\*[vl]\"
+. if "\\*[args]"" \
+. return
+.
+. t*getarg hal \\*[args] \" horizontal table cell alignment
+. if !"\\*[hal]"" \{\
+. t*index bcrl \\*[hal]
+. ie \\n[t*index] \
+. ds t*hal\\$1 \\*[hal]\"
+. el \{\
+. tmc \\n[.F]:\\n[.c]: Invalid horizontal alignment '\\*[hal]':
+. tm1 " must be 'b', 'c', 'l' or 'r'.
+. \}\}
+. if "\\*[args]"" \
+. return
+.
+. t*getarg val \\*[args] \" vertical table cell alignment
+. if !"\\*[val]"" \{\
+. t*index tmb \\*[val]
+. ie \\n[t*index] \
+. ds t*val\\$1 \\*[val]\"
+. el \{\
+. tmc \\n[.F]:\\n[.c]: Invalid vertical alignment '\\*[val]':
+. tm1 " must be 't', 'm' or 'b'.
+. \}\}
+. if "\\*[args]"" \
+. return
+.
+. t*getarg ff \\*[args] \" font family
+. if !"\\*[ff]"" \
+. ds t*ff\\$1 \\*[ff]\"
+. if "\\*[args]"" \
+. return
+.
+. t*getarg fst \\*[args] \" font style
+. if !"\\*[fst]"" \
+. ds t*fst\\$1 \\*[fst]\"
+. if "\\*[args]"" \
+. return
+.
+. t*getarg fsz \\*[args] \" font size and spacing factor
+. if !"\\*[fsz]"" \
+. ds t*fsz\\$1 \\*[fsz]\"
+..
+.
+.
+.\" Append to your page header macro ('pg@top' for MS)
+.\" to enable tables to span pages.
+.de t*hm
+. ev t*tbl
+. nr ** \\n[.t]
+. while !""\\*[t*kept]" \{\
+. pops * t*kept
+. popr * t*kept
+. if (\\n[*] - \\n[**]) \{\
+. tm \\n[.F]:\\n[.c]: Table \\*[*] higher than page -- ignored!
+. break
+. \}
+.
+. if (\\n[*] - \\n[.t]) \{\
+. ds t*kept \\n[*] \\*[t*kept]\"
+. ds t*kept \\*[*] \\*[t*kept]\"
+. tmc \\n[.F]:\\n[.c]: Remaining table(s),
+. tm1 " because not all fit onto this page.
+. break
+. \}
+.
+. t*DI \\*[*]
+. \}
+. ev
+..
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
+.\" vim: filetype=groff: