wireframe-whiteboard Groff by example: tables with tbl

Use this sample groff document to learn how to format tables that span data between rows and columns.

One of the first popular document preparation systems was nroff and troff, from Unix by Bell Labs. Troff, later ditroff for device independent troff, created output for a phototypesetter. This allowed for producing very professional-looking technical documentation, articles, and books long before high resolution laser printers were either common or affordable.

But documents are more than just text. Depending on the contents, a technical document might require more advanced formatting like tables. Troff added the tbl preprocessor program in Unix 6th Edition, in May 1975. The tbl program processed an input file before full processing by the troff program, generating output that the troff program could interpret on behalf of the phototypesetter.

GNU groff now encompasses the original Unix troff tools, including tbl. When we think of tbl, we're probably using tbl from groff.

Tbl by example

A basic table using tbl might look like this:

.TS
tab(@) allbox center;
lb cb rb
l  c  r.
Left@Center@Right
one@two@three
four@five@six
seven@eight@nine
.TE

This code generates a table with three columns and three rows. The .TS and .TE requests indicate the table start and table end. The first row uses bold (b) type, such as for a header; the rest of the table uses regular weight text. The first column is aligned left (l), the middle column is centered (c), and the third column is aligned right (r).

But the tbl preprocessor can do more than simple grids of columns and rows. More complex data might require spanning data between columns or rows. This sample document includes two tables that use spans across rows and columns:

.pp
Here's a simple table with boxes around every cell.
In the column specification, append
.b b
to make that item bold, which is typical for a
header.
.TS
tab(@) allbox center;
lb cb rb
l  c  r.
Left@Center@Right
one@two@three
four@five@six
seven@eight@nine
.TE
.pp
Here's a more complicated table that spans columns
and rows. Use
.b s
to span columns into each other, and
.b ^
to span rows into each other: (reference:
.i "ANSI X3.9-1978" ,
page 3-4s)
.TS
tab(@) allbox center;
c c s
^ c c
^ ^ c
^ ^ c
^ ^ c
^ ^ c
c s s.
Comment Lines@PROGRAM, FUNCTION, or SUBROUTINE
@FORMAT@IMPLICIT
@@Other Specification
@@DATA
@@Statement Function
@@Executable
END@@
.TE
.pp
And an updated version of the table with additional
spans. Note that the column specification at the top
has one row per line, so we can match up the rows we
want: (reference:
.i "ANSI X3.9-1978" ,
page 3-4)
.TS
tab(@) allbox center;
c c s s
^ c c c
^ ^ ^ c
^ ^ c c
^ ^ ^ c
c s s s.
Comment Lines@PROGRAM, FUNCTION, SUBROUTINE, or BLOCK DATA@@
@FORMAT and ENTRY@PARAMETER@IMPLICIT
@@@Other Specifications
@@DATA@Statement Functions
@@@Executable
END@@@
.TE

This document uses the -me macros, although tbl will work with any macro package. Save this sample file as table.me.

Process the file with the tbl preprocessor program, and then the groff program:

$ tbl table.me | groff -me -Tps > table.ps

You can also use the -t command line option with groff to run the tbl preprocessor for you:

$ groff -t -me -Tps table.me > table.ps

A table formatted with groff tbl

A table formatted with groff tbl

To span data, note that you need to provide a separate row specification in the table header. For example, to center text within a single cell, you use the c format specifier. But to span data from the previous cell into the next cell, use the s format specifier. To span cells between rows, use the ^ specifier; this tells groff to span data from the above cell into the same cell in the next row.