groff
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Groff] Strategy for fixing tbl


From: Eric S. Raymond
Subject: [Groff] Strategy for fixing tbl
Date: Thu, 8 Feb 2007 04:47:06 -0500
User-agent: Mutt/1.4.2.2i

I've been reading the tbl code.  I don't completely understand it yet, but
I think I've found a fairly simple technique for addressing the T{ T} problem.
Please critique.

First, the source for a simple table:

.TS
l l l.
AAAAAA  BBBBB   CCCC
DDD     T{
EEEEE
T}      FF
GGG     HHH     III
.TE

Note the one T{ T} in the middle. Internally, tbl calls these 'block
entries'.  Now, here is what the key sections of the output look like,
with some text commentary and [..........] standing for omitted lines.

.if !\n(.g .ab GNU tbl requires GNU troff.
.if !dTS .ds TS
.if !dTE .ds TE
.lf 1 -
.TS
[..........]

No table data appears before this point.  There are probably some minor
variations by format line elements, but up to here it seems to be mostly
canned preamble.

I'm going to magically suppose that we have added to this preamble the
setting of a numeric register named '3bc' that counts the number of
columns containing block entries -- in this case, 1.  I don't know how
to do that, yet, but bear with me.

.lf 3 -
.nr 3w0 \n[3w0]>?\w\[tbl]AAAAAA\[tbl]
.lf 3
.nr 3w1 \n[3w1]>?\w\[tbl]BBBBB\[tbl]
.lf 3
.nr 3w2 \n[3w2]>?\w\[tbl]CCCC\[tbl]
.lf 4
.nr 3w0 \n[3w0]>?\w\[tbl]DDD\[tbl]
.lf 6
.nr 3w2 \n[3w2]>?\w\[tbl]FF\[tbl]
.lf 7
.nr 3w0 \n[3w0]>?\w\[tbl]GGG\[tbl]
.lf 7
.nr 3w1 \n[3w1]>?\w\[tbl]HHH\[tbl]
.lf 7
.nr 3w2 \n[3w2]>?\w\[tbl]III\[tbl]

This is interesting.  >? is the max operator.  What we're seeing here
looks like computation of minimum column widths based on all the
non-block entries.  There is no term corresponding to EEEEE because
it's a block entry and the width is not fixed.

.nr 3w0 \n[3w0]>?(\n[3lnw0]+\n[3rnw0])
.if \n[3aw0] .nr 3w0 \n[3w0]>?(\n[3aw0]+2n)
.nr 3w1 \n[3w1]>?(\n[3lnw1]+\n[3rnw1])
.if \n[3aw1] .nr 3w1 \n[3w1]>?(\n[3aw1]+2n)
.nr 3w2 \n[3w2]>?(\n[3lnw2]+\n[3rnw2])
.if \n[3aw2] .nr 3w2 \n[3w2]>?(\n[3aw2]+2n)

The stuff above looks like column width corrections for inter-column 
spacing.

Now, I'm going to insert a bit of notional code in here in the style tbl
might generate it:

        .nr 3avail \n[.ll]
        .nr 3avail -\n[3w0]
        .nr 3avail -\n[3w1]
        .nr 3avail -\n[3w2]
        .nr 3avail 0>?\n[3avail]

I think I just computed the amount of line width available for 
block-entry expansion.  Back to the real code, now.

.di 3tbd1,1
.if \n[3fll] .fi
.in 0
.ll (u;\n[3w1]>?(\n[.l]*1/4))
.cp \n(3c
.lf 5
EEEEE
.br
.di

That was the block entry being stashed in a diversion -- *after* the
fixed column widths (and, notionally, the remaining available space)
have already been computed. The bit we need to change is (\n[.l]*1/4),
which is allocating 1/(3+1)th of the current line length.

Suppose, at this point, we just changed that .ll line to this:

        .ll (u;\n[3w1]+\n[3avail]/\n[3bc])

In this particular table, \n[3bc] is 1.  Had there been more table
columns containing blocks, using \n[3bc] as the divisor would ensure
that the unused width got evenly divided among them.

I think this would just work.  Look at the next couple of lines:

.cp 0
.nr 3w1 \n[3w1]>?\n[dl]
.nr 3tbh1,1 \n[dn]
.nr 3tbw1,1 \n[dl]

It seems clear that in the code tbl generates, after each diversion
is omitted it gets the actual diversion sizes and uses them to correct
the cell width, cell height, and column width associated with the cell.

So everything after that, including the motions to position the cell
entries, should work unaltered.   We can see the column offsets and total
table width being computed in the next few lines:

.3init
.in \n[3ind]u
.nf
.nr 3cd0 0
.nr 3cl0 0*\n[3sep]
.nr 3ce0 \n[3cl0]+\n[3w0]
.nr 3cl1 \n[3ce0]+(3*\n[3sep])
.nr 3cd1 \n[3ce0]+\n[3cl1]/2
.nr 3ce1 \n[3cl1]+\n[3w1]
.nr 3cl2 \n[3ce1]+(3*\n[3sep])
.nr 3cd2 \n[3ce1]+\n[3cl2]/2
.nr 3ce2 \n[3cl2]+\n[3w2]
.nr 3cd3 \n[3ce2]+(0*\n[3sep])
.nr TW \n[3cd3]

The rest, including the actual table output, is not interesting.  We've
computed all the parameters it's going to use.

[....]
.TE

Am I hallucinating?  This looks really simple.  I don't know how to compute
the bc value yet, but that can't be difficult.
-- 
                <a href="http://www.catb.org/~esr/";>Eric S. Raymond</a>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]