Professional Documents
Culture Documents
U
*
4
3 tabu and longtabu
2 7
1 6 Flexible LAT EX tabulars
5 9 FC
8 2011/02/26 version 2.8 release
10
Abstract
This package defines a single environment tabu to make all kinds of tabulars in text or in math mode
provided that they do not split across pages.
An environment longtabu based on D. Carlisle longtable package is also provided to make tabulars
that can stretch out on several pages, while keeping some features (not all of them) of the tabu
environment.
tabu is more flexible that tabular, tabular*, tabularx and array and extends the possibilities. All
tabulars in this document were made with the tabu environment, of course... The implementation is
optimised to minimise the measurements required to put all together.
b likes colors too, with special lines that are able to keep the alignment of the surrounded text...
U
and also like numbers with the possibility to embed siunitx S (or s) columns. b does not modify
U
any of the macro defined by array.sty or in the LATEX kernel1 .
b requires -TEX and the standard package array.sty. Natural widths of columns are computed
U
(but not printed ) by the code of varwidth by D. Arseneau. Finally longtabu is based on longtable.
Contents
Summary of the features provided by b .......................................... 3
U
*
This documentation is produced with the DocStrip utility, and required b with its linegoal option.
U
1. Inside the tabu environment a few macros are modified... this was compulsory ! 1 / 101
b Flexible LATEX tabulars
11.2 Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
11.3 The tabu strategies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
11.4 Identification and Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
11.5 Flow chart of expansion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
11.6 Some constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
11.7 Rules, colors and vertical adjustment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
11.8 The entry inside tabu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
11.9 The rewriting process: inside the \@mkpream group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
11.10 Implementing the strategy at the exit of the \@mkpream group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
11.11 One trial after the other (\tabu@strategy) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
11.12 The algorithms: Measuring the tabu box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
11.13 Measuring the natural width of columns (varwidth code from D. Arseneau) . . . . . . . . . . . . . . . . . . . . . 69
11.14 Measuring the height and depths of rows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
11.15 \tabuphantomline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
11.16 Horizontal lines inside tabu: \tabucline, \firsthline and \lasthline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
11.17 Numbers in tabu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
11.18 Verbatim inside tabu with X columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
11.19 \savetabu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
11.20 \rowfont . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
11.21 Taking care of footnotes and \arraybackslash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
11.22 Corrections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
11.23 Package options and Initialisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
12 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
13 History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
[2011/02/26 v2.8] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
[2011/02/25 v2.7] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
[2011/02/24 v2.6] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
[2011/02/19 v2.5] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
[2011/02/17 v2.4] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
[2011/02/13 v2.3] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
[2011/02/12 v2.2 New implementation - Absolutely no modification of array.sty] . . . . . . . . . . . . . . . . . . . . . . . . . 91
[2011/01/19 v2.1] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
[rev.2.8 release] 2010 2011 FC
[2011/01/18 v2.0] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
[2011/01/15 v1.9] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
[2010/12/28 v1.8] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
[2010/12/18 v1.7] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
[2010/12/07 v1.5] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
[2010/11/22 v1.4] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
[2010/11/18 v1.3] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
[2010/11/15 v1.2] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
[2010/10/28 v1.1] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
14 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
U
b
2 / 101
b Flexible LATEX tabulars
U S u m m a r y o f t h e f e a t u r e s p r ov i d e d by b
U
tabu is like tabular in text mode and like array in math mode when
there is no X column in its preamble
longtabu is like longtable with the possibility to use tabu X columns and
vertical lines with the extended syntax.
{tabu} to hdimeni specifies the target width of the whole tabular. This is like
tabular with an automatic stretchability that can be overwritten
with @{\extracolsep {dimen}} in front of the preamble.
{tabu} spread hdimeni has no equivalent in LATEX: the final width is hdimeni wider than
the natural width that can be obtained with spread 0pt.
|[width,color] vertical lines have an optional parameter.
X[coef,align,type] X columns widths are adjusted in order for the whole tabular to
X[coef,align,type,$] fit the target width. The target width is a dimension either:
directly specified with {tabu} tohdimeni
computed from the natural width: {tabu} spreadhdimeni
by default \linewidth (or \linegoal with the linegoal package
option).
coef scales the widths of the X columns, if there are more than
one X column.
align is either r, c, l or j (or R C L J) and type can be p
(default), m or b.
X[$] makes a math X column (ie. >{$}X<{$})
X[$$] display math X column: >{$\displaystyle }X<{$}
X[coef,align,type] X columns widths are first computed with the absolute value:
|coef|. Then the width is made narrower down to the natural
width of the column if possible.
In any case, the final width does not exceed the one obtained
with X[|coef|].
X[X options]{S[S options]} Embed a siunitx S column into a tabu-X column.
\everyrow {code} Allows to add horizontal lines automatically for every row.
The settings can be changed inside the tabu
\rowfont [align]{font spec} Modify the font and optionally the alignment of each cell in one
row.
\tabulinesep =hdimeni More control on vertical spacing of lines in a way very close to
cellspaces method (dynamic vertical spacing adjustment).
\extrarowsep =hdimeni Control vertical spacing (\extrarowheight and
\extrarowdepth): fixed vertical spacing adjustment.
\tabulinesep generally gives better results.
\tabudecimal {\usermacro } a help to align numbers easily inside a column.
\savetabu {user-name} Saves the tabu preamble and its parameters. The command must
appear at the end of a line.
\usetabu {user-name} Makes a tabu of exactly the same shape as the one saved with
\savetabu. All parameters (target, preamble, stretch etc.) are
[rev.2.8 release] 2010 2011 FC
restored.
This command is put alone in the preamble in place of the
columns specifications.
\preamble {user-name} Makes a tabu with the same preamble as the one saved with
\savetabu. The only preamble is restored, not the target nor
any other parameter.
This command is put alone in the preamble in place of the
columns specifications.
U
b
3 / 101
b Flexible LATEX tabulars
U
S u m m a r y o f t h e f e a t u r e s p r ov i d e d by b
U
\tabulinestyle {line spec} Sets the current line style to be used for | and \tabucline
\newtabulinestyle {name=spec,...} Defines a line style for use with \tabucline [name] or with
|[name]
\tabucline [spec]{start-stop} Draws a line comparable to \hline. The line hspeci can contain
information for making a dash or dotted line (f.ex. [on 3pt off
6pt]) and a color name.
The line spec can also be defined with \newtabulinestyle
\taburulecolor |dbl rule sep|{rule color} sets the color for rules (\hline, \firsthline...)
\taburowcolors [skip]hnumberi{first .. last} Sets the color series to make alternate background colors for rows
\tabuphantomline inserts a phantom (ie.invisible) line inside the tabu
May be usefull with \multicolumn in some cases.
\tracingtabu = 0, 1, 2, 3, 4 Reports informations in the .log file about the steps of the
algorithm for tabu X columns, and the informations saved by
\savetabu.
[rev.2.8 release] 2010 2011 FC
U
b
4 / 101
b Flexible LATEX tabulars
U
1 Examples and counterexamples
Lets begin in colors !
b provides facilities to put horizontal and vertical leaders in a tabular. The package xcolor
U
must be loaded of course. Background colors for cells are left to package colortbl which is fully
compatible with b .
U
1.1 Locally global settings and their scopes
\tabulinestyle b observes TEX grouping levels for the settings of rule colors (\taburulecolor) and styles
U
\taburulecolor (\tabulinestyle), and \everyrow. There is however a subtility for nested tabu environments as
\taburowcolors described in this example:
\everyrow
Listing 1: Locally global settings and their scopes
\ t a b u r u l e c o l o r | g r a y ! 5 0 | { r e d } \ a r r a y r u l e w i d t h =1pt
{
\ t a b u r u l e c o l o r | y e l l o w |{ b l u e }
\ b e g i n { tabu }{|X|X|} \ h l i n e
Here t h e l i n e s & a r e drawn i n b l u e \\ \ t a b u r u l e c o l o r { g r e e n } \ h l i n e
But s t a r t i n g from h e r e & t h e y a r e g r e e n c o l o u r e d ! \\ \ h l i n e
And now a n e s t e d tabu & \ b e g i n { tabu }{X} \ f i r s t h l i n e \ h l i n e
g u e s s what c o l o u r \\ \ h l i n e
i s used f o r r u l e s ?\\ \ l a s t h l i n e \ h l i n e
\ end { tabu } \\ \ h l i n e
\ end { tabu }
% I n s i d e t h e group , r u l e c o l o r s a r e b l u e
}
% A f t e r t h e group , r u l e c o l o r s a r e r e d a g a i n !
\ b e g i n { tabu }{X}\ h l i n e \ h l i n e \ i n d e n t \ end { tabu }
Color of the last And now a nested tabu guess what colour
end-of-line setting
Color of the is used for rules ?
TEX group
Inside the group, rule colors are blue After the group, rule colors are red again !
is done inside a \noalign group). But a nested tabu does not inherit from this global
setting, and inherits from the settings of the TEX group instead.
If \arrayrulecolor or \doublerulesepcolor (from package colortbl) are used instead of
\taburulecolor then colors are globally overwritten.
U
b
5 / 101
b Flexible LATEX tabulars
U A counterexample from the xcolor package: \rowcolors does not like \cline, \cmidrule etc.2
\ r o w c o l o r s {2}{ g r e e n ! 2 5 } { y e l l o w ! 5 0 }
\ b e g i n { t a b u l a r }{ c c } \ t o p r u l e
\ r e p e a t c e l l 2{ test row 1
rows =5 , test row 2
t e x t / c o l 1= t e s t , test row 3
t e x t / c o l 2=row \number\rownum} \\ test row 4
t e s t & o t h e r row \number\rownum \\ \ c m i d r u l e test row 5
{1 -2} test other row 6
t e s t & o t h e r row \number\rownum \\ test other row 8
t e s t & o t h e r row \number\rownum \\ \ test other row 9
bottomrule
\ end { t a b u l a r }
\ t a b u r o w c o l o r s [ 2 ] 2{ g r e e n ! 2 5 . . y e l l o w ! 5 0 }
\ b e g i n { tabu }{*2{X [ c ] } } \ t o p r u l e test row 1
\ r e p e a t c e l l 2{ test row 2
rows =5 , test row 3
t e x t / c o l 1= t e s t , test row 4
t e x t / c o l 2=row \ thetaburow } \\ test row 5
t e s t & o t h e r row \ thetaburow \\ \ c m i d r u l e test other row 6
{1 -2}
t e s t & o t h e r row \ thetaburow \\ test other row 7
t e s t & o t h e r row \ thetaburow \\ \ bottomrule test other row 8
\ end { tabu }
b does not use real alternate colors but colorseries provided by package xcolor. This allow
U
some gradations:
test Row number 1=1
\ t a b u r o w c o l o r s 5{ g r e e n ! 2 5 . . y e l l o w ! 5 0 } test Row number 2=2
\ b e g i n { tabu }{X [ - 1 ] X} test Row number 3=3
\ r e p e a t c e l l 2{ test Row number 4=4
rows =10 ,
test Row number 5=5
t e x t / c o l 1= t e s t ,
t e x t / c o l 2={Row number test Row number 6=6
\ row$=$\ thetaburow } , test Row number 7=7
} test Row number 8=8
\ end { tabu } test Row number 9=9
test Row number 10=10
\ end { tabu }
. M mp
a
[rev.2.8 release] 2010 2011 FC
x
E
2. Because color changes are done at \everycr, which is not exactly the same as b \everyrow!
U
U
b
6 / 101
b Flexible LATEX tabulars
tabu is useless when nested inside another tabular. The star form of the environment should
be used only for the outermost table ! Comments are removed, unless the % character is given a
category code of 12 (or 11) before the entry inside the environment.
\ t a b u l i n e s t y l e { on 2 pt Crimson ! 6 0 o f f 3 pt y e l l o w ! 5 0 } \ t a b u l i n e s e p =2mm
\ m a k e a t l e t t e r \ @makeother \%
\ b e g i n { tabu *} s p r e a d 0 pt {|X [ - 1 ] X|} \ t a b u c l i n e -
This i s a s m a l l \ Verb+\Verbatim+\par
insertion
&
\ b e g i n { Verbatim } [ l i s t p a r a m e t e r s ={\ t o p s e p =-\ ht \ s t r u t b o x } ]
And t h i s i s a c o m p l e t e % with some comments
Verbatim environment % e v e r y now and then
\ end { Verbatim }
\\ \ t a b u c l i n e -
\ end { tabu *}
X[$] columns
$\ b e g i n { tabu } s p r e a d . 5 i n |{*3{X[ $ $ c ] } } |
\ a l p h a & \ b e t a & \gamma \\ X ai
\sum_ i \ f r a c { a_ i }{ x_ i } & 0 & \ c d o t \\ 0
\ end { tabu }$
i
xi
X[$$] columns
U
b
7 / 101
b Flexible LATEX tabulars
U
limitations:
The X column must be centered: X[c] to keep the alignment,
The optional alignment parameter of \rowfont must not be used.
\ newcolumntype Z{X [ c ] {%
S [ group - f o u r - d i g i t s=t r u e ,
round - mode=p l a c e s ,
round - p r e c i s i o n =2 ,
round - i n t e g e r - to - d e c i m a l=t r u e , January February ...
per - mode=symbol ] } } 12.32 745.32 ...
\ tabucolumn Z 21.13 0.00 ...
\ b e g i n { tabu } s p r e a d 8 pt {|*2{Z|} c } \ t a b u c l i n e -
\ rowfont \ b f s e r i e s 213.32 12.34 ...
{ January } &{ February } & . . . \\ 2 143.12 324.33 ...
\ t a b u c l i n e [ 1 pt on 2 pt GreenYellow ] - Column widths are
12.324 &7 4 5 . 3 2 & . . . \\ exactly the same
21.13 &0 & . . . \\
2 1 3 . 3 2 4 5 &1 2 . 3 4 2 & . . . \\
2 1 4 3 . 1 2 &3 2 4 . 3 2 5 & . . . \\\ t a b u c l i n e -
\ end { tabu }
\tabucolumn is there to say b that the column type has to be treated with a high priority
U
8 / 101
b Flexible LATEX tabulars
\begin {tabu} tohdimeni is like tabular but the inter-columns space is given a stretchability of 1fil, in other
words @{\extracolsep {0pt plus 1fil}} is inserted by default at the beginning of the tabular
preamble, unless another value for \extracolsep is specified. Therefore tabu to fills in width
the specified hdimeni.
\begin {tabu} spreadhdimeni does a tabular whose width is hdimeni wider than its natural width.
@{\extracolsep {0pt plus 1fil}} is inserted by default if hdimeni> 0.
U
b
9 / 101
b Flexible LATEX tabulars
If the width of the whole tabular is not specified with tabu to it is considered to be
\linewidth. The linegoal package option makes the default width equal to \linegoal.
Compilation must then be done with pdfTEX either in pdf or dvi mode, and package
linegoal is loaded. \linegoal requires pdfTEX for its \pdfsavepos primitive and the
zref-savepos: if the tabu is not alone in its paragraph ie.if the target is not \linewidth,
then two compilations (or more) are required to get the correct target.
Default target for nested tabu environments is always \linewidth, which equals to the
column width inside p, m, b and X columns.
U
As long as the \halign content is expanded more than once, protections against counters
b
10 / 101
b Flexible LATEX tabulars
U incrementation, whatsits (write) index entries, footnotes etc.. are set up: the mechanism of
tabularx is reimplemented and enhanced for tabu X columns. \tabuDisableCommands
can be used to neutralize the expansion of additional macros during the trials.
1 2 3 4 5 6
But the text in each cell is very short: one single character, and you prefer the table to be tight,
but dont know the exact width of the whole:
\begin{tabu} spread 0pt{|X[2]|X[2]|X|X|X[2]|X[2]|} \hline
1 & 2 & 3 & 4 & 5 & 6 \\\hline
\end{tabu}
1 2 3 4 5 6
But now its definitely too narrow, then give it some more space:
\begin{tabu} spread 2in{|X[2]|X[2]|X|X|X[2]|X[2]|} \hline
1 & 2 & 3 & 4 & 5 & 6 \\\hline
\end{tabu}
1 2 3 4 5 6
tabu spread is useless with long columns: the following tabular was made with this preamble:
\begin{tabu} spread 3cm{@{}X[9]X[4]|X|}
"Like the air we breathe, Sherlock Holmes is everywhere. His pipe- There the text was too long,
Sherlock Holmes
smoking, deer stalkered image peers at us from ads in Yellow Pages, and tabu spread behaves as if
to signs for neighbourhood crime-watch; from billboards to the you didnt give it a target.
classroom; from film and television to the public library, and now
over the Internet. He long ago transcended the boundaries of 19th The result of this example is
Century London3 to become an international best-seller and has the same as if one had written
been accepted as part of British folklore. Holmes is alive to millions." \begin {tabu}to\linewidth.
The official web site: http://www.sherlockholmes.com/
In the preamble, @{} means that the margin is removed.
\gamma & \ d e l t a + \ e p s i l o n + \ z e t a + \ e t a + \ t h e t a
\ end { tabu }$
&
This i s a tabu with n e g a t i v width c o e f f i c i e n t s f o r \ t e x t t X columns
\\ \ t a b u c l i n e -
\ end { tabu }
!
This is a tabu with negativ width coefficients for X columns
++ ++
U
3. Capital of the U.K. (too see a linked footnote)
b
11 / 101
b Flexible LATEX tabulars
U
!
And this is the same with \tabulinesep set to 2pt.
++ ++
Multicolumn in tabu
\tabuphantomline
The process of \multicolumn implies the TEX primitive \omit which discards the tabular
preamble for the spanned columns. Discarding the preamble means discarding the information
about the widths of the columns. This explains why the following example does not work
properly:
\begin{tabu}{|X|X|X[2]|} \tabucline-
\multicolumn2{|c|}{Hello} & World \\ \tabucline-
\end{tabu}
The correct result can be obtained by the mean of a phantom line, that will remain invisible
unless your preamble contains special @ or ! columns that prints some text:
\begin{tabu}{|X|X|X[2]|} \tabucline-
\multicolumn2{|c|}{Hello} & World \\ \tabucline-
\tabuphantomline
\end{tabu}
Hello World
Remember you may need \tabuphantomline in conjunction with \savetabu and \usetabu
with \multicolumn. Even if it is possible to add a \tabuphantomline in any line of the tabu,
it is a good practice to append it at the end of the tabu, for it may introduce indesirable side
effects on vertical alignment otherwise, when tabu is nested inside another tabular.
In particular, \tabuphantomline should not be followed by \cr or \\ or \tabularnewline...
The need for this command could disappear in a future release, but this requires a complete new
implementation of \multicolumn...
These parameters can be used in text and math modes to give more vertical space between lines,
especially when using math formulae.
Examples (with \tracingtabu = 3 and interfaces-\papergraduate to see the struts):
4. However \tabulinesep is not a dimension ! You cant test, for example, \ifdim \tabulinesep > 0pt ! Test
U
\abovetabulinesep and \belowtabulinesep instead, if needed.
b
12 / 101
b Flexible LATEX tabulars
U
3
d d d
2
dt dt dt
1
\tabulinesep = 0mm \tabulinesep = 1mm \tabulinesep = 3mm
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0
\tabulinesep is a soft parameter, and leads to rows which do not share the same height.
\extrarowsep =hdimeni
\extrarowsep =^hdimeni
\extrarowsep =_ hdimeni
\extrarowsep =^hdimeni_hdimeni
\extrarowsep =_hdimeni^hdimeni
\extrarowsep is an extra vertical space which is added to each row, inconditionally. array.sty
provides the TEX dimension \extrarowheight and b provides \extrarowdepth in addition.
U
As a result, the rows can share the same height/depth but the spacing is not dynamic.
\tabulinesep can be used even with positive values for \extrarowsep, for tabu inserts only one
strut per row and vertical spacing computations are possible in all cases.
The macro can be prefixed by \global as well, even inside a \noalign group5 .
Set \extrarowheight and \extrarowdepth to different values, with the syntaxes:
\extrarowsep =^hdimeni sets \extrarowheight
\extrarowdepth is unchanged
\extrarowsep =_hdimeni sets \extrarowdepth
\extrarowheight is unchanged
\extrarowsep =_hdimeni^hdimeni sets \extrarowdepth and \extrarowheight.
Both \extrarowheight and \extrarowdepth are scaled by \arraystretch (a scaling macro6 of
array.sty) if \arraystretch > 1...
These parameters can be used in text and math modes.
Examples (with \tracingtabu = 3 and interfaces-\papergraduate to see the struts):
Standard c
4 X[-1,c] columns Math mode Mixed: X[-1c]X[-1c$]
column
3
One Two One Two First
2 d
Three Four Three Four tx Second
dt
\extrarowsep =3mm
1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0
4
Standard c
X[-1,c] columns Math mode Mixed: X[-1c]X[-1c$]
3
column
One Two One Two First
[rev.2.8 release] 2010 2011 FC
2
Three Four Three Four tx d
Second
dt
\extrarowsep =0mm
1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0
5. However \extrarowsep is not a dimension ! You cant test, for example, \ifdim \extrarowsep > 0pt ! Test
\extrarowheight and \extrarowdepth instead, if needed.
U
6. \arraystretch is not a dimension but a macro that stores a scaling factor.
b
13 / 101
b Flexible LATEX tabulars
Here, vertical lines are made with delarray shortcuts: $\begin{tabu} spread 1em |{cc}|
Vertical lines inside the tabular preamble gives:
properly designed commands for horizontal rules in tabulars. arydshln is pretty good too, but it
modifies a huge amount of macros of array.sty, something that b does not.
U
Lines in tabu printed in this document are mostly made with booktabs.
\end {tabu}
vi rt ab
s
to U
It is not a necessary to protect the optional argument with braces: [{...}]. because b takes
U
care the | token to be rewritten before any other column type (the same for tabu X columns,
and siunitx S columns). The rewriting process is divided into three stages under control inside a
U tabu environment.
b
14 / 101
b Flexible LATEX tabulars
Tables
\begin {tabu}[t]{c} Tables with no versus
with no\\ line \\ commands \\ used line
\end {tabu} commands
versus tables
ent
used
alig op
\begin {tabu}[t]{|c|}
nm
T
Tables
\begin {tabu}[t]{c} Tables with no versus
with no\\ line \\ commands \\ used line
\end {tabu} commands
alig ttom
versus tables
ent
used
nm
\begin {tabu}[b]{|c|}
Bo
But the optional argument must come in first position: \firsthline [extratabsurround] ...
The same for \lastline.
In yellow you can see the \extratabsurround strut, because \tracingtabu = 3 for this tabu
U
b
15 / 101
b Flexible LATEX tabulars
\ t a b u r u l e c o l o r | l i m e |{ D a r k S l a t e B l u e }
\ a r r a y r u l e w i d t h =1mm \ d o u b l e r u l e s e p =2mm
Here i s Here is a tabu
b package !
U
\ b e g i n { tabu } s p r e a d 0 pt {X [ - 1 ] } environment
\ f i r s t h l i n e \ hline made with
a tabu \\
environment \\
made with \\ \ l a s t h l i n e [ 5mm] \ h l i n e \ h l i n e
\ end { tabu } \TabU package ! \ par And the next paragraph follows...
And t h e n e x t p a r a g r a p h f o l l o w s . . .
This command defines a line style to be used in the first optional argument of \tabucline (horizal
lines) or the optional argument of |(vertical lines) or with \tabulinestyle (locally-global style).
Style names and color names are babel-protected.
16 / 101
b Flexible LATEX tabulars
\everyrow can be used in longtabu as well. The syntax is like \everycr: a token-like syntax,
and braces are mandatory: \everyrow {argument}.
U
b
17 / 101
b Flexible LATEX tabulars
U
\taburowcolors [first line]hnumberi{first .. last}
\taburowcolors sets the alternate colors to be used on every row of the tabular. The command
can be used before a tabu environment or inside it, at the end of a row.
The optional parameter [first line] tells the first row from which background colors are starting
this optional parameter has no effect when \taburowcolors is used at the end of a row:
background are starting immediately in this case.
hnumberi is the number of colors in the color series. If not specified, it defaults to 2 (for alternate
rows color).
Finally hfirsti and hlasti are the first and the last colors in the colorseries.
Example:
\ t a b u r o w c o l o r s [ 2 ] 3{ Crimson ! 3 0 . .
ForestGreen !40} This is just a test
\ t a b u r u l e c o l o r | GreenYellow |{ OrangeRed }
\ a r r a y r u l e w i d t h =1pt \ d o u b l e r u l e s e p =1.5 pt and i think it will
\ everyrow {\ h l i n e \ h l i n e } look rather bad
\ b e g i n { tabu } {X [ - 1 ] X}
This i s &just a t e s t \\ for ive not
and i t h i n k &it w i l l \\
chosen the colors
look & r a t h e r bad \\
for &i ' ve not \\ with care. i cant
chosen &the c o l o r s \\
with c a r e . &i can ' t \\ say less...
say &less . . . \\ 1 This is Crimson
\ t a b u r o w c o l o r s 2{ Crimson . . F o r e s t G r e e n }
1 &This i s Crimson \\ 2 This is ForestGreen
2 &This i s F o r e s t G r e e n \\ 3 This is Crimson
3 &This i s Crimson \\
4 &This i s F o r e s t G r e e n \\ 4 This is ForestGreen
\ end { tabu }
\tabureset
To go back to standard parameters, b provides the command \tabureset which basically
U
does:
\tabulinesep = 0pt \extrarowsep = 0pt \extratabsurround = 0pt
\tabulinestyle {} \everyrow {} \taburulecolor ||{}
\taburowcolors {}
r = right R
j = justify J
Any other value for the optional halignmenti parameter is silently ignored. If ragged2e is not
loaded, L R C and J are synonymous with the lowercase equivalent.
\begin{tabu}{|X|X[-1]|} \tabucline-
\rowfont[c]\bfseries
This &Is \\\tabucline[on 2pt,blue]-
U
\xpackage{tabu} &package \\\tabucline[off 2pt blue]-
b
18 / 101
b Flexible LATEX tabulars
U \rowfont[r]\itshape
for &\textt{tabu} and \textt{longtabu} \\\tabucline-
\end{tabu}
This Is
tabu package
for tabu and longtabu
\usetabu {huser-namei}
\usetabu is the complement of \savetabu: it can be put alone in the tabu preamble instead of
the usual columns specifications to restore any previous settings saved with \savetabu.
The huser-namei must exist otherwise, you get an error.
\usetabu is a help to make several tabulars of exactly the same shape, same target,
same preamble. The only parameter that can be changed is the optional vertical position
parameter for the whole tabular.
\usetabu does not work with longtabu .
\usetabu locally restores:
the preamble7 .
the vertical position [c], [b] or [t], unless another position is specified.
the target width of the tabu in points: the saved target width does not contain any
control sequence: it is fixed and stored in points.
the width of tabu X columns: those widths are not calculated any more even in the
case of negativ coefficients and X columns are directly transformed into p, m or b
columns of the same widths as the ones that where calculated at the time of \savetabu
\tabcolsep (or \arraycolsep in math mode) \extrarowheight, \extrarowdepth,
\arraystretch and \extratabsurround
\arrayrulewidth, \doublerulesep and the parameters for \everyrow \taburulecolor,
\tabulinestyle, and \taburowcolors
[rev.2.8 release] 2010 2011 FC
Example:
\ t a b c o l s e p =12pt \ e x t r a r o w s e p=1mm
\ t a b u l i n e s t y l e { on 1 pt F o r e s t G r e e n }
U
7. The complete \halign-preamble is restored.
b
19 / 101
b Flexible LATEX tabulars
\ tabureset
\ b e g i n { tabu }{\ u s e t a b u {mytabu }} \ tabucline -
\ multicolumn 3{| c }{ This i s tabu } & package \\ \ t a b u c l i n e -
\ tabuphantomline
\ end { tabu }
\preamble {huser-namei}
\preamble can also be used after \savetabu. This is a variant of \usetabu that locally restores:
the tabu (or longtabu) preamble.
the vertical position [c], [b] or [t] (or [c], [l] or [r] for longtabu), unless another position
is specified.
the tabu / longtabu target width, unless another target is specified.
Any other tabular parameter is not restored.
Put \preamble {huser-namei} alone inside the tabu (or longtabu) preamble in place of the
usual columns specifications.
\preamble works exactly as if you defined a custom environment for tabu.
\preamble works with longtabu .
Example (continued...):
\ t a b u l i n e s t y l e {1 pt o f f 1 pt }
\ b e g i n { tabu } t o \ l i n e w i d t h {\ preamble {mytabu }} \ t a b u c l i n e -
This &is &tabu &package \\ \ t a b u c l i n e -
\ end { tabu }
\tabcolsep, rule colors etc. are not restored from \savetabu: the only tabu preamble is restored.
replace siunitx S and s columns or numprint n and N columns or other packages that provide
alignment such as warpcol, dcolumn or rccol. It just make easy to apply a macro you get already
on each number in a column of a tabu.
\tabudecimal has been developped mainly because it makes possible to align numbers inside
tabu X columns.
U
b
20 / 101
b Flexible LATEX tabulars
U
\tabudecimal {huser-macroi}
\tabudecimal can be used in the preamble of a tabu before a column specification. The
huser-macroi is a macro with one parameter that has to be defined before.
U
b
21 / 101
b Flexible LATEX tabulars
U
reach its target for the whole: the tabular and the delimiter(s). You can see the difference:
This is t a b u with delar- This is t a b u with de-
e)
s ray shortcuts for paren- larray shortcuts for curly
xe wid
o
hb o thesis around. brackets around.
ll t tw
fu
er .8p rx
ov 17 bula
th d ta
wi t an or
f
This is tabularx with de-
p This is tabularx with de-
.5
17
(
larray shortcuts for paren-
larray shortcuts for curly
thesis around. brackets around.
U
b
22 / 101
b Flexible LATEX tabulars
The process of rewriting columns is usually longer inside tabu than inside tabular, but conversely
tabu with X columns is optimised compared to tabularx, because the preamble is built only once,
and not rebuilt before each trial as tabularx does. Thus tabu is much quicker than tabularx.
The process of rewriting is very sensitiv to the order in which columns are actually rewritten.
[rev.2.8 release] 2010 2011 FC
This becomes critical when columns are defined with an optional argument like tabu X and |
columns or siunitx S column.
U
b
23 / 101
b Flexible LATEX tabulars
U
8 The package options
8.1 The debugshow package option
\tracingtabu
\tracingtabu = 1, 2, 3 or 4
The control sequence \tracingtabu has the same effect as the debugshow option:
b will report the widths it computes at each attempt to read the target, when X
U
columns are used.
Saved informations on the tabu are reported in the .log file when \savetabu is used.
\tracingtabu = 2 gives more information on the measures of the natural widths.
\tracingtabu = 3 shows the struts inserted inside the tabu environment and gives more
information about the measures of the height and depth of every row.
\tracingtabu = 4 displays information on the insertions made by \tabucline.
Typical information in the .log file:
(tabu) Try tabu X tabu Width Target Coefs Update
(tabu) 1) 386.67296pt 797.34592pt 386.67296pt 2.0pt -205.33649pt
(tabu) 2) 181.33647pt 386.67294pt 386.67296pt 2.0pt 0.00002pt
(tabu) 2) Target reached (hfuzz=0.1pt) ****************
What does it mean?
1) The first attempt was performed with X=386.67296pt
The tabu width (797.34592pt) exceeded the target by 410.67296pt.
Thus X has been updated: 410.67296pt /2 = 205.33649pt and then:
X = 386.67296pt 205.33649pt = 181.33647pt
2) The second attempt lead to a tabu width of 386.67294pt: the target is reached.
The final width of each X column is the product of tabu X by its width coefficient.
U
b
24 / 101
b Flexible LATEX tabulars
U the array:
\begin {tabu} \{{X}. \left \{\begin {tabu}{X}
... ...
is like:
\end {tabu} \end {tabu} \right .
U
b
25 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
11 Technical notice and Implementation
11.1 Drawing a tabular - The b approach
U
b has a different approach than almost any other package providing facilities for tabulars. colortbl and
U
arydshln both put the cells contents into a box for measuring purpose, and then use the dimensions of each
box to make their setups:
colortbl needs the dimensions of the box to put a rule in the background of the cell,
arydshln needs the dimensions to set the length of its leaders (dash lines).
This is achieved by modifying the macros defined in array.sty to insert columns inside the \halign preamble.
Instead, b proceeds as follow:
U
1. It first measures (if there are some negative width coefficients, or if tabu spread is used) the natural
widths of the cells / the columns,
2. Then it always measures the height and depth of each cell / row,
3. Thereafter, the tabular is printed exactly as if array.sty was entitle to print it: no extra boxing of
the cells material. The measurements have been stored and can be used to set the struts (only one per
row) and the lengths of vertical leaders.
4. No macros of array.sty is modified at stage 3.
b material inserted in the tabular for vertical leaders, \rowfont etc. is put inside the special free
U
11.2 Algorithms
tabu to target
The algorithm of \tabu@arith computes the desired widths to reach the target. In any case, only one
measure of the tabular is required to get the widths for all columns. Here we describe the method with an
example and some equations too to show that this handle all cases in generality.
Notations and initialisation of X In the case of tabu to the target T = 300 is given : it is the target
specified by the user or the default tabu target which is \linewidth hparindent correctioni or \linegoal.
Each X column has a width coefficient which is given too (or default to 1). The coefficients are: c1 , c2 , . . . cn .
X is the main dimension that drives the widths of all columns with a non negative coefficient, and limit the
widths of columns with a negative coefficient.
Then we have first:
Coef ci
P
c1 c2 c3 c4 c5 c6
1 2 5 2 2 3 15
Target T 300
Some coefficients are negative and we have to measure the natural widths of the corresponding columns, for
[rev.2.8 release] 2010 2011 FC
if ci > 0
(
ci X
i =
Min (|ci | X, i ) if ci < 0 with i T i
i is the natural width of the column in the sense that it is the maximum of the natural widths of each
cell in the ith X column, limited to the tabu target: i T i.
U
b
26 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
The whole width of the tabular is always:
\tabcolsep
wd(table) = i + incompressible material vertical lines/leaders thickness
X
i non X columns
then: i i = i ci X T at the first trial. But this is not the same if some coefficients are negative,
P P
because in this case the column width i can shrink until its natural width i and may be until to 0pt !
And then if every column has a negative coefficient, one of them can have a width close to the target T . We
have to ensure that the first measure of the natural widths does not limit them artificially:
i ci < 0 = |ci | X T
ci > 0 = ci X T
P
i
ci >0
T T
And finally, for the measure: X = Max Max ; P
i |ci | ci
ci <0 i
ci >0
Coef ci
P
c1 c2 c3 c4 c5 c6
1 2 5 2 2 3 15
Target T 300
X 300
i 10 300 80 80
i 10 300 80 80 600 900 1970 1800
First step of the algorithm: reducing the width After having measured the table we get: wd(table) = 2100.
The incompressible material is 21001970 = 130 wide and the gap to the target is = 2100300 = 1800.
We now choose a new value for X:
i = Min (i ; ci X) +
X X X X
ci X |ci | X
i
i i ci <0 i i
ci >0
i
P
i
Lets try X0 = so that i |ci | X 0 i :
P 0 P P
|ci |
P
i i i
i
Coef ci
P
c1 c2 c3 c4 c5 c6
[rev.2.8 release] 2010 2011 FC
1 2 5 2 2 3 15
Target T 300
X 300
i 10 300 80 80
i 10 300 80 80 600 900 1970 1800
X0 11.33
1970 1800 170
X0 = = = 11.33 Note that the computation of X 0 does not involve any measurement.
U 15 15
b
27 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
Coef ci
P
c1 c2 c3 c4 c5 c6
1 2 5 2 2 3 15
Target T 300
X 300
i 10 300 80 80
i 10 300 80 80 600 900 1970 1800
X0 11.33
0i 10, 00 22, 67 56, 67 22, 67 22, 67 34, 00 168, 67 1.33
Here we are in the case where the table width:
= i + incompressible material i + I = T
P 0 P
i i
Without any measure, we can say that the final table width will be less than the target, if we choose
X 0 . The free space to share among the X columns (computed with X 0 ) is now 0 = T ( i 0i + I) =
P
Giving space We say that a column is saturated (ie.full) if its natural width is greater than |ci | X, or all
the same that i < i . We also will consider that the columns with ci > 0 have a natural width which is
always equal to ci X: in other words, a column with a non negative coefficient is always saturated.
Giving space (or refunding space) to the columns must be done in priority to the saturated columns. If all
columns are finally underfull, then we will distribute the extra space to each, according a distribution rule.
But this case can only occur if i ci < 0 because we first choosed X so that:
T
X P
ci
i
ci >0
and hence, the sum of the widths of the non negative columns exceeds the target.
Lets rank the columns widths:
01 1
Because of the saturation, the total amount of space to give: || shall be shared among the columns
according to their widths coefficients. We shall not give too much space: the columns shall remain saturated.
Let 0 < ||0 the amount of space to give, then after the operation:
1 + 2 + 3 = 01 + 02 + 03 +
= |c1 | X 0 + |c2 | X 0 + |c3 | X 0 +
[rev.2.8 release] 2010 2011 FC
||0
Lets say X = X 0 + then its possible, without any measure, to compute:
|ci |
P
i
ci saturated
i + 4 |ci | X + 4 |ci | X 0 + 0 = 0i + 0 T I
X X X X
i i i i
ci saturated ci saturated
U
b
28 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
Or for clarity: i + I = wd(table) T and the new free space to share is now :
P
i
!
= T i + I
X
i
At each step of the computation, and without any measure but the first, X grows, decreases, and finally
the target is reached for X such that hfuzz.
Coef ci
P
c1 c2 c3 c4 c5 c6
1 2 5 2 2 3 15
Target T 300
X 300
i 10 300 80 80
i 10 300 80 80 600 900 1970 1800
X0 11.33
0i 10, 00 22, 67 56, 67 22, 67 22, 67 34, 00 168, 67 1.33
X 11.43
i 10, 00 22, 86 57, 14 22, 86 22, 86 34, 29 170, 00 0
Now if the width of the table is less that the target, because 1) every column has a negative coefficient and
2) their natural widths are so small than the tabular dont fill the wanted horizontal space, the algorithm
artificially raise the natural widths, according to a linear distribution:
i i
0i = i + P = i + P = i 1 + P
i i i
i i i
i = Min (i ; |ci | X)
X X
i i
is true. Its always possible to find a X such that the behaviour anounced in the documentation is observed !
[rev.2.8 release] 2010 2011 FC
Then lets get some non negative coefficients. The natural widths of such columns must be measured, but
the natural width of the tabular is not the same, for the proportions between column widths expressed by
their positive coefficient ci must be respected.
The real natural width of the tabular, which observe the proportions between columns with a non negative
coefficient is:
i
wd(table) + Max i > wd(table)
X X
ci
i ci i i
ci >0
ci >0 ci >0
U
b
29 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
This quantity is computed, b adds the spread and fix the new target to the sum, in the limit of the
U
default target.
T T
Then X is initialized such that: X = Max Max ; P
i |ci | ci
ci <0 i
ci >0
and the algorithm described in the former section works, without any new measurement of the tabular.
Unless this was not possible or deemed inconvenient for clarity, the code is presented in the same
order it executes.
4 4 4 3
yes
X column ? arithmetic 0
no
3 3 3
\tabu@endrewrite \tabu@select \tabu@strategy
1 (outer in mode 3)
4 4 4
yes 2 (outer in mode 4)
[rev.2.8 release] 2010 2011 FC
X column ? arithmetic
no
1 (outer in mode 3)
1
2 (outer in mode 4)
\tabu@endrewrite \tabu@select \tabu@strategy
U
b
30 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
11.4 Identification and Requirements
b requires array.sty and varwidth.sty. The package namespace is tabu@.
U
1 h*packagei
2 \NeedsTeXFormat{LaTeX2e}[2005/12/01]
3 \ProvidesPackage{tabu}[2011/02/26 v2.8 - flexible LaTeX tabulars (FC)]
4 \RequirePackage{array}[2008/09/09]
5 \RequirePackage{varwidth}[2009/03/30]
U
6 \AtEndOfPackage{\tabu@AtEnd \let\tabu@AtEnd \@undefined}
7 \let\tabu@AtEnd\@empty
8 \def\TMP@EnsureCode#1={%
9 \edef\tabu@AtEnd{\tabu@AtEnd
10 \catcode#1 \the\catcode#1}%
11 \catcode#1=%
12 }% \TMP@EnsureCode
13 \TMP@EnsureCode 33 = 12 % !
14 \TMP@EnsureCode 58 = 12 % : (for siunitx)
15 \TMP@EnsureCode124 = 12 % |
16 \TMP@EnsureCode 36 = 3 % $ = math shift
17 \TMP@EnsureCode 38 = 4 % & = tab alignmment character
18 \TMP@EnsureCode 32 = 10 % space
19 \TMP@EnsureCode 94 = 7 % ^
20 \TMP@EnsureCode 95 = 8 % _
b
loads tabu setup and prepares \tabu@cleanup and \tabu@reset
U
if \tabu@target > 0 then prepare
\tabu@begin
@{\extracolsep {\@flushglue }}
\@arrayleft
\vtop or \vbox or \vcenter \bgroup... \halign { preamble...
[rev.2.8 release] 2010 2011 FC
\end {tabu}
if in math mode
end of \halign
\endtabu \endtabular \endarray
end of \vtop, \vbox or \vcenter
end of math group
if in text mode
end of \hbox
31 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
tabu to with X column The important part of the job is made inside the dashed box above: \@mkpream
expands the columns definitions, which can be user defined. Hopefully, it does its job inside a group,
therefore a user-column can set a macro to be expanded \aftergroup. This implementation allows much
modifications in the tabular preparation, without any change in the macros of array.sty.
\begingroup \@mkpream
Finds a X column
Parse the optional parameter for X
rewrite X column Set \aftergroup \tabu@prep@TRIAL
... \@mkpream ... builds the \halign preamble
\xdef \@preamble
triggered by Neutralisation of \write
\endgroup
\aftergroup
Protection for: footnotes
\tabu@prep@TRIAL \tabu@setup@TRIAL
counters
index
prepares \tabu@Xfinish
\tabu@arrayleft@measure
Collect the tabu body
\tabu@endTRIAL \endarray
Updates
No
\tabucolX \tabu@arith Yes
\tabu@Xfinish
\wd {tabu}\tabu@target < \hfuzz?
U
And the next trial will be done as if the user called tabu to with this target.
b
32 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
11.6 Some constants
Here we define the constants used by b : TEX registers and a few helper macros.
U
When working inside a tabular (ie.\halign) each cell is a TEX group. Probably the most important
property of each register defined here is whether it is global or not. A local register does not suffer, never,
any global assignment.
TEX registers
taburow LATEX counter that globally stores the value of the current row. It is updated at \everyrow, rather than at
\everycr8 . \thetaburow expands to the (arabic) number.
This counter can be read by the user, but she must not change its value because it is used internally to
store the height/depth of every row, for vertical spacing adjustment (and vertical leaders).
\tabu@nbcols TEX counter that locally saves the total number of columns of the tabu. Special @ and ! columns
are not counted (they are not real columns for \halign, but only insertions into the preamble).
The value is used by \tabucline to ensure that the leader does not jut out over the last column...
\tabu@cnt TEX counter that locally stores the number of trials. Incidentally, it is also temporarily used to parse
the width coefficient for X columns, during the rewriting process.
\tabu@Xcol TEX counter that locally stores the number of tabu X columns. Defined while rewriting the X token, it
is used in the specification of the width of the column (\tabu@hsize {Rank of the X column}{coef}).
It is also used to store the natural width of X columns (in the cases of a negativ coefficient or if tabu
spread is used).
\tabu@alloc A global counter whose initial value (1) is incremented for each nested tabular. The end of the outermost
\tabu@nested tabular globally resets the value to 1. \tabu@nested stores locally the value of \tabu@alloc and is
therefore the index of the current tabular (the one that is actually in construction).
This influences the initialisation process (cf. \tabu@setup and \tabu@init).
\tabu@start They are used locally by \tabucline and \everyrow while parsing the parameters: this is, for clarity,
\tabu@stop the local name for \@tempcnta and \@tempcntb.
21 \newcount \c@taburow \def\thetaburow {\number\c@taburow}
22 \newcount \tabu@nbcols
23 \newcount \tabu@cnt
24 \newcount \tabu@Xcol
25 \let\tabu@start \@tempcnta
26 \let\tabu@stop \@tempcntb
27 \newcount \tabu@alloc \tabu@alloc=\m@ne
28 \newcount \tabu@nested
29 \def\tabu@alloc@{\global\advance\tabu@alloc \@ne \tabu@nested\tabu@alloc}
\tabu@target TEX dimen that locally stores the tabu target (either to or spread).
\tabu@spreadtarget TEX dimen that locally stores the tabu spread given by the user.
\tabu@naturalX TEX dimen that globally stores the total natural widths of the X columns, in the cases of negativ
coefficients and/or tabu spread. The value is reset to 0pt at \everyrow, and maxima/minima are stored
into the macro \tabu@naturalXmin and \tabu@naturalXmax: those are required for the algorithm of
tabu spread (\tabu@spreadarith).
[rev.2.8 release] 2010 2011 FC
\tabucolX TEX dimen that locally stores the width corresponding to the preamble token X[1]: the standard width
of X columns.
\tabu@DELTA This is for clarity, the local name of \@tempdimc in \tabu@arith.
\tabu@thick They are used locally by \tabu@getline, while parsing the parameters for a line specification. This is for
\tabu@on clarity, the local name for \@tempdima, \@tempdimb and \@tempdimc.
\tabu@off
8. Package xcolor defines the \rownum TEX counter, which is globally updated at \everycr. Hence this \rownum counter is
U
not reliable in case the user invokes \cline or \cmidrule for example...
b
33 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
30 \newdimen \tabu@target
31 \newdimen \tabu@spreadtarget
32 \newdimen \tabu@naturalX
33 \newdimen \tabucolX
34 \let\tabu@DELTA \@tempdimc
35 \let\tabu@thick \@tempdima
36 \let\tabu@on \@tempdimb
37 \let\tabu@off \@tempdimc
\tabu@Xsum TEX dimen that locally stores the sum of all width coefficients for X columns. This is required to fix the
initial value for \tabucolX and then in the algorithms (\tabu@arith and \tabu@arithnegcoef).
38 \newdimen \tabu@Xsum
\extrarowdepth array.sty defines \extrarowheight as a TEX dimen register: the extra height to be finally added to each
row of a table. b defines \extrarowdepth in addition: the extra depth. Though \extrarowheight and
U
\tabustrutrule The TEX dimen \tabustrutrule is here only for debugging purpose: its value must be 0pt. It behaves
mostly like TEX primitive \overfullrule, and allow to see the struts introduced in the tabular, and to
control vertical spacing. Setting \tabustrutrule to a positive value has no effect unless \tracingtabu is
3. The official interface is \tracingtabu = 3.
39 \newdimen \extrarowdepth
40 \newdimen \abovetabulinesep
41 \newdimen \belowtabulinesep
42 \newdimen \tabustrutrule \tabustrutrule \z@
\tabu@thebody This token stores locally the collected content of the tabu environment during the measuring process.
\tabu@footnotes Token that globally stores the footnotes inside the tabu environment, for \insert does not work inside such
a level of groupings...
43 \newtoks \tabu@thebody
44 \newtoks \tabu@footnotes
\tabu@box Stores loally the whole tabu when an attempt to adjust X columns is performed.
\tabu@arstrutbox While the \@arstrutbox may redefined globally at the end of each line (for vertical spacing adjustment),
we define a new box and \let \@arstrutbox to be that box inside the tabu environment.
Hence, the \@arstrutbox used by other tabular environment does not suffer any modification.
\tabu@hleads Those boxes are used to built horizontal and vertical leaders. In order not to rebuilt the boxes every time a
\tabu@vleads leader is inserted, the box is globally defined if a line style is specified (via |[line style] or \tabucline [line
style]{...} or \tabulinestyle {line style}.
[rev.2.8 release] 2010 2011 FC
45 \newsavebox \tabu@box
46 \newsavebox \tabu@arstrutbox
47 \newsavebox \tabu@hleads
48 \newsavebox \tabu@vleads
U
b
34 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
Switches
\iftabu@colortbl The global switch \iftabu@colortbl is used by \rowfont when modifying the alignments, because colortbl
changes the glues put inside the \halign preamble to make standard alignments. This switch is set At
Begin Document.
\iftabu@siunitx Global switch set \AtBeginDocument. true if siunitx package is detected.
\iftabu@measuring This switch is somewhat magic in the sense that it has several meanings... It is temporarily set to true by
\tabu@arith in the trial group, to say that the tabu did not reach its target yet. It is also set to true in
the \@mkpream group when the first X column is encountered in the preamble. Finally, it is true in the
trialS group when the outermost tabular is in strategy number 2 or number 3.
\iftabu@spread A switch whether tabu spread is used or not. A nested tabu inside a X column whose coefficient is
negative has a default target set to spread 0pt.
\iftabu@negcoef A switch set to true in case of negativ coef (natural width if less than X[coef]).
\iftabu@everyrow A very important global switch: true when outside any tabu environment, true as well when inside a cell of
a tabu, but globally set to false at \everycr and therefore inside any \noalign command. This allows to
insert leaders (by \omit \span \omit \cr \noalign {...}) or first/last line corrections only once, even if
\everycr is executed more than once.
\iftabu@long Finally the swith \iftabu@long is set to true inside longtabu and to false inside tabu. This is convenient
because some setup are slightly different between tabu and longtabu.
49 \newif \iftabu@colortbl
50 \newif \iftabu@siunitx
51 \newif \iftabu@measuring
52 \newif \iftabu@spread
53 \newif \iftabu@negcoef
54 \newif \iftabu@everyrow
55 \def\tabu@everyrowtrue {\global\let\iftabu@everyrow \iftrue}
56 \def\tabu@everyrowfalse{\global\let\iftabu@everyrow \iffalse}
57 \newif \iftabu@long
\iftabuscantokens \iftabuscantokens is the switch for whether or not tabu will use \scantokens. Though the user can set
\tabu@rescan \iftabuscantokens to \iftrue or \iffalse, the official interface is tabu .
It does not make sense to use \scantokens in a nested tabu: only the outermost tabu can use \scantokens,
for the environment body must be collected with care !
\tabu@rescan is the helper macro for scanning tokens.
58 \newif \iftabuscantokens
59 \def\tabu@rescan {\tabu@verbatim \scantokens }
60 \def\tabu@gobblespace #1 {#1}
61 \def\tabu@gobbletoken #1#2{#1}
62 \def\tabu@gobbleX{\futurelet\@let@token \tabu@gobblex}
63 \def\tabu@gobblex{\if ^^J\noexpand\@let@token \expandafter\@gobble
64 \else\ifx \@sptoken\@let@token
65 \expandafter\tabu@gobblespace\expandafter\tabu@gobbleX
66 \fi\fi
67 }% \tabu@gobblex
68 \def\tabu@X{^^J}
U
b
35 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
69 {\obeyspaces
70 \global\let\tabu@spxiii= % saves an active space (for \ifx)
71 \gdef\tabu@@spxiii{ }}
72 \def\tabu@ifenvir {% only for \multicolumn
73 \expandafter\tabu@if@nvir\csname\@currenvir\endcsname
74 }% \tabu@ifenvir
75 \def\tabu@if@nvir #1{\csname @\ifx\tabu#1first\else
76 \ifx\longtabu#1first\else
77 second\fi\fi oftwo\endcsname
78 }% \tabu@ifenvir
79 \def\tabu@modulo #1#2{\numexpr\ifnum\numexpr#1=\z@ 0\else #1-(#1-(#2-1)/2)/(#2)*(#2)\fi}
\tabu@textbar The character | may have a special category code inside the document, depending on the language setting
or for example, | can be the delimiter shortcut for verbatim. We use \scantokens to allow an \ifx test
even if the category code of | changes along the compilation.
100 \def\tabu@textbar #1{\begingroup \endlinechar\m@ne \scantokens{\def\:{|}}%
101 \expandafter\endgroup \expandafter#1\:% !!! semi simple group !!!
102 }% \tabu@textbar
\tabu@everyrow@bgroup Commands like \everyrow, \taburulecolor, \tabulinestyle, \taburowcolors can be expanded either
in a cell or outside a tabu environment or at the end of a row, inside a \noalign group.
\tabu@everyrow@egroup
To avoid the insertion of an empty math atom (equivalent to \hbox to0pt{}) we open a semi-simple group
rather than a math group if not in \noalign. \toks@ is used to define the local-to-the-TEX-group setting
(post-fixed by @L).
[rev.2.8 release] 2010 2011 FC
U
b
36 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
Rebuild the \@arstrutbox
\tabu@arstrut The macros rebuilds the \@arstrutbox (a \hbox). With the debug variants when \tracingtabu = 3 and
\tabu@rearstrut \tabustrutrule > 0.
109 \def\tabu@arstrut {\global\setbox\@arstrutbox \hbox{\vrule
110 height \arraystretch \dimexpr\ht\strutbox+\extrarowheight
111 depth \arraystretch \dimexpr\dp\strutbox+\extrarowdepth
112 width \z@}%
113 }% \tabu@arstrut
114 \def\tabu@rearstrut {%
115 \@tempdima \arraystretch\dimexpr\ht\strutbox+\extrarowheight \relax
116 \@tempdimb \arraystretch\dimexpr\dp\strutbox+\extrarowdepth \relax
117 \ifodd 1\ifdim \ht\@arstrutbox=\@tempdima
118 \ifdim \dp\@arstrutbox=\@tempdimb 0 \fi\fi
119 \tabu@mkarstrut
120 \fi
121 }% \tabu@rearstrut
\tabu@DBG@arstrut This is the debug version of \tabu@arstrut: used when \tracingtabu = 3 or more to show the struts
inserted in the tabular.
122 \def\tabu@@DBG #1{\ifdim\tabustrutrule>\z@ \color{#1}\fi}
123 \def\tabu@DBG@arstrut {\global\setbox\@arstrutbox
124 \hbox to\z@{\hbox to\z@{\hss
125 {\tabu@DBG{cyan}\vrule
126 height \arraystretch \dimexpr\ht\strutbox+\extrarowheight
127 depth \z@
128 width \tabustrutrule}\kern-\tabustrutrule
129 {\tabu@DBG{pink}\vrule
130 height \z@
131 depth \arraystretch \dimexpr\dp\strutbox+\extrarowdepth
132 width \tabustrutrule}}}%
133 }% \tabu@DBG@arstrut
\tabu@save@decl No inversion on tokens in the tabu preamble, when not in math mode.
134 \def\tabu@save@decl{\toks\count@ \expandafter{\the\toks\expandafter\count@
135 \@nextchar}}%
136 \def\tabu@savedecl{\ifcat$\d@llarend\else
137 \let\save@decl \tabu@save@decl \fi % no inversion of tokens in text mode
138 }% \tabu@savedecl
\tabu@finalstrut
\tabu@nowrite A trick (from the TEX-book) to forbidd \write when a trial is done on the \halign.
\tabu@noxfootnotes Disable footnotes during trials.
142 \def\tabu@nowrite #1#{{\afterassignment}\toks@}
143 \let\tabu@write\write
144 \let\tabu@immediate\immediate
145 \def\tabu@WRITE{\begingroup
U
146 \def\immediate\write{\aftergroup\endgroup
b
37 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
147 \tabu@immediate\tabu@write}%
148 }% \tabu@WRITE
149 \expandafter\def\expandafter\tabu@GenericError\expandafter{%
150 \expandafter\tabu@WRITE\GenericError}
151 \def\tabu@warn{\tabu@WRITE\PackageWarning{tabu}}
152 \def\tabu@noxfootnote [#1]{\@gobble}
\tabu@nocolor For optimisation purpose, color changes are deactivated during trials, for they do not affect the measures.
\tabu@norowcolor 153 \def\tabu@nocolor #1#{\@gobble}
154 \newcommand*\tabu@norowcolor[2][]{}
U
189 \def\tabu@n@Gextra{\ifx \tabu@G@extra\@empty \else \noalign{\tabu@Rextra}\fi}
b
38 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
190 \def\tabu@Rextra{\tabu@Grestore \tabu@G@extra \tabu@C@extra}
191 \let\tabu@C@extra \z@
192 \let\tabu@G@extra \@empty
\tabulinesep \tabulinesep makes the assignment for both \abovetabulinesep and \belowtabulinesep.
The macro may be prefixed by \global.
193 \newcommand*\tabulinesep{\edef\tabu@C@linesep{\the\numexpr\tabu@C@linesep+1}%
194 \iftabu@everyrow \aftergroup\tabu@Glinesep
195 \else \aftergroup\tabu@n@Glinesep
196 \fi
197 \@ifnextchar={\tabu@gobbletoken\tabu@linesep} \tabu@linesep
198 }% \tabulinesep
199 \def\tabu@linesep {\@ifnextchar_%
200 {\tabu@gobbletoken{\tabu@setsep\abovetabulinesep \belowtabulinesep}}
201 {\ifx ^\@let@token \def\tabu@temp{%
202 \tabu@gobbletoken{\tabu@setsep\belowtabulinesep \abovetabulinesep}}%
203 \else \let\tabu@temp \@empty
204 \afterassignment \tabu@setlinesep \abovetabulinesep
205 \fi \tabu@temp}%
206 }% \tabu@linesep
207 \def\tabu@setsep #1#2{\def\tabu@temp{\tabu@sets@p#1#2}\afterassignment\tabu@temp#2}
208 \def\tabu@sets@p #1#2{\@ifnextchar^%
209 {\tabu@gobbletoken{\tabu@setsep\belowtabulinesep \abovetabulinesep}}
210 {\ifx _\@let@token \def\tabu@temp{%
211 \tabu@gobbletoken{\tabu@setsep\abovetabulinesep \belowtabulinesep}}%
212 \else \let\tabu@temp \@empty
213 \tabu@Gsave \tabu@G@linesep \tabu@C@linesep \abovetabulinesep \belowtabulinesep
214 \fi \tabu@temp}%
215 }% \tabu@sets@p
216 \def\tabu@setlinesep {\belowtabulinesep=\abovetabulinesep
217 \tabu@Gsave \tabu@G@linesep \tabu@C@linesep \abovetabulinesep \belowtabulinesep
218 }% \tabu@setlinesep
219 \def\tabu@Glinesep{\ifx \tabu@G@linesep\@empty \else {\tabu@Rlinesep}\fi}
220 \def\tabu@n@Glinesep{\ifx \tabu@G@linesep\@empty \else \noalign{\tabu@Rlinesep}\fi}
221 \def\tabu@Rlinesep{\tabu@Grestore \tabu@G@linesep \tabu@C@linesep}
222 \let\tabu@C@linesep \z@
223 \let\tabu@G@linesep \@empty
233 }% \tabu@Grestore
U
b
39 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
Setting code for every row
\everyrow As long as tabu needs to execute some code at \everycr, its not difficult to provide a command to give the
user the opportunity to execute its own arbitrary code. However, \everyrow will be used almost only with
\hline (or \tabucline or \midrule).
\everyrow can be changed anywhere inside the tabu: at the end of a row, or even inside a cell.
The rows LATEX counter taburow must not be changed by the user!.
The settings are saved in a locally-global way...
234 \newcommand*\everyrow{\tabu@everyrow@bgroup
235 \tabu@start \z@ \tabu@stop \z@ \tabu@evrstartstop
236 }% \everyrow
237 \def\tabu@evrstartstop {\@ifnextchar^%
238 {\afterassignment \tabu@evrstartstop \tabu@stop=}%
239 {\ifx ^\@let@token
240 \afterassignment\tabu@evrstartstop \tabu@start=%
241 \else \afterassignment\tabu@everyr@w \toks@
242 \fi}%
243 }% \tabu@evrstartstop
244 \def\tabu@everyr@w {%
245 \xdef\tabu@everyrow{%
246 \noexpand\tabu@everyrowfalse
247 \let\noalign \relax
248 \noexpand\tabu@rowfontreset
249 \iftabu@colortbl \noexpand\tabu@rc@ \fi % \taburowcolors
250 \let\noexpand\tabu@docline \noexpand\tabu@docline@evr
251 \the\toks@
252 \noexpand\tabu@evrh@@k
253 \noexpand\tabu@rearstrut
254 \global\advance\c@taburow \@ne}%
255 \iftabu@everyrow \toks@\expandafter
256 {\expandafter\def\expandafter\tabu@evr@L\expandafter{\the\toks@}\ignorespaces}%
257 \else \xdef\tabu@evr@G{\the\toks@}%
258 \fi
259 \tabu@everyrow@egroup
260 }% \tabu@everyr@w
261 \def\tabu@evr {\def\tabu@evrh@@k} % for internal use only
262 \tabu@evr{}
40 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
273 \iftabu@everyrow
274 \toks@\expandafter{\expandafter \def \expandafter
275 \tabu@ls@L\expandafter{\tabu@thestyle}\ignorespaces}%
276 \gdef\tabu@ls@{\tabu@ls@L}%
277 \else
278 \global\let\tabu@ls@G \tabu@thestyle
279 \gdef\tabu@ls@{\tabu@ls@G}%
280 \fi
281 \tabu@everyrow@egroup
282 }% \tabulinestyle
\taburulecolor colortbl provides \arrayrulecolor, but the definition is global and must be restores manually after the table.
\taburulecolor works with the same scheme as \everyrow: even if the definition of the rules colors must
be global (because we it can be changed inside the tabular) the value is not restored globally at the end of
the environment.
Instead, \tabu@arc@L stores locally the color definition (ie.its definition is relative to the group level
before the entry inside the tabu environment).
This is the same for \doublerulesepcolor (which may be given as an optional argument to \taburulecolor):
colortbl makes the definition global, while b keeps grouping level into mind (locally-global settings).
U
283 \newcommand*\taburulecolor{\tabu@everyrow@bgroup \tabu@textbar \tabu@rulecolor}
284 \def\tabu@rulecolor #1{\toks@{}%
285 \def\tabu@temp #1##1#1{\tabu@ruledrsc{##1}}\@ifnextchar #1%
286 \tabu@temp
287 \tabu@rulearc
288 }% \tabu@rulecolor
289 \def\tabu@ruledrsc #1{\edef\tabu@temp{#1}\tabu@strtrim\tabu@temp
290 \ifx \tabu@temp\@empty \def\tabu@temp{\tabu@rule@drsc@ {}{}}%
291 \else \edef\tabu@temp{\noexpand\tabu@rule@drsc@ {}{\tabu@temp}}%
292 \fi
293 \tabu@temp
294 }% \tabu@ruledrsc@
295 \def\tabu@ruledrsc@ #1#{\tabu@rule@drsc@ {#1}}
296 \def\tabu@rule@drsc@ #1#2{%
297 \iftabu@everyrow
298 \ifx \\#1#2\\\toks@{\let\CT@drsc@ \relax}%
299 \else \toks@{\def\CT@drsc@{\color #1{#2}}}%
300 \fi
301 \else
302 \ifx \\#1#2\\\global\let\CT@drsc@ \relax
303 \else \gdef\CT@drsc@{\color #1{#2}}%
304 \fi
305 \fi
306 \tabu@rulearc
307 }% \tabu@rule@drsc@
308 \def\tabu@rulearc #1#{\tabu@rule@arc@ {#1}}
309 \def\tabu@rule@arc@ #1#2{%
310 \iftabu@everyrow
311 \ifx \\#1#2\\\toks@\expandafter{\the\toks@ \def\CT@arc@{}}%
[rev.2.8 release] 2010 2011 FC
41 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
321 \fi
322 \global\let\tabu@arc@G \CT@arc@
323 \global\let\tabu@drsc@G \CT@drsc@
324 \fi
325 \tabu@everyrow@egroup
326 }% \tabu@rule@arc@
365 \expandafter\resetcolorseries\expandafter[\the\count@]{tabu@rcseries@\the\tabu@nested}%
366 \xglobal\colorlet{tabu@rc@\the\tabu@nested}{tabu@rcseries@\the\tabu@nested!!+}%
367 \let\noalign \relax \rowcolor{tabu@rc@\the\tabu@nested}%
368 \def\tabu@rc@ ##1##2{\gdef\tabu@rc@{%
369 \ifnum \tabu@modulo {\c@taburow-##2}{##1+1}=\@ne
370 \resetcolorseries[{##1}]{tabu@rcseries@\the\tabu@nested}\fi
371 \xglobal\colorlet{tabu@rc@\the\tabu@nested}{tabu@rcseries@\the\tabu@nested!!+}%
372 \rowcolor{tabu@rc@\the\tabu@nested}}%
373 }\edef\x{\noexpand\tabu@rc@{\the\count@}{\the\c@taburow}}\x
U
b
42 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
374 \global\let\tabu@rc@G \tabu@rc@
375 \fi
376 \fi
377 \tabu@everyrow@egroup
378 }% \tabu@rowcolorseries
379 \tabuDisableCommands {\let\tabu@rc@ \@empty }
380 \def\tabu@rowcolorserieserror {\PackageError{tabu}
381 {Invalid syntax for \string\taburowcolors
382 \MessageBreak Please look at the documentation!}\@ehd
383 }% \tabu@rowcolorserieserror
\tabureset Simply and locally reset the default values for \tabulinesep (0pt), \extrarowsep (0pt),
\extratabsurround (0pt), \tabulinestyle {}, \everyrow {} and \taburulecolor []{}.
384 \newcommand*\tabureset {%
385 \tabulinesep=\z@ \extrarowsep=\z@ \extratabsurround=\z@
386 \tabulinestyle{}\everyrow{}\taburulecolor||{}\taburowcolors{}%
387 }% \tabureset
\tabu@ \tabu@thick =3pt BlanchedAlmond \tabu@ \tabu@on =4pt Crimson \tabu@ \tabu@
Define \tabu@ as an appropriate macro which uses \afterassignment to:
1. Assign the corresponding dimension (thickness, dash length or gap length).
2. Collect the rest until the next \tabu@, trim spaces and check if the color exists.
Limitation: A color name must not contain a sequence that matches on of the patterns:
...onha character of category 12 i... or ...offha character of category 12 i...
But this limitation is not too heavy, I suppose...
U
b
43 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
The result is \tabu@thestyle: a tabu line style to be used to rewrite a | column, for \tabucline.
We use locally the LATEX defined dimen registers \@tempdima, \@tempdimb and \@tempdimc. For
clarity, their names are \tabu@thick, \tabu@on and \tabu@off here...
388 \def\tabu@getline #1{\begingroup
389 \csname \ifcsname if@safe@actives\endcsname % <babel>
390 @safe@activestrue\else
391 relax\fi \endcsname
392 \edef\tabu@temp{#1}\tabu@sanitizearg{#1}\@tempa
393 \let\tabu@thestyle \relax
394 \ifcsname tabu@linestyle@\@tempa \endcsname
395 \edef\tabu@thestyle{\endgroup
396 \def\tabu@thestyle{\expandafter\noexpand
397 \csname tabu@linestyle@\@tempa\endcsname}%
398 }\tabu@thestyle
399 \else \expandafter\tabu@definestyle \tabu@temp \@nil
400 \fi
401 }% \tabu@getline
431 \fi
432 \edef \tabu@thestyle ##1##2{\endgroup
433 \def\tabu@thestyle{%
434 \ifin@ \noexpand\tabu@leadersstyle {\tabu@thick}
435 {\the\tabu@on}{##1}
436 {\the\tabu@off}{##2}%
437 \else \noexpand\tabu@rulesstyle
438 {##1\vrule width \tabu@thick}%
439 {##1\leaders \hrule height \tabu@thick \hfil}%
U
b
44 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
440 \fi}%
441 }\expandafter \expandafter
442 \expandafter \tabu@thestyle \expandafter
443 \expandafter \expandafter
444 {\expandafter\tabu@c@lon\expandafter}\expandafter{\tabu@c@loff}%
445 }% \tabu@definestyle
\tabu@onxiii We have to define the active o character, which looks for the next tokens, trying to find a pattern like
\tabu@ofxiii onhcategory 12 i or offhcategory 12 i (possibly with active spaces between on or off and the next
\tabu@offiii character of catcode 12).
446 {\catcode\O=\active \lccode\O=\o \catcode\,=\active
447 \lowercase{\gdef\tabu@oXIII {\catcode\o=\active \let O=\tabu@oxiii}}
448 \gdef\tabu@commaXIII {\catcode\,=\active \let ,=\space}
449 }% \catcode
450 \def\tabu@oxiii #1{%
451 \ifcase \ifx n#1\z@ \else
452 \ifx f#1\@ne\else
453 \tw@ \fi\fi
454 \expandafter\tabu@onxiii
455 \or \expandafter\tabu@ofxiii
456 \else o%
457 \fi#1}%
458 \def\tabu@onxiii #1#2{%
459 \ifcase \ifx !#2\tw@ \else
460 \ifcat.\noexpand#2\z@ \else
461 \ifx \tabu@spxiii#2\@ne\else
462 \tw@ \fi\fi\fi
463 \tabu@getparam{on}#2\expandafter\@gobble
464 \or \expandafter\tabu@onxiii % (space is active)
465 \else o\expandafter\@firstofone
466 \fi{#1#2}}%
467 \def\tabu@ofxiii #1#2{%
468 \ifx #2f\expandafter\tabu@offxiii
469 \else o\expandafter\@firstofone
470 \fi{#1#2}}
471 \def\tabu@offxiii #1#2{%
472 \ifcase \ifx !#2\tw@ \else
473 \ifcat.\noexpand#2\z@ \else
474 \ifx\tabu@spxiii#2\@ne \else
475 \tw@ \fi\fi\fi
476 \tabu@getparam{off}#2\expandafter\@gobble
477 \or \expandafter\tabu@offxiii % (space is active)
478 \else o\expandafter\@firstofone
479 \fi{#1#2}}
\tabu@getcolor first makes the assignment to \tabu@on and then looks for the color name which might
have been placed before the next \tabu@.
481 \def\tabu@getcolor #1{% \tabu@ <- \tabu@getcolor after \edef
482 \ifx \tabu@#1\else % no more spec
483 \let\tabu@theparam=#1\afterassignment \tabu@getc@l@r #1\fi
484 }% \tabu@getcolor
485 \def\tabu@getc@l@r #1\tabu@ {%
486 \def\tabu@temp{#1}\tabu@strtrim \tabu@temp
U
b
45 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
487 \ifx \tabu@temp\@empty
488 \else%\ifcsname \string\color@\tabu@temp \endcsname % if the color exists
489 \ifx \tabu@theparam \tabu@off \let\tabu@c@loff \tabu@c@l@r
490 \else \let\tabu@c@lon \tabu@c@l@r
491 \fi
492 %\else \tabu@warncolour{\tabu@temp}%
493 \fi%\fi
494 \tabu@ % next spec
495 }% \tabu@getc@l@r
496 \def\tabu@warncolour #1{\PackageWarning{tabu}
497 {Color #1 is not defined. Default color used}%
498 }% \tabu@warncolour
\tabu@leadersstyle When a style is executed, it expands either \tabu@leadersstyle or \tabu@rulesstyle depending on whether
\tabu@rulesstyle or not it contains leaders (dashed lines) or simple rules (solid lines): TEX internals allow to insert solid lines
easily inside a tabular, while inserting leaders is more complex.
\tabu@leadersstyle eventually rebuilds the (horizontal and vertical) leaders boxes, and then define
two macros: \tabu@thevleaders and \tabu@thehleades, suitable to draw vertical and horizontal lines
respectively. Incidentally, \tabu@leaders is defined to be the parameters for the leaders.
\tabu@rulesstyle only defines the two macros \tabu@thevrule and \tabu@thehrule. The control sequence
\tabu@leaders is undefined so that we know if the style contains a leader or a rule.
499 \def\tabu@leadersstyle #1#2#3#4#5{\def\tabu@leaders{{#1}{#2}{#3}{#4}{#5}}%
500 \ifx \tabu@leaders\tabu@leaders@G \else
501 \tabu@LEADERS{#1}{#2}{#3}{#4}{#5}\fi
502 }% \tabu@leadersstyle
503 \def\tabu@rulesstyle #1#2{\let\tabu@leaders \@undefined
504 \gdef\tabu@thevrule{#1}\gdef\tabu@thehrule{#2}%
505 }% \tabu@rulesstyle
\tabu@LEADERS Here the two leaders boxes \tabu@hleads and \tabu@vleads are built, as well as the leaders macros
\tabu@thehleaders and \tabu@thevleaders.
506 \def\tabu@LEADERS #1#2#3#4#5{%% width, dash, dash color, gap, gap color
507 {\let\color \tabu@color % => during trials -> \color = \tabu@nocolor
508 {% % but the leaders boxes should have colors !
509 \def\@therule{\vrule}\def\@thick{height}\def\@length{width}%
510 \def\@box{\hbox}\def\@unbox{\unhbox}\def\@elt{\wd}%
511 \def\@skip{\hskip}\def\@ss{\hss}\def\tabu@leads{\tabu@hleads}%
512 \tabu@l@@d@rs {#1}{#2}{#3}{#4}{#5}%
513 \global\let\tabu@thehleaders \tabu@theleaders
514 }%
515 {%
516 \def\@therule{\hrule}\def\@thick{width}\def\@length{height}%
517 \def\@box{\vbox}\def\@unbox{\unvbox}\def\@elt{\ht}%
518 \def\@skip{\vskip}\def\@ss{\vss}\def\tabu@leads{\tabu@vleads}%
519 \tabu@l@@d@rs {#1}{#2}{#3}{#4}{#5}%
520 \global\let\tabu@thevleaders \tabu@theleaders
521 }%
522 \gdef\tabu@leaders@G{{#1}{#2}{#3}{#4}{#5}}%
[rev.2.8 release] 2010 2011 FC
523 }%
524 }% \tabu@LEADERS
525 \def\tabu@therule #1#2{\@therule \@thick#1\@length\dimexpr#2/2 \@depth\z@}
526 \def\tabu@l@@d@rs #1#2#3#4#5{%% width, dash, dash color, gap, gap color
527 \global\setbox \tabu@leads=\@box{%
528 {#3\tabu@therule{#1}{#2}}%
529 \ifx\\#5\\\@skip#4\else{#5\tabu@therule{#1}{#4*2}}\fi
530 {#3\tabu@therule{#1}{#2}}}%
531 \global\setbox\tabu@leads=\@box to\@elt\tabu@leads{\@ss
U
b
46 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
532 {#3\tabu@therule{#1}{#2}}\@unbox\tabu@leads}%
533 \edef\tabu@theleaders ##1{\def\noexpand\tabu@theleaders {%
534 {##1\tabu@therule{#1}{#2}}%
535 \xleaders \copy\tabu@leads \@ss
536 \tabu@therule{0pt}{-#2}{##1\tabu@therule{#1}{#2}}}%
537 }\tabu@theleaders{#3}%
538 }% \tabu@l@@d@rs
47 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
578 \ifx \tabu@temp\LNGL@setlinegoal
579 \LNGL@setlinegoal \expandafter \@firstoftwo \fi % @gobbles \LNGL@setlinegoal
580 \tabu@begin
581 }% \tabu@linegoalt@rget
582 \def\tabu@begin #1#{%
583 \iftabu@measuring \expandafter\tabu@nestedmeasure \fi
584 \ifdim \tabu@target=\z@ \let\tabu@halignto \@empty
585 \else \edef\tabu@halignto{\tabu@halignto\the\tabu@target}%
586 \fi
587 \@testopt \tabu@tabu@ \tabu@aligndefault #1\@nil
588 }% \tabu@begin
589 \long\def\tabu@tabu@ [#1]#2\@nil #3{\tabu@setup
590 \def\tabu@align {#1}\def\tabu@savedpream{\NC@find #3}%
591 \tabu@ [\tabu@align ]#2{#3\tabu@rewritefirst }%
592 }% \tabu@tabu@
593 \def\tabu@nestedmeasure {%
594 \ifodd 1\iftabu@spread \else \ifdim\tabu@target=\z@ \else 0 \fi\fi\relax
595 \tabu@spreadtrue
596 \else \begingroup \iffalse{\fi \ifnum0=}\fi
597 \toks@{}\def\tabu@stack{b}%
598 \expandafter\tabu@collectbody\expandafter\tabu@quickrule
599 \expandafter\endgroup
600 \fi
601 }% \tabu@nestedmeasure
602 \def\tabu@quickrule {\indent\vrule height\z@ depth\z@ width\tabu@target}
\tabu@setup \tabu@init is expanded only when tabu is not nested. In this case, and if \parindent > 0, and if
\tabu@init \tabudefaulttarget =\linewidth, the correction of the default target for paragraph indentation is executed
\tabu@indent (see paragraph indentation).
603 \def\tabu@setup{\tabu@alloc@
604 \ifcase \tabu@nested
605 \ifmmode \else \iftabu@spread\else \ifdim\tabu@target=\z@
606 \let\tabu@afterendpar \par
607 \fi\fi\fi
608 \def\tabu@aligndefault{c}\tabu@init \tabu@indent
609 \else % <nested tabu>
610 \def\tabu@aligndefault{t}\let\tabudefaulttarget \linewidth
611 \fi
612 \let\tabu@thetarget \tabudefaulttarget \let\tabu@restored \@undefined
613 \edef\tabu@NC@list{\the\NC@list}\NC@list{\NC@do \tabu@rewritefirst}%
614 \everycr{}\let\@startpbox \tabu@startpbox % for nested tabu inside longtabu...
615 \let\@endpbox \tabu@endpbox % idem " " " " " "
616 \let\@tabarray \tabu@tabarray % idem " " " " " "
617 \tabu@setcleanup \tabu@setreset
618 }% \tabu@setup
619 \def\tabu@init{\tabu@starttimer \tabu@measuringfalse
620 \edef\tabu@hfuzz {\the\dimexpr\hfuzz+1sp}\global\tabu@footnotes{}%
621 \let\firsthline \tabu@firsthline \let\lasthline \tabu@lasthline
622 \let\firstline \tabu@firstline \let\lastline \tabu@lastline
[rev.2.8 release] 2010 2011 FC
48 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
632 \let\justifying \tabu@justifying \let\rowfont \tabu@rowfont
633 \let\fbox \tabu@fbox \let\color@b@x \tabu@color@b@x
634 \let\tabu@@everycr \everycr \let\tabu@@everypar \everypar
635 \let\tabu@prepnext@tokORI \prepnext@tok\let\prepnext@tok \tabu@prepnext@tok
636 \let\tabu@multicolumnORI\multicolumn \let\multicolumn \tabu@multicolumn
637 \let\tabu@startpbox \@startpbox % for nested tabu inside longtabu pfff !!!
638 \let\tabu@endpbox \@endpbox % idem " " " " " " "
639 \let\tabu@tabarray \@tabarray % idem " " " " " " "
640 \tabu@adl@fix \let\endarray \tabu@endarray % <fix> colortbl & arydshln (delarray)
641 \iftabu@colortbl\CT@everycr\expandafter{\expandafter\iftabu@everyrow \the\CT@everycr \fi}\fi
642 }% \tabu@init
643 \def\tabu@indent{% correction for indentation
644 \ifdim \parindent>\z@\ifx \linewidth\tabudefaulttarget
645 %
646 \everypar\expandafter{%
647 \the\everypar\everypar\expandafter{\the\everypar}%
648 \setbox\z@=\lastbox
649 \ifdim\wd\z@>\z@ \edef\tabu@thetarget
650 {\the\dimexpr -\wd\z@+\tabudefaulttarget}\fi
651 \box\z@}%
652 \fi\fi
653 }% \tabu@indent
\tabu@setcleanup We have to save locally (in the group of the environment) the current value of the last global assignments
to \CT@arc@, \CT@drsc@, \tabu@ls@ etc.
\tabu@cleanup Restoration will be done globally after the box that contains the tabular by \tabu@cleanup.
654 \def\tabu@setcleanup {% saves last global assignments
655 \ifodd 1\ifmmode \else \iftabu@long \else 0\fi\fi\relax
656 \def\tabu@aftergroupcleanup{%
657 \def\tabu@aftergroupcleanup{\aftergroup\tabu@cleanup}}%
658 \else
659 \def\tabu@aftergroupcleanup{%
660 \aftergroup\aftergroup\aftergroup\tabu@cleanup
661 \let\tabu@aftergroupcleanup \relax}%
662 \fi
663 \let\tabu@arc@Gsave \tabu@arc@G
664 \let\tabu@arc@G \tabu@arc@L % <init>
665 \let\tabu@drsc@Gsave \tabu@drsc@G
666 \let\tabu@drsc@G \tabu@drsc@L % <init>
667 \let\tabu@ls@Gsave \tabu@ls@G
668 \let\tabu@ls@G \tabu@ls@L % <init>
669 \let\tabu@rc@Gsave \tabu@rc@G
670 \let\tabu@rc@G \tabu@rc@L % <init>
671 \let\tabu@evr@Gsave \tabu@evr@G
672 \let\tabu@evr@G \tabu@evr@L % <init>
673 \let\tabu@celllalign@save \tabu@celllalign
674 \let\tabu@cellralign@save \tabu@cellralign
675 \let\tabu@cellleft@save \tabu@cellleft
[rev.2.8 release] 2010 2011 FC
49 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
685 \edef\c@taburow@save {\the\c@taburow}%
686 \edef\tabu@naturalX@save {\the\tabu@naturalX}%
687 \let\tabu@naturalXmin@save \tabu@naturalXmin
688 \let\tabu@naturalXmax@save \tabu@naturalXmax
689 \let\tabu@mkarstrut@save \tabu@mkarstrut
690 \edef\tabu@clarstrut{%
691 \extrarowheight \the\dimexpr \ht\@arstrutbox-\ht\strutbox \relax
692 \extrarowdepth \the\dimexpr \dp\@arstrutbox-\dp\strutbox \relax
693 \let\noexpand\@arraystretch \@ne \noexpand\tabu@rearstrut}%
694 }% \tabu@setcleanup
695 \def\tabu@cleanup {\begingroup
696 \globaldefs\@ne \tabu@everyrowtrue
697 \let\tabu@arc@G \tabu@arc@Gsave
698 \let\CT@arc@ \tabu@arc@G
699 \let\tabu@drsc@G \tabu@drsc@Gsave
700 \let\CT@drsc@ \tabu@drsc@G
701 \let\tabu@ls@G \tabu@ls@Gsave
702 \let\tabu@ls@ \tabu@ls@G
703 \let\tabu@rc@G \tabu@rc@Gsave
704 \let\tabu@rc@ \tabu@rc@G
705 \let\CT@do@color \relax
706 \let\tabu@evr@G \tabu@evr@Gsave
707 \let\tabu@celllalign \tabu@celllalign@save
708 \let\tabu@cellralign \tabu@cellralign@save
709 \let\tabu@cellleft \tabu@cellleft@save
710 \let\tabu@cellright \tabu@cellright@save
711 \let\tabu@@celllalign \tabu@@celllalign@save
712 \let\tabu@@cellralign \tabu@@cellralign@save
713 \let\tabu@@cellleft \tabu@@cellleft@save
714 \let\tabu@@cellright \tabu@@cellright@save
715 \let\tabu@rowfontreset \tabu@rowfontreset@save
716 \let\tabu@@rowfontreset \tabu@@rowfontreset@save
717 \tabu@naturalX =\tabu@naturalX@save
718 \let\tabu@naturalXmax \tabu@naturalXmax@save
719 \let\tabu@naturalXmin \tabu@naturalXmin@save
720 \let\tabu@mkarstrut \tabu@mkarstrut@save
721 \c@taburow =\c@taburow@save
722 \ifcase \tabu@nested \tabu@alloc \m@ne\fi
723 \endgroup % <end of \globaldefs>
724 \ifcase \tabu@nested
725 \the\tabu@footnotes \global\tabu@footnotes{}%
726 \tabu@afterendpar \tabu@elapsedtime
727 \fi
728 \tabu@clarstrut
729 \everyrow\expandafter {\tabu@evr@G}%
730 }% \tabu@cleanup
731 \let\tabu@afterendpar \relax
\tabu@setreset At the beginning of each trial, we have to restore the current value that were active at the entry in the
[rev.2.8 release] 2010 2011 FC
tabu environment (for they could have been globally overwritten inside the tabular).
The same must occur when using \usetabu as a preamble. Values are restored locally inside the tabu box.
\tabu@reset \tabu@setreset defines \tabu@reset to be expanded at the beginning of each trial and when \usetabu is
used.
732 \def\tabu@setreset {%
733 \edef\tabu@savedparams {% \relax for \tabu@message@save
734 \ifmmode \col@sep \the\arraycolsep
735 \else \col@sep \the\tabcolsep \fi \relax
U
b
50 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
736 \arrayrulewidth \the\arrayrulewidth \relax
737 \doublerulesep \the\doublerulesep \relax
738 \extratabsurround \the\extratabsurround \relax
739 \extrarowheight \the\extrarowheight \relax
740 \extrarowdepth \the\extrarowdepth \relax
741 \abovetabulinesep \the\abovetabulinesep \relax
742 \belowtabulinesep \the\belowtabulinesep \relax
743 \def\noexpand\arraystretch{\arraystretch}%
744 \ifdefined\minrowclearance \minrowclearance\the\minrowclearance\relax\fi}%
745 \begingroup
746 \@temptokena\expandafter{\tabu@savedparams}% => only for \savetabu / \usetabu
747 \ifx \tabu@arc@L\relax \else \tabu@setsave \tabu@arc@L \fi
748 \ifx \tabu@drsc@L\relax \else \tabu@setsave \tabu@drsc@L \fi
749 \tabu@setsave \tabu@ls@L \tabu@setsave \tabu@evr@L
750 \expandafter \endgroup \expandafter
751 \def\expandafter\tabu@saved@ \expandafter{\the\@temptokena
752 \let\tabu@arc@G \tabu@arc@L
753 \let\tabu@drsc@G \tabu@drsc@L
754 \let\tabu@ls@G \tabu@ls@L
755 \let\tabu@rc@G \tabu@rc@L
756 \let\tabu@evr@G \tabu@evr@L}%
757 \def\tabu@reset{\tabu@savedparams
758 \tabu@everyrowtrue \c@taburow \z@
759 \let\CT@arc@ \tabu@arc@L
760 \let\CT@drsc@ \tabu@drsc@L
761 \let\tabu@ls@ \tabu@ls@L
762 \let\tabu@rc@ \tabu@rc@L
763 \global\tabu@alloc \tabu@alloc@save
764 \everyrow\expandafter{\tabu@evr@L}}%
765 }% \tabu@reset
766 \def\tabu@setsave #1{\expandafter\tabu@sets@ve #1\@nil{#1}}
767 \long\def\tabu@sets@ve #1\@nil #2{\@temptokena\expandafter{\the\@temptokena \def#2{#1}}}
777 }% \tabu@new@columntype
\tabu@privatecolumntype Columns types defined with \tabu@privatecolumntype are "mounted" only inside the \@mkpream
group of tabu.
778 \def\tabu@privatecolumntype #1{%
779 \expandafter\tabu@private@columntype
780 \csname NC@find@\string#1\expandafter\endcsname
781 \csname NC@rewrite@\string#1\expandafter\endcsname
782 \csname tabu@NC@find@\string#1\expandafter\endcsname
U
783 \csname tabu@NC@rewrite@\string#1\endcsname
b
51 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
784 {#1}%
785 }% \tabu@privatecolumntype
786 \def\tabu@private@columntype#1#2#3#4{%
787 \g@addto@macro\tabu@privatecolumns{\let#1#3\let#2#4}%
788 \tabu@new@columntype#3#4%
789 }% \tabu@private@columntype
790 \let\tabu@privatecolumns \@empty
\tabu@lines The | token for vertical lines may have a special catcode. array.sty makes the test with \if and therefore,
it is catcode insensitiv. Here, we use \scantokens and check if | is not an other character.
798 \def\tabu@lines #1{%
799 \ifx|#1\else \tabu@privatecolumntype #1{\tabu@rewritevline}\fi
800 \NC@list\expandafter{\the\NC@list \NC@do #1}%
801 }% \tabu@lines@
\tabu@vlinearg The macro that parses the optional argument of | vertical lines...
802 \def\tabu@vlinearg #1{%
803 \ifx\\#1\\\def\tabu@thestyle {\tabu@ls@}%
804 \else\tabu@getline {#1}%
805 \fi
806 \def\tabu@rewritten ##1{\def\tabu@rewritten{!{##1\tabu@thevline}}%
807 }\expandafter\tabu@rewritten\expandafter{\tabu@thestyle}%
808 \expandafter \tabu@keepls \tabu@thestyle \@nil
809 }% \tabu@vlinearg
810 \def\tabu@keepls #1\@nil{%
811 \ifcat $\@cdr #1\@nil $%
812 \ifx \relax#1\else
813 \ifx \tabu@ls@#1\else
814 \let#1\relax
815 \xdef\tabu@mkpreambuffer{\tabu@mkpreambuffer
816 \tabu@savels\noexpand#1}\fi\fi\fi
817 }% \tabu@keepls
[rev.2.8 release] 2010 2011 FC
52 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
828 \def\tabu@savels #1{%
829 \expandafter\let\csname\string#1\endcsname #1%
830 \expandafter\def\expandafter\tabu@reset\expandafter{\tabu@reset
831 \tabu@resetls#1}}%
832 \def\tabu@resetls #1{\expandafter\let\expandafter#1\csname\string#1\endcsname}%
53 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
\tabu@rewriteX This macro is expanded by during the rewriting process in case a X column is found.
\tabu@Xsum (a dimen) stores the sum of the (absolute) width coefficients.
For the first X column found in the preamble, a special setup occurs:
if the default target is used (no target specified or tabu spread with X columns), the target: \tabu@target
is set to the default, with a message in the .log file.
\@halignto is \let to \relax to avoid its expansion in \xdef \@preamble just after \@mkpream.
Indeed as long as we have to measure the natural width of the tabular, \@halign must be empty for
trial steps.
The rest of the setup is made \aftergroup (ie.after \xdef \@preamble which occurs inside a group) by
\tabu@prep@TRIAL.
870 \def\tabu@rewriteX #1#2#3{\tabu@Xarg {#1}{#2}{#3}%
871 \iftabu@measuring
872 \else \tabu@measuringtrue % first X column found in the preamble
873 \let\@halignto \relax \let\tabu@halignto \relax
874 \iftabu@spread \tabu@spreadtarget \tabu@target \tabu@target \z@
875 \else \tabu@spreadtarget \z@ \fi
876 \ifdim \tabu@target=\z@
877 \setlength\tabu@target \tabu@thetarget
878 \tabu@message{\tabu@message@defaulttarget}%
879 \else \tabu@message{\tabu@message@target}\fi
880 \fi
881 }% \tabu@rewriteX
\tabu@Xarg A tedious (and fastidious) macro to parse the optional argument of X columns. The aim is to built
\tabu@Xparse \tabu@rewritten which expands to the column specification:
>{alignment} p or m or b {\dimexpr coef \tabucolX \relax }
After that array.sty make it easy: \expandafter \NC@find \tabu@rewritten
884 \def\tabu@Xarg #1#2#3{%
885 \advance\tabu@Xcol \@ne \let\tabu@Xlcr \@empty
886 \let\tabu@Xdisp \@empty \let\tabu@Xmath \@empty
887 \ifx\\#1\\% <shortcut when no option>
888 \def\tabu@rewritten{p}\tabucolX \p@ % <default coef = 1>
889 \else
890 \let\tabu@rewritten \@empty \let\tabu@temp \@empty \tabucolX \z@
891 \tabu@Xparse {}#1\relax
892 \fi
893 \tabu@Xrewritten{#2}{#3}%
894 }% \tabu@Xarg
895 \def\tabu@Xparse #1{\futurelet\@let@token \tabu@Xtest}
896 \expandafter\def\expandafter\tabu@Xparsespace\space{\tabu@Xparse{}}
897 \def\tabu@Xtest{%
898 \ifcase \ifx \relax\@let@token \z@ \else
[rev.2.8 release] 2010 2011 FC
54 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
908 \if C\@let@token 9\else
909 \if R\@let@token 10\else
910 \if J\@let@token 11\else
911 \ifx \@sptoken\@let@token 12\else
912 \if .\@let@token 13\else
913 \if -\@let@token 13\else
914 \ifcat $\@let@token 14\else
915 15\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\relax
916 \or \tabu@Xtype {p}%
917 \or \tabu@Xtype {m}%
918 \or \tabu@Xtype {b}%
919 \or \tabu@Xalign \raggedright\relax
920 \or \tabu@Xalign \centering\relax
921 \or \tabu@Xalign \raggedleft\relax
922 \or \tabu@Xalign \tabu@justify\relax
923 \or \tabu@Xalign \RaggedRight\raggedright
924 \or \tabu@Xalign \Centering\centering
925 \or \tabu@Xalign \RaggedLeft\raggedleft
926 \or \tabu@Xalign \justifying\tabu@justify
927 \or \expandafter \tabu@Xparsespace
928 \or \expandafter \tabu@Xcoef
929 \or \expandafter \tabu@Xm@th
930 \or \tabu@Xcoef{}%
931 \else\expandafter \tabu@Xparse
932 \fi
933 }% \tabu@Xtest
934 \def\tabu@Xalign #1#2{%
935 \ifx \tabu@Xlcr\@empty \else \PackageWarning{tabu}
936 {Duplicate horizontal alignment specification}\fi
937 \ifdefined#1\def\tabu@Xlcr{#1}\let#1\relax
938 \else \def\tabu@Xlcr{#2}\let#2\relax\fi
939 \expandafter\tabu@Xparse
940 }% \tabu@Xalign
941 \def\tabu@Xtype #1{%
942 \ifx \tabu@rewritten\@empty \else \PackageWarning{tabu}
943 {Duplicate vertical alignment specification}\fi
944 \def\tabu@rewritten{#1}\expandafter\tabu@Xparse
945 }% \tabu@Xtype
946 \def\tabu@Xcoef#1{\edef\tabu@temp{\tabu@temp#1}%
947 \afterassignment\tabu@Xc@ef \tabu@cnt\number\if-#10\fi
948 }% \tabu@Xcoef
949 \def\tabu@Xc@ef{\advance\tabucolX \tabu@temp\the\tabu@cnt\p@
950 \tabu@Xparse{}%
951 }% \tabu@Xc@ef
952 \def\tabu@Xm@th #1{\futurelet \@let@token \tabu@Xd@sp}
953 \def\tabu@Xd@sp{\let\tabu@Xmath=$%
954 \ifx $\@let@token \def\tabu@Xdisp{\displaystyle}%
955 \expandafter\tabu@Xparse
956 \else \expandafter\tabu@Xparse\expandafter{\expandafter}%
[rev.2.8 release] 2010 2011 FC
957 \fi
958 }% \tabu@Xd@sp
\tabu@Xrewritten Final step: the whole optional argument has been read, then builds the rewritten column specification.
959 \def\tabu@Xrewritten {%
960 \ifx \tabu@rewritten\@empty \def\tabu@rewritten{p}\fi
961 \ifdim \tabucolX<\z@ \tabu@negcoeftrue
962 \else\ifdim \tabucolX=\z@ \tabucolX \p@
963 \fi\fi
U
b
55 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
964 \edef\tabu@temp{{\the\tabu@Xcol}{\tabu@strippt\tabucolX}}%
965 \edef\tabu@Xcoefs{\tabu@Xcoefs \tabu@ \tabu@temp}%
966 \edef\tabu@rewritten ##1##2{\def\noexpand\tabu@rewritten{%
967 >{\tabu@Xlcr \ifx$\tabu@Xmath$\tabu@Xdisp\fi ##1}%
968 \tabu@rewritten {\tabu@hsize \tabu@temp}%
969 <{##2\ifx$\tabu@Xmath$\fi}}%
970 }\tabu@rewritten
971 }% \tabu@Xrewritten
\preamble (private column type) \preamble is defined as a tabu new column type: loaded only inside the \@mkpream
group inside the tabu environment.
988 \tabu@privatecolumntype \preamble [1]{%
989 \ifx\\#1\\\tabu@saveerr{}\else
990 \@ifundefined{tabu@saved@\string#1}
991 {\tabu@saveerr{#1}}
992 {\csname tabu@saved@\string#1\expandafter\endcsname\expandafter\z@}%
993 \fi
994 }% \NC@rewrite@\preamble
\tabu@rewritefirst This new column type is not really a column type! It is always added to a tabu preamble in order to do
some setup before any other column is rewritten by \@mkpream.
Thus, \NC@list is simply set to {\NC@do \tabu@rewritefirst }. The rewritting of \tabu@rewritefirst
will restore the original list \NC@list.
This column type sets:
\tabu@select to be expanded \aftergroup (after the closing of the \@mkpream group. All the
thick is there: all information collected during the rewritting of X columns (and vertical lines
or leaders) can be reinjected into the group below the \@mkpream group, by the mean of the
U
b
56 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
\tabu@mkpreambuffer (globally defined).
The private columns types are loaded by \tabu@rewritefirst: they will be rewritten afterwards,
during the rewritting loop. This way, X column definition for tabu are only available during the
rewritting process of the tabu preamble, making it possible (and easy) to embed a tabularx inside a
cell of a tabu.
\save@decl is modified inside the \@mkpream group, if tabu is in text mode.
995 \tabu@newcolumntype \tabu@rewritefirst{%
996 \iftabu@long \aftergroup \tabu@longpream % <the whole implementation is here !>
997 \else \aftergroup \tabu@pream
998 \fi
999 \let\tabu@ \relax \let\tabu@hsize \relax
1000 \let\tabu@Xcoefs \@empty \let\tabu@savels \relax
1001 \tabu@Xcol \z@ \tabu@cnt \tw@
1002 \gdef\tabu@mkpreambuffer{\tabu@{}}\tabu@measuringfalse
1003 \global\setbox\@arstrutbox \box\@arstrutbox
1004 \NC@list{\NC@do *}\tabu@textbar \tabu@lines
1005 \NC@list\expandafter{\the\NC@list \NC@do X}%
1006 \iftabu@siunitx % <siunitx S and s columns>
1007 \NC@list\expandafter{\the\NC@list \NC@do S\NC@do s}\fi
1008 \NC@list\expandafter{\the\expandafter\NC@list \tabu@highprioritycolumns}%
1009 \expandafter\def\expandafter\tabu@NC@list\expandafter{%
1010 \the\expandafter\NC@list \tabu@NC@list}% % * | X S <original>
1011 \NC@list\expandafter{\expandafter \NC@do \expandafter\usetabu
1012 \expandafter \NC@do \expandafter\preamble
1013 \the\NC@list \NC@do \tabu@rewritemiddle
1014 \NC@do \tabu@rewritelast}%
1015 \tabu@savedecl
1016 \tabu@privatecolumns
1017 \edef\tabu@prev{\the\@temptokena}\NC@find \tabu@rewritemiddle
1018 }% NC@rewrite@\tabu@rewritefirst
\tabu@rewritemiddleThis new column type is rewritten after X columns, because it is declared by when the column
\tabu@rewritelast \tabu@rewritefirst is actually rewritten. In the case where \tabu@target is > 0 (either because of tabu
to or tabu spread has been called) and if there is no X column, then @{\extracolsep \@flushglue } is
added at the beginning of the preamble.
To avoid duplicate margin in the tabu we have to test the next token in the preamble. If the next token is
| or ! then no margin must be added and @{\extracolsep \@flushglue } can be inserted at the beginning
of the preamble.
Otherwise, we must insert !{\extracolsep \@flushglue } in order to keep the margin.
\tabu@rewritelast column type is loaded by \tabu@rewritefirst column type, only inside the \@mkpream
group inside the tabu environment.
1019 \tabu@newcolumntype \tabu@rewritemiddle{%
1020 \edef\tabu@temp{\the\@temptokena}\NC@find \tabu@rewritelast
1021 }% \NC@rewrite@\tabu@rewritemiddle
1022 \tabu@newcolumntype \tabu@rewritelast{%
1023 \ifx \tabu@temp\tabu@prev \advance\tabu@cnt \m@ne
[rev.2.8 release] 2010 2011 FC
U
b
57 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
The end of the rewritting process: determining the tabu strategy
\tabu@endrewrite Determines the strategy to be executed \aftergroup (at the closing of the \@mkpream group):
0) There is no real strategy: tabu behaves like tabular, there no X column, and no need to
measure the vertical dimensions of the cells (no dynamic spacing, no vertical leader). In
case a target has been given to tabu, it behaves like tabular* and a infinite stretchability is
given to the column inter-space. This is done (if required) by \tabu@extracolsep.
1) Measuring natural width of some (or all) columns is compulsory for tabu spread of X
columns with negativ coefficients. Thereafter, the strategy nr 2 will bring into play.
2) Measuring the natural width is not necessary, or has been done before. But tabu contains
X columns and trials have to be performed to reach the desired target, adjusting the
\tabucolX dimension accordingly. Then, the strategy nr 3 may bring into play, if vertical
measure is required.
3) Vertical measure of the cells is required, for vertical spacing adjustment or vertical leaders.
This step can be done only if the width are known.
> 3 The tabu is finished and ready to be printed !!
1032 \def\tabu@endrewrite {%
1033 \let\tabu@temp \NC@find
1034 \ifx \@arrayright\relax \let\@arrayright \@empty \fi
1035 \count@=%
1036 \ifx \@finalstrut\tabu@finalstrut \z@ % outer in mode 0 print
1037 \iftabu@measuring
1038 \xdef\tabu@mkpreambuffer{\tabu@mkpreambuffer
1039 \tabu@target \csname tabu@\the\tabu@nested.T\endcsname
1040 \tabucolX \csname tabu@\the\tabu@nested.X\endcsname
1041 \edef\@halignto {\ifx\@arrayright\@empty to\tabu@target\fi}}%
1042 \fi
1043 \else\iftabu@measuring 4 % X columns
1044 \xdef\tabu@mkpreambuffer{\tabu@{\tabu@mkpreambuffer
1045 \tabu@target \the\tabu@target
1046 \tabu@spreadtarget \the\tabu@spreadtarget}%
1047 \def\noexpand\tabu@Xcoefs{\tabu@Xcoefs}%
1048 \edef\tabu@halignto{\ifx \@arrayright\@empty to\tabu@target\fi}}%
1049 \let\tabu@Xcoefs \relax
1050 \else\ifcase\tabu@nested \thr@@ % outer, no X
1051 \global\let\tabu@afterendpar \relax
1052 \else \@ne % inner, no X, outer in mode 1 or 2
1053 \fi
1054 \ifdefined\tabu@usetabu
1055 \else \ifdim\tabu@target=\z@
1056 \else \let\tabu@temp \tabu@extracolsep
1057 \fi\fi
1058 \fi
1059 \fi
1060 \xdef\tabu@mkpreambuffer{\count@ \the\count@ \tabu@mkpreambuffer}%
1061 \tabu@temp
1062 }% \tabu@endrewrite
[rev.2.8 release] 2010 2011 FC
\tabu@extracolsep Inserts \extracolsep \@flushglue in front of the preamble, unless another value for \extracolsep has
been specified.
\@flushglue is 0pt plus 1fil.
1063 \def\tabu@extracolsep{\@defaultunits \expandafter\let
1064 \expandafter\tabu@temp \expandafter=\the\@temptokena \relax\@nnil
1065 \ifx \tabu@temp\@sptoken
1066 \expandafter\tabu@gobblespace \expandafter\tabu@extracolsep
U
b
58 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1067 \else
1068 \edef\tabu@temp{\noexpand\NC@find
1069 \if |\noexpand\tabu@temp @%
1070 \else\if !\noexpand\tabu@temp @%
1071 \else !%
1072 \fi\fi
1073 {\noexpand\extracolsep\noexpand\@flushglue}}%
1074 \fi
1075 \tabu@temp
1076 }% \tabu@extrac@lsep
\tabu@select Here we check if trials are required or not: depending on the value of \count@ (set at \tabu@endrewrite,
and injected here by \tabu@mkpreambuffer), on \iftabu@measuring (nested trials).
[rev.2.8 release] 2010 2011 FC
When trials are required, \tabu@select give control to \tabu@setstrategy (to prepare the neutralisation
of commands, save counters etc).
When trials are not required, we just have to expand \tabuthepreamble, after having set up the \everyrow
stuff properly (for vertical adjustment or vertical measure, if needed).
1098 \def\tabu@select {%
1099 \ifnum\tabu@nested>\z@ \tabuscantokensfalse \fi
1100 \ifnum \count@=\@ne \iftabu@measuring \count@=\tw@ \fi\fi
1101 \ifcase \count@
U
b
59 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1102 \global\let\tabu@elapsedtime \relax
1103 \tabu@seteverycr
1104 \expandafter \tabuthepreamble % vertical adjustment (inheritated from outer)
1105 \or % exit in vertical measure + struts per cell because no X and outer in mode 3
1106 \tabu@evr{\tabu@verticalinit}\tabu@celllalign@def{\tabu@verticalmeasure}%
1107 \def\tabu@cellralign{\tabu@verticalspacing}%
1108 \tabu@seteverycr
1109 \expandafter \tabuthepreamble
1110 \or % exit without measure because no X and outer in mode 4
1111 \tabu@evr{}\tabu@celllalign@def{}\let\tabu@cellralign \@empty
1112 \tabu@seteverycr
1113 \expandafter \tabuthepreamble
1114 \else % needs trials
1115 \tabu@evr{}\tabu@celllalign@def{}\let\tabu@cellralign \@empty
1116 \tabu@savecounters
1117 \expandafter \tabu@setstrategy
1118 \fi
1119 }% \tabu@select
1120 \def\tabu@@ {\gdef\tabu@mkpreambuffer}
60 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1150 \else -#2\p@ \tabu@negcoeftrue
1151 \@tempdima \dimexpr \tabu@target*\p@/\dimexpr-#2\p@\relax \relax
1152 \ifdim \tabucolX<\@tempdima \tabucolX \@tempdima \fi
1153 \tabu@wddef{#1}{0pt}%
1154 \fi
1155 }% \tabu@Xinit
by \tabu@endtrial.
1181 \def\tabu@strategy {\relax % stops \count@ assignment !
1182 \ifcase\count@ % case 0 = print with vertical adjustment (outer is finished)
1183 \expandafter \tabu@endoftrials
1184 \or % case 1 = exit in vertical measure (outer in mode 3)
1185 \expandafter\xdef\csname tabu@\the\tabu@nested.T\endcsname{\the\tabu@target}%
1186 \expandafter\xdef\csname tabu@\the\tabu@nested.X\endcsname{\the\tabucolX}%
1187 \expandafter \tabu@endoftrials
1188 \or % case 2 = exit with a rule replacing the table (outer in mode 4)
U
b
61 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1189 \expandafter \tabu@quickend
1190 \or % case 3 = outer is in mode 3 because of no X
1191 \begingroup
1192 \tabu@evr{\tabu@verticalinit}\tabu@celllalign@def{\tabu@verticalmeasure}%
1193 \def\tabu@cellralign{\tabu@verticalspacing}%
1194 \expandafter \tabu@measuring
1195 \else % case 4 = horizontal measure
1196 \begingroup
1197 \global\let\tabu@elapsedtime \tabu@message@etime
1198 \long\def\multicolumn##1##2##3{\multispan{##1}}%
1199 \let\tabu@startpboxORI \@startpbox
1200 \iftabu@spread
1201 \def\tabu@naturalXmax {\z@}%
1202 \let\tabu@naturalXmin \tabu@naturalXmax
1203 \tabu@evr{\global\tabu@naturalX \z@}%
1204 \let\@startpbox \tabu@startpboxmeasure
1205 \else\iftabu@negcoef
1206 \let\@startpbox \tabu@startpboxmeasure
1207 \else \let\@startpbox \tabu@startpboxquick
1208 \fi\fi
1209 \expandafter \tabu@measuring
1210 \fi
1211 }% \tabu@strategy
\tabu@measuring Expands \tabu@trial with the whole content of the environment stored in \toks@ by \tabu@collectbody.
At the end of the trial, \count@ will be reassigned to the value it had before the trial. Then \tabu@endtrial
will choose the algorithm depending on the strategy number, and set the new strategy number (into
\count@ again) for the next step.
\tabu@trial This is the starting point of trials: \halign is expanded here.
\tabu@longtrial This is the long version of \tabu@trial for longtabu. Almost the same apart for the math group and the
end (a longtable environment does not finish with \endarray).
1212 \def\tabu@measuring{\expandafter \tabu@trial \expandafter
1213 \count@ \the\count@ \tabu@endtrial
1214 }% \tabu@measuring
1215 \def\tabu@trial{\iftabu@long \tabu@longtrial \else \tabu@shorttrial \fi}
1216 \def\tabu@shorttrial {\setbox\tabu@box \hbox\bgroup \tabu@seteverycr
1217 \ifx \tabu@savecounters\relax \else
1218 \let\tabu@savecounters \relax \tabu@clckpt \fi
1219 $\iftabuscantokens \tabu@rescan \else \expandafter\@secondoftwo \fi
1220 \expandafter{\expandafter \tabuthepreamble
1221 \the\tabu@thebody
1222 \csname tabu@adl@endtrial\endcsname
1223 \endarray}$\egroup % got \tabu@box
1224 }% \tabu@shorttrial
1225 \def\tabu@longtrial {\setbox\tabu@box \hbox\bgroup \tabu@seteverycr
1226 \ifx \tabu@savecounters\relax \else
1227 \let\tabu@savecounters \relax \tabu@clckpt \fi
[rev.2.8 release] 2010 2011 FC
U
b
62 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1237 \def\tabu@adl@endtrial{% <arydshln in nested trials - problem for global column counters!>
1238 \crcr \noalign{\global\adl@ncol \tabu@nbcols}}% anything global is crap, junky and fails !
\tabu@seteverycr \ialign resets \everycr to an empty token. This macro sets \everycr for the tabu environment : a bridge
around \ialign is built: \everycr redefines itself \afterassignment!
1239 \def\tabu@seteverycr {\tabu@reset
1240 \everycr \expandafter{\the\everycr \tabu@everycr}%
1241 \let\everycr \tabu@noeverycr % <for ialign>
1242 }% \tabu@seteverycr
1243 \def\tabu@noeverycr{{\aftergroup\tabu@restoreeverycr \afterassignment}\toks@}
1244 \def\tabu@restoreeverycr {\let\everycr \tabu@@everycr}
1245 \def\tabu@everycr {\iftabu@everyrow \noalign{\tabu@everyrow}\fi}
\tabu@endoftrials When the algorithm said the tabular was ready to be printed, \tabu@endoftrials closes the trials group
and prints the tabular...
The required values (column widths, struts etc.) are injected into the group by the mean of the buffer
\tabu@bufferX (locally defined).
\tabu@closetrialsgroup This closes the group in which all the trials are done.
1246 \def\tabu@endoftrials {%
1247 \iftabuscantokens \expandafter\@firstoftwo
1248 \else \expandafter\@secondoftwo
1249 \fi
1250 {\expandafter \tabu@closetrialsgroup \expandafter
1251 \tabu@rescan \expandafter{%
1252 \expandafter\tabuthepreamble
1253 \the\expandafter\tabu@thebody
1254 \iftabu@long \else \endarray \fi}}
1255 {\expandafter\tabu@closetrialsgroup \expandafter
1256 \tabuthepreamble
1257 \the\tabu@thebody}%
1258 \tabu@endenvir % Finish !
1259 }% \tabu@endoftrials
1260 \def\tabu@closetrialsgroup {%
1261 \toks@\expandafter{\tabu@endenvir}%
1262 \edef\tabu@bufferX{\endgroup
1263 \tabucolX \the\tabucolX
1264 \tabu@target \the\tabu@target
1265 \tabu@cnt \the\tabu@cnt
1266 \def\noexpand\tabu@endenvir{\the\toks@}%
1267 %Quid de \@halignto = \tabu@halignto ??
1268 }% \tabu@bufferX
1269 \tabu@bufferX
1270 \ifcase\tabu@nested % print out (outer in mode 0)
1271 \global\tabu@cnt \tabu@cnt
1272 \tabu@evr{\tabu@verticaldynamicadjustment}%
1273 \tabu@celllalign@def{\everypar{}}\let\tabu@cellralign \@empty
1274 \let\@finalstrut \tabu@finalstrut
1275 \else % vertical measure of nested tabu
[rev.2.8 release] 2010 2011 FC
1276 \tabu@evr{\tabu@verticalinit}%
1277 \tabu@celllalign@def{\tabu@verticalmeasure}%
1278 \def\tabu@cellralign{\tabu@verticalspacing}%
1279 \fi
1280 \tabu@clckpt \let\@halignto \tabu@halignto
1281 \let\@halignto \@empty
1282 \tabu@seteverycr
1283 \ifdim \tabustrutrule>\z@ \ifnum\tabu@nested=\z@
1284 \setbox\@arstrutbox \box\voidb@x % force \@arstrutbox to be rebuilt (visible struts)
U
b
63 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1285 \fi\fi
1286 }% \tabu@closetrialsgroup
\tabu@quickend Quick exit after having measuring the natural width of a nested tabu.
1287 \def\tabu@quickend {\expandafter \endgroup \expandafter
1288 \tabu@target \the\tabu@target \tabu@quickrule
1289 \let\endarray \relax \tabu@endenvir
1290 }% \tabu@quickend
\tabu@endtrial Depending on the strategy that was just applied, \tabu@endtrial chooses the algorithm and determines
the number of the strategy for the next step.
1291 \def\tabu@endtrial {\relax % stops \count@ assignment !
1292 \ifcase \count@ \tabu@err % case 0 = impossible here
1293 \or \tabu@err % case 1 = impossible here
1294 \or \tabu@err % case 2 = impossible here
1295 \or % case 3 = outer goes into mode 0
1296 \def\tabu@bufferX{\endgroup}\count@ \z@
1297 \else % case 4 = outer goes into mode 3
1298 \iftabu@spread \tabu@spreadarith % inner into mode 1 (outer in mode 3)
1299 \else \tabu@arith % or 2 (outer in mode 4)
1300 \fi
1301 \count@=%
1302 \ifcase\tabu@nested \thr@@ % outer goes into mode 3
1303 \else\iftabu@measuring \tw@ % outer is in mode 4
1304 \else \@ne % outer is in mode 3
1305 \fi\fi
1306 \edef\tabu@bufferX{\endgroup
1307 \tabucolX \the\tabucolX
1308 \tabu@target \the\tabu@target}%
1309 \fi
1310 \expandafter \tabu@bufferX \expandafter
1311 \count@ \the\count@ \tabu@strategy
1312 }% \tabu@endtrial
1313 \def\tabu@err{\errmessage{(tabu) Internal impossible error! (\count@=\the\count@)}}
1314 \def\tabu@arithnegcoef {%
1315 \@tempdima \z@ \dimen@ \z@ \let\tabu@ \tabu@arith@negcoef \tabu@Xcoefs
1316 }% \tabu@arithnegcoef
1317 \def\tabu@arith@negcoef #1#2{%
1318 \ifdim #2\p@>\z@ \advance\dimen@ #2\p@ % saturated by definition
1319 \advance\@tempdima #2\tabucolX
1320 \else
1321 \ifdim -#2\tabucolX <\tabu@wd{#1}% c_i X < natural width <= \tabu@target-> saturated
1322 \advance\dimen@ -#2\p@
U
b
64 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1323 \advance\@tempdima -#2\tabucolX
1324 \else
1325 \advance\@tempdima \tabu@wd{#1}% natural width <= c_i X => neutralised
1326 \ifdim \tabu@wd{#1}<\tabu@target \else % neutralised
1327 \advance\dimen@ -#2\p@ % saturated (natural width = tabu@target)
1328 \fi
1329 \fi
1330 \fi
1331 }% \tabu@arith@negcoef
65 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1379 \tabucolX \the\tabucolX
1380 \tabu@target \the\tabu@target}%
1381 }% \tabu@arith
1413 \def\tabu@message@defaulttarget{%
1414 \ifnum\tabu@nested=\z@^^J(tabu) Default target:
1415 \ifx\tabudefaulttarget\linewidth \string\linewidth
1416 \ifdim \tabu@thetarget=\linewidth \else
1417 -\the\dimexpr\linewidth-\tabu@thetarget\fi =
1418 \else\ifx\tabudefaulttarget\linegoal\string\linegoal=
[rev.2.8 release] 2010 2011 FC
1419 \fi\fi
1420 \else (tabu) Default target (nested): \fi
1421 \the\tabu@target \on@line
1422 \ifnum\tabu@nested=\z@ , page \the\c@page\fi}
1423 \def\tabu@message@target {^^J(tabu) Target specified:
1424 \the\tabu@target \on@line, page \the\c@page}
\tabu@message@arith
66 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1426 \tabu@msgalign \tabucolX { }{ }{ }{ }{ }\@@
1427 \tabu@msgalign \wd\tabu@box { }{ }{ }{ }{ }\@@
1428 \tabu@msgalign \tabu@target { }{ }{ }{ }{ }\@@
1429 \tabu@msgalign@PT \dimen@ { }{}{}{}{}{}{}\@@
1430 \ifdim \tabu@DELTA<\tabu@hfuzz giving space\else
1431 \tabu@msgalign \dimexpr (\@tempdima-\tabu@DELTA) *\p@/\tabu@Xsum -\tabucolX {}{}{}{}{}\@@
1432 \fi
1433 }% \tabu@message@arith
\tabu@message@spreadarith
\tabu@message@negcoef
\tabu@message@reached
1451 \def\tabu@message@reached{\tabu@header
1452 ******* Reached Target:
1453 hfuzz = \tabu@hfuzz\on@line\space *******}
\tabu@message@etime
1454 \def\tabu@message@etime{\edef\tabu@stoptime{\the\pdfelapsedtime}%
1455 \tabu@message{(tabu)\tabu@spaces Time elapsed during measure:
1456 \the\numexpr(\tabu@stoptime-\tabu@starttime-32767)/65536\relax sec
1457 \the\numexpr\numexpr(\tabu@stoptime-\tabu@starttime)
1458 -\numexpr(\tabu@stoptime-\tabu@starttime-32767)/65536\relax*65536\relax
1459 *1000/65536\relax ms \tabu@spaces(\the\tabu@cnt\space
1460 cycle\ifnum\tabu@cnt>\@ne s\fi)^^J^^J}}
\tabu@message@verticalsp
1461 \def\tabu@message@verticalsp {%
1462 \ifdim \@tempdima>\tabu@ht
1463 \ifdim \@tempdimb>\tabu@dp
1464 \expandafter\expandafter\expandafter\string\tabu@ht =
[rev.2.8 release] 2010 2011 FC
67 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1474 \expandafter\expandafter\expandafter\string\tabu@dp =
1475 \tabu@msgalign \@tempdimb { }{ }{ }{ }{ }\@@^^J\fi
1476 \fi
1477 }% \tabu@message@verticalsp
\tabu@message@save
1478 \edef\tabu@spaces{\@spaces}
1479 \def\tabu@strippt{\expandafter\tabu@pt\the}
1480 {\@makeother\P \@makeother\T\lowercase{\gdef\tabu@pt #1PT{#1}}}
1481 \def\tabu@msgalign{\expandafter\tabu@msg@align\the\dimexpr}
1482 \def\tabu@msgalign@PT{\expandafter\tabu@msg@align\romannumeral-\0\tabu@strippt}
1483 \def\do #1{%
1484 \def\tabu@msg@align##1.##2##3##4##5##6##7##8##9\@@{%
1485 \ifnum##1<10 #1 #1\else
1486 \ifnum##1<100 #1 \else
1487 \ifnum##1<\@m #1\fi\fi\fi
1488 ##1.##2##3##4##5##6##7##8#1}%
1489 \def\tabu@header{(tabu) \ifnum\tabu@cnt<10 #1\fi\the\tabu@cnt) }%
1490 \def\tabu@titles{\ifnum \tabu@nested=\z@
1491 (tabu) Try#1 #1 tabu X #1 #1 #1tabu Width #1 #1 Target
1492 #1 #1 #1 Coefs #1 #1 #1 Update^^J\fi}%
1493 \def\tabu@spreadheader{%
1494 (tabu) Try#1 #1 Spread #1 #1 tabu Width #1 #1 #1 Nat. X #1 #1 #1 #1Nat. Min.
1495 #1 New Target^^J%
1496 (tabu) sprd}
1497 \def\tabu@message@save {\begingroup
1498 \def\x ####1{\tabu@msg@align ####1{ }{ }{ }{ }{}\@@}
1499 \def\z ####1{\expandafter\x\expandafter{\romannumeral-\0\tabu@strippt
1500 \dimexpr####1\p@{ }{ }}}%
1501 \let\color \relax \def\tabu@rulesstyle ####1####2{\detokenize{####1}}%
1502 \let\CT@arc@ \relax \let\@preamble \@gobble
1503 \let\tabu@savedpream \@firstofone
1504 \let\tabu@savedparams \@firstofone
1505 \def\tabu@target ####1\relax {(tabu) target #1 #1 #1 #1 #1 = \x{####1}^^J}%
1506 \def\tabucolX ####1\relax {(tabu) X columns width#1 = \x{####1}^^J}%
1507 \def\tabu@nbcols ####1\relax {(tabu) Number of columns: \z{####1}^^J}%
1508 \def\tabu@aligndefault ####1{(tabu) Default alignment: #1 #1 ####1^^J}%
1509 \def\col@sep ####1\relax {(tabu) column sep #1 #1 #1 = \x{####1}^^J}%
1510 \def\arrayrulewidth ####1\relax{(tabu) arrayrulewidth #1 = \x{####1}}%
1511 \def\doublerulesep ####1\relax { doublerulesep = \x{####1}^^J}%
1512 \def\extratabsurround####1\relax{(tabu) extratabsurround = \x{####1}^^J}%
1513 \def\extrarowheight ####1\relax{(tabu) extrarowheight #1 = \x{####1}}%
1514 \def\extrarowdepth ####1\relax {extrarowdepth = \x{####1}^^J}%
1515 \def\abovetabulinesep####1\relax{(tabu) abovetabulinesep=\x{####1} }%
1516 \def\belowtabulinesep####1\relax{ belowtabulinesep=\x{####1}^^J}%
1517 \def\arraystretch ####1{(tabu) arraystretch #1 #1 = \z{####1}^^J}%
1518 \def\minrowclearance####1\relax{(tabu) minrowclearance #1 = \x{####1}^^J}%
1519 \def\tabu@arc@L ####1{(tabu) taburulecolor #1 #1 = ####1^^J}%
1520 \def\tabu@drsc@L ####1{(tabu) tabudoublerulecolor= ####1^^J}%
[rev.2.8 release] 2010 2011 FC
68 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1530 }\do{ }
\tabu@endpboxmeasure The cell has been built inside a box: we have to get its dimensions, and update \tabu@naturalX,
\tabu@naturalXmin and \tabu@naturalXmax accordingly (for tabu spread), and even store (globally)
each column width: the column width is the maximum width of the cells it contains.
1554 \def\tabu@endpboxmeasure {%
1555 \@finalstrut \@arstrutbox
1556 \end{varwidth}\egroup % <got my \tabu@box>
1557 \ifdim \tabu@temp\p@ <\z@ % neg coef
1558 \ifdim \tabu@wd\tabu@Xcol <\wd\tabu@box
1559 \tabu@wddef\tabu@Xcol {\the\wd\tabu@box}%
1560 \tabu@debug{\tabu@message@endpboxmeasure}%
[rev.2.8 release] 2010 2011 FC
1561 \fi
1562 \else % spread coef>0
1563 \global\advance \tabu@naturalX \wd\tabu@box
1564 \@tempdima =\dimexpr \wd\tabu@box *\p@/\dimexpr \tabu@temp\p@\relax \relax
1565 \ifdim \tabu@naturalXmax <\tabu@naturalX
1566 \xdef\tabu@naturalXmax {\the\tabu@naturalX}\fi
1567 \ifdim \tabu@naturalXmin <\@tempdima
1568 \xdef\tabu@naturalXmin {\the\@tempdima}\fi
1569 \fi
U
1570 \box\tabu@box \egroup % end of \vtop (measure) restore \tabu@target
b
69 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1571 }% \tabu@endpboxmeasure
1572 \def\tabu@wddef #1{\expandafter\xdef
1573 \csname tabu@\the\tabu@nested.W\number#1\endcsname}
1574 \def\tabu@wd #1{\csname tabu@\the\tabu@nested.W\number#1\endcsname}
1575 \def\tabu@message@endpboxmeasure{\tabu@spaces\tabu@spaces<-> % <-> save natural wd
1576 \the\tabu@Xcol. X[\tabu@temp]:
1577 target = \the\tabucolX \space
1578 \expandafter\expandafter\expandafter\string\tabu@wd\tabu@Xcol
1579 =\tabu@wd\tabu@Xcol
1580 }% \tabu@message@endpboxmeasure
\tabu@startpboxquick Contents of paragraph columns are not built during trials in strategy number 4.
1581 \def\tabu@startpboxquick {\bgroup
1582 \let\@startpbox \tabu@startpboxORI % restore immediately
1583 \let\tabu \tabu@quick % \begin is expanded before...
1584 \expandafter\@gobble \@startpbox % gobbles \bgroup
1585 }% \tabu@startpboxquick
1586 \def\tabu@quick {\begingroup \iffalse{\fi \ifnum0=}\fi
1587 \toks@{}\def\tabu@stack{b}\tabu@collectbody \tabu@endquick
1588 }% \tabu@quick
1589 \def\tabu@endquick {%
1590 \ifodd 1\ifx\tabu@end@envir\tabu@endtabu \else
1591 \ifx\tabu@end@envir\tabu@endtabus \else 0\fi\fi\relax
1592 \endgroup
1593 \else \let\endtabu \relax
1594 \tabu@end@envir
1595 \fi
1596 }% \tabu@quick
1597 \def\tabu@endtabu {\end{tabu}}
1598 \def\tabu@endtabus {\end{tabu*}}
U
\tabu@verticalmeasure
know the height/depth of every row.
1599 \def\tabu@verticalmeasure{\everypar{}%
1600 \ifnum \currentgrouptype>12 % 14=semi-simple, 15=math shift group
1601 \setbox\tabu@box =\hbox\bgroup
1602 \let\tabu@verticalspacing \tabu@verticalsp@lcr
1603 \d@llarbegin % after \hbox ...
1604 \else
1605 \edef\tabu@temp{\ifnum\currentgrouptype=5\vtop
1606 \else\ifnum\currentgrouptype=12\vcenter
1607 \else\vbox\fi\fi}%
1608 \setbox\tabu@box \hbox\bgroup$\tabu@temp \bgroup
1609 \let\tabu@verticalspacing \tabu@verticalsp@pmb
1610 \fi
1611 }% \tabu@verticalmeasure
[rev.2.8 release] 2010 2011 FC
U
1619 \noindent\vrule height\@tempdima depth\@tempdimb
b
70 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1620 }% \tabu@verticalsp@lcr
\tabu@verticaldynamicadjustment This updates the \@arstrutbox at \everyrow (ie.\everycr) in order to adjust the vertical
spacing of cells.
1645 \def\tabu@verticaldynamicadjustment {%
1646 \advance\c@taburow \@ne
1647 \extrarowheight \dimexpr\tabu@ht - \ht\strutbox
1648 \extrarowdepth \dimexpr\tabu@dp - \dp\strutbox
1649 \let\arraystretch \@empty
1650 \advance\c@taburow \m@ne
1651 }% \tabu@verticaldynamicadjustment
11.15 \tabuphantomline
\tabuphantomline This macro inserts a phantom line in front of a tabu. This is necessary when you use \usetabu with tabu
X column, with a single line containing \multicolumn...
1652 \def\tabuphantomline{\crcr \noalign{%
1653 {\globaldefs \@ne
1654 \setbox\@arstrutbox \box\voidb@x
1655 \let\tabu@@celllalign \tabu@celllalign
1656 \let\tabu@@cellralign \tabu@cellralign
[rev.2.8 release] 2010 2011 FC
71 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1666 \toks@\expandafter{\tabu@temp \noindent\tabu@everyrowfalse \cr
1667 \noalign{\tabu@rearstrut
1668 {\globaldefs\@ne
1669 \let\tabu@celllalign \tabu@@celllalign
1670 \let\tabu@cellralign \tabu@@cellralign
1671 \let\tabu@cellleft \tabu@@cellleft
1672 \let\tabu@cellright \tabu@@cellright
1673 \let\tabu@thevline \tabu@@thevline}}}%
1674 \expandafter}\the\toks@
1675 }% \tabuphantomline
\tabu@hlineAZ Here we go, inside a \noalign group, we collect the next tokens:
\tabu@nexthlineAZ 1. first the option,
\tabu@xhlineAZ
2. and then the next tokens if they are \hline or \firsthline.
The code to be executed at the end of the \noalign group is built into \toks@.
1695 \def\tabu@hlineAZ #1#2{\noalign{\ifnum0=}\fi \dimen@ \z@ \count@ \z@
1696 \toks@{}\def\tabu@hlinecorrection{#1}\def\tabu@temp{#2}%
1697 \tabu@hlineAZsurround
[rev.2.8 release] 2010 2011 FC
1698 }% \tabu@hlineAZ
1699 \newcommand*\tabu@hlineAZsurround[1][\extratabsurround]{%
1700 \extratabsurround #1\let\tabucline \tabucline@scan
1701 \let\hline \tabu@hlinescan \let\firsthline \hline
1702 \let\cline \tabu@clinescan \let\lasthline \hline
1703 \expandafter \futurelet \expandafter \tabu@temp
1704 \expandafter \tabu@nexthlineAZ \tabu@temp
1705 }% \tabu@hlineAZsurround
1706 \def\tabu@hlinescan {\tabu@thick \arrayrulewidth \tabu@xhlineAZ \hline}
U
b
72 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1707 \def\tabu@clinescan #1{\tabu@thick \arrayrulewidth \tabu@xhlineAZ {\cline{#1}}}
1708 \def\tabucline@scan{\@testopt \tabucline@sc@n {}}
1709 \def\tabucline@sc@n #1[#2]{\tabu@xhlineAZ {\tabucline[{#1}]{#2}}}
1710 \def\tabu@nexthlineAZ{%
1711 \ifx \tabu@temp\hline \else
1712 \ifx \tabu@temp\cline \else
1713 \ifx \tabu@temp\tabucline \else
1714 \tabu@hlinecorrection
1715 \fi\fi\fi
1716 }% \tabu@nexthlineAZ
1717 \def\tabu@xhlineAZ #1{%
1718 \toks@\expandafter{\the\toks@ #1}%
1719 \@tempdimc \tabu@thick % The last line width
1720 \ifcase\count@ \@tempdimb \tabu@thick % The first line width
1721 \else \advance\dimen@ \dimexpr \tabu@thick+\doublerulesep \relax
1722 \fi
1723 \advance\count@ \@ne \futurelet \tabu@temp \tabu@nexthlineAZ
1724 }% \tabu@xhlineAZ
\tabu@firsthlinecorrection This is the correction macro for \firsthline, ie.a strut and a skip are inserted before the first
\hline.
1725 \def\tabu@firsthlinecorrection{% \count@ = number of \hline -1
1726 \@tempdima \dimexpr \ht\@arstrutbox+\dimen@
1727 \edef\firsthline{% <local in \noalign>
1728 \omit \hbox to\z@{\hss{\noexpand\tabu@DBG{yellow}\vrule
1729 height \the\dimexpr\@tempdima+\extratabsurround
1730 depth \dp\@arstrutbox
1731 width \tabustrutrule}\hss}\cr
1732 \noalign{\vskip -\the\dimexpr \@tempdima+\@tempdimb
1733 +\dp\@arstrutbox \relax}%
1734 \the\toks@
1735 }\ifnum0={\fi
1736 \expandafter}\firsthline % we are then !
1737 }% \tabu@firsthlinecorrection
\tabu@lasthlinecorrection This is the correction macro for \lasthline, ie.a strut and a skip are inserted after the last
\hline.
1738 \def\tabu@lasthlinecorrection{%
1739 \@tempdima \dimexpr \dp\@arstrutbox+\dimen@+\@tempdimb+\@tempdimc
1740 \edef\lasthline{% <local in \noalign>
1741 \the\toks@
1742 \noalign{\vskip -\the\dimexpr\dimen@+\@tempdimb+\dp\@arstrutbox}%
1743 \omit \hbox to\z@{\hss{\noexpand\tabu@DBG{yellow}\vrule
1744 depth \the\dimexpr \dp\@arstrutbox+\@tempdimb+\dimen@
1745 +\extratabsurround-\@tempdimc
1746 height \z@
1747 width \tabustrutrule}\hss}\cr
1748 }\ifnum0={\fi
[rev.2.8 release] 2010 2011 FC
73 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1757 \else
1758 \gdef\CT@LT@sep{%
1759 \multispan\LT@cols{%
1760 \CT@drsc@\leaders\hrule\@height\doublerulesep\hfill}\cr}%
1761 \fi
1762 \else
1763 \global\let\LT@next\empty
1764 \gdef\CT@LT@sep{%
1765 \noalign{\penalty-\@lowpenalty\vskip-\arrayrulewidth}}%
1766 \fi
1767 \ifnum0={\fi}%
1768 \multispan\LT@cols
1769 {\CT@arc@\leaders\hrule\@height\arrayrulewidth\hfill}\cr
1770 \CT@LT@sep
1771 \multispan\LT@cols
1772 {\CT@arc@\leaders\hrule\@height\arrayrulewidth\hfill}\cr
1773 \noalign{\penalty\@M}%
1774 \LT@next
1775 }% \tabu@LT@@hline
74 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1806 \fi
1807 }% \tabu@clinearg
1808 \def\tabu@clinebox #1{\tabu@clineleads{\xleaders#1\hss}}
1809 \def\tabu@clineleads #1{%
1810 \let\tabu@thestyle \relax \let\tabu@leaders \@undefined
1811 \gdef\tabu@thehrule{#1}}
1812 \def\tabu@thehline{\begingroup
1813 \ifdefined\tabu@leaders
1814 \noexpand\tabu@thehleaders
1815 \else \noexpand\tabu@thehrule
1816 \fi \endgroup
1817 }% \tabu@thehline
1818 \def\tabu@xcline{%
1819 \ifx \tabu@temp\tabucline
1820 \toks@\expandafter{\the\toks@ \noalign
1821 {\ifx\CT@drsc@\relax \vskip
1822 \else \CT@drsc@\hrule height
1823 \fi
1824 \doublerulesep}}%
1825 \fi
1826 \tabu@docline
1827 }% \tabu@xcline
1828 \def\tabu@docline {\ifnum0={\fi \expandafter}\the\toks@}
1829 \def\tabu@docline@evr {\xdef\tabu@doclineafter{\the\toks@}%
1830 \ifnum0={\fi}\aftergroup\tabu@doclineafter}
1831 \def\tabu@multispan #1#2{%
1832 \ifnum\numexpr#1>\@ne #2\expandafter\tabu@multispan
1833 \else \expandafter\@gobbletwo
1834 \fi {#1-1}{#2}%
1835 }% \tabu@multispan
\tabu@startstop This macro parses the mandatory argument of \tabucline: start-column and end-column of the \cline.
1836 \def\tabu@startstop #1{\tabu@start@stop #1\relax 1-\tabu@nbcols \@nnil}
1837 \def\tabu@start@stop #1-#2\@nnil{%
1838 \@defaultunits \tabu@start\number 0#1\relax \@nnil
1839 \@defaultunits \tabu@stop \number 0#2\relax \@nnil
1840 \tabu@stop \ifnum \tabu@start>\tabu@nbcols \m@ne
1841 \else\ifnum \tabu@stop=\z@ \tabu@nbcols
1842 \else\ifnum \tabu@stop>\tabu@nbcols \tabu@nbcols
1843 \else \tabu@stop
1844 \fi\fi\fi
1845 \advance\tabu@start \m@ne
1846 \ifnum \tabu@start>\z@ \advance\tabu@stop -\tabu@start \fi
1847 }% \tabu@start@stop
\tabudecimal
75 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1856 \ifcase 0\ifx\tabu@temp\ignorespaces\else
1857 \ifx\tabu@temp\@sptoken1\else
1858 2\fi\fi\relax
1859 \let\tabu@getdecimal@ \tabu@getdecimal
1860 \expandafter\tabu@skipdecimal
1861 \or \expandafter\tabu@gobblespace\expandafter\tabu@scandecimal
1862 \else \expandafter\tabu@skipdecimal
1863 \fi
1864 }% \tabu@getdecimal@ignorespaces
1865 \def\tabu@get@decimal#1{\@temptokena\expandafter{\the\@temptokena #1}%
1866 \tabu@scandecimal}
1867 \def\do#1{%
1868 \def\tabu@get@decimalspace#1{%
1869 \@temptokena\expandafter{\the\@temptokena #1}\tabu@scandecimal}%
1870 }\do{ }
1871 \let\tabu@@tabudecimal \tabu@tabudecimal
\tabu@getdecimal
1872 \def\tabu@getdecimal{%
1873 \ifcase 0\ifx 0\tabu@temp\else
1874 \ifx 1\tabu@temp\else
1875 \ifx 2\tabu@temp\else
1876 \ifx 3\tabu@temp\else
1877 \ifx 4\tabu@temp\else
1878 \ifx 5\tabu@temp\else
1879 \ifx 6\tabu@temp\else
1880 \ifx 7\tabu@temp\else
1881 \ifx 8\tabu@temp\else
1882 \ifx 9\tabu@temp\else
1883 \ifx .\tabu@temp\else
1884 \ifx ,\tabu@temp\else
1885 \ifx -\tabu@temp\else
1886 \ifx +\tabu@temp\else
1887 \ifx e\tabu@temp\else
1888 \ifx E\tabu@temp\else
1889 \ifx\tabu@cellleft\tabu@temp1\else
1890 \ifx\ignorespaces\tabu@temp1\else
1891 \ifx\@sptoken\tabu@temp2\else
1892 3\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\relax
1893 \expandafter\tabu@get@decimal
1894 \or \expandafter\tabu@skipdecimal
1895 \or \expandafter\tabu@get@decimalspace
1896 \else\expandafter\tabu@printdecimal
1897 \fi
1898 }% \tabu@getdecimal
1899 \def\tabu@printdecimal{%
1900 \edef\tabu@temp{\the\@temptokena}%
1901 \ifx\tabu@temp\@empty\else
[rev.2.8 release] 2010 2011 FC
1902 \ifx\tabu@temp\space\else
1903 \expandafter\tabu@decimal\expandafter{\the\@temptokena}%
1904 \fi\fi
1905 }% \tabu@printdecimal
U
b
76 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
11.18 Verbatim inside tabu with X columns
\tabu@verbatim Setup to be done before \scantokens to allow verbatim inside the tabu environment.
1906 \def\tabu@verbatim{%
1907 \let\verb \tabu@verb
1908 \let\FV@DefineCheckEnd \tabu@FV@DefineCheckEnd
1909 }% \tabu@verbatim
1923 \xdef\FV@EnvironName{\detokenize\expandafter{\FV@EnvironName}}}%
1924 }\expandafter\tabu@FV@DefineCheckEnd\expandafter{\FV@DefineCheckEnd}
1925 }% \tabu@fancyvrb
1926 \def\tabu@FV@CheckEnd #1{\expandafter\FV@@CheckEnd \detokenize{#1\end{}}\@nil}
1927 \edef\tabu@FV@@@CheckEnd {\detokenize{\end{}}}
1928 \begingroup
1929 \catcode\[1 \catcode\]2
1930 \@makeother\{ \@makeother\}
1931 \edef\x[\endgroup
U
b
77 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1932 \def\noexpand\tabu@FV@@CheckEnd ##1\detokenize[\end{]##2\detokenize[}]##3%
1933 ]\x \@nil{\def\@tempa{#2}\def\@tempb{#3}}
\tabu@FV@ListProcessLine This macro replaces \FV@ListProcessLine when measuring the natural width of a Verbatim
environment (see \tabu@startpboxmeasure)
1934 \def\tabu@FV@ListProcessLine #1{%
1935 \hbox {%to \hsize{%
1936 \kern\leftmargin
1937 \hbox {%to \linewidth{%
1938 \FV@LeftListNumber
1939 \FV@LeftListFrame
1940 \FancyVerbFormatLine{#1}\hss
1941 %% DG/SR modification begin - Jan. 28, 1998 (for numbers=right add-on)
1942 %% \FV@RightListFrame}%
1943 \FV@RightListFrame
1944 \FV@RightListNumber}%
1945 %% DG/SR modification end
1946 \hss}}
11.19 \savetabu
\savetabu When this command is called by the user, the tabu preamble and target are globally stored into a macro
\tabu@saved@huser-namei.
1947 \newcommand*\savetabu[1]{\noalign{%
1948 \tabu@sanitizearg{#1}\tabu@temp
1949 \ifx \tabu@temp\@empty \tabu@savewarn{}{The tabu will not be saved}\else
1950 \@ifundefined{tabu@saved@\tabu@temp}{}{\tabu@savewarn{#1}{Overwritting}}%
1951 \ifdefined\tabu@restored \expandafter\let
1952 \csname tabu@saved@\tabu@temp \endcsname \tabu@restored
1953 \else {\tabu@save}%
1954 \fi
1955 \fi}%
1956 }% \savetabu
1957 \def\tabu@save {%
1958 \toks0\expandafter{\tabu@saved@}%
1959 \iftabu@negcoef
1960 \let\tabu@wddef \relax \let\tabu@ \tabu@savewd \edef\tabu@savewd{\tabu@Xcoefs}%
1961 \toks0\expandafter{\the\toks\expandafter0\tabu@savewd}\fi
1962 \toks1\expandafter{\tabu@savedpream}%
1963 \toks2\expandafter{\tabu@savedpreamble}%
1964 \let\@preamble \relax
1965 \let\tabu@savedpream \relax \let\tabu@savedparams \relax
1966 \edef\tabu@preamble{%
1967 \def\noexpand\tabu@aligndefault{\tabu@align}%
1968 \def\tabu@savedparams {\noexpand\the\toks0}%
1969 \def\tabu@savedpream {\noexpand\the\toks1}}%
1970 \edef\tabu@usetabu{%
1971 \def\@preamble {\noexpand\the\toks2}%
[rev.2.8 release] 2010 2011 FC
78 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
1982 {\the\toks1}}\@tempa
1983 \tabu@message@save
1984 }% \tabu@save
1985 \long\def\tabu@s@ved #1#2#3{%
1986 \def\tabu@usetabu{#1}% <for \tabu@message@save>
1987 \expandafter\gdef\csname tabu@saved@\tabu@temp\endcsname ##1{%
1988 \ifodd ##1% \usetabu
1989 \tabu@measuringfalse \tabu@spreadfalse % Just in case...
1990 \gdef\tabu@usetabu {%
1991 \ifdim \tabu@target>\z@ \tabu@warn@usetabu \fi
1992 \global\let\tabu@usetabu \@undefined
1993 \def\@halignto {to\tabu@target}%
1994 #1%
1995 \ifx \tabu@align\tabu@aligndefault@text
1996 \ifnum \tabu@nested=\z@
1997 \let\tabu@align \tabu@aligndefault \fi\fi}%
1998 \else % \preamble
1999 \gdef\tabu@preamble {%
2000 \global\let\tabu@preamble \@undefined
2001 #2%
2002 \ifx \tabu@align\tabu@aligndefault@text
2003 \ifnum \tabu@nested=\z@
2004 \let\tabu@align \tabu@aligndefault \fi\fi}%
2005 \fi
2006 #3}%
2007 }% \tabu@s@ved
2008 \def\tabu@aligndefault@text {\tabu@aligndefault}%
2009 \def\tabu@warn@usetabu {\PackageWarning{tabu}
2010 {Specifying a target with \string\usetabu\space is useless
2011 \MessageBreak The target cannot be changed!}}
2012 \def\tabu@savewd #1#2{\ifdim #2\p@<\z@ \tabu@wddef{#1}{\tabu@wd{#1}}\fi}
11.20 \rowfont
Setting font and alignment specification
\rowfont \rowfont uses the control sequences \tabu@celllalign, \tabu@cellleft, \tabu@cellright and
\tabu@cellralign which have been placed on purpose into the user-defined tokens inserted in any preamble by
the array package.
\tabu@celllalign and \tabu@cellralign are used to modify the alignment. If the optional [alignment]
[rev.2.8 release] 2010 2011 FC
parameter of \rowfont is not specified, then those control sequences expand to \@empty.
\tabu@cellleft contains the font-modification information.
Placement of those control sequences into the user-tokens that are inserted in the preamble by the array
package is explained below under the macro \tabu@prepnext@tok.
2019 \newskip \tabu@cellskip
2020 \def\tabu@rowfont{\ifdim \baselineskip=\z@\noalign\fi
2021 {\ifnum0=}\fi \tabu@row@font}
U
b
79 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
2022 \newcommand*\tabu@row@font[2][]{%
2023 \ifnum7=\currentgrouptype
2024 \global\let\tabu@@cellleft \tabu@cellleft
2025 \global\let\tabu@@cellright \tabu@cellright
2026 \global\let\tabu@@celllalign \tabu@celllalign
2027 \global\let\tabu@@cellralign \tabu@cellralign
2028 \global\let\tabu@@rowfontreset\tabu@rowfontreset
2029 \fi
2030 \global\let\tabu@rowfontreset \tabu@rowfont@reset
2031 \expandafter\gdef\expandafter\tabu@cellleft\expandafter{\tabu@cellleft #2}%
2032 \ifcsname tabu@cell@#1\endcsname % row alignment
2033 \csname tabu@cell@#1\endcsname \fi
2034 \ifnum0={\fi}% end of group / noalign group
2035 }% \rowfont
2036 \def\tabu@ifcolorleavevmode #1{\let\color \tabu@leavevmodecolor #1\let\color\tabu@color}%
\tabu@rowfont@reset This macro restores \tabu@celllalign, \tabu@cellleft, \tabu@cellright, and \tabu@cellralign to the
value they had before the expansion of \rowfont.
It expands when a new row is inserted into the tabular or array.
2037 \def\tabu@rowfont@reset{%
2038 \global\let\tabu@rowfontreset \tabu@@rowfontreset
2039 \global\let\tabu@cellleft \tabu@@cellleft
2040 \global\let\tabu@cellright \tabu@@cellright
2041 \global\let\tabu@cellfont \@empty
2042 \global\let\tabu@celllalign \tabu@@celllalign
2043 \global\let\tabu@cellralign \tabu@@cellralign
2044 }% \tabu@@rowfontreset
2045 \let\tabu@rowfontreset \@empty % overwritten \AtBeginDocument if colortbl
When a column is inserted in the tabular preamble (\@preamble), the TEX counter \count@ is equal to
i + 1 (ie.the right token) and the counter \@tempcnta is equal to i (ie.the left token). If the column is
special (ie.@ or !) \@tempcnta is not updated.
Thus, when a new token is prepared by \prepnext@tok:
either: i =\count @ =\@ tempcnta : the token to prepare (ie.\toks < i + 1 >) is the right one of a
[rev.2.8 release] 2010 2011 FC
80 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
expanded again (by \save@decl): if it happens, then again \count@ =\@tempcnta +1 (same
case) but \iftabu@cellright is false and nothing is changed.
else: The token to prepare (which is \toks < i + 1 >=\toks \count@ +1), cannot be the right one of a
normal column: \iftabu@cellright is set to false.
The fact that |\count@ \@tempcnta | > 1 tells us that the previous token \toks < i > is
necessarily the single one of a special @ or ! column. We dont modify this token, as long as
special columns are always inserted as is: \rowcolor has no effect on special columns, nor \rowfont.
Thereafter, the original initialisation sequence occurs: \advance \count@ by\@ne and initialize the token
to prepare (\toks \count@ =\toks < i + 1 >) to an empty one.
2046 \newif \iftabu@cellright
2047 \def\tabu@prepnext@tok{%
2048 \ifnum \count@<\z@ % <first initialisation>
2049 \@tempcnta \@M % <not initialized by array.sty>
2050 \tabu@nbcols\z@
2051 \let\tabu@fornoopORI \@fornoop
2052 \tabu@cellrightfalse
2053 \else
2054 \ifcase \numexpr \count@-\@tempcnta \relax % (case 0): prev. token is left
2055 \advance \tabu@nbcols \@ne
2056 \iftabu@cellright % before-previous token is right and is finished
2057 \tabu@cellrightfalse % <only once>
2058 \tabu@righttok
2059 \fi
2060 \tabu@lefttok
2061 \or % (case 1) previous token is right
2062 \tabu@cellrighttrue \let\@fornoop \tabu@lastnoop
2063 \else % special column: do not change the token
2064 \iftabu@cellright % before-previous token is right
2065 \tabu@cellrightfalse
2066 \tabu@righttok
2067 \fi
2068 \fi % \ifcase
2069 \fi
2070 \tabu@prepnext@tokORI
2071 }% \tabu@prepnext@tok
2072 \long\def\tabu@lastnoop#1\@@#2#3{\tabu@lastn@@p #2\@nextchar \in@\in@@}
2073 \def\tabu@lastn@@p #1\@nextchar #2#3\in@@{%
2074 \ifx \in@#2\else
2075 \let\@fornoop \tabu@fornoopORI
2076 \xdef\tabu@mkpreambuffer{\tabu@nbcols\the\tabu@nbcols \tabu@mkpreambuffer}%
2077 \toks0\expandafter{\expandafter\tabu@everyrowtrue \the\toks0}%
2078 \expandafter\prepnext@tok
2079 \fi
2080 }% \tabu@lastnoop
2081 \def\tabu@righttok{%
2082 \advance \count@ \m@ne
2083 \toks\count@\expandafter {\the\toks\count@ \tabu@cellright \tabu@cellralign}%
[rev.2.8 release] 2010 2011 FC
U
b
81 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
Neutralisation of glues and alignment modification
\tabu@cellleft First initialisation to \@empty.
\tabu@celllalign 2089 \let\tabu@cellleft \@empty
\tabu@cellright 2090 \let\tabu@cellright \@empty
\tabu@cellralign 2091 \tabu@celllalign@def{\tabu@cellleft}%
2092 \let\tabu@cellralign \@empty
\tabu@cell@align
\tabu@cell@l Setup macros to modify the alignment. The skips inserted to make the standard alignment specified in the
\tabu@cell@c tabular preamble are not the same with standard array tabulars and colortbl tabulars, hence the switch
\tabu@cell@r \iftabu@colortbl.
\tabu@cell@j 2101 \def\tabu@cell@l{% force alignment to left
2102 \tabu@cell@align
2103 {\tabu@removehfil \raggedright \tabu@cellleft}% left
2104 {\tabu@flush1\tabu@ignorehfil}% right
2105 \raggedright
2106 }% \tabu@cell@l
2107 \def\tabu@cell@c{% force alignment to center
2108 \tabu@cell@align
2109 {\tabu@removehfil \centering \tabu@flush{.5}\tabu@cellleft}
2110 {\tabu@flush{.5}\tabu@ignorehfil}
2111 \centering
2112 }% \tabu@cell@c
2113 \def\tabu@cell@r{% force alignment to right
2114 \tabu@cell@align
2115 {\tabu@removehfil \raggedleft \tabu@flush1\tabu@cellleft}
2116 \tabu@ignorehfil
2117 \raggedleft
2118 }% \tabu@cell@r
2119 \def\tabu@cell@j{% force justification (for p, m, b columns)
2120 \tabu@cell@align
2121 {\tabu@justify\tabu@cellleft}
2122 {}
2123 \tabu@justify
2124 }% \tabu@cell@j
2125 \def\tabu@justify{%
2126 \leftskip\z@skip \@rightskip\leftskip \rightskip\@rightskip
2127 \parfillskip\@flushglue
[rev.2.8 release] 2010 2011 FC
2128 }% \tabu@justify
2129 %% ragged2e settings
2130 \def\tabu@cell@L{% force alignment to left (ragged2e)
2131 \tabu@cell@align
2132 {\tabu@removehfil \RaggedRight \tabu@cellleft}
2133 {\tabu@flush 1\tabu@ignorehfil}
2134 \RaggedRight
2135 }% \tabu@cell@L
2136 \def\tabu@cell@C{% force alignment to center (ragged2e)
U
b
82 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
2137 \tabu@cell@align
2138 {\tabu@removehfil \Centering \tabu@flush{.5}\tabu@cellleft}
2139 {\tabu@flush{.5}\tabu@ignorehfil}
2140 \Centering
2141 }% \tabu@cell@C
2142 \def\tabu@cell@R{% force alignment to right (ragged2e)
2143 \tabu@cell@align
2144 {\tabu@removehfil \RaggedLeft \tabu@flush 1\tabu@cellleft}
2145 \tabu@ignorehfil
2146 \RaggedLeft
2147 }% \tabu@cell@R
2148 \def\tabu@cell@J{% force justification (ragged2e)
2149 \tabu@cell@align
2150 {\justifying \tabu@cellleft}
2151 {}
2152 \justifying
2153 }% \tabu@cell@J
2154 \def\tabu@flush#1{%
2155 \iftabu@colortbl % colortbl uses \hfill rather than \hfil
2156 \hskip \ifnum13<\currentgrouptype \stretch{#1}%
2157 \else \ifdim#1pt<\p@ \tabu@cellskip
2158 \else \stretch{#1}
2159 \fi\fi \relax
2160 \else % array.sty
2161 \ifnum 13<\currentgrouptype
2162 \hfil \hskip1sp \relax \fi
2163 \fi
2164 }% \tabu@flush
\tabu@removehfil \tabu@removehfil removes (eventually) the infinite stretchable glue inserted before the cell (in the preamble
of \halign) to make the column alignment.
2165 \let\tabu@hfil \hfil
2166 \let\tabu@hfill \hfill
2167 \let\tabu@hskip \hskip
2168 \def\tabu@removehfil{%
2169 \iftabu@colortbl
2170 \unkern \tabu@cellskip =\lastskip
2171 \ifnum\gluestretchorder\tabu@cellskip =\tw@ \hskip-\tabu@cellskip
2172 \else \tabu@cellskip \z@skip
2173 \fi
2174 \else
2175 \ifdim\lastskip=1sp\unskip\fi
2176 \ifnum\gluestretchorder\lastskip =\@ne
2177 \hfilneg % \hfilneg for array.sty but not for colortbl...
2178 \fi
2179 \fi
2180 }% \tabu@removehfil
\tabu@ignorehfil \tabu@ignorehfil removes (eventually) the infinite stretchable glue inserted after the cell (in the preamble
[rev.2.8 release] 2010 2011 FC
83 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
2188 \def\hfill {\let\hfill \tabu@hfill}% (colortbl uses \hfill) pfff...
2189 \def\hskip ####1\relax{\let\hskip \tabu@hskip}}% local
2190 }% \tabu@colortblalignments
\tabu@Hy@ftntext The macros in case hyperref is loaded with the option hyperfootnotes=true:
\tabu@Hy@xfootnote 2199 \long\def\tabu@Hy@ftntext{\tabu@Hy@ftntxt {\the \c@footnote }}
2229 #2%
2230 \fi
2231 }%
2232 }% \tabu@Hy@footnotetext
U
b
84 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
\centering, \raggedright, \raggedleft and \@normalcr
Inside tabu environment, no need to add \arraybackslash after such commands.
2233 \def\tabu@latextwoe {%
2234 \def\tabu@temp##1##2##3{{\toks@\expandafter{##2##3}\xdef##1{\the\toks@}}}
2235 \tabu@temp \tabu@centering \centering \arraybackslash
2236 \tabu@temp \tabu@raggedleft \raggedleft \arraybackslash
2237 \tabu@temp \tabu@raggedright \raggedright \arraybackslash
2238 }% \tabu@latextwoe
2239 \def\tabu@raggedtwoe {%
2240 \def\tabu@temp ##1##2##3{{\toks@\expandafter{##2##3}\xdef##1{\the\toks@}}}
2241 \tabu@temp \tabu@Centering \Centering \arraybackslash
2242 \tabu@temp \tabu@RaggedLeft \RaggedLeft \arraybackslash
2243 \tabu@temp \tabu@RaggedRight \RaggedRight \arraybackslash
2244 \tabu@temp \tabu@justifying \justifying \arraybackslash
2245 }% \tabu@raggedtwoe
2246 \def\tabu@normalcrbackslash{\let\\\@normalcr}
2247 \def\tabu@trivlist{\expandafter\def\expandafter\@trivlist\expandafter{%
2248 \expandafter\tabu@normalcrbackslash \@trivlist}}
\tabu@fcolorbox works exactly like xcolor \fcolorbox but allows the syntax:
\fcolorbox {frame color}{background color}\bgroup...\egroup
suitable for use insed tabular columns. \fcolorbox is \let to \tabu@fcolorbox at the entry inside a tabu
environment.
11.22 Corrections
[rev.2.8 release] 2010 2011 FC
85 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
2266 \iftabu@colortbl
2267 \ifdefined\adl@array % <colortbl + arydshln>
2268 \def\tabu@endarray{%
2269 \adl@endarray \egroup \adl@arrayrestore \CT@end \egroup %<original>
2270 \@arrayright % <FC>
2271 \gdef\@preamble{}}% <FC>
2272 \else % <colortbl / no arydshln>
2273 \def\tabu@endarray{%
2274 \crcr \egroup \egroup %<original>
2275 \@arrayright % <FC>
2276 \gdef\@preamble{}\CT@end}%
2277 \fi
2278 \else
2279 \ifdefined\adl@array % <arydshln / no colortbl>
2280 \def\tabu@endarray{%
2281 \adl@endarray \egroup \adl@arrayrestore \egroup %<original>
2282 \@arrayright % <FC>
2283 \gdef\@preamble{}}% <FC>
2284 \else % <no arydshln / no colotbl + \@arrayright missing>
2285 \PackageWarning{tabu}
2286 {\string\@arrayright\space is missing from the
2287 \MessageBreak definition of \string\endarray.
2288 \MessageBreak Comptability with delarray.sty is broken.}%
2289 \fi\fi
2290 }% \tabu@fix@arrayright
arydshln @ columns
2291 \def\tabu@adl@xarraydashrule #1#2#3{%
2292 \ifnum\@lastchclass=\adl@class@start\else
2293 \ifnum\@lastchclass=\@ne\else
2294 \ifnum\@lastchclass=5 \else % <FC> @-arg (class 5) and !-arg (class 1)
2295 \adl@leftrulefalse \fi\fi % must be treated the same
2296 \fi
2297 \ifadl@zwvrule\else \ifadl@inactive\else
2298 \@addtopreamble{\vrule\@width\arrayrulewidth
2299 \@height\z@ \@depth\z@}\fi \fi
2300 \ifadl@leftrule
2301 \@addtopreamble{\adl@vlineL{\CT@arc@}{\adl@dashgapcolor}%
2302 {\number#1}#3}%
2303 \else \@addtopreamble{\adl@vlineR{\CT@arc@}{\adl@dashgapcolor}%
2304 {\number#2}#3}
2305 \fi
2306 }% \tabu@adl@xarraydashrule
\fi
\egroup \adl@colhtdp \box\adl@box \hfil
The \vrule inserted is exactly what package array calls: \@finalstrut \@arstrutbox.
However, just like in array.sty, this array-strut should be inserted inconditionnally, and \ifhmode applies
only to \nobreak (misplaced \fi in arydshln definition).
Finally, arydshln is not compatible with colors in columns, such that: >{\color {red}}p3in, Unless colortbl
is also loaded, the color group is missing.
U
b
86 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
Fixed inside tabu environment.
2307 \def\tabu@adl@act@endpbox {%
2308 \unskip \ifhmode \nobreak \fi \@finalstrut \@arstrutbox
2309 \egroup \egroup
2310 \adl@colhtdp \box\adl@box \hfil
2311 }% \tabu@adl@act@endpbox
2312 \def\tabu@adl@fix {%
2313 \let\adl@xarraydashrule \tabu@adl@xarraydashrule % <fix> arydshln
2314 \let\adl@act@endpbox \tabu@adl@act@endpbox % <fix> arydshln
2315 \let\adl@act@@endpbox \tabu@adl@act@endpbox % <fix> arydshln
2316 \let\@preamerror \@preamerr % <fix> arydshln
2317 }% \tabu@adl@fix
linegoal (package option) The linegoal package option only sets \tabudefaulttarget to be equal to \linegoal. The required
package linegoal is loaded.
2328 \DeclareOption{linegoal}{%
2329 \AtEndOfPackage{%
2330 \RequirePackage{linegoal}[2010/12/07]%
2331 \let\tabudefaulttarget \linegoal% \linegoal is \linewidth if not pdfTeX
2332 }}
\scantokens (package option) The scantokens package option makes tabu equal to tabu .
2333 \DeclareOption{scantokens}{\tabuscantokenstrue}
2336 {\afterassignment\tabu@tracing\count@}
2337 {\afterassignment\tabu@tracing\count@1\relax}}
2338 \def\tabu@tracing{\expandafter\endgroup
2339 \expandafter\tabu@tr@cing \the\count@ \relax
2340 }% \tabu@tracing
2341 \def\tabu@tr@cing #1\relax {%
2342 \ifnum#1>\thr@@ \let\tabu@tracinglines\message
2343 \else \let\tabu@tracinglines\@gobble
2344 \fi
U
2345 \ifnum#1>\tw@ \let\tabu@DBG \tabu@@DBG
b
87 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
2346 \def\tabu@mkarstrut {\tabu@DBG@arstrut}%
2347 \tabustrutrule 1.5\p@
2348 \else \let\tabu@DBG \@gobble
2349 \def\tabu@mkarstrut {\tabu@arstrut}%
2350 \tabustrutrule \z@
2351 \fi
2352 \ifnum#1>\@ne \let\tabu@debug \message
2353 \else \let\tabu@debug \@gobble
2354 \fi
2355 \ifnum#1>\z@
2356 \let\tabu@message \message
2357 \let\tabu@tracing@save \tabu@message@save
2358 \let\tabu@starttimer \tabu@pdftimer
2359 \else
2360 \let\tabu@message \@gobble
2361 \let\tabu@tracing@save \@gobble
2362 \let\tabu@starttimer \relax
2363 \fi
2364 }% \tabu@tr@cing
2365 \AtBeginDocument{\tabu@AtBeginDocument}
2366 \def\tabu@AtBeginDocument{\let\tabu@AtBeginDocument \@undefined
2367 \ifdefined\arrayrulecolor \tabu@colortbltrue % <colortbl>
2368 \tabu@colortblalignments % different glues are used
2369 \else \tabu@colortblfalse \fi
2370 \ifdefined\CT@arc@ \else \let\CT@arc@ \relax \fi
2371 \ifdefined\CT@drsc@\else \let\CT@drsc@ \relax \fi
2372 \let\tabu@arc@L \CT@arc@ \let\tabu@drsc@L \CT@drsc@
2373 \ifodd 1\ifcsname siunitx_table_collect_begin:Nn\endcsname % <siunitx: ok>
2374 \expandafter\ifx
2375 \csname siunitx_table_collect_begin:Nn\endcsname\relax 0\fi\fi\relax
2376 \tabu@siunitxtrue
2377 \else \let\tabu@maybesiunitx \@firstofone % <not siunitx: setup>
[rev.2.8 release] 2010 2011 FC
88 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
2387 \csname\ifcsname ifHy@hyperfootnotes\endcsname % <hyperfootnotes>
2388 ifHy@hyperfootnotes\else iffalse\fi\endcsname
2389 \let\tabu@footnotetext \tabu@Hy@ftntext
2390 \let\tabu@xfootnote \tabu@Hy@xfootnote \fi
2391 \ifdefined\FV@DefineCheckEnd% <fancyvrb>
2392 \tabu@fancyvrb \fi
2393 \ifdefined\color % <color / xcolor>
2394 \let\tabu@color \color
2395 \def\tabu@leavevmodecolor ##1{%
2396 \def\tabu@leavevmodecolor {\leavevmode ##1}%
2397 }\expandafter\tabu@leavevmodecolor\expandafter{\color}%
2398 \else
2399 \let\tabu@color \tabu@nocolor
2400 \let\tabu@leavevmodecolor \@firstofone \fi
2401 \tabu@latextwoe
2402 \ifdefined\@raggedtwoe@everyselectfont % <ragged2e>
2403 \tabu@raggedtwoe
2404 \else
2405 \let\tabu@cell@L \tabu@cell@l
2406 \let\tabu@cell@R \tabu@cell@r
2407 \let\tabu@cell@C \tabu@cell@c
2408 \let\tabu@cell@J \tabu@cell@j \fi
2409 \expandafter\in@ \expandafter\@arrayright \expandafter{\endarray}%
2410 \ifin@ \let\tabu@endarray \endarray
2411 \else \tabu@fix@arrayright \fi% <fix for colortbl & arydshln (delarray)>
2412 \everyrow{}%
2413 }% \tabu@AtBeginDocument
2414 \def\tabu@warn@cellspace{%
2415 \PackageWarning{tabu}{%
2416 Package cellspace has some limitations
2417 \MessageBreak And redefines some macros of array.sty.
2418 \MessageBreak Please use \string\tabulinesep\space to control
2419 \MessageBreak vertical spacing of lines inside tabu environnement}%
2420 }% \tabu@warn@cellspace
U
2442 \newtabulinestyle {=\maxdimen}% creates the factory settings \tabu@linestyle@
b
89 / 101
b Tecnical notice and implementation Flexible LATEX tabulars
U
2443 \tabulinestyle{}
2444 \taburowcolors{}
2445 \let\tabudefaulttarget \linewidth
2446 \ProcessOptions* % \ProcessOptions* is quicker !
2447 h/packagei
[rev.2.8 release] 2010 2011 FC
U
b
90 / 101
b index Flexible LATEX tabulars
U
12 References
[1] A new implementation of LATEXs tabular and array environments by Frank Mittelbach
2008/09/09 v2.4c Tabular extension package (FMi)
CTAN:help/Catalogue/entries/array.html
[2] The varwidth package by Donald Arseneau
2009/03/30 ver 0.92 Variable-width minipages
CTAN:help/Catalogue/entries/varwidth.html
[3] The enumitem-zref package by FC
2011/02/18 ver 1.8 Extended references for enumitem pkg
CTAN:help/Catalogue/entries/enumitem-zref.html
13 History
[2011/02/26 v2.8]
Bug in the starred version (with \scantokens) of the longtabu environment.
[2011/02/25 v2.7]
Automatic \par after the end of the tabu environment used with its default target is
removed in case of tabu spread: this was a bug.
Some \ignorespaces were missing (in \everyrow, \taburulecolor, \taburowcolors and
\tabulinestyle).
[2011/02/24 v2.6]
\savetabu now also saves \tabulinesep (ie.\abovetabulinesep and \belowtabulinesep)
Bug fixed for custom-environments when nested.
\taburulecolor works even if colortbl is not loaded for the tabu environment.
This is now the same for the longtabu environment.
[2011/02/19 v2.5]
Bug fixed for \pdfelapsedtime when compilation without pdfTEX.
Modification of \@finalstrut (null-rule added) to avoid problems with \columncolor.
[2011/02/17 v2.4]
Documentation revisited
[2011/02/13 v2.3]
Fixed two bugs for nested tabu environment: when using \rowfont and when tabu is
nested inside longtabu
In particular, outside of the tabu environment, absolutely none of the macros of array.sty,
(and obviously none of LATEX) is modified.
[rev.2.8 release] 2010 2011 FC
The process has been completely reinvented: tabu follows a path along different modes (or
strategies) measuring natural width of cells, fixing X column widths, measuring vertical
length of rows and then printing the final tabular. The process is optimized, especially in
the case of nested tabu environments: a tabular is not built twice for measuring purpose...
As a result, many new features are now possible... vertical leaders (dashed lines), dynamic
vertical spacing adjustment, and hopefully still more in a next release.
tabu now systematically collects the environment body. But with \scantokens, it is possible
to insert verbatim material inside the columns: use tabu* instead of tabu, for the outer
most tabular.
U
b
91 / 101
b index Flexible LATEX tabulars
U New: \firsthline and \lasthline can draw multiple lines, and there is an option to set
\extratabsurround instantly, and locally.
New: \taburulecolor with a good behaviour with groupings (like \everyrow)
Modification: \tabulinestyle sets the line style for the tabu, \newtabulinestyle defines a
new line style.
U
[2011/01/19 v2.1]
Vertical spacing had a bug with longtabu and paragraph columns.
Fixed.
New: \everyrow.
Fix a bug of \rowfont when using siunitx S columns.
Some code optimisation.
To do (if possible): a syntax X[6mc]S[...] to embed siunitx S column inside tabu and
longtabu X columns...
[2011/01/18 v2.0]
Vertical spacing of lines implemented ! See \tabulinesep and \extrarowsep.
\tabulinestyle : user defined line style can now be used inside the optional argument of the
|[...] preamble token.
|[...] is now allowed in \multicolumn preamble inside tabu environment.
Bug fixed inside \tabu@prepnexttok (again !!! - a difficult case !)
Incompatibility of package cellspace with tabu spread and tabu with negativ coefficients for
X columns with has been lifted.
However, as said in the documentation of package cellspace, S column modifier does not
work in the case of nested tabulars.
The S column modifier becomes C when the package siunitx is loaded (see siunitx
documentation).
Moreover, cellspace does not work with color or xcolor and paragraph column types !!
Finally, cellspace redefines globally \@startpbox and \@endpbox and is therefore not
fully compatible with array.sty and therefore with b .
U
For all those reasons, b displays a warning to discourage the use of cellspace with the
U
tabu environment.
[2011/01/15 v1.9]
Bug in \savetabu when used inside longtabu...
Bug when tabu with X column is nested inside lontabu.
Documentation (\rowfont was missing in the summary).
[2010/12/28 v1.8]
\tracingtabu / debugshow package option:
reporting of the time elapsed during trials (if \pdfelapsedtime and thus pdfTEX is available)
[rev.2.8 release] 2010 2011 FC
92 / 101
b index Flexible LATEX tabulars
U [2010/12/18 v1.7]
Code optimisation
Modification in the columns rewritting process (bug with some new column types defined by
the user).
[2010/12/07 v1.5]
Implementation of negativ width coefficients for X columns (cf. tabu X columns Mastering
horizontal space point 2).
Columns natural widths computation (for tabu spread with X columns and negativ
coefficients) is based on the code of the varwidth package by Donald Arseneau.
longtabu is now provided, based on the longtable package by David Carlisle.
longtabu can be used just like tabu.
Vertical lines can be used whatever the catcode of | is.
\savetabu reports saved informations in the .log (debugshow option).
\savetabu... \usetabu now restores the \halign preamble rather than the tabu preamble!
\preamble can be use in the tabu preamble to restore a tabu preamble.
\tabucline is more robust with special preambles containing > or < tokens.
\tabucline now takes care of \arrayrulecolor (package colortbl).
enumitem-zref package has been added to the documentation (see the link point 1)
Optimisation of some parts of the code.
[2010/11/22 v1.4]
Compatibility improvement with linegoal for the syntax:
\begin {tabu} to\linegoal {...}
Hyper footnotes now work correctly.
Fix a bug when using colored vertical lines in tabu in math mode.
Fix a bug with vertical lines and colortbl \arrayrulecolor specification.
Fix a compatibility bug with arydshln: when nesting a tabular that use vertical dashed lines
(arydshln) inside tabu spread with X columns.
[2010/11/18 v1.3]
Fix a bug that may appear in \tabucline depending on the preamble due to arbitrary
\countdef.
Improvement in the use of \everycr: no \global stuff. Thus bug fixed when nesting tabu
inside AMS-align environment for example. Same issue with \rowfont which now works
without global modification of \everycr.
No phantom line is added to tabu but a command \tabuphantomline is provided for this
purpose (required with \multicolumn in some cases).
Improvement on vertical alignment.
To do: an example file to test a wide range of possibilities...
[rev.2.8 release] 2010 2011 FC
Documentation.
U
b
93 / 101
b index Flexible LATEX tabulars
U [2010/11/15 v1.2]
Improvement in parameters parsing for optional parameters (| and \tabucline).
Modification / optimization in \tabu@prepnext@tok.
Modification of \tabucline to get better results with m columns (X[m]) and also when
\minrowclearance > 0 (package colortbl).
[2010/10/28 v1.1]
First version.
14 Index
Numbers written in italic refer to the page where the corresponding entry is described; numbers
underlined refer to the code line of the definition; plain numbers refer to the code lines where the
entry is used.
1467, 1472, 1475, 1615, 1618, 1619, 1627, \c@taburow@save . . . . . . . . . . . . . . . 685, 721
1630, 1632, 1720, 1732, 1739, 1742, 1744 \catcode 10, 11, 80, 92, 446, 447, 448, 449, 1929
\@tempdimc 34, 37, 1385, 1387, 1391, 1393, \Centering . . . . . . . 630, 924, 2138, 2140, 2241
1396, 1439, 1440, 1625, 1719, 1739, 1745 \centering . . . 628, 920, 924, 2109, 2111, 2235
\@temptokena 746, 751, 767, 857, 861, 1017, \cl@@ckpt . . . . . . . . . . . . . . . . . . . . . . . 1139
1020, 1064, 1849, 1865, 1869, 1900, 1903 \cleaders . . . . . . . . . . . . . . . . . . . . . . . . 1802
\@thefnmark . . . . . . . . . . . . . . . . 2203, 2212 \cline . . . . . . . . . . . . . . . . . . 1702, 1707, 1712
\@trivlist . . . . . . . . . . . . . . . . . . . 2247, 2248 \color . . . . . . . 90, 122, 299, 303, 312, 320,
\@whilesw . . . . . . . . . . . . . . . . . . . . . . . 1357 507, 624, 1128, 1501, 2036, 2393, 2394, 2397
\@xfootnote . . . . . . . . . . . . . . 628, 1127, 2198 \color@ . . . . . . . . . . . . . . . . . . . . . . . . . 488
U
\@xfootnotetext . . . . . . . . . . . . . . . . . . . 627 \color@b@x . . . . . . . . . . . . . . . . . . . . . . 633
b
94 / 101
b index Flexible LATEX tabulars
95 / 101
b index Flexible LATEX tabulars
96 / 101
b index Flexible LATEX tabulars
97 / 101
b index Flexible LATEX tabulars
\tabu@lastline . . . . . . . . . . . . . . . . 622, 1676 1202, 1383, 1385, 1437, 1565, 1566, 2433
\tabu@lastn@@p . . . . . . . . . . . . . . 2072, 2073 \tabu@naturalXmax@save . . . . . . . . 688, 718
\tabu@lastnoop . . . . . . . . . . 2062, 2072, 2080 \tabu@naturalXmin . . . . . . . . . . . . . . 687,
\tabu@lastspace . . . . . . . . . . . . . . . . . . 88, 89 719, 1202, 1384, 1385, 1438, 1567, 1568, 2432
\tabu@lasttry . . . . . . . . . . . . . . . . . . . . . 1132 \tabu@naturalXmin@save . . . . . . . . . 687, 719
\tabu@latextwoe . . . . . . . . . 2233, 2238, 2401 \tabu@nbcols . . 21, 1238, 1507, 1665, 1836,
\tabu@LEADERS . . . . . . . . . . . . . . 501, 506 1840, 1841, 1842, 1974, 2050, 2055, 2076
\tabu@leaders . 499, 500, 503, 819, 1810, 1813 \tabu@NC@list . . . . . . . . . . . . . . . . . . . .
\tabu@leaders@G . . . . . . . . . . . . . . . 500, 522 . . 613, 838, 1009, 1010, 1024, 1079, 1091
\tabu@leadersstyle . . . . . . . . . . . . . . 434, 499 \tabu@negcoeffalse . . . . . . . . . . . . . . 544, 555
U
\tabu@leads . . . . . 511, 518, 527, 531, 532, 535 \tabu@negcoeftrue . . . . . . . . . . . . . 961, 1150
b
98 / 101
b index Flexible LATEX tabulars
U \tabu@nested 21, 350, 353, 354, 355, 364, 365, \tabu@rewritemulticolumn . . . . . . . . . . . 833
366, 367, 370, 371, 372, 604, 722, 724, \tabu@rewritevline . . . . . . . . . . 795, 796, 799
1039, 1040, 1050, 1099, 1185, 1186, 1270, \tabu@rewriteX . . . . . . . . . . . . 852, 870, 984
1283, 1302, 1414, 1422, 1445, 1490, 1573, \tabu@rewriteX@Ss . . . . . . . . . 855, 857, 866
1574, 1641, 1642, 1643, 1644, 1996, 2003 \tabu@rewriteXrestore . . . . . . . . . . . 882, 984
\tabu@nestedmeasure . . . . . . . 583, 593, 601 \tabu@rewritten . . . 797, 806, 807, 853, 865,
\tabu@new@columntype . . 769, 774, 777, 788 883, 888, 890, 942, 944, 960, 966, 968, 970
\tabu@newcolumntype 768, 833, 995, 1019, 1022 \tabu@Rextra . . . . . . . . . . . . . 188, 189, 190
\tabu@newlinestyle . . . . . . . . . 264, 266, 271 \tabu@righttok . . . . . . 2058, 2066, 2081, 2085
\tabu@nexthlineAZ . . . . . . . . . . . . . . . . 1695 \tabu@Rlinesep . . . . . . . . . . . . 219, 220, 221
\tabu@nocolor . . . . . . . . 153, 507, 1128, 2399 \tabu@row@font . . . . . . . . . . . . . . 2021, 2022
\tabu@noeverycr . . . . . . . . . . . . . 1241, 1243 \tabu@rowc@lors . . . . . . . . . . . . . . . 328, 329
\tabu@nohfil . . . . . . . . 2181, 2182, 2184, 2186 \tabu@rowcolors . . . . . . . . . . . 327, 328, 336
\tabu@nolongtabu . . . . . . . . . . . . . 558, 2385 \tabu@rowcolorseries . . . . . . . . 335, 337, 378
\tabu@normalcrbackslash . . . . . . . 2246, 2248 \tabu@rowcolorserieserror . . . . 343, 380, 383
\tabu@norowcolor . . . . . . . . . . . . . 153, 1128 \tabu@rowfont . . . . . . . . . . . . . . . . 632, 2020
\tabu@nosiunitx . . . . . . . . . . . 853, 856, 2378 \tabu@rowfont@reset . . . . . . . . . . 2030, 2037
\tabu@nowrite . . . . . . . . . . . . . . . . 142, 1125 \tabu@rowfontreset . . . . . . . . . . . . . . 248,
\tabu@noxfootnote . . . . . . . . . . . . . . . . 152 681, 683, 715, 2028, 2030, 2038, 2045, 2434
\tabu@noxfootnotes . . . . . . . . . . . . . . . . 142 \tabu@rowfontreset@save . . . . . . . . . 681, 715
\tabu@off . 30, 403, 421, 423, 424, 425, 436, 489 \tabu@rule@arc@ . . . . . . . . . . . 308, 309, 326
\tabu@offiii . . . . . . . . . . . . . . . . . . . . . . 446 \tabu@rule@drsc@ . . . 290, 291, 295, 296, 307
\tabu@offxiii . . . . . . . . . . . . . . 468, 471, 477 \tabu@rulearc . . . . . . . . . . . . . 287, 306, 308
\tabu@ofxiii . . . . . . . . . . . . . . . . . . . . . . 446 \tabu@rulecolor . . . . . . . . . . . . 283, 284, 288
\tabu@on . . . . 30, 403, 421, 422, 423, 425, 435 \tabu@ruledrsc . . . . . . . . . . . . . . . . 285, 289
\tabu@onxiii . . . . . . . . . . . . . . . . . . . . . 446 \tabu@ruledrsc@ . . . . . . . . . . . . . . . 294, 295
\tabu@oXIII . . . . . . . . . . . . . . . . . . . 411, 447 \tabu@rulesstyle . . . . . . . . . . . 437, 499, 1501
\tabu@oxiii . . . . . . . . . . . . . . . . . . . 447, 450 \tabu@sanitizearg 93, 267, 344, 345, 392, 1948
\tabu@pdftimer . . . . . . . . . . 2358, 2438, 2439 \tabu@save . . . . . . . . . . . . . 1953, 1957, 1984
\tabu@pream . . . . . . . . . . . . . . . . . 997, 1077 \tabu@save@decl . . . . . . . . . . . . . . . . . . 134
\tabu@preamble . . . . . . 1966, 1981, 1999, 2000 \tabu@savecounters . . . . . . . . . . . . . . . . .
\tabu@prepnext@tok . . . . . . . . . . . 635, 2046 . 1116, 1137, 1140, 1217, 1218, 1226, 1227
\tabu@prepnext@tokORI . . . . . . . . 635, 2070 \tabu@saved@ . . . . . . . . . . . . . . . . 751, 1958
\tabu@prev . . . . . . . . . . . . . 1017, 1023, 1026 \tabu@savedecl . . . . . . . . 136, 138, 836, 1015
\tabu@printdecimal . . . . . . . 1896, 1899, 1905 \tabu@savedparams . . . . . . . . . . . . . . . . .
\tabu@private@columntype . . . 779, 786, 789 . . . 733, 746, 757, 1504, 1965, 1968, 1976
\tabu@privatecolumns . . . 787, 790, 837, 1016 \tabu@savedpream . . . . . . . . . . . . . . . . . .
\tabu@privatecolumntype . . . . . . . . . . . . . . . . . . 590, 1503, 1962, 1965, 1969, 1977
. . . . . . . . . . 778, 795, 799, 852, 980, 988 \tabu@savedpreamble . . . . . 1081, 1092, 1963
\tabu@pt . . . . . . . . . . . 1446, 1448, 1479, 1480 \tabu@saveerr . . . . . 981, 983, 989, 991, 2013
\tabu@pushbegins . . . . . . . . . . . . 1157, 1177 \tabu@savels . . . . . . . . . . 816, 828, 839, 1000
\tabu@quick . . . . . . . . 1583, 1586, 1588, 1596 \tabu@savewarn . . . . . . . . . . 1949, 1950, 2013
\tabu@quickend . . . . . . . . . . . . . . 1189, 1287 \tabu@savewd . . . . . . . . . . . 1960, 1961, 2012
\tabu@quickrule . . . . . . . . . . . . 598, 602, 1288 \tabu@scandecimal . . . . . . . . . . . . . . . . .
\tabu@RaggedLeft . . . . . . . . . . . . . 631, 2242 . . . . . 1851, 1853, 1854, 1861, 1866, 1869
\tabu@raggedleft . . . . . . . . . . . . . . 629, 2236 \tabu@select . . . . . . . . . . . . 1087, 1096, 1098
\tabu@RaggedRight . . . . . . . . . . . . 631, 2243 \tabu@setcleanup . . . . . . . . . . . . . . . 617, 654
\tabu@raggedright . . . . . . . . . . . . . 629, 2237 \tabu@seteverycr . . . . . . . . . . . . . . . . . . .
\tabu@raggedtwoe . . . . . . . . 2239, 2245, 2403 1103, 1108, 1112, 1216, 1225, 1239, 1282
\tabu@rc@ . . . . . . . . . . 249, 339, 340, 348, \tabu@setextra . . . . . 169, 171, 176, 178, 180
356, 361, 362, 368, 373, 374, 379, 704, 762 \tabu@setextrasep . . . . . . . . . . 173, 185, 187
\tabu@rc@G 340, 374, 669, 670, 703, 704, 755, 2425 \tabu@setlinesep . . . . . . . . . . . 204, 216, 218
\tabu@rc@Gsave . . . . . . . . . . . . . . . 669, 703 \tabu@setreset . . . . . . . . . . . . . . . . . 617, 732
\tabu@rc@L . . . . . . . . 339, 362, 670, 755, 762 \tabu@sets@p . . . . . . . . . . . . . . 207, 208, 215
[rev.2.8 release] 2010 2011 FC
99 / 101
b index Flexible LATEX tabulars
100 / 101
b index Flexible LATEX tabulars
U
b
101 / 101