diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/tabu |
Initial commit
Diffstat (limited to 'macros/latex/contrib/tabu')
-rw-r--r-- | macros/latex/contrib/tabu/README.md | 84 | ||||
-rw-r--r-- | macros/latex/contrib/tabu/tabu.dtx | 7839 | ||||
-rw-r--r-- | macros/latex/contrib/tabu/tabu.pdf | bin | 0 -> 2526818 bytes | |||
-rw-r--r-- | macros/latex/contrib/tabu/tabu.sty | 2602 |
4 files changed, 10525 insertions, 0 deletions
diff --git a/macros/latex/contrib/tabu/README.md b/macros/latex/contrib/tabu/README.md new file mode 100644 index 0000000000..61a3eb8eeb --- /dev/null +++ b/macros/latex/contrib/tabu/README.md @@ -0,0 +1,84 @@ +# tabu + + +## Original Tabu README + + +## tabu - Flexible LaTeX tabulars + + +tabu provides a single environment: tabu +designed to make all kind of tabulars provided that they do +not split accross pages. + +tabu is based on array.sty and requires no other package. +tabu does not modify array.sty nor the classes of tokens. + +Starting from version 1.5, longtabu is provided: based on +longtable, longtabu allows tabulars to stretch out on +several pages. + +tabu can be used in place of tabular, tabular* and tabularx +X columns in tabu can be specified with a width coefficient +the alignement (l,r,c,j) the column type (p,m,b) or even $. + +tabu also works in math mode and its name remains tabu. +tabu can contain any type of tabular, array, tabularx +tabu can be put inside tabular, array, tabularx, tabular* + +\begin{tabu} is like tabular if the preamble has no X column +\begin{tabu} to <dimen> specifies the target width +\begin{tabu} spread <dimen> enlarge the natural width + +tabu with X columns has a default target if not specified +(usefull for nested tabus + compatibility with \linegoal) + +tabu provides facilities to change the font and the alignment +in one row (\rowfont), save and restore the preamble and the +tabular parameters (\savetabu, \usetabu, \preamble). + +tabu provides other facilities to align numbers in X columns +draw lines with color, dashed or even leaders. Those facilities +are provided for convenience: they work as long as the tabu +preamble does not contain "too special tokens". + +tabu has been tested successfully with many packages related +to tabulars, cells, alignment... + +- - - - + +## Emergency updates to the LaTeX tabu package + +The original author of tabu appears out of contact, and tabu had not +been updated for several years, finally becoming unusable in 2019 as +updates to other packages mean some of its patched code did not work +as intended. + +The package is not being actively maintained however any major required +fixes may be reported to the https://github.com/tabu-fixed/tabu repository +and volunteers there (currently members of the LaTeX3 Team) will attempt +to update the package with any fixes required. + + + + +## Issues from Stackexchange + +### Fixed in release 2.9 + +https://tex.stackexchange.com/questions/469282/xcolor-breaking-and-align-environments-inside-tabu + +https://tex.stackexchange.com/questions/468948/longtabu-and-color-compatibility + +https://tex.stackexchange.com/questions/466147/tabu-very-recently-stopped-working-with-color-xcolor-or-with-fancyvrb/466261 + +https://tex.stackexchange.com/questions/87144/incompatibility-between-verbatim-and-tabu-danger-of-using-scantokens-in-a-pac + +https://tex.stackexchange.com/questions/430973/tabu-m-column-vertical-alignment-not-working-after-package-updates +(Note that this is only a temporary fix reverting the change in array package m column implementation. +A more complete fix would be to adapt tabu code to the new array.) + + +### Not yet handled + +https://tex.stackexchange.com/questions/201510/what-is-the-difference-between-and-linebreak-in-cfoot
\ No newline at end of file diff --git a/macros/latex/contrib/tabu/tabu.dtx b/macros/latex/contrib/tabu/tabu.dtx new file mode 100644 index 0000000000..284698fcb7 --- /dev/null +++ b/macros/latex/contrib/tabu/tabu.dtx @@ -0,0 +1,7839 @@ +% \iffalse meta-comment +% tabu : 2011/02/26 v2.8 - tabu: flexible LaTeX tabulars] +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either +% version 1.3 of this license or (at your option) any later +% version. The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% +% This work consists of the main source file tabu.dtx +% and the derived files +% tabu.sty, tabu.pdf, tabu.ins +% +% Unpacking: +% (a) If tabu.ins is present: +% etex tabu.ins +% (b) Without tabu.ins: +% etex tabu.dtx +% (c) If you insist on using LaTeX +% latex \let\install=y\input{tabu.dtx} +% (quote the arguments according to the demands of your shell) +% +% Documentation: +% (pdf)latex tabu.dtx +% lppl copyright 2010-2011 by FC <florent.chervet@free.fr> +%<*ignore> +\begingroup + \def\x{LaTeX2e}% +\expandafter\endgroup +\ifcase 0\ifx\install y1\fi\expandafter + \ifx\csname processbatchFile\endcsname\relax\else1\fi + \ifx\fmtname\x\else 1\fi\relax +\else\csname fi\endcsname +%</ignore> +%<*install> +\input docstrip.tex +\Msg{************************************************************************} +\Msg{* Installation} +\Msg{* Package: 2011/02/26 v2.8 - tabu: Flexible LaTeX tabulars} +\Msg{************************************************************************} + +\keepsilent +\askforoverwritefalse + +\let\MetaPrefix \relax +\preamble + +This is a generated file. +Copyright (FC) 2010-2011 - lppl + +tabu : 2011/02/26 v2.8 - tabu : Flexible LaTeX tabulars + +********************************************************************************************** +\string\begin{tabu} { preamble } => default target: \string\linewidth or \string\linegoal +\string\begin{tabu} to <dimen>{ preamble } => target specified +\string\begin{tabu} spread <dimen>{ preamble } => target relative to the ``natural width'' + + tabu works in text and in math modes. + + X columns: automatic width ajustment + horizontal and vertical alignment + \string\begin{tabu} { X[4c] X[1c] X[-2ml] } + + Horizontal lines and / or leaders: + \string\hline\string\hline => double horizontal line + \string\firsthline\string\hline => for nested tabulars + \string\lasthline\string\hline => for nested tabulars + \string\tabucline[line spec]{column-column} => ``funny'' lines (dash/leader) + Automatic lines / leaders : + \string\everyrow{\string\hline\string\hline} + + Vertical lines and / or leaders: + \string\begin{tabu} { |[3pt red] X[4c] X[1c] X[-2ml] |[3pt blue] } + \string\begin{tabu} { |[3pt red] X[4c] X[1c] X[-2ml] |[3pt on 2pt off 4pt blue] } + + Fixed vertical spacing adjustment: + \string\extrarowheight=<dimen> \string\extrarowdepth=<dimen> + or: \string\extrarowsep=<dimen> => may be prefixed by \string\global + + Dynamic vertical spacing adjustment: + \string\abovetabulinesep=<dimen> \string\belowtabulinesep=<dimen> + or: \string\tabulinesep=<dimen> => may be prefixed by \string\global + + delarray.sty shortcuts: in math and text modes + \string\begin{tabu} .... \string\({ preamble }\string\) + + Algorithms reports: + \string\tracingtabu=1 \string\tracingtabu=2 + +********************************************************************************************** + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either +version 1.3 of this license or (at your option) any later +version. The latest version of this license is in + http://www.latex-project.org/lppl.txt + +This work consists of the main source file tabu.dtx +and the derived files + tabu.sty, tabu.pdf, tabu.ins + +tabu : Flexible LaTeX tabulars +lppl copyright 2010-2011 by FC <florent.chervet@free.fr> + +\endpreamble +\let\MetaPrefix \DoubleperCent + +{ +\catcode164=9 +\generate{% + \file{tabu.ins}{\from{tabu.dtx}{install}}% + \file{tabu.sty}{\from{tabu.dtx}{package}}% +} +} + +\askforoverwritefalse +\generate{% + \file{tabu.drv}{\from{tabu.dtx}{driver}}% +} + +\obeyspaces +\Msg{************************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* file into a directory searched by TeX:} +\Msg{*} +\Msg{* tabu.sty} +\Msg{*} +\Msg{* To produce the documentation run the file `tabu.dtx'} +\Msg{* through LaTeX.} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*} +\Msg{************************************************************************} + +\endbatchfile +%</install> +%<*ignore> +\fi +%</ignore> +%<*driver> +\let\microtypeYN=y +\edef\thisfile{\jobname} +\def\thisinfo{Flexible \LaTeX{} tabulars (\FC)} +\def\thisdate{2011/02/26} +\def\thisversion{2.8} +\def\CTANbaseurl{http://www.ctan.org/tex-archive/macros/latex} +\def\CTANdisplay{CTAN:macros/latex} +\makeatletter\protected\def\CTANhref{\@ifstar\CTANhrefstar\CTANhrefnost}\makeatother +\newcommand*\CTANhrefstar[3][/contrib/]{\href{\CTANbaseurl#1#2}{#3}} +\newcommand*\CTANhrefnost[2][/contrib/]{\href{\CTANbaseurl#1#2}{\nolinkurl{\CTANdisplay#1#2}}} +\let\loadclass\LoadClass +\def\LoadClass#1{\loadclass[abstracton]{scrartcl}\let\scrmaketitle\maketitle\AtEndOfClass{\let\maketitle\scrmaketitle}} +{\makeatletter{\endlinechar`\^^J\obeyspaces + \gdef\ErrorUpdate#1=#2,{\@ifpackagelater{#1}{#2}{}{\let\CheckDate\errmessage\toks@\expandafter{\the\toks@ + \thisfile-documentation: updates required ! + package #1 must be later than #2 + to compile this documentation.}}}}% + \gdef\CheckDate#1{{\let\CheckDate\relax\toks@{}\@for\x:=\thisfile=\thisdate,#1\do{\expandafter\ErrorUpdate\x,}\CheckDate\expandafter{\the\toks@}}}} +\AtBeginDocument{\CheckDate{interfaces=2011/02/12,linegoal=2011/02/25}} +\PassOptionsToPackage{svgnames,table}{xcolor} +\PassOptionsToPackage{hyperfootnotes}{hyperref} +\documentclass[a4paper,oneside]{ltxdoc} +\AtBeginDocument{\tracingnesting=1 \DeleteShortVerb{\|}\catcode164=14} +\usepackage[latin1]{inputenc} +\usepackage[T1]{fontenc} +\usepackage{ltxnew,etoolbox,geometry,graphicx,xcolor,needspace,ragged2e} % general tools +\usepackage{lmodern,bbding,hologo,relsize,moresize,manfnt,pifont,upgreek} % fonts +\usepackage[official]{eurosym} % font +\ifx y\microtypeYN % + \usepackage[expansion=all,stretch=20,shrink=60]{microtype}\fi % font (microtype) +\usepackage{xspace,tocloft,titlesec,fancyhdr,lastpage,enumitem,marginnote} % paragraphs & pages management +\usepackage{holtxdoc,bookmark,hypbmsec,enumitem-zref} % hyper-links +\usepackage{array,delarray,longtable,colortbl,multirow,makecell,booktabs} % tabulars +\usepackage{tabularx}\tracingtabularx % tabularx +\usepackage{amsmath,amsopn} % mathematics \DeclareMathOperator in amsopn +\usepackage[a]{esvect} % mathematics : for nice vectors arrows +\usepackage{numprint,xfrac,siunitx} % numbers / units / fractions +\usepackage{embedfile} % .dtx enclosed in .pdf +\usepackage{fancyvrb}\fvset{gobble=0,listparameters={\topsep=0pt}} % verbatim +\usepackage{interfaces} % interfaces (ŕ tester aussi avant \documentclass) +\usetikz{basic,chains,positioning} % pgf / TikZ +\usepackage{nccfoots} % \Footnote{marker}{text} +\usepackage{embedfile} +\RequirePackage{amsopn,amsmath}% +\RequirePackage[a]{esvect}% for vectors +\DeclareMathOperator*\Div{div} +\DeclareMathOperator*\Rot{\vv{\text{rot}}} +\DeclareMathOperator*\Min{Min} +\DeclareMathOperator*\Max{Max} +\newrobustcmd*\dpartial[2]{\displaystyle\genfrac{}{}{}{}{\partial\mkern.2\thinmuskip#1}{\partial\mkern.2\thinmuskip#2}} +\newrobustcmd*\dtotal[2]{\displaystyle\genfrac{}{}{}{}{\text d\mkern.2\thinmuskip#1}{\text d\mkern.2\thinmuskip#2}} +\newrobustcmd*\abs[1]{\left\lvert#1\right\rvert} +\usepackage{expl3,l3keys2e,siunitx} +\usepackage{xfrac} +\usepackage{listings} +\lstset{ + gobble=1, + language=[LaTeX]TeX, + basicstyle=\ttfamily, + breaklines=true, + upquote=true, +% prebreak={\%\,\ding{229}}, + backgroundcolor=\color[gray]{0.90}, + keywordstyle=\color{blue}\bfseries, + keywordstyle=[2]{\color{ForestGreen}}, + commentstyle=\ttfamily\color{violet}, + keywordstyle=[3]{\color{black}\bfseries}, + keywordstyle=[4]{\color{red}\bfseries}, + keywordstyle=[5]{\color{blue}\bfseries}, + keywordstyle=[6]{\color{green}\bfseries}, + keywordstyle=[7]{\color{yellow}\bfseries}, + %extendedchars={true}, + alsoletter={&}, +morekeywords=[1]{ + \lstdefinestyle, + \lstinputlisting,\lstset, + \color, + \geometry,\lasthline,\firsthline, + \cmidrule,\toprule,\bottomrule, + \everyrow,\tabulinestyle,\tabureset,\savetabu,\usetabu,\preamble, + \taburulecolor,\taburowcolors}, +morekeywords=[2]{ + tabular, + caption, + table, + tabu}, +morekeywords=[3]{ + &}, +morekeywords=[4]{red}, +morekeywords=[5]{blue}, +morekeywords=[6]{green}, +morekeywords=[7]{yellow}, +} +\csname endofdump\endcsname +\CodelineNumbered +\usepackage{fancyvrb}\fvset{gobble=1,listparameters={\topsep=0pt}} +\usepackage[linegoal]{tabu}\tracingtabu=2 +\newtabulinestyle{dash=on1pt off1pt} +\lastlinefit999 +\geometry{top=0pt,includeheadfoot,headheight=.6cm,headsep=.6cm,bottom=.6cm,footskip=.5cm,left=4cm,right=1.5cm} +\hypersetup{% + pdftitle={tabu}, + pdfsubject={a simple line parser for TeX}, + pdfauthor={Florent CHERVET}, + colorlinks,linkcolor=reflink,urlcolor=refurl, + pdfstartview=FitH,pdfpagemode=UseOutlines, + pdfkeywords={tex, e-tex, latex, package, tabular, array, halign, tabularx, longtable, color, colortbl, alignment}, + } +\embedfile{\thisfile.dtx} +\begin{document} + \DocInput{\thisfile.dtx} +\end{document} +%</driver> +% \fi +% +% \CheckSum{7884} +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% \DoNotIndex{\begin,\CodelineIndex,\CodelineNumbered,\def,\DisableCrossrefs,\~,\@ifpackagelater,\z@,\@ne,\@@,\@firstoftwo,\@firstofone,\@secondoftwo,\@fornoop,\@elt,\tabu@temp} +% \DoNotIndex{\DocInput,\documentclass,\EnableCrossrefs,\end,\GetFileInfo,\TMP@EnsureCode,\@length,\@thick,\@m,\@makeother,\@mpfn,\@preamerr,\@preamerror,\@skip,\@spaces,\tabu@spaces} +% \DoNotIndex{\NeedsTeXFormat,\OnlyDescription,\RecordChanges,\usepackage,\@ss,\@therule,\@unbox,\[,\],\{,\},\cellspacetoplimit,\begin,\bcolumn,\adl@xarraydashrule,\adl@vlineR,\adl@vlineL} +% \DoNotIndex{\ProvidesClass,\ProvidesPackage,\ProvidesFile,\RequirePackage,\adl@ncol,\adl@leftrulefalse,\adl@dashgapcolor,\adl@colhtdp,\adl@class@start,\adl@box,\adl@arrayrestore} +% \DoNotIndex{\filename,\fileversion,\filedate,\let,\adl@array,\adl@act@@endpbox,\adl@act@endpbox,\0,\,,\;,\&,\@cdr,\@box,\@currentHref,\@currentlabel,\@currentlabelname,\@currenvir} +% \DoNotIndex{\@listctr,\@nameuse,\csname,\else,\endcsname,\expandafter,\AtEndOfPackage,\crcr,\copy,\FV@RightListNumber,\FV@RightListFrame,\Hy@footnote@currentHref,\Hy@raisedlink} +% \DoNotIndex{\gdef,\global,\if,\item,\newcommand,\nobibliography,\newrobustcmd,\renewrobustcmd,\providerobustcmd,\hyper@@anchor,\ifadl@inactive,\ifadl@leftrule,\ifadl@zwvrule,\ifHy@nesting} +% \DoNotIndex{\par,\providecommand,\relax,\renewcommand,\renewenvironment,\in@@,\o,\on@line,\P,\ProcessOptions,\LNGL@setlinegoal,\set@color,\T,\O,\tabu@adl@endtrial} +% \DoNotIndex{\stepcounter,\usecounter,\nocite,\fi,\tabu@adl@act@endpbox,\tabu@adl@xarraydashrule,\tabu@FV@@@CheckEnd,\tabu@FV@@CheckEnd,\tabu@FV@DefineCheckEnd,\tabu@FV@ListProcessLine} +% \DoNotIndex{\@fileswfalse,\@gobble,\@ifstar,\@unexpandable@protect,\tabu@fornoopORI,\tabu@m@ybesiunitx,\tabu@multic@lumn,\tabu@multicolumnORI,\tabu@s@ved,\tabu@startpboxORI,\tabucline@sc@n,\z} +% \DoNotIndex{\AtBeginDocument,\AtEndDocument,\begingroup,\endgroup,\ifnum,\ifodd,\ifdim,\ifcsname,\ifcat,\ifcase,\iffalse,\FancyVerbFormatLine,\begin,\end,\@let@token,\@undefined,\active} +% \DoNotIndex{\frenchspacing,\MessageBreak,\newif,\PackageWarningNoLine,\@addtopreamble,\@depth,\@height,\@width,\@firstofone,\@frameb@x,\@lastchclass,\@M,\m,\@nextchar,\@startpbox} +% \DoNotIndex{\protect,\string,\xdef,\ifx,\texttt,\@biblabel,\bibitem,\@tempa,\{,\},\^,\ ,\DeclareOption,\CT@end,\CT@arc@,\CT@drsc@,\count@,\col@sep,\endgraf,\dimexpr,\fbox,\fboxsep,\g@addto@macro} +% \DoNotIndex{\z@,\wd,\vrule,\voidb@x,\verb,\bibitem,\NC@rewrite@,\NC@list,\NC@do,\NC@,\nobreak,\number,\showbox,\tabu@AtEnd,\tabu@getnbc@ls,\tabu@s@nitizetext} +% \DoNotIndex{\FrameCommand,\MakeFramed,\FrameRestore,\hskip,\hfil,\hfill,\hsize,\hspace,\hss,\hbox,\hb@xt@,\endMakeFramed,\escapechar,\tabu@s@veX,\tabu@sett@rget,\tabu@stack} +% \DoNotIndex{\do,\date,\if@tempswa,\@tempdima,\@tempboxa,\@tempswatrue,\@tempswafalse,\ifdefined,\ifhmode,\ifmmode,\cr,\@lowpenalty,\@medpenalty,\maxdimen,\tabu@,\tabu@@,\tabu@l@@d@rs} +% \DoNotIndex{\box,\author,\advance,\multiply,\Command,\outer,\next,\leavevmode,\kern,\title,\toks@,\trcg@where,\tt,\tabu@msgalign@PT,\toks} +% \DoNotIndex{\the,\width,\star,\space,\section,\subsection,\textasteriskcentered,\textwidth,\stform} +% \DoNotIndex{\",\:,\@empty,\@for,\@gtempa,\@latex@error,\@namedef,\@nameuse,\@tempa,\@testopt,\@width,\\,\m@ne,\makeatletter,\makeatother} +% \DoNotIndex{\maketitle,\parindent,\x,\kernel@ifnextchar} +% \DoNotIndex{\DefineShortVerb,\DeleteShortVerb,\UndefineShortVerb,\MakeShortVerb,\endinput,\@eha,\@ehd,\@nil,\@nnil,\@ifundefined,\@ifpackagelater,\@ifpackageloaded} +% \DoNotIndex{\p@,\tracingtabu,\@ne,\tw@,\m@ne,\thr@@,\z@skip} +% \makeatletter +% \newrobustcmd\ClearPage{\@ifstar\clearpage{}} +% \providecommand\lsstyle{} +% \newcommand\TabU {\texorpdfstring \T@bU {tabu }} +% \newrobustcmd*\T@bU[1][\pkgcolor]{\quitvmode\hbox{{#1{\larger[3]\usefont{U}{eur}mn\char"1C}$_\aleph \mkern.1666mu b\,$\rotatebox[origin=c]{-90}{\sf\smaller U}}}\xspaceverb} +% \newrobustcmd*\TABU[1][\pkgcolor]{\quitvmode\hbox{{#1{\larger[8]\usefont{U}{eur}mn\char"1C}$_\aleph \mkern.1666mu b\,$\rotatebox[origin=c]{-90}{\sf\smaller U}}}\xspaceverb} +% \colorlet{reflink}{CornflowerBlue!40!Indigo} +% \colorlet{pkgcolor}{reflink} +% \colorlet{refurl}{CornflowerBlue} +% \def\pkgcolor{\texorpdfstring{\color{pkgcolor}}{}} +% \catcode`\§ \active \def§{\@ifnextchar §{\par\nobreak\vskip-2\parskip}{\par\nobreak\vskip-\parskip}} +% \def\thispackage{\xpackage{{\TabU}}\Xspace} +% \def\Xpackage#1{\href{http://www.ctan.org/tex-archive/help/Catalogue/entries/#1.html}{\xpackage{#1}}} +% \def\Underbrace#1_#2{$\underbrace{\vtop to2ex{}\hbox{#1}}_{\footnotesize\hbox{#2}}$} +%\def\FV@DefineCommandChars #1#2#3{% +% \edef\FV@restoreCommandChars{% +% \catcode`#1\the\catcode`#1\relax +% \catcode`#2\the\catcode`#2\relax +% \catcode`#3\the\catcode`#3\relax}% +% \def \FV@CommandChars {\catcode `#1=0\relax \catcode `#2=1\relax \catcode `#3=2\relax }% +% \output\expandafter{\expandafter\FV@restoreCommandChars\the\output}% +%} +% \parindent\z@\parskip.4\baselineskip\topsep\parskip\partopsep\z@\leftmargini=2.5cm +% \widowpenalty=5000\clubpenalty=8000 +% \newrobustcmd*\macrocodecolor{\color{macrocode}}\definecolor{macrocode}{rgb}{0.07,0.03,0.10} +% \def\macro@font{\def\Cr@scale{.87}\changefont{fam=pcrs,siz=10pt,ser=m,color=macrocode,spread=1}\let\AltMacroFont\macro@font} +% \def\MacroFont{\changefont{fam=pcrs,siz=10pt,ser=b,color=macrocode}} +% \def\texorpdf#1#2{\texorpdfstring{#1{#2}}{#2}} +% \let\ltxthinspace\, \def\,{\texorpdfstring\ltxthinspace{}} +% \def\textitbf#1{\textbf{\itshape#1}}\let\textbfit\textitbf +% \DefineVerbatimEnvironment{VerbLines}{Verbatim}{frame=lines,framesep=6pt,fontfamily=\ttdefault,fontseries=m} +% \DefineVerbatimEnvironment{VerbLines*}{Verbatim}{frame=lines,framesep=6pt,fontfamily=\ttdefault,fontseries=m,commandchars=$()} +% \DefineVerbatimEnvironment{Verbat}{Verbatim}{fontfamily=\ttdefault,fontseries=m} +% \DefineVerbatimEnvironment{Verb*}{Verbatim}{fontfamily=\ttdefault,fontseries=m,commandchars=$()} +% \renewrobustcmd*\mathversion[1]{^^A +% \expandafter\ifx\csname mv@#1\endcsname\relax +% \@latex@error{Math version `#1' is not defined}\@eha +% \else \edef\math@version{#1}\gdef\glb@currsize{}\aftergroup\glb@settings +% \ifmmode \check@mathfonts \fi +% \fi +% } +% \newcommand*\ifcurrentenvir[1]{\expandafter\ifx\csname\@currenvir\expandafter\endcsname\csname#1\endcsname +% \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi} +% \newcommand*\currentenvirname{\@currenvir} +% \newrobustcmd*\OR{{\,\upshape\texttbf\textbar\,}} +% \newrobustcmd*\CheckOK{{\scriptsize\textcolor{ForestGreen}\CheckmarkBold}} +% \newrobustcmd*\CheckFAIL{{\scriptsize\textcolor{Crimson}\XSolidBrush}} +% \newcommand\tikzlabel[2][]{\tikz[{remember picture,#1}]\coordinate ({#2});\ignorespaces} +% \tabuDisableCommands{\let\tikzlabel \@gobble} +% \newlist{itempunct}{itemize}{1} +% \setlist[itempunct]{nolistsep,font=\smaller,leftmargin=1.7em,label=\textbullet} +% \def\smex{\leavevmode\hb@xt@2em{\hfil$\longrightarrow$\hfil}} +% \def\ttdefault{lmvtt} +% \renewrobustcmd\#[1]{{\usefont{T1}{pcr}{bx}{n}\char`\##1}} +% \newrobustcmd*\grabcs{\leavevmode\hbox\bgroup\bgroup\makeatletter\aftergroup\endgrabcs} +% \def\endgrabcs{\egroup\xspaceverb} +% \renewrobustcmd*\cs{\grabcs\cs@} +% \newrobustcmd\cs@[2][]{\begingroup\escapechar\m@ne\def\x ##1{\endgroup\tabu@maybehyperlink{##1}{\texttt{#1{\@backslashchar##1}}}}\expandafter\x\expandafter{\string#2}\egroup} +% \newcommand*\cs@pdf[1]{\@backslashchar\if\@backslashchar\string#1 \else\string#1\fi} +% \newrobustcmd*\csbf{\cs[\textbf]} +% \newrobustcmd*\csref[2][]{{\escapechar\m@ne\edef\my@tempa{\string#2}\edef\x ##1{\noexpand\hyperref{}{declcs}{\my@tempa}{\noexpand\cs[{##1}]{\my@tempa}}}\expandafter}\x{#1}} +% \newcommand\env{\texorpdfstring \env@ \env@pdf} +% \newcommand*\env@pdf[1]{#1} +% \newrobustcmd*\env@{\@ifstar {\env@starsw[environment]}{\env@starsw[]}} +% \new\def\env@starsw[#1]#2{\textt{#2}\ifblank{#1}{}{ #1}\Xspace} +% \newrobustcmd*\tabu@maybehyperlink [2]{\ifcsname tabu@declcs.\detokenize{#1}\endcsname \hyperref{}{declcs}{#1}{#2}\else #2\fi} +% \csundef{tabu@declcs.begin} +% \newcommand\textttbf[1]{\texorpdf\textbf{\textt{#1}}} +% \newrobustcmd*\blue{\color{blue}}\newcommand*\red{\color{dr}}\newcommand*\green{\color{green}}\newcommand\rred{\color{red}} +% \newrobustcmd*\FC[1][\color{copper}]{{#1\usefont{T1}{fts}xn FC}} +% \definecolor{copper}{rgb}{0.67,0.33,0.00} \newcommand\copper{\color{copper}} +% \definecolor{dg}{rgb}{0.02,0.29,0.00} \newcommand\dg{\color{dg}} +% \definecolor{db}{rgb}{0,0,0.502} \newcommand\db{\color{db}} +% \definecolor{dr}{rgb}{0.75,0.00,0.00} \let\dr\red +% \definecolor{lk}{rgb}{0.25,0.25,0.25} \newrobustcmd\lk{\color{lk}} +% \definecolor{llk}{rgb}{0.40,0.40,0.40} +% \newrobustcmd\bk{\color{black}}\newcommand\md{\mdseries} +% \newrobustcmd\ie{\emph{ie.}} +% \newcommand\textt[1]{\texorpdf\texttt{#1}} +% \newcommand\texttbf[1]{\texorpdf\textbf{\textt{#1}}} +% \newcommand\cellstrut{}\let\cellstrut\bottopstrut +% \newrobustcmd\etc{{\bk\emph{etc.}}} +% \def\M{\@ifstar{\M@i\@firstofone}{\M@i\meta}} +% \def\M@i#1{\@ifnextchar[\M@square +% {\ifx (\@let@token^^A) +% \expandafter\M@paren +% \else\ifx |\@let@token +% \expandafter\expandafter\expandafter\M@bar +% \else \expandafter\expandafter\expandafter\M@brace +% \fi\fi#1}} +% \def\M@square #1[#2]{\M@Bracket[{#1{#2}}]} +% \def\M@paren #1(#2){\M@Bracket({#1{#2}})} +% \def\M@bar #1|#2|{\M@Bracket\textbar{#1{#2}}\textbar} +% \def\M@brace #1#2{\M@Bracket\{{#1{#2}}\}} +% \def\M@Bracket#1#2#3{{\ttfamily#1#2#3}} +% \newrobustcmd*\thisyear{\begingroup +% \def\thisyear##1/##2\@nil{\endgroup +% \oldstylenums{\ifnum##1=2010\else 2010\,\textendash\,\fi ##1}^^A +% }\expandafter\thisyear\thisdate\@nil +% } +% +% \newrobustcmd*\csanchor[2][]{^^A +% \immediate\write\@mainaux{\csgdef{tabu@declcs.\string\detokenize{#2}}{}}^^A +% \raisedhyperdef[14pt]{declcs}{#2}{\cs[{#1}]{#2}}^^A +% } +% \renewrobustcmd\declcs[2][]{^^A +% \if@nobreak \par\nobreak +% \else \par\addvspace\parskip +% \Needspace{.08\textheight}\fi +% \changefont{size+=2.5pt,spread=1,fam=\ttdefault}^^A +% \def\*{\unskip\,\texttt{*}}\noindent +% \hskip-\leftmargini +% \begin{tabu}{|l|}\hline +% \expandafter\SpecialUsageIndex\csname #2\endcsname +% \csanchor[{#1}]{#2}} +% \renewcommand\enddeclcs{% +% \crcr \hline \end{tabu}\nobreak +% \par \nobreak \noindent +% \ignorespacesafterend +% } +% \def\declmargin{\hspace*\declmarginwidth } +% \def\declmarginwidth{\dimexpr -\leftmargini +\arrayrulewidth +\tabcolsep\relax} +% \pretocmd\textasteriskcentered{\usefont{OMS}{cmsy}mn}{}{} +% \newsavebox\tempbox +% +% \bookmarksetup{open=true,openlevel=2} +% \pagesetup{% +% head/rule/width=.0pt, +% left/offset=3cm,foot/left/offset+=.5cm,right/offset=1cm, +% head/font=\scriptsize, +% head/color=LightSteelBlue, +% head/left=\moveleft1cm\vbox to\z@{\vss\setbox0=\null\ht0=\z@\wd0=\paperwidth\dp0=\headheight\rlap{\colorbox{GhostWhite}{\box0}}}\vskip-\headheight\thispackage, +% head/right=Flexible \LaTeX{} tabulars, +% foot/font=\lk\scriptsize, +% foot/left=\vbox to\baselineskip{\vss{{\rotatebox[origin=l]{90}{\thispackage\,[rev.\thisversion\ release]\,\copyright\,\thisyear\,\lower.4ex\hbox{\pkgcolor\NibRight}\,\FC}}}}, +% foot/right=\oldstylenums{\arabic{page}} / \oldstylenums{\pageref{LastPage}}% +% } +% \pagesetup[plain]{% +% norules,font=\scriptsize, +% foot/right=\oldstylenums{\arabic{page}} / \oldstylenums{\pageref{LastPage}}, +% left/offset=3cm,foot/left/offset+=.5cm,right/offset=1cm, +% foot/left=\vbox to\baselineskip{\vss{{\rotatebox[origin=l]{90}{\thispackage\,[rev.\thisversion\ release]\,\copyright\,\thisyear\,\lower.4ex\hbox{\pkgcolor\NibRight}\,\FC\quad \xemail{florent.chervet at free.fr}}}}}, +% } +% \pagestyle{fancy} +% \bottomtitles=.15\textheight +% \sectionformat\section{ +% mark=\marksthe{section}{#1}, +% left=\declmarginwidth, +% top=\medskipamount, +% bottom=\smallskipamount, +% font=\normalfont\LARGE\bfseries, +% bookmark={bold,color=[rgb]{0.02,0.05,.2}}, +% break=\goodbreak} +% \sectionformat\subsection{% +% top=\medskipamount, +% bottom=.5\smallskipamount, +% left=.5\declmarginwidth, +% bookmark={color=[rgb]{0.02,0.05,.1}}, +% font=\normalfont\Large\bfseries, +% break=\addpenalty{-\@highpenalty}} +% \sectionformat\subsubsection{ +% bookmark={italic=false,color=lk}, +% font=\normalfont\large\bfseries\lk, +% label=, +% top=\medskipamount, +% bottom=.5\smallskipamount, +% break=\addpenalty{-\@medpenalty}} +% \setitemize{itemsep=\parskip,topsep=0pt,labelsep=1em,parsep=0pt,beginpenalty=10000} +% \tikzset{every picture/.add style={}{/utils/exec=\changefont{spread=1}}} +% \newrobustcmd*\IMPLEMENTATION{% +% ^^A\geometry{top=0pt,includeheadfoot,headheight=.6cm,headsep=.6cm,bottom=.6cm,footskip=.5cm,left=4cm,right=1.5cm} +% \newgeometry{top=0.8cm,headheight=.5cm,headsep=.3cm,bottom=1.2cm,footskip=.5cm,left=35mm,right=3mm} +% \pagesetup*{ +% left/offset-=5mm,right/offset-=12mm, +% head/left=\moveleft1cm\vbox to\z@{\vss\setbox0=\null\ht0=\z@\wd0=\paperwidth\dp0=\headheight\rlap{\colorbox{GhostWhite}{\box0}}}\vskip-\headheight \TabU\ \ T\,e\,c\,n\,i\,c\,a\,l\ \, n\,o\,t\,i\,c\,e \ \, a\,n\,d \ \, i\,m\,p\,l\,e\,m\,e\,n\,t\,a\,t\,i\,o\,n, +% }% +% \clearpage +% \tocsetup{depth-=1} +% \addtocontents{toc}{\tocsetup{subsection/font+=\string\smaller,subsection/skip=-2pt plus2pt minus2pt}} +% \sectionformat\section{bookmark/color=black}\sectionformat\subsection{bookmark/color=black} +% \bookmarksetup{bold*,openlevel=3} \hfuzz=3mm +% \section(Technical notice and Implementation)[\mdseries\scshape\pmb{Technical notice and Implementation}]{\textlarger{Technical notice and Implementation}}\label{implementation}} +% \let\plainllap\llap +% \newrobustcmd\macro@llap[1]{{\global\let\llap\plainllap +% \setbox0=\hbox\bgroup \raisedhyperdef{macro}{\saved@macroname}{#1}\egroup +% \ifdim\wd0>32mm +% \hbox to\z@ \bgroup\hss \hbox to32mm{\unhcopy0\hss}\egroup +% \edef\@tempa{\hskip\dimexpr\the\wd0-32mm}\global\everypar\expandafter{\the\expandafter\everypar +% \@tempa \global\everypar{}}^^A +% \else \llap{\unhbox0}\fi}} +% \AtBeginEnvironment{macro}{\if@nobreak\else\Needspace{2\baselineskip}\fi +% \MacrocodeTopsep\z@skip \MacroTopsep\z@skip \parsep\z@ \topsep\z@ \itemsep\z@ \partopsep\z@ +% \let\llap\macro@llap} +% \AtEndEnvironment{macro}{\goodbreak \vskip.3\parskip} +% \newrobustcmd*\stform{\ifincsname\else \expandafter\@stform \fi} +% \newrobustcmd*\@stform{\@ifnextchar*{\@@stform[]\textasteriskcentered\@gobble}\@@stform } +% \newrobustcmd*\@@stform[2][\string]{\textttbf{#1#2}\xspaceverb } +% \newrobustcmd*\xspaceverb{\ifnum\catcode`\ =\active\else \expandafter\xspace \fi} +% \new\let\Xspace \xspaceverb +% +% \makeatother +% +% \deffootnote{1em}{0pt}{\rlap{\textsuperscript{\thefootnotemark}}\kern1em} +% +% \newtabulinestyle{ a =.7pt on 3pt Crimson off4pt yellow, +% b =.7pt on 3pt LawnGreen off3pt, +% c =1.4pt on 3pt DarkSlateBlue off3pt, +% test =1pt blue, +% testdash =.7pt on1.2pt off 2pt blue, +% } +% \def\dash{\hbox{$\scriptscriptstyle\cdotp$}} +% +% \AtBeginShipoutNext{\AtBeginShipoutUpperLeft{% +% \tikz[remember picture,overlay]{ +% \coordinate (upper west) at (current page.north west); +% \coordinate (upper east) at (current page.north east); +% \node at ($(upper west)+(3cm,-4.5cm)$) [anchor=north west,rotate=30] {{\tabulinestyle{a}\tabulinesep=5pt \mathversion{bold}\color{teal} +% \begin{tabu}to 5cm{*4{|>{\smaller}X[c$]}|} \tabucline[c]- +% \multicolumn1{|c}{1} & \multicolumn1c{2} & \multicolumn1c{3} & 4 \\ \tabucline[c]- +% \multicolumn1{|c}{5} & \multicolumn1c{6} & 7 \\ \tabucline[c]{-3} +% \multicolumn1{|c}{8} & 9 \\ \tabucline[c]{-2} +% 10 \\ \tabucline[c]{-1} +% \end{tabu}}}; +% \node at ($(upper east)+(-.5cm,-4cm)$) [anchor=north east,rotate=-35] {{ +% \tabulinestyle{a} +% \tabulinesep=5pt \mathversion{bold} +% \begin{tabu}to 5cm{|*4{>{\smaller\pkgcolor}X[$mc]}|} \tabucline[b]{4-} +% \multicolumn3{c|}{} & \alpha \\ \tabucline[b]{3-} +% \multicolumn2{c|}{} & \beta & \gamma \\ \tabucline[b]{2-} +% \multicolumn1{c|}{} & \delta & \epsilon & \zeta \\ \tabucline[b]{-} +% \eta & \theta & \iota & \kappa \\ \tabucline[b]- +% \end{tabu}}}; +% }}} +% \title{\vspace*{-28pt}\href{http://www.tex.ac.uk/tex-archive/help/Catalogue/entries/tabu.html}{\scalebox{2}{\TABU[]}}\Footnotemark{\textsuperscript*}\vspace*{6pt}} +% \date{} +% \author{\small\thisdate~--~\hyperref[\thisversion]{version \thisversion\ release}} +% \subtitle{\begin{tabu}{X[c]}\Large tabu\, and\, longtabu \\[1ex] \LARGE Flexible \LaTeX{} tabulars\\ \small\FC \end{tabu}\vspace*{-12pt}} +% +% \maketitle +% +% {\makeatletter +% \Footnotetext{*}{\noindent\parskip=0pt\scriptsize +% This documentation is produced with the \textt{DocStrip} utility, and required \thispackage +% with its \hyperref[subsec:linegoal package option]{\textt{linegoal}} option.\par +% \begin{tabu} {X[-3]X[-1]X} +% \smex To get the package, &run: &\textt{etex \thisfile.dtx} \\ +% \smex To get the documentation &run (thrice): &\textt{pdflatex \thisfile.dtx} \\ +% \leavevmode\hphantom\smex To get the index, &run: &\textt{makeindex -s gind.ist \thisfile.idx} +% \end{tabu}§ +% The \xext{dtx} file is embedded into this pdf file thank to \Xpackage{embedfile} by H. Oberdiek.} +% } +% +% \deffootnote{1em}{0pt}{\rlap{\thefootnotemark.}\kern1em} +% +% {\let\quotation\relax\let\endquotation\relax\vspace*{-1cm}% +% \begin{abstract}\parskip\smallskipamount\parindent0pt\lastlinefit0\leftskip.2cm\rightskip\leftskip +% +% This package defines a single environment \env{tabu} to make all kinds of tabulars +% in text or in math mode provided that they do not split across pages. +% +% An environment \env{longtabu} -- based on D. Carlisle \Xpackage{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 \env*{tabu}. +% +% \env{tabu} is more flexible that \env{tabular}, \env{tabular*}, \env{tabularx} +% and \env{array} and extends the possibilities. All tabulars in this document were made +% with the \env*{tabu}, \emph{of course}... The implementation is optimised to minimise the +% measurements required to put all together. +% +% \TabU likes colors too, with special lines that are able to keep the alignment of the surrounded +% text... and also like numbers with the possibility to embed \Xpackage{siunitx} \textt S (or \textt s) +% columns. +% \TabU does not modify any of the macro defined by \xfile{array.sty} or in the \LaTeX{} +% kernel\footnote{Inside the \env*{tabu} a few macros are modified... this was compulsory !}. +% \medskip +% +% \TabU requires \eTeX{} and the standard package \xfile{array.sty}. Natural widths of columns +% are computed (but not printed ) by the code of \Xpackage{varwidth} by D. Arseneau. +% Finally \env{longtabu} is based on \Xpackage{longtable}. +% +% \end{abstract}} +% +% \makeatletter \enlargethispage\baselineskip +% \tocsetup{ +% depth=3, +% dot=$\scriptscriptstyle\ldotp$, +% dotsep=1mu, +% title/top=8pt plus2pt minus4pt, +% title/bottom=6pt, +% title=Contents\quad\leaders\vrule height3.1pt depth-3pt\hfill\null, +% bookmark={text=Contents,bold}, +% after=\leavevmode\hrule height3.1pt depth-3pt, +% twocolumns=false, +% section/skip=4pt plus2pt minus2pt, +% section/leaders=\leaders\hbox{$\m@th\mkern1mu\hbox{$\mathbf\ldotp$}\mkern1mu$}\hfill, +% section/dotsep, +% subsection/skip=0pt plus2pt minus 2pt, +% subsection/numwidth+=5pt, +% subsubsection/font=\slshape, +% subsubsection/pagenumbers=off, +% subsubsection/skip-=1pt,subsubsection/numwidth-=4pt, +% }\makeatother +% +% {% +% \hypersetup{linkcolor=black} +% \tableofcontents +% } +% +% \begingroup +% ^^A\geometry{top=0pt,includeheadfoot,headheight=.6cm,headsep=.6cm,bottom=.6cm,footskip=.5cm,left=4cm,right=1.5cm} +% \newgeometry{top=0pt,includeheadfoot,headheight=.6cm,headsep=.6cm,bottom=.6cm,footskip=.5cm,left=1.5cm,right=1cm} +% \pagesetup*{left/offset-=2.5cm,right/offset-=.5cm} +% +% \changefont{spread*=1.1} +% \phantomsection \label{Summary} +% \addcontentsline{toc}{section}{\protect\textcolor{FireBrick}{Summary of the features provided by \TabU}} ^^A\textt{\pkgcolor t\,a\,b\,u}}} +% \def\arraystretch{1}\vspace*{-9mm} +% \tabcolsep=3pt \tabulinesep=.5mm +% \begin{longtabu}{>{\ttfamily\bfseries}X[-1]X} \toprule +% \rowfont{\larger\bfseries\lsstyle} +% \multicolumn2c{Summary of the features provided by \thispackage} +% \\ \tabucline[\dash]- \endhead +% \hyperref[tabu.sec]{tabu} & +% is like \textt{tabular} in text mode and like \textt{array} \hyperref[math mode.sec]{in math mode} when there is no +% \textt X column in its preamble +% \\ +% \hyperref[longtabu.sec]{longtabu} & +% is like \textt{longtable} with the possibility to use \textt{tabu X} columns and vertical lines +% with the extended syntax. +% \\ +% \hyperref[tabu.sec]{\M*{tabu} to \meta{dimen}} & +% specifies the target width of the whole tabular. This is like \textt{tabular\textasteriskcentered}\, +% with an automatic stretchability that can be overwritten with \textt{@\M*{\cs\extracolsep\M*{dimen}}} +% in front of the preamble. +% \\ +% \hyperref[longtabu.sec]{\M*{tabu} spread \meta{dimen}} & +% has no equivalent in \LaTeX: the final width is \meta{dimen} wider than the +% natural width that can be obtained with \textt{spread 0pt}. +% \\ \tabucline[\dash]- +% \hyperref[Vertical lines]{\texttbf\textbar[width,color]} & +% vertical lines have an optional parameter. +% \\ \tabucline[\dash]- +% \hyperref[tabu X columns]{X[coef,align,type]} \par +% \refitem{tabu X columns,3}[{X[coef,align,type,\$]}] & +% \textt X columns widths are adjusted in order for the whole tabular to fit the +% target width. The target width is a dimension either: +% \begin{itempunct}[label=\ding{223}] +% \item directly specified with \textt{\M*{tabu} to\meta{dimen}} +% \item computed from the natural width: \textt{\M*{tabu} spread\meta{dimen}} +% \item by default \cs\linewidth (or \cs\linegoal with the \hyperref[subsec:linegoal package option]{\textt{linegoal} package option}). +% \end{itempunct} +% \textt{coef} scales the widths of the \textt X columns, if there are more than one \textt X column. \par +% \textt{align} is either \textt r, \textt c, \textt l\, or\, \textt j\, (or \hyperref{}{declcs}{rowfont}{\textt{R C L J}}) +% and \textt{type}\, can be \textt p (default), \textt m\, or\, \textt b.\par +% \textt{X[\$]}\, makes a math \textt X column (\ie \, \textt{>\M*{\$}X<\M*{\$}})\par +% \textt{X[\$\$}] display math \textt X column: \textt{>\M*{\$\cs\displaystyle}X<\M*{\$}} +% \\ +% \refitem{tabu X columns,2}[{X[$-$coef,align,type]}] & +% \textt X columns widths are first computed with the absolute value: $\mathversion{bold}\abs{\textt{coef}}$. +% Then the width is made narrower down to the natural width of the column if possible.\par +% In any case, the final width does not exceed the one obtained with \textt{X$\mathversion{bold}\left[\abs{\textt{coef}}\right]$}. +% \\ +% \hyperref[subsec:embedding siunitx S columns]{\textt{X\M*[X options]\M*{S\M*[S options]}}} & +% Embed a \Xpackage{siunitx} \textt S column into a \env{tabu}-\textt X column. +% \\ \tabucline[\dash]- +% \cs\everyrow\M*{code} & Allows to add horizontal lines automatically for every row.\par +% The settings can be changed inside the \textt{tabu} +% \\ \tabucline[\dash]- +% \cs\rowfont\M*[align]\M*{font spec} & +% Modify the font and optionally the alignment of each cell in one row. +% \\ \tabucline[\dash]- +% \cs\tabulinesep$=$\meta{dimen} & +% More control on vertical spacing of lines in a way very close to \Xpackage{cellspace}'s method (dynamic vertical spacing adjustment). +% \\ +% \cs\extrarowsep$=$\meta{dimen} & +% Control vertical spacing (\cs\extrarowheight and \cs\extrarowdepth): fixed vertical spacing adjustment.\par +% \cs\tabulinesep generally gives better results. +% \\ \tabucline[\dash]- +% \cs\tabudecimal\M*{\cs\usermacro} & a help to align numbers easily inside a column. +% \\ \tabucline[\dash]- +% \cs\savetabu\M*{user-name} & +% Saves the \textt{tabu} preamble and its parameters. +% The command must appear at the end of a line. +% \\ +% \cs\usetabu\M*{user-name} & +% Makes a \textt{tabu} of exactly the same shape as the one saved with \cs\savetabu. +% All parameters (\textt{target}, \textt{preamble}, \textt{stretch} \etc) are restored.\par +% This command is put alone in the preamble in place of the columns specifications. +% \\ +% \cs\preamble\M*{user-name} & +% Makes a \textt{tabu} with the same preamble as the one saved with \cs\savetabu. +% The only \textt{preamble} is restored, not the \textt{target} nor any other parameter.\par +% This command is put alone in the preamble in place of the columns specifications. +% \\ \tabucline[\dash]- +% \cs\tabulinestyle\M*{line spec} & Sets the current line style to be used for \texttbf\textbar\, and \cs\tabucline +% \\ +% \cs\newtabulinestyle\M*{name=spec,...} & Defines a line style for use with \cs\tabucline\M*[name] or with \texttbf\textbar\M*[name] +% \\ +% \cs\tabucline\M*[spec]\M*{start-stop} & Draws a line comparable to \cs\hline. The line \meta{spec} can contain +% information for making a dash or dotted line (f.ex. \M*[on 3pt off 6pt]) and a color name.\par +% The line spec can also be defined with \cs\newtabulinestyle +% \\ \tabucline[\dash]- +% \cs\taburulecolor\M*|dbl rule sep|\M*{rule color} & sets the color for rules (\cs\hline, \cs\firsthline ...) +% \\ \tabucline[\dash]- +% \cs\taburowcolors\M*[skip]\meta{number}\M*{first .. last} & Sets the color series to make alternate background colors for rows +% \\ \tabucline[\dash]- +% \cs\tabuphantomline & inserts a phantom (\ie invisible) line inside the \textt{tabu}\par +% May be usefull with \cs\multicolumn in some cases. +% \\ \tabucline[\dash]- +% \cs\tracingtabu$=0, 1, 2, 3, 4$ +% & +% Reports informations in the \xext{log} file about the steps of the algorithm for \textt{tabu X} columns, +% and the informations saved by \cs\savetabu. +% \\ \bottomrule +% \end{longtabu} +% +% \clearpage \endgroup +% +% +% \section{Examples and counterexamples} +% +% {\tabulinestyle{2pt on 3pt pkgcolor off4pt yellow!50}\tabulinesep=1mm +% \declmargin\begin{tabu}to\dimexpr\linewidth-\declmarginwidth{|X[c]|}\tabucline- +% \indent\bfseries\larger\lk Let's begin in colors ! \\ \tabucline- +% \end{tabu} +% } +% +% \TabU provides facilities to put horizontal and vertical leaders in a tabular. The package \Xpackage{xcolor} +% must be loaded of course. Background colors for cells are left to package \Xpackage{colortbl} which is fully +% compatible with \TabU. +% +% \subsection{``Locally global'' settings and their scopes} +% +% \TabU \marginnote{\llap{\begin{tabu}{r}\cs\tabulinestyle \\ \cs\taburulecolor \\ \cs\taburowcolors \\ \cs\everyrow \end{tabu}}} +% observes \TeX{} grouping levels for the settings of rule colors (\cs\taburulecolor) and styles (\cs\tabulinestyle), +% and \cs\everyrow. There is however a subtility for nested \env{tabu} environments as described in this example: +% +% {\smaller +% \begin{lstlisting}[caption={Locally global settings and their scopes}] +% \taburulecolor |gray!50|{red} \arrayrulewidth=1pt +% { +% \taburulecolor |yellow|{blue} +% \begin{tabu}{|X|X|} \hline +% Here the lines & are drawn in blue \\ \taburulecolor{green} \hline +% But starting from here & they are green coloured ! \\ \hline +% And now a nested tabu & \begin{tabu}{X} \firsthline\hline +% guess what colour \\ \hline +% is used for rules ?\\ \lasthline\hline +% \end{tabu} \\ \hline +% \end{tabu} +% % Inside the group, rule colors are blue +% } +% % After the group, rule colors are red again ! +% \begin{tabu}{X}\hline\hline\indent\end{tabu} +% \end{lstlisting}} +% +% +% {\taburulecolor |gray!50|{red}\tracingtabu=0 \arrayrulewidth=1pt +% { +% \taburulecolor|yellow|{blue}\tabulinesep=1mm +% \begin{tabu}{|X|X|} \hline +% \tikzlabel{start} +% Here the lines & are drawn in blue \\ \taburulecolor{green} \hline +% But starting from here & they are green coloured ! \\ \hline +% \tikzlabel{nested} +% And now a nested \env{tabu} & \extrarowsep=2mm\begin{tabu}{|X|} \firsthline\hline +% guess what colour \\ \hline +% \tikzlabel{inner} is used for rules ?\\ \lasthline\hline +% \end{tabu} \\ \hline +% \end{tabu} +% % Inside the group, rule colors are blue +% } +% % After the group, rule colors are red again ! +% \begin{tabu}{X}\hline\hline\indent\end{tabu} +% } +% \tikz[remember picture,overlay]{ +% \draw [->] ([xshift=-1cm]start) -- ([xshift=-\tabcolsep]start); +% \node at ([xshift=-1cm]start) [anchor=east,font=\smaller] {\begin{tabu}{c} Color of the \\ \TeX{} group\end{tabu}}; +% \draw [->,yshift=4mm] ([xshift=-1cm]nested) -- ([xshift=-\tabcolsep]nested); +% \node at ([xshift=-1cm]nested) [anchor=east,font=\smaller] {\begin{tabu}{c} Color of the last \\ end-of-line setting\end{tabu}}; +% \coordinate (A) at ([xshift=-1cm]nested); +% \coordinate (B) at (A |- inner); +% \draw [->] (B) -- ([xshift=-\tabcolsep]inner); +% \node at (B) [anchor=east,font=\smaller]{\begin{tabu}{c} Color of the\\ \TeX{} group\end{tabu}}; +% } +% The ``rules'' are the following: +% +% \begin{itemize}[leftmargin=*] +% \item If outside of a \env*{tabu}, the settings are local to the \TeX{} group. Every tabular drawn inside this group +% will inherit from the settings of that group. +% \item If \cs\taburulecolor (or \cs\everyrow or \cs\tabulinestyle) is used inside a cell of the tabular, this is the same: +% the settings a local to that cell, and any nested tabular will inherit from the setting of that cell. +% \item When used after the end of a row, the settings are globally changed from that point until the end of the tabular, +% or until a new setting is set at the end of a further row (\TeX nically, this is done inside a \cs\noalign group). +% But a nested \env{tabu} does not inherit from this ``global'' setting, and inherits from the settings of the \TeX{} +% group instead. +% \end{itemize} +% +% If \cs\arrayrulecolor\, or\, \cs\doublerulesepcolor\, (from package \Xpackage{colortbl}) are used instead +% of\, \cs\taburulecolor\, then colors are globally overwritten. +% +% \clearpage +% +% A counterexample from the \Xpackage{xcolor} package: \cs\rowcolors does not like +% \cs\cline, \cs\cmidrule etc.\footnote{Because color changes are done at \cs\everycr, +% which is not exactly the same as \TabU \cs\everyrow !} +% +% {\smaller +% \setbox\tempbox=\vbox{\linewidth.65\linewidth \hsize\linewidth +% \begin{lstlisting} +% \rowcolors{2}{green!25}{yellow!50} +% \begin{tabular}{cc} \toprule +% \repeatcell2{ +% rows=5, +% text/col1=test, +% text/col2=row \number\rownum} \\ +% test & other row \number\rownum \\ \cmidrule{1-2} +% test & other row \number\rownum \\ +% test & other row \number\rownum \\ \bottomrule +% \end{tabular} +% \end{lstlisting}} +% +% \begin{tabu}{X[2mc]X[1mc]} +% \indent\copy\tempbox +% & +% \rowcolors{2}{green!25}{yellow!50} +% \begin{tabular}{cc} \toprule +% \repeatcell2{ +% rows=5, +% text/col1=test, +% text/col2=row \number\rownum} \\ +% test & other row \number\rownum \\ \cmidrule{1-2} +% test & other row \number\rownum \tikzlabel{rownum} \\ +% test & other row \number\rownum \\ \bottomrule +% \end{tabular} +% \end{tabu} +% } +% +% The \cs\rownum counter is not reliable in the case of \cs\cline or \cs\cmidrule. \tikzlabel{rownumstart} +% \tikz[remember picture,overlay]{ +% \draw [->,gray] (rownumstart) -| (rownum); +% } +% +% In addition, the first coloured row is yellow, while one could have expected it green... +% +% For \TabU color changes are called at \cs\everyrow: +% +% {\smaller +% \setbox\tempbox=\vbox{\linewidth.65\linewidth \hsize\linewidth +% \begin{lstlisting} +% \taburowcolors [2] 2{green!25 .. yellow!50} +% \begin{tabu}{*2{X[c]}} \toprule +% \repeatcell2{ +% rows=5, +% text/col1=test, +% text/col2=row \thetaburow} \\ +% test & other row \thetaburow \\ \cmidrule{1-2} +% test & other row \thetaburow \\ +% test & other row \thetaburow \\ \bottomrule +% \end{tabu} +% \end{lstlisting}} +% +% \begin{tabu}{X[2mc]X[mc]} +% \indent\copy\tempbox +% & +% \taburowcolors [2] 2{green!25 .. yellow!50} +% \begin{tabu}spread 0pt {*2{X[-1c]}} \toprule +% \repeatcell2{ +% rows=5, +% text/col1=test, +% text/col2=row \thetaburow} \\ +% test & other row \thetaburow \\ \cmidrule{1-2} +% test & other row \thetaburow \\ +% test & other row \thetaburow \\ \bottomrule +% \end{tabu} +% \end{tabu} +% +% } +% +% \thispackage does not use ``real'' alternate colors but colorseries provided by package \Xpackage{xcolor}. +% This allow some gradations: +% +% \setbox\tempbox=\vbox{\linewidth=.65\linewidth\hsize\linewidth\smaller +% \begin{lstlisting} +% \taburowcolors 5{green!25 .. yellow!50} +% \begin{tabu}{X[-1]X} +% \repeatcell 2{ +% rows=10, +% text/col1=test, +% text/col2={Row number +% \row$=$\thetaburow}, +% } +% \end{tabu} +% \end{lstlisting}} +% +% { +% \begin{tabu}{X[2mc]X[mc]} +% \indent\copy\tempbox +% & +% \taburowcolors 5{green!25 .. yellow!50} +% \begin{tabu}{X[-1]X} +% \repeatcell 2{ +% rows=10, +% text/col1=test, +% text/col2={Row number \row$=$\thetaburow}, +% } +% \end{tabu} +% \end{tabu} +% } +% +% \subsection{\textt X column widths computation} +% +% The new algorithm implemented in version \hyperref[\thisversion]\thisversion{} requires only one measure of the width of the table +% in any case. \marginnote{\tikz{\node [inner sep=0pt,outer sep=0pt,rotate=45,fill=yellow!30] +% {\color{FireBrick}\tabcolsep=0pt\begin{tabu}{l} Example provided by \\ M. Manuel Kuehner\end{tabu}};}} +% This speeds up the convergence of the algorithm. +% +% { +% \centering +% {\smaller +% \begin{lstlisting} +% \begin{tabu} to 140mm {|X[1,l] | X[2,c] | X[3,c] | X[1,r]|} +% |\dotfill | & Text & Text & Text \\ +% Text & Text & Text & Text +% \end{tabu} +% \end{lstlisting}} +% +% \begin{tabu} to 140mm{|X[1,l] | X[2,c] | X[3,c] | X[1,r]|} \savetabu{X columns widths} +% |\dotfill | &Text &Text &Text \\ +% Text &Text &Text &Text +% \end{tabu} +% +% \tabulinestyle{1pt Blue} +% \begin{tabu}to 140mm{\preamble{X columns widths}} \tabucline- +% \rowfont[c]{\smaller} +% 1\textt X$=17.5mm$ & 2\textt X $=35mm$&3\textt X $=52.5mm$ &1\textt X $=17.5mm$ \\ \tabucline- +% \end{tabu}\par +% } +% +% $$X=\left( 140mm - 8\times \cs\tabcolsep - 5\times \cs\arrayrulewidth \right) / 7 = 17.4896mm$$ +% +% \Needspace{4\baselineskip} +% \subsection(Verbatim material){Inserting Verbatim material (\xpackage{fancyvrb})} +% \label{Verbatim material.subsec} +% +% Though the content of the \env*{tabu} is collected for measuring purpose, it is possible to insert +% verbatim material with the \env{tabu\stform*} variant of the environment. The content is then carefully +% collected and re-scanned (with \cs\scantokens). During the process, the \texttbf @ letter is read with the category +% code it has been given at the entry inside the environment (it is possible to say \cs\makeatletter before \cs\begin\M*{tabu\stform*}). +% +% Example: +% +% {\makeatletter +% \begin{tabu*}{*2{X[p]}} +% It is possible to insert Verbatim material with some \Verb+\csname+ +% \Verb+ control sequences \endcsname+ +% inside a \env{tabu} and inside \textt X columns. Negativ coefficients work well too, adjusting +% the width of the \textt X column to the natural width if it is finally less than the width +% computed with the absolute value of the coefficient.\par +% A complete \Verb+Verbatim+ environment is also admissible.\par +% But you must use the star form of the environment: \env{tabu\stform*} which uses \cs\scantokens. +% & +% \begin{Verbatim}[commandchars={$[]},listparameters={\topsep=-\ht\@arstrutbox}] +% Verbatim environments must be put +% alone on their lines (in the input +% file) for nothing is allowed +% after $cs[begin]{Verbatim} or +% $cs[end]{Verbatim}. +% Another point to know is that +% \begin and \end control sequences +% should match otherwise, you must +% enclose the Verbatim environment +% inside braces. +% This is related to the fact that tabu +% collects its body, and looks for +% matching pairs of \begin ... \end ! +% \end{Verbatim} +% \end{tabu*} +% } +% +% \env{tabu\stform*} 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. +% +% {\smaller +% \begin{lstlisting} +% \tabulinestyle{on2pt Crimson!60 off3pt yellow!50} \tabulinesep=2mm +% \makeatletter \@makeother\% +% \begin{tabu*}spread 0pt {|X[-1]X|} \tabucline- +% This is a small \Verb+\Verbatim+\par +% insertion +% & +% \begin{Verbatim}[listparameters={\topsep=-\ht\strutbox}] +% And this is a complete % with some comments +% Verbatim environment % every now and then +% \end{Verbatim} +% \\ \tabucline- +% \end{tabu*} +% \end{lstlisting}} +% +% { +% \tabulinestyle{on2pt Crimson!60 off2pt yellow!80} \tabulinesep=2mm +% \makeatletter +% \begin{tabu*} spread 0pt {|X[-1]|X|} \tabucline- +% Here a small \Verb+\Verbatim+\par +% insertion +% & +% \vtop\bgroup +% \begin{Verbatim}[gobble=1,listparameters={\topsep=-\ht\strutbox},commandchars=$()] +% And this is a complete $@percentchar with some comments $strut +% Verbatim environment $@percentchar every now and then +% \end{Verbatim} +% \egroup +% \\ \tabucline- +% \end{tabu*} +% \par} +% +% It's not possible to insert a \env*{lstlisting} presently, but you can save such an environment in a \cs\vbox +% and insert it inside the \env{tabu} of course. +% +% \subsection{Maths inside \textt{tabu X} columns} +% +% { +% \setbox\tempbox=\vbox{\linewidth=.6\linewidth\hsize\linewidth\smaller +% \begin{lstlisting} +% $\begin{tabu}spread .5in |{*3{X[$c]}}| +% \alpha & \beta & \gamma \\ +% \sum_i \frac{a_i}{x_i} & 0 & \cdot \\ +% \end{tabu}$ +% \end{lstlisting}} +% +% \begin{tabu}{X[m]X[-1m]} +% \indent\copy\tempbox +% & +% $\begin{tabu}spread .5in |{*3{X[$c]}}| +% \alpha & \beta & \gamma \\ +% \sum_i \frac{a_i}{x_i} & 0 & \cdot \\ +% \end{tabu}$ \\ +% \multicolumn2c{\lk\textt{X\M*[\$]} columns} +% \end{tabu} +% } +% +% { +% \setbox\tempbox=\vbox{\linewidth=.6\linewidth\hsize\linewidth\smaller +% \begin{lstlisting} +% $\begin{tabu}spread .5in |{*3{X[$$c]}}| +% \alpha & \beta & \gamma \\ +% \sum_i \frac{a_i}{x_i} & 0 & \cdot \\ +% \end{tabu}$ +% \end{lstlisting}} +% +% \begin{tabu}{X[m]X[-1m]} +% \indent\copy\tempbox +% & +% $\begin{tabu}spread .5in |{*3{X[$$c]}}| +% \alpha & \beta & \gamma \\ +% \sum_i \frac{a_i}{x_i} & 0 & \cdot \\ +% \end{tabu}$ \\ +% \multicolumn2c{\lk\textt{X\M*[\$\$]} columns} +% \end{tabu} +% } +% +% +% \subsection(siunitx S columns inside tabu X columns){Embedding \xpackage{sunitx} \textt S columns inside \textt X columns} +% \label{subsec:embedding siunitx S columns} +% +% A \textt S column from \Xpackage{siunitx} can be embedded into a \textt X column of \thispackage... with the following limitations: +% \begin{itemize}[leftmargin=2em] +% \item The \textt X column must be centered: \textt{X[c]} to keep the alignment, +% \item The optional alignment parameter of \cs\rowfont must not be used. +% \end{itemize} +% +% { +% \tabulinestyle{1pt GreenYellow} +% +% \setbox\tempbox=\vbox{\linewidth=.65\linewidth\hsize\linewidth\smaller +% \begin{lstlisting} +% \newcolumntype Y{S[group-four-digits=true, +% round-mode=places, +% round-precision=2, +% round-integer-to-decimal=true, +% per-mode=symbol, +% detect-all]} +% \tabucolumn Y +% \tabulinestyle{1pt GreenYellow} +% \begin{tabu}spread 8pt{|*2{Y|}c} \tabucline- +% \rowfont\bfseries +% {January} &{February} &... \\ +% \tabucline[1pt on2pt GreenYellow]- +% 12.324 &745.32 &... \\ +% 21.13 &0 &... \\ +% 213.3245 &12.342 &... \\ +% 2143.12 &324.325 &... \\\tabucline- +% \end{tabu} +% \end{lstlisting}} +% +% \newcolumntype Y{S[group-four-digits=true, +% round-mode=places, +% round-precision=2, +% round-integer-to-decimal=true, +% per-mode=symbol, +% detect-all]} +% \tabucolumn Y +% \begin{tabu}{X[m]X[-1m]} +% \indent\copy\tempbox +% & +% \begin{tabu}spread 8pt{|*2{Y|}c} \tabucline- +% \rowfont\bfseries +% {January} &{February} &... \\\tabucline[1pt on2pt GreenYellow]- +% 12.324 &745.32 &... \\ +% 21.13 &0 &... \\ +% 213.3245 &12.342 &... \\ +% 2143.12 &324.325 &... \\\tabucline- +% \multicolumn3c{\makecell[c]{Column widths are not \\ exactly the same}} +% \end{tabu} +% \end{tabu} +% +% \setbox\tempbox=\vbox{\linewidth=.58\linewidth\hsize\linewidth\smaller +% \begin{lstlisting} +% \newcolumntype Z{X[c]{% +% S[group-four-digits=true, +% round-mode=places, +% round-precision=2, +% round-integer-to-decimal=true, +% per-mode=symbol]}} +% \tabucolumn Z +% \begin{tabu}spread 8pt{|*2{Z|}c} \tabucline- +% \rowfont\bfseries +% {January} &{February} &... \\ +% \tabucline[1pt on2pt GreenYellow]- +% 12.324 &745.32 &... \\ +% 21.13 &0 &... \\ +% 213.3245 &12.342 &... \\ +% 2143.12 &324.325 &... \\\tabucline- +% \end{tabu} +% \end{lstlisting}} +% +% \newcolumntype Z{X[c]{S[group-four-digits=true, +% round-mode=places, +% round-precision=2, +% round-integer-to-decimal=true, +% add-decimal-zero, +% per-mode=symbol]}} +% \tabucolumn Z +% +% \begin{tabu}{X[m]X[-1m]} +% \indent\copy\tempbox +% & +% \begin{tabu}spread 8pt{|*2{Z|}c} \tabucline- +% \rowfont\bfseries +% {January} &{February} &... \\\tabucline[1pt on2pt GreenYellow]- +% 12.324 &745.32 &... \\ +% 21.13 &0 &... \\ +% 213.3245 &12.342 &... \\ +% 2143.12 &324.325 &... \\\tabucline- +% \multicolumn3c{\makecell[c]{Column widths are \\ exactly the same}} +% \end{tabu} +% \end{tabu} +% } +% +% \cs\tabucolumn is there to say \thispackage that the column type has to be treated +% with a high priority in the rewriting process. +% +% Another possibility to print number is provided with \cs\tabudecimal. +% +% +% \setitemize{leftmargin=3em} +% \section{The \textt{tabu} environment} +% \label{tabu.sec} +% +% \subsection(tabu, tabu to, tabu spread){\textt{tabu}, \textt{tabu to} and \textt{tabu spread}} +% +% \begin{declcs}{begin}\M*{tabu} \M*[pos] \M*{tabular preamble} \\ +% \cs{begin}\M*{tabu} to \meta{dimen} \M*[pos] \M*{tabular preamble} \\ +% \cs{begin}\M*{tabu} spread \meta{dimen} \M*[pos] \M*{tabular preamble} \\ +% \end{declcs} +% +% The \env*{tabu} behaves mostly like \env{tabular}: the preamble +% is parsed by the macros in \xfile{array.sty} and some measures are performed before printing. +% \env{tabu} improves \env{tabular} and \env{array}: +% +% \begin{itemize} +% \item \textbf{footnotes} and index words are allowed inside \env{tabu}, unlike \xpackage{tabularx}, footnote links +% are not broken when compiled with \xpackage{hyperref}. The syntax \cs\footnote\M[number]\M{text} +% is allowed in \env{tabu} and \env{longtabu} (this is not implemented for \xpackage{longtable} yet...) +% \item \textt X columns are implemented with an \emph{optional} parameter for the \textbf{width-coefficient} +% (which can be \refitem{item:Negativ width coefficients}[negativ]: see next section), +% the \textbf{alignment} (\textt r, \textt c, \textt l, or \textt j, and \textt R, \textt C, \textt L or \textt J +% for \xpackage{ragged2e} settings) and +% the \textbf{column type} (\textt p, \textt m, or \textt b). \\ +% \env{tabu} has a \refitem{item:default target width}[default target width] when used with \textt X columns, +% making nesting even easier. +% \item You are used to the \env*{tabular} in text mode, and \env*{array} in \hyperref[math mode.sec]{math mode}, +% but \env{tabu} works in both modes and its name does not change... \textt X columns are also +% possible in \hyperref[math mode.sec]{math mode}; \xpackage{delarray} shortcuts for delimiters are available in both math and text modes. +% \item A \env*{tabu} can contain another tabular of any kind: \env{tabular}, \env{tabular\stform*}, +% \env{tabularx} or \env{tabu} itself can be placed in any cell of a \env{tabu}. Conversely, +% \env{tabu} can be placed in a \env{tabular}, \env{tabularx} \etc. +% \item \env{tabu} provides facilities for \hyperref[Lines inside tabu]{vertical and horizontal lines}, +% and for the insertion of \hyperref[Verbatim material.subsec]{verbatim text} inside \textt X columns. +% \item \env{tabu} is fully compatible with \xpackage{colortbl}, \xpackage{delarray}, \xpackage{hhline}, +% \xpackage{makecell}, \xpackage{booktabs}, \xpackage{siunitx}, \xpackage{dcolumn}, \xpackage{warpcol}, \etc. +% When you are inside a \env*{tabu}, you can use \cs\raggedleft, \cs\raggedright +% and \cs\centering without special care about \cs\arraybackslash and conversely \cs\\ has its +% ``normal'' meaning inside a list of items that may appear in a \textt X column... +% \end{itemize} +% +% \bigskip +% +% \declmargin \cs{begin}\M*{tabu} \textt{to}\meta{dimen} is like \env{tabular\textasteriskcentered} but the inter-columns space is +% given a stretchability of 1fil, in other words \textt{@\M*{\cs\extracolsep\M*{0pt plus 1fil}}} +% is inserted by default at the beginning of the tabular preamble, unless another value for \cs\extracolsep is specified. Therefore +% ``\env{tabu to}'' fills in width the specified \meta{dimen}. +% +% \bigskip +% +% \declmargin \cs{begin}\M*{tabu} \textt{spread}\meta{dimen} does a tabular whose width is \meta{dimen} wider than its natural width. +% \textt{@\M*{\cs\extracolsep\M*{0pt plus 1fil}}} is inserted by default if \meta{dimen}$>0$. +% +% \subsection{\textt{longtabu}, \textt{longtabu to} and \textt{longtabu spread}} +% \label{longtabu.sec} +% +% \begin{declcs}{begin}\M*{longtabu}\,\M*[l\OR c\OR r]\,\M*{tabular preamble} \\ +% \cs{begin}\M*{longtabu} to \meta{dimen}\,\M*[l\OR c\OR r]\,\M*{tabular preamble} \\ +% \cs{begin}\M*{longtabu} spread \meta{dimen}\, \M*[l\OR c\OR r]\,\M*{tabular preamble} +% \end{declcs} +% +% \env{longtabu} is just like \env{tabu} but page breaks are allowed between rows of the table. +% \env{longtabu} is based on the \Xpackage{longtable} package which must be loaded, and all features +% of the \env{longtable} environment works inside \env{longtabu}: \cs\endhead, \cs\endfirsthead, +% \cs\endfoot, \cs\endlastfoot and \cs\caption. +% +% \env{longtabu} enhances the \env*{longtable} with the possibility to use \textt{X columns} +% and line specifications for horizontal and \hyperref[Vertical lines]{vertical rules}. +% \env{longtabu} is thus much easier than \Xpackage{ltxtable}. +% \goodbreak +% +% The following commands provided for \textt{tabu} do not work with \textt{longtabu}:\par\nobreak +% \let\theadfont\bfseries +% \newtabulinestyle{green-yellow=on 3pt LawnGreen off3pt yellow!60} +% {\tabulinesep=2pt +% \begin{tabu}{X[-1]*2{X[-1c]}X} \tabucline[\heavyrulewidth]- +% \rowfont[c]\bfseries +% \env{tabu} command &\thead{Not \\available} &\thead{Not (yet)\\implemented} &Comment \\\tabucline[\dash]- \everyrow{\tabucline[green-yellow]-} +% \cs\tabucline & &\indent\lower.5ex\hbox{\AsteriskRoundedEnds} &\cs\tabucline does not care of page breaks presently: use \cs\hline instead. \\ +% \cs\usetabu &\CheckFAIL & &but \cs\savetabu and \cs\preamble work. \\ +% \hyperref[math mode.sec]{mathematical mode} &\CheckFAIL & &\env{longtable} is not designed to work in math mode. \\ +% \xpackage{delarray} shortcuts &\CheckFAIL & &a delimiter cannot be spanned over pages... \\ +% \cs\tabuphantomline &\CheckFAIL & &useless inside \env{longtabu} +% \everyrow{} \\\tabucline[\heavyrulewidth]- +% \end{tabu} +% } +% +% However, \hyperref[tabu X columns]{\textt{tabu X} columns}, \cs\rowfont, \cs\extrarowsep, \cs\tabulinesep, \cs\tabudecimal, +% \cs\tabucline (with restrictions on page breaks), \cs\taburulecolor, \cs\tabulinestyle, \cs\taburowcolors, \cs\preamble, +% \hyperref[longtabu.sec]{\env{\M*{longtabu} to}}, \hyperref[longtabu.sec]{\env{\M*{longtabu} spread}} +% work inside \env{longtabu}. +% +% \subsection{\textt{tabu X} columns -- Mastering horizontal space} +% \label{tabu X columns} +% +% \textt{tabu X} columns can be viewed as an enhancement of \xpackage{tabularx} \textt X columns, but do not interact +% with them, for they are defined only for a short time during the parsing of the preamble: +% \begin{itemize}[name=tabu X columns] +% \item \textbf{width coefficients} can optionally be given to \textt X columns\\ +% ex.\, \texttbf{X[2.5]X[1]}\, is the same as\, \texttbf{X[2.5]X}\, and the same as\, \texttbf{X[5]X[2]} \\ +% This means that the first \textt X column will be two and a half wider than the second one or +% that the first \textt X column width will be \sfrac{5}{7} of the whole tabular width. \\[.5\baselineskip] +% \begin{tabu}to\linewidth{|X[c,2.5]|X[c]|} \firsthline \textt{X[2.5]} & \textt X \\ \hline\end{tabu} +% \item \textbf{negativ width coefficients} \label{item:Negativ width coefficients} can be given to \textt X columns: \\ +% ex.\, \texttbf{X[-2.5]X[1]}\, or\, \texttbf{X[-2.5]X} \, or\, \texttbf{X[-5]X[2]} \\ +% In this case, the first \textt X column will be \textitbf{at most} two and a half wider than the second one, +% and if the \emph{natural width} of the first \textt X column is finally less than +% $2.5 \times \left(\text{the width of the second column}\right)$ then it will be narrowed down to this natural width. +% \textbf{The following \textt{tabu}{\smaller s} have the same preamble:} \\ +% \hspace*{1em}\cs{begin}\M*{tabu} to\cs\linewidth\M*{|X\M*[$-$2.5c]|X\M*[c]|}: \\ +% \begin{tabu} to\linewidth{|X[c,-2.5]|X[c]|} \tabucline- +% \textt{X[$-$2.5]} & \textt X \\ \tabucline- +% \end{tabu} \\ +% \begin{tabu} to\linewidth{|X[c,-2.5]|X[c]|} \tabucline- +% Negativ coefficients make \textt X columns close to standard\par \textt l, \textt c and \textt r columns. +% & \textt X \\ \tabucline- +% \end{tabu} +% \item horizontal alignment specification is made easier with\, \texttbf{X[5,r]X[2,c]}\, for example. Vertical +% alignment can be specified as well with\, \textt{X[5,r,m]X[2,p,c]}\, (commas are not required, +% but \textt{X[2cm]} or \textt{X[4pc]} could be misunderstood -- not by \TeX{}: by you...).\\ +% \begin{tabu}to \linewidth{X[-2c]X[c]c} +% \rowfont{\bfseries\ttfamily} Modifier & Meaning & Default \\ +% \textt l, \textt c, \textt r, \textt j, \textt L, \textt C, \textt R, \textt J & left, centered, right, justified & \textt j \\ +% \textt p, \textt m, \textt b & \textt X column is converted into \textt p, \textt m or \textt b column & \textt p \\ +% \$ & \textt{X\M*[\$]} is a shortcut for:\, \textt{>\M*{\$}X<\M*{\$}} & \\ +% \$\$ & \textt{X\M*[\$\$]} is a shortcut for:\, \textt{>\M*{\$\cs\displaystyle}X<\M*{\$}} & \\ +% \end{tabu} +% \item \textt{tabu X} columns can be spanned with \cs\multicolum. +% \item \textt{tabu X} columns can be used with ``\textt{tabu spread}'' for small tabulars. +% \item \textt{tabu X} columns can contain any type of \textt{tabular}, \textt{tabular*}, \textt{tabularx} or \textt{tabu} +% without special care about the syntax. \textt{tabu} can also be put inside \textt{tabular}, \textt{tabular*} +% and \textt{tabularx}. As long as \textt{tabu} with \textt X columns has a \emph{default target}, nesting \textt{tabu} +% with \textt X columns is easy. Furthermore, the default global alignment of a nested \textt{tabu} is \textt t +% (for \textt{top}) while the default global alignment of a \textt{tabu} in a paragraph is \textt c (for \textt{centered}). +% ^^AWhen nested inside another \textt{tabu}, \textt{tabu} takes care not to add duplicate margins around its cells... +% \item The ``algorithm'' (or the arithmetic) to get the target width for \textt{tabu X} columns is the same as the one +% used by \xpackage{tabularx}. \cs\hfuzz is the ``tolerance'' for the whole tabular width. We use \eTeX{} \cs{dimexpr} + +% instead of \TeX{} primitives (with round/truncate bias correction). +% \item \label{item:convergence optimisation} Convergence to the target width is optimised: +% the \cs\halign preamble is not re-built at each trial, but only expanded again, +% until the target is reached. Though optimized, the process is the same as the one implemented for \textt{tabularx} +% and in particular the content of the \textt{tabu} environment is collected as soon as a \textt{tabu X} column +% is found in the preamble. This implies restrictions on catcode modifications and verbatim text inside +% a \textt{tabu} with \textt X columns. +% \item \label{item:default target width} If the width of the whole tabular is not specified with ``\textt{tabu to}'' +% it is considered to be \cs\linewidth. +% \nameref{subsec:linegoal package option} makes the default width equal to \cs\linegoal. Compilation must then be done +% with \hologo{pdfTeX} either in \textt{pdf} or \textt{dvi} mode, and package \xpackage{linegoal} is loaded. +% \cs\linegoal requires \hologo{pdfTeX} for its \cs\pdfsavepos primitive and the \xpackage{zref-savepos}: +% if the \textt{tabu} is not alone in its paragraph \ie if the target is not +% \cs\linewidth, then two compilations (or more) are required to get the correct target. \\ +% Default target for nested \textt{tabu} environments is always \cs\linewidth, which equals to the column width inside +% \textt p, \textt m, \textt b and \textt X columns. +% \item As long as the \cs\halign content is expanded more than once, protections against counters incrementation, whatsits (\emph{write}) +% index entries, footnotes \etc. are set up: the mechanism of \xpackage{tabularx} is reimplemented and enhanced for \textt{tabu X} columns. +% \cs\tabuDisableCommands can be used to neutralize the expansion of additional macros during the trials. +% \end{itemize} +% +% \subsubsection(X columns with tabu spread){X columns with ``\textt{tabu spread}''} +% \label{X columns with tabu spread} +% +% \textt{tabu X} columns can be used with ``\textt{tabu spread}'' to adjust the column widths of tabulars that contain +% only small pieces of text. The question is: how to make a tabular the width of the line, with 6 columns; the columns 1, 2, 5 and 6 +% are of equal widths and the widths of columns 3 and 4 are only one half. As possible solution: +% +% \begin{Verb*} +% \begin{tabu} to\linewidth{|X[2]|X[2]|X|X|X[2]|X[2]|} \hline +% 1 & 2 & 3 & 4 & 5 & 6 \\\hline +% \end{tabu} +% \end{Verb*} +% +% \medskip +% +% \begin{tabu} to\linewidth{|X[2]|X[2]|X|X|X[2]|X[2]|} \hline +% 1 &2 &3 &4 &5 &6 \\\hline +% \end{tabu} +% +% \bigskip +% +% But the text in each cell is very short: one single character, and you prefer the table to be tight, +% but don't know the exact width of the whole: +% +% \begin{Verb*} +% \begin{tabu} spread 0pt{|X[2]|X[2]|X|X|X[2]|X[2]|} \hline +% 1 & 2 & 3 & 4 & 5 & 6 \\\hline +% \end{tabu} +% \end{Verb*} +% +% {\centering +% \begin{tabu} spread0pt{|X[2]|X[2]|X|X|X[2]|X[2]|} \hline +% 1 & 2 & 3 & 4 & 5 & 6 \\\hline +% \end{tabu}\par} +% +% \bigskip +% +% But now it's definitely too narrow, then give it some more space: +% +% \begin{Verb*} +% \begin{tabu} spread 2in{|X[2]|X[2]|X|X|X[2]|X[2]|} \hline +% 1 & 2 & 3 & 4 & 5 & 6 \\\hline +% \end{tabu} +% \end{Verb*} +% +% {\centering +% \begin{tabu} spread2in{|X[2]|X[2]|X|X|X[2]|X[2]|} \hline +% 1 & 2 & 3 & 4 & 5 & 6 \\\hline +% \end{tabu}\par} +% +% \bigskip +% +% \textt{tabu spread} is useless with long columns: the following tabular was made with this preamble: +% \begin{Verb*} +% \begin{tabu} spread 3cm{@{}X[9]X[4]|X|} +% \end{Verb*} +% +% {\footnotesize +% \begin{tabu} spread 3cm{@{}X[9]X[4]|X|} +% "Like the air we breathe, Sherlock Holmes is everywhere. +% His pipe-smoking, deer stalkered image peers at us from ads in Yellow Pages, +% to signs for neighbourhood crime-watch; from billboards to the classroom; +% from film and television to the public library, and now over the Internet. +% He long ago transcended the boundaries of 19th Century London\footnote{Capital of the U.K. (too see a linked footnote)} +% to become an international best-seller and has been accepted as part +% of British folklore. Holmes is alive to millions." +% & +% There the text was too long, and \textt{tabu spread} behaves as if you didn't give it a target.\par\vskip\baselineskip +% The result of this example is the same as if one had written \cs{begin}\M*{tabu}\textt{to}\cs\linewidth. +% & \cellcolor{GhostWhite}\centering\rotatebox{-90}{\kern-1.4ex\bfseries Sherlock Holmes} +% \\ \tabucline{1-2} +% \multicolumn{2}{|c|}{The ``official'' web site: \url{http://www.sherlockholmes.com/}} & \omit \\ \tabucline{-2} +% \end{tabu}} +% +% In the preamble, \textt{@\M*{}} means that the margin is removed. +% +% \subsubsection{Negativ width coefficients for \textt X columns} +% +% {\smaller +% \begin{lstlisting} +% \tabulinestyle{3pt ForestGreen} +% \begin{tabu}{|X[-1m]|X[c m]|} +% \tabucline- \savetabu{FirstNegativTest} +% $\begin{tabu}({X[-1$]X[-1$c]}) +% \alpha & \beta \\ +% \gamma & \delta + \epsilon + \zeta + \eta + \theta +% \end{tabu}$ +% & +% This is a tabu with negativ width coefficients for \textt X columns +% \\ \tabucline- +% \end{tabu} +% \end{lstlisting} +% } +% +% ^^A% \begin{Verbat} +% ^^A% \begin{tabu}{|[3pt ForestGreen]X[-1m]|X[c m]|[3pt ForestGreen]} +% ^^A% \tabucline[3pt ForestGreen]- +% ^^A% $\begin{tabu}({X[-1$]X[-1$c]}) +% ^^A% \alpha & \beta \\ +% ^^A% \gamma & \delta + \epsilon + \zeta + \eta + \theta +% ^^A% \end{tabu}$ +% ^^A% & +% ^^A% This is a tabu with negativ width coefficients for \textt X columns +% ^^A% \\ \tabucline[3pt ForestGreen]- +% ^^A% \end{tabu} +% ^^A% \end{Verbat} +% +% { \tabulinestyle{3pt ForestGreen} +% \begin{tabu}{|X[-1m]|X[c m]|} \tabucline- \savetabu{FirstNegativTest} +% $\begin{tabu}({X[-1$]X[-1$c]}) +% \alpha & \beta \\ +% \gamma & \delta + \epsilon + \zeta + \eta + \theta +% \end{tabu}$ +% & +% This is a tabu with negativ width coefficients for \textt X columns +% \\ \tabucline- +% \end{tabu} +% +% \tabulinesep=2pt +% \begin{tabu}{\usetabu{FirstNegativTest}}\tabucline[3pt ForestGreen]- +% $\begin{tabu}({X[-1$]X[-1$c]}) +% \alpha & \beta \\ +% \gamma & \delta + \epsilon + \zeta + \eta + \theta +% \end{tabu}$ +% & +% And this is the same with \csref{tabulinesep} set to $2pt$. +% \\ \tabucline[3pt ForestGreen]- +% \end{tabu} +% } +% +% \subsubsection{Multicolumn in \textt{tabu}} +% +% \begin{declcs}{tabuphantomline} +% \end{declcs} +% +% The process of \cs\multicolumn implies the \TeX{} primitive \cs\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{Verb*} +% \begin{tabu}{|X|X|X[2]|} \tabucline- +% \multicolumn2{|c|}{Hello} & World \\ \tabucline- +% \end{tabu} +% \end{Verb*} +% +% The correct result can be obtained by the mean of a phantom line, that will remain invisible +% unless your preamble contains special \texttbf @ or \texttbf ! columns that prints some text: +% +% \begin{Verb*} +% \begin{tabu}{|X|X|X[2]|} \tabucline- +% \multicolumn2{|c|}{Hello} & World \\ \tabucline- +% \tabuphantomline +% \end{tabu} +% \end{Verb*} +% +% \begin{tabu}{|X|X|X[2]|} \tabucline- +% \multicolumn2{|c|}{Hello} & World \\ \tabucline- +% \tabuphantomline +% \end{tabu} +% +% Remember you may need \cs\tabuphantomline in conjunction with \cs\savetabu and \cs\usetabu with \cs\multicolumn. +% Even if it is possible to add a \cs\tabuphantomline in any line of the \textt{tabu}, it is a good practice +% to append it \emph{at the end} of the \textt{tabu}, for it may introduce indesirable side effects on vertical alignment +% otherwise, when \textt{tabu} is nested inside another tabular. +% +% In particular, \cs\tabuphantomline should not be followed by \cs\cr or \cs\\ or \cs\tabularnewline... +% +% The need for this command could disappear in a future release, but this requires +% a complete new implementation of \cs\multicolumn... +% +% +% \subsection{\cs{tabulinesep} and \cs{extrarowsep} -- Mastering vertical space} +% \label{tabulinesep.subsec}\label{vertical spacing.sec} +% +% \begin{declcs}{tabulinesep}$=$\meta{dimen} \\ +% \cs\tabulinesep$=$\string^\meta{dimen} \\ +% \cs\tabulinesep$=$\string_ \meta{dimen} \\ +% \cs\tabulinesep$=$\string^\meta{dimen}\string_\meta{dimen} \\ +% \cs\tabulinesep$=$\string_\meta{dimen}\string^\meta{dimen} +% \end{declcs} +% +% \cs\tabulinesep sets the \emph{minimal } vertical space allowed between the cell content and the +% cell border. The macro may be prefixed by \cs\global (even inside a \cs\noalign group)\footnote{However +% \cs\tabulinesep is not a dimension ! You can't test, for example, \cs{ifdim} \cs\tabulinesep$>0pt$ ! +% Test \cs\abovetabulinesep and \cs\belowtabulinesep instead, if needed.}. +% +% It is possible to set the ``top limit'' (a \TeX{} dimension called \cs\abovetabulinesep) and the +% ``bottom limit'' independently with the syntaxes:\par\nobreak +% +% \begin{tabu}{X[-1]X} +% \cs\tabulinesep=\string^\meta{dimen} & sets \cs\abovetabulinesep \\ +% \cs\tabulinesep=\string_\meta{dimen} & sets \cs\belowtabulinesep \\ +% \cs\tabulinesep=\string_\meta{dimen}\string^\meta{dimen} & sets \cs\belowtabulinesep and \cs\abovetabulinesep. +% \end{tabu} +% +% These parameters can be used in text and math modes to give more vertical space between lines, +% especially when using math formulae. +% +% Examples \textcolor{gray}{(with \cs\tracingtabu$=3$ and \Xpackage{interfaces}-\cs\papergraduate to see the struts)}: +% +% \begin{tikzpicture} +% +% \papergraduate (0,0) (158mm,32mm); +% +% \node at (5mm,5mm) [anchor=south west,inner sep=0pt] +% {{\tabulinesep=4pt\tabustrutrule=0pt\extrarowsep0pt +% \def\test#1{\tabulinesep=#1\tracingtabu=3 \ifdim\abovetabulinesep>0pt \tabustrutrule=2pt\fi +% \begin{tabu}{|*2{X[-1c$]|}} \hline +% \dpartial \Phi \theta & \dtotal \theta t \\ \hline +% \end{tabu}}% +% \begin{tabu} to 15cm{@{}|[test]*3{X[cm]|[test]}} \tabucline[test]- +% \test{0mm} +% & +% \test{1mm} +% & +% \test{3mm} +% \\ \tabucline[testdash]- +% \cs\tabulinesep$=0mm$ & \cs\tabulinesep$=1mm$ & \cs\tabulinesep$=3mm$ +% \\ \tabucline[test]- +% \end{tabu} +% } +% }; +% \end{tikzpicture} +% +% \cs\tabulinesep is a soft parameter, and leads to rows which do not share the same height. +% +% \begin{declcs}{extrarowsep}$=$\meta{dimen} \\ +% \cs\extrarowsep$=$\string^\meta{dimen} \\ +% \cs\extrarowsep$=$\string_ \meta{dimen} \\ +% \cs\extrarowsep$=$\string^\meta{dimen}\string_\meta{dimen} \\ +% \cs\extrarowsep$=$\string_\meta{dimen}\string^\meta{dimen} +% \end{declcs} +% +% \cs\extrarowsep is an extra vertical space which is added to each row, inconditionally. \xfile{array.sty} +% provides the \TeX{} dimension \cs\extrarowheight and \thispackage provides \cs\extrarowdepth in addition. +% +% As a result, the rows can share the same height/depth but the spacing is not dynamic. \cs\tabulinesep +% can be used even with positive values for \cs\extrarowsep, for \env{tabu} inserts only one strut per row +% and vertical spacing computations are possible in all cases. +% +% The macro can be prefixed by \cs\global as well, even inside a \cs\noalign group\footnote{However \cs\extrarowsep is not a dimension ! +% You can't test, for example, \cs{ifdim} \cs\extrarowsep$>0pt$ ! +% Test \cs\extrarowheight and \cs\extrarowdepth instead, if needed.}. +% +% Set \cs\extrarowheight and \cs\extrarowdepth to different values, with the syntaxes:\par\nobreak +% \begin{tabu}{X[-1]X} +% \cs\extrarowsep=\string^\meta{dimen} &\begin{tabu}{@{}l} sets \cs\extrarowheight \\ \cs\extrarowdepth is unchanged\end{tabu} \\ +% \cs\extrarowsep=\string_\meta{dimen} &\begin{tabu}{@{}l} sets \cs\extrarowdepth \\ \cs\extrarowheight is unchanged\end{tabu} \\ +% \cs\extrarowsep=\string_\meta{dimen}\string^\meta{dimen} &sets \cs\extrarowdepth and \cs\extrarowheight. +% \end{tabu} +% +% Both \cs\extrarowheight and \cs\extrarowdepth are scaled by \cs\arraystretch (a scaling \emph{macro}\footnote{\cs\arraystretch is not a dimension +% but a macro that stores a scaling factor.} of \xfile{array.sty}) +% if \cs\arraystretch$>1$... +% +% These parameters can be used in text and math modes. +% +% Examples \textcolor{gray}{(with \cs\tracingtabu$=3$ and \Xpackage{interfaces}-\cs\papergraduate to see the struts)}:\par\nobreak +% { +% \def\arraystretch{1} +% \def\smalltest#1#2{\tracingtabu=3 \begin{tabu}{#1} \hline #2 \\ \hline \end{tabu}} +% +% \def\test#1{{\tabulinesep=1mm\extrarowsep=0pt\tracingtabu=0 +% \begin{tabu}to 15cm{@{}|[test]*3{>{\tabulinesep=0pt\extrarowsep=#1}X[mc]|[test]}>{\tabulinesep=0pt\extrarowsep=#1}X[1.3mc]|[test]} +% \tabucline[test]- +% \rowfont\bfseries +% Standard \textt c column & \textt{X[-1,c]} columns & Math mode & Mixed: \textt{X[-1c]X[-1c\$]} +% \\ \tabucline[test]- +% \smalltest{*2c}{One & Two \\ \hline Three & Four } +% & +% \smalltest{*2{X[-1,c]}}{One & Two \\ \hline Three & Four } +% & +% $\smalltest{*2c}{\alpha & \beta \\ \hline \dfrac \Phi \theta & \Gamma_x^t}$ +% & +% \smalltest{X[-1c]X[-1c$]}{First & \dpartial \Phi \theta \\ \hline Second & \dtotal \theta t} +% \\ \tabucline[testdash]- +% \multicolumn4{|[test]c|[test]}{\cs\extrarowsep=$#1$} +% \\ \tabucline[test]- +% \end{tabu} +% }} +% \tikz{ +% \papergraduate [xcolor=ForestGreen,ycolor=Maroon,opacity=.1,text opacity=.9] (0,0) (158mm,46mm); +% \node at (5mm,5mm) [anchor=south west,inner sep=0pt] {\test{3mm}}; +% } +% \tikz{ +% \papergraduate[xcolor=ForestGreen,ycolor=Maroon,opacity=.1,text opacity=.9] (0,0) (158mm,40mm); +% \node at (5mm,5mm) [anchor=south west,inner sep=0pt] {\test{0mm}}; +% } +% } +% +% \subsection{\textt{tabu} in math mode} +% \label{math mode.sec} +% +% {\tabulinesep=2pt +% \begin{tabu} to\linewidth {XX[-1$]} \toprule +% On the left, you can see the famous Maxwell-Lorentz equations for electromagnetic field in vacuum, +% publicated in \oldstylenums{1873}. +% & +% \hfil\arraycolsep=3pt +% \begin{tabu}({rl}. +% \Div\vv E &= \dfrac \rho {\epsilon_0} \\ +% \Div\vv B &= 0 \\ +% \Rot\vv E &= - \dpartial{\vv B} t \\ +% \Rot\vv B &= \mu_0 \vv j + \mu_0 \epsilon_0\, \dpartial{\vv E} t +% \end{tabu} +% \\ \bottomrule +% \end{tabu}} +% +% In this example, the big \env{tabu} is: \cs{begin}\M*{tabu} to\cs\linewidth \M*{XX[-1\$]}. +% +% The nested \env{tabu} (in math mode) uses \xpackage{delarray} shortcut: its preamble is: \Verb+\begin{tabu}({rl}.+ +% +% \cs\tabulinesep has been set to \texttbf{2pt}. +% Horizontal rules are \Xpackage{booktabs} \cs\toprule and \cs\bottomrule. +% +% \begin{tabu}{@{}*3{X[c]@{}}} \toprule \savetabu{math} +% \rowfont{\bfseries\ttfamily} array & tabu & tabu spread $1em$ \\ \midrule +% $\begin{array} [t] |{cc}| +% \alpha & \beta \\ +% \gamma & \delta +% \end{array}$ +% & +% $\begin{tabu} |{cc}| +% \alpha & \beta \\ +% \gamma & \delta +% \end{tabu}$ +% & +% $\begin{tabu} spread 1em |{cc}| +% \alpha & \beta \\ +% \gamma & \delta +% \end{tabu}$ +% \\ \bottomrule +% \end{tabu} +% +% Here, vertical lines are made with \xpackage{delarray} shortcuts:\hfill +% \verb+$\begin{tabu} spread 1em |{cc}|+ +% +% \begin{tabu}{\usetabu{math}} +% \multicolumn2{@{}l}{Vertical lines inside the tabular preamble gives:} +% & +% $\begin{tabu} spread 1em [c]{|cc|} +% \alpha & \beta \\ +% \gamma & \delta +% \end{tabu}$ +% \tabuphantomline +% \end{tabu} +% +% \bigskip +% {\raggedleft\footnotesize\lk This was an example of \cs\savetabu...\cs\usetabu to keep the alignment.\par} +% +% \section{Lines leaders and colors inside \env{tabu}} +% \label{Lines inside tabu} +% +% \subsection{First important remark} +% +% The features provided in this section are quite experimental: they are not generally taken for good typography. +% You can use \thispackage with package \xpackage{booktabs} for example, which provides properly designed +% commands for horizontal rules in tabulars. \xpackage{arydshln} is pretty good too, but it modifies a huge +% amount of macros of \xfile{array.sty}, something that \thispackage does not. +% +% Lines in \env{tabu} printed in this document are mostly made with \xpackage{booktabs}. +% +% +% \subsection(Vertical lines){Vertical lines: \textt\textbar\ has an optional parameter} +% \label{Vertical lines}\enlargethispage\baselineskip +% +% Inside \textt{tabu} environment, the vertical line marker \textt\textbar\ has an \emph{optional} argument +% which is the width of the vertical rule. The default width remains \cs\arrayrulewidth of course. +% The optional argument for \textt\textbar\ can also contain the name of a color. +% color \emph{names} are only possible, not a color specification by the mean of a color model. +% The width of the line if specified, must come before the color name and... +% as for \hyperref[tabu X columns]{\textt X columns} parameters, commas are optional. +% +% Example:\par\nobreak +% {\tabcolsep=3pt\def\margintext#1{\noalign{\vtop to0pt{\marginnote{\rotatebox{45}{\ttfamily\small #1}}[-2cm]\vss}}} +% \begin{tabu*}{@{}X[-1mc]X[m]X[-2ml]@{}} \toprule +% \begin{tabu}{||[5pt]|c|c||[5pt]|} +% Hello & World +% \end{tabu} +% & +% The \env{tabu} you see on the left was made with the code on the right. +% & +% \begin{Verbatim} +% \begin{tabu}{||[5pt]|c|c||[5pt]|} +% Hello & World +% \end{tabu} +% \end{Verbatim} +% \\ \midrule \margintext{\begin{tabu}{c}Use {\pkgcolor\env{tabu\stform*}}\\ to insert \textt{Verbatim}\\ environments !\end{tabu}} +% \begin{tabu}{||[5pt red]|c|c||[5pt Indigo]|} +% Hello & World +% \end{tabu} +% & +% The \env{tabu} you see on the left was made with the code on the right. +% & +% \begin{Verbatim} +% \begin{tabu}{||[5pt red]|c|c||[5pt Indigo]|} +% Hello & World +% \end{tabu} +% \end{Verbatim} +% \\ \bottomrule +% \multicolumn3{r}{\scriptsize\lk This example was printed inside a \env{tabu\stform*} whose preamble is: \textt{X[$-$1m]\,X[m]\,X[-2m]}} +% \end{tabu*} +% } +% +% It is not a necessary to protect the optional argument with braces: \M*[\M*{...}]. +% because \thispackage takes care the \textt\textbar\ token to be rewritten +% before any other column type (the same for \textt{tabu X} columns,\, and\, \Xpackage{siunitx} \textt S columns). +% The rewriting process is divided into three stages under control inside a \env*{tabu}. +% +% \subsection{Multiple \cs{firsthline} and \cs{lasthline}} +% +% \begin{declcs}{firsthline}\M[extratabsurround] \qquad make multiple lines ! \\ +% \csanchor{firstline} \M[extratabsurround]\cs\hline \\ +% \csanchor{lasthline}\M[extratabsurround] \\ +% \csanchor{lastline} \M[extratabsurround]\cs\hline +% \end{declcs} +% +% \cs\firsthline and \cs\lasthline are defined in \xfile{array.sty} and +% can be used to preserve the alignment of text, when using horizontal lines. +% Besides, the optional argument can be used to change (locally) the \cs\extratabsurround dimension. +% +% The example of \xpackage{array} documentation is:\par\nobreak +% {\centering +% \begin{tabu}to 10.5cm{|[test]*2{X[mc]|[test]}} \tabucline[test]- +% Tables +% \begin{tabu}[t]{c} +% with no\\ line \\ commands \\ used +% \end{tabu} +% versus tables +% \begin{tabu}[t]{|c|} +% \firsthline +% with some \\ line \\ commands \\ +% \lasthline +% \end{tabu} used. +% & +% Tables +% \begin{tabu}[t]{c} +% with no\\ line \\ commands \\ used +% \end{tabu} +% versus tables +% \begin{tabu}[t]{|c|} +% \hline +% with some \\ line \\ commands \\ +% \hline +% \end{tabu} used. +% \\ \tabucline[.7pt on1.5mm Crimson off3mm blue]- +% \rowfont[c]{} +% with \cs\firsthline and \cs\lasthline & with \cs\hline \par (text alignment is not preserved) +% \\ \tabucline[test]- +% \end{tabu} +% \par} +% +% Now with \env{tabu} you can make double, triple (or more) \cs\firsthline or \cs\lasthline as in:\par\nobreak +% {\centering +% \tabulinesep=1mm\tabulinestyle{test} +% \begin{tabu*}{|@{}X[-.5m]@{}|X[2m]@{}|m{4.5cm}|} \tabucline- +% \tikz{\node [rotate=65,inner sep=0pt,outer sep=0pt] +% {\begin{tabu}{c}Top \\ alignment\end{tabu}};} +% & +% \indent +% \begin{Verbatim}[commandchars=$()] +% Tables +% \begin{tabu}[($bf$red(t))]{c} +% with no\\ line \\ commands \\ used +% \end{tabu} +% versus tables +% \begin{tabu}[($bf$red(t))]{|c|} +% ($db(\firsthline))\hline\hline\hline +% with some \\ line \\ commands \\ +% ($db(\lasthline))\hline\hline\hline +% \end{tabu} used. +% \end{Verbatim} +% & +% Tables +% \begin{tabu}[t]{c} +% with no\\ line \\ commands \\ used +% \end{tabu} +% versus tables +% \begin{tabu}[t]{|c|} +% \firsthline\hline\hline\hline +% with some \\ line \\ commands \\ +% \lasthline\hline\hline\hline +% \end{tabu} used.% +% \\ \tabucline[testdash]- +% \tikz{\node [rotate=65,inner sep=0pt,outer sep=0pt] +% {\begin{tabu}{c}Bottom \\ alignment\end{tabu}};} +% & +% \indent +% \begin{Verbatim}[commandchars=$()] +% Tables +% \begin{tabu}[($bf$red(t))]{c} +% with no\\ line \\ commands \\ used +% \end{tabu} +% versus tables +% \begin{tabu}[($bf$red(b))]{|c|} +% ($db(\firsthline))\hline\hline\hline +% with some \\ line \\ commands \\ +% ($db(\lasthline))\hline\hline\hline +% \end{tabu} used. +% \end{Verbatim} +% & +% Tables +% \begin{tabu}[t]{c} +% with no\\ line \\ commands \\ used +% \end{tabu} +% versus tables \tracingtabu=3 +% \begin{tabu}[b]{|c|} +% \firsthline\hline\hline\hline +% with some \\ line \\ \tikzlabel{extratabstrut}commands \\ +% \lasthline\hline\hline\hline +% \end{tabu} used.% +% \\ \tabucline- +% \end{tabu*} +% \par} +% +% \begin{tabu}{X[-1]X[-1r]X[-1]} +% \cs\firsthline \cs\firsthline \cs\firsthline &is equivalent to: &\cs\firsthline \cs\hline \cs\hline \\ +% &and also to: &\cs\firstline \cs\hline \cs\hline \cs\hline +% \end{tabu} +% +% But the optional argument must come in \emph{first position}: \cs\firsthline\M*[extratabsurround] ... +% +% The same for \cs\lastline. +% +% In \textcolor{yellow}{yellow} you can see the \cs\extratabsurround strut, because \cs\tracingtabu$=3$ for this \env{tabu} +% \tikz[remember picture,overlay]{\draw [->,thick,gray] (0,0) -- (1,0) |- ([yshift=-3mm]extratabstrut);} +% +% +% \subsection(Lines styles){More style for lines} +% +% \begin{declcs}{taburulecolor}\M{rule color} \\ +% \cs\taburulecolor\M|double rule sep color|\M{rule color} +% \end{declcs} +% +% \cs\taburulecolor sets (in a ``locally-global'' way) the color to be used for \cs\hline, \cs\firsthline, \cs\lasthline and +% also vertical lines if the standard line style is used (the standard line style is active after \cs\tabulinestyle\M*{} or after +% \cs\tabureset). +% +% The optional parameter enclosed by vertical bars: \texttbf\textbar \meta{double rule sep color}\texttbf\textbar \, is the color +% to set between two adjacents rules. If not specified, double (or triple...) rules are separated by a vertical space (\cs\vskip). +% +% {\smaller +% \setbox\tempbox=\vbox{\linewidth=.55\linewidth \hsize\linewidth +% \begin{lstlisting} +% \taburulecolor |lime|{DarkSlateBlue} +% \arrayrulewidth=1mm \doublerulesep=2mm +% Here is +% \begin{tabu}spread 0pt {X[-1]} +% \firsthline\hline +% a tabu \\ +% environment \\ +% made with \\ \lasthline[5mm]\hline\hline +% \end{tabu} \TabU package !\par +% And the next paragraph follows... +% \end{lstlisting}} +% +% \begin{tabu}{X[mc]X[-1mc]} +% \indent\copy\tempbox +% & +% \taburulecolor |lime|{DarkSlateBlue} +% \arrayrulewidth=1mm \doublerulesep=2mm +% Here is +% \begin{tabu}spread 0pt {X[-1]} \firsthline\hline +% a \env{tabu} \\ +% environment \\ +% made with \\ \lasthline[5mm]\hline\hline +% \end{tabu} \TabU package !\par +% And the next paragraph follows... +% \end{tabu} +% } +% +% \begin{declcs}{tabulinestyle}\M{line style specification} +% \end{declcs} +% +% \cs\tabulinestyle sets the line style for vertical (\texttbf\textbar) and horizontal lines +% (\ie \cs\tabucline: \cs\hline, \cs\firsthline etc. are not modified by \cs\tabulinestyle) +% +% The line specification is of the form:\par\nobreak +% \begin{tabu*}{X[c]} +% \Verb+ 3pt rule color on 4pt dash color off 5pt gap color+ \\ +% \Verb+ rule color on 4pt dash color off 5pt gap color+ \\ +% \Verb+ on 4pt dash color off 6pt gap color+ \\ +% \Verb+ 3pt rule color+ \\ +% \Verb+ on 4pt dash color+ \\ +% \Verb+ off 5pt+ \\ +% \Verb+ 3pt+ \\ +% \Verb+ Named style defined by+ \cs\newtabulinestyle +% \end{tabu*} +% +% Well... any parameter is optional. Obviouly the \textt{rule color} is the same as the \textt{dash color} and +% the former overwrites the latter if both are given. +% +% Your color names can contain spaces but: +% \begin{itemize}[leftmargin=2em] +% \item If the first character in the line specification is not a letter, then it is taken as a dimension: the thickness of the line. +% Otherwise, the default thikness is used \ie \cs\arrayrulewidth. +% \item Your color names must not contain any series of characters that match one the patterns: \\ +% \indent\begin{tabu}{*2{X[c]}} \textt{on}\textttbf? & \textt{off}\textttbf?\end{tabu} +% where\, \texttbf?\, is a character of category 12, different from\, \texttbf !\, and possibly preceded by spaces. +% I don't think this is a real limitation... +% \end{itemize} +% +% +% \begin{declcs}{newtabulinestyle}\M{style=line spec., style=line spec., ...}\textsuperscript{babel} +% \end{declcs} +% +% This command defines a line style to be used in the first optional argument of \cs\tabucline (horizal lines) +% or the optional argument of \texttbf\textbar (vertical lines) or with \cs\tabulinestyle (locally-global style). +% +% Style names and color names are \xpackage{babel}-protected. +% +% \begin{declcs}{tabucline}\M[style or spec.]\M*{start-end}\\ +% \end{declcs} +% +% \cs\tabucline is an attempt to give a versatile command to make horizontal lines: +% \begin{itemize} +% \item \cs\tabucline is pretty good with vertical lines even if the thickness of the line grows up, +% \item \cs\tabucline takes care of \cs\extrarowheight, +% \item \cs\tabucline can make horizontal dashed lines, with a \xpackage{pgf}/\xpackage{TikZ} syntax:\\ +% \cs\tabucline\M*[\meta{width} on\meta{dash} off\meta{gap}]\M*{\meta{first column}-\meta{last column}} +% \item alternatively, you can give \cs\tabucline a \cs\hbox to make a leader with it: The \meta{\ttfamily spec.} must then +% begin with \cs\hbox, \cs\box or \cs\copy, +% \item finally you can give \cs\tabucline a color \emph{name}, after the line specification. +% \end{itemize} +% +% Any parameter can be omitted. \newtabulinestyle{tabucline=.4pt on2pt off1.5pt} +% +% {\parskip=0pt\topsep=0pt \tabulinesep=1.5mm +% \begin{center}\def\margintext#1{\noalign{\vtop to0pt{\marginnote{\ttfamily\small #1}[-1.8ex]\vss}}}^^A +% \begin{tabu}{|[1.5pt]|>{\ttfamily}X[-1]X||[1.5pt]} \tabucline[\heavyrulewidth]- \savetabu{tabucline} +% \cs\tabucline\M*[1pt on 1.5pt off 2pt]\M*{1-4} & draws a horizontal dashed line of width \textt{1pt}. Dashes are +% \textt{1.5pt} long and gap width is \textt{2pt}. The line is drawn +% between columns 1 and 4. Here there are only 2 columns and the line +% stops at column 2. \\ \tabucline[1pt on 1.5pt off 2pt]{1-4} \margintext{[1pt on 1.5pt off 2pt]} +% \cs\tabucline\M*[1.5pt]\M*{-} & draws a horizontal solid line of width \textt{1.5pt} between the first +% and the last column. \\ \tabucline[1.5pt]{-} \margintext{[1.5pt]} +% \cs\tabucline\M*{2-} & \spaceskip=\fontdimen2\font plus1em\relax draws a horizontal solid line of width \cs\arrayrulewidth between the second +% column and the last one.\\ \tabucline{2-} \margintext{default} +% \cs\tabucline\M*[on 2pt red]\M*{-5} & draws a horizontal dashed line between columns 1 and 5 +% of width \cs\arrayrulewidth. Dashed are +% \textt{2pt} long and gap width is \textt{4pt} (the default). +% \\ \tabucline[on 2pt red]{-5} \margintext{[on 2pt red]} +% \end{tabu} +% \end{center}} +% +% \begin{tabu}{@{}X[-2,c]@{}X[c]@{}} \tabucline[\heavyrulewidth]- \tabucline[\hbox{$\scriptstyle\star$}]- \toprule +% \rowfont[c]{\bfseries} +% Define the line style &Use the line style \\\midrule +% \cs\newtabulinestyle\M*{myline=0.4pt on 2.5pt off 1pt red} &\cs\tabucline\M*[myline]\M*{-} \\\tabucline[\heavyrulewidth on 2.5pt off 1pt red]- +% \multicolumn2c{Or use a leader or a box to make a leader with it} \\ +% \multicolumn2c{directly in the argument of \cs\tabucline} \\ +% \multicolumn2c{\cs\tabucline\M*[\cs\hbox\M*{\$\cs\scriptstyle\cs\star\$}]\M*{1-3}} +% \\\bottomrule \tabucline[\hbox{$\scriptstyle\star$}]- \tabucline[\heavyrulewidth]- +% \end{tabu} +% +% \begin{tabu}{*{3}{X[cm]}} +% \tabcolsep=2pt +% \begin{tabu}{|l|l|} \tabucline[.4pt on 1pt off 3pt]{-} +% \multicolumn2{|c|}{Dashed or dotted} \\\tabucline[1pt on2pt off1pt]{-} +% And below &is the default \\\tabucline[on 4pt]- +% \end{tabu} +% & +% \tabcolsep=2pt +% \begin{tabu}{|c|c|} \tabucline[.4pt off 2pt]{-} +% Dash &Gap \\\tabucline[10pt on2pt off 1pt]{1-2} +% \multicolumn2{|c|}{This one was thick} \\\tabucline[3pt]- +% \end{tabu} +% & +% \tabcolsep=2pt +% \begin{tabu}{|X[cm]|X[cm]|X[2cm]|} \tabucline[.4pt on6pt off 2pt]{-} +% Dash &Gap... &...or leader +% \\\tabucline[\hbox{\small\kern1pt\ScissorRight\vrule width3.4pt depth-5pt height5.4pt\kern1pt\vrule width3.4pt depth-5pt height5.4pt\kern1pt}]- +% \multicolumn3{|c|}{Interesting ?} \\\tabucline- +% \end{tabu} +% \end{tabu} +% \nobreak\par\nobreak\vspace*{\bigskipamount}\nobreak +% +% +% \subsection{Automatic horizontal lines and row colors} +% +% \begin{declcs}{everyrow}\M*{code} +% \end{declcs} +% +% \cs\everyrow can be used to insert horizontal lines automatically: +% +% {\smaller +% \begin{lstlisting} +% \begin{tabu}to .5\linewidth{cX[2mc]X} \tabucline[1pt]- +% \everyrow{\tabucline[on 2pt]-} +% This is &a small example &of a \textt{tabu} \\ +% which &automatically &inserts \\ +% a horizontal &line after &each of its row \everyrow{} \\ \tabucline[1pt]- +% \end{tabu} +% \end{lstlisting} +% +% \centering +% \tabulinesep=3pt +% \begin{tabu}to .5\linewidth{cX[2c]X} \tabucline[1pt]- \everyrow{\tabucline[on 2pt]-} +% This is &a small example &of a \textt{tabu} \\ +% which &automatically &inserts \\ +% a horizontal &line after &each of its row \everyrow{} \\\tabucline[1pt]- +% \end{tabu}\par} +% +% \cs\everyrow can be used in \textt{longtabu} as well. The syntax is like \cs\everycr: a token-like syntax, +% and braces are mandatory:\quad \cs\everyrow\M*{argument}. +% +% \begin{declcs}{taburowcolors}\M*[first line]\meta{number}\M*{first .. last} +% \end{declcs} +% +% \cs\taburowcolors sets the alternate colors to be used on every row of the tabular. +% The command can be used before a \env*{tabu} or inside it, at the end of a row. +% +% The optional parameter \M*[first line] tells the first row from which background colors +% are starting -- this optional parameter has no effect when \cs\taburowcolors is used at the +% end of a row: background are starting immediately in this case. +% +% \meta{number} is the number of colors in the color series. If not specified, it defaults +% to $2$ (for alternate rows color). +% +% Finally \meta{first} and \meta{last} are the first and the last colors in the colorseries. +% +% +% Example: +% +% { +% \setbox\tempbox=\vbox{\linewidth=.55\linewidth\hsize\linewidth\smaller +% \begin{lstlisting} +% \taburowcolors[2] 3{Crimson!30 .. +% ForestGreen!40} +% \taburulecolor |GreenYellow|{OrangeRed} +% \arrayrulewidth=1pt \doublerulesep=1.5pt +% \everyrow{\hline\hline} +% \begin{tabu} {X[-1]X} +% This is &just a test \\ +% and i think &it will \\ +% look &rather bad \\ +% for &i've not \\ +% chosen &the colors \\ +% with care. &i can't \\ +% say &less... \\ +% \taburowcolors 2{Crimson .. ForestGreen} +% 1 &This is Crimson \\ +% 2 &This is ForestGreen \\ +% 3 &This is Crimson \\ +% 4 &This is ForestGreen \\ +% \end{tabu} +% \end{lstlisting}} +% +% \begin{tabu}{X[m]X[-1m]} +% \indent\copy\tempbox +% & +% \taburowcolors[2]3{Crimson!30 .. ForestGreen!40} +% \taburulecolor |GreenYellow|{OrangeRed} +% \arrayrulewidth=1pt \doublerulesep=1.5pt +% \everyrow{\hline\hline} +% \begin{tabu}{X[-1]X} +% This is &just a test \\ +% and i think &it will \\ +% look &rather bad \\ +% for &i've not \\ +% chosen &the colors \\ +% with care. &i can't \\ +% say &less... \\ +% \taburowcolors 2{Crimson .. ForestGreen} +% 1 &This is Crimson \\ +% 2 &This is ForestGreen \\ +% 3 &This is Crimson \\ +% 4 &This is ForestGreen \\ +% \end{tabu} +% \end{tabu} +% } +% +% \begin{declcs}{tabureset} +% \end{declcs} +% +% To go back to ``standard'' parameters, \thispackage provides the command \cs\tabureset which basically does: +% +% \begin{tabu}{||[on 3pt pkgcolor off 3pt]XXX|[on 3pt pkgcolor off3pt]|} +% \cs\tabulinesep$=0pt$ &\cs\extrarowsep$=0pt$ &\cs\extratabsurround$=0pt$ \\ +% \cs\tabulinestyle\M*{} &\cs\everyrow\M*{} &\cs\taburulecolor\M*||\M*{} \\ +% \cs\taburowcolors\M*{} & & +% \end{tabu} +% +% +% \section(row font and alignment){Modifying the font and the alignment in one row: \cs{rowfont}} +% +% \begin{declcs}{rowfont}\M[alignment]\M*{font specification} +% \end{declcs} +% +% Inside a \env*{tabu}, you can modify the font for each cell in a row. +% \cs\rowfont has priority over column font specification, exactly like \cs\rowcolor (package \xpackage{colortbl}) +% has priority over \cs\columncolor. +% +% The alignment of each cell in one row can also be changed to: \topsep=0pt +% \begin{center} +% \begin{tabu}{>{\ttfamily}r@{\,$=$\,}lc>{\ttfamily}r} +% l &left &{\qquad\smaller or\, for \xpackage{ragged2e} settings: } &L \\ +% c ¢er & &C \\ +% r &right & &R \\ +% j &justify & &J \\ +% \end{tabu} +% \end{center} +% +% Any other value for the optional \meta{alignment} parameter is silently ignored. If \xpackage{ragged2e} is not loaded, +% \textt L\, \textt R\, \textt C\, and\, \textt J\, are synonymous with the lowercase equivalent. +% +% \begin{Verb*} +% \begin{tabu}{|X|X[-1]|} \tabucline- +% ($db(\rowfont))[c]\bfseries +% This &Is \\\tabucline[on 2pt,blue]- +% \xpackage{tabu} &package \\\tabucline[off 2pt blue]- +% ($db(\rowfont))[r]\itshape +% for &\textt{tabu} and \textt{longtabu} \\\tabucline- +% \end{tabu} +% \end{Verb*} +% +% \begin{tabu}{|X|X[-1]|}\tabucline- +% \rowfont[c]\bfseries +% This &Is \\\tabucline[on 2pt,blue]- +% \xpackage{tabu} &package \\\tabucline[off 2pt blue]- +% \rowfont[r]\itshape +% for &\textt{tabu} and \textt{longtabu} \\\tabucline- +% \end{tabu} +% +% +% \section(Saving and restoring tabu)[Saving and restoring a \env{tabu}: \cs{savetabu}, \cs{usetabu} and \cs{preamble}]{Saving and restoring a \env{tabu}} +% +% \begin{declcs}{savetabu}\M{user-name} +% \end{declcs} +% +% The command \cs\savetabu can be used at the end of any line of a \env*{tabu} to save the +% parameters of a \env*{tabu}. The saving is always global. +% This allows to easily make tabulars which share exactly the same shape throughout your document. +% This can also be used as a kind of \env{tabbing} environment which is able to remember the tabs positions... +% +% If the \meta{user-name} has been used before, an info is displayed in the \xext{log} file and the +% previous settings are overwritten. +% +% With the \cs\tracingtabu $>0$, informations about the saved parameters are reported in the \xext{log} file. +% +% Recalling saved parameters are done with \cs\usetabu (complete recovery) or \cs\preamble (partial recovery of +% the preamble only). +% +% \begin{declcs}{usetabu}\M{user-name} +% \end{declcs} +% +% \cs\usetabu is the complement of \cs\savetabu: it can be put alone in the \env{tabu} preamble instead +% of the usual columns specifications to restore any previous settings saved with \cs\savetabu. +% +% The \meta{user-name} must exist otherwise, you get an error. +% +% \cs\usetabu is a help to \textbf{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. +% +% \cs\usetabu does not work with \hyperref[longtabu.sec]{\env{longtabu}}. +% +% \Needspace{2\baselineskip} +% +% \cs\usetabu locally restores:\nobreak +% \begin{itemize} +% \item the preamble\footnote{The complete \cs\halign-preamble is restored.}. +% \item the vertical position \M*[c],\, \M*[b]\, or\, \M*[t], unless another position is specified. +% \item the target width of the \env{tabu} in points: the saved target width does not contain +% any control sequence: it is fixed and stored in points. +% \item the width of \textt{tabu X} columns: those widths are not calculated any more -- even in the case +% of negativ coefficients -- and \textt X columns are directly transformed into +% \textt p, \textt m or \textt b columns of the same widths as the ones that where calculated +% at the time of \cs\savetabu +% \item \cs\tabcolsep (or \cs\arraycolsep in math mode)\, \cs\extrarowheight,\, \cs\extrarowdepth,\, \cs\arraystretch\, and\, \cs\extratabsurround +% \item \cs\arrayrulewidth,\, \cs\doublerulesep\, and the parameters for \cs\everyrow\, \cs\taburulecolor,\, \cs\tabulinestyle,\, and\, +% \cs\taburowcolors +% \item \cs\minrowclearance,\, (package \Xpackage{colortbl}) +% \end{itemize} +% +% \cs\abovetabulinesep\,and\, \cs\belowtabulinesep are not restored, because they are related to the +% content of the tabular rather than to its shape. +% \medskip +% +% Example: +% +% {\smaller +% \begin{lstlisting} +% \tabcolsep=12pt \extrarowsep=1mm +% \tabulinestyle{on 1pt ForestGreen} +% \begin{tabu}to .7\linewidth{|XXX|X[c]|} \savetabu{mytabu} \tabucline- +% This & is & tabu & package \\ \tabucline- +% \end{tabu} +% \end{lstlisting}} +% +% \begin{center} +% \tabcolsep=12pt\extrarowsep=1mm \tabulinestyle{on 4pt ForestGreen} +% \begin{tabu}to .7\linewidth{|XXX|X[c]|} \savetabu{mytabu} +% \tabucline- +% This & is & tabu & package \\ \tabucline- +% \end{tabu} +% \end{center} +% +% \Needspace{3\baselineskip} +% +% {\smaller +% \begin{lstlisting} +% \tabureset +% \begin{tabu}{\usetabu{mytabu}} \tabucline- +% \multicolumn3{|c}{This is tabu} & package \\ \tabucline- +% \tabuphantomline +% \end{tabu} +% \end{lstlisting}} +% +% \begin{center} +% \tabureset +% \begin{tabu}{\usetabu{mytabu}} \tabucline- +% \multicolumn3{|c|}{This is tabu} & package \\ \tabucline- +% \tabuphantomline +% \end{tabu} +% \end{center} +% +% +% If one day you use \env{tabu}, you will have the idea to restore a \env{tabu} while modifying its target, +% or adding new columns... \cs\savetabu and \cs\usetabu have not been thought for this purpose, and you may +% have unexpected results. +% +% \begin{declcs}{preamble}\M{user-name} +% \end{declcs} +% +% \cs\preamble can also be used after \cs\savetabu. This is a variant of \cs\usetabu that locally restores: +% \begin{itemize} +% \item the \env{tabu} (or \env{longtabu}) preamble. +% \item the vertical position \M*[c],\, \M*[b]\, or\, \M*[t] (or \M*[c],\, \M*[l]\, or\, \M*[r] for \env{longtabu}), +% unless another position is specified. +% \item the \env{tabu} / \env{longtabu} target width, unless another target is specified. +% \end{itemize} +% Any other tabular parameter is not restored. +% +% Put \cs\preamble\M{user-name} alone inside the \env{tabu} (or \env{longtabu}) preamble in place of the usual +% columns specifications. +% +% \cs\preamble works exactly as if you defined a \hyperref[Custom environments]{custom environment} for \env{tabu}. +% +% \cs\preamble works with \hyperref[longtabu.sec]{\env{longtabu}}. +% +% Example (continued...): +% +% {\smaller +% \begin{lstlisting} +% \tabulinestyle{1pt off1pt} +% \begin{tabu} to\linewidth{\preamble{mytabu}} \tabucline- +% This &is &tabu &package \\ \tabucline- +% \end{tabu} +% \end{lstlisting}} +% +% {\tabulinestyle{1pt off1pt} +% \begin{tabu} to\linewidth{\preamble{mytabu}} \tabucline- +% This &is &\textt{tabu} &package \\\tabucline- +% \end{tabu} +% } +% +% \cs\tabcolsep, rule colors etc. are not restored from \cs\savetabu: the only \env{tabu} preamble is restored. +% +% \section{Some other features} +% +% \subsection(Numbers in tabu){Printing numbers inside \textt{tabu} with \xpackage{numprint} and \xpackage{siunitx}} +% +% \subsubsection{\cs{tabudecimal}} +% +% \thispackage provides a \emph{facility} to print numbers inside columns. This facility is not +% implemented to replace \xpackage{siunitx} \textt S and \textt s columns or \xpackage{numprint} +% \textt n and \textt N columns or other packages that provide alignment such as \xpackage{warpcol}, +% \xpackage{dcolumn} or \xpackage{rccol}. It just make +% easy to apply a macro you get already on each number in a column of a \env{tabu}. +% +% \cs\tabudecimal has been developped mainly because it makes possible to align numbers inside \textt{tabu X} columns. +% +% \begin{declcs}{tabudecimal}\M{user-macro} +% \end{declcs} +% +% \cs\tabudecimal can be used in the preamble of a \env{tabu} before a column specification. +% The \meta{user-macro} is a macro with one parameter that has to be defined before. +% +% \medskip +% +% Example with \csbf\numprint: +% +% \begin{Verb*} +% \def\usermacro#1{\numprint[\officialeuro]{\zap@space #1 \@empty}} +% \nprounddigits{2} \npprintnull \npthousandsep{\,} \npunitseparator{~} +% \end{Verb*} +% +% \nprounddigits{2} \npprintnull \npthousandsep{\,} \npunitseparator{~} +% \makeatletter \let\npunitcommand\@firstofone +% \def\usermacro#1{\numprint[\officialeuro]{\zap@space #1 \@empty}} +% \makeatother +% +% \begin{tabu*}{XX} +% { +% \begin{Verbatim} +% \rowfont[c]{\bf} January & February \\ +% 12.324 & 745.32 \\ +% 21.13 & 0 \\ +% 213.3245 & 12.342 \\ +% 2143.12 & 324.325 \\ +% \end{tabu} +% \end{Verbatim} +% } +% & +% \taburulecolor{GreenYellow} +% \begin{tabu}{|*2{>{\tabudecimal\usermacro}X[r]|}c} \tabucline[1pt GreenYellow]- +% \rowfont[c]\bf January &February & ...\\ \tabucline[1pt on2pt GreenYellow]- +% 12.324 &745.32 & ... \\ +% 21.13 &0 & ... \\ +% 213.3245 &12.342 & ... \\ +% 2143.12 &324.325 & ... \\ \tabucline[1pt GreenYellow]- +% \end{tabu} +% \end{tabu*} +% +% \medbreak +% +% Example with \csbf\SI: +% +% \begin{Verb*} +% \def\usermacro#1{\SI[group-four-digits=true, % thousand separator +% round-mode=places, % round numbers +% round-precision=2, % with 2 decimal digits +% round-integer-to-decimal=true, % add trailing 0 if necessary +% per-mode=symbol]{#1}{\officialeuro\per\kilo\gram}} +% \begin{tabu}spread 0pt{|[GreenYellow]*2{>{\tabudecimal \usermacro}X[r]|[GreenYellow]}} .... +% \end{Verb*} +% +% +% \def\usermacro#1{\SI[group-four-digits=true, +% round-mode=places, +% round-precision=2, +% round-integer-to-decimal=true, +% per-mode=symbol]{#1}{\officialeuro\per\kilo\gram}} +% \begin{tabu}{*2{X}} +% \tabulinesep=3pt \taburulecolor{GreenYellow} +% \begin{tabu}spread 8pt{|*2{>{\tabudecimal\usermacro}X[r]|}c} \tabucline[1pt GreenYellow]- +% \rowfont[c]\bf January &February &... \\\tabucline[1pt on2pt GreenYellow]- +% 12.324 &745.32 &... \\ +% 21.13 &0 &... \\ +% 213.3245 &12.342 &... \\ +% 2143.12 &324.325 &... \\\tabucline[1pt GreenYellow]- +% \end{tabu} +% & +% As you can see, the columns widths are exactly the same, whatever their content. \par \bigskip +% Here \cs\tabulinesep has been set to $3pt$. +% \end{tabu} +% +% \subsubsection{You should know how it works...} +% +% Yes you should know how it works to avoid problems. \env{tabu} has a small scanner +% based on \cs\futurelet to grab all numbers, blank spaces, commas and dots $+$ and $-$ sign +% and also the letter \textt e and \textt E for exponants. +% The scanner stops as soon as something else than a number, blank space, comma, dot, $+$, $-$, \textt e, \textt E +% is found, and even if it is a macro that contains a number. +% +% This explains why there is \cs\zap@space in the definition of \cs\usermacro: because the scanner +% scans blank spaces and because \cs\numprint does not allow blank spaces in its mandatory argument, +% quite strangely... +% +% +% \subsection{Paragraph indentation} +% \label{Paragraph indentation.subsec} +% +% \env{tabu} takes care of paragraph indentation when it is used with \textt X columns and its default target, +% no matter if it has been loaded or not with the \textt{linegoal} option. +% Example with \LaTeX{} default: \cs\parindent $=20$pt. +% +% {\parindent=20pt \let\tabudefaulttarget \linewidth \tabulinestyle{GreenYellow} +% +% \begin{tabu}{|X|} \tabucline- +% This is \env{\pkgcolor tabu} with its default target in an indented paragraph. \\ \tabucline- +% \end{tabu} +% +% \noindent\begin{tabu}{|X|}\tabucline- +% This is \env{\pkgcolor tabu} with its default target, preceded by \cs\noindent \\ \tabucline- +% \end{tabu} +% +% +% \begin{tabularx}\linewidth{|X|} \hline +% This is \env{tabularx} with target: \cs\linewidth in an indented paragraph. \\ \hline +% \end{tabularx} +% +% \noindent\begin{tabularx}\linewidth{|X|} \hline +% This is \env{tabularx} with target: \cs\linewidth, preceded by \cs\noindent \\ \hline +% \end{tabularx} +% +% } +% +% +% \subsection{\texorpdf\xpackage{delarray} shortcuts} +% \label{delarray shortcuts tabularx.subsec} +% +% When you enclose your tabular with math delimiters using \xpackage{delarray} shortcuts, +% \thispackage tries to reach its target for the whole: the tabular and the delimiter(s). +% You can see the difference: +% +% {\centering +% \extrarowsep=8pt +% +% \AtBeginShipoutNext{\AtBeginShipoutUpperLeft{\tikz[remember picture,overlay] +% \node at (tabularx overfull) [xshift=-3cm,yshift=-1.5cm,align=center,text width=5cm,rotate=40,font=\ttfamily\smaller] +% {{with overfull hboxes\\ +% (17.5pt and 17.8pt two wide)\\ +% for \xpackage{tabularx} +% }}; }} +% +% \renewcommand\text[1]{This is +% {\ttfamily \ifcurrentenvir{tabu}{\pkgcolor\lsstyle}{}\currentenvirname} +% with \xpackage{delarray} shortcuts for #1 around.} +% +% \tabcolsep=10pt \tabulinesep=3mm \tabulinestyle{.7pt pkgcolor} +% \begin{tabu}to 12cm{|*2{X|}} \tabucline- +% \begin{tabu}({X}) \tikzlabel{tabularx overfull} +% \text{parenthesis} \end{tabu} +% & +% \begin{tabu}\{{X}\} +% \text{curly brackets} \end{tabu} +% \\ \tabucline[1pt on2pt pkgcolor]- +% +% \begin{tabularx}{\linewidth}[t]({X}) +% \text{parenthesis} \end{tabularx} +% & +% \begin{tabularx}{\linewidth}[t]\{{X}\} +% \text{curly brackets} \end{tabularx} +% \\ \tabucline- +% \end{tabu} +% +% {\hfill\scriptsize\lk Here \cs\tabulinesep$=3mm$\par} +% } +% +% \section(Differences: tabu, tabular, tabularx, longtable){Differences between \env{tabu},\, \env{tabular},\, \env{tabularx} and \env{longtable}} +% +% \subsection{Paragraph indentation} +% +% See \nameref{Paragraph indentation.subsec} +% +% \subsection{Custom environments} +% \label{Custom environments} +% +% Unlike \env{tabularx}, it is possible to define your own environment using \env{tabu}: +% +% \begin{Verbat} +% \newenvironment{foo} +% {\begin{tabu}{X[1.2]|[1pt gray]X}} +% {\end{tabu}} +% \end{Verbat} +% +% \newenvironment{footabu} +% {\begin{tabu}{@{}X[1.2]|[1pt,gray]X@{}}} +% {\end{tabu}} +% +% \begin{footabu} +% \env*{tabu}, even when \textt X columns are used, may appear +% in the definition of your custom \env*{tabular}. +% & +% You can also use the commands \cs\savetabu\, \cs\preamble\, (or\, \cs\usetabu) for this purpose. +% \end{footabu} +% +% +% +% \subsection{Inversion of tokens} +% \label{subsec:inversion of tokens} +% +% \begin{SaveVerbatim}{tempVerb} +% \begin{tabular}{|>{\bfseries}>{ before }l<{ one }<{ two }|} +% cell content +% \end{tabular} +% \end{SaveVerbatim} +% +% +% When you typeset the following \env{tabular}: +% \UseVerbatim{tempVerb} +% +% \begin{tabu}to .9\linewidth{XX} \savetabu{tabbing} +% You get the following result: +% & +% \begin{tabular}{|>{\bfseries}>{ before }l<{ one }<{ two }|} +% cell content +% \end{tabular} +% \end{tabu} +% +% +% \smex The word \emph{before} is not bold, and \textitbf{two} comes before \textitbf{one}. +% +% The reason is explained in the documentation of \xfile{array.sty}, and is related +% to the \env*{array} in math mode when using \cs\newcolumntype. +% +% This rather strange inversion of tokens may be justified in math mode (otherwise, errors may occur) +% but not in text mode in our opinion. Inside a \env*{tabu}, when not in math mode, +% the tokens are not reversed and you get the intuitively expected result: +% +% \begin{tabu}{\usetabu{tabbing}} +% \indent & +% \begin{tabu}{|>{\bfseries}>{ before }l<{ one }<{ two }|} +% cell content +% \end{tabu} +% \end{tabu} +% +% In math mode however, tokens are in the reverse order in the \env*{tabu} +% like they are in the \env*{array}. +% +% \subsection(Improved rewrite process){Improved process for rewriting columns \textmd{\emph{(for keen readers)}}} +% +% Any tabular that does not split accross pages is made with the following process: +% +% \begin{tikzpicture}[ +% start chain=going below, every join/.style={->,thin,black,solid},node distance=.5cm and 1cm, +% every node/.style={black,on chain}] +% \node (initialisation) at (0,0) {\begin{tabu}{c} initialisation \\ \cs\hbox\end{tabu}} +% node (@array) [join] {\cs\@array} +% {[start branch] +% node (@arraydesc) [join] {% +% \begin{tabu}\{{l}. +% \begin{tabu}[c].{l}\} +% \cs\begingroup \\ +% \qquad \cs{@mkpream}\M*{preamble} \\ +% \cs\endgroup \\ +% \end{tabu} ``\textt{@mkpream}'' group +% \\[4ex] +% \cs\halign\M*{\cs{@preamble} \textellipsis\ tabular content } +% \end{tabu}} +% } +% node (end) [join] {end of \cs\hbox}; +% \end{tikzpicture} +% +% For more details, see the \nameref{Flow chart of expansion}. +% +% +% \cs\@mkpream works in two times inside a (semi-simple) group: +% +% \begin{description}[font=\mdseries\itshape,topsep=0pt,itemsep=0pt] +% \item [First the rewriting process:] \ \\ +% Each special column in the tabular preamble is transformed into +% one the columns defined by \xfile{array.sty}. +% \item [Second the building of the \textup{\cs\halign} preamble:] \ \\ +% The ``rewritten preamble'' is parsed and transformed in a preamble for the \TeX{} primitive +% \cs\halign. The result is stored into the \cs\@preamble macro. +% \end{description} +% +% Any special columns of \textt{tabu} are defined only inside the ``\textt{@mkpream}'' group. +% +% In the following example, you get an error with \env{tabular} and no error with \env{tabu}. +% With \textt{tabular}, and \xpackage{siunitx} \textt S column, the {\descfont\mdseries\itshape rewriting process} +% is as follow:\nobreak +% +% \begin{tabu*}{@{}X[m]X[m1.2]@{}} +% \begin{Verbatim} +% \documentclass{minimal} +% \usepackage{numprint,siunitx,xcolor} +% \usepackage{tabu} +% \begin{document} +% +% \begin{tabular}{*2{S[color=green]}} +% 123,45 +% \end{tabular} +% +% \begin{tabu}{*2{S[color=green]}} +% 123,45 +% \end{tabu} +% +% \end{document} +% \end{Verbatim} +% & +% Inside \textt{tabular}: +% \begin{enumerate}[label=\arabic*),topsep=\parskip,itemsep=.5\parskip,leftmargin=3em] +% \item Rewrite \textt S: not found because inside \M*{...} +% \item Rewrite \stform* +% \item Rewrite \textt n column defined by package \xpackage{numprint} \\ +% Then the \textt `n' in \textt{gree\textcolor{red}n} is rewritten \smex problem +% \end{enumerate} +% \vskip1ex +% Inside \textt{tabu}: +% \begin{enumerate}[label=\arabic*),itemsep=.5\parskip,topsep=\parskip,parsep=\parskip,leftmargin=3em] +% \item Rewrite \stform* +% \item Rewrite \textt\textbar\ (there is none here) +% \interitem \textt{\scshape go back} +% \item Rewrite \stform* +% \item Rewrite \textt\textbar\ +% \item Rewrite \textt S +% \item Rewrite \textt n \smex not found because \textt S was rewritten before, according to \xpackage{siunitx} definition. +% \end{enumerate} +% \end{tabu*} +% +% The process of rewriting columns is usually longer inside \env{tabu} than inside \env{tabular}, +% but conversely \env{tabu} with \textt X columns is optimised compared to \env{tabularx}, +% because the preamble is built only once, and not rebuilt before each trial as \env{tabularx} does. +% Thus \env{tabu} is much quicker than \env{tabularx}. +% +% The process of rewriting is very sensitiv to the order in which columns are actually rewritten. +% This becomes critical when columns are defined with an optional argument like \xpackage{tabu} \textt X +% and \textttbf\textbar\ columns or \xpackage{siunitx} \textt S column. +% +% \Needspace{5\baselineskip} +% \section{The package options} +% +% \subsection(The debugshow option){The \textt{debugshow} package option} +% \label{debugshow}\label{debugshow package option} +% +% \begin{declcs}{tracingtabu} \\ +% \cs\tracingtabu\,=\,1, 2, 3 or 4 +% \end{declcs} +% +% The control sequence \cs\tracingtabu has the same effect as the \textt{debugshow} option: +% \begin{itemize} +% \item \thispackage will report the widths it computes at each attempt to read the target, +% when \textt X columns are used. +% \item Saved informations on the \env{tabu} are reported in the \xext{log} file when \cs\savetabu +% is used. +% \end{itemize} +% +% \begin{tabu}{X[-1]X} +% \cs\tracingtabu$=2$ & gives more information on the measures of the natural widths. \\ +% \cs\tracingtabu$=3$ & shows the struts inserted inside the \env*{tabu} and gives more information about +% the measures of the height and depth of every row. \\ +% \cs\tracingtabu$=4$ & displays information on the insertions made by \cs\tabucline. +% \end{tabu} +% +% Typical information in the \xext{log} file: +% +% {\ttfamily \noindent \tabcolsep=2pt +% \begin{tabu}{cr*3{X[2c]}X[c]X[2c]} +% \rowfont[c]{} +% (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) & \multicolumn5l{\ \ Target reached (hfuzz=0.1pt) **************** }\\ +% \end{tabu}} +% +% What does it mean? \def\pt#1{$#1$\textt{pt}} +% \begin{enumerate}[label=\arabic*),topsep=0pt,itemsep=\parskip,parsep=0pt] +% \item The first attempt was performed with \textt{X}$=$\pt{386.67296} \\ +% The \env{tabu} width (\pt{797.34592}) exceeded the target by \pt{410.67296}. \\ +% Thus \textt X has been updated: \pt{410.67296} $/2=$ \pt{205.33649} and then:\\ +% \null\quad\textt X $=$ \pt{386.67296} $-$ \pt{205.33649} $=$ \pt{181.33647} +% \item The second attempt lead to a \env{tabu} width of \pt{386.67294}: the target is reached. \\ +% The final width of each \textt X column is the product of \textt{tabu X} by its width coefficient. +% \end{enumerate} +% +% \subsection(The delarray option){The \textt{delarray} package option} +% +% \textt{delarray} option has the single effect to load \xfile{delarray.sty} for delimiters shortcuts +% around \env{tabu}. Delimiters shortcuts work both in math and text mode. +% +% \subsection(The linegoal option){The \textt{linegoal} package option} +% \label{subsec:linegoal package option} +% +% With the \textt{linegoal} option, the default target for \env{tabu} with \textt X columns is +% \cs\linegoal instead of \cs\linewidth. +% The \xpackage{linegoal} package must be loaded and compilation must be done with \hologo{pdfTeX}, +% otherwise, a warning is displayed and the \textt{linegoal} option has no effect: the default +% target remains \cs\linewidth. \cs\linegoal works with \hologo{pdfTeX} in \textt{pdf} mode +% \textbf{and in} \textt{dvi} mode. +% +% If for some reason, you wish to turn down the \textt{linegoal} option in your document, +% you can say (in a group for example): +% \verb+\let\tabudefaulttarget=\linewidth+ +% +% In any case, specifying the target overwrites the default: \cs{begin}\M*{tabu} to\cs\linewidth +% +% \section(Corrections){Corrections of some bugs \textmd{\emph{(available only inside \textt{\upshape tabu})}}} +% +% \subsection(delarray compatibility){Correction for \xpackage{colortbl} and \xpackage{arydshln}: compatibility with \xpackage{delarray}} +% +% Both \xpackage{colortbl} and \xpackage{arydshln} forget the control sequence \cs\@arrayright in their implementation, +% quite strangely because both of them take care of \cs\@arrayleft. As a result, \xpackage{delarray} shortcuts for +% delimiters around a tabular does not work if \xpackage{colortbl} and/or \xpackage{arydshln} are loaded. +% +% Those control sequences are used by the \xpackage{delarray} package to put variable size delimiters around the array:\par\nobreak +% {\centering\tabcolsep=12pt +% \begin{tabu*}{X[-1m]X[-1mc]X[-1m]} +% \begin{Verbatim} +% \begin{tabu} \{{X}. +% ... +% \end{tabu} +% \end{Verbatim} +% & +% is like: +% & +% \begin{Verbatim} +% \left\{\begin{tabu}{X} +% ... +% \end{tabu} \right. +% \end{Verbatim} +% \end{tabu*} +% } +% +% \subsection(arydshln @ columns){Correction for \xpackage{arydshln}: \texttbf @ columns} +% +% A bug in \cs\adl@xarraydashrule: \textt{!-arg} columns (class 1) and \textt{@-arg} columns (class 5) should be treated +% the same as far as rules are concerned. +% +% With this correction, the ``known problem number 1'' in \xpackage{arydshln} documentation is solved. +% +% +% \section{To do for even better \env{tabus}} +% +% In decreasing order of priority: +% +% \nprounddigits{0} +% \begin{itemize}[leftmargin=*,label=\ding{223}] +% \item Make double \cs\tabucline compatible with \xpackage{colortbl} \cs\doublerulesepcolor +% \item Multiple \cs\tabucline between different columns: extended specs: \\ +% \cs\tabucline\M[line spec]\M*{start-stop, start-stop}\M[line spec]\M*{start-stop} ... +% \item Reimplement \cs\multicolumn in order to allow the \textt X token in \cs\multicolumn preamble. \\ +% Provide \cs\multicell to allow spanning columns and rows at the same time. +% \item Presently, \env{longtabu} with \textt X columns works only if \cs\LTchunksize is greater than the number of rows. +% I compiled a \env{longtabu} of 56 pages on my PC with \cs\LTchunksize $ = $ \numprint{2000} without problem. +% Presently \cs\LTchunksize is set to \numprint{10000} during trials when \env{longtabu} contains \textt{X columns}. +% \item Make \cs\tabucline work with page breaks (one line on the top of the page, one line on the bottom of the previous). +% \end{itemize} +% +% \raggedbottom +% +% +% \StopEventually{ +% } +% +% \IMPLEMENTATION +% +% \subsection{Drawing a tabular - The \TabU approach} +% \label{tabu approach} +% +% \TabU has a different approach than almost any other package providing facilities for tabulars. +% \Xpackage{colortbl} and \Xpackage{arydshln} both put the cells contents into a box for measuring +% purpose, and then use the dimensions of each box to make their setups: +% \begin{description} +% \item [\xpackage{colortbl}] needs the dimensions of the box to put a rule in the background of the cell, +% \item [\xpackage{arydshln}] needs the dimensions to set the length of its leaders (dash lines). +% \end{description} +% +% This is achieved by modifying the macros defined in \xfile{array.sty} to insert columns inside the \cs\halign preamble. +% +% Instead, \TabU proceeds as follow: +% \begin{enumerate}[label=\arabic*.,name=tabu philosophy,nolistsep,leftmargin=2em] +% \item It first measures (if there are some negative width coefficients, or if \env{tabu spread} is used) the natural widths of the cells / the columns, +% \item Then it always measures the height and depth of each cell / row, +% \item Thereafter, the tabular is printed exactly as if \xfile{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. +% \item No macros of \xfile{array.sty} is modified at stage \refitem{tabu philosophy,3} +% \end{enumerate} +% +% \TabU material inserted in the tabular for vertical leaders, \cs\rowfont etc. is put inside the special ``free'' tokens +% provided by \xfile{array.sty}: +% \begin{itemize}[leftmargin=2em] +% \item A vertical leader is put inside a \,\texttbf !\, column:\, \texttbf{!\M*{vertical leader}} +% \item Changing font and alignment in one row requires some setup in \,\texttbf >\, tokens:\, \textttbf{>\M*{rowfont material}}. +% \end{itemize} +% +% This way, the commands of \xfile{array.sty} that build each column definition (or preamble, in the sense of \cs\halign) are never modified. +% +% \subsection{Algorithms} +% \label{algorithms} +% +% \subsubsection{\env{tabu to} target} +% \label{algorithms tabu to} +% +% The algorithm of \cs\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. +% +% \paragraph{Notations and initialisation of \textt X} +% +% In the case of \env{tabu to} the target $T=300$ is given : it is the target specified by the user or the default \env{tabu} +% target which is \cs\linewidth$-$\meta{parindent correction} or \cs\linegoal. Each \textt X column has a width +% coefficient which is given too (or default to $1$). The coefficients are: $c_1, c_2, \dots c_n$. +% +% $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: +% +% \newtabulinestyle{dash=on2pt off2pt} \tabulinesep=1mm +% \begin{tabu}{|X[2c]|*7{X[$c]}|[dash]*2{X[$c]}|} \tabucline- +% Coef $c_i$ & &c_1 &c_2 &c_3 &c_4 &c_5 &c_6 &\sum &\Delta \\\tabucline[dash]- +% & &-1 &-2 &-5 &-2 &2 &3 &15 & \\\tabucline- +% Target $T$ &300 & & & & & & & & \\\tabucline- +% \end{tabu} +% +% +% Some coefficients are negative and we have to measure the natural widths of the corresponding columns, for columns +% always have a width: +% $$ +% \lambda_i = \begin{tabu}spread0pt \{{lX[-1]}. c_i \cdot X & if $c_i>0$ \\ +% \Min\left(\abs{c_i} \cdot X , \nu_i\right) & if $c_i<0$ \quad with \quad $\nu_i \leq T \quad \forall i$ +% \end{tabu} +% $$ +% +% $\nu_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$ \textt X column, limited to the \env{tabu} target: $\nu_i \leq T \quad \forall i$. +% \newcommand*\wdtable{\mbox{wd(table)}} +% +% The whole width of the tabular is always: +% $$ \wdtable = \sum_i \lambda_i + \text{incompressible material} \begin{tabu}spread0pt \{{!{\text\textbullet}X[-1]}. +% \cs\tabcolsep \\ +% vertical lines/leaders thickness \\ +% non \textt X columns +% \end{tabu}$$ +% and should finally be equal to $T$, by the correct computation of the $\lambda_i$. +% +% +% So what is $X$ at first ? Columns that have a non negative coefficients always have a width equal to $\lambda_i = c_i \cdot X$ +% therefore, if we only have non negative coefficients, we can safely set: +% $$ X = \dfrac T{\displaystyle\sum_i c_i}$$ +% +% then: \quad $\sum_i \lambda_i = \sum_i c_i \cdot X \geq T$ \quad at the first trial. But this is not the same if some coefficients are negative, +% because in this case the column width $\lambda_i$ can shrink until its natural width $\nu_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: +% $$ \begin{tabu}{rl} \forall i \quad c_i<0 \implies & \abs{c_i} \cdot X \geq T \\ +% \exists\, c_i >0 \implies & \sum\limits_{\substack{ i\\ c_i >0}} c_i \cdot X \geq T +% \end{tabu}$$ +% And finally, for the measure: +% $\displaystyle X = \Max\left[\Max\limits_{\substack{i\\ c_i<0}} \dfrac T{\abs{c_i}} ; \dfrac T{\sum\limits_{\substack{i \\ c_i>0}} c_i }\right]$ +% +% \tabulinesep=1.5mm +% \begin{tabu}{|X[2c]|*7{X[$c]}|[dash]*2{X[$c]}|} \tabucline- +% Coef $c_i$ & &c_1 &c_2 &c_3 &c_4 &c_5 &c_6 &\sum &\Delta \\\tabucline[dash]- +% & &-1 &-2 &-5 &-2 &2 &3 &15 & \\\tabucline- +% Target $T$ &300 & & & & & & & & \\\tabucline- +% $X$ &\cellcolor{lime}300 & & & & & & & & \\\tabucline- +% $\nu_i$ & &10 &300 &80 &80 & & & & \\\tabucline[dash]- +% $\lambda_i$ & &10 &300 &80 &80 &600 &900 &1970 &1800 \\\tabucline- +% \end{tabu} +% +% \paragraph{First step of the algorithm: reducing the width} +% +% After having measured the table we get: $\wdtable = 2100$. The \emph{incompressible material} is \, $2100-1970 = 130$ \, wide and +% the gap to the target is \, $\Delta=2100-300=1800$. +% +% We now choose a new value for $X$: +% $$ \sum_i \lambda_i = \sum_i \Min_{\substack{i\\ c_i<0}}\left(\nu_i ; c_i\cdot X\right) + \sum_{\substack{i\\ c_i>0}} c_i\cdot X \leq \sum_i \abs{c_i}\cdot X$$ +% Let's try \, $X' = \dfrac{\sum\limits_i \lambda_i - \Delta}{\sum\limits_i \abs{c_i}}$ \, so that \, +% $\sum\limits_i \lambda'_i \leq \sum\limits_i \abs{c_i}\cdot X' \leq \sum\limits_i \lambda_i -\Delta $ : +% +% \begin{tabu}{|X[2c]|*7{X[$c]}|[dash]*2{X[$c]}|} \tabucline- +% Coef $c_i$ & &c_1 &c_2 &c_3 &c_4 &c_5 &c_6 &\sum &\Delta \\\tabucline[dash]- +% & &-1 &-2 &-5 &-2 &2 &3 &15 & \\\tabucline- +% Target $T$ &300 & & & & & & & & \\\tabucline- +% $X$ &300 & & & & & & & & \\\tabucline- +% $\nu_i$ & &10 &300 &80 &80 & & & & \\\tabucline[dash]- +% $\lambda_i$ & &10 &300 &80 &80 &600 &900 &1970 &1800 \\\tabucline- +% $X'$ &\cellcolor{lime} 11.33 & & & & & & & & \\\tabucline- +% \end{tabu} +% $X' = \dfrac{1970 - 1800}{15} = \dfrac{170}{15} = 11.33$ \quad Note that the computation of $X'$ does not involve any measurement. +% +% +% \begin{tabu}{|X[2c]|*7{X[$r]}|[dash]>\bf X[$r]X[$r]|} \tabucline- +% \rowfont[c]{} +% Coef $c_i$ & &c_1 &c_2 &c_3 &c_4 &c_5 &c_6 &\sum &\Delta \\\tabucline[dash]- +% & &-1 &-2 &-5 &-2 &2 &3 &15 & \\\tabucline- +% Target $T$ &300 & & & & & & & & \\\tabucline- +% $X$ &300 & & & & & & & & \\\tabucline- +% $\nu_i$ & &10 &300 &80 &80 & & & & \\\tabucline[dash]- +% $\lambda_i$ & &10 &300 &80 &80 &600 &900 &1970 &1800 \\\tabucline- +% $X'$ &\cellcolor{lime} 11.33 & & & & & & & & \\\tabucline[dash]- +% $\lambda'_i$ & &10,00 &22,67 &56,67 &22,67 &22,67 &34,00 &168,67 &\cellcolor{lime}-1.33 \\\tabucline- +% \end{tabu} +% +% Here we are in the case where the table width: +% $$\begin{tabu}{rl} \wdtable = &\sum\limits_i \lambda_i + \text{incompressible material} = T + \Delta \\ +% \implies & \sum\limits_i \lambda'_i + \text{incompressible material} \leq \sum\limits_i \lambda_i -\Delta + I = T +% \end{tabu}$$ +% +% Without any measure, we can say that the final table width will be less than the target, if we choose $X'$. The free space to +% share among the \textt X columns (computed with $X'$) is now $\Delta' = T - (\sum_i \lambda'_i + I) = 300 - (168.67 + 130) = -1.33$, +% where $I$ is the incompressible material. +% +% \paragraph{Giving space} +% +% We say that a column is \emph{saturated} (\ie full) if its natural width is greater than $\abs{c_i}\cdot X$, or +% all the same that $\lambda_i < \nu_i$. We also will consider that the columns with $c_i>0$ have a ``natural width'' +% which is always equal to $c_i\cdot X$: in other words, a column with a non negative coefficient is always \emph{saturated}. +% +% Giving space (or ``refunding'' space) to the columns must be done in priority to the \emph{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 \, $\forall i\quad c_i<0$ \, because we first choosed $X$ so that: +% $$ X \geq \frac T{\sum\limits_{\substack{i\\ c_i>0}} c_i}$$ +% and hence, the sum of the widths of the ``non negative'' columns exceeds the target. +% +% Let's rank the columns widths: +% +% \begin{tikzpicture}[yscale=.4] +% +% \draw (0,10) rectangle ++ (8,.5) node (H) {} node [above] {$\lambda'_1$}; +% \draw [dash pattern=on2pt off2pt] (H) rectangle ++ (2,-.5) node [above,yshift=6pt] {$\nu_1$}; +% +% \draw (0,8) rectangle ++ (7,.5) node (H) {} node [above] {$\lambda'_2$}; +% \draw [dash pattern=on2pt off2pt] (H) rectangle ++ (2,-.5) node [above,yshift=6pt] {$\nu_2$}; +% +% \draw (0,6) rectangle ++ (4,.5) node (H) {} node [above] {$\lambda'_3$}; +% \draw [dash pattern=on2pt off2pt] (H) rectangle ++ (2,-.5) node [above,yshift=6pt] {$\nu_3$}; +% +% \draw [dash pattern=on2pt off2pt] (0,4) rectangle ++ (2,.5) node (H) {} node [above] {$\nu_4$}; +% \draw (H) rectangle ++ (1,-.5) node [above,yshift=4pt] {$\abs{c_4} X$}; +% +% \node at (11,10) [anchor=north west] {\begin{tabu}{l} we first give space \\ to the saturated columns \\ $1$, $2$ and $3$\end{tabu}}; +% +% \end{tikzpicture} +% +% Because of the saturation, the total amount of space to give: \, $\abs\Delta$ \, 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 < \epsilon \leq \abs\Delta'$ the amount of space to give, then after the operation: +% \begin{align*} +% \lambda_1" + \lambda_2" + \lambda_3" &= \lambda'_1 + \lambda'_2 + \lambda'_3 + \epsilon \\ +% &= \abs{c_1} X' + \abs{c_2} X' + \abs{c_3} X' + \epsilon +% \end{align*} +% +% Let's say $ X" = X' + \dfrac {\abs\Delta'} {\sum\limits_{\substack{i \\ c_i \text{saturated}}} \abs{c_i}}$ \, then it's possible, +% without any measure, to compute: +% $$\sum\limits_{\substack{i \\ c_i \text{saturated}}} \lambda"_i+\nu_4 \,\leq\, \sum\limits_{\substack{i \\ c_i \text{saturated}}} \abs{c_i}\cdot X" +\nu_4 \,\leq\, \sum\limits_i \abs{c_i}X'+\Delta' = \sum\limits_i\lambda'_i+\Delta'\leq T-I$$ +% +% Or for clarity: \quad $ \sum\limits_i \lambda_i" + I = \wdtable \, \leq \, T$ and the new free space to share is now : +% $$\Delta" = \abs{ T - \left(\sum\limits_i \lambda"_i + I \right) }$$ +% +% At each step of the computation, and without any measure but the first, $X$ grows, $\Delta$ decreases, and finally the target is reached for $X$ such that $\Delta \leq \text{hfuzz}$. +% +% \begin{tabu}{|X[2c]|*7{X[$r]}|[dash]>\bf X[$r]X[$r]|} \tabucline- +% \rowfont[c]{} +% Coef $c_i$ & &c_1 &c_2 &c_3 &c_4 &c_5 &c_6 &\sum &\Delta \\\tabucline[dash]- +% & &-1 &-2 &-5 &-2 &2 &3 &15 & \\\tabucline- +% Target $T$ &300 & & & & & & & & \\\tabucline- +% $X$ &300 & & & & & & & & \\\tabucline- +% $\nu_i$ & &10 &300 &80 &80 & & & & \\\tabucline[dash]- +% $\lambda_i$ & &10 &300 &80 &80 &600 &900 &1970 &1800 \\\tabucline- +% $X'$ &11.33 & & & & & & & & \\\tabucline[dash]- +% $\lambda'_i$ & &10,00 &22,67 &56,67 &22,67 &22,67 &34,00 &168,67 &-1.33 \\\tabucline- +% $X"$ &\cellcolor{lime} 11.43 & & & & & & & & \\\tabucline[dash]- +% $\lambda"_i$ & &10,00 &22,86 &57,14 &22,86 &22,86 &34,29 &170,00 &\cellcolor{GreenYellow}0 \\\tabucline- +% \end{tabu} +% +% \bigskip +% +% 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 don't fill the wanted horizontal space, the algorithm artificially raise the natural widths, +% according to a linear distribution: +% $$ \lambda'_i = \lambda_i + \Delta \cdot \dfrac{\lambda_i}{\sum\limits_i \lambda_i} = \nu_i + \Delta \cdot \dfrac{\nu_i}{\sum\limits_i \nu_i} +% = \nu_i \cdot \left(1+\dfrac{\Delta}{\sum\limits_i \nu_i}\right)$$ +% +% \subsubsection{\env{tabu spread} dimen} +% \label{algorithms tabu spread} +% +% The case of \env{tabu spread} is interesting and quite complex... +% +% Here, the aim of the game is to give a target to the table, depending on its natural width. +% \env{tabu} has a default target (\cs\linewidth in general, but it is possible to \cs\let\cs\tabudefaulttarget +% to another value... for example \cs\linegoal) which is a maximum for the final target of \env{tabu spread}. +% The case where the spread is $0pt$ is not simpler nor more difficult. +% +% If every column has a negative coefficient, it's rather easy because either the table exceeds the target, and then the new target +% will be the default target (the \emph{maximum}), or the table width is less than the default target and we fix the new target +% to be that width $+$ the spread, in the limit of the default target. +% +% The condition that must hold on coefficient is not restritive if every column has a negative coefficient because if you say, +% for example: \, $X = \Max\limits_i \dfrac{\nu_i}{\abs{c_i}}$ \, then: +% $$ \sum\limits_i \lambda_i = \sum\limits_i \Min \left(\nu_i ; \abs{c_i}\cdot X\right)$$ +% is true. It's always possible to find a $X$ such that the behaviour anounced in the documentation is observed ! +% +% Then let's 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 $c_i$ +% -- must be respected. +% +% The real natural width of the tabular, which observe the proportions between columns with a non negative coefficient is: +% $$ \wdtable + \Max\limits_{\substack{i \\ c_i>0}} \left(\dfrac{\nu_i}{c_i}\right)\times \sum\limits_{\substack{i \\ c_i>0}} c_i - \sum_{\substack{i\\c_i>0}} \nu_i > \wdtable$$ +% +% This quantity is computed, \TabU adds the \textt{spread} and fix the new target to the sum, in the limit of the default target. +% +% Then $X$ is initialized such that: +% $\displaystyle X = \Max\left[\Max\limits_{\substack{i\\ c_i<0}} \dfrac T{\abs{c_i}} ; \dfrac T{\sum\limits_{\substack{i \\ c_i>0}} c_i }\right]$ +% +% and the algorithm described in the former section works, without any new measurement of the tabular. +% +% +% \begin{minipage}{.9\linewidth} +% Unless this was not possible or deemed inconvenient for clarity, the code is presented in the same +% order it executes. +% \end{minipage} +% +% \subsection{The \env{tabu} strategies} +% +% { +% \tabulinesep=1mm +% \begin{tabu}{|X[-2c]|*2{X[-3$c]>{\smaller}X[3]|}} \hline +% \rowfont\bfseries +% &\multicolumn2{c|}{Not nested (outer)} &\multicolumn2{c|}{Nested} \\ +% \rowfont[c]{\ifmmode\else\ttfamily\fi} +% &\cs{count@} &condition &\cs{count@} &condition \\\tabucline[on2pt off2pt]- +% & & &0 &outer is in mode $0$ \\ +% \tiny\cs{tabu@endrewrite} +% &3 &no \textt X column &1 &no \textt X column \\ +% &4 &\textt X columns &3 &\textt X column \\\tabucline[on2pt off2pt]- +% & & &0 &outer in mode $0\,\Rightarrow$ print \\ +% \tiny\cs{tabu@select} +% & & &1 &outer in mode $3$ \\ +% & & &2 &from $1$ in \cs{tabu@endrewrite} if outer in mode $4$ \\ +% &3 \text{ or } 4 &needs trials &3 \text{ or } 4 &needs trials \\\tabucline[on2pt off2pt]- +% &0 &print out & & \\ +% & & &1 &Exit in vertical measure\par (outer in mode 3) \\ +% \tiny\cs{tabu@strategy} +% & & &2 &Exit with a rule\par (outer in mode 4) \\ +% &3 &Vertical measure & & \\ &4 &Horizontal measure &4 &Horizontal measure\par (nested in coef$<0$ or spread) \\\hline +% \end{tabu} +% } +% +% \begin{tikzpicture}[every node/.add style={}{outer sep=2mm},yscale=1.5,xscale=1.4,framed] +% +% \node at (5,1.5) [font=\itshape] {Path followed by the outermost \env{tabu}}; +% +% \node (X) {\textt X column ?}; +% +% \path (X) -- ++ (2,1) node (endrew4) {4} -- ++ (2,0) node (select4) {4} +% -- ++(2,0) node (strat4) {4} -- ++(0,-1) node (arith) {arithmetic} -- (strat4) -- ++ (2,0) node (to3) {3} -- ++(2,-1) node (to0) {0}; +% +% \draw [->] (X) -- (endrew4) node [midway,left] {yes}; +% \draw [->] (endrew4) -- (select4); +% \draw [->] (select4) -- (strat4); +% \draw [<->] (strat4) -- (arith); +% \draw [->] (strat4) -- (to3); +% \draw [->] (to3) -- (to0); +% +% \path (X) -- ++(2,-1) node (endrew3) {3} -- ++(2,0) node (select3) {3} -- ++(2,0) node (strat3) {3}; +% \draw [->] (X) -- (endrew3) node [midway,left] {no}; +% \draw [->] (endrew3) -- (select3); +% \draw [->] (select3) -- (strat3); +% \draw [->] (strat3) -- (to0); +% +% \node at (2,-1.5) {\cs{tabu@endrewrite}}; +% \node at (4,-1.5) {\cs{tabu@select}}; +% \node at (7,-1.5) {\cs{tabu@strategy}}; +% +% \end{tikzpicture} +% +% \begin{tikzpicture}[every node/.add style={}{outer sep=2mm},yscale=1.5,xscale=1.4,framed] +% +% \node at (5,2) [font=\itshape] {Path followed by a nested \env{tabu}}; +% +% \node (X) {\textt X column ?}; +% +% \path (X) -- ++ (2,1) node (endrew4) {4} -- ++ (2,0) node (select4) {4} +% -- ++(2,0) node (strat4) {4} -- ++(0,-1) node (arith) {arithmetic} -- (strat4) -- ++ (1.5,.3) node (to1) [anchor=west] {1 (outer in mode 3)} +% -- (strat4) -- ++ (1.5,-.3) node (to2) [anchor=west] {2 (outer in mode 4)}; +% +% \draw [->] (X) -- (endrew4) node [midway,left] {yes}; +% \draw [->] (endrew4) -- (select4); +% \draw [->] (select4) -- (strat4); +% \draw [<->] (strat4) -- (arith); +% \draw [->] (strat4) -- (to1); \draw [->] (strat4) -- (to2); +% +% \path (X) -- ++(2,-1) node (endrew1) {1} -- ++ (1.5,.3) node (select1) [anchor=west] {1 (outer in mode 3)} +% -- (endrew1) -- ++(1.5,-.3) node (select2) [anchor=west] {2 (outer in mode 4)}; +% +% \draw [->] (X) -- (endrew1); +% \draw [->] (endrew1) -- (select1); +% \draw [->] (endrew1) -- (select2); +% +% \draw [->] (X) -- (endrew1) node [midway,left] {no}; +% +% \node at (2,-1.7) {\cs{tabu@endrewrite}}; +% \node at (4,-1.7) {\cs{tabu@select}}; +% \node at (7,-1.7) {\cs{tabu@strategy}}; +% +% \end{tikzpicture} +% +% +% \subsection{Identification and Requirements} +% \label{Identification and Requirements} +% +% \TabU requires \xfile{array.sty} and \xfile{varwidth.sty}. The package namespace is \textttbf{\pkgcolor tabu@}. +% +% \begin{macrocode} +%<*package> +\NeedsTeXFormat{LaTeX2e}[2005/12/01] +\ProvidesPackage{tabu}[2011/02/26 v2.8 - flexible LaTeX tabulars (FC)] +\RequirePackage{array}[2008/09/09] +\RequirePackage{varwidth}[2009/03/30] +% \end{macrocode} +% +% Minimal catcode acertaining for loading \thispackage in good conditions: +% +% \begin{macrocode} +\AtEndOfPackage{\tabu@AtEnd \let\tabu@AtEnd \@undefined} +\let\tabu@AtEnd\@empty +\def\TMP@EnsureCode#1={% + \edef\tabu@AtEnd{\tabu@AtEnd + \catcode#1 \the\catcode#1}% + \catcode#1=% +}% \TMP@EnsureCode +\TMP@EnsureCode 33 = 12 % ! +\TMP@EnsureCode 58 = 12 % : (for siunitx) +\TMP@EnsureCode124 = 12 % | +\TMP@EnsureCode 36 = 3 % $ = math shift +\TMP@EnsureCode 38 = 4 % & = tab alignmment character +\TMP@EnsureCode 32 = 10 % space +\TMP@EnsureCode 94 = 7 % ^ +\TMP@EnsureCode 95 = 8 % _ +% \end{macrocode} +% +% \enlargethispage{\baselineskip} +% \subsection{Flow chart of expansion} +% \label{Flow chart of expansion} +% +% { +% \hskip-\evensidemargin +% \begin{tikzpicture}[yscale=.4,xscale=.6,framed, +% start chain, every join/.style={->,thin,black,solid},node distance=.5cm and .5cm, +% every node/.style={black}] +% \node [on chain,draw] (begintabu) at (0,0) {\cs{begin}\M*{tabu}} node [anchor=west] at (begintabu.east) {(\cs\begingroup)} +% node [on chain=going below,join] (tabu) {\cs\tabu} +% node [on chain=going right,join] (tabudesc) {$\begin{tabu}\{{>{$}l<{$}}. +% sets \cs{tabu@target} \\ +% loads \env{tabu} setup and prepares \cs{tabu@cleanup} and \cs{tabu@reset} +% \end{tabu}$} +% node [on chain=going below,join] (tabu@begin) {\cs{tabu@begin}} +% node [on chain] (tabu@begindesc) {$\begin{tabu}\{{>{$}l<{$}}. +% if \cs{tabu@target} $> 0$ then prepare \\ +% \textt{@\M*{\cs\extracolsep\M*{\cs{@flushglue}}}} +% \end{tabu}$}; +% \chainin (tabu@begin) +% node [on chain=going below] (H) {} +% node [on chain=going below,join=with tabu@begin] (toarray) {\cs\tabular or \cs\array if in math mode}; +% \draw [densely dotted,gray,very thick] (begintabu.west |- H) -- (tabu@begindesc.east |- H) coordinate (H); +% \path [fill=AliceBlue] (begintabu.north -| H) rectangle ($(H)+(1,0)$) coordinate (bluebox) +% node [midway,rotate=-90] {\large\thispackage}; +% +% { [start chain=array] +% \node [on chain] at (begintabu |- toarray) [yshift=-2.5cm] (@array) {\cs{@array}}; +% \draw [->] (toarray.west) -| (@array); +% \node [on chain=going right,join,fill=GhostWhite,draw=gray,dashed] (@arraydesc) +% {\begin{tabu}\{{l}. +% creates the \cs{@arstrutbox} \\ +% \cs\begingroup \\ +% \quad \cs{@mkpream}: parse the preamble to create \cs{@preamble} \\ +% \quad \cs\xdef \cs{@preamble} macro \\ +% \cs\endgroup\\ +% \cs{@arrayleft}\\ +% \cs\vtop or \cs\vbox or \cs\vcenter \cs\bgroup ... \cs\halign\{ preamble... +% \end{tabu}} +% node [on chain=going below] (H) {}; +% } +% { [start chain=endtabu] +% \node [on chain] (end{tabu}) at (begintabu |- H) {\cs{end}\M*{tabu}} +% node [on chain=going below,join] (endtabu) {\cs\endtabu} +% node [on chain=going right,join] (endtabular) {\cs\endtabular} +% node [on chain=going right,join] (endarray) {\cs\endarray} +% node [on chain=going right,join] (endarraydesc) {\begin{tabu}\{{l}. end of \cs\halign \\ end of \cs\vtop, \cs\vbox or \cs\vcenter\end{tabu}}; +% \chainin (endtabular) +% node [on chain=going below,node distance=.7cm] (H) {}; +% \node at (H -| endarraydesc.west) [anchor=west] (endtabulardesc) {\begin{tabu}\{{l}. end of math group \\ end of \cs\hbox\end{tabu}}; +% \draw [->] (endtabular) |- (endtabulardesc) node [near end,above] {\small if in text mode}; +% \draw [->] (endtabu.north east) to [bend left,looseness=.5] node [midway,above] {\small if in math mode} (endarray.north); +% \node at (endtabulardesc.south -| begintabu) [yshift=-.5cm] (endgroup) {\cs\endgroup} node at (endgroup.east) [anchor=west] {end of envir}; +% \draw [->] (endtabu) -- (endgroup); +% } +% \path [fill=LightGoldenrodYellow] (bluebox) rectangle ($(endtabulardesc.south -| bluebox)-(1,0)$) +% node [midway,rotate=-90] {\large\xpackage{array}}; +% \end{tikzpicture} +% } +% +% \paragraph(tabu to with X column){\textt{tabu to} with \textt X column} +% +% The important part of the job is made inside the dashed box above: \cs\@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 +% \cs\aftergroup. This implementation allows much modifications in the tabular preparation, +% without any change in the macros of \xfile{array.sty}. \enlargethispage\baselineskip +% +% {\hskip-0cm +% \begin{tikzpicture}[yscale=.4,xscale=.6,framed, +% start chain=going below,node distance=.3cm and .5cm, +% every join/.style={->,thin,black,solid},every node/.style={black}] +% +% \node [on chain] (begingroup) at (0,0) {\cs\begingroup} +% node [on chain=going right] (@mkpream) {\cs{@mkpream}} +% node [on chain,join] {Finds a \textt X column} +% node [on chain,join] {rewrite \textt X column} +% {[start branch] node [on chain] {\begin{tabu}\{{l}. Parse the optional parameter for \textt X\\ Set \cs\aftergroup\cs{tabu@prep@TRIAL}\end{tabu}} +% } +% node [on chain,join] {... \cs{@mkpream} ...} +% {[start branch] node [on chain,join] {builds the \cs\halign preamble}} +% node [on chain,join] {\cs\xdef\cs{@preamble}} +% node [on chain,join] (endgroup) {\cs\endgroup} +% node [on chain] (H) {}; +% \node (tabu@prep@TRIAL) at (begingroup |- H) {\cs{tabu@prep@TRIAL}}; +% \draw [->] (endgroup.west) -| (tabu@prep@TRIAL.north) node [midway,left] {\ssmall\begin{tabu}{c} triggered by\\ \cs\aftergroup\end{tabu}}; +% \chainin (tabu@prep@TRIAL); +% { [start branch] \node [on chain,join] {\cs{tabu@setup@TRIAL}} +% node [on chain,join] {\begin{tabu}\{{l}. +% Neutralisation of \cs\write \\ +% Protection for: \begin{tabu}{!{\textbullet}l} +% footnotes \\ counters \\ index +% \end{tabu} +% \end{tabu}}; +% } +% \node [on chain] (H) {} +% node [on chain,join=with tabu@prep@TRIAL] (tabu@arrayleft@measure) {\cs{tabu@arrayleft@measure}} +% node [on chain=going right,join] {\begin{tabu}\{{l}. prepares \cs{tabu@Xfinish} \\ Collect the \textt{tabu} body\end{tabu}} +% node [on chain,join] (tabu@TRIAL) {\cs{tabu@TRIAL}} +% {[start branch] node [on chain,join] {\begin{tabu}{l} Expands \cs\halign into a \cs\vbox \end{tabu}} +% } +% node [on chain,join] {\cs{tabu@endTRIAL}} +% {[start branch] node [on chain,join] {\cs\endarray} +% } +% node [on chain,join] (tabu@arith) {\begin{tabu}{c} \cs{tabu@arith}\\ \cs\wd\M*{tabu}$-$\cs{tabu@target} $<$ \cs\hfuzz ?\end{tabu}} +% node [on chain=going right,node distance=1cm] (tabu@Xfinish) {\cs{tabu@Xfinish}}; +% \draw (tabu@arith) [->] -- (tabu@Xfinish) node [midway,above,blue] {Yes}; +% \draw [->] (tabu@arith.west) |- (tabu@TRIAL) node (No) [very near start,left] {{\small\begin{tabu}.{r}\} Updates \\ \cs\tabucolX\end{tabu}} \textcolor{red}{No}}; +% +% \end{tikzpicture}} +% +% \subsubsection(tabu spread with X column){\textt{tabu spread} with \textt X column} +% +% In the case of ``\env{tabu spread}'' with \textt X columns, the process is the same +% as the one described for ``\textt{tabu to}'' with \textt X columns. However, the first +% trial is different because we have first to measure the \emph{natural width} of the +% tabular. +% The process is the following: +% \begin{itemize}[label=\small\textbullet] +% \item \cs\tabu@target is first set to \cs\linewidth (or \cs\linegoal with the \textt{linegoal} package option). +% \item The \textt X column corresponds to a \cs\vbox with \cs\hsize fixed to \cs\tabu@target. +% \item Inside this \cs\vbox the cell content is written into a \cs\hbox whose width is limited to \cs\tabu@target. +% This \cs\hbox is captured into the box register \cs\tabu@box. +% \item At the end of the cell, the \cs\badness of the \cs\hbox is checked: +% \begin{itemize}[label=\textendash,leftmargin=*] +% \item if the \cs\badness is $> 1000$ then the text is too long and ``\textt{tabu spread}'' +% is useless: \textt{tabu to \cs{tabu@target}} give the same result. +% \item Otherwise, we get the natural width of the cell content by: \\ +% \cs\setbox \cs\tabu@box \cs\hbox \M*{\cs\unhbox \cs\tabu@box} +% \end{itemize} +% \item At the end of the first trial, \cs{tabu@spreadarith} checks if: +% $$ \text{width(tabular)} + \text{spread} < \cs\linewidth \text{ (or \cs\linegoal)}$$ +% \begin{itemize}[label=\textendash,leftmargin=*] +% \item if not, then \textt{tabu to}\cs{tabu@target} give the same result +% \item Otherwise, the target for \textt{tabu to} will be: +% $$\hskip-\leftmargin +% \text{width(tabular)} + \text{spread} - \sum_i \text{natural widths X}_i +% +\underbrace{\text{Max}_i\left(\dfrac{\text{natural width X}_i}{\text{coef}_i}\right)\times \sum_i\text{coef}_i} +% _{\text{\begin{tabu}{c} minimal natural width that can be obtained \\ with the given coefs\end{tabu}}} +% $$ +% \end{itemize} +% And the next trial will be done as if the user called ``\textt{tabu to}'' with this target. +% \end{itemize} +% +% +% \subsection{Some constants} +% \label{Some constants} +%¤<package>%% Constants -------------------------------------------------------- +% +% Here we define the constants used by \thispackage: \TeX{} registers and a few \emph{helper} macros. +% +% When working inside a tabular (\ie \cs\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 \emph{local} register does not +% suffer, never, any global assignment. +% +% \subsubsection(TeX registers){\TeX{} registers} +% +% \begin{macro}{taburow} +% +% \LaTeX{} counter that globally stores the value of the current row. It is updated at \cs\everyrow, +% rather than at \cs\everycr\footnote{Package \xpackage{xcolor} defines the \cs\rownum \TeX{} counter, +% which is globally updated at \cs\everycr. Hence this \cs\rownum counter is not reliable in case +% the user invokes \cs\cline or \cs\cmidrule for example...}. +% \cs\thetaburow expands to the (arabic) number. +% +% This counter can be read by the user, but she \textbf{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). +% +% \begin{macro}{\tabu@nbcols} +% +% \TeX{} counter that -- locally -- saves the total number of columns of the \env{tabu}. Special \texttbf @ \, and \,\texttbf ! \, +% columns are not counted (they are not \emph{real} columns for \cs\halign, but only insertions into the preamble). +% +% The value is used by \cs\tabucline to ensure that the leader does not jut out over the last column... +% +% \begin{macro}{\tabu@cnt} +% +% \TeX{} counter that -- locally -- stores the number of trials. Incidentally, it is also temporarily used +% to parse the width coefficient for \textt X columns, during the rewriting process. +% +% \begin{macro}{\tabu@Xcol} +% +% \TeX{} counter that -- locally -- stores the number of \textt{tabu X} columns. Defined while rewriting +% the \textt X token, it is used in the specification of the width of the column (\cs\tabu@hsize\M*{Rank of the X column}\M*{coef}). +% +% It is also used to store the natural width of \textt X columns (in the cases of a negativ coefficient or if \env{tabu spread} +% is used). +% +% \begin{macro}{\tabu@alloc} +% \begin{macro}{\tabu@nested} +% +% A global counter whose initial value ($-1$) is incremented for each nested tabular. The end of the outermost tabular globally +% resets the value to $-1$. \cs\tabu@nested stores locally the value of \cs\tabu@alloc and is therefore the ``index'' of the current +% tabular (the one that is actually in construction). +% +% This influences the initialisation process (cf. \cs\tabu@setup and \cs\tabu@init). +% +% \begin{macro}{\tabu@start} +% \begin{macro}{\tabu@stop} +% +% They are used locally by \cs\tabucline\, and\, \cs\everyrow\, while parsing the parameters: +% this is, for clarity, the local name for \cs\@tempcnta and \cs\@tempcntb. +% +% \begin{macrocode} +\newcount \c@taburow \def\thetaburow {\number\c@taburow} +\newcount \tabu@nbcols +\newcount \tabu@cnt +\newcount \tabu@Xcol +\let\tabu@start \@tempcnta +\let\tabu@stop \@tempcntb +\newcount \tabu@alloc \tabu@alloc=\m@ne +\newcount \tabu@nested +\def\tabu@alloc@{\global\advance\tabu@alloc \@ne \tabu@nested\tabu@alloc} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@target} +% +% \TeX{} dimen that -- locally -- stores the \env{tabu} target (either ``\textt{to}'' or ``\textt{spread}''). +% +% \begin{macro}{\tabu@spreadtarget} +% +% \TeX{} dimen that -- locally -- stores the \env{tabu} spread given by the user. +% +% \begin{macro}{\tabu@naturalX} +% +% \TeX{} dimen that -- globally -- stores the total natural widths of the \textt X columns, +% in the cases of negativ coefficients and/or \textt{tabu spread}. The value is reset to $0pt$ +% at \cs\everyrow, and \emph{maxima/minima} are stored into the macro \cs\tabu@naturalXmin +% and \cs\tabu@naturalXmax: those are required for the algorithm of \textt{tabu spread} (\cs\tabu@spreadarith). +% +% \begin{macro}{\tabucolX} +% +% \TeX{} dimen that -- locally -- stores the width corresponding to the preamble token \textt{X[1]}: +% the standard width of \textt X columns. +% +% \begin{macro}{\tabu@DELTA} +% +% This is for clarity, the local name of \cs\@tempdimc in \cs\tabu@arith. +% +% \begin{macro}{\tabu@thick} +% \begin{macro}{\tabu@on} +% \begin{macro}{\tabu@off} +% +% They are used locally by \cs\tabu@getline, while parsing the parameters for a line specification. +% This is for clarity, the local name for \cs\@tempdima, \cs\@tempdimb and \cs\@tempdimc. +% +% \begin{macrocode} +\newdimen \tabu@target +\newdimen \tabu@spreadtarget +\newdimen \tabu@naturalX +\newdimen \tabucolX +\let\tabu@DELTA \@tempdimc +\let\tabu@thick \@tempdima +\let\tabu@on \@tempdimb +\let\tabu@off \@tempdimc +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@Xsum} +% +% \TeX{} dimen that -- locally -- stores the sum of all width coefficients for \textt X columns. +% This is required to fix the initial value for \cs\tabucolX and then in the algorithms (\cs\tabu@arith and +% \cs\tabu@arithnegcoef). +% +% \begin{macrocode} +\newdimen \tabu@Xsum +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\extrarowdepth} +% +% \xfile{array.sty} defines \cs\extrarowheight as a \TeX{} dimen register: the extra height +% to be finally added to each row of a table. \thispackage defines \cs\extrarowdepth in addition: +% the \emph{extra depth}. Though \cs\extrarowheight and \cs\extrarowdepth can be set by the user, +% the official interface is \cs\extrarowsep. +% +% \begin{macro}{\abovetabulinesep} +% \begin{macro}{\belowtabulinesep} +% +% \TeX{} dimensions \cs\abovetabulinesep and \cs\belowtabulinesep store the minimum allowed vertical space +% between the contents of the cells and their borders. Their values are ignored if non positive. Though they +% can be set by the user, the official interface is \cs\tabulinesep. +% +% The philosophy and the technics are similar to the one provided by the \Xpackage{cellspace} package. +% However, limitations of \xpackage{cellspace} are lifted (nested \env{tabu} environments, use of colors... +% see the \refitem{cellspace limitations}[\xpackage{cellspace} limitations] in the revision history). \thispackage +% inserts only one strut per line, whose name is \cs\@arstrut. +% +% \begin{macro}{\tabustrutrule} +% +% The \TeX{} dimen \cs\tabustrutrule is here only for debugging purpose: its value must be $0pt$. +% It behaves mostly like \TeX{} primitive \cs\overfullrule, and allow to see the struts introduced in the tabular, +% and to control vertical spacing. Setting \cs\tabustrutrule to a positive value has no effect unless \cs\tracingtabu +% is $\geq 3$. The official interface is \cs\tracingtabu$=3$. +% +% \begin{macrocode} +\newdimen \extrarowdepth +\newdimen \abovetabulinesep +\newdimen \belowtabulinesep +\newdimen \tabustrutrule \tabustrutrule \z@ +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@thebody} +% +% This token stores -- locally -- the collected content of the \env*{tabu} during the measuring process. +% +% \begin{macro}{\tabu@footnotes} +% +% Token that globally stores the footnotes inside the \env*{tabu}, for \cs\insert does not work +% inside such a level of groupings... +% +% \begin{macrocode} +\newtoks \tabu@thebody +\newtoks \tabu@footnotes +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@box} +% +% Stores -- loally -- the whole \env{tabu} when an attempt to adjust \textt X columns is performed. +% +% \begin{macro}{\tabu@arstrutbox} +% +% While the \cs\@arstrutbox may redefined globally at the end of each line (for vertical spacing adjustment), +% we define a new box and \cs\let\cs\@arstrutbox to be that box inside the \env*{tabu}. +% +% Hence, the \cs\@arstrutbox used by other tabular environment does not suffer any modification. +% +% \begin{macro}{\tabu@hleads} +% \begin{macro}{\tabu@vleads} +% +% Those boxes are used to built horizontal and vertical leaders. In order not to rebuilt +% the boxes every time a leader is inserted, the box is globally defined if a line style is +% specified (\emph{via} \texttbf\textbar\M[line style]\, or \cs\tabucline\M[line style]\M*{...}\, +% or \cs\tabulinestyle\M*{line style}. +% +% \begin{macrocode} +\newsavebox \tabu@box +\newsavebox \tabu@arstrutbox +\newsavebox \tabu@hleads +\newsavebox \tabu@vleads +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsubsection{Switches} +% +% \begin{macro}{\iftabu@colortbl} +% +% The global switch \cs\iftabu@colortbl is used by \cs\rowfont when modifying the alignments, because +% \xpackage{colortbl} changes the glues put inside the \cs\halign preamble to make standard alignments. +% This switch is set At Begin Document. +% +% \begin{macro}{\iftabu@siunitx} +% +% Global switch set \cs\AtBeginDocument. \textt{true} if \Xpackage{siunitx} package is detected. +% +% \begin{macro}{\iftabu@measuring} +% +% This switch is somewhat \emph{magic} in the sense that it has several meanings... It is temporarily set +% to \textt{true} by \cs\tabu@arith in the trial group, to say that the \env{tabu} did not reach its target yet. +% It is also set to \textt{true} in the \cs\@mkpream group when the first \textt X column is encountered in the +% preamble. Finally, it is true in the trial\textbf{S} group when the outermost tabular is in strategy number $2$ +% or number $3$. +% +% \begin{macro}{\iftabu@spread} +% +% A switch whether ``\env{tabu spread}'' is used or not. A nested \env{tabu} inside a \textt X column whose coefficient +% is negative has a default target set to \textt{spread 0pt}. +% +% \begin{macro}{\iftabu@negcoef} +% +% A switch set to true in case of negativ coef (natural width if less than \textt{X[coef]}). +% +% \begin{macro}{\iftabu@everyrow} +% +% A very important global switch: \textt{true} when outside any \env{tabu} environment, \textt{true} as well when inside a cell +% of a \env{tabu}, but globally set to \textt{false} at \cs\everycr and therefore inside any \cs\noalign command. This allows to +% insert leaders (by \cs\omit\cs\span\cs\omit\cs\cr\cs\noalign\M*{...}) or first/last line corrections only once, even if \cs\everycr +% is executed more than once. +% +% \begin{macro}{\iftabu@long} +% +% Finally the swith \cs\iftabu@long is set to \textt{true} inside \env{longtabu} and to false inside \env{tabu}. +% This is convenient because some setup are slightly different between \env{tabu} and \env{longtabu}. +% +% \begin{macrocode} +\newif \iftabu@colortbl +\newif \iftabu@siunitx +\newif \iftabu@measuring +\newif \iftabu@spread +\newif \iftabu@negcoef +\newif \iftabu@everyrow +\def\tabu@everyrowtrue {\global\let\iftabu@everyrow \iftrue} +\def\tabu@everyrowfalse{\global\let\iftabu@everyrow \iffalse} +\newif \iftabu@long +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\iftabuscantokens} +% \begin{macro}{\tabu@rescan} +% +% \cs\iftabuscantokens is the switch for whether or not \env{tabu} will use \cs\scantokens. +% Though the user can set \cs\iftabuscantokens +% to \cs\iftrue or \cs\iffalse, the official interface is \env{tabu\stform*}. +% +% It does not make sense to use \cs\scantokens in a nested \env{tabu}: only the outermost \env{tabu} +% can use \cs\scantokens, for the environment body must be collected with care ! +% +% \cs\tabu@rescan is the helper macro for scanning tokens. +% +% \begin{macrocode} +\newif \iftabuscantokens +\def\tabu@rescan {\tabu@verbatim \scantokens } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{Some helper macros} +%¤<package>%% Utilities (for internal usage) ----------------------------------- +% +% \begin{macro}{\tabu@gobblespace} +% \begin{macro}{\tabu@gobbletoken} +% +% Two macros which are needed when scanning tokens with \cs\futurelet. +% +% \begin{macro}{\tabu@gobbleX} +% +% This gobbles the character number 10 in ASCII (\verb+^^J+ in \TeX{}). +% +% \begin{macro}{\tabu@ifenvir} +% +% Checks if the current environment is \env{tabu} or \env{longtabu} (for \cs\multicolumn inside \env{tabu}). +% +% \begin{macro}{\tabu@modulo} +% +% Computes the modulo (for \cs\taburowcolors). The method is taken from H.O. \Xpackage{intcalc} package. +% +% \begin{macrocode} +\def\tabu@gobblespace #1 {#1} +\def\tabu@gobbletoken #1#2{#1} +\def\tabu@gobbleX{\futurelet\@let@token \tabu@gobblex} +\def\tabu@gobblex{\if ^^J\noexpand\@let@token \expandafter\@gobble + \else\ifx \@sptoken\@let@token + \expandafter\tabu@gobblespace\expandafter\tabu@gobbleX + \fi\fi +}% \tabu@gobblex +\def\tabu@X{^^J} +{\obeyspaces +\global\let\tabu@spxiii= % saves an active space (for \ifx) +\gdef\tabu@@spxiii{ }} +\def\tabu@ifenvir {% only for \multicolumn + \expandafter\tabu@if@nvir\csname\@currenvir\endcsname +}% \tabu@ifenvir +\def\tabu@if@nvir #1{\csname @\ifx\tabu#1first\else + \ifx\longtabu#1first\else + second\fi\fi oftwo\endcsname +}% \tabu@ifenvir +\def\tabu@modulo #1#2{\numexpr\ifnum\numexpr#1=\z@ 0\else #1-(#1-(#2-1)/2)/(#2)*(#2)\fi} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@strtrim} +% +% Trimming spaces at low cost... +% +% \begin{macrocode} +{\catcode`\&=3 +\gdef\tabu@strtrim #1{% #1 = control sequence to trim + \ifodd 1\ifx #1\@empty \else \ifx #1\space \else 0\fi \fi + \let\tabu@c@l@r \@empty \let#1\@empty + \else \expandafter \tabu@trimspaces #1\@nnil + \fi +}% \tabu@strtrim +\gdef\tabu@trimspaces #1\@nnil{\let\tabu@c@l@r=#2\tabu@firstspace .#1& }% +\gdef\tabu@firstspace #1#2#3 &{\tabu@lastspace #2#3&} +\gdef\tabu@lastspace #1{\def #3{#1}% + \ifx #3\tabu@c@l@r \def\tabu@c@l@r{\protect\color{#1}}\expandafter\remove@to@nnil \fi + \tabu@trimspaces #1\@nnil} +}% \catcode +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@sanitizearg} +% +% Sanitize an argument (\xpackage{babel} compliant). +% +% \begin{macrocode} +\def\tabu@sanitizearg #1#2{{% + \csname \ifcsname if@safe@actives\endcsname % <babel> + @safe@activestrue\else + relax\fi \endcsname + \edef#2{#1}\tabu@strtrim#2\@onelevel@sanitize#2% + \expandafter}\expandafter\def\expandafter#2\expandafter{#2}% +}% \tabu@sanitizearg +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@textbar} +% +% The character \texttbf\textbar \, may have a special category code inside the document, +% depending on the language setting or for example, \texttbf\textbar\, can be the delimiter +% shortcut for verbatim. We use \cs\scantokens to allow an \cs\ifx test even if the category +% code of \texttbf\textbar\, changes along the compilation. +% +% \begin{macrocode} +\def\tabu@textbar #1{\begingroup \endlinechar\m@ne \scantokens{\def\:{|}}% + \expandafter\endgroup \expandafter#1\:% !!! semi simple group !!! +}% \tabu@textbar +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@everyrow@bgroup} +% \begin{macro}{\tabu@everyrow@egroup} +% +% Commands like \cs\everyrow, \cs\taburulecolor, \cs\tabulinestyle, \cs\taburowcolors can be expanded +% either in a cell or outside a \env*{tabu} or at the end of a row, inside a \cs\noalign group. +% +% To avoid the insertion of an empty math atom (equivalent to \cs\hbox to$0pt$\M*{}) we open a semi-simple +% group rather than a math group if not in \cs\noalign. \cs\toks@ is used to define the local-to-the-\TeX{}-group +% setting (post-fixed by \textt{@L}). +% +% \begin{macrocode} +\def\tabu@everyrow@bgroup{\iftabu@everyrow \begingroup \else \noalign{\ifnum0=`}\fi \fi} +\def\tabu@everyrow@egroup{% + \iftabu@everyrow \expandafter \endgroup \the\toks@ + \else \ifnum0=`{\fi}% + \fi +}% \tabu@everyrow@egroup +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{Rebuild the \cs{@arstrutbox}} +% +% \begin{macro}{\tabu@arstrut} +% \begin{macro}{\tabu@rearstrut} +% +% The macros rebuilds the \cs\@arstrutbox (a \cs\hbox). With the \emph{debug} variants +% when \cs\tracingtabu$=3$ and \cs\tabustrutrule$>0$. +% +% \begin{macrocode} +\def\tabu@arstrut {\global\setbox\@arstrutbox \hbox{\vrule + height \arraystretch \dimexpr\ht\strutbox+\extrarowheight + depth \arraystretch \dimexpr\dp\strutbox+\extrarowdepth + width \z@}% +}% \tabu@arstrut +\def\tabu@rearstrut {% + \@tempdima \arraystretch\dimexpr\ht\strutbox+\extrarowheight \relax + \@tempdimb \arraystretch\dimexpr\dp\strutbox+\extrarowdepth \relax + \ifodd 1\ifdim \ht\@arstrutbox=\@tempdima + \ifdim \dp\@arstrutbox=\@tempdimb 0 \fi\fi + \tabu@mkarstrut + \fi +}% \tabu@rearstrut +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@DBG@arstrut} +% +% This is the ``debug'' version of \cs\tabu@arstrut: used when +% \cs\tracingtabu $=3$ or more to show the struts inserted in the tabular. +% +% \begin{macrocode} +\def\tabu@@DBG #1{\ifdim\tabustrutrule>\z@ \color{#1}\fi} +\def\tabu@DBG@arstrut {\global\setbox\@arstrutbox + \hbox to\z@{\hbox to\z@{\hss + {\tabu@DBG{cyan}\vrule + height \arraystretch \dimexpr\ht\strutbox+\extrarowheight + depth \z@ + width \tabustrutrule}\kern-\tabustrutrule + {\tabu@DBG{pink}\vrule + height \z@ + depth \arraystretch \dimexpr\dp\strutbox+\extrarowdepth + width \tabustrutrule}}}% +}% \tabu@DBG@arstrut +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@save@decl} +% +% No inversion on tokens in the \env{tabu} preamble, when not in math mode. +% +% \begin{macrocode} +\def\tabu@save@decl{\toks\count@ \expandafter{\the\toks\expandafter\count@ + \@nextchar}}% +\def\tabu@savedecl{\ifcat$\d@llarend\else + \let\save@decl \tabu@save@decl \fi % no inversion of tokens in text mode +}% \tabu@savedecl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@finalstrut} +% \begin{macrocode} +\def\tabu@finalstrut #1{\unskip\ifhmode\nobreak\fi\vrule height\z@ depth\z@ width\z@} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Disable some commands during trials} +% +% \begin{macro}{\tabuDisableCommands} +% +% Following the model of \xpackage{hyperref} \cs\pdfstringdefDisableCommands, +% \cs\tabuDisableCommands allow the user to change the definition of some commands +% during the trial loops, by the mean of a hook to be expanded by \cs\tabu@setstrategy. +% +% \begin{macrocode} +\newcommand*\tabuDisableCommands {\g@addto@macro\tabu@trialh@@k } +\let\tabu@trialh@@k \@empty +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@nowrite} +% +% A trick (from the \TeX-book) to forbidd \cs\write when a trial is done on the \cs\halign. +% +% \begin{macro}{\tabu@noxfootnotes} +% +% Disable footnotes during trials. +% +% \begin{macrocode} +\def\tabu@nowrite #1#{{\afterassignment}\toks@} +\let\tabu@write\write +\let\tabu@immediate\immediate +\def\tabu@WRITE{\begingroup + \def\immediate\write{\aftergroup\endgroup + \tabu@immediate\tabu@write}% +}% \tabu@WRITE +\expandafter\def\expandafter\tabu@GenericError\expandafter{% + \expandafter\tabu@WRITE\GenericError} +\def\tabu@warn{\tabu@WRITE\PackageWarning{tabu}} +\def\tabu@noxfootnote [#1]{\@gobble} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@nocolor} +% \begin{macro}{\tabu@norowcolor} +% +% For optimisation purpose, color changes are deactivated during trials, +% for they do not affect the measures. +% +% \begin{macrocode} +\def\tabu@nocolor #1#{\@gobble} +\newcommand*\tabu@norowcolor[2][]{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{\xpackage{siunitx} \textt S and s columns management} +% +% \begin{macro}{\tabu@maybesiunitx} +% +% A macro that encloses the definition of \cs\tabu@celllalign, in order to check if the column is a \xpackage{siunitx} +% \textt S (or \textt s) column, and neutralise the setup of \cs\rowfont in this case, for \xpackage{siunitx} provides +% its own \textt{key=value} options to set fonts inside \textt S (or \textt s) columns. +% +% \begin{macrocode} +\def\tabu@maybesiunitx #1{\def\tabu@temp{#1}% + \futurelet\@let@token \tabu@m@ybesiunitx} +\def\tabu@m@ybesiunitx #1{\def\tabu@m@ybesiunitx {% + \ifx #1\@let@token \let\tabu@cellleft \@empty \let\tabu@cellright \@empty \fi + \tabu@temp}% \tabu@m@ybesiunitx +}\expandafter\tabu@m@ybesiunitx \csname siunitx_table_collect_begin:Nn\endcsname +\def\tabu@celllalign@def #1{\def\tabu@celllalign{\tabu@maybesiunitx{#1}}}% +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Rules, colors and vertical adjustment} +% \label{Rules, colors and vertical adjustment} +% +% \subsubsection{\cs{extrarowsep} and \cs{tabulinesep}} +%¤<package>%% Fixed vertical spacing adjustment: \extrarowsep ------------------ +% +% \begin{macro}{\extrarowsep} +% +% \cs\extrarowsep makes the assignment for both \cs\extrarowheight and \cs\extrarowdepth. +% +% The macro may be prefixed by \cs\global. +% +% \begin{macrocode} +\newcommand*\extrarowsep{\edef\tabu@C@extra{\the\numexpr\tabu@C@extra+1}% + \iftabu@everyrow \aftergroup\tabu@Gextra + \else \aftergroup\tabu@n@Gextra + \fi + \@ifnextchar={\tabu@gobbletoken\tabu@extra} \tabu@extra +}% \extrarowsep +\def\tabu@extra {\@ifnextchar_% + {\tabu@gobbletoken{\tabu@setextra\extrarowheight \extrarowdepth}} + {\ifx ^\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setextra\extrarowdepth \extrarowheight}}% + \else \let\tabu@temp \@empty + \afterassignment \tabu@setextrasep \extrarowdepth + \fi \tabu@temp}% +}% \tabu@extra +\def\tabu@setextra #1#2{\def\tabu@temp{\tabu@extr@#1#2}\afterassignment\tabu@temp#2} +\def\tabu@extr@ #1#2{\@ifnextchar^% + {\tabu@gobbletoken{\tabu@setextra\extrarowdepth \extrarowheight}} + {\ifx _\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setextra\extrarowheight \extrarowdepth}}% + \else \let\tabu@temp \@empty + \tabu@Gsave \tabu@G@extra \tabu@C@extra \extrarowheight \extrarowdepth + \fi \tabu@temp}% +}% \tabu@extr@ +\def\tabu@setextrasep {\extrarowheight=\extrarowdepth + \tabu@Gsave \tabu@G@extra \tabu@C@extra \extrarowheight \extrarowdepth +}% \tabu@setextrasep +\def\tabu@Gextra{\ifx \tabu@G@extra\@empty \else {\tabu@Rextra}\fi} +\def\tabu@n@Gextra{\ifx \tabu@G@extra\@empty \else \noalign{\tabu@Rextra}\fi} +\def\tabu@Rextra{\tabu@Grestore \tabu@G@extra \tabu@C@extra} +\let\tabu@C@extra \z@ +\let\tabu@G@extra \@empty +% \end{macrocode} +% \end{macro} +% +%¤<package>%% Dynamic vertical spacing adjustment: \tabulinesep ---------------- +% +% \begin{macro}{\tabulinesep} +% +% \cs\tabulinesep makes the assignment for both \cs\abovetabulinesep and \cs\belowtabulinesep. +% +% The macro may be prefixed by \cs\global. +% +% \begin{macrocode} +\newcommand*\tabulinesep{\edef\tabu@C@linesep{\the\numexpr\tabu@C@linesep+1}% + \iftabu@everyrow \aftergroup\tabu@Glinesep + \else \aftergroup\tabu@n@Glinesep + \fi + \@ifnextchar={\tabu@gobbletoken\tabu@linesep} \tabu@linesep +}% \tabulinesep +\def\tabu@linesep {\@ifnextchar_% + {\tabu@gobbletoken{\tabu@setsep\abovetabulinesep \belowtabulinesep}} + {\ifx ^\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setsep\belowtabulinesep \abovetabulinesep}}% + \else \let\tabu@temp \@empty + \afterassignment \tabu@setlinesep \abovetabulinesep + \fi \tabu@temp}% +}% \tabu@linesep +\def\tabu@setsep #1#2{\def\tabu@temp{\tabu@sets@p#1#2}\afterassignment\tabu@temp#2} +\def\tabu@sets@p #1#2{\@ifnextchar^% + {\tabu@gobbletoken{\tabu@setsep\belowtabulinesep \abovetabulinesep}} + {\ifx _\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setsep\abovetabulinesep \belowtabulinesep}}% + \else \let\tabu@temp \@empty + \tabu@Gsave \tabu@G@linesep \tabu@C@linesep \abovetabulinesep \belowtabulinesep + \fi \tabu@temp}% +}% \tabu@sets@p +\def\tabu@setlinesep {\belowtabulinesep=\abovetabulinesep + \tabu@Gsave \tabu@G@linesep \tabu@C@linesep \abovetabulinesep \belowtabulinesep +}% \tabu@setlinesep +\def\tabu@Glinesep{\ifx \tabu@G@linesep\@empty \else {\tabu@Rlinesep}\fi} +\def\tabu@n@Glinesep{\ifx \tabu@G@linesep\@empty \else \noalign{\tabu@Rlinesep}\fi} +\def\tabu@Rlinesep{\tabu@Grestore \tabu@G@linesep \tabu@C@linesep} +\let\tabu@C@linesep \z@ +\let\tabu@G@linesep \@empty +% \end{macrocode} +% \end{macro} +% +%¤<package>%% \global\extrarowsep and \global\tabulinesep ------------------- +% +% \begin{macro}{\tabu@Gsave} +% \begin{macro}{\tabu@Grestore} +% +% Utility macros to implement the possibility to prefix a macro by \cs\global. +% +% \begin{macrocode} +\def\tabu@Gsave #1#2#3#4{\xdef#1{#1% + \toks#2{\toks\the\currentgrouplevel{\global#3\the#3\global#4\the#4}}}% +}% \tabu@Gsave +\def\tabu@Grestore#1#2{% + \toks#2{}#1\toks\currentgrouplevel\expandafter{\expandafter}\the\toks#2\relax + \ifcat$\the\toks\currentgrouplevel$\else + \global\let#1\@empty \global\let#2\z@ + \the\toks\currentgrouplevel + \fi +}% \tabu@Grestore +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{Setting code for every row} +%¤<package>%% Setting code for every row --------------------------------------- +% +% \begin{macro}{\everyrow} +% +% As long as \env{tabu} needs to execute some code at \cs\everycr, +% it's not difficult to provide a command to give the user the opportunity to execute +% its own arbitrary code. However, \cs\everyrow will be used almost only with \cs\hline +% (or \cs\tabucline or \cs\midrule). +% +% \cs\everyrow can be changed anywhere inside the \env{tabu}: at the end of a row, or even +% inside a cell. +% +% The \textt{rows} \LaTeX{} counter \textt{taburow} \textt{must not be changed by the user!}. +% +% The settings are saved in a ``locally-global'' way... +% +% \begin{macrocode} +\newcommand*\everyrow{\tabu@everyrow@bgroup + \tabu@start \z@ \tabu@stop \z@ \tabu@evrstartstop +}% \everyrow +\def\tabu@evrstartstop {\@ifnextchar^% + {\afterassignment \tabu@evrstartstop \tabu@stop=}% + {\ifx ^\@let@token + \afterassignment\tabu@evrstartstop \tabu@start=% + \else \afterassignment\tabu@everyr@w \toks@ + \fi}% +}% \tabu@evrstartstop +\def\tabu@everyr@w {% + \xdef\tabu@everyrow{% + \noexpand\tabu@everyrowfalse + \let\noalign \relax + \noexpand\tabu@rowfontreset + \iftabu@colortbl \noexpand\tabu@rc@ \fi % \taburowcolors + \let\noexpand\tabu@docline \noexpand\tabu@docline@evr + \the\toks@ + \noexpand\tabu@evrh@@k + \noexpand\tabu@rearstrut + \global\advance\c@taburow \@ne}% + \iftabu@everyrow \toks@\expandafter + {\expandafter\def\expandafter\tabu@evr@L\expandafter{\the\toks@}\ignorespaces}% + \else \xdef\tabu@evr@G{\the\toks@}% + \fi + \tabu@everyrow@egroup +}% \tabu@everyr@w +\def\tabu@evr {\def\tabu@evrh@@k} % for internal use only +\tabu@evr{} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Setting line styles and colors} +%¤<package>%% line style and leaders ------------------------------------------- +% +% \begin{macro}{\newtabulinestyle} +% +% \cs\newtabulinestyle\M*{style=spec.,style=spec,style=spec} +% +% All the job is done by \cs\tabu@getline. New line style specification are always defined globally, +% and can be overwritten without warning... +% +% \begin{macrocode} +\newcommand*\newtabulinestyle [1]{% + {\@for \@tempa :=#1\do{\expandafter\tabu@newlinestyle \@tempa==\@nil}}% +}% \newtabulinestyle +\def\tabu@newlinestyle #1=#2=#3\@nil{\tabu@getline {#2}% + \tabu@sanitizearg {#1}\@tempa + \ifodd 1\ifx \@tempa\@empty \ifdefined\tabu@linestyle@ 0 \fi\fi + \global\expandafter\let + \csname tabu@linestyle@\@tempa \endcsname =\tabu@thestyle \fi +}% \tabu@newlinestyle +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabulinestyle} +% +% \cs\tabulinestyle\M*{style name}\, or\, \cs\tabulinestyle{line specs / leader} +% +% The job is done by \cs\tabu@getline. The settings as usual, are stored in a ``locally-global'' way... +% +% \begin{macrocode} +\newcommand*\tabulinestyle [1]{\tabu@everyrow@bgroup \tabu@getline{#1}% + \iftabu@everyrow + \toks@\expandafter{\expandafter \def \expandafter + \tabu@ls@L\expandafter{\tabu@thestyle}\ignorespaces}% + \gdef\tabu@ls@{\tabu@ls@L}% + \else + \global\let\tabu@ls@G \tabu@thestyle + \gdef\tabu@ls@{\tabu@ls@G}% + \fi + \tabu@everyrow@egroup +}% \tabulinestyle +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\taburulecolor} +% +% \Xpackage{colortbl} provides \cs\arrayrulecolor, but the definition is global and must be +% restores manually after the table. \cs\taburulecolor works with the same scheme as \cs\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, \cs\tabu@arc@L stores locally the color definition (\ie its definition is relative to +% the group level before the entry inside the \env*{tabu}). +% +% This is the same for \cs\doublerulesepcolor (which may be given as an optional argument to +% \cs\taburulecolor): \Xpackage{colortbl} makes the definition global, while \thispackage keeps +% grouping level into mind (``locally-global'' settings). +% +% \begin{macrocode} +\newcommand*\taburulecolor{\tabu@everyrow@bgroup \tabu@textbar \tabu@rulecolor} +\def\tabu@rulecolor #1{\toks@{}% + \def\tabu@temp #1##1#1{\tabu@ruledrsc{##1}}\@ifnextchar #1% + \tabu@temp + \tabu@rulearc +}% \tabu@rulecolor +\def\tabu@ruledrsc #1{\edef\tabu@temp{#1}\tabu@strtrim\tabu@temp + \ifx \tabu@temp\@empty \def\tabu@temp{\tabu@rule@drsc@ {}{}}% + \else \edef\tabu@temp{\noexpand\tabu@rule@drsc@ {}{\tabu@temp}}% + \fi + \tabu@temp +}% \tabu@ruledrsc@ +\def\tabu@ruledrsc@ #1#{\tabu@rule@drsc@ {#1}} +\def\tabu@rule@drsc@ #1#2{% + \iftabu@everyrow + \ifx \\#1#2\\\toks@{\let\CT@drsc@ \relax}% + \else \toks@{\def\CT@drsc@{\color #1{#2}}}% + \fi + \else + \ifx \\#1#2\\\global\let\CT@drsc@ \relax + \else \gdef\CT@drsc@{\color #1{#2}}% + \fi + \fi + \tabu@rulearc +}% \tabu@rule@drsc@ +\def\tabu@rulearc #1#{\tabu@rule@arc@ {#1}} +\def\tabu@rule@arc@ #1#2{% + \iftabu@everyrow + \ifx \\#1#2\\\toks@\expandafter{\the\toks@ \def\CT@arc@{}}% + \else \toks@\expandafter{\the\toks@ \def\CT@arc@{\color #1{#2}}}% + \fi + \toks@\expandafter{\the\toks@ + \let\tabu@arc@L \CT@arc@ + \let\tabu@drsc@L \CT@drsc@ + \ignorespaces}% + \else + \ifx \\#1#2\\\gdef\CT@arc@{}% + \else \gdef\CT@arc@{\color #1{#2}}% + \fi + \global\let\tabu@arc@G \CT@arc@ + \global\let\tabu@drsc@G \CT@drsc@ + \fi + \tabu@everyrow@egroup +}% \tabu@rule@arc@ +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\taburowcolors} +% +% \cs\taburowcolors \M*{number}\meta{number}\M*{first color .. last color} +% +% The aim of the game is to define the process that will be executed at \cs\everyrow. +% +% After that, the usual process for ``locally-global'' settings is plugged +% into \cs\tabu@cleanup and \cs\tabu@reset... +% +% \begin{macrocode} +\def\taburowcolors {\tabu@everyrow@bgroup \@testopt \tabu@rowcolors 1} +\def\tabu@rowcolors [#1]#2#{\tabu@rowc@lors{#1}{#2}} +\def\tabu@rowc@lors #1#2#3{% + \toks@{}\@defaultunits \count@ =\number0#2\relax \@nnil + \@defaultunits \tabu@start =\number0#1\relax \@nnil + \ifnum \count@<\tw@ \count@=\tw@ \fi + \advance\tabu@start \m@ne + \ifnum \tabu@start<\z@ \tabu@start \z@ \fi + \tabu@rowcolorseries #3\in@..\in@ \@nnil +}% \tabu@rowcolors +\def\tabu@rowcolorseries #1..#2\in@ #3\@nnil {% + \ifx \in@#1\relax + \iftabu@everyrow \toks@{\def\tabu@rc@{}\let\tabu@rc@L \tabu@rc@}% + \else \gdef\tabu@rc@{}\global\let\tabu@rc@G \tabu@rc@ + \fi + \else + \ifx \\#2\\\tabu@rowcolorserieserror \fi + \tabu@sanitizearg{#1}\tabu@temp + \tabu@sanitizearg{#2}\@tempa + \advance\count@ \m@ne + \iftabu@everyrow + \def\tabu@rc@ ##1##2##3##4{\def\tabu@rc@{% + \ifnum ##2=\c@taburow + \definecolorseries{tabu@rcseries@\the\tabu@nested}{rgb}{last}{##3}{##4}\fi + \ifnum \c@taburow<##2 \else + \ifnum \tabu@modulo {\c@taburow-##2}{##1+1}=\z@ + \resetcolorseries[{##1}]{tabu@rcseries@\the\tabu@nested}\fi + \xglobal\colorlet{tabu@rc@\the\tabu@nested}{tabu@rcseries@\the\tabu@nested!!+}% + \rowcolor{tabu@rc@\the\tabu@nested}\fi}% + }\edef\x{\noexpand\tabu@rc@ {\the\count@} + {\the\tabu@start} + {\tabu@temp} + {\@tempa}% + }\x + \toks@\expandafter{\expandafter\def\expandafter\tabu@rc@\expandafter{\tabu@rc@}}% + \toks@\expandafter{\the\toks@ \let\tabu@rc@L \tabu@rc@ \ignorespaces}% + \else % inside \noalign + \definecolorseries{tabu@rcseries@\the\tabu@nested}{rgb}{last}{\tabu@temp}{\@tempa}% + \expandafter\resetcolorseries\expandafter[\the\count@]{tabu@rcseries@\the\tabu@nested}% + \xglobal\colorlet{tabu@rc@\the\tabu@nested}{tabu@rcseries@\the\tabu@nested!!+}% + \let\noalign \relax \rowcolor{tabu@rc@\the\tabu@nested}% + \def\tabu@rc@ ##1##2{\gdef\tabu@rc@{% + \ifnum \tabu@modulo {\c@taburow-##2}{##1+1}=\@ne + \resetcolorseries[{##1}]{tabu@rcseries@\the\tabu@nested}\fi + \xglobal\colorlet{tabu@rc@\the\tabu@nested}{tabu@rcseries@\the\tabu@nested!!+}% + \rowcolor{tabu@rc@\the\tabu@nested}}% + }\edef\x{\noexpand\tabu@rc@{\the\count@}{\the\c@taburow}}\x + \global\let\tabu@rc@G \tabu@rc@ + \fi + \fi + \tabu@everyrow@egroup +}% \tabu@rowcolorseries +\tabuDisableCommands {\let\tabu@rc@ \@empty } +\def\tabu@rowcolorserieserror {\PackageError{tabu} + {Invalid syntax for \string\taburowcolors + \MessageBreak Please look at the documentation!}\@ehd +}% \tabu@rowcolorserieserror +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabureset} +% +% Simply -- and locally -- reset the default values for \cs\tabulinesep (0pt), \cs\extrarowsep (0pt), \cs\extratabsurround (0pt), +% \cs\tabulinestyle\M*{}, \cs\everyrow\M*{} and \cs\taburulecolor\M*[]\M*{}. +% +% \begin{macrocode} +\newcommand*\tabureset {% + \tabulinesep=\z@ \extrarowsep=\z@ \extratabsurround=\z@ + \tabulinestyle{}\everyrow{}\taburulecolor||{}\taburowcolors{}% +}% \tabureset +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Parsing line styles} +%¤<package>%% Parsing the line styles ------------------------------------------ +% +% \begin{macro}{\tabu@getline} +% +% This macro parses a line specification argument of the form: +% +% \centerline{\ttfamily 3pt BlanchedAlmond on 4pt Crimsom off 2pt ForestGreen} +% +% Note that \text{Crimson} will overwrite \textt{BlanchedAlmond} in this case: the color +% for the line dash may be specified after the line width or after the line dash length. +% +% The process uses \cs\scantokens on the argument given by the user, which is first +% expanded in a context where the \xpackage{babel} switch \cs{if@save@actives} is set to \textt{true}. +% Then \cs\scantokens is used on the argument in a group where the letter ``\texttbf o'' is active, +% and defined to be a macro which rewrites the line specification. Incidentally, the comma is active too, +% and expands to a space. This way the initial argument is ``genetically modified'', so that it becomes +% very easy to assign dimensions (thickness, dash length and gap length) and colors separately. +% +% For example: \textt{3pt BlanchedAlmond on 4pt Crimson} will be expanded in a context where +% ``\texttbf o'' is active (and equal to \cs\tabu@oxiii, the \textt{xiii} suffix means ``active'' \ie \cs\catcode$=13$). +% +% Then the ``\textttbf o'' in \textt{BlanchedAlm\texttbf ond} is rewritten as follow: +% \begin{enumerate} +% \item ``\texttbf o'' sees ``\texttbf n'' after itself, then it expands \cs\tabu@onxiii. +% \item \cs\tabu@onxiii sees a character whose catcode is not other, then the rewriting process is aborted, +% and ``\texttbf{ond}'' is rewritten as ``\texttbf{ond}'' where the ``\texttbf o'' is not active but the usual letter ``\texttbf o''. +% \end{enumerate} +% +% The next ``\texttbf o'' is rewritten as follow: +% \begin{enumerate} +% \item ``\texttbf o'' sees ``\texttbf n'' after itself, then it expands \cs\tabu@onxiii. +% \item \cs\tabu@onxiii sees a space (which is active): it calls back itself again, +% \item \cs\tabu@onxiii sees a character whose catcode is other: then the sequence ``\texttbf{on\textvisiblespace 3}'' +% is rewritten as:\\ +% ``\cs\tabu@ \cs\tabu@on =4pt Crimson'' +% \end{enumerate} +% +% Finally the whole argument is rewritten as: +% +% {\centering +% \cs\tabu@ \cs\tabu@thick =3pt BlanchedAlmond \cs\tabu@ \cs\tabu@on =4pt Crimson \cs\tabu@ \cs\tabu@ \par} +% +% Define \cs\tabu@ as an appropriate macro which uses \cs\afterassignment to: +% \begin{enumerate} +% \item Assign the corresponding dimension (thickness, dash length or gap length). +% \item Collect the rest until the next \cs\tabu@, trim spaces and check if the color exists. +% \end{enumerate} +% +% Limitation: A color name must not contain a sequence that matches on of the patterns: +% +% \begin{tabu}{XcX} +% ...\texttbf{on}\meta{a character of category 12}... & or & ...\texttbf{off}\meta{a character of category 12}... +% \end{tabu} +% +% But this ``limitation'' is not too heavy, I suppose... +% +% The result is \cs\tabu@thestyle: a \textt{tabu} line style to be used to rewrite a \texttbf\textbar\, column, +% for \cs\tabucline. +% +% We use locally the \LaTeX{} defined dimen registers \cs\@tempdima, \cs\@tempdimb and \cs\@tempdimc. +% For clarity, their names are \cs\tabu@thick, \cs\tabu@on and \cs\tabu@off here... +% +% \begin{macrocode} +\def\tabu@getline #1{\begingroup + \csname \ifcsname if@safe@actives\endcsname % <babel> + @safe@activestrue\else + relax\fi \endcsname + \edef\tabu@temp{#1}\tabu@sanitizearg{#1}\@tempa + \let\tabu@thestyle \relax + \ifcsname tabu@linestyle@\@tempa \endcsname + \edef\tabu@thestyle{\endgroup + \def\tabu@thestyle{\expandafter\noexpand + \csname tabu@linestyle@\@tempa\endcsname}% + }\tabu@thestyle + \else \expandafter\tabu@definestyle \tabu@temp \@nil + \fi +}% \tabu@getline +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@definestyle} +% +% Here is the \cs\scantokens stuff. +% +% \begin{macrocode} +\def\tabu@definestyle #1#2\@nil {\endlinechar \m@ne \makeatletter + \tabu@thick \maxdimen \tabu@on \maxdimen \tabu@off \maxdimen + \let\tabu@c@lon \@undefined \let\tabu@c@loff \@undefined + \ifodd 1\ifcat .#1\else\ifcat\relax #1\else 0\fi\fi % catcode 12 or non expandable cs + \def\tabu@temp{\tabu@getparam{thick}}% + \else \def\tabu@temp{\tabu@getparam{thick}\maxdimen}% + \fi + {% + \let\tabu@ \relax + \def\:{\obeyspaces \tabu@oXIII \tabu@commaXIII \edef\:}% (space active \: happy ;-)) + \scantokens{\:{\tabu@temp #1#2 \tabu@\tabu@}}% + \expandafter}\expandafter + \def\expandafter\:\expandafter{\:}% line spec rewritten now ;-) + \def\;{\def\:}% + \scantokens\expandafter{\expandafter\;\expandafter{\:}}% space is now inactive (catcode 10) + \let\tabu@ \tabu@getcolor \:% all arguments are ready now ;-) + \ifdefined\tabu@c@lon \else \let\tabu@c@lon\@empty \fi + \ifx \tabu@c@lon\@empty \def\tabu@c@lon{\CT@arc@}\fi + \ifdefined\tabu@c@loff \else \let\tabu@c@loff \@empty \fi + \ifdim \tabu@on=\maxdimen \ifdim \tabu@off<\maxdimen + \tabu@on \tabulineon \fi\fi + \ifdim \tabu@off=\maxdimen \ifdim \tabu@on<\maxdimen + \tabu@off \tabulineoff \fi\fi + \ifodd 1\ifdim \tabu@off=\maxdimen \ifdim \tabu@on=\maxdimen 0 \fi\fi + \in@true % <leaders> + \else \in@false % <rule> + \fi + \ifdim\tabu@thick=\maxdimen \def\tabu@thick{\arrayrulewidth}% + \else \edef\tabu@thick{\the\tabu@thick}% + \fi + \edef \tabu@thestyle ##1##2{\endgroup + \def\tabu@thestyle{% + \ifin@ \noexpand\tabu@leadersstyle {\tabu@thick} + {\the\tabu@on}{##1} + {\the\tabu@off}{##2}% + \else \noexpand\tabu@rulesstyle + {##1\vrule width \tabu@thick}% + {##1\leaders \hrule height \tabu@thick \hfil}% + \fi}% + }\expandafter \expandafter + \expandafter \tabu@thestyle \expandafter + \expandafter \expandafter + {\expandafter\tabu@c@lon\expandafter}\expandafter{\tabu@c@loff}% +}% \tabu@definestyle +% \end{macrocode} +% \end{macro} +% \begin{macro}{\tabu@onxiii} +% \begin{macro}{\tabu@ofxiii} +% \begin{macro}{\tabu@offiii} +% +% We have to define the active ``\texttbf o'' character, which looks for the next tokens, +% trying to find a pattern like \texttbf{on}\meta{category 12} or \texttbf{off}\meta{category 12} +% (possibly with -- active -- spaces between \textt{on} or \textt{off} and the next character of catcode 12). +% +% \begin{macrocode} +{\catcode`\O=\active \lccode`\O=`\o \catcode`\,=\active + \lowercase{\gdef\tabu@oXIII {\catcode`\o=\active \let O=\tabu@oxiii}} + \gdef\tabu@commaXIII {\catcode`\,=\active \let ,=\space} +}% \catcode +\def\tabu@oxiii #1{% + \ifcase \ifx n#1\z@ \else + \ifx f#1\@ne\else + \tw@ \fi\fi + \expandafter\tabu@onxiii + \or \expandafter\tabu@ofxiii + \else o% + \fi#1}% +\def\tabu@onxiii #1#2{% + \ifcase \ifx !#2\tw@ \else + \ifcat.\noexpand#2\z@ \else + \ifx \tabu@spxiii#2\@ne\else + \tw@ \fi\fi\fi + \tabu@getparam{on}#2\expandafter\@gobble + \or \expandafter\tabu@onxiii % (space is active) + \else o\expandafter\@firstofone + \fi{#1#2}}% +\def\tabu@ofxiii #1#2{% + \ifx #2f\expandafter\tabu@offxiii + \else o\expandafter\@firstofone + \fi{#1#2}} +\def\tabu@offxiii #1#2{% + \ifcase \ifx !#2\tw@ \else + \ifcat.\noexpand#2\z@ \else + \ifx\tabu@spxiii#2\@ne \else + \tw@ \fi\fi\fi + \tabu@getparam{off}#2\expandafter\@gobble + \or \expandafter\tabu@offxiii % (space is active) + \else o\expandafter\@firstofone + \fi{#1#2}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@getparam} +% +% The rewritten stuff. +% +% \begin{macrocode} +\def\tabu@getparam #1{\tabu@ \csname tabu@#1\endcsname=} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@getcolor} +% +% \cs\tabu@ \cs\tabu@on =\meta{3pt} \textt{Crimson}\cs\tabu@ +% +% \cs\tabu@getcolor first makes the assignment to \cs\tabu@on and then looks for the color +% name which might have been placed before the next \cs\tabu@. +% +% \begin{macrocode} +\def\tabu@getcolor #1{% \tabu@ <- \tabu@getcolor after \edef + \ifx \tabu@#1\else % no more spec + \let\tabu@theparam=#1\afterassignment \tabu@getc@l@r #1\fi +}% \tabu@getcolor +\def\tabu@getc@l@r #1\tabu@ {% + \def\tabu@temp{#1}\tabu@strtrim \tabu@temp + \ifx \tabu@temp\@empty + \else%\ifcsname \string\color@\tabu@temp \endcsname % if the color exists + \ifx \tabu@theparam \tabu@off \let\tabu@c@loff \tabu@c@l@r + \else \let\tabu@c@lon \tabu@c@l@r + \fi + %\else \tabu@warncolour{\tabu@temp}% + \fi%\fi + \tabu@ % next spec +}% \tabu@getc@l@r +\def\tabu@warncolour #1{\PackageWarning{tabu} + {Color #1 is not defined. Default color used}% +}% \tabu@warncolour +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@leadersstyle} +% \begin{macro}{\tabu@rulesstyle} +% +% When a style is executed, it expands either \cs\tabu@leadersstyle or \cs\tabu@rulesstyle depending on whether 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. +% +% \cs\tabu@leadersstyle eventually rebuilds the (horizontal and vertical) leaders boxes, and then define two macros: +% \cs\tabu@thevleaders and \cs\tabu@thehleades, suitable to draw vertical and horizontal lines respectively. +% Incidentally, \cs\tabu@leaders is defined to be the parameters for the leaders. +% +% \cs\tabu@rulesstyle only defines the two macros \cs\tabu@thevrule and \cs\tabu@thehrule. The control sequence +% \cs\tabu@leaders is undefined so that we know if the style contains a leader or a rule. +% +% \begin{macrocode} +\def\tabu@leadersstyle #1#2#3#4#5{\def\tabu@leaders{{#1}{#2}{#3}{#4}{#5}}% + \ifx \tabu@leaders\tabu@leaders@G \else + \tabu@LEADERS{#1}{#2}{#3}{#4}{#5}\fi +}% \tabu@leadersstyle +\def\tabu@rulesstyle #1#2{\let\tabu@leaders \@undefined + \gdef\tabu@thevrule{#1}\gdef\tabu@thehrule{#2}% +}% \tabu@rulesstyle +% \end{macrocode} +% \end{macro} +% \end{macro} +% +%¤<package>%% The leaders boxes ------------------------------------------------ +% \begin{macro}{\tabu@LEADERS} +% +% Here the two leaders boxes \cs\tabu@hleads and \cs\tabu@vleads are built, as well as the leaders macros +% \cs\tabu@thehleaders and \cs\tabu@thevleaders. +% +% \begin{macrocode} +\def\tabu@LEADERS #1#2#3#4#5{%% width, dash, dash color, gap, gap color + {\let\color \tabu@color % => during trials -> \color = \tabu@nocolor + {% % but the leaders boxes should have colors ! + \def\@therule{\vrule}\def\@thick{height}\def\@length{width}% + \def\@box{\hbox}\def\@unbox{\unhbox}\def\@elt{\wd}% + \def\@skip{\hskip}\def\@ss{\hss}\def\tabu@leads{\tabu@hleads}% + \tabu@l@@d@rs {#1}{#2}{#3}{#4}{#5}% + \global\let\tabu@thehleaders \tabu@theleaders + }% + {% + \def\@therule{\hrule}\def\@thick{width}\def\@length{height}% + \def\@box{\vbox}\def\@unbox{\unvbox}\def\@elt{\ht}% + \def\@skip{\vskip}\def\@ss{\vss}\def\tabu@leads{\tabu@vleads}% + \tabu@l@@d@rs {#1}{#2}{#3}{#4}{#5}% + \global\let\tabu@thevleaders \tabu@theleaders + }% + \gdef\tabu@leaders@G{{#1}{#2}{#3}{#4}{#5}}% + }% +}% \tabu@LEADERS +\def\tabu@therule #1#2{\@therule \@thick#1\@length\dimexpr#2/2 \@depth\z@} +\def\tabu@l@@d@rs #1#2#3#4#5{%% width, dash, dash color, gap, gap color + \global\setbox \tabu@leads=\@box{% + {#3\tabu@therule{#1}{#2}}% + \ifx\\#5\\\@skip#4\else{#5\tabu@therule{#1}{#4*2}}\fi + {#3\tabu@therule{#1}{#2}}}% + \global\setbox\tabu@leads=\@box to\@elt\tabu@leads{\@ss + {#3\tabu@therule{#1}{#2}}\@unbox\tabu@leads}% + \edef\tabu@theleaders ##1{\def\noexpand\tabu@theleaders {% + {##1\tabu@therule{#1}{#2}}% + \xleaders \copy\tabu@leads \@ss + \tabu@therule{0pt}{-#2}{##1\tabu@therule{#1}{#2}}}% + }\tabu@theleaders{#3}% +}% \tabu@l@@d@rs +% \end{macrocode} +% \end{macro} +% +% +% \subsection{The entry inside \env{tabu}} +% +% \subsubsection{\cs{tabu}, \cs{endtabu}, \cs{longtabu} and \cs{endlontabu}} +%¤<package>%% \tabu \endtabu \tabu* \longtabu \endlongtabu \longtabu* ---------- +% +% \begin{macro}{\tabu} +% +% \cs\tabu and \cs\longtabu are the commands of the environments. +% +% \begin{macro}{\endtabu} +% +% \cs\endtabu is \cs\endtabular or \cs\endarray in math mode. +% +% \begin{macrocode} +\newcommand*\tabu {\tabu@longfalse + \ifmmode \def\tabu@ {\array}\def\endtabu {\endarray}% + \else \def\tabu@ {\tabu@tabular}\def\endtabu {\endtabular}\fi + \expandafter\let\csname tabu*\endcsname \tabu + \expandafter\def\csname endtabu*\endcsname{\endtabu}% + \tabu@spreadfalse \tabu@negcoeffalse \tabu@settarget +}% {tabu} +\let\tabu@tabular \tabular % <For LyX: some users redefine \tabular...> +\expandafter\def\csname tabu*\endcsname{\tabuscantokenstrue \tabu} +\newcommand*\longtabu {\tabu@longtrue + \ifmmode\PackageError{tabu}{longtabu not allowed in math mode}\fi + \def\tabu@{\longtable}\def\endlongtabu{\endlongtable}% + \LTchunksize=\@M + \expandafter\let\csname tabu*\endcsname \tabu + \expandafter\def\csname endlongtabu*\endcsname{\endlongtabu}% + \let\LT@startpbox \tabu@LT@startpbox % \everypar{ array struts } + \tabu@spreadfalse \tabu@negcoeffalse \tabu@settarget +}% {longtabu} +\expandafter\def\csname longtabu*\endcsname{\tabuscantokenstrue \longtabu} +\def\tabu@nolongtabu{\PackageError{tabu} + {longtabu requires the longtable package}\@ehd} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{Setting the \env{tabu} target} +%¤<package>%% Read the target and then : \tabular or \@array ------------------ +% +% \begin{macro}{\tabu@settarget} +% \begin{macro}{\tabu@begin} +% +% The macro sets \cs\tabu@target (a dimen) to the value specified for ``\env{tabu to}'' or ``\env{tabu spread}''. +% +% \begin{macrocode} +\def\tabu@settarget {\futurelet\@let@token \tabu@sett@rget } +\def\tabu@sett@rget {\tabu@target \z@ + \ifcase \ifx \bgroup\@let@token \z@ \else + \ifx \@sptoken\@let@token \@ne \else + \if t\@let@token \tw@ \else + \if s\@let@token \thr@@\else + \z@\fi\fi\fi\fi + \expandafter\tabu@begin + \or \expandafter\tabu@gobblespace\expandafter\tabu@settarget + \or \expandafter\tabu@to + \or \expandafter\tabu@spread + \fi +}% \tabu@sett@rget +\def\tabu@to to{\def\tabu@halignto{to}\tabu@gettarget} +\def\tabu@spread spread{\tabu@spreadtrue\def\tabu@halignto{spread}\tabu@gettarget} +\def\tabu@gettarget {\afterassignment\tabu@linegoaltarget \tabu@target } +\def\tabu@linegoaltarget {\futurelet\tabu@temp \tabu@linegoalt@rget } +\def\tabu@linegoalt@rget {% + \ifx \tabu@temp\LNGL@setlinegoal + \LNGL@setlinegoal \expandafter \@firstoftwo \fi % @gobbles \LNGL@setlinegoal + \tabu@begin +}% \tabu@linegoalt@rget +\def\tabu@begin #1#{% + \iftabu@measuring \expandafter\tabu@nestedmeasure \fi + \ifdim \tabu@target=\z@ \let\tabu@halignto \@empty + \else \edef\tabu@halignto{\tabu@halignto\the\tabu@target}% + \fi + \@testopt \tabu@tabu@ \tabu@aligndefault #1\@nil +}% \tabu@begin +\long\def\tabu@tabu@ [#1]#2\@nil #3{\tabu@setup + \def\tabu@align {#1}\def\tabu@savedpream{\NC@find #3}% + \tabu@ [\tabu@align ]#2{#3\tabu@rewritefirst }% +}% \tabu@tabu@ +\def\tabu@nestedmeasure {% + \ifodd 1\iftabu@spread \else \ifdim\tabu@target=\z@ \else 0 \fi\fi\relax + \tabu@spreadtrue + \else \begingroup \iffalse{\fi \ifnum0=`}\fi + \toks@{}\def\tabu@stack{b}% + \expandafter\tabu@collectbody\expandafter\tabu@quickrule + \expandafter\endgroup + \fi +}% \tabu@nestedmeasure +\def\tabu@quickrule {\indent\vrule height\z@ depth\z@ width\tabu@target} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +%¤<package>%% \tabu@setup \tabu@init \tabu@indent +% \begin{macro}{\tabu@setup} +% \begin{macro}{\tabu@init} +% \begin{macro}{\tabu@indent} +% +% \cs\tabu@init is expanded only when \env{tabu} is not nested. +% In this case, and if \cs\parindent$>0$, and if \cs\tabudefaulttarget$=$\cs\linewidth, +% the correction of the default target for paragraph indentation is executed +% (see \hyperref[Paragraph indentation.subsec]{paragraph indentation}). +% +% \begin{macrocode} +\def\tabu@setup{\tabu@alloc@ + \ifcase \tabu@nested + \ifmmode \else \iftabu@spread\else \ifdim\tabu@target=\z@ + \let\tabu@afterendpar \par + \fi\fi\fi + \def\tabu@aligndefault{c}\tabu@init \tabu@indent + \else % <nested tabu> + \def\tabu@aligndefault{t}\let\tabudefaulttarget \linewidth + \fi + \let\tabu@thetarget \tabudefaulttarget \let\tabu@restored \@undefined + \edef\tabu@NC@list{\the\NC@list}\NC@list{\NC@do \tabu@rewritefirst}% + \everycr{}\let\@startpbox \tabu@startpbox % for nested tabu inside longtabu... + \let\@endpbox \tabu@endpbox % idem " " " " " " + \let\@tabarray \tabu@tabarray % idem " " " " " " + \tabu@setcleanup \tabu@setreset +}% \tabu@setup +\def\tabu@init{\tabu@starttimer \tabu@measuringfalse + \edef\tabu@hfuzz {\the\dimexpr\hfuzz+1sp}\global\tabu@footnotes{}% + \let\firsthline \tabu@firsthline \let\lasthline \tabu@lasthline + \let\firstline \tabu@firstline \let\lastline \tabu@lastline + \let\hline \tabu@hline \let\@xhline \tabu@xhline + \let\color \tabu@color \let\@arstrutbox \tabu@arstrutbox + \iftabu@colortbl\else\let\LT@@hline \tabu@LT@@hline \fi + \tabu@trivlist %<restore \\=\@normalcr inside lists> + \let\@footnotetext \tabu@footnotetext \let\@xfootnotetext \tabu@xfootnotetext + \let\@xfootnote \tabu@xfootnote \let\centering \tabu@centering + \let\raggedright \tabu@raggedright \let\raggedleft \tabu@raggedleft + \let\tabudecimal \tabu@tabudecimal \let\Centering \tabu@Centering + \let\RaggedRight \tabu@RaggedRight \let\RaggedLeft \tabu@RaggedLeft + \let\justifying \tabu@justifying \let\rowfont \tabu@rowfont + \let\fbox \tabu@fbox \let\color@b@x \tabu@color@b@x + \let\tabu@@everycr \everycr \let\tabu@@everypar \everypar + \let\tabu@prepnext@tokORI \prepnext@tok\let\prepnext@tok \tabu@prepnext@tok + \let\tabu@multicolumnORI\multicolumn \let\multicolumn \tabu@multicolumn + \let\tabu@startpbox \@startpbox % for nested tabu inside longtabu pfff !!! + \let\tabu@endpbox \@endpbox % idem " " " " " " " + \let\tabu@tabarray \@tabarray % idem " " " " " " " + \tabu@adl@fix \let\endarray \tabu@endarray % <fix> colortbl & arydshln (delarray) + \iftabu@colortbl\CT@everycr\expandafter{\expandafter\iftabu@everyrow \the\CT@everycr \fi}\fi +}% \tabu@init +\def\tabu@indent{% correction for indentation + \ifdim \parindent>\z@\ifx \linewidth\tabudefaulttarget +% + \everypar\expandafter{% + \the\everypar\everypar\expandafter{\the\everypar}% + \setbox\z@=\lastbox + \ifdim\wd\z@>\z@ \edef\tabu@thetarget + {\the\dimexpr -\wd\z@+\tabudefaulttarget}\fi + \box\z@}% + \fi\fi +}% \tabu@indent +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@setcleanup} +% +% We have to save locally (in the group of the environment) the current value of +% the last global assignments to \cs\CT@arc@, \cs\CT@drsc@, \cs\tabu@ls@ etc. +% +% \begin{macro}{\tabu@cleanup} +% +% Restoration will be done globally after the box that contains the tabular by \cs\tabu@cleanup. +% +% \begin{macrocode} +\def\tabu@setcleanup {% saves last global assignments + \ifodd 1\ifmmode \else \iftabu@long \else 0\fi\fi\relax + \def\tabu@aftergroupcleanup{% + \def\tabu@aftergroupcleanup{\aftergroup\tabu@cleanup}}% + \else + \def\tabu@aftergroupcleanup{% + \aftergroup\aftergroup\aftergroup\tabu@cleanup + \let\tabu@aftergroupcleanup \relax}% + \fi + \let\tabu@arc@Gsave \tabu@arc@G + \let\tabu@arc@G \tabu@arc@L % <init> + \let\tabu@drsc@Gsave \tabu@drsc@G + \let\tabu@drsc@G \tabu@drsc@L % <init> + \let\tabu@ls@Gsave \tabu@ls@G + \let\tabu@ls@G \tabu@ls@L % <init> + \let\tabu@rc@Gsave \tabu@rc@G + \let\tabu@rc@G \tabu@rc@L % <init> + \let\tabu@evr@Gsave \tabu@evr@G + \let\tabu@evr@G \tabu@evr@L % <init> + \let\tabu@celllalign@save \tabu@celllalign + \let\tabu@cellralign@save \tabu@cellralign + \let\tabu@cellleft@save \tabu@cellleft + \let\tabu@cellright@save \tabu@cellright + \let\tabu@@celllalign@save \tabu@@celllalign + \let\tabu@@cellralign@save \tabu@@cellralign + \let\tabu@@cellleft@save \tabu@@cellleft + \let\tabu@@cellright@save \tabu@@cellright + \let\tabu@rowfontreset@save \tabu@rowfontreset + \let\tabu@@rowfontreset@save\tabu@@rowfontreset + \let\tabu@rowfontreset \@empty + \edef\tabu@alloc@save {\the\tabu@alloc}% restore at \tabu@reset + \edef\c@taburow@save {\the\c@taburow}% + \edef\tabu@naturalX@save {\the\tabu@naturalX}% + \let\tabu@naturalXmin@save \tabu@naturalXmin + \let\tabu@naturalXmax@save \tabu@naturalXmax + \let\tabu@mkarstrut@save \tabu@mkarstrut + \edef\tabu@clarstrut{% + \extrarowheight \the\dimexpr \ht\@arstrutbox-\ht\strutbox \relax + \extrarowdepth \the\dimexpr \dp\@arstrutbox-\dp\strutbox \relax + \let\noexpand\@arraystretch \@ne \noexpand\tabu@rearstrut}% +}% \tabu@setcleanup +\def\tabu@cleanup {\begingroup + \globaldefs\@ne \tabu@everyrowtrue + \let\tabu@arc@G \tabu@arc@Gsave + \let\CT@arc@ \tabu@arc@G + \let\tabu@drsc@G \tabu@drsc@Gsave + \let\CT@drsc@ \tabu@drsc@G + \let\tabu@ls@G \tabu@ls@Gsave + \let\tabu@ls@ \tabu@ls@G + \let\tabu@rc@G \tabu@rc@Gsave + \let\tabu@rc@ \tabu@rc@G + \let\CT@do@color \relax + \let\tabu@evr@G \tabu@evr@Gsave + \let\tabu@celllalign \tabu@celllalign@save + \let\tabu@cellralign \tabu@cellralign@save + \let\tabu@cellleft \tabu@cellleft@save + \let\tabu@cellright \tabu@cellright@save + \let\tabu@@celllalign \tabu@@celllalign@save + \let\tabu@@cellralign \tabu@@cellralign@save + \let\tabu@@cellleft \tabu@@cellleft@save + \let\tabu@@cellright \tabu@@cellright@save + \let\tabu@rowfontreset \tabu@rowfontreset@save + \let\tabu@@rowfontreset \tabu@@rowfontreset@save + \tabu@naturalX =\tabu@naturalX@save + \let\tabu@naturalXmax \tabu@naturalXmax@save + \let\tabu@naturalXmin \tabu@naturalXmin@save + \let\tabu@mkarstrut \tabu@mkarstrut@save + \c@taburow =\c@taburow@save + \ifcase \tabu@nested \tabu@alloc \m@ne\fi + \endgroup % <end of \globaldefs> + \ifcase \tabu@nested + \the\tabu@footnotes \global\tabu@footnotes{}% + \tabu@afterendpar \tabu@elapsedtime + \fi + \tabu@clarstrut + \everyrow\expandafter {\tabu@evr@G}% +}% \tabu@cleanup +\let\tabu@afterendpar \relax +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@setreset} +% +% At the beginning of each trial, we have to restore the current value that were active +% at the entry in the \env*{tabu} (for they could have been globally overwritten inside the tabular). +% +% The same must occur when using \cs\usetabu as a preamble. Values are restored locally inside the +% \env{tabu} box. +% +% \begin{macro}{\tabu@reset} +% +% \cs\tabu@setreset defines \cs\tabu@reset to be expanded at the beginning of each trial and +% when \cs\usetabu is used. +% +% \begin{macrocode} +\def\tabu@setreset {% + \edef\tabu@savedparams {% \relax for \tabu@message@save + \ifmmode \col@sep \the\arraycolsep + \else \col@sep \the\tabcolsep \fi \relax + \arrayrulewidth \the\arrayrulewidth \relax + \doublerulesep \the\doublerulesep \relax + \extratabsurround \the\extratabsurround \relax + \extrarowheight \the\extrarowheight \relax + \extrarowdepth \the\extrarowdepth \relax + \abovetabulinesep \the\abovetabulinesep \relax + \belowtabulinesep \the\belowtabulinesep \relax + \def\noexpand\arraystretch{\arraystretch}% + \ifdefined\minrowclearance \minrowclearance\the\minrowclearance\relax\fi}% + \begingroup + \@temptokena\expandafter{\tabu@savedparams}% => only for \savetabu / \usetabu + \ifx \tabu@arc@L\relax \else \tabu@setsave \tabu@arc@L \fi + \ifx \tabu@drsc@L\relax \else \tabu@setsave \tabu@drsc@L \fi + \tabu@setsave \tabu@ls@L \tabu@setsave \tabu@evr@L + \expandafter \endgroup \expandafter + \def\expandafter\tabu@saved@ \expandafter{\the\@temptokena + \let\tabu@arc@G \tabu@arc@L + \let\tabu@drsc@G \tabu@drsc@L + \let\tabu@ls@G \tabu@ls@L + \let\tabu@rc@G \tabu@rc@L + \let\tabu@evr@G \tabu@evr@L}% + \def\tabu@reset{\tabu@savedparams + \tabu@everyrowtrue \c@taburow \z@ + \let\CT@arc@ \tabu@arc@L + \let\CT@drsc@ \tabu@drsc@L + \let\tabu@ls@ \tabu@ls@L + \let\tabu@rc@ \tabu@rc@L + \global\tabu@alloc \tabu@alloc@save + \everyrow\expandafter{\tabu@evr@L}}% +}% \tabu@reset +\def\tabu@setsave #1{\expandafter\tabu@sets@ve #1\@nil{#1}} +\long\def\tabu@sets@ve #1\@nil #2{\@temptokena\expandafter{\the\@temptokena \def#2{#1}}} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{The rewriting process: inside the ``\cs{@mkpream} group''} +%¤<package>%% The Rewritting Process ------------------------------------------- +% +% \subsubsection{New column types and private (new) column types} +% +% \begin{macro}{\tabu@newcolumntype} +% +% A helper macro to create new column types for \env{tabu}. +% +% The column types \textbf{are not appended} to \cs\NC@list in order to keep them local to \env{tabu}. +% +% \begin{macrocode} +\def\tabu@newcolumntype #1{% + \expandafter\tabu@new@columntype + \csname NC@find@\string#1\expandafter\endcsname + \csname NC@rewrite@\string#1\endcsname + {#1}% +}% \tabu@newcolumntype +\def\tabu@new@columntype #1#2#3{% + \def#1##1#3{\NC@{##1}}% + \let#2\relax \newcommand*#2% +}% \tabu@new@columntype +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@privatecolumntype} +% +% Columns types defined with \cs\tabu@privatecolumntype are "mounted" only inside the \cs\@mkpream group +% of \env{tabu}. +% +% \begin{macrocode} +\def\tabu@privatecolumntype #1{% + \expandafter\tabu@private@columntype + \csname NC@find@\string#1\expandafter\endcsname + \csname NC@rewrite@\string#1\expandafter\endcsname + \csname tabu@NC@find@\string#1\expandafter\endcsname + \csname tabu@NC@rewrite@\string#1\endcsname + {#1}% +}% \tabu@privatecolumntype +\def\tabu@private@columntype#1#2#3#4{% + \g@addto@macro\tabu@privatecolumns{\let#1#3\let#2#4}% + \tabu@new@columntype#3#4% +}% \tabu@private@columntype +\let\tabu@privatecolumns \@empty +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{High priority columns} +% +% \begin{macro}{\tabucolumn} +% +% \cs\tabucolumn puts a user-defined column in high priority in the \env{tabu} rewriting process. +% +% \begin{macrocode} +\newcommand*\tabucolumn [1]{\expandafter \def \expandafter + \tabu@highprioritycolumns\expandafter{\tabu@highprioritycolumns + \NC@do #1}}% +\let\tabu@highprioritycolumns \@empty +% \end{macrocode} +% \end{macro} +% +% +% \subsubsection{Rewriting vertical lines and leaders} +%¤<package>%% The | ``column'' : rewriting process -------------------------- +% +% \begin{macro}{| (private column type)} +% +% This is the rewrite macro for the \texttbf\textbar\ column type inside \textt{tabu} and \textt{longtabu}. +% +% Vertical lines are \textit{simply rewritten} as special \texttbf! columns. +% +% \begin{macrocode} +\tabu@privatecolumntype |{\tabu@rewritevline} +\newcommand*\tabu@rewritevline[1][]{\tabu@vlinearg{#1}% + \expandafter \NC@find \tabu@rewritten} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@lines} +% +% The \texttbf\textbar\, token for vertical lines may have a special +% catcode. \xfile{array.sty} makes the test with \cs\if and therefore, +% it is catcode insensitiv. Here, we use \cs\scantokens and check if +% \texttbf\textbar\, is not an \emph{other} character. +% +% \begin{macrocode} +\def\tabu@lines #1{% + \ifx|#1\else \tabu@privatecolumntype #1{\tabu@rewritevline}\fi + \NC@list\expandafter{\the\NC@list \NC@do #1}% +}% \tabu@lines@ +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@vlinearg} +% +% The macro that parses the optional argument of \textt\textbar\ vertical lines... +% +% \begin{macrocode} +\def\tabu@vlinearg #1{% + \ifx\\#1\\\def\tabu@thestyle {\tabu@ls@}% + \else\tabu@getline {#1}% + \fi + \def\tabu@rewritten ##1{\def\tabu@rewritten{!{##1\tabu@thevline}}% + }\expandafter\tabu@rewritten\expandafter{\tabu@thestyle}% + \expandafter \tabu@keepls \tabu@thestyle \@nil +}% \tabu@vlinearg +\def\tabu@keepls #1\@nil{% + \ifcat $\@cdr #1\@nil $% + \ifx \relax#1\else + \ifx \tabu@ls@#1\else + \let#1\relax + \xdef\tabu@mkpreambuffer{\tabu@mkpreambuffer + \tabu@savels\noexpand#1}\fi\fi\fi +}% \tabu@keepls +\def\tabu@thevline {\begingroup + \ifdefined\tabu@leaders + \setbox\@tempboxa=\vtop to\dimexpr + \ht\@arstrutbox+\dp\@arstrutbox{{\tabu@thevleaders}}% + \ht\@tempboxa=\ht\@arstrutbox \dp\@tempboxa=\dp\@arstrutbox + \box\@tempboxa + \else + \tabu@thevrule + \fi \endgroup +}% \tabu@thevline +\def\tabu@savels #1{% + \expandafter\let\csname\string#1\endcsname #1% + \expandafter\def\expandafter\tabu@reset\expandafter{\tabu@reset + \tabu@resetls#1}}% +\def\tabu@resetls #1{\expandafter\let\expandafter#1\csname\string#1\endcsname}% +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Vertical lines and leaders in the \cs{multicolumn} preamble} +%¤<package>%% \multicolumn inside tabu environment ----------------------------- +% +% \begin{macro}{\tabu@rewritemulticolumn} +% +% A special rewrite to allow \texttbf\textbar\M*[...] in \cs\multicolumn preamble inside \env*{tabu}. +% +% As long as \cs\multicolumn begins with \cs\omit (via \cs\multispan) special care has to be taken: +% everything shall be purely expandable until \cs\omit. +% +% \cs\multicolumn is not an environment: no group is opened apart the \cs\@mkpream group. +% We open a semi simple group for \cs\multicolumn when inside \env{tabu}, in order for the setup +% to be local (in case a user would try to embed a \env{tabular} inside the argument of \cs\multicolumn...) +% +% \begin{macrocode} +\tabu@newcolumntype \tabu@rewritemulticolumn{% + \aftergroup \tabu@endrewritemulticolumn % after \@mkpream group + \NC@list{\NC@do *}\tabu@textbar \tabu@lines + \tabu@savedecl + \tabu@privatecolumns + \NC@list\expandafter{\the\expandafter\NC@list \tabu@NC@list}% + \let\tabu@savels \relax + \NC@find +}% \tabu@rewritemulticolumn +\def\tabu@endrewritemulticolumn{\gdef\tabu@mkpreambuffer{}\endgroup} +\def\tabu@multicolumn{\tabu@ifenvir \tabu@multic@lumn \tabu@multicolumnORI} +\long\def\tabu@multic@lumn #1#2#3{\multispan{#1}\begingroup + \tabu@everyrowtrue + \NC@list{\NC@do \tabu@rewritemulticolumn}% + \expandafter\@gobbletwo % gobbles \multispan{#1} + \tabu@multicolumnORI{#1}{\tabu@rewritemulticolumn #2}% + {\iftabuscantokens \tabu@rescan \else \expandafter\@firstofone \fi + {#3}}% +}% \tabu@multic@lumn +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Rewriting \env{tabu X} columns} +% \label{tabu X column definition} +%¤<package>%% The X column(s): rewriting process ----------------------------- +% +% \begin{macro}{X (private column type)} +% +% This is the rewrite macro for \textt{tabu X} columns. +% Such a column has an optional argument: the width coefficient for the \textt{tabu X} column +% whose default value is 1, and may be some alignments parameters. +% The coefficient is used in the expression: \texttbf p\M*{\cs\dimexpr\meta{coef}\cs\tabucolX} +% +% \begin{macrocode} +\tabu@privatecolumntype X[1][]{\begingroup \tabu@siunitx{\endgroup \tabu@rewriteX {#1}}} +\def\tabu@nosiunitx #1{#1{}{}\expandafter \NC@find \tabu@rewritten } +\def\tabu@siunitx #1{\@ifnextchar \bgroup + {\tabu@rewriteX@Ss{#1}} + {\tabu@nosiunitx{#1}}} +\def\tabu@rewriteX@Ss #1#2{\@temptokena{}% + \@defaultunits \let\tabu@temp =#2\relax\@nnil + \ifodd 1\ifx S\tabu@temp \else \ifx s\tabu@temp \else 0 \fi\fi + \def\NC@find{\def\NC@find >####1####2<####3\relax{#1 {####1}{####3}% + }\expandafter\NC@find \the\@temptokena \relax + }\expandafter\NC@rewrite@S \@gobble #2\relax + \else \tabu@siunitxerror + \fi + \expandafter \NC@find \tabu@rewritten +}% \tabu@rewriteX@Ss +\def\tabu@siunitxerror {\PackageError{tabu}{Not a S nor s column ! + \MessageBreak X column can only embed siunitx S or s columns}\@ehd +}% \tabu@siunitxerror +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@rewriteX} +% +% This macro is expanded by during the rewriting process in case a \textt X column is found. +% +% \cs\tabu@Xsum (a dimen) stores the sum of the (absolute) width coefficients. +% +% For the first \textt{X column} found in the preamble, a special setup occurs: +% \begin{itemize}[itemsep=0pt,topsep=0pt,leftmargin=*] +% \item if the default target is used (no target specified or \env{tabu spread} with \textt X columns), +% the target: \cs\tabu@target is set to the default, with a message in the \xext{log} file. +% \item \cs\@halignto is \cs\let to \cs\relax to avoid its expansion in \cs\xdef\cs\@preamble just after \cs\@mkpream. +% Indeed as long as we have to measure the natural width of the tabular, \cs\@halign must be empty for trial steps. +% \item The rest of the setup is made \cs\aftergroup (\ie after \cs\xdef\cs\@preamble which occurs inside a group) by \cs\tabu@prep@TRIAL. +% \end{itemize} +% +% \begin{macrocode} +\def\tabu@rewriteX #1#2#3{\tabu@Xarg {#1}{#2}{#3}% + \iftabu@measuring + \else \tabu@measuringtrue % first X column found in the preamble + \let\@halignto \relax \let\tabu@halignto \relax + \iftabu@spread \tabu@spreadtarget \tabu@target \tabu@target \z@ + \else \tabu@spreadtarget \z@ \fi + \ifdim \tabu@target=\z@ + \setlength\tabu@target \tabu@thetarget + \tabu@message{\tabu@message@defaulttarget}% + \else \tabu@message{\tabu@message@target}\fi + \fi +}% \tabu@rewriteX +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@rewriteXrestore} +% +% This macro replaces \cs\tabu@rewriteX in the case of \cs\usetabu. +% +% \begin{macrocode} +\def\tabu@rewriteXrestore #1#2#3{\let\@halignto \relax + \def\tabu@rewritten{l}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@Xarg} +% \begin{macro}{\tabu@Xparse} +% +% A tedious (and fastidious) macro to parse the optional argument of \textt X columns. The aim is to built +% \cs\tabu@rewritten which expands to the column specification: +% +% {\centering \textt{>\M*{alignment} p \emph{or} m \emph{or} b \M*{\cs\dimexpr coef \cs\tabucolX\cs\relax}}\par} +% +% After that \xfile{array.sty} make it easy:\, \cs\expandafter\cs\NC@find\cs\tabu@rewritten +% +% \begin{macrocode} +\def\tabu@Xarg #1#2#3{% + \advance\tabu@Xcol \@ne \let\tabu@Xlcr \@empty + \let\tabu@Xdisp \@empty \let\tabu@Xmath \@empty + \ifx\\#1\\% <shortcut when no option> + \def\tabu@rewritten{p}\tabucolX \p@ % <default coef = 1> + \else + \let\tabu@rewritten \@empty \let\tabu@temp \@empty \tabucolX \z@ + \tabu@Xparse {}#1\relax + \fi + \tabu@Xrewritten{#2}{#3}% +}% \tabu@Xarg +\def\tabu@Xparse #1{\futurelet\@let@token \tabu@Xtest} +\expandafter\def\expandafter\tabu@Xparsespace\space{\tabu@Xparse{}} +\def\tabu@Xtest{% + \ifcase \ifx \relax\@let@token \z@ \else + \if ,\@let@token \m@ne\else + \if p\@let@token 1\else + \if m\@let@token 2\else + \if b\@let@token 3\else + \if l\@let@token 4\else + \if c\@let@token 5\else + \if r\@let@token 6\else + \if j\@let@token 7\else + \if L\@let@token 8\else + \if C\@let@token 9\else + \if R\@let@token 10\else + \if J\@let@token 11\else + \ifx \@sptoken\@let@token 12\else + \if .\@let@token 13\else + \if -\@let@token 13\else + \ifcat $\@let@token 14\else + 15\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\relax + \or \tabu@Xtype {p}% + \or \tabu@Xtype {m}% + \or \tabu@Xtype {b}% + \or \tabu@Xalign \raggedright\relax + \or \tabu@Xalign \centering\relax + \or \tabu@Xalign \raggedleft\relax + \or \tabu@Xalign \tabu@justify\relax + \or \tabu@Xalign \RaggedRight\raggedright + \or \tabu@Xalign \Centering\centering + \or \tabu@Xalign \RaggedLeft\raggedleft + \or \tabu@Xalign \justifying\tabu@justify + \or \expandafter \tabu@Xparsespace + \or \expandafter \tabu@Xcoef + \or \expandafter \tabu@Xm@th + \or \tabu@Xcoef{}% + \else\expandafter \tabu@Xparse + \fi +}% \tabu@Xtest +\def\tabu@Xalign #1#2{% + \ifx \tabu@Xlcr\@empty \else \PackageWarning{tabu} + {Duplicate horizontal alignment specification}\fi + \ifdefined#1\def\tabu@Xlcr{#1}\let#1\relax + \else \def\tabu@Xlcr{#2}\let#2\relax\fi + \expandafter\tabu@Xparse +}% \tabu@Xalign +\def\tabu@Xtype #1{% + \ifx \tabu@rewritten\@empty \else \PackageWarning{tabu} + {Duplicate vertical alignment specification}\fi + \def\tabu@rewritten{#1}\expandafter\tabu@Xparse +}% \tabu@Xtype +\def\tabu@Xcoef#1{\edef\tabu@temp{\tabu@temp#1}% + \afterassignment\tabu@Xc@ef \tabu@cnt\number\if-#10\fi +}% \tabu@Xcoef +\def\tabu@Xc@ef{\advance\tabucolX \tabu@temp\the\tabu@cnt\p@ + \tabu@Xparse{}% +}% \tabu@Xc@ef +\def\tabu@Xm@th #1{\futurelet \@let@token \tabu@Xd@sp} +\def\tabu@Xd@sp{\let\tabu@Xmath=$% + \ifx $\@let@token \def\tabu@Xdisp{\displaystyle}% + \expandafter\tabu@Xparse + \else \expandafter\tabu@Xparse\expandafter{\expandafter}% + \fi +}% \tabu@Xd@sp +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@Xrewritten} +% +% Final step: the whole optional argument has been read, then builds +% the rewritten column specification. +% +% \begin{macrocode} +\def\tabu@Xrewritten {% + \ifx \tabu@rewritten\@empty \def\tabu@rewritten{p}\fi + \ifdim \tabucolX<\z@ \tabu@negcoeftrue + \else\ifdim \tabucolX=\z@ \tabucolX \p@ + \fi\fi + \edef\tabu@temp{{\the\tabu@Xcol}{\tabu@strippt\tabucolX}}% + \edef\tabu@Xcoefs{\tabu@Xcoefs \tabu@ \tabu@temp}% + \edef\tabu@rewritten ##1##2{\def\noexpand\tabu@rewritten{% + >{\tabu@Xlcr \ifx$\tabu@Xmath$\tabu@Xdisp\fi ##1}% + \tabu@rewritten {\tabu@hsize \tabu@temp}% + <{##2\ifx$\tabu@Xmath$\fi}}% + }\tabu@rewritten +}% \tabu@Xrewritten +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@hsize} +% +% \cs\tabu@hsize\M*{\textt X column number}\M*{\textt X column width coefficient} +% +% Depending on the sign of the coefficient, and of the stored value for the natural width +% of the column the \textt X cell belongs to, \cs\tabu@hsize returns the wanted width for +% the \emph{par-box} that contains the cell content. +% +% \begin{macrocode} +\def\tabu@hsize #1#2{% + \ifdim #2\p@<\z@ + \ifdim \tabucolX=\maxdimen \tabu@wd{#1}\else + \ifdim \tabu@wd{#1}<-#2\tabucolX \tabu@wd{#1}\else -#2\tabucolX\fi + \fi + \else #2\tabucolX + \fi +}% \tabu@hsize +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Rewritting \cs{usetabu} and \cs{preamble}} +%¤<package>%% \usetabu and \preamble: rewritting process --------------------- +% +% The rewritting process is very simple, when all the job has been done +% cleverly at the time of \cs\savetabu !! +% +% The \cs\savetabu macro is a bit more complex... +% +% \begin{macro}{\usetabu (private column type)} +% +% \cs\usetabu is defined as a \env{tabu} new column type: loaded only inside the \cs\@mkpream +% group inside the \env*{tabu}. +% +% \begin{macrocode} +\tabu@privatecolumntype \usetabu [1]{% + \ifx\\#1\\\tabu@saveerr{}\else + \@ifundefined{tabu@saved@\string#1} + {\tabu@saveerr{#1}} + {\let\tabu@rewriteX \tabu@rewriteXrestore + \csname tabu@saved@\string#1\expandafter\endcsname\expandafter\@ne}% + \fi +}% \NC@rewrite@\usetabu +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\preamble (private column type)} +% +% \cs\preamble is defined as a \textt{tabu} new column type: loaded only inside the \cs\@mkpream +% group inside the \textt{tabu} environment. +% +% \begin{macrocode} +\tabu@privatecolumntype \preamble [1]{% + \ifx\\#1\\\tabu@saveerr{}\else + \@ifundefined{tabu@saved@\string#1} + {\tabu@saveerr{#1}} + {\csname tabu@saved@\string#1\expandafter\endcsname\expandafter\z@}% + \fi +}% \NC@rewrite@\preamble +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Controlling the rewritting process} +% +%¤<package>%% Controlling the rewritting process ------------------------------- +% +% \begin{macro}{\tabu@rewritefirst} +% +% This new column type is not really a column type! It is always added to a \env{tabu} preamble +% in order to do some setup before any other column is rewritten by \cs\@mkpream. +% +% Thus, \cs\NC@list is simply set to \M*{\cs{NC@do} \cs{tabu@rewritefirst}}. The rewritting of +% \cs\tabu@rewritefirst will restore the original list \cs\NC@list. +% +% This ``column type'' sets: +% \begin{itemize} +% \item \cs\tabu@select to be expanded \cs\aftergroup (after the closing of the \cs\@mkpream group. +% All the thick is there: all information collected during the rewritting of \textt X columns +% (and vertical lines or leaders) can be \emph{reinjected} into the group below the \cs\@mkpream +% group, by the mean of the \cs\tabu@mkpreambuffer (globally defined). +% \item The private columns types are loaded by \cs\tabu@rewritefirst: they will be rewritten afterwards, +% during the rewritting loop. This way, \textt X column definition for \env{tabu} are only available +% during the rewritting process of the \env{tabu} preamble, making it possible (and easy) to +% embed a \env{tabularx} inside a cell of a \env{tabu}. +% \item \cs\save@decl is modified inside the \cs\@mkpream group, if \env{tabu} is in text mode. +% \end{itemize} +% +% \begin{macrocode} +\tabu@newcolumntype \tabu@rewritefirst{% + \iftabu@long \aftergroup \tabu@longpream % <the whole implementation is here !> + \else \aftergroup \tabu@pream + \fi + \let\tabu@ \relax \let\tabu@hsize \relax + \let\tabu@Xcoefs \@empty \let\tabu@savels \relax + \tabu@Xcol \z@ \tabu@cnt \tw@ + \gdef\tabu@mkpreambuffer{\tabu@{}}\tabu@measuringfalse + \global\setbox\@arstrutbox \box\@arstrutbox + \NC@list{\NC@do *}\tabu@textbar \tabu@lines + \NC@list\expandafter{\the\NC@list \NC@do X}% + \iftabu@siunitx % <siunitx S and s columns> + \NC@list\expandafter{\the\NC@list \NC@do S\NC@do s}\fi + \NC@list\expandafter{\the\expandafter\NC@list \tabu@highprioritycolumns}% + \expandafter\def\expandafter\tabu@NC@list\expandafter{% + \the\expandafter\NC@list \tabu@NC@list}% % * | X S <original> + \NC@list\expandafter{\expandafter \NC@do \expandafter\usetabu + \expandafter \NC@do \expandafter\preamble + \the\NC@list \NC@do \tabu@rewritemiddle + \NC@do \tabu@rewritelast}% + \tabu@savedecl + \tabu@privatecolumns + \edef\tabu@prev{\the\@temptokena}\NC@find \tabu@rewritemiddle +}% NC@rewrite@\tabu@rewritefirst +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@rewritemiddle} +% \begin{macro}{\tabu@rewritelast} +% +% This new column type is rewritten after \textt X columns, because it is declared by +% when the column \cs\tabu@rewritefirst is actually rewritten. In the case where \cs\tabu@target +% is $>0$ (either because of ``\textt{tabu to}'' or ``\textt{tabu spread}'' has been called) +% and if there is no \textt X column, then \textt{@\M*{\cs\extracolsep\cs{@flushglue}}} is added +% at the beginning of the preamble. +% +% To avoid duplicate margin in the \textt{tabu} we have to test the next token in the preamble. +% If the next token is \textt\textbar\ or \textt !\ then no margin must be added and +% \texttbf @\M*{\cs\extracolsep\cs{@flushglue}} can be inserted at the beginning of the preamble. +% +% Otherwise, we must insert \texttbf !\M*{\cs\extracolsep\cs{@flushglue}} in order to keep the margin. +% +% \cs\tabu@rewritelast column type is loaded by \cs\tabu@rewritefirst column type, only inside the \cs\@mkpream +% group inside the \env*{tabu}. +% +% \begin{macrocode} +\tabu@newcolumntype \tabu@rewritemiddle{% + \edef\tabu@temp{\the\@temptokena}\NC@find \tabu@rewritelast +}% \NC@rewrite@\tabu@rewritemiddle +\tabu@newcolumntype \tabu@rewritelast{% + \ifx \tabu@temp\tabu@prev \advance\tabu@cnt \m@ne + \NC@list\expandafter{\tabu@NC@list \NC@do \tabu@rewritemiddle + \NC@do \tabu@rewritelast}% + \else \let\tabu@prev\tabu@temp + \fi + \ifcase \tabu@cnt \expandafter\tabu@endrewrite + \else \expandafter\NC@find \expandafter\tabu@rewritemiddle + \fi +}% \NC@rewrite@\tabu@rewritelast +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{The end of the rewritting process: determining the \env{tabu} strategy} +%¤<package>%% Choosing the strategy -------------------------------------------- +% +% \begin{macro}{\tabu@endrewrite} +% +% Determines the strategy to be executed \cs\aftergroup (at the closing of the \cs\@mkpream group): +% \begin{enumerate}[label=\arabic*),first=0] +% \item There is no real strategy: \env{tabu} behaves like \env{tabular}, there no \textt 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 \env{tabu}, it behaves like \env{tabular*} and a infinite stretchability +% is given to the column inter-space. This is done (if required) by \cs\tabu@extracolsep. +% \item Measuring natural width of some (or all) columns is compulsory for \env{tabu spread} of \textt X columns +% with negativ coefficients. Thereafter, the strategy nr 2 will bring into play. +% \item Measuring the natural width is not necessary, or has been done before. But \env{tabu} contains \textt X columns +% and trials have to be performed to reach the desired target, adjusting the \cs\tabucolX dimension accordingly. +% Then, the strategy nr 3 may bring into play, if vertical measure is required. +% \item 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. +% \item [$>3$] The \env{tabu} is finished and ready to be printed !! +% \end{enumerate} +% +% \begin{macrocode} +\def\tabu@endrewrite {% + \let\tabu@temp \NC@find + \ifx \@arrayright\relax \let\@arrayright \@empty \fi + \count@=% + \ifx \@finalstrut\tabu@finalstrut \z@ % outer in mode 0 print + \iftabu@measuring + \xdef\tabu@mkpreambuffer{\tabu@mkpreambuffer + \tabu@target \csname tabu@\the\tabu@nested.T\endcsname + \tabucolX \csname tabu@\the\tabu@nested.X\endcsname + \edef\@halignto {\ifx\@arrayright\@empty to\tabu@target\fi}}% + \fi + \else\iftabu@measuring 4 % X columns + \xdef\tabu@mkpreambuffer{\tabu@{\tabu@mkpreambuffer + \tabu@target \the\tabu@target + \tabu@spreadtarget \the\tabu@spreadtarget}% + \def\noexpand\tabu@Xcoefs{\tabu@Xcoefs}% + \edef\tabu@halignto{\ifx \@arrayright\@empty to\tabu@target\fi}}% + \let\tabu@Xcoefs \relax + \else\ifcase\tabu@nested \thr@@ % outer, no X + \global\let\tabu@afterendpar \relax + \else \@ne % inner, no X, outer in mode 1 or 2 + \fi + \ifdefined\tabu@usetabu + \else \ifdim\tabu@target=\z@ + \else \let\tabu@temp \tabu@extracolsep + \fi\fi + \fi + \fi + \xdef\tabu@mkpreambuffer{\count@ \the\count@ \tabu@mkpreambuffer}% + \tabu@temp +}% \tabu@endrewrite +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@extracolsep} +% +% Inserts \cs\extracolsep\cs\@flushglue in front of the preamble, unless another value for +% \cs\extracolsep has been specified. +% +% \cs\@flushglue is \textt{0pt plus 1fil}. +% +% \begin{macrocode} +\def\tabu@extracolsep{\@defaultunits \expandafter\let + \expandafter\tabu@temp \expandafter=\the\@temptokena \relax\@nnil + \ifx \tabu@temp\@sptoken + \expandafter\tabu@gobblespace \expandafter\tabu@extracolsep + \else + \edef\tabu@temp{\noexpand\NC@find + \if |\noexpand\tabu@temp @% + \else\if !\noexpand\tabu@temp @% + \else !% + \fi\fi + {\noexpand\extracolsep\noexpand\@flushglue}}% + \fi + \tabu@temp +}% \tabu@extrac@lsep +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Implementing the strategy at the exit of the \cs{@mkpream} group} +% \label{implement the strategy} +%¤<package>%% Implementing the strategy ---------------------------------------- +% +% \subsubsection{\cs{tabu@select}} +% +% \begin{macro}{\tabu@pream} +% +% Triggered \cs\aftergroup by the rewritting of \cs\tabu@rewritefirst. +% +% The \cs\tabu@mkpreambuffer macro is expanded twice: first it injects \cs\count@ (the strategy number) +% and \cs\tabu@nbcols, and redefines itself. +% +% Second -- and only if measurements are necessary -- it expands into the \emph{trials group} +% to inject \cs\tabu@Xcoefs (the coefficients of \textt X columns), \cs\tabu@Xsum +% (the sum of the absolute coefficients), \cs\tabu@target, \cs\tabu@spreadtarget, and +% \cs\tabu@vertical, which is the number by which one have to increment the strategy number after +% step $2$ (either $1$: then a last measure is done for the vertical dimensions, or $255$ then +% the strategy number is $>3$ and \cs\tabu@strategy orders to finish.) +% +% \begin{macro}{\tabu@longpream} +% +% This is the \textt{long} version for \env{longtabu}: the material to collect +% until \cs\@preamble is different ! +% +% \begin{macrocode} +\long\def\tabu@pream #1\@preamble {% + \let\tabu@ \tabu@@ \tabu@mkpreambuffer \tabu@aftergroupcleanup + \NC@list\expandafter {\tabu@NC@list}% in case of nesting... + \ifdefined\tabu@usetabu \tabu@usetabu \tabu@target \z@ \fi + \let\tabu@savedpreamble \@preamble + \global\let\tabu@elapsedtime \relax + \tabu@thebody ={#1\tabu@aftergroupcleanup}% + \tabu@thebody =\expandafter{\the\expandafter\tabu@thebody + \@preamble}% + \edef\tabuthepreamble {\the\tabu@thebody}% ( no @ allowed for \scantokens ) + \tabu@select +}% \tabu@pream +\long\def\tabu@longpream #1\LT@bchunk #2\LT@bchunk{% + \let\tabu@ \tabu@@ \tabu@mkpreambuffer \tabu@aftergroupcleanup + \NC@list\expandafter {\tabu@NC@list}% in case of nesting... + \let\tabu@savedpreamble \@preamble + \global\let\tabu@elapsedtime \relax + \tabu@thebody ={#1\LT@bchunk #2\tabu@aftergroupcleanup \LT@bchunk}% + \edef\tabuthepreamble {\the\tabu@thebody}% ( no @ allowed for \scantokens ) + \tabu@select +}% \tabu@longpream +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@select} +% +% Here we check if trials are required or not: depending on the value of \cs\count@ (set at \cs\tabu@endrewrite, and +% \emph{injected} here by \cs\tabu@mkpreambuffer), on \cs\iftabu@measuring (nested trials). +% +% When trials are required, \cs\tabu@select give control to \cs\tabu@setstrategy (to prepare the neutralisation of commands, save counters etc). +% +% When trials are not required, we just have to expand \cs\tabuthepreamble, after having set up the \cs\everyrow stuff properly +% (for vertical adjustment or vertical measure, if needed). +% +% \begin{macrocode} +\def\tabu@select {% + \ifnum\tabu@nested>\z@ \tabuscantokensfalse \fi + \ifnum \count@=\@ne \iftabu@measuring \count@=\tw@ \fi\fi + \ifcase \count@ + \global\let\tabu@elapsedtime \relax + \tabu@seteverycr + \expandafter \tabuthepreamble % vertical adjustment (inheritated from outer) + \or % exit in vertical measure + struts per cell because no X and outer in mode 3 + \tabu@evr{\tabu@verticalinit}\tabu@celllalign@def{\tabu@verticalmeasure}% + \def\tabu@cellralign{\tabu@verticalspacing}% + \tabu@seteverycr + \expandafter \tabuthepreamble + \or % exit without measure because no X and outer in mode 4 + \tabu@evr{}\tabu@celllalign@def{}\let\tabu@cellralign \@empty + \tabu@seteverycr + \expandafter \tabuthepreamble + \else % needs trials + \tabu@evr{}\tabu@celllalign@def{}\let\tabu@cellralign \@empty + \tabu@savecounters + \expandafter \tabu@setstrategy + \fi +}% \tabu@select +\def\tabu@@ {\gdef\tabu@mkpreambuffer} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{General setup for trials: neutralisation of \cs{write} etc.}% +%¤<package>%% Protections to set up before trials ------------------------------ +% +% \begin{macro}{\tabu@setstrategy} +% +% This is the general setup for trials: the \env{tabu} will be expanded more than once, +% thus some protections are set: the value of global counters are saved, footnotes +% have a special setup, \cs\hbadness and \cs\hfuzz are neutralised etc. +% +% The initial value for \cs\tabucolX is computed with the coefficients stored +% into \cs\tabu@Wvoefs: +% \centerline{\cs{tabu@}\M*{coef1} \cs{tabu@}\M*{coef2} \cs{tabu@}\M*{coef3} etc.} +% +% is very suitable for loops on the column width coefficients (without the need of \cs\@for or whatsoever). +% +% \begin{macrocode} +\def\tabu@setstrategy {\begingroup % <trials group> + \tabu@trialh@@k \tabu@cnt \z@ % number of trials + \hbadness \@M \let\hbadness \@tempcnta + \hfuzz \maxdimen \let\hfuzz \@tempdima + \let\write \tabu@nowrite\let\GenericError \tabu@GenericError + \let\savetabu \@gobble \let\tabudefaulttarget \linewidth + \let\@footnotetext \@gobble \let\@xfootnote \tabu@xfootnote + \let\color \tabu@nocolor\let\rowcolor \tabu@norowcolor + \let\tabu@aftergroupcleanup \relax % only after the last trial + \tabu@mkpreambuffer + \ifnum \count@>\thr@@ \let\@halignto \@empty \tabucolX@init + \def\tabu@lasttry{\m@ne\p@}\fi + \begingroup \iffalse{\fi \ifnum0=`}\fi + \toks@{}\def\tabu@stack{b}\iftabuscantokens \endlinechar=10 \obeyspaces \fi % + \tabu@collectbody \tabu@strategy % +}% \tabu@setstrategy +\def\tabu@savecounters{% + \def\@elt ##1{\csname c@##1\endcsname\the\csname c@##1\endcsname}% + \edef\tabu@clckpt {\begingroup \globaldefs=\@ne \cl@@ckpt \endgroup}\let\@elt \relax +}% \tabu@savecounters +\def\tabucolX@init {% \tabucolX <= \tabu@target / (sum coefs > 0) + \dimen@ \z@ \tabu@Xsum \z@ \tabucolX \z@ \let\tabu@ \tabu@Xinit \tabu@Xcoefs + \ifdim \dimen@>\z@ + \@tempdima \dimexpr \tabu@target *\p@/\dimen@ + \tabu@hfuzz\relax + \ifdim \tabucolX<\@tempdima \tabucolX \@tempdima \fi + \fi +}% \tabucolX@init +\def\tabu@Xinit #1#2{\tabu@Xcol #1 \advance \tabu@Xsum + \ifdim #2\p@>\z@ #2\p@ \advance\dimen@ #2\p@ + \else -#2\p@ \tabu@negcoeftrue + \@tempdima \dimexpr \tabu@target*\p@/\dimexpr-#2\p@\relax \relax + \ifdim \tabucolX<\@tempdima \tabucolX \@tempdima \fi + \tabu@wddef{#1}{0pt}% + \fi +}% \tabu@Xinit +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Collecting the \env{tabu} body} +%¤<package>%% Collecting the environment body ---------------------------------- +% +% The macro collect the stuff inside \cs\@array: depending on the global vertical alignment +% parameter for the whole tabular, the tabular is built inside a \cs\vbox, \cs\vtop or \cs\vcenter +% (the default -- unless \env{tabu} is nested). +% +% At this time, we define \cs\tabu@trial (which inherits from the \cs\vbox, \cs\vtop or \cs\vcenter) +% and \cs\tabu@Xfinish as well. +% +% \begin{macro}{\tabu@collectbody} +% \begin{macro}{\tabu@endofcollect} +% +% The mechanism is the same as \hologo{AmS}-\cs\collect@body (also defined in \xfile{environ.sty}). +% The content of the tabular is captured inside \cs\toks@, expanded by \cs\tabu@trial. +% +% \begin{macrocode} +\long\def\tabu@collectbody #1#2\end #3{% + \edef\tabu@stack{\tabu@pushbegins #2\begin\end\expandafter\@gobble\tabu@stack}% + \ifx \tabu@stack\@empty + \toks@\expandafter{\expandafter\tabu@thebody\expandafter{\the\toks@ #2}% + \def\tabu@end@envir{\end{#3}}% + \iftabuscantokens + \iftabu@long \def\tabu@endenvir {\end{#3}\tabu@gobbleX}% + \else \def\tabu@endenvir {\let\endarray \@empty + \end{#3}\tabu@gobbleX}% + \fi + \else \def\tabu@endenvir {\end{#3}}\fi}% + \let\tabu@collectbody \tabu@endofcollect + \else\def\tabu@temp{#3}% + \ifx \tabu@temp\@empty \toks@\expandafter{\the\toks@ #2\end }% + \else \ifx\tabu@temp\tabu@@spxiii \toks@\expandafter{\the\toks@ #2\end #3}% + \else \ifx\tabu@temp\tabu@X \toks@\expandafter{\the\toks@ #2\end #3}% + \else \toks@\expandafter{\the\toks@ #2\end{#3}}% + \fi\fi\fi + \fi + \tabu@collectbody{#1}% +}% \tabu@collectbody +\long\def\tabu@pushbegins#1\begin#2{\ifx\end#2\else b\expandafter\tabu@pushbegins\fi}% +\def\tabu@endofcollect #1{\ifnum0=`{}\fi + \expandafter\endgroup \the\toks@ #1% +}% \tabu@endofcollect +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{One trial after the other (\cs{tabu@strategy})} +% \label{One trial after the other} +%¤<package>%% The trials: switching between strategies ------------------------- +% +% \subsubsection{Switching between the strategies} +% +% \begin{macro}{\tabu@strategy} +% +% This macro does some specific setup depending on the strategy ($1$, $2$ or $3$), +% and orders to finish when all measurements are done. +% +% This consists in a switch (\cs\ifcase) which is done before the trials by \cs\tabu@strategy, +% and after the trials by \cs\tabu@endtrial. +% +% \begin{macrocode} +\def\tabu@strategy {\relax % stops \count@ assignment ! + \ifcase\count@ % case 0 = print with vertical adjustment (outer is finished) + \expandafter \tabu@endoftrials + \or % case 1 = exit in vertical measure (outer in mode 3) + \expandafter\xdef\csname tabu@\the\tabu@nested.T\endcsname{\the\tabu@target}% + \expandafter\xdef\csname tabu@\the\tabu@nested.X\endcsname{\the\tabucolX}% + \expandafter \tabu@endoftrials + \or % case 2 = exit with a rule replacing the table (outer in mode 4) + \expandafter \tabu@quickend + \or % case 3 = outer is in mode 3 because of no X + \begingroup + \tabu@evr{\tabu@verticalinit}\tabu@celllalign@def{\tabu@verticalmeasure}% + \def\tabu@cellralign{\tabu@verticalspacing}% + \expandafter \tabu@measuring + \else % case 4 = horizontal measure + \begingroup + \global\let\tabu@elapsedtime \tabu@message@etime + \long\def\multicolumn##1##2##3{\multispan{##1}}% + \let\tabu@startpboxORI \@startpbox + \iftabu@spread + \def\tabu@naturalXmax {\z@}% + \let\tabu@naturalXmin \tabu@naturalXmax + \tabu@evr{\global\tabu@naturalX \z@}% + \let\@startpbox \tabu@startpboxmeasure + \else\iftabu@negcoef + \let\@startpbox \tabu@startpboxmeasure + \else \let\@startpbox \tabu@startpboxquick + \fi\fi + \expandafter \tabu@measuring + \fi +}% \tabu@strategy +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@measuring} +% +% Expands \cs\tabu@trial with the whole content of the environment stored in \cs\toks@ by \cs\tabu@collectbody. +% +% At the end of the trial, \cs\count@ will be reassigned to the value it had before the trial. +% Then \cs\tabu@endtrial will choose the algorithm depending on the strategy number, and +% set the new strategy number (into \cs\count@ again) for the next step. +% +% \begin{macro}{\tabu@trial} +% +% This is the starting point of trials: \cs\halign is expanded here. +% +% \begin{macro}{\tabu@longtrial} +% +% This is the long version of \cs\tabu@trial for \env{longtabu}. Almost the same apart for the +% math group and the end (a \env{longtable} environment does not finish with \cs\endarray). +% +% \begin{macrocode} +\def\tabu@measuring{\expandafter \tabu@trial \expandafter + \count@ \the\count@ \tabu@endtrial +}% \tabu@measuring +\def\tabu@trial{\iftabu@long \tabu@longtrial \else \tabu@shorttrial \fi} +\def\tabu@shorttrial {\setbox\tabu@box \hbox\bgroup \tabu@seteverycr + \ifx \tabu@savecounters\relax \else + \let\tabu@savecounters \relax \tabu@clckpt \fi + $\iftabuscantokens \tabu@rescan \else \expandafter\@secondoftwo \fi + \expandafter{\expandafter \tabuthepreamble + \the\tabu@thebody + \csname tabu@adl@endtrial\endcsname + \endarray}$\egroup % got \tabu@box +}% \tabu@shorttrial +\def\tabu@longtrial {\setbox\tabu@box \hbox\bgroup \tabu@seteverycr + \ifx \tabu@savecounters\relax \else + \let\tabu@savecounters \relax \tabu@clckpt \fi + \iftabuscantokens \tabu@rescan \else \expandafter\@secondoftwo \fi + \expandafter{\expandafter \tabuthepreamble + \the\tabu@thebody + \tabuendlongtrial}\egroup % got \tabu@box +}% \tabu@longtrial +\def\tabuendlongtrial{% no @ allowed for \scantokens + \LT@echunk \global\setbox\@ne \hbox{\unhbox\@ne}\kern\wd\@ne + \LT@get@widths +}% \tabuendlongtrial +\def\tabu@adl@endtrial{% <arydshln in nested trials - problem for global column counters!> + \crcr \noalign{\global\adl@ncol \tabu@nbcols}}% anything global is crap, junky and fails ! +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@seteverycr} +% +% \cs\ialign resets \cs\everycr to an empty token. This macro sets \cs\everycr for the +% \env*{tabu} : a \emph{bridge} around \cs\ialign is built: \cs\everycr redefines itself +% \cs\afterassignment ! +% +% \begin{macrocode} +\def\tabu@seteverycr {\tabu@reset + \everycr \expandafter{\the\everycr \tabu@everycr}% + \let\everycr \tabu@noeverycr % <for ialign> +}% \tabu@seteverycr +\def\tabu@noeverycr{{\aftergroup\tabu@restoreeverycr \afterassignment}\toks@} +\def\tabu@restoreeverycr {\let\everycr \tabu@@everycr} +\def\tabu@everycr {\iftabu@everyrow \noalign{\tabu@everyrow}\fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@endoftrials} +% +% When the algorithm said the tabular was ready to be printed, \cs\tabu@endoftrials +% closes the trials group and prints the tabular... +% +% The required values (column widths, struts etc.) are \emph{injected} into the group +% by the mean of the buffer \cs\tabu@bufferX (locally defined). +% +% \begin{macro}{\tabu@closetrialsgroup} +% +% This closes the group in which all the trials are done. +% +% \begin{macrocode} +\def\tabu@endoftrials {% + \iftabuscantokens \expandafter\@firstoftwo + \else \expandafter\@secondoftwo + \fi + {\expandafter \tabu@closetrialsgroup \expandafter + \tabu@rescan \expandafter{% + \expandafter\tabuthepreamble + \the\expandafter\tabu@thebody + \iftabu@long \else \endarray \fi}} + {\expandafter\tabu@closetrialsgroup \expandafter + \tabuthepreamble + \the\tabu@thebody}% + \tabu@endenvir % Finish ! +}% \tabu@endoftrials +\def\tabu@closetrialsgroup {% + \toks@\expandafter{\tabu@endenvir}% + \edef\tabu@bufferX{\endgroup + \tabucolX \the\tabucolX + \tabu@target \the\tabu@target + \tabu@cnt \the\tabu@cnt + \def\noexpand\tabu@endenvir{\the\toks@}% + %Quid de \@halignto = \tabu@halignto ?? + }% \tabu@bufferX + \tabu@bufferX + \ifcase\tabu@nested % print out (outer in mode 0) + \global\tabu@cnt \tabu@cnt + \tabu@evr{\tabu@verticaldynamicadjustment}% + \tabu@celllalign@def{\everypar{}}\let\tabu@cellralign \@empty + \let\@finalstrut \tabu@finalstrut + \else % vertical measure of nested tabu + \tabu@evr{\tabu@verticalinit}% + \tabu@celllalign@def{\tabu@verticalmeasure}% + \def\tabu@cellralign{\tabu@verticalspacing}% + \fi + \tabu@clckpt \let\@halignto \tabu@halignto + \let\@halignto \@empty + \tabu@seteverycr + \ifdim \tabustrutrule>\z@ \ifnum\tabu@nested=\z@ + \setbox\@arstrutbox \box\voidb@x % force \@arstrutbox to be rebuilt (visible struts) + \fi\fi +}% \tabu@closetrialsgroup +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@quickend} +% +% Quick exit after having measuring the natural width of a nested \env{tabu}. +% +% \begin{macrocode} +\def\tabu@quickend {\expandafter \endgroup \expandafter + \tabu@target \the\tabu@target \tabu@quickrule + \let\endarray \relax \tabu@endenvir +}% \tabu@quickend +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\tabu@endtrial} +% +% Depending on the strategy that was just applied, \cs\tabu@endtrial +% chooses the algorithm and determines the number of the strategy for the next step. +% +% \begin{macrocode} +\def\tabu@endtrial {\relax % stops \count@ assignment ! + \ifcase \count@ \tabu@err % case 0 = impossible here + \or \tabu@err % case 1 = impossible here + \or \tabu@err % case 2 = impossible here + \or % case 3 = outer goes into mode 0 + \def\tabu@bufferX{\endgroup}\count@ \z@ + \else % case 4 = outer goes into mode 3 + \iftabu@spread \tabu@spreadarith % inner into mode 1 (outer in mode 3) + \else \tabu@arith % or 2 (outer in mode 4) + \fi + \count@=% + \ifcase\tabu@nested \thr@@ % outer goes into mode 3 + \else\iftabu@measuring \tw@ % outer is in mode 4 + \else \@ne % outer is in mode 3 + \fi\fi + \edef\tabu@bufferX{\endgroup + \tabucolX \the\tabucolX + \tabu@target \the\tabu@target}% + \fi + \expandafter \tabu@bufferX \expandafter + \count@ \the\count@ \tabu@strategy +}% \tabu@endtrial +\def\tabu@err{\errmessage{(tabu) Internal impossible error! (\count@=\the\count@)}} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{The algorithms: Measuring the \env{tabu} box} +% \label{The algorithms: Measuring the tabubox} +%¤<package>%% The algorithms: compute the widths / stop or go on --------------- +% +% At the end of each trial, we call \cs\tabu@arith (or \cs\tabu@spreadarith) +% to computes the widths and update the values. +% +% At the exit, \cs\iftabu@measuring is set to \cs\iftrue: a further trial is necessary, +% or \cs\iffalse: the target width is reached. +% +% \subsubsection(Algorithm for tabu to){The arithmetic of \textt X columns: the \env{tabu to} case} +% +% \begin{macro}{\tabu@arithnegcoef} +% +% This is a loop against the width coefficients. There is no \cs\@for or \cs\@whiles because +% \cs\tabu@Xcoefs stores the series in the form: \cs\tabu@\M*{coef1} \cs\tabu@\M*{coef2} \cs\tabu@\M*{coef3}. +% +% Thus, just \cs\let\cs\tabu@ to be \cs\tabu@arith@negcoef and expand \cs\tabu@Xcoefs ! +% +% The aim of the game is to \emph{neutralize} some \textt X columns: when their natural width +% are less than $\text{coef}\times $\cs\tabucolX. +% +% \begin{macrocode} +\def\tabu@arithnegcoef {% + \@tempdima \z@ \dimen@ \z@ \let\tabu@ \tabu@arith@negcoef \tabu@Xcoefs +}% \tabu@arithnegcoef +\def\tabu@arith@negcoef #1#2{% + \ifdim #2\p@>\z@ \advance\dimen@ #2\p@ % saturated by definition + \advance\@tempdima #2\tabucolX + \else + \ifdim -#2\tabucolX <\tabu@wd{#1}% c_i X < natural width <= \tabu@target-> saturated + \advance\dimen@ -#2\p@ + \advance\@tempdima -#2\tabucolX + \else + \advance\@tempdima \tabu@wd{#1}% natural width <= c_i X => neutralised + \ifdim \tabu@wd{#1}<\tabu@target \else % neutralised + \advance\dimen@ -#2\p@ % saturated (natural width = tabu@target) + \fi + \fi + \fi +}% \tabu@arith@negcoef +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@arith} +% +% General algorithms for \env{tabu to} with \textt X columns. +% +% \begin{macrocode} +\def\tabu@givespace #1#2{% here \tabu@DELTA < \z@ + \ifdim \@tempdima=\z@ + \tabu@wddef{#1}{\the\dimexpr -\tabu@DELTA*\p@/\tabu@Xsum}% + \else + \tabu@wddef{#1}{\the\dimexpr \tabu@hsize{#1}{#2} + *(\p@ -\tabu@DELTA*\p@/\@tempdima)/\p@\relax}% + \fi +}% \tabu@givespace +\def\tabu@arith {\advance\tabu@cnt \@ne + \ifnum \tabu@cnt=\@ne \tabu@message{\tabu@titles}\fi + \tabu@arithnegcoef + \@tempdimb \dimexpr \wd\tabu@box -\@tempdima \relax % <incompressible material> + \tabu@DELTA = \dimexpr \wd\tabu@box - \tabu@target \relax + \tabu@message{\tabu@message@arith}% + \ifdim \tabu@DELTA <\tabu@hfuzz + \ifdim \tabu@DELTA<\z@ % wd (tabu)<\tabu@target ? + \let\tabu@ \tabu@givespace \tabu@Xcoefs + \advance\@tempdima \@tempdimb \advance\@tempdima -\tabu@DELTA % for message + \else % already converged: nothing to do but nearly impossible... + \fi + \tabucolX \maxdimen + \tabu@measuringfalse + \else % need for narrower X columns + \tabucolX =\dimexpr (\@tempdima -\tabu@DELTA) *\p@/\tabu@Xsum \relax + \tabu@measuringtrue + \@whilesw \iftabu@measuring\fi {% + \advance\tabu@cnt \@ne + \tabu@arithnegcoef + \tabu@DELTA =\dimexpr \@tempdima+\@tempdimb -\tabu@target \relax % always < 0 here + \tabu@message{\tabu@header + \tabu@msgalign \tabucolX { }{ }{ }{ }{ }\@@ + \tabu@msgalign \@tempdima+\@tempdimb { }{ }{ }{ }{ }\@@ + \tabu@msgalign \tabu@target { }{ }{ }{ }{ }\@@ + \tabu@msgalign@PT \dimen@ { }{}{}{}{}{}{}\@@ + \ifdim -\tabu@DELTA<\tabu@hfuzz \tabu@spaces target ok\else + \tabu@msgalign \dimexpr -\tabu@DELTA *\p@/\dimen@ {}{}{}{}{}\@@ + \fi}% + \ifdim -\tabu@DELTA<\tabu@hfuzz + \advance\@tempdima \@tempdimb % for message + \tabu@measuringfalse + \else + \advance\tabucolX \dimexpr -\tabu@DELTA *\p@/\dimen@ \relax + \fi + }% + \fi + \tabu@message{\tabu@message@reached}% + \edef\tabu@bufferX{\endgroup \tabu@cnt \the\tabu@cnt + \tabucolX \the\tabucolX + \tabu@target \the\tabu@target}% +}% \tabu@arith +% \end{macrocode} +% \end{macro} +% +% \subsubsection(Algorithm for tabu spread){The arithmetic of \textt X columns for \env{tabu spread}} +% +% \begin{macro}{\tabu@spreadarith} +% +% Algorithm for \env{tabu spread} with \textt X columns: the aim of the game is to compute the +% target (relative to the natural width of the tabular) and go to \cs\tabu@arith afterwards. +% +% \begin{macrocode} +\def\tabu@spreadarith {% + \dimen@ \z@ \@tempdima \tabu@naturalXmax \let\tabu@ \tabu@spread@arith \tabu@Xcoefs + \edef\tabu@naturalXmin {\the\dimexpr\tabu@naturalXmin*\dimen@/\p@}% + \@tempdimc =\dimexpr \wd\tabu@box -\tabu@naturalXmax+\tabu@naturalXmin \relax + \iftabu@measuring + \tabu@target =\dimexpr \@tempdimc+\tabu@spreadtarget \relax + \edef\tabu@bufferX{\endgroup \tabucolX \the\tabucolX \tabu@target\the\tabu@target}% + \else + \tabu@message{\tabu@message@spreadarith}% + \ifdim \dimexpr \@tempdimc+\tabu@spreadtarget >\tabu@target + \tabu@message{(tabu) spread + \ifdim \@tempdimc>\tabu@target useless here: default target used% + \else too large: reduced to fit default target\fi.}% + \else + \tabu@target =\dimexpr \@tempdimc+\tabu@spreadtarget \relax + \tabu@message{(tabu) spread: New target set to \the\tabu@target^^J}% + \fi + \begingroup \let\tabu@wddef \@gobbletwo + \@tempdimb \@tempdima + \tabucolX@init + \tabu@arithnegcoef + \wd\tabu@box =\dimexpr \wd\tabu@box +\@tempdima-\@tempdimb \relax + \expandafter\endgroup \expandafter\tabucolX \the\tabucolX + \tabu@arith + \fi +}% \tabu@spreadarith +\def\tabu@spread@arith #1#2{% + \ifdim #2\p@>\z@ \advance\dimen@ #2\p@ + \else \advance\@tempdima \tabu@wd{#1}\relax + \fi +}% \tabu@spread@arith +% \end{macrocode} +% \end{macro} +% +% \subsubsection(\xext{log} report){Reporting in the \xext{log} file (\textt{debugshow option})} +%¤<package>%% Reporting in the .log file --------------------------------------- +% +% \begin{macro}{\tabu@message@defaulttarget} +% \begin{macrocode} +\def\tabu@message@defaulttarget{% + \ifnum\tabu@nested=\z@^^J(tabu) Default target: + \ifx\tabudefaulttarget\linewidth \string\linewidth + \ifdim \tabu@thetarget=\linewidth \else + -\the\dimexpr\linewidth-\tabu@thetarget\fi = + \else\ifx\tabudefaulttarget\linegoal\string\linegoal= + \fi\fi + \else (tabu) Default target (nested): \fi + \the\tabu@target \on@line + \ifnum\tabu@nested=\z@ , page \the\c@page\fi} +\def\tabu@message@target {^^J(tabu) Target specified: + \the\tabu@target \on@line, page \the\c@page} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@message@arith} +% \begin{macrocode} +\def\tabu@message@arith {\tabu@header + \tabu@msgalign \tabucolX { }{ }{ }{ }{ }\@@ + \tabu@msgalign \wd\tabu@box { }{ }{ }{ }{ }\@@ + \tabu@msgalign \tabu@target { }{ }{ }{ }{ }\@@ + \tabu@msgalign@PT \dimen@ { }{}{}{}{}{}{}\@@ + \ifdim \tabu@DELTA<\tabu@hfuzz giving space\else + \tabu@msgalign \dimexpr (\@tempdima-\tabu@DELTA) *\p@/\tabu@Xsum -\tabucolX {}{}{}{}{}\@@ + \fi +}% \tabu@message@arith +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@message@spreadarith} +% \begin{macrocode} +\def\tabu@message@spreadarith {\tabu@spreadheader + \tabu@msgalign \tabu@spreadtarget { }{ }{ }{ }{}\@@ + \tabu@msgalign \wd\tabu@box { }{ }{ }{ }{}\@@ + \tabu@msgalign -\tabu@naturalXmax { }{}{}{}{}\@@ + \tabu@msgalign \tabu@naturalXmin { }{ }{ }{ }{}\@@ + \tabu@msgalign \ifdim \dimexpr\@tempdimc>\tabu@target \tabu@target + \else \@tempdimc+\tabu@spreadtarget \fi + {}{}{}{}{}\@@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@message@negcoef} +% \begin{macrocode} +\def\tabu@message@negcoef #1#2{ + \tabu@spaces\tabu@spaces\space * #1. X[\rem@pt#2]: + \space width = \tabu@wd {#1} + \expandafter\string\csname tabu@\the\tabu@nested.W\number#1\endcsname + \ifdim -\tabu@pt#2\tabucolX<\tabu@target + < \number-\rem@pt#2 X + = \the\dimexpr -\tabu@pt#2\tabucolX \relax + \else + <= \the\tabu@target\space < \number-\rem@pt#2 X\fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@message@reached} +% \begin{macrocode} +\def\tabu@message@reached{\tabu@header + ******* Reached Target: + hfuzz = \tabu@hfuzz\on@line\space *******} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@message@etime} +% \begin{macrocode} +\def\tabu@message@etime{\edef\tabu@stoptime{\the\pdfelapsedtime}% + \tabu@message{(tabu)\tabu@spaces Time elapsed during measure: + \the\numexpr(\tabu@stoptime-\tabu@starttime-32767)/65536\relax sec + \the\numexpr\numexpr(\tabu@stoptime-\tabu@starttime) + -\numexpr(\tabu@stoptime-\tabu@starttime-32767)/65536\relax*65536\relax + *1000/65536\relax ms \tabu@spaces(\the\tabu@cnt\space + cycle\ifnum\tabu@cnt>\@ne s\fi)^^J^^J}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@message@verticalsp} +% \begin{macrocode} +\def\tabu@message@verticalsp {% + \ifdim \@tempdima>\tabu@ht + \ifdim \@tempdimb>\tabu@dp + \expandafter\expandafter\expandafter\string\tabu@ht = + \tabu@msgalign \@tempdima { }{ }{ }{ }{ }\@@ + \expandafter\expandafter\expandafter\string\tabu@dp = + \tabu@msgalign \@tempdimb { }{ }{ }{ }{ }\@@^^J% + \else + \expandafter\expandafter\expandafter\string\tabu@ht = + \tabu@msgalign \@tempdima { }{ }{ }{ }{ }\@@^^J% + \fi + \else\ifdim \@tempdimb>\tabu@dp + \tabu@spaces\tabu@spaces\tabu@spaces + \expandafter\expandafter\expandafter\string\tabu@dp = + \tabu@msgalign \@tempdimb { }{ }{ }{ }{ }\@@^^J\fi + \fi +}% \tabu@message@verticalsp +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@message@save} +% \begin{macrocode} +\edef\tabu@spaces{\@spaces} +\def\tabu@strippt{\expandafter\tabu@pt\the} +{\@makeother\P \@makeother\T\lowercase{\gdef\tabu@pt #1PT{#1}}} +\def\tabu@msgalign{\expandafter\tabu@msg@align\the\dimexpr} +\def\tabu@msgalign@PT{\expandafter\tabu@msg@align\romannumeral-`\0\tabu@strippt} +\def\do #1{% + \def\tabu@msg@align##1.##2##3##4##5##6##7##8##9\@@{% + \ifnum##1<10 #1 #1\else + \ifnum##1<100 #1 \else + \ifnum##1<\@m #1\fi\fi\fi + ##1.##2##3##4##5##6##7##8#1}% + \def\tabu@header{(tabu) \ifnum\tabu@cnt<10 #1\fi\the\tabu@cnt) }% + \def\tabu@titles{\ifnum \tabu@nested=\z@ + (tabu) Try#1 #1 tabu X #1 #1 #1tabu Width #1 #1 Target + #1 #1 #1 Coefs #1 #1 #1 Update^^J\fi}% + \def\tabu@spreadheader{% + (tabu) Try#1 #1 Spread #1 #1 tabu Width #1 #1 #1 Nat. X #1 #1 #1 #1Nat. Min. + #1 New Target^^J% + (tabu) sprd} + \def\tabu@message@save {\begingroup + \def\x ####1{\tabu@msg@align ####1{ }{ }{ }{ }{}\@@} + \def\z ####1{\expandafter\x\expandafter{\romannumeral-`\0\tabu@strippt + \dimexpr####1\p@{ }{ }}}% + \let\color \relax \def\tabu@rulesstyle ####1####2{\detokenize{####1}}% + \let\CT@arc@ \relax \let\@preamble \@gobble + \let\tabu@savedpream \@firstofone + \let\tabu@savedparams \@firstofone + \def\tabu@target ####1\relax {(tabu) target #1 #1 #1 #1 #1 = \x{####1}^^J}% + \def\tabucolX ####1\relax {(tabu) X columns width#1 = \x{####1}^^J}% + \def\tabu@nbcols ####1\relax {(tabu) Number of columns: \z{####1}^^J}% + \def\tabu@aligndefault ####1{(tabu) Default alignment: #1 #1 ####1^^J}% + \def\col@sep ####1\relax {(tabu) column sep #1 #1 #1 = \x{####1}^^J}% + \def\arrayrulewidth ####1\relax{(tabu) arrayrulewidth #1 = \x{####1}}% + \def\doublerulesep ####1\relax { doublerulesep = \x{####1}^^J}% + \def\extratabsurround####1\relax{(tabu) extratabsurround = \x{####1}^^J}% + \def\extrarowheight ####1\relax{(tabu) extrarowheight #1 = \x{####1}}% + \def\extrarowdepth ####1\relax {extrarowdepth = \x{####1}^^J}% + \def\abovetabulinesep####1\relax{(tabu) abovetabulinesep=\x{####1} }% + \def\belowtabulinesep####1\relax{ belowtabulinesep=\x{####1}^^J}% + \def\arraystretch ####1{(tabu) arraystretch #1 #1 = \z{####1}^^J}% + \def\minrowclearance####1\relax{(tabu) minrowclearance #1 = \x{####1}^^J}% + \def\tabu@arc@L ####1{(tabu) taburulecolor #1 #1 = ####1^^J}% + \def\tabu@drsc@L ####1{(tabu) tabudoublerulecolor= ####1^^J}% + \def\tabu@evr@L ####1{(tabu) everyrow #1 #1 #1 #1 = \detokenize{####1}^^J}% + \def\tabu@ls@L ####1{(tabu) line style = \detokenize{####1}^^J}% + \def\NC@find ####1\@nil{(tabu) tabu preamble#1 #1 = \detokenize{####1}^^J}% + \def\tabu@wddef####1####2{(tabu) Natural width ####1 = \x{####2}^^J}% + \let\edef \@gobbletwo \let\def \@empty \let\let \@gobbletwo + \tabu@message{% + (tabu) \string\savetabu{\tabu@temp}: \on@line^^J% + \tabu@usetabu \@nil^^J}% + \endgroup} +}\do{ } +% \end{macrocode} +% \end{macro} +% +% \subsection(Natural width measure){Measuring the natural width of columns (\xpackage{varwidth} code from D. Arseneau)} +%¤<package>%% Measuring the natural width (varwidth) - store the results ------- +% +% \begin{macro}{\tabu@startpboxmeasure} +% +% The important job is done at the end: by \cs\tabu@endpboxmeasure. +% +% When ``\env{tabu spread}'' is used with \textt X columns, the first trial must +% measure the natural width of the columns. When \textt X columns have negativ coefficient, +% the natural is computed after the target has been reached, with the absolute coefficients. +% +% Nested trials may occur (\env{tabu spread} inside a \textt X column with negativ +% coefficient for example). +% +% For the furthur trials, the standard scheme for \textt X column is used: the natural width +% is measured only once. +% +% \hologo{pdfTeX} font expansion is disabled inside the \env*{varwidth} +% (we set \cs\pdfadjustspacing to \textt 0). +% +% \begin{macrocode} +\def\tabu@startpboxmeasure #1{\bgroup % entering \vtop + \edef\tabu@temp{\expandafter\@secondoftwo \ifx\tabu@hsize #1\else\relax\fi}% + \ifodd 1\ifx \tabu@temp\@empty 0 \else % starts with \tabu@hsize ? + \iftabu@spread \else % if spread -> measure + \ifdim \tabu@temp\p@>\z@ 0 \fi\fi\fi% if coef>0 -> do not measure + \let\@startpbox \tabu@startpboxORI % restore immediately (nesting) + \tabu@measuringtrue % for the quick option... + \tabu@Xcol =\expandafter\@firstoftwo\ifx\tabu@hsize #1\fi + \ifdim \tabu@temp\p@>\z@ \ifdim \tabu@temp\tabucolX<\tabu@target + \tabu@target=\tabu@temp\tabucolX \fi\fi + \setbox\tabu@box \hbox \bgroup + \begin{varwidth}\tabu@target + \let\FV@ListProcessLine \tabu@FV@ListProcessLine % \hbox to natural width... + \narrowragged \arraybackslash \parfillskip \@flushglue + \ifdefined\pdfadjustspacing \pdfadjustspacing\z@ \fi + \bgroup \aftergroup\tabu@endpboxmeasure + \ifdefined \cellspacetoplimit \tabu@cellspacepatch \fi + \else \expandafter\@gobble + \tabu@startpboxquick{#1}% \@gobble \bgroup + \fi +}% \tabu@startpboxmeasure +\def\tabu@cellspacepatch{\def\bcolumn##1\@nil{}\let\ecolumn\@empty + \bgroup\color@begingroup} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@endpboxmeasure} +% +% The cell has been built inside a box: we have to get its dimensions, +% and update \cs\tabu@naturalX, \cs\tabu@naturalXmin and \cs\tabu@naturalXmax +% accordingly (for \env{tabu spread}), and even store (globally) each column width: +% the column width is the maximum width of the cells it contains. +% +% \begin{macrocode} +\def\tabu@endpboxmeasure {% + \@finalstrut \@arstrutbox + \end{varwidth}\egroup % <got my \tabu@box> + \ifdim \tabu@temp\p@ <\z@ % neg coef + \ifdim \tabu@wd\tabu@Xcol <\wd\tabu@box + \tabu@wddef\tabu@Xcol {\the\wd\tabu@box}% + \tabu@debug{\tabu@message@endpboxmeasure}% + \fi + \else % spread coef>0 + \global\advance \tabu@naturalX \wd\tabu@box + \@tempdima =\dimexpr \wd\tabu@box *\p@/\dimexpr \tabu@temp\p@\relax \relax + \ifdim \tabu@naturalXmax <\tabu@naturalX + \xdef\tabu@naturalXmax {\the\tabu@naturalX}\fi + \ifdim \tabu@naturalXmin <\@tempdima + \xdef\tabu@naturalXmin {\the\@tempdima}\fi + \fi + \box\tabu@box \egroup % end of \vtop (measure) restore \tabu@target +}% \tabu@endpboxmeasure +\def\tabu@wddef #1{\expandafter\xdef + \csname tabu@\the\tabu@nested.W\number#1\endcsname} +\def\tabu@wd #1{\csname tabu@\the\tabu@nested.W\number#1\endcsname} +\def\tabu@message@endpboxmeasure{\tabu@spaces\tabu@spaces<-> % <-> save natural wd + \the\tabu@Xcol. X[\tabu@temp]: + target = \the\tabucolX \space + \expandafter\expandafter\expandafter\string\tabu@wd\tabu@Xcol + =\tabu@wd\tabu@Xcol +}% \tabu@message@endpboxmeasure +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@startpboxquick} +% +% Contents of paragraph columns are not built during trials in +% strategy number $4$. +% +% \begin{macrocode} +\def\tabu@startpboxquick {\bgroup + \let\@startpbox \tabu@startpboxORI % restore immediately + \let\tabu \tabu@quick % \begin is expanded before... + \expandafter\@gobble \@startpbox % gobbles \bgroup +}% \tabu@startpboxquick +\def\tabu@quick {\begingroup \iffalse{\fi \ifnum0=`}\fi + \toks@{}\def\tabu@stack{b}\tabu@collectbody \tabu@endquick +}% \tabu@quick +\def\tabu@endquick {% + \ifodd 1\ifx\tabu@end@envir\tabu@endtabu \else + \ifx\tabu@end@envir\tabu@endtabus \else 0\fi\fi\relax + \endgroup + \else \let\endtabu \relax + \tabu@end@envir + \fi +}% \tabu@quick +\def\tabu@endtabu {\end{tabu}} +\def\tabu@endtabus {\end{tabu*}} +% \end{macrocode} +% \end{macro} +% +% \subsection(Vertical measure){Measuring the height and depths of rows} +%¤<package>%% Measuring the heights and depths - store the results ------------- +% +% \begin{macro}{\tabu@verticalmeasure} +% +% Starting point for vertical measure of every cell. Only the maxima/minima are stored, +% for \TabU must know the height/depth of every row. +% +% \begin{macrocode} +\def\tabu@verticalmeasure{\everypar{}% + \ifnum \currentgrouptype>12 % 14=semi-simple, 15=math shift group + \setbox\tabu@box =\hbox\bgroup + \let\tabu@verticalspacing \tabu@verticalsp@lcr + \d@llarbegin % after \hbox ... + \else + \edef\tabu@temp{\ifnum\currentgrouptype=5\vtop + \else\ifnum\currentgrouptype=12\vcenter + \else\vbox\fi\fi}% + \setbox\tabu@box \hbox\bgroup$\tabu@temp \bgroup + \let\tabu@verticalspacing \tabu@verticalsp@pmb + \fi +}% \tabu@verticalmeasure +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@verticalsp@lcr} +% +% Vertical spacing adjustment for standard \textt l,\, \textt c,\, \textt r\, columns. +% +% \begin{macrocode} +\def\tabu@verticalsp@lcr{% + \d@llarend \egroup % <got my \tabu@box> + \@tempdima \dimexpr \ht\tabu@box+\abovetabulinesep + \@tempdimb \dimexpr \dp\tabu@box+\belowtabulinesep \relax + \ifdim\tabustrutrule>\z@ \tabu@debug{\tabu@message@verticalsp}\fi + \ifdim \tabu@ht<\@tempdima \tabu@htdef{\the\@tempdima}\fi + \ifdim \tabu@dp<\@tempdimb \tabu@dpdef{\the\@tempdimb}\fi + \noindent\vrule height\@tempdima depth\@tempdimb +}% \tabu@verticalsp@lcr +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@verticalsp@pmb} +% +% Vertical spacing adjustment with struts for \textt p,\, \textt m,\, or \textt b\, columns. +% +% \begin{macrocode} +\def\tabu@verticalsp@pmb{% inserts struts as needed + \par \expandafter\egroup + \expandafter$\expandafter + \egroup \expandafter + \@tempdimc \the\prevdepth + \@tempdima \dimexpr \ht\tabu@box+\abovetabulinesep + \@tempdimb \dimexpr \dp\tabu@box+\belowtabulinesep \relax + \ifdim\tabustrutrule>\z@ \tabu@debug{\tabu@message@verticalsp}\fi + \ifdim \tabu@ht<\@tempdima \tabu@htdef{\the\@tempdima}\fi + \ifdim \tabu@dp<\@tempdimb \tabu@dpdef{\the\@tempdimb}\fi + \let\@finalstrut \@gobble + \hrule height\@tempdima depth\@tempdimb width\hsize +%% \box\tabu@box +}% \tabu@verticalsp@pmb +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@verticalinit} +% +% Initialisation of \cs\tabu@ht and \cs\tabu@dp. Done at \cs\everyrow. + +% \begin{macrocode} +\def\tabu@verticalinit{% + \ifnum \c@taburow=\z@ \tabu@rearstrut \fi % after \tabu@reset ! + \advance\c@taburow \@ne + \tabu@htdef{\the\ht\@arstrutbox}\tabu@dpdef{\the\dp\@arstrutbox}% + \advance\c@taburow \m@ne +}% \tabu@verticalinit +\def\tabu@htdef {\expandafter\xdef \csname tabu@\the\tabu@nested.H\the\c@taburow\endcsname} +\def\tabu@ht {\csname tabu@\the\tabu@nested.H\the\c@taburow\endcsname} +\def\tabu@dpdef {\expandafter\xdef \csname tabu@\the\tabu@nested.D\the\c@taburow\endcsname} +\def\tabu@dp {\csname tabu@\the\tabu@nested.D\the\c@taburow\endcsname} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@verticaldynamicadjustment} +% +% This updates the \cs\@arstrutbox at \cs\everyrow (\ie \cs\everycr) in order to +% adjust the vertical spacing of cells. +% +% \begin{macrocode} +\def\tabu@verticaldynamicadjustment {% + \advance\c@taburow \@ne + \extrarowheight \dimexpr\tabu@ht - \ht\strutbox + \extrarowdepth \dimexpr\tabu@dp - \dp\strutbox + \let\arraystretch \@empty + \advance\c@taburow \m@ne +}% \tabu@verticaldynamicadjustment +% \end{macrocode} +% \end{macro} +% +% \subsection{\cs{tabuphantomline}} +% +% \begin{macro}{\tabuphantomline} +% +% This macro inserts a phantom line in front of a \env{tabu}. +% This is necessary when you use \cs\usetabu with \textt{tabu X} column, +% with a single line containing \cs\multicolumn... +% +% \begin{macrocode} +\def\tabuphantomline{\crcr \noalign{% + {\globaldefs \@ne + \setbox\@arstrutbox \box\voidb@x + \let\tabu@@celllalign \tabu@celllalign + \let\tabu@@cellralign \tabu@cellralign + \let\tabu@@cellleft \tabu@cellleft + \let\tabu@@cellright \tabu@cellright + \let\tabu@@thevline \tabu@thevline + \let\tabu@celllalign \@empty + \let\tabu@cellralign \@empty + \let\tabu@cellright \@empty + \let\tabu@cellleft \@empty + \let\tabu@thevline \relax}% + \edef\tabu@temp{\tabu@multispan \tabu@nbcols{\noindent &}}% + \toks@\expandafter{\tabu@temp \noindent\tabu@everyrowfalse \cr + \noalign{\tabu@rearstrut + {\globaldefs\@ne + \let\tabu@celllalign \tabu@@celllalign + \let\tabu@cellralign \tabu@@cellralign + \let\tabu@cellleft \tabu@@cellleft + \let\tabu@cellright \tabu@@cellright + \let\tabu@thevline \tabu@@thevline}}}% + \expandafter}\the\toks@ +}% \tabuphantomline +% \end{macrocode} +% \end{macro} +% +% \subsection(Horizontal lines inside tabu){Horizontal lines inside \env{tabu}: \cs{tabucline}, \cs{firsthline} and \cs{lasthline}} +%¤<package>%% \firsthline and \lasthline corrections --------------------------- +% +% \subsubsection{Horizontal lines: multiple \cs{firsthline} / \cs{lasthline}} +% +% \begin{macro}{\tabu@firstline} +% \begin{macro}{\tabu@lastline}% +% \begin{macro}{\tabu@firsthline} +% \begin{macro}{\tabu@lasthline} +% +% \cs\firsthline and \cs\lasthline are \cs\let to \cs\tabu@firsthline and \cs\tabu@lasthline +% inside the \env*{tabu}. +% +% This allows to duplicate horizontal lines, while keeping the alignement: +% +% \cs\firsthline\cs\firsthline\cs\firsthline is allowed inside \env{tabu} and is the same as: +% +% \cs\firsthline\cs\hline\cs\hline. +% +% \begin{macrocode} +\def\tabu@firstline {\tabu@hlineAZ \tabu@firsthlinecorrection {}} +\def\tabu@firsthline{\tabu@hlineAZ \tabu@firsthlinecorrection \hline} +\def\tabu@lastline {\tabu@hlineAZ \tabu@lasthlinecorrection {}} +\def\tabu@lasthline {\tabu@hlineAZ \tabu@lasthlinecorrection \hline} +\def\tabu@hline {% replaces \hline if no colortbl (see \AtBeginDocument) + \noalign{\ifnum0=`}\fi + {\CT@arc@\hrule height\arrayrulewidth}% + \futurelet \tabu@temp \tabu@xhline +}% \tabu@hline +\def\tabu@xhline{% + \ifx \tabu@temp \hline + {\ifx \CT@drsc@\relax \vskip + \else\ifx \CT@drsc@\@empty \vskip + \else \CT@drsc@\hrule height + \fi\fi + \doublerulesep}% + \fi + \ifnum0=`{\fi}% +}% \tabu@xhline +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@hlineAZ} +% \begin{macro}{\tabu@nexthlineAZ} +% \begin{macro}{\tabu@xhlineAZ} +% +% Here we go, inside a \cs\noalign group, we collect the next tokens: +% \begin{enumerate}[label=\arabic*.] +% \item first the option, +% \item and then the next tokens if they are \cs\hline or \cs\firsthline. +% \end{enumerate} +% +% The code to be executed at the end of the \cs\noalign group is built into \cs\toks@. +% +% \begin{macrocode} +\def\tabu@hlineAZ #1#2{\noalign{\ifnum0=`}\fi \dimen@ \z@ \count@ \z@ + \toks@{}\def\tabu@hlinecorrection{#1}\def\tabu@temp{#2}% + \tabu@hlineAZsurround +}% \tabu@hlineAZ +\newcommand*\tabu@hlineAZsurround[1][\extratabsurround]{% + \extratabsurround #1\let\tabucline \tabucline@scan + \let\hline \tabu@hlinescan \let\firsthline \hline + \let\cline \tabu@clinescan \let\lasthline \hline + \expandafter \futurelet \expandafter \tabu@temp + \expandafter \tabu@nexthlineAZ \tabu@temp +}% \tabu@hlineAZsurround +\def\tabu@hlinescan {\tabu@thick \arrayrulewidth \tabu@xhlineAZ \hline} +\def\tabu@clinescan #1{\tabu@thick \arrayrulewidth \tabu@xhlineAZ {\cline{#1}}} +\def\tabucline@scan{\@testopt \tabucline@sc@n {}} +\def\tabucline@sc@n #1[#2]{\tabu@xhlineAZ {\tabucline[{#1}]{#2}}} +\def\tabu@nexthlineAZ{% + \ifx \tabu@temp\hline \else + \ifx \tabu@temp\cline \else + \ifx \tabu@temp\tabucline \else + \tabu@hlinecorrection + \fi\fi\fi +}% \tabu@nexthlineAZ +\def\tabu@xhlineAZ #1{% + \toks@\expandafter{\the\toks@ #1}% + \@tempdimc \tabu@thick % The last line width + \ifcase\count@ \@tempdimb \tabu@thick % The first line width + \else \advance\dimen@ \dimexpr \tabu@thick+\doublerulesep \relax + \fi + \advance\count@ \@ne \futurelet \tabu@temp \tabu@nexthlineAZ +}% \tabu@xhlineAZ +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@firsthlinecorrection} +% +% This is the ``correction macro'' for \cs\firsthline, \ie a strut and a skip are inserted +% \textbf{before} the first \cs\hline. +% +% \begin{macrocode} +\def\tabu@firsthlinecorrection{% \count@ = number of \hline -1 + \@tempdima \dimexpr \ht\@arstrutbox+\dimen@ + \edef\firsthline{% <local in \noalign> + \omit \hbox to\z@{\hss{\noexpand\tabu@DBG{yellow}\vrule + height \the\dimexpr\@tempdima+\extratabsurround + depth \dp\@arstrutbox + width \tabustrutrule}\hss}\cr + \noalign{\vskip -\the\dimexpr \@tempdima+\@tempdimb + +\dp\@arstrutbox \relax}% + \the\toks@ + }\ifnum0=`{\fi + \expandafter}\firsthline % we are then ! +}% \tabu@firsthlinecorrection +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\tabu@lasthlinecorrection} +% +% This is the ``correction macro'' for \cs\lasthline, \ie a strut and a skip are inserted +% \textbf{after} the last \cs\hline. +% +% \begin{macrocode} +\def\tabu@lasthlinecorrection{% + \@tempdima \dimexpr \dp\@arstrutbox+\dimen@+\@tempdimb+\@tempdimc + \edef\lasthline{% <local in \noalign> + \the\toks@ + \noalign{\vskip -\the\dimexpr\dimen@+\@tempdimb+\dp\@arstrutbox}% + \omit \hbox to\z@{\hss{\noexpand\tabu@DBG{yellow}\vrule + depth \the\dimexpr \dp\@arstrutbox+\@tempdimb+\dimen@ + +\extratabsurround-\@tempdimc + height \z@ + width \tabustrutrule}\hss}\cr + }\ifnum0=`{\fi + \expandafter}\lasthline % we are then ! +}% \tabu@lasthlinecorrection +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@LT@@hline} +% +% Allowing colored rules even if \xpackage{colortbl} is not loaded. +% +% \begin{macrocode} +\def\tabu@LT@@hline{% + \ifx\LT@next\hline + \global\let\LT@next \@gobble + \ifx \CT@drsc@\relax + \gdef\CT@LT@sep{% + \noalign{\penalty-\@medpenalty\vskip\doublerulesep}}% + \else + \gdef\CT@LT@sep{% + \multispan\LT@cols{% + \CT@drsc@\leaders\hrule\@height\doublerulesep\hfill}\cr}% + \fi + \else + \global\let\LT@next\empty + \gdef\CT@LT@sep{% + \noalign{\penalty-\@lowpenalty\vskip-\arrayrulewidth}}% + \fi + \ifnum0=`{\fi}% + \multispan\LT@cols + {\CT@arc@\leaders\hrule\@height\arrayrulewidth\hfill}\cr + \CT@LT@sep + \multispan\LT@cols + {\CT@arc@\leaders\hrule\@height\arrayrulewidth\hfill}\cr + \noalign{\penalty\@M}% + \LT@next +}% \tabu@LT@@hline +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Horizontal lines: \cs{tabucline}} +%¤<package>%% Horizontal lines : \tabucline ------------------------------------ +% +% \begin{macro}{\tabucline} +% +% \cs\tabucline \M[style or spec.]\M*{start-end} +% +% \cs\tabucline appears only at the end of a line: this is the place where we can insert a \cs\noalign group. +% The line to be inserted inside the \env{tabu} is build inside this \cs\noalign group. +% +% \cs\tabu@start and \cs\tabu@stop store the limits for the line: they are, for clarity, +% the local name of \cs\@tempcnta and \cs\@tempcntb. +% +% \begin{macrocode} +\let\tabu@start \@tempcnta +\let\tabu@stop \@tempcntb +\newcommand*\tabucline{\noalign{\ifnum0=`}\fi \tabu@cline} +\newcommand*\tabu@cline[2][]{\tabu@startstop{#2}% + \ifnum \tabu@stop<\z@ \toks@{}% + \else \tabu@clinearg{#1}\tabu@thestyle + \edef\tabucline{\toks@{% + \ifnum \tabu@start>\z@ \omit + \tabu@multispan\tabu@start {\span\omit}&\fi + \omit \tabu@multispan\tabu@stop {\span\omit}% + \tabu@thehline\cr + }}\tabucline + \tabu@tracinglines{(tabu:tabucline) Style: #1^^J\the\toks@^^J^^J}% + \fi + \futurelet \tabu@temp \tabu@xcline +}% \tabu@cline +\def\tabu@clinearg #1{% + \ifx\\#1\\\let\tabu@thestyle \tabu@ls@ + \else \@defaultunits \expandafter\let\expandafter\@tempa + \romannumeral-`\0#1\relax \@nnil + \ifx \hbox\@tempa \tabu@clinebox{#1}% + \else\ifx \box\@tempa \tabu@clinebox{#1}% + \else\ifx \vbox\@tempa \tabu@clinebox{#1}% + \else\ifx \vtop\@tempa \tabu@clinebox{#1}% + \else\ifx \copy\@tempa \tabu@clinebox{#1}% + \else\ifx \leaders\@tempa \tabu@clineleads{#1}% + \else\ifx \cleaders\@tempa \tabu@clineleads{#1}% + \else\ifx \xleaders\@tempa \tabu@clineleads{#1}% + \else\tabu@getline {#1}% + \fi\fi\fi\fi\fi\fi\fi\fi + \fi +}% \tabu@clinearg +\def\tabu@clinebox #1{\tabu@clineleads{\xleaders#1\hss}} +\def\tabu@clineleads #1{% + \let\tabu@thestyle \relax \let\tabu@leaders \@undefined + \gdef\tabu@thehrule{#1}} +\def\tabu@thehline{\begingroup + \ifdefined\tabu@leaders + \noexpand\tabu@thehleaders + \else \noexpand\tabu@thehrule + \fi \endgroup +}% \tabu@thehline +\def\tabu@xcline{% + \ifx \tabu@temp\tabucline + \toks@\expandafter{\the\toks@ \noalign + {\ifx\CT@drsc@\relax \vskip + \else \CT@drsc@\hrule height + \fi + \doublerulesep}}% + \fi + \tabu@docline +}% \tabu@xcline +\def\tabu@docline {\ifnum0=`{\fi \expandafter}\the\toks@} +\def\tabu@docline@evr {\xdef\tabu@doclineafter{\the\toks@}% + \ifnum0=`{\fi}\aftergroup\tabu@doclineafter} +\def\tabu@multispan #1#2{% + \ifnum\numexpr#1>\@ne #2\expandafter\tabu@multispan + \else \expandafter\@gobbletwo + \fi {#1-1}{#2}% +}% \tabu@multispan +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@startstop} +% +% This macro parses the mandatory argument of \cs\tabucline: start-column and end-column of the \cs\cline. +% +% \begin{macrocode} +\def\tabu@startstop #1{\tabu@start@stop #1\relax 1-\tabu@nbcols \@nnil} +\def\tabu@start@stop #1-#2\@nnil{% + \@defaultunits \tabu@start\number 0#1\relax \@nnil + \@defaultunits \tabu@stop \number 0#2\relax \@nnil + \tabu@stop \ifnum \tabu@start>\tabu@nbcols \m@ne + \else\ifnum \tabu@stop=\z@ \tabu@nbcols + \else\ifnum \tabu@stop>\tabu@nbcols \tabu@nbcols + \else \tabu@stop + \fi\fi\fi + \advance\tabu@start \m@ne + \ifnum \tabu@start>\z@ \advance\tabu@stop -\tabu@start \fi +}% \tabu@start@stop +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Numbers in \env{tabu}} +%¤<package>%% Numbers: siunitx S columns (and \tabudecimal) ------------------- +% +% \subsubsection{\cs{tabudecimal}} +% +% \begin{macro}{\tabudecimal} +% +% \cs\tabu@tabudecimal is \cs\tabudecimal inside the \env*{tabu}. +% +% \begin{macrocode} +\def\tabu@tabudecimal #1{% + \def\tabu@decimal{#1}\@temptokena{}% + \let\tabu@getdecimal@ \tabu@getdecimal@ignorespaces + \tabu@scandecimal +}% \tabu@tabudecimal +\def\tabu@scandecimal{\futurelet \tabu@temp \tabu@getdecimal@} +\def\tabu@skipdecimal#1{#1\tabu@scandecimal} +\def\tabu@getdecimal@ignorespaces{% + \ifcase 0\ifx\tabu@temp\ignorespaces\else + \ifx\tabu@temp\@sptoken1\else + 2\fi\fi\relax + \let\tabu@getdecimal@ \tabu@getdecimal + \expandafter\tabu@skipdecimal + \or \expandafter\tabu@gobblespace\expandafter\tabu@scandecimal + \else \expandafter\tabu@skipdecimal + \fi +}% \tabu@getdecimal@ignorespaces +\def\tabu@get@decimal#1{\@temptokena\expandafter{\the\@temptokena #1}% + \tabu@scandecimal} +\def\do#1{% + \def\tabu@get@decimalspace#1{% + \@temptokena\expandafter{\the\@temptokena #1}\tabu@scandecimal}% +}\do{ } +\let\tabu@@tabudecimal \tabu@tabudecimal +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@getdecimal} +% +% +% +% \begin{macrocode} +\def\tabu@getdecimal{% + \ifcase 0\ifx 0\tabu@temp\else + \ifx 1\tabu@temp\else + \ifx 2\tabu@temp\else + \ifx 3\tabu@temp\else + \ifx 4\tabu@temp\else + \ifx 5\tabu@temp\else + \ifx 6\tabu@temp\else + \ifx 7\tabu@temp\else + \ifx 8\tabu@temp\else + \ifx 9\tabu@temp\else + \ifx .\tabu@temp\else + \ifx ,\tabu@temp\else + \ifx -\tabu@temp\else + \ifx +\tabu@temp\else + \ifx e\tabu@temp\else + \ifx E\tabu@temp\else + \ifx\tabu@cellleft\tabu@temp1\else + \ifx\ignorespaces\tabu@temp1\else + \ifx\@sptoken\tabu@temp2\else + 3\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\relax + \expandafter\tabu@get@decimal + \or \expandafter\tabu@skipdecimal + \or \expandafter\tabu@get@decimalspace + \else\expandafter\tabu@printdecimal + \fi +}% \tabu@getdecimal +\def\tabu@printdecimal{% + \edef\tabu@temp{\the\@temptokena}% + \ifx\tabu@temp\@empty\else + \ifx\tabu@temp\space\else + \expandafter\tabu@decimal\expandafter{\the\@temptokena}% + \fi\fi +}% \tabu@printdecimal +% \end{macrocode} +% \end{macro} +% +% +% \subsection(Verbatim with X columns){Verbatim inside \textt{tabu} with \textt X columns} +%¤<package>%% Verbatim inside X columns ---------------------------------------- +% +% \begin{macro}{\tabu@verbatim} +% +% Setup to be done before \cs\scantokens to allow verbatim inside the \env*{tabu}. +% +% \begin{macrocode} +\def\tabu@verbatim{% + \let\verb \tabu@verb + \let\FV@DefineCheckEnd \tabu@FV@DefineCheckEnd +}% \tabu@verbatim +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Compatibility with \LaTeX's kernel \cs{verb} command} +% +% \begin{macro}{\tabu@verb} +% +% The \cs\verb macro from the latex kernel expands \cs\@ifstar in +% a context where the space token: \textvisiblespace\, has a category code of 12. +% +% This is not compatible with \cs\scantokens since \cs\scantokens adds a space +% after each control sequence, including \cs\verb: +% +% \cs\verb+some verbatim text+ \qquad becomes: +% +% \cs\verb\textvisiblespace+some verbatim text+ +% +% and thus, the space token \textvisiblespace\, is set as the \cs\verb delimiter. +% +% We therefore use (a silly) \cs\@ifstar in order to gobble the possible space token. +% +% \begin{macrocode} +\let\tabu@ltx@verb \verb +\def\tabu@verb{\@ifstar {\tabu@ltx@verb*} \tabu@ltx@verb} +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Compatibility with the \xpackage{fancyvrb} package} +% +% \begin{macro}{\tabu@FV@DefineCheckEnd} +% +% This is quite the same issue as for \LaTeX{} \cs\verb command: a space is inserted +% after each control sequence scanned by \cs\scantoken. +% +% This leads to a break in the macro that checks the end of a \env*{Verbatim}, +% since this macro basically checks for a line that conforms to the pattern: +% +% \#1\cs{end}\M*{\#2}\#3 +% +% while with \cs\scantokens, such a line becomes: +% +% \#1\cs{end}\textvisiblespace\M*{\#2}\#3 +% +% in a context where the space token is not of category 10 (space). +% +% Thus we replace the end-check for the \env*{Verbatim} by a check +% on the detokenized-line (with \eTeX{} \cs\detokenize): +% +% \begin{macrocode} +\def\tabu@fancyvrb {% + \def\tabu@FV@DefineCheckEnd ##1{% + \def\tabu@FV@DefineCheckEnd{% + ##1% <original definition (if fancyvrb is loaded)> + \let\FV@CheckEnd \tabu@FV@CheckEnd + \let\FV@@CheckEnd \tabu@FV@@CheckEnd + \let\FV@@@CheckEnd \tabu@FV@@@CheckEnd + \edef\FV@EndScanning{% + \def\noexpand\next{\noexpand\end{\FV@EnvironName}}% + \global\let\noexpand\FV@EnvironName\relax + \noexpand\next}% + \xdef\FV@EnvironName{\detokenize\expandafter{\FV@EnvironName}}}% + }\expandafter\tabu@FV@DefineCheckEnd\expandafter{\FV@DefineCheckEnd} +}% \tabu@fancyvrb +\def\tabu@FV@CheckEnd #1{\expandafter\FV@@CheckEnd \detokenize{#1\end{}}\@nil} +\edef\tabu@FV@@@CheckEnd {\detokenize{\end{}}} +\begingroup +\catcode`\[1 \catcode`\]2 +\@makeother\{ \@makeother\} + \edef\x[\endgroup + \def\noexpand\tabu@FV@@CheckEnd ##1\detokenize[\end{]##2\detokenize[}]##3% + ]\x \@nil{\def\@tempa{#2}\def\@tempb{#3}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@FV@ListProcessLine} +% +% This macro replaces \cs\FV@ListProcessLine when measuring the +% natural width of a \env*{Verbatim} (see \cs\tabu@startpboxmeasure) +% +% \begin{macrocode} +\def\tabu@FV@ListProcessLine #1{% + \hbox {%to \hsize{% + \kern\leftmargin + \hbox {%to \linewidth{% + \FV@LeftListNumber + \FV@LeftListFrame + \FancyVerbFormatLine{#1}\hss +%% DG/SR modification begin - Jan. 28, 1998 (for numbers=right add-on) +%% \FV@RightListFrame}% + \FV@RightListFrame + \FV@RightListNumber}% +%% DG/SR modification end + \hss}} +% \end{macrocode} +% \end{macro} +% +% \sectionformat\subsection{bookmark={color*=DarkRed}} +% \subsection{\cs{savetabu}} +% +%¤<package>%% \savetabu -------------------------------------------------------- +% +% \begin{macro}{\savetabu} +% +% When this command is called by the user, the \env{tabu} preamble and target are globally +% stored into a macro \cs{tabu@saved@\meta{user-name}}. +% +% \begin{macrocode} +\newcommand*\savetabu[1]{\noalign{% + \tabu@sanitizearg{#1}\tabu@temp + \ifx \tabu@temp\@empty \tabu@savewarn{}{The tabu will not be saved}\else + \@ifundefined{tabu@saved@\tabu@temp}{}{\tabu@savewarn{#1}{Overwritting}}% + \ifdefined\tabu@restored \expandafter\let + \csname tabu@saved@\tabu@temp \endcsname \tabu@restored + \else {\tabu@save}% + \fi + \fi}% +}% \savetabu +\def\tabu@save {% + \toks0\expandafter{\tabu@saved@}% + \iftabu@negcoef + \let\tabu@wddef \relax \let\tabu@ \tabu@savewd \edef\tabu@savewd{\tabu@Xcoefs}% + \toks0\expandafter{\the\toks\expandafter0\tabu@savewd}\fi + \toks1\expandafter{\tabu@savedpream}% + \toks2\expandafter{\tabu@savedpreamble}% + \let\@preamble \relax + \let\tabu@savedpream \relax \let\tabu@savedparams \relax + \edef\tabu@preamble{% + \def\noexpand\tabu@aligndefault{\tabu@align}% + \def\tabu@savedparams {\noexpand\the\toks0}% + \def\tabu@savedpream {\noexpand\the\toks1}}% + \edef\tabu@usetabu{% + \def\@preamble {\noexpand\the\toks2}% + \tabu@target \the\tabu@target \relax + \tabucolX \the\tabucolX \relax + \tabu@nbcols \the\tabu@nbcols \relax + \def\noexpand\tabu@aligndefault{\tabu@align}% + \def\tabu@savedparams {\noexpand\the\toks0}% + \def\tabu@savedpream {\noexpand\the\toks1}}% + \let\tabu@aligndefault \relax \let\@sharp \relax + \edef\@tempa{\noexpand\tabu@s@ved + {\tabu@usetabu} + {\tabu@preamble} + {\the\toks1}}\@tempa + \tabu@message@save +}% \tabu@save +\long\def\tabu@s@ved #1#2#3{% + \def\tabu@usetabu{#1}% <for \tabu@message@save> + \expandafter\gdef\csname tabu@saved@\tabu@temp\endcsname ##1{% + \ifodd ##1% \usetabu + \tabu@measuringfalse \tabu@spreadfalse % Just in case... + \gdef\tabu@usetabu {% + \ifdim \tabu@target>\z@ \tabu@warn@usetabu \fi + \global\let\tabu@usetabu \@undefined + \def\@halignto {to\tabu@target}% + #1% + \ifx \tabu@align\tabu@aligndefault@text + \ifnum \tabu@nested=\z@ + \let\tabu@align \tabu@aligndefault \fi\fi}% + \else % \preamble + \gdef\tabu@preamble {% + \global\let\tabu@preamble \@undefined + #2% + \ifx \tabu@align\tabu@aligndefault@text + \ifnum \tabu@nested=\z@ + \let\tabu@align \tabu@aligndefault \fi\fi}% + \fi + #3}% +}% \tabu@s@ved +\def\tabu@aligndefault@text {\tabu@aligndefault}% +\def\tabu@warn@usetabu {\PackageWarning{tabu} + {Specifying a target with \string\usetabu\space is useless + \MessageBreak The target cannot be changed!}} +\def\tabu@savewd #1#2{\ifdim #2\p@<\z@ \tabu@wddef{#1}{\tabu@wd{#1}}\fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@savewarn} +% \begin{macro}{\tabu@saveerr} +% +% Info for overwritting when \cs\savetabu is used. +% +% Error if \cs\usetabu is called with an unknown argument. +% +% \begin{macrocode} +\def\tabu@savewarn#1#2{\PackageInfo{tabu} + {User-name `#1' already used for \string\savetabu + \MessageBreak #2}}% +\def\tabu@saveerr#1{\PackageError{tabu} + {User-name `#1' is unknown for \string\usetabu + \MessageBreak I cannot restore an unknown preamble!}\@ehd} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \sectionformat\subsection{bookmark={color*=DarkRed}} +% \subsection(\cs{rowfont}){\csbf{rowfont}} +% +% \subsubsection(Font and alignment){Setting font and alignment specification} +%¤<package>%% \rowfont --------------------------------------------------------- +% +% \begin{macro}{\rowfont} +% +% {\sloppy\spaceskip=\fontdimen2\font plus1em minus1em\relax +% \cs\rowfont uses the control sequences \cs\tabu@celllalign, \cs\tabu@cellleft, \cs\tabu@cellright and \linebreak +% \cs\tabu@cellralign which have been placed on purpose into the user-defined tokens inserted +% in any preamble by the \xpackage{array} package. +% } +% +% \cs\tabu@celllalign and \cs\tabu@cellralign are used to modify the alignment. If the optional +% \M[alignment] parameter of \cs\rowfont is not specified, then those control sequences expand +% to \cs\@empty. +% +% \cs\tabu@cellleft contains the font-modification information. +% +% Placement of those control sequences into the user-tokens that are inserted in the preamble +% by the \xpackage{array} package is explained below under the macro \cs\tabu@prepnext@tok. +% +% \begin{macrocode} +\newskip \tabu@cellskip +\def\tabu@rowfont{\ifdim \baselineskip=\z@\noalign\fi + {\ifnum0=`}\fi \tabu@row@font} +\newcommand*\tabu@row@font[2][]{% + \ifnum7=\currentgrouptype + \global\let\tabu@@cellleft \tabu@cellleft + \global\let\tabu@@cellright \tabu@cellright + \global\let\tabu@@celllalign \tabu@celllalign + \global\let\tabu@@cellralign \tabu@cellralign + \global\let\tabu@@rowfontreset\tabu@rowfontreset + \fi + \global\let\tabu@rowfontreset \tabu@rowfont@reset + \expandafter\gdef\expandafter\tabu@cellleft\expandafter{\tabu@cellleft #2}% + \ifcsname tabu@cell@#1\endcsname % row alignment + \csname tabu@cell@#1\endcsname \fi + \ifnum0=`{\fi}% end of group / noalign group +}% \rowfont +\def\tabu@ifcolorleavevmode #1{\let\color \tabu@leavevmodecolor #1\let\color\tabu@color}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@rowfont@reset} +% +% This macro restores \cs\tabu@celllalign,\, \cs\tabu@cellleft,\, \cs\tabu@cellright,\, and\, \cs\tabu@cellralign +% to the value they had before the expansion of \cs\rowfont. +% +% It expands when a new row is inserted into the tabular or array. +% +% \begin{macrocode} +\def\tabu@rowfont@reset{% + \global\let\tabu@rowfontreset \tabu@@rowfontreset + \global\let\tabu@cellleft \tabu@@cellleft + \global\let\tabu@cellright \tabu@@cellright + \global\let\tabu@cellfont \@empty + \global\let\tabu@celllalign \tabu@@celllalign + \global\let\tabu@cellralign \tabu@@cellralign +}% \tabu@@rowfontreset +\let\tabu@rowfontreset \@empty % overwritten \AtBeginDocument if colortbl +% \end{macrocode} +% \end{macro} +% +% \subsubsection(Tokens preparation){Preparing stuff to be able to use \cs{rowfont}} +%¤<package>%% \tabu@prepnext@tok ----------------------------------------------- +% +% \begin{macro}{\tabu@prepnext@tok} +% +% \cs\tabu@prepnext@tok will replace \cs\prepnext@tok defined in \xfile{array.sty} (only inside a \env*{tabu}). +% its purpose is to count the number of columns, and to insert the control sequences +% \cs\tabu@celllalign,\, \cs\tabu@cellleft,\, \cs\tabu@cellright\, and\, \cs\tabu@cellralign\, +% at the edge of each cell of the tabular. This is done by putting them inside the user-tokens +% placed around each column by the \xpackage{array} package. +% +% \cs\prepnext@tok in \xfile{array.sty} initialises each user-token to an empty one, each time there is +% a need for a new one ! The macro has a very simple definition, but it expansion is the occasion to +% look carefully at the counters \cs\count@ and \cs\@tempcnta which gives us all information required +% to decide is the token in preparation will be finally placed on the left or on the right of a column. +% +% \begin{center} +% \begin{tikzpicture} +% \node (L) at (1,1) {$\underbrace{\hbox{>\M*{\cs\bfseries\cs\color\M*{red}}}}$} +% node [anchor=west] (r) at (L.east) {\raise.5ex\hbox{\larger r}} +% node [anchor=west] (R) at (r.east) {$\underbrace{\hbox{<\M*{\cs\color\M*{black}\cs ,\cs\$}}}$} +% node [anchor=center] at (L.south) {\cs\toks<$i$>} +% node [anchor=center] at (R.south) {\cs\toks<$i+1$>}; +% \end{tikzpicture} +% \end{center} +% +% When a column is inserted in the tabular preamble (\cs\@preamble), the \TeX{} counter \cs\count@ +% is equal to $i+1$ (\ie the right token) and the counter \cs\@tempcnta is equal to $i$ (\ie the left token). +% If the column is special (\ie \texttbf @ or \texttbf !) \cs\@tempcnta is not updated. +% +% Thus, when a new token is ``prepared'' by \cs\prepnext@tok: +% \begin{description}[leftmargin=1cm,beginpenalty=10000] +% \item[either: $\mathbf{i=}$\cs\count@$\,=$\cs\@tempcnta]: the token to prepare (\ie \cs\toks$<i+1>$) +% is the right one of a ``normal'' column. The switch \cs\iftabu@cellright is set to \textt{true}. \\ +% The \emph{previous} token (\cs\toks$<i>=$\cs\toks\cs\count@) is necessarily the left one of this ``normal'' column: +% we prepend \cs\tabu@celllalign and append \cs\tabu@cellleft to this token (\cs\toks$<i>$). +% This token is finished and will not change afterwards. +% +% \item[or: $\mathbf{i=}$\cs\count@$\,=$\cs\@tempcnta$+1$]: the token to prepare (\cs\toks$<i+1>$) is either the left one of a normal column, +% or the single one of a special\, \texttbf @ or \texttbf !\, column.\\ +% If the switch \cs\iftabu@cellright is true, then the \emph{previous} token \cs\toks$<i>$ is the right one of the last inserted column +% (which was a ``normal'' column, thus):, \cs\tabu@cellright\cs\tabu@cellralign\, is appended to it, and the switch +% \cs\ittabu@cellright is reset to \texttt{false}. +% May be \cs\prepnext@tok will be expanded again (by \cs\save@decl): if it happens, +% then again\, \cs\count@$\,=$\cs\@tempcnta$+1$\, (same case) but \cs\iftabu@cellright is \textt{false} and nothing is changed. +% +% \item[else:] The token to prepare (which is \cs\toks$<i+1>=$\cs\toks\cs\count@$+1$), cannot be the right one of a ``normal'' column: +% \cs\iftabu@cellright is set to \textt{false}. \\ +% The fact that\, $\vert$\cs\count@$-$\cs\@tempcnta$\vert>1$\, tells us that the previous token \cs\toks$<i>$ +% is necessarily the single one of a ``special''\, \texttbf @ or \texttbf !\, column. We don't modify this token, as +% long as \emph{special columns are always inserted as is}:\, \cs\rowcolor has no effect on special +% columns, nor\, \cs\rowfont. +% \end{description} +% Thereafter, the original initialisation sequence occurs: \cs\advance\cs\count@\textt{ by}\cs\@ne and initialize the token +% to prepare (\cs\toks\cs\count@$\,=$\cs\toks$<i+1>$) to an empty one. +% +% \begin{macrocode} +\newif \iftabu@cellright +\def\tabu@prepnext@tok{% + \ifnum \count@<\z@ % <first initialisation> + \@tempcnta \@M % <not initialized by array.sty> + \tabu@nbcols\z@ + \let\tabu@fornoopORI \@fornoop + \tabu@cellrightfalse + \else + \ifcase \numexpr \count@-\@tempcnta \relax % (case 0): prev. token is left + \advance \tabu@nbcols \@ne + \iftabu@cellright % before-previous token is right and is finished + \tabu@cellrightfalse % <only once> + \tabu@righttok + \fi + \tabu@lefttok + \or % (case 1) previous token is right + \tabu@cellrighttrue \let\@fornoop \tabu@lastnoop + \else % special column: do not change the token + \iftabu@cellright % before-previous token is right + \tabu@cellrightfalse + \tabu@righttok + \fi + \fi % \ifcase + \fi + \tabu@prepnext@tokORI +}% \tabu@prepnext@tok +\long\def\tabu@lastnoop#1\@@#2#3{\tabu@lastn@@p #2\@nextchar \in@\in@@} +\def\tabu@lastn@@p #1\@nextchar #2#3\in@@{% + \ifx \in@#2\else + \let\@fornoop \tabu@fornoopORI + \xdef\tabu@mkpreambuffer{\tabu@nbcols\the\tabu@nbcols \tabu@mkpreambuffer}% + \toks0\expandafter{\expandafter\tabu@everyrowtrue \the\toks0}% + \expandafter\prepnext@tok + \fi +}% \tabu@lastnoop +\def\tabu@righttok{% + \advance \count@ \m@ne + \toks\count@\expandafter {\the\toks\count@ \tabu@cellright \tabu@cellralign}% + \advance \count@ \@ne +}% \tabu@righttok +\def\tabu@lefttok{\toks\count@\expandafter{\expandafter\tabu@celllalign + \the\toks\count@ \tabu@cellleft}% after because of $ +}% \tabu@lefttok +% \end{macrocode} +% \end{macro} +% +% \subsubsection(Glue neutralisation){Neutralisation of glues and alignment modification} +%¤<package>%% Neutralisation of glues ------------------------------------------ +% +% \begin{macro}{\tabu@cellleft} +% \begin{macro}{\tabu@celllalign} +% \begin{macro}{\tabu@cellright} +% \begin{macro}{\tabu@cellralign} +% +% First initialisation to \cs\@empty. +% +% \begin{macrocode} +\let\tabu@cellleft \@empty +\let\tabu@cellright \@empty +\tabu@celllalign@def{\tabu@cellleft}% +\let\tabu@cellralign \@empty +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@cell@align} +% \begin{macrocode} +\def\tabu@cell@align #1#2#3{% + \let\tabu@maybesiunitx \toks@ \tabu@celllalign + \global \expandafter \tabu@celllalign@def \expandafter {\the\toks@ #1}% + \toks@\expandafter{\tabu@cellralign #2}% + \xdef\tabu@cellralign{\the\toks@}% + \toks@\expandafter{\tabu@cellleft #3}% + \xdef\tabu@cellleft{\the\toks@}% +}% \tabu@cell@align +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@cell@l} +% \begin{macro}{\tabu@cell@c} +% \begin{macro}{\tabu@cell@r} +% \begin{macro}{\tabu@cell@j} +% +% Setup macros to modify the alignment. The skips inserted to make the standard alignment +% specified in the \textt{tabular} preamble are not the same with standard \xpackage{array} tabulars +% and \xpackage{colortbl} tabulars, hence the switch \cs\iftabu@colortbl. +% +% \begin{macrocode} +\def\tabu@cell@l{% force alignment to left + \tabu@cell@align + {\tabu@removehfil \raggedright \tabu@cellleft}% left + {\tabu@flush1\tabu@ignorehfil}% right + \raggedright +}% \tabu@cell@l +\def\tabu@cell@c{% force alignment to center + \tabu@cell@align + {\tabu@removehfil \centering \tabu@flush{.5}\tabu@cellleft} + {\tabu@flush{.5}\tabu@ignorehfil} + \centering +}% \tabu@cell@c +\def\tabu@cell@r{% force alignment to right + \tabu@cell@align + {\tabu@removehfil \raggedleft \tabu@flush1\tabu@cellleft} + \tabu@ignorehfil + \raggedleft +}% \tabu@cell@r +\def\tabu@cell@j{% force justification (for p, m, b columns) + \tabu@cell@align + {\tabu@justify\tabu@cellleft} + {} + \tabu@justify +}% \tabu@cell@j +\def\tabu@justify{% + \leftskip\z@skip \@rightskip\leftskip \rightskip\@rightskip + \parfillskip\@flushglue +}% \tabu@justify +%% ragged2e settings +\def\tabu@cell@L{% force alignment to left (ragged2e) + \tabu@cell@align + {\tabu@removehfil \RaggedRight \tabu@cellleft} + {\tabu@flush 1\tabu@ignorehfil} + \RaggedRight +}% \tabu@cell@L +\def\tabu@cell@C{% force alignment to center (ragged2e) + \tabu@cell@align + {\tabu@removehfil \Centering \tabu@flush{.5}\tabu@cellleft} + {\tabu@flush{.5}\tabu@ignorehfil} + \Centering +}% \tabu@cell@C +\def\tabu@cell@R{% force alignment to right (ragged2e) + \tabu@cell@align + {\tabu@removehfil \RaggedLeft \tabu@flush 1\tabu@cellleft} + \tabu@ignorehfil + \RaggedLeft +}% \tabu@cell@R +\def\tabu@cell@J{% force justification (ragged2e) + \tabu@cell@align + {\justifying \tabu@cellleft} + {} + \justifying +}% \tabu@cell@J +\def\tabu@flush#1{% + \iftabu@colortbl % colortbl uses \hfill rather than \hfil + \hskip \ifnum13<\currentgrouptype \stretch{#1}% + \else \ifdim#1pt<\p@ \tabu@cellskip + \else \stretch{#1} + \fi\fi \relax + \else % array.sty + \ifnum 13<\currentgrouptype + \hfil \hskip1sp \relax \fi + \fi +}% \tabu@flush +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\tabu@removehfil} +% +% \cs\tabu@removehfil removes (eventually) the infinite stretchable glue inserted +% \emph{before} the cell (in the preamble of \cs\halign) to make the column alignment. +% +% \begin{macrocode} +\let\tabu@hfil \hfil +\let\tabu@hfill \hfill +\let\tabu@hskip \hskip +\def\tabu@removehfil{% + \iftabu@colortbl + \unkern \tabu@cellskip =\lastskip + \ifnum\gluestretchorder\tabu@cellskip =\tw@ \hskip-\tabu@cellskip + \else \tabu@cellskip \z@skip + \fi + \else + \ifdim\lastskip=1sp\unskip\fi + \ifnum\gluestretchorder\lastskip =\@ne + \hfilneg % \hfilneg for array.sty but not for colortbl... + \fi + \fi +}% \tabu@removehfil +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@ignorehfil} +% +% \cs\tabu@ignorehfil removes (eventually) the infinite stretchable glue inserted +% \emph{after} the cell (in the preamble of \cs\halign) to make the column alignment. +% +% \begin{macrocode} +\def\tabu@ignorehfil{\aftergroup \tabu@nohfil} +\def\tabu@nohfil{% \hfil -> do nothing + restore original \hfil + \def\hfil{\let\hfil \tabu@hfil}% local to (alignment template) group +}% \tabu@nohfil +\def\tabu@colortblalignments {% if colortbl + \def\tabu@nohfil{% + \def\hfil {\let\hfil \tabu@hfil}% local to (alignment template) group + \def\hfill {\let\hfill \tabu@hfill}% (colortbl uses \hfill) pfff... + \def\hskip ####1\relax{\let\hskip \tabu@hskip}}% local +}% \tabu@colortblalignments +% \end{macrocode} +% \end{macro} +% +% \subsection{Taking care of footnotes and \cs{arraybackslash}} +% \label{Taking care of footnotes and arraybackslash} +% +% \subsubsection{Footnotes and hyperfootnotes} +%¤<package>%% Taking care of footnotes and hyperfootnotes ---------------------- +% +% \begin{macro}{\tabu@footenotetext} +% +% The macros in case \xpackage{hyperref} is not used, or used with the option \textt{hyperfootnotes=false}: +% +% \begin{macrocode} +\long\def\tabu@footnotetext #1{% + \edef\@tempa{\the\tabu@footnotes + \noexpand\footnotetext [\the\csname c@\@mpfn\endcsname]}% + \global\tabu@footnotes\expandafter{\@tempa {#1}}}% +\long\def\tabu@xfootnotetext [#1]#2{% + \global\tabu@footnotes\expandafter{\the\tabu@footnotes + \footnotetext [{#1}]{#2}}} +\let\tabu@xfootnote \@xfootnote +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabu@Hy@ftntext} +% \begin{macro}{\tabu@Hy@xfootnote} +% +% The macros in case \xpackage{hyperref} is loaded with the option \textt{hyperfootnotes=true}: +% +% \begin{macrocode} +\long\def\tabu@Hy@ftntext{\tabu@Hy@ftntxt {\the \c@footnote }} +\long\def\tabu@Hy@xfootnote [#1]{% + \begingroup + \value\@mpfn #1\relax + \protected@xdef \@thefnmark {\thempfn}% + \endgroup + \@footnotemark \tabu@Hy@ftntxt {#1}% +}% \tabu@Hy@xfootnote +\long\def\tabu@Hy@ftntxt #1#2{% + \edef\@tempa{% + \the\tabu@footnotes + \begingroup + \value\@mpfn #1\relax + \noexpand\protected@xdef\noexpand\@thefnmark {\noexpand\thempfn}% + \expandafter \noexpand \expandafter + \tabu@Hy@footnotetext \expandafter{\Hy@footnote@currentHref}% + }% + \global\tabu@footnotes\expandafter{\@tempa {#2}% + \endgroup}% +}% \tabu@Hy@ftntxt +\long\def\tabu@Hy@footnotetext #1#2{% + \H@@footnotetext{% + \ifHy@nesting + \hyper@@anchor {#1}{#2}% + \else + \Hy@raisedlink{% + \hyper@@anchor {#1}{\relax}% + }% + \def\@currentHref {#1}% + \let\@currentlabelname \@empty + #2% + \fi + }% +}% \tabu@Hy@footnotetext +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{\cs{centering}, \cs{raggedright}, \cs{raggedleft} and \cs{@normalcr}} +%¤<package>%% No need for \arraybackslash ! ------------------------------------ +% +% Inside \env*{tabu}, no need to add \cs\arraybackslash after such commands. +% +% \begin{macrocode} +\def\tabu@latextwoe {% +\def\tabu@temp##1##2##3{{\toks@\expandafter{##2##3}\xdef##1{\the\toks@}}} +\tabu@temp \tabu@centering \centering \arraybackslash +\tabu@temp \tabu@raggedleft \raggedleft \arraybackslash +\tabu@temp \tabu@raggedright \raggedright \arraybackslash +}% \tabu@latextwoe +\def\tabu@raggedtwoe {% +\def\tabu@temp ##1##2##3{{\toks@\expandafter{##2##3}\xdef##1{\the\toks@}}} +\tabu@temp \tabu@Centering \Centering \arraybackslash +\tabu@temp \tabu@RaggedLeft \RaggedLeft \arraybackslash +\tabu@temp \tabu@RaggedRight \RaggedRight \arraybackslash +\tabu@temp \tabu@justifying \justifying \arraybackslash +}% \tabu@raggedtwoe +\def\tabu@normalcrbackslash{\let\\\@normalcr} +\def\tabu@trivlist{\expandafter\def\expandafter\@trivlist\expandafter{% + \expandafter\tabu@normalcrbackslash \@trivlist}} +% \end{macrocode} +% +% \subsubsection{Utilities: \env{tabu} \cs{fbox}} +%¤<package>%% Utilities: \fbox \fcolorbox and \tabudecimal ------------------- +% +% \cs\tabu@fbox works exactly like \LaTeX{} \cs\fbox but allows the syntax: \cs\fbox\cs\bgroup...\cs\egroup +% suitable for use inside tabular columns. \cs\fbox is \cs\let to \cs\tabu@fbox at the entry inside a \env*{tabu}. +% +% \begin{macrocode} +\def\tabu@fbox {\leavevmode\afterassignment\tabu@beginfbox \setbox\@tempboxa\hbox} +\def\tabu@beginfbox {\bgroup \kern\fboxsep + \bgroup\aftergroup\tabu@endfbox} +\def\tabu@endfbox {\kern\fboxsep\egroup\egroup + \@frameb@x\relax} +% \end{macrocode} +% +% \cs\tabu@fcolorbox works exactly like \xpackage{xcolor} \cs\fcolorbox but allows the syntax: +% +% \cs\fcolorbox\M*{frame color}\M*{background color}\cs\bgroup...\cs\egroup +% +% suitable for use insed tabular columns. \cs\fcolorbox is \cs\let to \cs\tabu@fcolorbox at the entry inside a \env*{tabu}. +% +% \begin{macrocode} +\def\tabu@color@b@x #1#2{\leavevmode \bgroup + \def\tabu@docolor@b@x{#1{#2\color@block{\wd\z@}{\ht\z@}{\dp\z@}\box\z@}}% + \afterassignment\tabu@begincolor@b@x \setbox\z@ \hbox +}% \tabu@color@b@x +\def\tabu@begincolor@b@x {\kern\fboxsep \bgroup + \aftergroup\tabu@endcolor@b@x \set@color} +\def\tabu@endcolor@b@x {\kern\fboxsep \egroup + \dimen@\ht\z@ \advance\dimen@ \fboxsep \ht\z@ \dimen@ + \dimen@\dp\z@ \advance\dimen@ \fboxsep \dp\z@ \dimen@ + \tabu@docolor@b@x \egroup +}% \tabu@endcolor@b@x +% \end{macrocode} +% +% \subsection{Corrections} +% \label{Corrections} +%¤<package>%% Corrections (arydshln, delarray, colortbl) ----------------------- +% +% \subsubsection(delarray compatibility fix){delarray comptability fix for \xpackage{colortbl} and \xpackage{arydshln}} +% +% Both \xpackage{colortbl} and \xpackage{arydshln} forgot the control sequence \cs\@arrayright +% which must be expanded by \cs\endarray. Originally defined for \xpackage{delarray}, this control +% sequence is used by \env{tabu} environments when \textt{tabu X} columns are present in the preamble. +% +% Here is the fix. We test if \cs\endarray contains \cs\@arrayright before modifying the control sequence, +% in case \xpackage{colortbl} and/or \xpackage{arydshln} modify their definition. +% +% \begin{macrocode} +\def\tabu@fix@arrayright {%% \@arrayright is missing from \endarray + \iftabu@colortbl + \ifdefined\adl@array % <colortbl + arydshln> + \def\tabu@endarray{% + \adl@endarray \egroup \adl@arrayrestore \CT@end \egroup %<original> + \@arrayright % <FC> + \gdef\@preamble{}}% <FC> + \else % <colortbl / no arydshln> + \def\tabu@endarray{% + \crcr \egroup \egroup %<original> + \@arrayright % <FC> + \gdef\@preamble{}\CT@end}% + \fi + \else + \ifdefined\adl@array % <arydshln / no colortbl> + \def\tabu@endarray{% + \adl@endarray \egroup \adl@arrayrestore \egroup %<original> + \@arrayright % <FC> + \gdef\@preamble{}}% <FC> + \else % <no arydshln / no colotbl + \@arrayright missing> + \PackageWarning{tabu} + {\string\@arrayright\space is missing from the + \MessageBreak definition of \string\endarray. + \MessageBreak Comptability with delarray.sty is broken.}% + \fi\fi +}% \tabu@fix@arrayright +% \end{macrocode} +% +% \subsubsection{arydshln @ columns} +% +% \begin{macrocode} +\def\tabu@adl@xarraydashrule #1#2#3{% + \ifnum\@lastchclass=\adl@class@start\else + \ifnum\@lastchclass=\@ne\else + \ifnum\@lastchclass=5 \else % <FC> @-arg (class 5) and !-arg (class 1) + \adl@leftrulefalse \fi\fi % must be treated the same + \fi + \ifadl@zwvrule\else \ifadl@inactive\else + \@addtopreamble{\vrule\@width\arrayrulewidth + \@height\z@ \@depth\z@}\fi \fi + \ifadl@leftrule + \@addtopreamble{\adl@vlineL{\CT@arc@}{\adl@dashgapcolor}% + {\number#1}#3}% + \else \@addtopreamble{\adl@vlineR{\CT@arc@}{\adl@dashgapcolor}% + {\number#2}#3} + \fi +}% \tabu@adl@xarraydashrule +% \end{macrocode} +% +% \subsubsection{arydshln, colors without \xpackage{colortbl} and empty \textt p columns} +% +% \xpackage{arydshln} redefines \cs\@endpbox for \textt p columns. The definition is stored in \cs\adl@act@endpbox. +% Here it is: +% +% \begin{Verb*} +% \unskip \ifhmode \nobreak +% \vrule\@width\z@\@height\z@\@depth\dp\@arstrutbox +% \fi +% \egroup \adl@colhtdp \box\adl@box \hfil +% \end{Verb*} +% +% The \cs\vrule inserted is exactly what package \xpackage{array} calls: \cs\@finalstrut\cs\@arstrutbox. +% +% However, just like in \xfile{array.sty}, this array-\textt{strut} should be inserted inconditionnally, +% and \cs\ifhmode applies only to \cs\nobreak (misplaced \cs\fi in \xpackage{arydshln} definition). +% +% Finally, \xpackage{arydshln} is not compatible with colors in columns, such that: \textt{>\M*{\cs\color\M*{red}}p{3in}}, +% Unless \xpackage{colortbl} is also loaded, the color group is missing. +% +% Fixed inside \env*{tabu}. +% +% \begin{macrocode} +\def\tabu@adl@act@endpbox {% + \unskip \ifhmode \nobreak \fi \@finalstrut \@arstrutbox + \egroup \egroup + \adl@colhtdp \box\adl@box \hfil +}% \tabu@adl@act@endpbox +\def\tabu@adl@fix {% + \let\adl@xarraydashrule \tabu@adl@xarraydashrule % <fix> arydshln + \let\adl@act@endpbox \tabu@adl@act@endpbox % <fix> arydshln + \let\adl@act@@endpbox \tabu@adl@act@endpbox % <fix> arydshln + \let\@preamerror \@preamerr % <fix> arydshln +}% \tabu@adl@fix +% \end{macrocode} +% +% \subsubsection{\xpackage{longtable} \cs{@startpbox}: \cs{everypar} needed} +%¤<package>%% Correction for longtable' \@startbox definition ------------------ +%¤<package>%% => \everypar is ``missing'' : TeX should be in vertical mode +% +% \begin{macro}{\tabu@LT@startpbox} +% +% The leading strut should be inserted at \cs\everypar in order for \cs\tabulinesep to work +% (otherwise, \TeX{} is in horizontal mode and \cs\nointerlineskip breaks). +% +% \begin{macrocode} +\def\tabu@LT@startpbox #1{% + \bgroup + \let\@footnotetext\LT@p@ftntext + \setlength\hsize{#1}% + \@arrayparboxrestore + \everypar{% + \vrule \@height \ht\@arstrutbox \@width \z@ + \everypar{}}% +}% \tabu@LT@startpbox +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Package options and Initialisation} +% \label{Package options and Initialisation} +% +% \subsubsection{\cs{tracingtabu} and the package options} +%¤<package>%% \tracingtabu and the package options ------------------ +% +% \begin{macro}{delarray (package option)} +% +% The \textt{delarray} package option is only there for convenience: it simply loads +% the \Xpackage{delarray} package. +% +% \begin{macrocode} +\DeclareOption{delarray}{\AtEndOfPackage{\RequirePackage{delarray}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{linegoal (package option)} +% +% The \textt{linegoal} package option only sets \cs\tabudefaulttarget to be equal to +% \cs\linegoal. The required package \Xpackage{linegoal} is loaded. +% +% \begin{macrocode} +\DeclareOption{linegoal}{% + \AtEndOfPackage{% + \RequirePackage{linegoal}[2010/12/07]% + \let\tabudefaulttarget \linegoal% \linegoal is \linewidth if not pdfTeX +}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\scantokens (package option)} +% +% The \textt{scantokens} package option makes \env{tabu} equal to \env{tabu\stform*}. +% +% \begin{macrocode} +\DeclareOption{scantokens}{\tabuscantokenstrue} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tracingtabu} +% \begin{macro}{debugshow (package option)} +% +% \cs\tracingtabu is the same as the package option \hyperref[debugshow]{\textt{debugshow}}. +% +% \begin{macrocode} +\DeclareOption{debugshow}{\AtEndOfPackage{\tracingtabu=\tw@}} +\def\tracingtabu {\begingroup\@ifnextchar=% + {\afterassignment\tabu@tracing\count@} + {\afterassignment\tabu@tracing\count@1\relax}} +\def\tabu@tracing{\expandafter\endgroup + \expandafter\tabu@tr@cing \the\count@ \relax +}% \tabu@tracing +\def\tabu@tr@cing #1\relax {% + \ifnum#1>\thr@@ \let\tabu@tracinglines\message + \else \let\tabu@tracinglines\@gobble + \fi + \ifnum#1>\tw@ \let\tabu@DBG \tabu@@DBG + \def\tabu@mkarstrut {\tabu@DBG@arstrut}% + \tabustrutrule 1.5\p@ + \else \let\tabu@DBG \@gobble + \def\tabu@mkarstrut {\tabu@arstrut}% + \tabustrutrule \z@ + \fi + \ifnum#1>\@ne \let\tabu@debug \message + \else \let\tabu@debug \@gobble + \fi + \ifnum#1>\z@ + \let\tabu@message \message + \let\tabu@tracing@save \tabu@message@save + \let\tabu@starttimer \tabu@pdftimer + \else + \let\tabu@message \@gobble + \let\tabu@tracing@save \@gobble + \let\tabu@starttimer \relax + \fi +}% \tabu@tr@cing +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{Initialisation and setup \cs{AtBeginDocument}} +%¤<package>%% Setup \AtBeginDocument +% +% At the end of the \xpackage{tabu} package: +% \begin{itemize} +% \item \cs\tracingtabu is set to $0$: this initialises the message commands. Eventually,, t +% he value will be overwritten by the \textt{debugshow} package option later. +% \item \cs\everyrow is set to empty: this initialises the process at \cs\everycr to the default process, +% \item a new \emph{empty} line style is defined, to be equivalent to \cs\hline: this creates the \emph{default leaders}, +% which will be used if a line style specification cannot be parsed successfully.\\ +% Then this default line style is set to be the current one. +% \end{itemize} +% +% At Begin Document,a fix for \Xpackage{arydshln} and \Xpackage{colortbl} comptability with \Xpackage{delarray} +% shortcuts available inside \env{tabu}: requirement for this fix is checked by \cs\tabu@fix@arrayright. +% +% Then the switch \cs\iftabu@colortbl is set. +% +% Finally, the \env*{longtabu} is defined only if the \Xpackage{longtable} package is detected. +% +% \begin{macrocode} +\AtBeginDocument{\tabu@AtBeginDocument} +\def\tabu@AtBeginDocument{\let\tabu@AtBeginDocument \@undefined + \ifdefined\arrayrulecolor \tabu@colortbltrue % <colortbl> + \tabu@colortblalignments % different glues are used + \else \tabu@colortblfalse \fi + \ifdefined\CT@arc@ \else \let\CT@arc@ \relax \fi + \ifdefined\CT@drsc@\else \let\CT@drsc@ \relax \fi + \let\tabu@arc@L \CT@arc@ \let\tabu@drsc@L \CT@drsc@ + \ifodd 1\ifcsname siunitx_table_collect_begin:Nn\endcsname % <siunitx: ok> + \expandafter\ifx + \csname siunitx_table_collect_begin:Nn\endcsname\relax 0\fi\fi\relax + \tabu@siunitxtrue + \else \let\tabu@maybesiunitx \@firstofone % <not siunitx: setup> + \let\tabu@siunitx \tabu@nosiunitx + \tabu@siunitxfalse + \fi + \ifdefined\adl@array % <arydshln> + \else \let\tabu@adl@fix \relax + \let\tabu@adl@endtrial \@empty \fi + \ifdefined\longtable % <longtable> + \else \let\longtabu \tabu@nolongtabu \fi + \ifdefined\cellspacetoplimit \tabu@warn@cellspace\fi + \csname\ifcsname ifHy@hyperfootnotes\endcsname % <hyperfootnotes> + ifHy@hyperfootnotes\else iffalse\fi\endcsname + \let\tabu@footnotetext \tabu@Hy@ftntext + \let\tabu@xfootnote \tabu@Hy@xfootnote \fi + \ifdefined\FV@DefineCheckEnd% <fancyvrb> + \tabu@fancyvrb \fi + \ifdefined\color % <color / xcolor> + \let\tabu@color \color + \def\tabu@leavevmodecolor ##1{% + \def\tabu@leavevmodecolor {\leavevmode ##1}% + }\expandafter\tabu@leavevmodecolor\expandafter{\color}% + \else + \let\tabu@color \tabu@nocolor + \let\tabu@leavevmodecolor \@firstofone \fi + \tabu@latextwoe + \ifdefined\@raggedtwoe@everyselectfont % <ragged2e> + \tabu@raggedtwoe + \else + \let\tabu@cell@L \tabu@cell@l + \let\tabu@cell@R \tabu@cell@r + \let\tabu@cell@C \tabu@cell@c + \let\tabu@cell@J \tabu@cell@j \fi + \expandafter\in@ \expandafter\@arrayright \expandafter{\endarray}% + \ifin@ \let\tabu@endarray \endarray + \else \tabu@fix@arrayright \fi% <fix for colortbl & arydshln (delarray)> + \everyrow{}% +}% \tabu@AtBeginDocument +\def\tabu@warn@cellspace{% + \PackageWarning{tabu}{% + Package cellspace has some limitations + \MessageBreak And redefines some macros of array.sty. + \MessageBreak Please use \string\tabulinesep\space to control + \MessageBreak vertical spacing of lines inside tabu environnement}% +}% \tabu@warn@cellspace +% \end{macrocode} +% +%¤<package>%% tabu Package initialisation +% +% \cs\ProcessOption\stform* is much quicker than without the star... +% +% \begin{macrocode} +\tabuscantokensfalse +\let\tabu@arc@G \relax +\let\tabu@drsc@G \relax +\let\tabu@evr@G \@empty +\let\tabu@rc@G \@empty +\def\tabu@ls@G {\tabu@linestyle@}% +\let\tabu@@rowfontreset \@empty % <init> +\let\tabu@@celllalign \@empty +\let\tabu@@cellralign \@empty +\let\tabu@@cellleft \@empty +\let\tabu@@cellright \@empty +\def\tabu@naturalXmin {\z@} +\def\tabu@naturalXmax {\z@} +\let\tabu@rowfontreset \@empty +\def\tabulineon {4pt}\let\tabulineoff \tabulineon +\tabu@everyrowtrue +\ifdefined\pdfelapsedtime % <pdfTeX> + \def\tabu@pdftimer {\xdef\tabu@starttime{\the\pdfelapsedtime}}% +\else \let\tabu@pdftimer \relax \let\tabu@message@etime \relax +\fi +\tracingtabu=\z@ +\newtabulinestyle {=\maxdimen}% creates the 'factory' settings \tabu@linestyle@ +\tabulinestyle{} +\taburowcolors{} +\let\tabudefaulttarget \linewidth +\ProcessOptions* % \ProcessOptions* is quicker ! +% \end{macrocode} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \restoregeometry +% \bookmarksetup{bold*} +% \pagesetup*{ +% left/offset+=5mm,right/offset+=12mm, +% head/color=LightSteelBlue, +% head/left=\moveleft1cm\vbox to0pt{\vss\setbox0=\null\ht0=0pt\wd0=\paperwidth\dp0=\headheight\rlap{\colorbox{GhostWhite}{\box0}}}\vskip-\headheight \TabU\ \ i\,n\,d\,e\,x, +% } +% +% \begin{thebibliography}{9} +% +% \bibitem{array} +% \textit{A new implementation of \LaTeX's \env{tabular} and \env{array} environments} by Frank Mittelbach\\ +% 2008/09/09 v2.4c -- Tabular extension package (FMi) \\ +% \href{http://www.tex.ac.uk/tex-archive/help/Catalogue/entries/array.html}{\nolinkurl{CTAN:help/Catalogue/entries/array.html}} +% +% \bibitem{varwidth} +% \textit{The \xpackage{varwidth} package} by Donald Arseneau \\ +% 2009/03/30 ver 0.92 -- Variable-width minipages \\ +% \href{http://www.ctan.org/tex-archive/help/Catalogue/entries/varwidth.html}{\nolinkurl{CTAN:help/Catalogue/entries/varwidth.html}} +% +% \bibitem{enumitem-zref} +% \textit{The \xpackage{enumitem-zref} package} by \FC \\ +% 2011/02/18 ver 1.8 -- Extended references for enumitem pkg \\ +% \href{http://www.ctan.org/tex-archive/help/Catalogue/entries/enumitem-zref.html}{\nolinkurl{CTAN:help/Catalogue/entries/enumitem-zref.html}} +% \label{enumitem-zref} +% +% \end{thebibliography} +% +% \begin{History} +% +% \def\Version#1{\HistVersion{#1}\setitemize{name=#1,leftmargin=2em}\itemize} +% \addtocontents{toc}{\tocsetup{subsection/font+=\string\smaller}} +% \sectionformat\subsection[hang]{ +% font=\normalsize\bfseries\pkgcolor, +% top=\smallskipamount, +% bottom=0pt, +% break=\addpenalty{-\csname @medpenalty\endcsname}, +% } +% \robustify\textbf \robustify\xfile ^^A\HistLabel does \edef on \@currentlabel (\protected@edef required !!) +% +% \begin{Version}{2011/02/26 v2.8}\HistLabel{2.8} +% \item Bug in the starred version (with \cs\scantokens) of the \env*{longtabu\stform*}. +% \end{Version} +% +% \begin{Version}{2011/02/25 v2.7}\HistLabel{2.7} +% \item Automatic \cs\par after the end of the \env*{tabu} used with its default target is removed in case of \env{tabu spread}: this was a bug. +% \item Some \cs\ignorespaces were missing (in \cs\everyrow, \cs\taburulecolor, \cs\taburowcolors and \cs\tabulinestyle). +% \end{Version} +% +% \begin{Version}{2011/02/24 v2.6}\HistLabel{2.6} +% \item \cs\savetabu now also saves \cs\tabulinesep (\ie \cs\abovetabulinesep and \cs\belowtabulinesep) +% \item Bug fixed for \hyperref[Custom environments]{custom-environments} when nested. +% \item \cs\taburulecolor works even if \xpackage{colortbl} is not loaded for the \env*{tabu}. \\ +% This is now the same for the \env*{longtabu}. +% \end{Version} +% +% \begin{Version}{2011/02/19 v2.5}\HistLabel{2.5} +% \item Bug fixed for \cs\pdfelapsedtime when compilation without \hologo{pdfTeX}. +% \item Modification of \cs\@finalstrut (``null-rule'' added) to avoid problems with \cs\columncolor. +% \end{Version} +% +% \begin{Version}{2011/02/17 v2.4}\HistLabel{2.4} +% \item Documentation revisited +% \end{Version} +% +% \begin{Version}{2011/02/13 v2.3}\HistLabel{2.3} +% \item Fixed two bugs for nested \env*{tabu}: when using \cs\rowfont and when \env{tabu} is nested inside \env{longtabu} +% \end{Version} +% +% \begin{Version}{2011/02/12 v2.2 -- \texorpdf\textbf{New implementation - Absolutely no modification of \texorpdf\xfile{array.sty}}}\HistLabel{2.2} +% \item \thispackage has been totally reimplemented, including the algorithms. \\ +% In particular, outside of the \env*{tabu}, absolutely none of the macros of \xfile{array.sty}, +% (and obviously none of \LaTeX{}) is modified. \\[\medskipamount] +% The process has been completely reinvented: \env{tabu} follows a path along different modes (or strategies) +% measuring natural width of cells, fixing \textt X column widths, measuring vertical length of rows and then printing the +% final tabular. The process is optimized, especially in the case of nested \env{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. \\[\medskipamount] +% \env{tabu} now systematically collects the environment body. But with \cs\scantokens, it is possible to insert verbatim +% material inside the columns: use \env{tabu*} instead of \env{tabu}, for the outer most tabular. +% +% \item New: \cs\firsthline and \cs\lasthline can draw multiple lines, and there is an option to +% set \cs\extratabsurround instantly, and locally. +% \item New: \cs\taburulecolor with a good behaviour with groupings (like \cs\everyrow) +% \item Modification: \cs\tabulinestyle sets the line style for the tabu, \cs\newtabulinestyle defines +% a new line style. +% \end{Version} +% +% {\tabulinestyle{2pt on 3pt Crimson off 3pt GreenYellow} \tabulinesep=2mm\bfseries +% \begin{tabu}to\linewidth{|*5{X[c]|[.4pt on2pt off3pt GreenYellow]}X[c]|} \tabucline- +% This & is & the & new & \TabU & package \\ \tabucline- +% \end{tabu}\par +% } +% +% \begin{Version}{2011/01/19 v2.1}\HistLabel{2.1} +% \item \hyperref[vertical spacing.sec]{Vertical spacing} had a bug with \textt{longtabu} and paragraph columns.\\ +% Fixed. +% \item New: \cs\everyrow. +% \item Fix a bug of \cs\rowfont when using \Xpackage{siunitx} \textt S columns. +% \item Some code optimisation. +% \item To do (if possible): a syntax \textt{X[6mc]{S[...]}} to ``embed'' \Xpackage{siunitx} \textt S column +% inside \env{tabu} and \env{longtabu} \textt X columns... +% \end{Version} +% +% \begin{Version}{2011/01/18 v2.0}\HistLabel{2.0} +% \item \hyperref[vertical spacing.sec]{Vertical spacing} of lines implemented ! See \cs\tabulinesep and \cs\extrarowsep. +% \item \csref{tabulinestyle}: user defined line style can now be used inside the optional argument of the \texttbf\textbar\M*[...] +% preamble token. +% \item \texttbf\textbar\M*[...] is now allowed in \cs\multicolumn preamble inside \env{tabu} environment. +% \item Bug fixed inside \cs\tabu@prepnexttok (again !!! - a difficult case !) +% \item Incompatibility of package \Xpackage{cellspace} with \env{tabu spread} and \env{tabu} with \label{cellspace limitations} +% \refitem{item:Negativ width coefficients}[negativ coefficients] for \textt X columns with has been lifted. \\ +% However, as said in the documentation of package \xpackage{cellspace}, \textt S column modifier does not work +% in the case of nested tabulars. \\ +% The \textt S column modifier becomes \textt C when the package \Xpackage{siunitx} is loaded +% (see \xpackage{siunitx} documentation). \\ +% Moreover, \xpackage{cellspace} does not work with \xpackage{color} or \xpackage{xcolor} and paragraph column types !! \\ +% Finally, \xpackage{cellspace} redefines \textbf{globally} \cs\@startpbox and \cs\@endpbox and is +% therefore not fully compatible with \xfile{array.sty} and therefore with \thispackage. \\ +% For all those reasons, \thispackage displays a warning to discourage the use of \xpackage{cellspace} with the +% \textt{tabu} environment. +% \end{Version} +% +% \begin{Version}{2011/01/15 v1.9}\HistLabel{1.9} +% \item Bug in \cs\savetabu when used inside \env{longtabu}... +% \item Bug when \env{tabu} with \textt X column is nested inside \env{lontabu}. +% \item Documentation (\cs\rowfont was missing in the \hyperref[Summary]{summary}). +% \end{Version} +% +% \begin{Version}{2010/12/28 v1.8}\HistLabel{1.8} +% \item \csref{tracingtabu} / \hyperref[debugshow]{\textt{debugshow}} package option:\\ +% reporting of the time elapsed during trials (if \cs\pdfelapsedtime and thus \hologo{pdfTeX} is available) \\ +% Slight modifications for better reporting on the \xext{log} file. +% \item Fix a bug when \cs\savetabu is used after \cs\multicolumn (\cs\multicolumn globally redefines \cs\@preamble). +% \item Fix a bug with \cs\tabucline and \cs\CT@arc@ (\xpackage{colortbl}). +% \item Better privacy of columns types specifically defined for \env{tabu}. +% \item Improvement in the rewritting process (but only very few people should notice...) +% \item Documentation. +% \end{Version} +% +% \begin{Version}{2010/12/18 v1.7}\HistLabel{1.7} +% \item Code optimisation +% \item Modification in the columns rewritting process (bug with some new column types defined by the user). +% \end{Version} +% +% \begin{Version}{2010/12/07 v1.5}\HistLabel{1.5} +% \item Implementation of negativ width coefficients for \textt X columns (cf. \refitem{tabu X columns,2}[\nameref*{tabu X columns} point \ref]). +% \item Columns natural widths computation (for \textt{tabu spread} with \textt X columns and negativ coefficients) +% is based on the code of the \xpackage{varwidth} package by Donald Arseneau. +% \item \env{longtabu} is now provided, based on the \xpackage{longtable} package by David Carlisle. \\ +% \env{longtabu} can be used just like \textt{tabu}. +% \item Vertical lines can be used whatever the catcode of \textbf\textbar\ is. +% \item \cs\savetabu reports saved informations in the \xext{log} (\hyperref[debugshow]{\textt{debugshow}} option). +% \item \cs\savetabu ... \cs\usetabu now restores the \cs\halign preamble rather than the \env{tabu} preamble! \\ +% \cs\preamble can be use in the \textt{tabu} preamble to restore a \texttt{tabu} preamble. +% \item \cs\tabucline is more robust with ``special'' preambles containing\, \texttbf>\, or\, \texttbf<\, tokens. \\ +% \cs\tabucline now takes care of \cs\arrayrulecolor (package \xpackage{colortbl}). +% \item \Xpackage{enumitem-zref} package has been added to the documentation (see the link \refitem{2010/12/07 v1.5,1}[point 1]) +% \item Optimisation of some parts of the code. +% \end{Version} +% +% \begin{Version}{2010/11/22 v1.4}\HistLabel{1.4} +% \item Compatibility improvement with \xpackage{linegoal} for the syntax: \\ +% \cs{begin}\M*{tabu}\textt{ to\cs\linegoal}\M*{...} +% \item Hyper footnotes now work correctly. +% \item Fix a bug when using colored vertical lines in \env{tabu} in math mode. +% \item Fix a bug with vertical lines and \xpackage{colortbl} \cs\arrayrulecolor specification. +% \item Fix a compatibility bug with \xpackage{arydshln}: when nesting a tabular that use +% vertical dashed lines (\xpackage{arydshln}) inside \env{tabu spread} with \textt X columns. +% \end{Version} +% +% \begin{Version}{2010/11/18 v1.3}\HistLabel{1.3} +% \item Fix a bug that may appear in \cs\tabucline depending on the preamble due to arbitrary \cs\countdef. +% \item Improvement in the use of \cs\everycr: no \cs\global stuff. Thus bug fixed when nesting \env{tabu} +% inside \hologo{AmS}-\textt{align} environment for example. Same issue with \cs\rowfont which now works +% without global modification of \cs\everycr. +% \item No phantom line is added to \env{tabu} but a command \cs\tabuphantomline is provided for this purpose +% (required with \cs\multicolumn in some cases). +% \item Improvement on vertical alignment. +% \item To do: an example file to test a wide range of possibilities... +% \item Documentation. +% \end{Version} +% +% \begin{Version}{2010/11/15 v1.2}\HistLabel{1.2} +% \item Improvement in parameters parsing for optional parameters (\textt\textbar\ and \cs\tabucline). +% \item Modification / optimization in \cs\tabu@prepnext@tok. +% \item Modification of \cs\tabucline to get better results with \textt m columns (\textt{X[m]}) +% and also when \cs\minrowclearance $>0$ (package \xpackage{colortbl}). +% \end{Version} +% +% \begin{Version}{2010/10/28 v1.1}\HistLabel{1.1} +% \item First version. +% \end{Version} +% +% \end{History} +% +% +% \PrintIndex +% +% \Finale
\ No newline at end of file diff --git a/macros/latex/contrib/tabu/tabu.pdf b/macros/latex/contrib/tabu/tabu.pdf Binary files differnew file mode 100644 index 0000000000..b61fb84ed7 --- /dev/null +++ b/macros/latex/contrib/tabu/tabu.pdf diff --git a/macros/latex/contrib/tabu/tabu.sty b/macros/latex/contrib/tabu/tabu.sty new file mode 100644 index 0000000000..e62cacff5f --- /dev/null +++ b/macros/latex/contrib/tabu/tabu.sty @@ -0,0 +1,2602 @@ +%%TABU-FIXED +%% +%% tabu : 2019-01-11 - tabu : Flexible LaTeX tabulars +%% +%% ********************************************************************************************** +%% \begin{tabu} { preamble } => default target: \linewidth or \linegoal +%% \begin{tabu} to <dimen>{ preamble } => target specified +%% \begin{tabu} spread <dimen>{ preamble } => target relative to the ``natural width'' +%% +%% tabu works in text and in math modes. +%% +%% X columns: automatic width ajustment + horizontal and vertical alignment +%% \begin{tabu} { X[4c] X[1c] X[-2ml] } +%% +%% Horizontal lines and / or leaders: +%% \hline\hline => double horizontal line +%% \firsthline\hline => for nested tabulars +%% \lasthline\hline => for nested tabulars +%% \tabucline[line spec]{column-column} => ``funny'' lines (dash/leader) +%% Automatic lines / leaders : +%% \everyrow{\hline\hline} +%% +%% Vertical lines and / or leaders: +%% \begin{tabu} { |[3pt red] X[4c] X[1c] X[-2ml] |[3pt blue] } +%% \begin{tabu} { |[3pt red] X[4c] X[1c] X[-2ml] |[3pt on 2pt off 4pt blue] } +%% +%% Fixed vertical spacing adjustment: +%% \extrarowheight=<dimen> \extrarowdepth=<dimen> +%% or: \extrarowsep=<dimen> => may be prefixed by \global +%% +%% Dynamic vertical spacing adjustment: +%% \abovetabulinesep=<dimen> \belowtabulinesep=<dimen> +%% or: \tabulinesep=<dimen> => may be prefixed by \global +%% +%% delarray.sty shortcuts: in math and text modes +%% \begin{tabu} .... \({ preamble }\) +%% +%% Algorithms reports: +%% \tracingtabu=1 \tracingtabu=2 +%% +%% ********************************************************************************************** +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either +%% version 1.3 of this license or (at your option) any later +%% version. The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% +%% +%%TABU-FIXED +%% tabu : Flexible LaTeX tabulars +%% lppl copyright 2010-2011 by FC <florent.chervet@free.fr> +%% +%% Updated 2019-01-11 +%% Copyright 2019 tabu-fixed github group (LaTeX3 Project members) +%% Please report any issues at https://github.com/tabu-fixed/tabu +%% + +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{tabu}[2019/01/11 v2.9 - flexible LaTeX tabulars (FC+tabu-fixed)] +\RequirePackage{array}[2008/09/09] +\RequirePackage{varwidth}[2009/03/30] +\AtEndOfPackage{\tabu@AtEnd \let\tabu@AtEnd \@undefined} +\let\tabu@AtEnd\@empty +\def\TMP@EnsureCode#1={% + \edef\tabu@AtEnd{\tabu@AtEnd + \catcode#1 \the\catcode#1}% + \catcode#1=% +}% \TMP@EnsureCode +\TMP@EnsureCode 33 = 12 % ! +\TMP@EnsureCode 58 = 12 % : (for siunitx) +\TMP@EnsureCode124 = 12 % | +\TMP@EnsureCode 36 = 3 % $ = math shift +\TMP@EnsureCode 38 = 4 % & = tab alignmment character +\TMP@EnsureCode 32 = 10 % space +\TMP@EnsureCode 94 = 7 % ^ +\TMP@EnsureCode 95 = 8 % _ +%% Constants -------------------------------------------------------- +\newcount \c@taburow \def\thetaburow {\number\c@taburow} +\newcount \tabu@nbcols +\newcount \tabu@cnt +\newcount \tabu@Xcol +\let\tabu@start \@tempcnta +\let\tabu@stop \@tempcntb +\newcount \tabu@alloc \tabu@alloc=\m@ne +\newcount \tabu@nested +\def\tabu@alloc@{\global\advance\tabu@alloc \@ne \tabu@nested\tabu@alloc} +\newdimen \tabu@target +\newdimen \tabu@spreadtarget +\newdimen \tabu@naturalX +\newdimen \tabucolX +\let\tabu@DELTA \@tempdimc +\let\tabu@thick \@tempdima +\let\tabu@on \@tempdimb +\let\tabu@off \@tempdimc +\newdimen \tabu@Xsum +\newdimen \extrarowdepth +\newdimen \abovetabulinesep +\newdimen \belowtabulinesep +\newdimen \tabustrutrule \tabustrutrule \z@ +\newtoks \tabu@thebody +\newtoks \tabu@footnotes +\newsavebox \tabu@box +\newsavebox \tabu@arstrutbox +\newsavebox \tabu@hleads +\newsavebox \tabu@vleads +\newif \iftabu@colortbl +\newif \iftabu@siunitx +\newif \iftabu@measuring +\newif \iftabu@spread +\newif \iftabu@negcoef +\newif \iftabu@everyrow +\def\tabu@everyrowtrue {\global\let\iftabu@everyrow \iftrue} +\def\tabu@everyrowfalse{\global\let\iftabu@everyrow \iffalse} +\newif \iftabu@long +\newif \iftabuscantokens +\def\tabu@rescan {\tabu@verbatim \scantokens } +%% Utilities (for internal usage) ----------------------------------- +\def\tabu@gobblespace #1 {#1} +\def\tabu@gobbletoken #1#2{#1} +\def\tabu@gobbleX{\futurelet\@let@token \tabu@gobblex} +\def\tabu@gobblex{\if ^^J\noexpand\@let@token \expandafter\@gobble + \else\ifx \@sptoken\@let@token + \expandafter\tabu@gobblespace\expandafter\tabu@gobbleX + \fi\fi +}% \tabu@gobblex +\def\tabu@X{^^J} +{\obeyspaces +\global\let\tabu@spxiii= % saves an active space (for \ifx) +\gdef\tabu@@spxiii{ }} +\def\tabu@ifenvir {% only for \multicolumn + \expandafter\tabu@if@nvir\csname\@currenvir\endcsname +}% \tabu@ifenvir +\def\tabu@if@nvir #1{\csname @\ifx\tabu#1first\else + \ifx\longtabu#1first\else + second\fi\fi oftwo\endcsname +}% \tabu@ifenvir +\def\tabu@modulo #1#2{\numexpr\ifnum\numexpr#1=\z@ 0\else #1-(#1-(#2-1)/2)/(#2)*(#2)\fi} +{\catcode`\&=3 +\gdef\tabu@strtrim #1{% #1 = control sequence to trim + \ifodd 1\ifx #1\@empty \else \ifx #1\space \else 0\fi \fi + \let\tabu@c@l@r \@empty \let#1\@empty + \else \expandafter \tabu@trimspaces #1\@nnil + \fi +}% \tabu@strtrim +\gdef\tabu@trimspaces #1\@nnil{\let\tabu@c@l@r=#2\tabu@firstspace .#1& }% +\gdef\tabu@firstspace #1#2#3 &{\tabu@lastspace #2#3&} +\gdef\tabu@lastspace #1{\def #3{#1}% + \ifx #3\tabu@c@l@r \def\tabu@c@l@r{\protect\color{#1}}\expandafter\remove@to@nnil \fi + \tabu@trimspaces #1\@nnil} +}% \catcode +\def\tabu@sanitizearg #1#2{{% + \csname \ifcsname if@safe@actives\endcsname % <babel> + @safe@activestrue\else + relax\fi \endcsname + \edef#2{#1}\tabu@strtrim#2\@onelevel@sanitize#2% + \expandafter}\expandafter\def\expandafter#2\expandafter{#2}% +}% \tabu@sanitizearg + +%%TABU-FIXED +\def\tabu@textbar#1{% + \begingroup + \newlinechar \m@ne% + \endlinechar \m@ne + \everyeof{\noexpand}% + \edef\:{\expandafter\noexpand\scantokens{|}}% + \expandafter + \endgroup + \expandafter #1% + \:% +}% \tabu@textbar +\def\tabu@everyrow@bgroup{\iftabu@everyrow \begingroup \else \noalign{\ifnum0=`}\fi \fi} +\def\tabu@everyrow@egroup{% + \iftabu@everyrow \expandafter \endgroup \the\toks@ + \else \ifnum0=`{\fi}% + \fi +}% \tabu@everyrow@egroup +\def\tabu@arstrut {\global\setbox\@arstrutbox \hbox{\vrule + height \arraystretch \dimexpr\ht\strutbox+\extrarowheight + depth \arraystretch \dimexpr\dp\strutbox+\extrarowdepth + width \z@}% +}% \tabu@arstrut +\def\tabu@rearstrut {% + \@tempdima \arraystretch\dimexpr\ht\strutbox+\extrarowheight \relax + \@tempdimb \arraystretch\dimexpr\dp\strutbox+\extrarowdepth \relax + \ifodd 1\ifdim \ht\@arstrutbox=\@tempdima + \ifdim \dp\@arstrutbox=\@tempdimb 0 \fi\fi + \tabu@mkarstrut + \fi +}% \tabu@rearstrut +\def\tabu@@DBG #1{\ifdim\tabustrutrule>\z@ \color{#1}\fi} +\def\tabu@DBG@arstrut {\global\setbox\@arstrutbox + \hbox to\z@{\hbox to\z@{\hss + {\tabu@DBG{cyan}\vrule + height \arraystretch \dimexpr\ht\strutbox+\extrarowheight + depth \z@ + width \tabustrutrule}\kern-\tabustrutrule + {\tabu@DBG{pink}\vrule + height \z@ + depth \arraystretch \dimexpr\dp\strutbox+\extrarowdepth + width \tabustrutrule}}}% +}% \tabu@DBG@arstrut +\def\tabu@save@decl{\toks\count@ \expandafter{\the\toks\expandafter\count@ + \@nextchar}}% +\def\tabu@savedecl{\ifcat$\d@llarend\else + \let\save@decl \tabu@save@decl \fi % no inversion of tokens in text mode +}% \tabu@savedecl +\def\tabu@finalstrut #1{\unskip\ifhmode\nobreak\fi\vrule height\z@ depth\z@ width\z@} +\newcommand*\tabuDisableCommands {\g@addto@macro\tabu@trialh@@k } +\let\tabu@trialh@@k \@empty +\def\tabu@nowrite #1#{{\afterassignment}\toks@} +\let\tabu@write\write +\let\tabu@immediate\immediate +\def\tabu@WRITE{\begingroup + \def\immediate\write{\aftergroup\endgroup + \tabu@immediate\tabu@write}% +}% \tabu@WRITE +\expandafter\def\expandafter\tabu@GenericError\expandafter{% + \expandafter\tabu@WRITE\GenericError} +\def\tabu@warn{\tabu@WRITE\PackageWarning{tabu}} +\def\tabu@noxfootnote [#1]{\@gobble} +\def\tabu@nocolor #1#{\@gobble} +\newcommand*\tabu@norowcolor[2][]{} +\def\tabu@maybesiunitx #1{\def\tabu@temp{#1}% + \futurelet\@let@token \tabu@m@ybesiunitx} +\def\tabu@m@ybesiunitx #1{\def\tabu@m@ybesiunitx {% + \ifx #1\@let@token \let\tabu@cellleft \@empty \let\tabu@cellright \@empty \fi + \tabu@temp}% \tabu@m@ybesiunitx +}\expandafter\tabu@m@ybesiunitx \csname siunitx_table_collect_begin:Nn\endcsname +\def\tabu@celllalign@def #1{\def\tabu@celllalign{\tabu@maybesiunitx{#1}}}% +%% Fixed vertical spacing adjustment: \extrarowsep ------------------ +\newcommand*\extrarowsep{\edef\tabu@C@extra{\the\numexpr\tabu@C@extra+1}% + \iftabu@everyrow \aftergroup\tabu@Gextra + \else \aftergroup\tabu@n@Gextra + \fi + \@ifnextchar={\tabu@gobbletoken\tabu@extra} \tabu@extra +}% \extrarowsep +\def\tabu@extra {\@ifnextchar_% + {\tabu@gobbletoken{\tabu@setextra\extrarowheight \extrarowdepth}} + {\ifx ^\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setextra\extrarowdepth \extrarowheight}}% + \else \let\tabu@temp \@empty + \afterassignment \tabu@setextrasep \extrarowdepth + \fi \tabu@temp}% +}% \tabu@extra +\def\tabu@setextra #1#2{\def\tabu@temp{\tabu@extr@#1#2}\afterassignment\tabu@temp#2} +\def\tabu@extr@ #1#2{\@ifnextchar^% + {\tabu@gobbletoken{\tabu@setextra\extrarowdepth \extrarowheight}} + {\ifx _\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setextra\extrarowheight \extrarowdepth}}% + \else \let\tabu@temp \@empty + \tabu@Gsave \tabu@G@extra \tabu@C@extra \extrarowheight \extrarowdepth + \fi \tabu@temp}% +}% \tabu@extr@ +\def\tabu@setextrasep {\extrarowheight=\extrarowdepth + \tabu@Gsave \tabu@G@extra \tabu@C@extra \extrarowheight \extrarowdepth +}% \tabu@setextrasep +\def\tabu@Gextra{\ifx \tabu@G@extra\@empty \else {\tabu@Rextra}\fi} +\def\tabu@n@Gextra{\ifx \tabu@G@extra\@empty \else \noalign{\tabu@Rextra}\fi} +\def\tabu@Rextra{\tabu@Grestore \tabu@G@extra \tabu@C@extra} +\let\tabu@C@extra \z@ +\let\tabu@G@extra \@empty +%% Dynamic vertical spacing adjustment: \tabulinesep ---------------- +\newcommand*\tabulinesep{\edef\tabu@C@linesep{\the\numexpr\tabu@C@linesep+1}% + \iftabu@everyrow \aftergroup\tabu@Glinesep + \else \aftergroup\tabu@n@Glinesep + \fi + \@ifnextchar={\tabu@gobbletoken\tabu@linesep} \tabu@linesep +}% \tabulinesep +\def\tabu@linesep {\@ifnextchar_% + {\tabu@gobbletoken{\tabu@setsep\abovetabulinesep \belowtabulinesep}} + {\ifx ^\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setsep\belowtabulinesep \abovetabulinesep}}% + \else \let\tabu@temp \@empty + \afterassignment \tabu@setlinesep \abovetabulinesep + \fi \tabu@temp}% +}% \tabu@linesep +\def\tabu@setsep #1#2{\def\tabu@temp{\tabu@sets@p#1#2}\afterassignment\tabu@temp#2} +\def\tabu@sets@p #1#2{\@ifnextchar^% + {\tabu@gobbletoken{\tabu@setsep\belowtabulinesep \abovetabulinesep}} + {\ifx _\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setsep\abovetabulinesep \belowtabulinesep}}% + \else \let\tabu@temp \@empty + \tabu@Gsave \tabu@G@linesep \tabu@C@linesep \abovetabulinesep \belowtabulinesep + \fi \tabu@temp}% +}% \tabu@sets@p +\def\tabu@setlinesep {\belowtabulinesep=\abovetabulinesep + \tabu@Gsave \tabu@G@linesep \tabu@C@linesep \abovetabulinesep \belowtabulinesep +}% \tabu@setlinesep +\def\tabu@Glinesep{\ifx \tabu@G@linesep\@empty \else {\tabu@Rlinesep}\fi} +\def\tabu@n@Glinesep{\ifx \tabu@G@linesep\@empty \else \noalign{\tabu@Rlinesep}\fi} +\def\tabu@Rlinesep{\tabu@Grestore \tabu@G@linesep \tabu@C@linesep} +\let\tabu@C@linesep \z@ +\let\tabu@G@linesep \@empty +%% \global\extrarowsep and \global\tabulinesep ------------------- +\def\tabu@Gsave #1#2#3#4{\xdef#1{#1% + \toks#2{\toks\the\currentgrouplevel{\global#3\the#3\global#4\the#4}}}% +}% \tabu@Gsave +\def\tabu@Grestore#1#2{% + \toks#2{}#1\toks\currentgrouplevel\expandafter{\expandafter}\the\toks#2\relax + \ifcat$\the\toks\currentgrouplevel$\else + \global\let#1\@empty \global\let#2\z@ + \the\toks\currentgrouplevel + \fi +}% \tabu@Grestore +%% Setting code for every row --------------------------------------- +\newcommand*\everyrow{\tabu@everyrow@bgroup + \tabu@start \z@ \tabu@stop \z@ \tabu@evrstartstop +}% \everyrow +\def\tabu@evrstartstop {\@ifnextchar^% + {\afterassignment \tabu@evrstartstop \tabu@stop=}% + {\ifx ^\@let@token + \afterassignment\tabu@evrstartstop \tabu@start=% + \else \afterassignment\tabu@everyr@w \toks@ + \fi}% +}% \tabu@evrstartstop +\def\tabu@everyr@w {% + \xdef\tabu@everyrow{% + \noexpand\tabu@everyrowfalse + \let\noalign \relax + \noexpand\tabu@rowfontreset + \iftabu@colortbl \noexpand\tabu@rc@ \fi % \taburowcolors + \let\noexpand\tabu@docline \noexpand\tabu@docline@evr + \the\toks@ + \noexpand\tabu@evrh@@k + \noexpand\tabu@rearstrut + \global\advance\c@taburow \@ne}% + \iftabu@everyrow \toks@\expandafter + {\expandafter\def\expandafter\tabu@evr@L\expandafter{\the\toks@}\ignorespaces}% + \else \xdef\tabu@evr@G{\the\toks@}% + \fi + \tabu@everyrow@egroup +}% \tabu@everyr@w +\def\tabu@evr {\def\tabu@evrh@@k} % for internal use only +\tabu@evr{} +%% line style and leaders ------------------------------------------- +\newcommand*\newtabulinestyle [1]{% + {\@for \@tempa :=#1\do{\expandafter\tabu@newlinestyle \@tempa==\@nil}}% +}% \newtabulinestyle +\def\tabu@newlinestyle #1=#2=#3\@nil{\tabu@getline {#2}% + \tabu@sanitizearg {#1}\@tempa + \ifodd 1\ifx \@tempa\@empty \ifdefined\tabu@linestyle@ 0 \fi\fi + \global\expandafter\let + \csname tabu@linestyle@\@tempa \endcsname =\tabu@thestyle \fi +}% \tabu@newlinestyle +\newcommand*\tabulinestyle [1]{\tabu@everyrow@bgroup \tabu@getline{#1}% + \iftabu@everyrow + \toks@\expandafter{\expandafter \def \expandafter + \tabu@ls@L\expandafter{\tabu@thestyle}\ignorespaces}% + \gdef\tabu@ls@{\tabu@ls@L}% + \else + \global\let\tabu@ls@G \tabu@thestyle + \gdef\tabu@ls@{\tabu@ls@G}% + \fi + \tabu@everyrow@egroup +}% \tabulinestyle +\newcommand*\taburulecolor{\tabu@everyrow@bgroup \tabu@textbar \tabu@rulecolor} +\def\tabu@rulecolor #1{\toks@{}% + \def\tabu@temp #1##1#1{\tabu@ruledrsc{##1}}\@ifnextchar #1% + \tabu@temp + \tabu@rulearc +}% \tabu@rulecolor +\def\tabu@ruledrsc #1{\edef\tabu@temp{#1}\tabu@strtrim\tabu@temp + \ifx \tabu@temp\@empty \def\tabu@temp{\tabu@rule@drsc@ {}{}}% + \else \edef\tabu@temp{\noexpand\tabu@rule@drsc@ {}{\tabu@temp}}% + \fi + \tabu@temp +}% \tabu@ruledrsc@ +\def\tabu@ruledrsc@ #1#{\tabu@rule@drsc@ {#1}} +\def\tabu@rule@drsc@ #1#2{% + \iftabu@everyrow + \ifx \\#1#2\\\toks@{\let\CT@drsc@ \relax}% + \else \toks@{\def\CT@drsc@{\color #1{#2}}}% + \fi + \else + \ifx \\#1#2\\\global\let\CT@drsc@ \relax + \else \gdef\CT@drsc@{\color #1{#2}}% + \fi + \fi + \tabu@rulearc +}% \tabu@rule@drsc@ +\def\tabu@rulearc #1#{\tabu@rule@arc@ {#1}} +\def\tabu@rule@arc@ #1#2{% + \iftabu@everyrow + \ifx \\#1#2\\\toks@\expandafter{\the\toks@ \def\CT@arc@{}}% + \else \toks@\expandafter{\the\toks@ \def\CT@arc@{\color #1{#2}}}% + \fi + \toks@\expandafter{\the\toks@ + \let\tabu@arc@L \CT@arc@ + \let\tabu@drsc@L \CT@drsc@ + \ignorespaces}% + \else + \ifx \\#1#2\\\gdef\CT@arc@{}% + \else \gdef\CT@arc@{\color #1{#2}}% + \fi + \global\let\tabu@arc@G \CT@arc@ + \global\let\tabu@drsc@G \CT@drsc@ + \fi + \tabu@everyrow@egroup +}% \tabu@rule@arc@ +\def\taburowcolors {\tabu@everyrow@bgroup \@testopt \tabu@rowcolors 1} +\def\tabu@rowcolors [#1]#2#{\tabu@rowc@lors{#1}{#2}} +\def\tabu@rowc@lors #1#2#3{% + \toks@{}\@defaultunits \count@ =\number0#2\relax \@nnil + \@defaultunits \tabu@start =\number0#1\relax \@nnil + \ifnum \count@<\tw@ \count@=\tw@ \fi + \advance\tabu@start \m@ne + \ifnum \tabu@start<\z@ \tabu@start \z@ \fi + \tabu@rowcolorseries #3\in@..\in@ \@nnil +}% \tabu@rowcolors +\def\tabu@rowcolorseries #1..#2\in@ #3\@nnil {% + \ifx \in@#1\relax + \iftabu@everyrow \toks@{\def\tabu@rc@{}\let\tabu@rc@L \tabu@rc@}% + \else \gdef\tabu@rc@{}\global\let\tabu@rc@G \tabu@rc@ + \fi + \else + \ifx \\#2\\\tabu@rowcolorserieserror \fi + \tabu@sanitizearg{#1}\tabu@temp + \tabu@sanitizearg{#2}\@tempa + \advance\count@ \m@ne + \iftabu@everyrow + \def\tabu@rc@ ##1##2##3##4{\def\tabu@rc@{% + \ifnum ##2=\c@taburow + \definecolorseries{tabu@rcseries@\the\tabu@nested}{rgb}{last}{##3}{##4}\fi + \ifnum \c@taburow<##2 \else + \ifnum \tabu@modulo {\c@taburow-##2}{##1+1}=\z@ + \resetcolorseries[{##1}]{tabu@rcseries@\the\tabu@nested}\fi + \xglobal\colorlet{tabu@rc@\the\tabu@nested}{tabu@rcseries@\the\tabu@nested!!+}% + \rowcolor{tabu@rc@\the\tabu@nested}\fi}% + }\edef\x{\noexpand\tabu@rc@ {\the\count@} + {\the\tabu@start} + {\tabu@temp} + {\@tempa}% + }\x + \toks@\expandafter{\expandafter\def\expandafter\tabu@rc@\expandafter{\tabu@rc@}}% + \toks@\expandafter{\the\toks@ \let\tabu@rc@L \tabu@rc@ \ignorespaces}% + \else % inside \noalign + \definecolorseries{tabu@rcseries@\the\tabu@nested}{rgb}{last}{\tabu@temp}{\@tempa}% + \expandafter\resetcolorseries\expandafter[\the\count@]{tabu@rcseries@\the\tabu@nested}% + \xglobal\colorlet{tabu@rc@\the\tabu@nested}{tabu@rcseries@\the\tabu@nested!!+}% + \let\noalign \relax \rowcolor{tabu@rc@\the\tabu@nested}% + \def\tabu@rc@ ##1##2{\gdef\tabu@rc@{% + \ifnum \tabu@modulo {\c@taburow-##2}{##1+1}=\@ne + \resetcolorseries[{##1}]{tabu@rcseries@\the\tabu@nested}\fi + \xglobal\colorlet{tabu@rc@\the\tabu@nested}{tabu@rcseries@\the\tabu@nested!!+}% + \rowcolor{tabu@rc@\the\tabu@nested}}% + }\edef\x{\noexpand\tabu@rc@{\the\count@}{\the\c@taburow}}\x + \global\let\tabu@rc@G \tabu@rc@ + \fi + \fi + \tabu@everyrow@egroup +}% \tabu@rowcolorseries +\tabuDisableCommands {\let\tabu@rc@ \@empty } +\def\tabu@rowcolorserieserror {\PackageError{tabu} + {Invalid syntax for \string\taburowcolors + \MessageBreak Please look at the documentation!}\@ehd +}% \tabu@rowcolorserieserror +\newcommand*\tabureset {% + \tabulinesep=\z@ \extrarowsep=\z@ \extratabsurround=\z@ + \tabulinestyle{}\everyrow{}\taburulecolor||{}\taburowcolors{}% +}% \tabureset +%% Parsing the line styles ------------------------------------------ +\def\tabu@getline #1{\begingroup + \csname \ifcsname if@safe@actives\endcsname % <babel> + @safe@activestrue\else + relax\fi \endcsname + \edef\tabu@temp{#1}\tabu@sanitizearg{#1}\@tempa + \let\tabu@thestyle \relax + \ifcsname tabu@linestyle@\@tempa \endcsname + \edef\tabu@thestyle{\endgroup + \def\tabu@thestyle{\expandafter\noexpand + \csname tabu@linestyle@\@tempa\endcsname}% + }\tabu@thestyle + \else \expandafter\tabu@definestyle \tabu@temp \@nil + \fi +}% \tabu@getline +\def\tabu@definestyle #1#2\@nil {\endlinechar \m@ne \makeatletter + \tabu@thick \maxdimen \tabu@on \maxdimen \tabu@off \maxdimen + \let\tabu@c@lon \@undefined \let\tabu@c@loff \@undefined + \ifodd 1\ifcat .#1\else\ifcat\relax #1\else 0\fi\fi % catcode 12 or non expandable cs + \def\tabu@temp{\tabu@getparam{thick}}% + \else \def\tabu@temp{\tabu@getparam{thick}\maxdimen}% + \fi + {% + \let\tabu@ \relax + \def\:{\obeyspaces \tabu@oXIII \tabu@commaXIII \edef\:}% (space active \: happy ;-)) + \scantokens{\:{\tabu@temp #1#2 \tabu@\tabu@}}% + \expandafter}\expandafter + \def\expandafter\:\expandafter{\:}% line spec rewritten now ;-) + \def\;{\def\:}% + \scantokens\expandafter{\expandafter\;\expandafter{\:}}% space is now inactive (catcode 10) + \let\tabu@ \tabu@getcolor \:% all arguments are ready now ;-) + \ifdefined\tabu@c@lon \else \let\tabu@c@lon\@empty \fi + \ifx \tabu@c@lon\@empty \def\tabu@c@lon{\CT@arc@}\fi + \ifdefined\tabu@c@loff \else \let\tabu@c@loff \@empty \fi + \ifdim \tabu@on=\maxdimen \ifdim \tabu@off<\maxdimen + \tabu@on \tabulineon \fi\fi + \ifdim \tabu@off=\maxdimen \ifdim \tabu@on<\maxdimen + \tabu@off \tabulineoff \fi\fi + \ifodd 1\ifdim \tabu@off=\maxdimen \ifdim \tabu@on=\maxdimen 0 \fi\fi + \in@true % <leaders> + \else \in@false % <rule> + \fi + \ifdim\tabu@thick=\maxdimen \def\tabu@thick{\arrayrulewidth}% + \else \edef\tabu@thick{\the\tabu@thick}% + \fi + \edef \tabu@thestyle ##1##2{\endgroup + \def\tabu@thestyle{% + \ifin@ \noexpand\tabu@leadersstyle {\tabu@thick} + {\the\tabu@on}{##1} + {\the\tabu@off}{##2}% + \else \noexpand\tabu@rulesstyle + {##1\vrule width \tabu@thick}% + {##1\leaders \hrule height \tabu@thick \hfil}% + \fi}% + }\expandafter \expandafter + \expandafter \tabu@thestyle \expandafter + \expandafter \expandafter + {\expandafter\tabu@c@lon\expandafter}\expandafter{\tabu@c@loff}% +}% \tabu@definestyle +{\catcode`\O=\active \lccode`\O=`\o \catcode`\,=\active + \lowercase{\gdef\tabu@oXIII {\catcode`\o=\active \let O=\tabu@oxiii}} + \gdef\tabu@commaXIII {\catcode`\,=\active \let ,=\space} +}% \catcode +\def\tabu@oxiii #1{% + \ifcase \ifx n#1\z@ \else + \ifx f#1\@ne\else + \tw@ \fi\fi + \expandafter\tabu@onxiii + \or \expandafter\tabu@ofxiii + \else o% + \fi#1}% +\def\tabu@onxiii #1#2{% + \ifcase \ifx !#2\tw@ \else + \ifcat.\noexpand#2\z@ \else + \ifx \tabu@spxiii#2\@ne\else + \tw@ \fi\fi\fi + \tabu@getparam{on}#2\expandafter\@gobble + \or \expandafter\tabu@onxiii % (space is active) + \else o\expandafter\@firstofone + \fi{#1#2}}% +\def\tabu@ofxiii #1#2{% + \ifx #2f\expandafter\tabu@offxiii + \else o\expandafter\@firstofone + \fi{#1#2}} +\def\tabu@offxiii #1#2{% + \ifcase \ifx !#2\tw@ \else + \ifcat.\noexpand#2\z@ \else + \ifx\tabu@spxiii#2\@ne \else + \tw@ \fi\fi\fi + \tabu@getparam{off}#2\expandafter\@gobble + \or \expandafter\tabu@offxiii % (space is active) + \else o\expandafter\@firstofone + \fi{#1#2}} +\def\tabu@getparam #1{\tabu@ \csname tabu@#1\endcsname=} +\def\tabu@getcolor #1{% \tabu@ <- \tabu@getcolor after \edef + \ifx \tabu@#1\else % no more spec + \let\tabu@theparam=#1\afterassignment \tabu@getc@l@r #1\fi +}% \tabu@getcolor +\def\tabu@getc@l@r #1\tabu@ {% + \def\tabu@temp{#1}\tabu@strtrim \tabu@temp + \ifx \tabu@temp\@empty + \else%\ifcsname \string\color@\tabu@temp \endcsname % if the color exists + \ifx \tabu@theparam \tabu@off \let\tabu@c@loff \tabu@c@l@r + \else \let\tabu@c@lon \tabu@c@l@r + \fi + %\else \tabu@warncolour{\tabu@temp}% + \fi%\fi + \tabu@ % next spec +}% \tabu@getc@l@r +\def\tabu@warncolour #1{\PackageWarning{tabu} + {Color #1 is not defined. Default color used}% +}% \tabu@warncolour +\def\tabu@leadersstyle #1#2#3#4#5{\def\tabu@leaders{{#1}{#2}{#3}{#4}{#5}}% + \ifx \tabu@leaders\tabu@leaders@G \else + \tabu@LEADERS{#1}{#2}{#3}{#4}{#5}\fi +}% \tabu@leadersstyle +\def\tabu@rulesstyle #1#2{\let\tabu@leaders \@undefined + \gdef\tabu@thevrule{#1}\gdef\tabu@thehrule{#2}% +}% \tabu@rulesstyle +%% The leaders boxes ------------------------------------------------ +\def\tabu@LEADERS #1#2#3#4#5{%% width, dash, dash color, gap, gap color + {\let\color \tabu@color % => during trials -> \color = \tabu@nocolor + {% % but the leaders boxes should have colors ! + \def\@therule{\vrule}\def\@thick{height}\def\@length{width}% + \def\@box{\hbox}\def\@unbox{\unhbox}\def\@elt{\wd}% + \def\@skip{\hskip}\def\@ss{\hss}\def\tabu@leads{\tabu@hleads}% + \tabu@l@@d@rs {#1}{#2}{#3}{#4}{#5}% + \global\let\tabu@thehleaders \tabu@theleaders + }% + {% + \def\@therule{\hrule}\def\@thick{width}\def\@length{height}% + \def\@box{\vbox}\def\@unbox{\unvbox}\def\@elt{\ht}% + \def\@skip{\vskip}\def\@ss{\vss}\def\tabu@leads{\tabu@vleads}% + \tabu@l@@d@rs {#1}{#2}{#3}{#4}{#5}% + \global\let\tabu@thevleaders \tabu@theleaders + }% + \gdef\tabu@leaders@G{{#1}{#2}{#3}{#4}{#5}}% + }% +}% \tabu@LEADERS +\def\tabu@therule #1#2{\@therule \@thick#1\@length\dimexpr#2/2 \@depth\z@} +\def\tabu@l@@d@rs #1#2#3#4#5{%% width, dash, dash color, gap, gap color + \global\setbox \tabu@leads=\@box{% + {#3\tabu@therule{#1}{#2}}% + \ifx\\#5\\\@skip#4\else{#5\tabu@therule{#1}{#4*2}}\fi + {#3\tabu@therule{#1}{#2}}}% + \global\setbox\tabu@leads=\@box to\@elt\tabu@leads{\@ss + {#3\tabu@therule{#1}{#2}}\@unbox\tabu@leads}% + \edef\tabu@theleaders ##1{\def\noexpand\tabu@theleaders {% + {##1\tabu@therule{#1}{#2}}% + \xleaders \copy\tabu@leads \@ss + \tabu@therule{0pt}{-#2}{##1\tabu@therule{#1}{#2}}}% + }\tabu@theleaders{#3}% +}% \tabu@l@@d@rs +%% \tabu \endtabu \tabu* \longtabu \endlongtabu \longtabu* ---------- +\newcommand*\tabu {\tabu@longfalse + \ifmmode \def\tabu@ {\array}\def\endtabu {\endarray}% + \else \def\tabu@ {\tabu@tabular}\def\endtabu {\endtabular}\fi + \expandafter\let\csname tabu*\endcsname \tabu + \expandafter\def\csname endtabu*\endcsname{\endtabu}% + \tabu@spreadfalse \tabu@negcoeffalse \tabu@settarget +}% {tabu} +\let\tabu@tabular \tabular % <For LyX: some users redefine \tabular...> +\expandafter\def\csname tabu*\endcsname{\tabuscantokenstrue \tabu} +\newcommand*\longtabu {\tabu@longtrue + \ifmmode\PackageError{tabu}{longtabu not allowed in math mode}\fi + \def\tabu@{\longtable}\def\endlongtabu{\endlongtable}% + \LTchunksize=\@M + \expandafter\let\csname tabu*\endcsname \tabu + \expandafter\def\csname endlongtabu*\endcsname{\endlongtabu}% + \let\LT@startpbox \tabu@LT@startpbox % \everypar{ array struts } + \tabu@spreadfalse \tabu@negcoeffalse \tabu@settarget +}% {longtabu} +\expandafter\def\csname longtabu*\endcsname{\tabuscantokenstrue \longtabu} +\def\tabu@nolongtabu{\PackageError{tabu} + {longtabu requires the longtable package}\@ehd} +%% Read the target and then : \tabular or \@array ------------------ +\def\tabu@settarget {\futurelet\@let@token \tabu@sett@rget } +\def\tabu@sett@rget {\tabu@target \z@ + \ifcase \ifx \bgroup\@let@token \z@ \else + \ifx \@sptoken\@let@token \@ne \else + \if t\@let@token \tw@ \else + \if s\@let@token \thr@@\else + \z@\fi\fi\fi\fi + \expandafter\tabu@begin + \or \expandafter\tabu@gobblespace\expandafter\tabu@settarget + \or \expandafter\tabu@to + \or \expandafter\tabu@spread + \fi +}% \tabu@sett@rget +\def\tabu@to to{\def\tabu@halignto{to}\tabu@gettarget} +\def\tabu@spread spread{\tabu@spreadtrue\def\tabu@halignto{spread}\tabu@gettarget} +\def\tabu@gettarget {\afterassignment\tabu@linegoaltarget \tabu@target } +\def\tabu@linegoaltarget {\futurelet\tabu@temp \tabu@linegoalt@rget } +\def\tabu@linegoalt@rget {% + \ifx \tabu@temp\LNGL@setlinegoal + \LNGL@setlinegoal \expandafter \@firstoftwo \fi % @gobbles \LNGL@setlinegoal + \tabu@begin +}% \tabu@linegoalt@rget +\def\tabu@begin #1#{% + \iftabu@measuring \expandafter\tabu@nestedmeasure \fi + \ifdim \tabu@target=\z@ \let\tabu@halignto \@empty + \else \edef\tabu@halignto{\tabu@halignto\the\tabu@target}% + \fi + \@testopt \tabu@tabu@ \tabu@aligndefault #1\@nil +}% \tabu@begin +\long\def\tabu@tabu@ [#1]#2\@nil #3{\tabu@setup + \def\tabu@align {#1}\def\tabu@savedpream{\NC@find #3}% + \tabu@ [\tabu@align ]#2{#3\tabu@rewritefirst }% +}% \tabu@tabu@ +\def\tabu@nestedmeasure {% + \ifodd 1\iftabu@spread \else \ifdim\tabu@target=\z@ \else 0 \fi\fi\relax + \tabu@spreadtrue + \else \begingroup \iffalse{\fi \ifnum0=`}\fi + \toks@{}\def\tabu@stack{b}% + \expandafter\tabu@collectbody\expandafter\tabu@quickrule + \expandafter\endgroup + \fi +}% \tabu@nestedmeasure +\def\tabu@quickrule {\indent\vrule height\z@ depth\z@ width\tabu@target} +%% \tabu@setup \tabu@init \tabu@indent +\def\tabu@setup{\tabu@alloc@ + \ifcase \tabu@nested + \ifmmode \else \iftabu@spread\else \ifdim\tabu@target=\z@ + \let\tabu@afterendpar \par + \fi\fi\fi + \def\tabu@aligndefault{c}\tabu@init \tabu@indent + \else % <nested tabu> + \def\tabu@aligndefault{t}\let\tabudefaulttarget \linewidth + \fi + \let\tabu@thetarget \tabudefaulttarget \let\tabu@restored \@undefined + \edef\tabu@NC@list{\the\NC@list}\NC@list{\NC@do \tabu@rewritefirst}% + \everycr{}\let\@startpbox \tabu@startpbox % for nested tabu inside longtabu... + \let\@endpbox \tabu@endpbox % idem " " " " " " + \let\@tabarray \tabu@tabarray % idem " " " " " " + \tabu@setcleanup \tabu@setreset +}% \tabu@setup +\def\tabu@init{\tabu@starttimer \tabu@measuringfalse + \edef\tabu@hfuzz {\the\dimexpr\hfuzz+1sp}\global\tabu@footnotes{}% + \let\firsthline \tabu@firsthline \let\lasthline \tabu@lasthline + \let\firstline \tabu@firstline \let\lastline \tabu@lastline + \let\hline \tabu@hline \let\@xhline \tabu@xhline + \let\color \tabu@color \let\@arstrutbox \tabu@arstrutbox + \iftabu@colortbl\else\let\LT@@hline \tabu@LT@@hline \fi + \tabu@trivlist %<restore \\=\@normalcr inside lists> + \let\@footnotetext \tabu@footnotetext \let\@xfootnotetext \tabu@xfootnotetext + \let\@xfootnote \tabu@xfootnote \let\centering \tabu@centering + \let\raggedright \tabu@raggedright \let\raggedleft \tabu@raggedleft + \let\tabudecimal \tabu@tabudecimal \let\Centering \tabu@Centering + \let\RaggedRight \tabu@RaggedRight \let\RaggedLeft \tabu@RaggedLeft + \let\justifying \tabu@justifying \let\rowfont \tabu@rowfont + \let\fbox \tabu@fbox \let\color@b@x \tabu@color@b@x + \let\tabu@@everycr \everycr \let\tabu@@everypar \everypar + \let\tabu@prepnext@tokORI \prepnext@tok\let\prepnext@tok \tabu@prepnext@tok + \let\tabu@multicolumnORI\multicolumn \let\multicolumn \tabu@multicolumn + \let\tabu@startpbox \@startpbox % for nested tabu inside longtabu pfff !!! + \let\tabu@endpbox \@endpbox % idem " " " " " " " + \let\tabu@tabarray \@tabarray % idem " " " " " " " + \tabu@adl@fix \let\endarray \tabu@endarray % <fix> colortbl & arydshln (delarray) + \iftabu@colortbl\CT@everycr\expandafter{\expandafter\iftabu@everyrow \the\CT@everycr \fi}\fi +%%TABU-FIXED set up old version of array package \@classz to avoid recoding m (and X) here. (Partial fix only: may not cover all cases) + \let\tabu@classzORI\@classz \let\@classz \tabu@classz +%%TABU-FIXED set up \tabu@currentgrouptype +\def\tabu@currentgrouptype{\currentgrouptype}% +\ifx\color@begingroup\begingroup +\def\color@begingroup{\expandafter\begingroup\expandafter\def\expandafter + \tabu@currentgrouptype\expandafter{\the\currentgrouptype}}% +\fi +}% \tabu@init +\def\tabu@indent{% correction for indentation + \ifdim \parindent>\z@\ifx \linewidth\tabudefaulttarget + \everypar\expandafter{% + \the\everypar\everypar\expandafter{\the\everypar}% + \setbox\z@=\lastbox + \ifdim\wd\z@>\z@ \edef\tabu@thetarget + {\the\dimexpr -\wd\z@+\tabudefaulttarget}\fi + \box\z@}% + \fi\fi +}% \tabu@indent +\def\tabu@setcleanup {% saves last global assignments + \ifodd 1\ifmmode \else \iftabu@long \else 0\fi\fi\relax + \def\tabu@aftergroupcleanup{% + \def\tabu@aftergroupcleanup{\aftergroup\tabu@cleanup}}% + \else + \def\tabu@aftergroupcleanup{% + \aftergroup\aftergroup\aftergroup\tabu@cleanup + \let\tabu@aftergroupcleanup \relax}% + \fi + \let\tabu@arc@Gsave \tabu@arc@G + \let\tabu@arc@G \tabu@arc@L % <init> + \let\tabu@drsc@Gsave \tabu@drsc@G + \let\tabu@drsc@G \tabu@drsc@L % <init> + \let\tabu@ls@Gsave \tabu@ls@G + \let\tabu@ls@G \tabu@ls@L % <init> + \let\tabu@rc@Gsave \tabu@rc@G + \let\tabu@rc@G \tabu@rc@L % <init> + \let\tabu@evr@Gsave \tabu@evr@G + \let\tabu@evr@G \tabu@evr@L % <init> + \let\tabu@celllalign@save \tabu@celllalign + \let\tabu@cellralign@save \tabu@cellralign + \let\tabu@cellleft@save \tabu@cellleft + \let\tabu@cellright@save \tabu@cellright + \let\tabu@@celllalign@save \tabu@@celllalign + \let\tabu@@cellralign@save \tabu@@cellralign + \let\tabu@@cellleft@save \tabu@@cellleft + \let\tabu@@cellright@save \tabu@@cellright + \let\tabu@rowfontreset@save \tabu@rowfontreset + \let\tabu@@rowfontreset@save\tabu@@rowfontreset + \let\tabu@rowfontreset \@empty + \edef\tabu@alloc@save {\the\tabu@alloc}% restore at \tabu@reset + \edef\c@taburow@save {\the\c@taburow}% + \edef\tabu@naturalX@save {\the\tabu@naturalX}% + \let\tabu@naturalXmin@save \tabu@naturalXmin + \let\tabu@naturalXmax@save \tabu@naturalXmax + \let\tabu@mkarstrut@save \tabu@mkarstrut + \edef\tabu@clarstrut{% + \extrarowheight \the\dimexpr \ht\@arstrutbox-\ht\strutbox \relax + \extrarowdepth \the\dimexpr \dp\@arstrutbox-\dp\strutbox \relax + \let\noexpand\@arraystretch \@ne \noexpand\tabu@rearstrut}% +}% \tabu@setcleanup +\def\tabu@cleanup {\begingroup + \globaldefs\@ne \tabu@everyrowtrue + \let\tabu@arc@G \tabu@arc@Gsave + \let\CT@arc@ \tabu@arc@G + \let\tabu@drsc@G \tabu@drsc@Gsave + \let\CT@drsc@ \tabu@drsc@G + \let\tabu@ls@G \tabu@ls@Gsave + \let\tabu@ls@ \tabu@ls@G + \let\tabu@rc@G \tabu@rc@Gsave + \let\tabu@rc@ \tabu@rc@G + \let\CT@do@color \relax + \let\tabu@evr@G \tabu@evr@Gsave + \let\tabu@celllalign \tabu@celllalign@save + \let\tabu@cellralign \tabu@cellralign@save + \let\tabu@cellleft \tabu@cellleft@save + \let\tabu@cellright \tabu@cellright@save + \let\tabu@@celllalign \tabu@@celllalign@save + \let\tabu@@cellralign \tabu@@cellralign@save + \let\tabu@@cellleft \tabu@@cellleft@save + \let\tabu@@cellright \tabu@@cellright@save + \let\tabu@rowfontreset \tabu@rowfontreset@save + \let\tabu@@rowfontreset \tabu@@rowfontreset@save + \tabu@naturalX =\tabu@naturalX@save + \let\tabu@naturalXmax \tabu@naturalXmax@save + \let\tabu@naturalXmin \tabu@naturalXmin@save + \let\tabu@mkarstrut \tabu@mkarstrut@save + \c@taburow =\c@taburow@save + \ifcase \tabu@nested \tabu@alloc \m@ne\fi + \endgroup % <end of \globaldefs> + \ifcase \tabu@nested + \the\tabu@footnotes \global\tabu@footnotes{}% + \tabu@afterendpar \tabu@elapsedtime + \fi + \tabu@clarstrut + \everyrow\expandafter {\tabu@evr@G}% +}% \tabu@cleanup +\let\tabu@afterendpar \relax +\def\tabu@setreset {% + \edef\tabu@savedparams {% \relax for \tabu@message@save + \ifmmode \col@sep \the\arraycolsep + \else \col@sep \the\tabcolsep \fi \relax + \arrayrulewidth \the\arrayrulewidth \relax + \doublerulesep \the\doublerulesep \relax + \extratabsurround \the\extratabsurround \relax + \extrarowheight \the\extrarowheight \relax + \extrarowdepth \the\extrarowdepth \relax + \abovetabulinesep \the\abovetabulinesep \relax + \belowtabulinesep \the\belowtabulinesep \relax + \def\noexpand\arraystretch{\arraystretch}% + \ifdefined\minrowclearance \minrowclearance\the\minrowclearance\relax\fi}% + \begingroup + \@temptokena\expandafter{\tabu@savedparams}% => only for \savetabu / \usetabu + \ifx \tabu@arc@L\relax \else \tabu@setsave \tabu@arc@L \fi + \ifx \tabu@drsc@L\relax \else \tabu@setsave \tabu@drsc@L \fi + \tabu@setsave \tabu@ls@L \tabu@setsave \tabu@evr@L + \expandafter \endgroup \expandafter + \def\expandafter\tabu@saved@ \expandafter{\the\@temptokena + \let\tabu@arc@G \tabu@arc@L + \let\tabu@drsc@G \tabu@drsc@L + \let\tabu@ls@G \tabu@ls@L + \let\tabu@rc@G \tabu@rc@L + \let\tabu@evr@G \tabu@evr@L}% + \def\tabu@reset{\tabu@savedparams + \tabu@everyrowtrue \c@taburow \z@ + \let\CT@arc@ \tabu@arc@L + \let\CT@drsc@ \tabu@drsc@L + \let\tabu@ls@ \tabu@ls@L + \let\tabu@rc@ \tabu@rc@L + \global\tabu@alloc \tabu@alloc@save + \everyrow\expandafter{\tabu@evr@L}}% +}% \tabu@reset +\def\tabu@setsave #1{\expandafter\tabu@sets@ve #1\@nil{#1}} +\long\def\tabu@sets@ve #1\@nil #2{\@temptokena\expandafter{\the\@temptokena \def#2{#1}}} +%%TABU-FIXED define classz to use vcenter, reverting a change in array package +\let\tabu@classzORI\@classz +\def\tabu@classz{% +\ifx\tabu@prepnext@tok\prepnext@tok% in tabu +\expandafter\tabu@classz@oldarray +\else +\tabu@classzORI +\fi}% +\def\tabu@classz@oldarray{% + \@classx + \@tempcnta \count@ + \prepnext@tok + \@addtopreamble{\ifcase \@chnum + \hfil + \d@llarbegin + \insert@column + \d@llarend \hfil \or + \hskip1sp\d@llarbegin \insert@column \d@llarend \hfil \or + \hfil\hskip1sp\d@llarbegin \insert@column \d@llarend \or + $\vcenter + \@startpbox{\@nextchar}\insert@column \@endpbox $\or + \vtop \@startpbox{\@nextchar}\insert@column \@endpbox \or + \vbox \@startpbox{\@nextchar}\insert@column \@endpbox + \fi}\prepnext@tok}% +%% The Rewritting Process ------------------------------------------- +\def\tabu@newcolumntype #1{% + \expandafter\tabu@new@columntype + \csname NC@find@\string#1\expandafter\endcsname + \csname NC@rewrite@\string#1\endcsname + {#1}% +}% \tabu@newcolumntype +\def\tabu@new@columntype #1#2#3{% + \def#1##1#3{\NC@{##1}}% + \let#2\relax \newcommand*#2% +}% \tabu@new@columntype +\def\tabu@privatecolumntype #1{% + \expandafter\tabu@private@columntype + \csname NC@find@\string#1\expandafter\endcsname + \csname NC@rewrite@\string#1\expandafter\endcsname + \csname tabu@NC@find@\string#1\expandafter\endcsname + \csname tabu@NC@rewrite@\string#1\endcsname + {#1}% +}% \tabu@privatecolumntype +\def\tabu@private@columntype#1#2#3#4{% + \g@addto@macro\tabu@privatecolumns{\let#1#3\let#2#4}% + \tabu@new@columntype#3#4% +}% \tabu@private@columntype +\let\tabu@privatecolumns \@empty +\newcommand*\tabucolumn [1]{\expandafter \def \expandafter + \tabu@highprioritycolumns\expandafter{\tabu@highprioritycolumns + \NC@do #1}}% +\let\tabu@highprioritycolumns \@empty +%% The | ``column'' : rewriting process -------------------------- +\tabu@privatecolumntype |{\tabu@rewritevline} +\newcommand*\tabu@rewritevline[1][]{\tabu@vlinearg{#1}% + \expandafter \NC@find \tabu@rewritten} +\def\tabu@lines #1{% + \ifx|#1\else \tabu@privatecolumntype #1{\tabu@rewritevline}\fi + \NC@list\expandafter{\the\NC@list \NC@do #1}% +}% \tabu@lines@ +\def\tabu@vlinearg #1{% + \ifx\\#1\\\def\tabu@thestyle {\tabu@ls@}% + \else\tabu@getline {#1}% + \fi + \def\tabu@rewritten ##1{\def\tabu@rewritten{!{##1\tabu@thevline}}% + }\expandafter\tabu@rewritten\expandafter{\tabu@thestyle}% + \expandafter \tabu@keepls \tabu@thestyle \@nil +}% \tabu@vlinearg +\def\tabu@keepls #1\@nil{% + \ifcat $\@cdr #1\@nil $% + \ifx \relax#1\else + \ifx \tabu@ls@#1\else + \let#1\relax + \xdef\tabu@mkpreambuffer{\tabu@mkpreambuffer + \tabu@savels\noexpand#1}\fi\fi\fi +}% \tabu@keepls +\def\tabu@thevline {\begingroup + \ifdefined\tabu@leaders + \setbox\@tempboxa=\vtop to\dimexpr + \ht\@arstrutbox+\dp\@arstrutbox{{\tabu@thevleaders}}% + \ht\@tempboxa=\ht\@arstrutbox \dp\@tempboxa=\dp\@arstrutbox + \box\@tempboxa + \else + \tabu@thevrule + \fi \endgroup +}% \tabu@thevline +\def\tabu@savels #1{% + \expandafter\let\csname\string#1\endcsname #1% + \expandafter\def\expandafter\tabu@reset\expandafter{\tabu@reset + \tabu@resetls#1}}% +\def\tabu@resetls #1{\expandafter\let\expandafter#1\csname\string#1\endcsname}% +%% \multicolumn inside tabu environment ----------------------------- +\tabu@newcolumntype \tabu@rewritemulticolumn{% + \aftergroup \tabu@endrewritemulticolumn % after \@mkpream group + \NC@list{\NC@do *}\tabu@textbar \tabu@lines + \tabu@savedecl + \tabu@privatecolumns + \NC@list\expandafter{\the\expandafter\NC@list \tabu@NC@list}% + \let\tabu@savels \relax + \NC@find +}% \tabu@rewritemulticolumn +\def\tabu@endrewritemulticolumn{\gdef\tabu@mkpreambuffer{}\endgroup} +\def\tabu@multicolumn{\tabu@ifenvir \tabu@multic@lumn \tabu@multicolumnORI} +\long\def\tabu@multic@lumn #1#2#3{\multispan{#1}\begingroup + \tabu@everyrowtrue + \NC@list{\NC@do \tabu@rewritemulticolumn}% + \expandafter\@gobbletwo % gobbles \multispan{#1} + \tabu@multicolumnORI{#1}{\tabu@rewritemulticolumn #2}% + {\iftabuscantokens \tabu@rescan \else \expandafter\@firstofone \fi + {#3}}% +}% \tabu@multic@lumn +%% The X column(s): rewriting process ----------------------------- +\tabu@privatecolumntype X[1][]{\begingroup \tabu@siunitx{\endgroup \tabu@rewriteX {#1}}} +\def\tabu@nosiunitx #1{#1{}{}\expandafter \NC@find \tabu@rewritten } +\def\tabu@siunitx #1{\@ifnextchar \bgroup + {\tabu@rewriteX@Ss{#1}} + {\tabu@nosiunitx{#1}}} +\def\tabu@rewriteX@Ss #1#2{\@temptokena{}% + \@defaultunits \let\tabu@temp =#2\relax\@nnil + \ifodd 1\ifx S\tabu@temp \else \ifx s\tabu@temp \else 0 \fi\fi + \def\NC@find{\def\NC@find >####1####2<####3\relax{#1 {####1}{####3}% + }\expandafter\NC@find \the\@temptokena \relax + }\expandafter\NC@rewrite@S \@gobble #2\relax + \else \tabu@siunitxerror + \fi + \expandafter \NC@find \tabu@rewritten +}% \tabu@rewriteX@Ss +\def\tabu@siunitxerror {\PackageError{tabu}{Not a S nor s column ! + \MessageBreak X column can only embed siunitx S or s columns}\@ehd +}% \tabu@siunitxerror +\def\tabu@rewriteX #1#2#3{\tabu@Xarg {#1}{#2}{#3}% + \iftabu@measuring + \else \tabu@measuringtrue % first X column found in the preamble + \let\@halignto \relax \let\tabu@halignto \relax + \iftabu@spread \tabu@spreadtarget \tabu@target \tabu@target \z@ + \else \tabu@spreadtarget \z@ \fi + \ifdim \tabu@target=\z@ + \setlength\tabu@target \tabu@thetarget + \tabu@message{\tabu@message@defaulttarget}% + \else \tabu@message{\tabu@message@target}\fi + \fi +}% \tabu@rewriteX +\def\tabu@rewriteXrestore #1#2#3{\let\@halignto \relax + \def\tabu@rewritten{l}} +\def\tabu@Xarg #1#2#3{% + \advance\tabu@Xcol \@ne \let\tabu@Xlcr \@empty + \let\tabu@Xdisp \@empty \let\tabu@Xmath \@empty + \ifx\\#1\\% <shortcut when no option> + \def\tabu@rewritten{p}\tabucolX \p@ % <default coef = 1> + \else + \let\tabu@rewritten \@empty \let\tabu@temp \@empty \tabucolX \z@ + \tabu@Xparse {}#1\relax + \fi + \tabu@Xrewritten{#2}{#3}% +}% \tabu@Xarg +\def\tabu@Xparse #1{\futurelet\@let@token \tabu@Xtest} +\expandafter\def\expandafter\tabu@Xparsespace\space{\tabu@Xparse{}} +\def\tabu@Xtest{% + \ifcase \ifx \relax\@let@token \z@ \else + \if ,\@let@token \m@ne\else + \if p\@let@token 1\else + \if m\@let@token 2\else + \if b\@let@token 3\else + \if l\@let@token 4\else + \if c\@let@token 5\else + \if r\@let@token 6\else + \if j\@let@token 7\else + \if L\@let@token 8\else + \if C\@let@token 9\else + \if R\@let@token 10\else + \if J\@let@token 11\else + \ifx \@sptoken\@let@token 12\else + \if .\@let@token 13\else + \if -\@let@token 13\else + \ifcat $\@let@token 14\else + 15\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\relax + \or \tabu@Xtype {p}% + \or \tabu@Xtype {m}% + \or \tabu@Xtype {b}% + \or \tabu@Xalign \raggedright\relax + \or \tabu@Xalign \centering\relax + \or \tabu@Xalign \raggedleft\relax + \or \tabu@Xalign \tabu@justify\relax + \or \tabu@Xalign \RaggedRight\raggedright + \or \tabu@Xalign \Centering\centering + \or \tabu@Xalign \RaggedLeft\raggedleft + \or \tabu@Xalign \justifying\tabu@justify + \or \expandafter \tabu@Xparsespace + \or \expandafter \tabu@Xcoef + \or \expandafter \tabu@Xm@th + \or \tabu@Xcoef{}% + \else\expandafter \tabu@Xparse + \fi +}% \tabu@Xtest +\def\tabu@Xalign #1#2{% + \ifx \tabu@Xlcr\@empty \else \PackageWarning{tabu} + {Duplicate horizontal alignment specification}\fi + \ifdefined#1\def\tabu@Xlcr{#1}\let#1\relax + \else \def\tabu@Xlcr{#2}\let#2\relax\fi + \expandafter\tabu@Xparse +}% \tabu@Xalign +\def\tabu@Xtype #1{% + \ifx \tabu@rewritten\@empty \else \PackageWarning{tabu} + {Duplicate vertical alignment specification}\fi + \def\tabu@rewritten{#1}\expandafter\tabu@Xparse +}% \tabu@Xtype +\def\tabu@Xcoef#1{\edef\tabu@temp{\tabu@temp#1}% + \afterassignment\tabu@Xc@ef \tabu@cnt\number\if-#10\fi +}% \tabu@Xcoef +\def\tabu@Xc@ef{\advance\tabucolX \tabu@temp\the\tabu@cnt\p@ + \tabu@Xparse{}% +}% \tabu@Xc@ef +\def\tabu@Xm@th #1{\futurelet \@let@token \tabu@Xd@sp} +\def\tabu@Xd@sp{\let\tabu@Xmath=$% + \ifx $\@let@token \def\tabu@Xdisp{\displaystyle}% + \expandafter\tabu@Xparse + \else \expandafter\tabu@Xparse\expandafter{\expandafter}% + \fi +}% \tabu@Xd@sp +\def\tabu@Xrewritten {% + \ifx \tabu@rewritten\@empty \def\tabu@rewritten{p}\fi + \ifdim \tabucolX<\z@ \tabu@negcoeftrue + \else\ifdim \tabucolX=\z@ \tabucolX \p@ + \fi\fi + \edef\tabu@temp{{\the\tabu@Xcol}{\tabu@strippt\tabucolX}}% + \edef\tabu@Xcoefs{\tabu@Xcoefs \tabu@ \tabu@temp}% + \edef\tabu@rewritten ##1##2{\def\noexpand\tabu@rewritten{% + >{\tabu@Xlcr \ifx$\tabu@Xmath$\tabu@Xdisp\fi ##1}% + \tabu@rewritten {\tabu@hsize \tabu@temp}% + <{##2\ifx$\tabu@Xmath$\fi}}% + }\tabu@rewritten +}% \tabu@Xrewritten +\def\tabu@hsize #1#2{% + \ifdim #2\p@<\z@ + \ifdim \tabucolX=\maxdimen \tabu@wd{#1}\else + \ifdim \tabu@wd{#1}<-#2\tabucolX \tabu@wd{#1}\else -#2\tabucolX\fi + \fi + \else #2\tabucolX + \fi +}% \tabu@hsize +%% \usetabu and \preamble: rewritting process --------------------- +\tabu@privatecolumntype \usetabu [1]{% + \ifx\\#1\\\tabu@saveerr{}\else + \@ifundefined{tabu@saved@\string#1} + {\tabu@saveerr{#1}} + {\let\tabu@rewriteX \tabu@rewriteXrestore + \csname tabu@saved@\string#1\expandafter\endcsname\expandafter\@ne}% + \fi +}% \NC@rewrite@\usetabu +\tabu@privatecolumntype \preamble [1]{% + \ifx\\#1\\\tabu@saveerr{}\else + \@ifundefined{tabu@saved@\string#1} + {\tabu@saveerr{#1}} + {\csname tabu@saved@\string#1\expandafter\endcsname\expandafter\z@}% + \fi +}% \NC@rewrite@\preamble +%% Controlling the rewritting process ------------------------------- +\tabu@newcolumntype \tabu@rewritefirst{% + \iftabu@long \aftergroup \tabu@longpream % <the whole implementation is here !> + \else \aftergroup \tabu@pream + \fi + \let\tabu@ \relax \let\tabu@hsize \relax + \let\tabu@Xcoefs \@empty \let\tabu@savels \relax + \tabu@Xcol \z@ \tabu@cnt \tw@ + \gdef\tabu@mkpreambuffer{\tabu@{}}\tabu@measuringfalse + \global\setbox\@arstrutbox \box\@arstrutbox + \NC@list{\NC@do *}\tabu@textbar \tabu@lines + \NC@list\expandafter{\the\NC@list \NC@do X}% + \iftabu@siunitx % <siunitx S and s columns> + \NC@list\expandafter{\the\NC@list \NC@do S\NC@do s}\fi + \NC@list\expandafter{\the\expandafter\NC@list \tabu@highprioritycolumns}% + \expandafter\def\expandafter\tabu@NC@list\expandafter{% + \the\expandafter\NC@list \tabu@NC@list}% % * | X S <original> + \NC@list\expandafter{\expandafter \NC@do \expandafter\usetabu + \expandafter \NC@do \expandafter\preamble + \the\NC@list \NC@do \tabu@rewritemiddle + \NC@do \tabu@rewritelast}% + \tabu@savedecl + \tabu@privatecolumns + \edef\tabu@prev{\the\@temptokena}\NC@find \tabu@rewritemiddle +}% NC@rewrite@\tabu@rewritefirst +\tabu@newcolumntype \tabu@rewritemiddle{% + \edef\tabu@temp{\the\@temptokena}\NC@find \tabu@rewritelast +}% \NC@rewrite@\tabu@rewritemiddle +\tabu@newcolumntype \tabu@rewritelast{% + \ifx \tabu@temp\tabu@prev \advance\tabu@cnt \m@ne + \NC@list\expandafter{\tabu@NC@list \NC@do \tabu@rewritemiddle + \NC@do \tabu@rewritelast}% + \else \let\tabu@prev\tabu@temp + \fi + \ifcase \tabu@cnt \expandafter\tabu@endrewrite + \else \expandafter\NC@find \expandafter\tabu@rewritemiddle + \fi +}% \NC@rewrite@\tabu@rewritelast +%% Choosing the strategy -------------------------------------------- +\def\tabu@endrewrite {% + \let\tabu@temp \NC@find + \ifx \@arrayright\relax \let\@arrayright \@empty \fi + \count@=% + \ifx \@finalstrut\tabu@finalstrut \z@ % outer in mode 0 print + \iftabu@measuring + \xdef\tabu@mkpreambuffer{\tabu@mkpreambuffer + \tabu@target \csname tabu@\the\tabu@nested.T\endcsname + \tabucolX \csname tabu@\the\tabu@nested.X\endcsname + \edef\@halignto {\ifx\@arrayright\@empty to\tabu@target\fi}}% + \fi + \else\iftabu@measuring 4 % X columns + \xdef\tabu@mkpreambuffer{\tabu@{\tabu@mkpreambuffer + \tabu@target \the\tabu@target + \tabu@spreadtarget \the\tabu@spreadtarget}% + \def\noexpand\tabu@Xcoefs{\tabu@Xcoefs}% + \edef\tabu@halignto{\ifx \@arrayright\@empty to\tabu@target\fi}}% + \let\tabu@Xcoefs \relax + \else\ifcase\tabu@nested \thr@@ % outer, no X + \global\let\tabu@afterendpar \relax + \else \@ne % inner, no X, outer in mode 1 or 2 + \fi + \ifdefined\tabu@usetabu + \else \ifdim\tabu@target=\z@ + \else \let\tabu@temp \tabu@extracolsep + \fi\fi + \fi + \fi + \xdef\tabu@mkpreambuffer{\count@ \the\count@ \tabu@mkpreambuffer}% + \tabu@temp +}% \tabu@endrewrite +\def\tabu@extracolsep{\@defaultunits \expandafter\let + \expandafter\tabu@temp \expandafter=\the\@temptokena \relax\@nnil + \ifx \tabu@temp\@sptoken + \expandafter\tabu@gobblespace \expandafter\tabu@extracolsep + \else + \edef\tabu@temp{\noexpand\NC@find + \if |\noexpand\tabu@temp @% + \else\if !\noexpand\tabu@temp @% + \else !% + \fi\fi + {\noexpand\extracolsep\noexpand\@flushglue}}% + \fi + \tabu@temp +}% \tabu@extrac@lsep +%% Implementing the strategy ---------------------------------------- +\long\def\tabu@pream #1\@preamble {% + \let\tabu@ \tabu@@ \tabu@mkpreambuffer \tabu@aftergroupcleanup + \NC@list\expandafter {\tabu@NC@list}% in case of nesting... + \ifdefined\tabu@usetabu \tabu@usetabu \tabu@target \z@ \fi + \let\tabu@savedpreamble \@preamble + \global\let\tabu@elapsedtime \relax + \tabu@thebody ={#1\tabu@aftergroupcleanup}% + \tabu@thebody =\expandafter{\the\expandafter\tabu@thebody + \@preamble}% + \edef\tabuthepreamble {\the\tabu@thebody}% ( no @ allowed for \scantokens ) + \tabu@select +}% \tabu@pream +\long\def\tabu@longpream #1\LT@bchunk #2\LT@bchunk{% + \let\tabu@ \tabu@@ \tabu@mkpreambuffer \tabu@aftergroupcleanup + \NC@list\expandafter {\tabu@NC@list}% in case of nesting... + \let\tabu@savedpreamble \@preamble + \global\let\tabu@elapsedtime \relax + \tabu@thebody ={#1\LT@bchunk #2\tabu@aftergroupcleanup \LT@bchunk}% + \edef\tabuthepreamble {\the\tabu@thebody}% ( no @ allowed for \scantokens ) + \tabu@select +}% \tabu@longpream +\def\tabu@select {% + \ifnum\tabu@nested>\z@ \tabuscantokensfalse \fi + \ifnum \count@=\@ne \iftabu@measuring \count@=\tw@ \fi\fi + \ifcase \count@ + \global\let\tabu@elapsedtime \relax + \tabu@seteverycr + \expandafter \tabuthepreamble % vertical adjustment (inheritated from outer) + \or % exit in vertical measure + struts per cell because no X and outer in mode 3 + \tabu@evr{\tabu@verticalinit}\tabu@celllalign@def{\tabu@verticalmeasure}% + \def\tabu@cellralign{\tabu@verticalspacing}% + \tabu@seteverycr + \expandafter \tabuthepreamble + \or % exit without measure because no X and outer in mode 4 + \tabu@evr{}\tabu@celllalign@def{}\let\tabu@cellralign \@empty + \tabu@seteverycr + \expandafter \tabuthepreamble + \else % needs trials + \tabu@evr{}\tabu@celllalign@def{}\let\tabu@cellralign \@empty + \tabu@savecounters + \expandafter \tabu@setstrategy + \fi +}% \tabu@select +\def\tabu@@ {\gdef\tabu@mkpreambuffer} +%% Protections to set up before trials ------------------------------ +\def\tabu@setstrategy {\begingroup % <trials group> + \tabu@trialh@@k \tabu@cnt \z@ % number of trials + \hbadness \@M \let\hbadness \@tempcnta + \hfuzz \maxdimen \let\hfuzz \@tempdima + \let\write \tabu@nowrite\let\GenericError \tabu@GenericError + \let\savetabu \@gobble \let\tabudefaulttarget \linewidth + \let\@footnotetext \@gobble \let\@xfootnote \tabu@xfootnote + \let\color \tabu@nocolor\let\rowcolor \tabu@norowcolor + \let\tabu@aftergroupcleanup \relax % only after the last trial + \tabu@mkpreambuffer + \ifnum \count@>\thr@@ \let\@halignto \@empty \tabucolX@init + \def\tabu@lasttry{\m@ne\p@}\fi + \begingroup \iffalse{\fi \ifnum0=`}\fi + \toks@{}\def\tabu@stack{b}\iftabuscantokens \endlinechar=10 \obeyspaces \fi % + \tabu@collectbody \tabu@strategy % +}% \tabu@setstrategy +\def\tabu@savecounters{% + \def\@elt ##1{\csname c@##1\endcsname\the\csname c@##1\endcsname}% + \edef\tabu@clckpt {\begingroup \globaldefs=\@ne \cl@@ckpt \endgroup}\let\@elt \relax +}% \tabu@savecounters +\def\tabucolX@init {% \tabucolX <= \tabu@target / (sum coefs > 0) + \dimen@ \z@ \tabu@Xsum \z@ \tabucolX \z@ \let\tabu@ \tabu@Xinit \tabu@Xcoefs + \ifdim \dimen@>\z@ + \@tempdima \dimexpr \tabu@target *\p@/\dimen@ + \tabu@hfuzz\relax + \ifdim \tabucolX<\@tempdima \tabucolX \@tempdima \fi + \fi +}% \tabucolX@init +\def\tabu@Xinit #1#2{\tabu@Xcol #1 \advance \tabu@Xsum + \ifdim #2\p@>\z@ #2\p@ \advance\dimen@ #2\p@ + \else -#2\p@ \tabu@negcoeftrue + \@tempdima \dimexpr \tabu@target*\p@/\dimexpr-#2\p@\relax \relax + \ifdim \tabucolX<\@tempdima \tabucolX \@tempdima \fi + \tabu@wddef{#1}{0pt}% + \fi +}% \tabu@Xinit +%% Collecting the environment body ---------------------------------- +\long\def\tabu@collectbody #1#2\end #3{% + \edef\tabu@stack{\tabu@pushbegins #2\begin\end\expandafter\@gobble\tabu@stack}% + \ifx \tabu@stack\@empty + \toks@\expandafter{\expandafter\tabu@thebody\expandafter{\the\toks@ #2}% + \def\tabu@end@envir{\end{#3}}% + \iftabuscantokens + \iftabu@long \def\tabu@endenvir {\end{#3}\tabu@gobbleX}% + \else \def\tabu@endenvir {\let\endarray \@empty + \end{#3}\tabu@gobbleX}% + \fi + \else \def\tabu@endenvir {\end{#3}}\fi}% + \let\tabu@collectbody \tabu@endofcollect + \else\def\tabu@temp{#3}% + \ifx \tabu@temp\@empty \toks@\expandafter{\the\toks@ #2\end }% + \else \ifx\tabu@temp\tabu@@spxiii \toks@\expandafter{\the\toks@ #2\end #3}% + \else \ifx\tabu@temp\tabu@X \toks@\expandafter{\the\toks@ #2\end #3}% + \else \toks@\expandafter{\the\toks@ #2\end{#3}}% + \fi\fi\fi + \fi + \tabu@collectbody{#1}% +}% \tabu@collectbody +\long\def\tabu@pushbegins#1\begin#2{\ifx\end#2\else b\expandafter\tabu@pushbegins\fi}% +\def\tabu@endofcollect #1{\ifnum0=`{}\fi + \expandafter\endgroup \the\toks@ #1% +}% \tabu@endofcollect +%% The trials: switching between strategies ------------------------- +\def\tabu@strategy {\relax % stops \count@ assignment ! + \ifcase\count@ % case 0 = print with vertical adjustment (outer is finished) + \expandafter \tabu@endoftrials + \or % case 1 = exit in vertical measure (outer in mode 3) + \expandafter\xdef\csname tabu@\the\tabu@nested.T\endcsname{\the\tabu@target}% + \expandafter\xdef\csname tabu@\the\tabu@nested.X\endcsname{\the\tabucolX}% + \expandafter \tabu@endoftrials + \or % case 2 = exit with a rule replacing the table (outer in mode 4) + \expandafter \tabu@quickend + \or % case 3 = outer is in mode 3 because of no X + \begingroup + \tabu@evr{\tabu@verticalinit}\tabu@celllalign@def{\tabu@verticalmeasure}% + \def\tabu@cellralign{\tabu@verticalspacing}% + \expandafter \tabu@measuring + \else % case 4 = horizontal measure + \begingroup + \global\let\tabu@elapsedtime \tabu@message@etime + \long\def\multicolumn##1##2##3{\multispan{##1}}% + \let\tabu@startpboxORI \@startpbox + \iftabu@spread + \def\tabu@naturalXmax {\z@}% + \let\tabu@naturalXmin \tabu@naturalXmax + \tabu@evr{\global\tabu@naturalX \z@}% + \let\@startpbox \tabu@startpboxmeasure + \else\iftabu@negcoef + \let\@startpbox \tabu@startpboxmeasure + \else \let\@startpbox \tabu@startpboxquick + \fi\fi + \expandafter \tabu@measuring + \fi +}% \tabu@strategy +\def\tabu@measuring{\expandafter \tabu@trial \expandafter + \count@ \the\count@ \tabu@endtrial +}% \tabu@measuring +\def\tabu@trial{\iftabu@long \tabu@longtrial \else \tabu@shorttrial \fi} +\def\tabu@shorttrial {\setbox\tabu@box \hbox\bgroup \tabu@seteverycr + \ifx \tabu@savecounters\relax \else + \let\tabu@savecounters \relax \tabu@clckpt \fi + $\iftabuscantokens \tabu@rescan \else \expandafter\@secondoftwo \fi + \expandafter{\expandafter \tabuthepreamble + \the\tabu@thebody + \csname tabu@adl@endtrial\endcsname + \endarray}$\egroup % got \tabu@box +}% \tabu@shorttrial +\def\tabu@longtrial {\setbox\tabu@box \hbox\bgroup \tabu@seteverycr + \ifx \tabu@savecounters\relax \else + \let\tabu@savecounters \relax \tabu@clckpt \fi + \iftabuscantokens \tabu@rescan \else \expandafter\@secondoftwo \fi + \expandafter{\expandafter \tabuthepreamble + \the\tabu@thebody + \tabuendlongtrial}\egroup % got \tabu@box +}% \tabu@longtrial +\def\tabuendlongtrial{% no @ allowed for \scantokens + \LT@echunk \global\setbox\@ne \hbox{\unhbox\@ne}\kern\wd\@ne + \LT@get@widths +}% \tabuendlongtrial +\def\tabu@adl@endtrial{% <arydshln in nested trials - problem for global column counters!> + \crcr \noalign{\global\adl@ncol \tabu@nbcols}}% anything global is crap, junky and fails ! +\def\tabu@seteverycr {\tabu@reset + \everycr \expandafter{\the\everycr \tabu@everycr}% + \let\everycr \tabu@noeverycr % <for ialign> +}% \tabu@seteverycr +\def\tabu@noeverycr{{\aftergroup\tabu@restoreeverycr \afterassignment}\toks@} +\def\tabu@restoreeverycr {\let\everycr \tabu@@everycr} +\def\tabu@everycr {\iftabu@everyrow \noalign{\tabu@everyrow}\fi} +\def\tabu@endoftrials {% + \iftabuscantokens \expandafter\@firstoftwo + \else \expandafter\@secondoftwo + \fi + {\expandafter \tabu@closetrialsgroup \expandafter + \tabu@rescan \expandafter{% + \expandafter\tabuthepreamble + \the\expandafter\tabu@thebody + \iftabu@long \else \endarray \fi}} + {\expandafter\tabu@closetrialsgroup \expandafter + \tabuthepreamble + \the\tabu@thebody}% + \tabu@endenvir % Finish ! +}% \tabu@endoftrials +\def\tabu@closetrialsgroup {% + \toks@\expandafter{\tabu@endenvir}% + \edef\tabu@bufferX{\endgroup + \tabucolX \the\tabucolX + \tabu@target \the\tabu@target + \tabu@cnt \the\tabu@cnt + \def\noexpand\tabu@endenvir{\the\toks@}% + %Quid de \@halignto = \tabu@halignto ?? + }% \tabu@bufferX + \tabu@bufferX + \ifcase\tabu@nested % print out (outer in mode 0) + \global\tabu@cnt \tabu@cnt + \tabu@evr{\tabu@verticaldynamicadjustment}% + \tabu@celllalign@def{\everypar{}}\let\tabu@cellralign \@empty + \let\@finalstrut \tabu@finalstrut + \else % vertical measure of nested tabu + \tabu@evr{\tabu@verticalinit}% + \tabu@celllalign@def{\tabu@verticalmeasure}% + \def\tabu@cellralign{\tabu@verticalspacing}% + \fi + \tabu@clckpt \let\@halignto \tabu@halignto + \let\@halignto \@empty + \tabu@seteverycr + \ifdim \tabustrutrule>\z@ \ifnum\tabu@nested=\z@ + \setbox\@arstrutbox \box\voidb@x % force \@arstrutbox to be rebuilt (visible struts) + \fi\fi +}% \tabu@closetrialsgroup +\def\tabu@quickend {\expandafter \endgroup \expandafter + \tabu@target \the\tabu@target \tabu@quickrule + \let\endarray \relax \tabu@endenvir +}% \tabu@quickend +\def\tabu@endtrial {\relax % stops \count@ assignment ! + \ifcase \count@ \tabu@err % case 0 = impossible here + \or \tabu@err % case 1 = impossible here + \or \tabu@err % case 2 = impossible here + \or % case 3 = outer goes into mode 0 + \def\tabu@bufferX{\endgroup}\count@ \z@ + \else % case 4 = outer goes into mode 3 + \iftabu@spread \tabu@spreadarith % inner into mode 1 (outer in mode 3) + \else \tabu@arith % or 2 (outer in mode 4) + \fi + \count@=% + \ifcase\tabu@nested \thr@@ % outer goes into mode 3 + \else\iftabu@measuring \tw@ % outer is in mode 4 + \else \@ne % outer is in mode 3 + \fi\fi + \edef\tabu@bufferX{\endgroup + \tabucolX \the\tabucolX + \tabu@target \the\tabu@target}% + \fi + \expandafter \tabu@bufferX \expandafter + \count@ \the\count@ \tabu@strategy +}% \tabu@endtrial +\def\tabu@err{\errmessage{(tabu) Internal impossible error! (\count@=\the\count@)}} +%% The algorithms: compute the widths / stop or go on --------------- +\def\tabu@arithnegcoef {% + \@tempdima \z@ \dimen@ \z@ \let\tabu@ \tabu@arith@negcoef \tabu@Xcoefs +}% \tabu@arithnegcoef +\def\tabu@arith@negcoef #1#2{% + \ifdim #2\p@>\z@ \advance\dimen@ #2\p@ % saturated by definition + \advance\@tempdima #2\tabucolX + \else + \ifdim -#2\tabucolX <\tabu@wd{#1}% c_i X < natural width <= \tabu@target-> saturated + \advance\dimen@ -#2\p@ + \advance\@tempdima -#2\tabucolX + \else + \advance\@tempdima \tabu@wd{#1}% natural width <= c_i X => neutralised + \ifdim \tabu@wd{#1}<\tabu@target \else % neutralised + \advance\dimen@ -#2\p@ % saturated (natural width = tabu@target) + \fi + \fi + \fi +}% \tabu@arith@negcoef +\def\tabu@givespace #1#2{% here \tabu@DELTA < \z@ + \ifdim \@tempdima=\z@ + \tabu@wddef{#1}{\the\dimexpr -\tabu@DELTA*\p@/\tabu@Xsum}% + \else + \tabu@wddef{#1}{\the\dimexpr \tabu@hsize{#1}{#2} + *(\p@ -\tabu@DELTA*\p@/\@tempdima)/\p@\relax}% + \fi +}% \tabu@givespace +\def\tabu@arith {\advance\tabu@cnt \@ne + \ifnum \tabu@cnt=\@ne \tabu@message{\tabu@titles}\fi + \tabu@arithnegcoef + \@tempdimb \dimexpr \wd\tabu@box -\@tempdima \relax % <incompressible material> + \tabu@DELTA = \dimexpr \wd\tabu@box - \tabu@target \relax + \tabu@message{\tabu@message@arith}% + \ifdim \tabu@DELTA <\tabu@hfuzz + \ifdim \tabu@DELTA<\z@ % wd (tabu)<\tabu@target ? + \let\tabu@ \tabu@givespace \tabu@Xcoefs + \advance\@tempdima \@tempdimb \advance\@tempdima -\tabu@DELTA % for message + \else % already converged: nothing to do but nearly impossible... + \fi + \tabucolX \maxdimen + \tabu@measuringfalse + \else % need for narrower X columns + \tabucolX =\dimexpr (\@tempdima -\tabu@DELTA) *\p@/\tabu@Xsum \relax + \tabu@measuringtrue + \@whilesw \iftabu@measuring\fi {% + \advance\tabu@cnt \@ne + \tabu@arithnegcoef + \tabu@DELTA =\dimexpr \@tempdima+\@tempdimb -\tabu@target \relax % always < 0 here + \tabu@message{\tabu@header + \tabu@msgalign \tabucolX { }{ }{ }{ }{ }\@@ + \tabu@msgalign \@tempdima+\@tempdimb { }{ }{ }{ }{ }\@@ + \tabu@msgalign \tabu@target { }{ }{ }{ }{ }\@@ + \tabu@msgalign@PT \dimen@ { }{}{}{}{}{}{}\@@ + \ifdim -\tabu@DELTA<\tabu@hfuzz \tabu@spaces target ok\else + \tabu@msgalign \dimexpr -\tabu@DELTA *\p@/\dimen@ {}{}{}{}{}\@@ + \fi}% + \ifdim -\tabu@DELTA<\tabu@hfuzz + \advance\@tempdima \@tempdimb % for message + \tabu@measuringfalse + \else + \advance\tabucolX \dimexpr -\tabu@DELTA *\p@/\dimen@ \relax + \fi + }% + \fi + \tabu@message{\tabu@message@reached}% + \edef\tabu@bufferX{\endgroup \tabu@cnt \the\tabu@cnt + \tabucolX \the\tabucolX + \tabu@target \the\tabu@target}% +}% \tabu@arith +\def\tabu@spreadarith {% + \dimen@ \z@ \@tempdima \tabu@naturalXmax \let\tabu@ \tabu@spread@arith \tabu@Xcoefs + \edef\tabu@naturalXmin {\the\dimexpr\tabu@naturalXmin*\dimen@/\p@}% + \@tempdimc =\dimexpr \wd\tabu@box -\tabu@naturalXmax+\tabu@naturalXmin \relax + \iftabu@measuring + \tabu@target =\dimexpr \@tempdimc+\tabu@spreadtarget \relax + \edef\tabu@bufferX{\endgroup \tabucolX \the\tabucolX \tabu@target\the\tabu@target}% + \else + \tabu@message{\tabu@message@spreadarith}% + \ifdim \dimexpr \@tempdimc+\tabu@spreadtarget >\tabu@target + \tabu@message{(tabu) spread + \ifdim \@tempdimc>\tabu@target useless here: default target used% + \else too large: reduced to fit default target\fi.}% + \else + \tabu@target =\dimexpr \@tempdimc+\tabu@spreadtarget \relax + \tabu@message{(tabu) spread: New target set to \the\tabu@target^^J}% + \fi + \begingroup \let\tabu@wddef \@gobbletwo + \@tempdimb \@tempdima + \tabucolX@init + \tabu@arithnegcoef + \wd\tabu@box =\dimexpr \wd\tabu@box +\@tempdima-\@tempdimb \relax + \expandafter\endgroup \expandafter\tabucolX \the\tabucolX + \tabu@arith + \fi +}% \tabu@spreadarith +\def\tabu@spread@arith #1#2{% + \ifdim #2\p@>\z@ \advance\dimen@ #2\p@ + \else \advance\@tempdima \tabu@wd{#1}\relax + \fi +}% \tabu@spread@arith +%% Reporting in the .log file --------------------------------------- +\def\tabu@message@defaulttarget{% + \ifnum\tabu@nested=\z@^^J(tabu) Default target: + \ifx\tabudefaulttarget\linewidth \string\linewidth + \ifdim \tabu@thetarget=\linewidth \else + -\the\dimexpr\linewidth-\tabu@thetarget\fi = + \else\ifx\tabudefaulttarget\linegoal\string\linegoal= + \fi\fi + \else (tabu) Default target (nested): \fi + \the\tabu@target \on@line + \ifnum\tabu@nested=\z@ , page \the\c@page\fi} +\def\tabu@message@target {^^J(tabu) Target specified: + \the\tabu@target \on@line, page \the\c@page} +\def\tabu@message@arith {\tabu@header + \tabu@msgalign \tabucolX { }{ }{ }{ }{ }\@@ + \tabu@msgalign \wd\tabu@box { }{ }{ }{ }{ }\@@ + \tabu@msgalign \tabu@target { }{ }{ }{ }{ }\@@ + \tabu@msgalign@PT \dimen@ { }{}{}{}{}{}{}\@@ + \ifdim \tabu@DELTA<\tabu@hfuzz giving space\else + \tabu@msgalign \dimexpr (\@tempdima-\tabu@DELTA) *\p@/\tabu@Xsum -\tabucolX {}{}{}{}{}\@@ + \fi +}% \tabu@message@arith +\def\tabu@message@spreadarith {\tabu@spreadheader + \tabu@msgalign \tabu@spreadtarget { }{ }{ }{ }{}\@@ + \tabu@msgalign \wd\tabu@box { }{ }{ }{ }{}\@@ + \tabu@msgalign -\tabu@naturalXmax { }{}{}{}{}\@@ + \tabu@msgalign \tabu@naturalXmin { }{ }{ }{ }{}\@@ + \tabu@msgalign \ifdim \dimexpr\@tempdimc>\tabu@target \tabu@target + \else \@tempdimc+\tabu@spreadtarget \fi + {}{}{}{}{}\@@} +\def\tabu@message@negcoef #1#2{ + \tabu@spaces\tabu@spaces\space * #1. X[\rem@pt#2]: + \space width = \tabu@wd {#1} + \expandafter\string\csname tabu@\the\tabu@nested.W\number#1\endcsname + \ifdim -\tabu@pt#2\tabucolX<\tabu@target + < \number-\rem@pt#2 X + = \the\dimexpr -\tabu@pt#2\tabucolX \relax + \else + <= \the\tabu@target\space < \number-\rem@pt#2 X\fi} +\def\tabu@message@reached{\tabu@header + ******* Reached Target: + hfuzz = \tabu@hfuzz\on@line\space *******} +\def\tabu@message@etime{\edef\tabu@stoptime{\the\pdfelapsedtime}% + \tabu@message{(tabu)\tabu@spaces Time elapsed during measure: + \the\numexpr(\tabu@stoptime-\tabu@starttime-32767)/65536\relax sec + \the\numexpr\numexpr(\tabu@stoptime-\tabu@starttime) + -\numexpr(\tabu@stoptime-\tabu@starttime-32767)/65536\relax*65536\relax + *1000/65536\relax ms \tabu@spaces(\the\tabu@cnt\space + cycle\ifnum\tabu@cnt>\@ne s\fi)^^J^^J}} +\def\tabu@message@verticalsp {% + \ifdim \@tempdima>\tabu@ht + \ifdim \@tempdimb>\tabu@dp + \expandafter\expandafter\expandafter\string\tabu@ht = + \tabu@msgalign \@tempdima { }{ }{ }{ }{ }\@@ + \expandafter\expandafter\expandafter\string\tabu@dp = + \tabu@msgalign \@tempdimb { }{ }{ }{ }{ }\@@^^J% + \else + \expandafter\expandafter\expandafter\string\tabu@ht = + \tabu@msgalign \@tempdima { }{ }{ }{ }{ }\@@^^J% + \fi + \else\ifdim \@tempdimb>\tabu@dp + \tabu@spaces\tabu@spaces\tabu@spaces + \expandafter\expandafter\expandafter\string\tabu@dp = + \tabu@msgalign \@tempdimb { }{ }{ }{ }{ }\@@^^J\fi + \fi +}% \tabu@message@verticalsp +\edef\tabu@spaces{\@spaces} +\def\tabu@strippt{\expandafter\tabu@pt\the} +{\@makeother\P \@makeother\T\lowercase{\gdef\tabu@pt #1PT{#1}}} +\def\tabu@msgalign{\expandafter\tabu@msg@align\the\dimexpr} +\def\tabu@msgalign@PT{\expandafter\tabu@msg@align\romannumeral-`\0\tabu@strippt} +\def\do #1{% + \def\tabu@msg@align##1.##2##3##4##5##6##7##8##9\@@{% + \ifnum##1<10 #1 #1\else + \ifnum##1<100 #1 \else + \ifnum##1<\@m #1\fi\fi\fi + ##1.##2##3##4##5##6##7##8#1}% + \def\tabu@header{(tabu) \ifnum\tabu@cnt<10 #1\fi\the\tabu@cnt) }% + \def\tabu@titles{\ifnum \tabu@nested=\z@ + (tabu) Try#1 #1 tabu X #1 #1 #1tabu Width #1 #1 Target + #1 #1 #1 Coefs #1 #1 #1 Update^^J\fi}% + \def\tabu@spreadheader{% + (tabu) Try#1 #1 Spread #1 #1 tabu Width #1 #1 #1 Nat. X #1 #1 #1 #1Nat. Min. + #1 New Target^^J% + (tabu) sprd} + \def\tabu@message@save {\begingroup + \def\x ####1{\tabu@msg@align ####1{ }{ }{ }{ }{}\@@} + \def\z ####1{\expandafter\x\expandafter{\romannumeral-`\0\tabu@strippt + \dimexpr####1\p@{ }{ }}}% + \let\color \relax \def\tabu@rulesstyle ####1####2{\detokenize{####1}}% + \let\CT@arc@ \relax \let\@preamble \@gobble + \let\tabu@savedpream \@firstofone + \let\tabu@savedparams \@firstofone + \def\tabu@target ####1\relax {(tabu) target #1 #1 #1 #1 #1 = \x{####1}^^J}% + \def\tabucolX ####1\relax {(tabu) X columns width#1 = \x{####1}^^J}% + \def\tabu@nbcols ####1\relax {(tabu) Number of columns: \z{####1}^^J}% + \def\tabu@aligndefault ####1{(tabu) Default alignment: #1 #1 ####1^^J}% + \def\col@sep ####1\relax {(tabu) column sep #1 #1 #1 = \x{####1}^^J}% + \def\arrayrulewidth ####1\relax{(tabu) arrayrulewidth #1 = \x{####1}}% + \def\doublerulesep ####1\relax { doublerulesep = \x{####1}^^J}% + \def\extratabsurround####1\relax{(tabu) extratabsurround = \x{####1}^^J}% + \def\extrarowheight ####1\relax{(tabu) extrarowheight #1 = \x{####1}}% + \def\extrarowdepth ####1\relax {extrarowdepth = \x{####1}^^J}% + \def\abovetabulinesep####1\relax{(tabu) abovetabulinesep=\x{####1} }% + \def\belowtabulinesep####1\relax{ belowtabulinesep=\x{####1}^^J}% + \def\arraystretch ####1{(tabu) arraystretch #1 #1 = \z{####1}^^J}% + \def\minrowclearance####1\relax{(tabu) minrowclearance #1 = \x{####1}^^J}% + \def\tabu@arc@L ####1{(tabu) taburulecolor #1 #1 = ####1^^J}% + \def\tabu@drsc@L ####1{(tabu) tabudoublerulecolor= ####1^^J}% + \def\tabu@evr@L ####1{(tabu) everyrow #1 #1 #1 #1 = \detokenize{####1}^^J}% + \def\tabu@ls@L ####1{(tabu) line style = \detokenize{####1}^^J}% + \def\NC@find ####1\@nil{(tabu) tabu preamble#1 #1 = \detokenize{####1}^^J}% + \def\tabu@wddef####1####2{(tabu) Natural width ####1 = \x{####2}^^J}% + \let\edef \@gobbletwo \let\def \@empty \let\let \@gobbletwo + \tabu@message{% + (tabu) \string\savetabu{\tabu@temp}: \on@line^^J% + \tabu@usetabu \@nil^^J}% + \endgroup} +}\do{ } +%% Measuring the natural width (varwidth) - store the results ------- +\def\tabu@startpboxmeasure #1{\bgroup % entering \vtop + \edef\tabu@temp{\expandafter\@secondoftwo \ifx\tabu@hsize #1\else\relax\fi}% + \ifodd 1\ifx \tabu@temp\@empty 0 \else % starts with \tabu@hsize ? + \iftabu@spread \else % if spread -> measure + \ifdim \tabu@temp\p@>\z@ 0 \fi\fi\fi% if coef>0 -> do not measure + \let\@startpbox \tabu@startpboxORI % restore immediately (nesting) + \tabu@measuringtrue % for the quick option... + \tabu@Xcol =\expandafter\@firstoftwo\ifx\tabu@hsize #1\fi + \ifdim \tabu@temp\p@>\z@ \ifdim \tabu@temp\tabucolX<\tabu@target + \tabu@target=\tabu@temp\tabucolX \fi\fi + \setbox\tabu@box \hbox \bgroup + \begin{varwidth}\tabu@target + \let\FV@ListProcessLine \tabu@FV@ListProcessLine % \hbox to natural width... + \narrowragged \arraybackslash \parfillskip \@flushglue + \ifdefined\pdfadjustspacing \pdfadjustspacing\z@ \fi + \bgroup + \aftergroup\tabu@endpboxmeasure +%%TABU-FIXED add \color@begingroup + \color@begingroup + \ifdefined \cellspacetoplimit \tabu@cellspacepatch \fi + \else \expandafter\@gobble + \tabu@startpboxquick{#1}% \@gobble \bgroup + \fi +}% \tabu@startpboxmeasure +\def\tabu@cellspacepatch{\def\bcolumn##1\@nil{}\let\ecolumn\@empty + \bgroup\color@begingroup} +\def\tabu@endpboxmeasure {% + \@finalstrut \@arstrutbox + \end{varwidth}% +%TABU-FIXED add \color@begingroup +\color@endgroup +\egroup % <got my \tabu@box> + \ifdim \tabu@temp\p@ <\z@ % neg coef + \ifdim \tabu@wd\tabu@Xcol <\wd\tabu@box + \tabu@wddef\tabu@Xcol {\the\wd\tabu@box}% + \tabu@debug{\tabu@message@endpboxmeasure}% + \fi + \else % spread coef>0 + \global\advance \tabu@naturalX \wd\tabu@box + \@tempdima =\dimexpr \wd\tabu@box *\p@/\dimexpr \tabu@temp\p@\relax \relax + \ifdim \tabu@naturalXmax <\tabu@naturalX + \xdef\tabu@naturalXmax {\the\tabu@naturalX}\fi + \ifdim \tabu@naturalXmin <\@tempdima + \xdef\tabu@naturalXmin {\the\@tempdima}\fi + \fi + \box\tabu@box \egroup % end of \vtop (measure) restore \tabu@target +}% \tabu@endpboxmeasure +\def\tabu@wddef #1{\expandafter\xdef + \csname tabu@\the\tabu@nested.W\number#1\endcsname} +\def\tabu@wd #1{\csname tabu@\the\tabu@nested.W\number#1\endcsname} +\def\tabu@message@endpboxmeasure{\tabu@spaces\tabu@spaces<-> % <-> save natural wd + \the\tabu@Xcol. X[\tabu@temp]: + target = \the\tabucolX \space + \expandafter\expandafter\expandafter\string\tabu@wd\tabu@Xcol + =\tabu@wd\tabu@Xcol +}% \tabu@message@endpboxmeasure +\def\tabu@startpboxquick {\bgroup + \let\@startpbox \tabu@startpboxORI % restore immediately + \let\tabu \tabu@quick % \begin is expanded before... + \expandafter\@gobble \@startpbox % gobbles \bgroup +}% \tabu@startpboxquick +\def\tabu@quick {\begingroup \iffalse{\fi \ifnum0=`}\fi + \toks@{}\def\tabu@stack{b}\tabu@collectbody \tabu@endquick +}% \tabu@quick +\def\tabu@endquick {% + \ifodd 1\ifx\tabu@end@envir\tabu@endtabu \else + \ifx\tabu@end@envir\tabu@endtabus \else 0\fi\fi\relax + \endgroup + \else \let\endtabu \relax + \tabu@end@envir + \fi +}% \tabu@quick +\def\tabu@endtabu {\end{tabu}} +\def\tabu@endtabus {\end{tabu*}} +%% Measuring the heights and depths - store the results ------------- +%%TABU-FIXED use \tabu@currentgrouptype +\def\tabu@verticalmeasure{\everypar{}% + \ifnum \tabu@currentgrouptype>12 % 14=semi-simple, 15=math shift group + \setbox\tabu@box =\hbox\bgroup + \let\tabu@verticalspacing \tabu@verticalsp@lcr + \d@llarbegin % after \hbox ... + \else + \edef\tabu@temp{\ifnum\tabu@currentgrouptype=5\vtop + \else\ifnum\tabu@currentgrouptype=12\vcenter + \else\vbox\fi\fi}% + \setbox\tabu@box \hbox\bgroup$\tabu@temp \bgroup + \let\tabu@verticalspacing \tabu@verticalsp@pmb + \fi +}% \tabu@verticalmeasure +\def\tabu@verticalsp@lcr{% + \d@llarend \egroup % <got my \tabu@box> + \@tempdima \dimexpr \ht\tabu@box+\abovetabulinesep + \@tempdimb \dimexpr \dp\tabu@box+\belowtabulinesep \relax + \ifdim\tabustrutrule>\z@ \tabu@debug{\tabu@message@verticalsp}\fi + \ifdim \tabu@ht<\@tempdima \tabu@htdef{\the\@tempdima}\fi + \ifdim \tabu@dp<\@tempdimb \tabu@dpdef{\the\@tempdimb}\fi + \noindent\vrule height\@tempdima depth\@tempdimb +}% \tabu@verticalsp@lcr +\def\tabu@verticalsp@pmb{% inserts struts as needed + \par \expandafter\egroup + \expandafter$\expandafter + \egroup \expandafter + \@tempdimc \the\prevdepth + \@tempdima \dimexpr \ht\tabu@box+\abovetabulinesep + \@tempdimb \dimexpr \dp\tabu@box+\belowtabulinesep \relax + \ifdim\tabustrutrule>\z@ \tabu@debug{\tabu@message@verticalsp}\fi + \ifdim \tabu@ht<\@tempdima \tabu@htdef{\the\@tempdima}\fi + \ifdim \tabu@dp<\@tempdimb \tabu@dpdef{\the\@tempdimb}\fi + \let\@finalstrut \@gobble + \hrule height\@tempdima depth\@tempdimb width\hsize +%% \box\tabu@box +}% \tabu@verticalsp@pmb + +\def\tabu@verticalinit{% + \ifnum \c@taburow=\z@ \tabu@rearstrut \fi % after \tabu@reset ! + \advance\c@taburow \@ne + \tabu@htdef{\the\ht\@arstrutbox}\tabu@dpdef{\the\dp\@arstrutbox}% + \advance\c@taburow \m@ne +}% \tabu@verticalinit +\def\tabu@htdef {\expandafter\xdef \csname tabu@\the\tabu@nested.H\the\c@taburow\endcsname} +\def\tabu@ht {\csname tabu@\the\tabu@nested.H\the\c@taburow\endcsname} +\def\tabu@dpdef {\expandafter\xdef \csname tabu@\the\tabu@nested.D\the\c@taburow\endcsname} +\def\tabu@dp {\csname tabu@\the\tabu@nested.D\the\c@taburow\endcsname} +\def\tabu@verticaldynamicadjustment {% + \advance\c@taburow \@ne + \extrarowheight \dimexpr\tabu@ht - \ht\strutbox + \extrarowdepth \dimexpr\tabu@dp - \dp\strutbox + \let\arraystretch \@empty + \advance\c@taburow \m@ne +}% \tabu@verticaldynamicadjustment +\def\tabuphantomline{\crcr \noalign{% + {\globaldefs \@ne + \setbox\@arstrutbox \box\voidb@x + \let\tabu@@celllalign \tabu@celllalign + \let\tabu@@cellralign \tabu@cellralign + \let\tabu@@cellleft \tabu@cellleft + \let\tabu@@cellright \tabu@cellright + \let\tabu@@thevline \tabu@thevline + \let\tabu@celllalign \@empty + \let\tabu@cellralign \@empty + \let\tabu@cellright \@empty + \let\tabu@cellleft \@empty + \let\tabu@thevline \relax}% + \edef\tabu@temp{\tabu@multispan \tabu@nbcols{\noindent &}}% + \toks@\expandafter{\tabu@temp \noindent\tabu@everyrowfalse \cr + \noalign{\tabu@rearstrut + {\globaldefs\@ne + \let\tabu@celllalign \tabu@@celllalign + \let\tabu@cellralign \tabu@@cellralign + \let\tabu@cellleft \tabu@@cellleft + \let\tabu@cellright \tabu@@cellright + \let\tabu@thevline \tabu@@thevline}}}% + \expandafter}\the\toks@ +}% \tabuphantomline +%% \firsthline and \lasthline corrections --------------------------- +\def\tabu@firstline {\tabu@hlineAZ \tabu@firsthlinecorrection {}} +\def\tabu@firsthline{\tabu@hlineAZ \tabu@firsthlinecorrection \hline} +\def\tabu@lastline {\tabu@hlineAZ \tabu@lasthlinecorrection {}} +\def\tabu@lasthline {\tabu@hlineAZ \tabu@lasthlinecorrection \hline} +\def\tabu@hline {% replaces \hline if no colortbl (see \AtBeginDocument) + \noalign{\ifnum0=`}\fi + {\CT@arc@\hrule height\arrayrulewidth}% + \futurelet \tabu@temp \tabu@xhline +}% \tabu@hline +\def\tabu@xhline{% + \ifx \tabu@temp \hline + {\ifx \CT@drsc@\relax \vskip + \else\ifx \CT@drsc@\@empty \vskip + \else \CT@drsc@\hrule height + \fi\fi + \doublerulesep}% + \fi + \ifnum0=`{\fi}% +}% \tabu@xhline +\def\tabu@hlineAZ #1#2{\noalign{\ifnum0=`}\fi \dimen@ \z@ \count@ \z@ + \toks@{}\def\tabu@hlinecorrection{#1}\def\tabu@temp{#2}% + \tabu@hlineAZsurround +}% \tabu@hlineAZ +\newcommand*\tabu@hlineAZsurround[1][\extratabsurround]{% + \extratabsurround #1\let\tabucline \tabucline@scan + \let\hline \tabu@hlinescan \let\firsthline \hline + \let\cline \tabu@clinescan \let\lasthline \hline + \expandafter \futurelet \expandafter \tabu@temp + \expandafter \tabu@nexthlineAZ \tabu@temp +}% \tabu@hlineAZsurround +\def\tabu@hlinescan {\tabu@thick \arrayrulewidth \tabu@xhlineAZ \hline} +\def\tabu@clinescan #1{\tabu@thick \arrayrulewidth \tabu@xhlineAZ {\cline{#1}}} +\def\tabucline@scan{\@testopt \tabucline@sc@n {}} +\def\tabucline@sc@n #1[#2]{\tabu@xhlineAZ {\tabucline[{#1}]{#2}}} +\def\tabu@nexthlineAZ{% + \ifx \tabu@temp\hline \else + \ifx \tabu@temp\cline \else + \ifx \tabu@temp\tabucline \else + \tabu@hlinecorrection + \fi\fi\fi +}% \tabu@nexthlineAZ +\def\tabu@xhlineAZ #1{% + \toks@\expandafter{\the\toks@ #1}% + \@tempdimc \tabu@thick % The last line width + \ifcase\count@ \@tempdimb \tabu@thick % The first line width + \else \advance\dimen@ \dimexpr \tabu@thick+\doublerulesep \relax + \fi + \advance\count@ \@ne \futurelet \tabu@temp \tabu@nexthlineAZ +}% \tabu@xhlineAZ +\def\tabu@firsthlinecorrection{% \count@ = number of \hline -1 + \@tempdima \dimexpr \ht\@arstrutbox+\dimen@ + \edef\firsthline{% <local in \noalign> + \omit \hbox to\z@{\hss{\noexpand\tabu@DBG{yellow}\vrule + height \the\dimexpr\@tempdima+\extratabsurround + depth \dp\@arstrutbox + width \tabustrutrule}\hss}\cr + \noalign{\vskip -\the\dimexpr \@tempdima+\@tempdimb + +\dp\@arstrutbox \relax}% + \the\toks@ + }\ifnum0=`{\fi + \expandafter}\firsthline % we are then ! +}% \tabu@firsthlinecorrection +\def\tabu@lasthlinecorrection{% + \@tempdima \dimexpr \dp\@arstrutbox+\dimen@+\@tempdimb+\@tempdimc + \edef\lasthline{% <local in \noalign> + \the\toks@ + \noalign{\vskip -\the\dimexpr\dimen@+\@tempdimb+\dp\@arstrutbox}% + \omit \hbox to\z@{\hss{\noexpand\tabu@DBG{yellow}\vrule + depth \the\dimexpr \dp\@arstrutbox+\@tempdimb+\dimen@ + +\extratabsurround-\@tempdimc + height \z@ + width \tabustrutrule}\hss}\cr + }\ifnum0=`{\fi + \expandafter}\lasthline % we are then ! +}% \tabu@lasthlinecorrection +\def\tabu@LT@@hline{% + \ifx\LT@next\hline + \global\let\LT@next \@gobble + \ifx \CT@drsc@\relax + \gdef\CT@LT@sep{% + \noalign{\penalty-\@medpenalty\vskip\doublerulesep}}% + \else + \gdef\CT@LT@sep{% + \multispan\LT@cols{% + \CT@drsc@\leaders\hrule\@height\doublerulesep\hfill}\cr}% + \fi + \else + \global\let\LT@next\empty + \gdef\CT@LT@sep{% + \noalign{\penalty-\@lowpenalty\vskip-\arrayrulewidth}}% + \fi + \ifnum0=`{\fi}% + \multispan\LT@cols + {\CT@arc@\leaders\hrule\@height\arrayrulewidth\hfill}\cr + \CT@LT@sep + \multispan\LT@cols + {\CT@arc@\leaders\hrule\@height\arrayrulewidth\hfill}\cr + \noalign{\penalty\@M}% + \LT@next +}% \tabu@LT@@hline +%% Horizontal lines : \tabucline ------------------------------------ +\let\tabu@start \@tempcnta +\let\tabu@stop \@tempcntb +\newcommand*\tabucline{\noalign{\ifnum0=`}\fi \tabu@cline} +\newcommand*\tabu@cline[2][]{\tabu@startstop{#2}% + \ifnum \tabu@stop<\z@ \toks@{}% + \else \tabu@clinearg{#1}\tabu@thestyle + \edef\tabucline{\toks@{% + \ifnum \tabu@start>\z@ \omit + \tabu@multispan\tabu@start {\span\omit}&\fi + \omit \tabu@multispan\tabu@stop {\span\omit}% + \tabu@thehline\cr + }}\tabucline + \tabu@tracinglines{(tabu:tabucline) Style: #1^^J\the\toks@^^J^^J}% + \fi + \futurelet \tabu@temp \tabu@xcline +}% \tabu@cline +\def\tabu@clinearg #1{% + \ifx\\#1\\\let\tabu@thestyle \tabu@ls@ + \else \@defaultunits \expandafter\let\expandafter\@tempa + \romannumeral-`\0#1\relax \@nnil + \ifx \hbox\@tempa \tabu@clinebox{#1}% + \else\ifx \box\@tempa \tabu@clinebox{#1}% + \else\ifx \vbox\@tempa \tabu@clinebox{#1}% + \else\ifx \vtop\@tempa \tabu@clinebox{#1}% + \else\ifx \copy\@tempa \tabu@clinebox{#1}% + \else\ifx \leaders\@tempa \tabu@clineleads{#1}% + \else\ifx \cleaders\@tempa \tabu@clineleads{#1}% + \else\ifx \xleaders\@tempa \tabu@clineleads{#1}% + \else\tabu@getline {#1}% + \fi\fi\fi\fi\fi\fi\fi\fi + \fi +}% \tabu@clinearg +\def\tabu@clinebox #1{\tabu@clineleads{\xleaders#1\hss}} +\def\tabu@clineleads #1{% + \let\tabu@thestyle \relax \let\tabu@leaders \@undefined + \gdef\tabu@thehrule{#1}} +\def\tabu@thehline{\begingroup + \ifdefined\tabu@leaders + \noexpand\tabu@thehleaders + \else \noexpand\tabu@thehrule + \fi \endgroup +}% \tabu@thehline +\def\tabu@xcline{% + \ifx \tabu@temp\tabucline + \toks@\expandafter{\the\toks@ \noalign + {\ifx\CT@drsc@\relax \vskip + \else \CT@drsc@\hrule height + \fi + \doublerulesep}}% + \fi + \tabu@docline +}% \tabu@xcline +\def\tabu@docline {\ifnum0=`{\fi \expandafter}\the\toks@} +\def\tabu@docline@evr {\xdef\tabu@doclineafter{\the\toks@}% + \ifnum0=`{\fi}\aftergroup\tabu@doclineafter} +\def\tabu@multispan #1#2{% + \ifnum\numexpr#1>\@ne #2\expandafter\tabu@multispan + \else \expandafter\@gobbletwo + \fi {#1-1}{#2}% +}% \tabu@multispan +\def\tabu@startstop #1{\tabu@start@stop #1\relax 1-\tabu@nbcols \@nnil} +\def\tabu@start@stop #1-#2\@nnil{% + \@defaultunits \tabu@start\number 0#1\relax \@nnil + \@defaultunits \tabu@stop \number 0#2\relax \@nnil + \tabu@stop \ifnum \tabu@start>\tabu@nbcols \m@ne + \else\ifnum \tabu@stop=\z@ \tabu@nbcols + \else\ifnum \tabu@stop>\tabu@nbcols \tabu@nbcols + \else \tabu@stop + \fi\fi\fi + \advance\tabu@start \m@ne + \ifnum \tabu@start>\z@ \advance\tabu@stop -\tabu@start \fi +}% \tabu@start@stop +%% Numbers: siunitx S columns (and \tabudecimal) ------------------- +\def\tabu@tabudecimal #1{% + \def\tabu@decimal{#1}\@temptokena{}% + \let\tabu@getdecimal@ \tabu@getdecimal@ignorespaces + \tabu@scandecimal +}% \tabu@tabudecimal +\def\tabu@scandecimal{\futurelet \tabu@temp \tabu@getdecimal@} +\def\tabu@skipdecimal#1{#1\tabu@scandecimal} +\def\tabu@getdecimal@ignorespaces{% + \ifcase 0\ifx\tabu@temp\ignorespaces\else + \ifx\tabu@temp\@sptoken1\else + 2\fi\fi\relax + \let\tabu@getdecimal@ \tabu@getdecimal + \expandafter\tabu@skipdecimal + \or \expandafter\tabu@gobblespace\expandafter\tabu@scandecimal + \else \expandafter\tabu@skipdecimal + \fi +}% \tabu@getdecimal@ignorespaces +\def\tabu@get@decimal#1{\@temptokena\expandafter{\the\@temptokena #1}% + \tabu@scandecimal} +\def\do#1{% + \def\tabu@get@decimalspace#1{% + \@temptokena\expandafter{\the\@temptokena #1}\tabu@scandecimal}% +}\do{ } +\let\tabu@@tabudecimal \tabu@tabudecimal +\def\tabu@getdecimal{% + \ifcase 0\ifx 0\tabu@temp\else + \ifx 1\tabu@temp\else + \ifx 2\tabu@temp\else + \ifx 3\tabu@temp\else + \ifx 4\tabu@temp\else + \ifx 5\tabu@temp\else + \ifx 6\tabu@temp\else + \ifx 7\tabu@temp\else + \ifx 8\tabu@temp\else + \ifx 9\tabu@temp\else + \ifx .\tabu@temp\else + \ifx ,\tabu@temp\else + \ifx -\tabu@temp\else + \ifx +\tabu@temp\else + \ifx e\tabu@temp\else + \ifx E\tabu@temp\else + \ifx\tabu@cellleft\tabu@temp1\else + \ifx\ignorespaces\tabu@temp1\else + \ifx\@sptoken\tabu@temp2\else + 3\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\relax + \expandafter\tabu@get@decimal + \or \expandafter\tabu@skipdecimal + \or \expandafter\tabu@get@decimalspace + \else\expandafter\tabu@printdecimal + \fi +}% \tabu@getdecimal +\def\tabu@printdecimal{% + \edef\tabu@temp{\the\@temptokena}% + \ifx\tabu@temp\@empty\else + \ifx\tabu@temp\space\else + \expandafter\tabu@decimal\expandafter{\the\@temptokena}% + \fi\fi +}% \tabu@printdecimal +%% Verbatim inside X columns ---------------------------------------- +\def\tabu@verbatim{% + \let\verb \tabu@verb + \let\FV@DefineCheckEnd \tabu@FV@DefineCheckEnd +}% \tabu@verbatim +\let\tabu@ltx@verb \verb +\def\tabu@verb{\@ifstar {\tabu@ltx@verb*} \tabu@ltx@verb} +\def\tabu@fancyvrb {% + \def\tabu@FV@DefineCheckEnd ##1{% + \def\tabu@FV@DefineCheckEnd{% + ##1% <original definition (if fancyvrb is loaded)> + \let\FV@CheckEnd \tabu@FV@CheckEnd + \let\FV@@CheckEnd \tabu@FV@@CheckEnd + \let\FV@@@CheckEnd \tabu@FV@@@CheckEnd + \edef\FV@EndScanning{% + \def\noexpand\next{\noexpand\end{\FV@EnvironName}}% + \global\let\noexpand\FV@EnvironName\relax + \noexpand\next}% + \xdef\FV@EnvironName{\detokenize\expandafter{\FV@EnvironName}}}% + }\expandafter\tabu@FV@DefineCheckEnd\expandafter{\FV@DefineCheckEnd} +}% \tabu@fancyvrb +\def\tabu@FV@CheckEnd #1{\expandafter\FV@@CheckEnd \detokenize{#1\end{}}\@nil} +\edef\tabu@FV@@@CheckEnd {\detokenize{\end{}}} +\begingroup +\catcode`\[1 \catcode`\]2 +\@makeother\{ \@makeother\} + \edef\x[\endgroup + \def\noexpand\tabu@FV@@CheckEnd ##1\detokenize[\end{]##2\detokenize[}]##3% + ]\x \@nil{\def\@tempa{#2}\def\@tempb{#3}} +\def\tabu@FV@ListProcessLine #1{% + \hbox {%to \hsize{% + \kern\leftmargin + \hbox {%to \linewidth{% + \FV@LeftListNumber + \FV@LeftListFrame + \FancyVerbFormatLine{#1}\hss +%% DG/SR modification begin - Jan. 28, 1998 (for numbers=right add-on) +%% \FV@RightListFrame}% + \FV@RightListFrame + \FV@RightListNumber}% +%% DG/SR modification end + \hss}} +%% \savetabu -------------------------------------------------------- +\newcommand*\savetabu[1]{\noalign{% + \tabu@sanitizearg{#1}\tabu@temp + \ifx \tabu@temp\@empty \tabu@savewarn{}{The tabu will not be saved}\else + \@ifundefined{tabu@saved@\tabu@temp}{}{\tabu@savewarn{#1}{Overwritting}}% + \ifdefined\tabu@restored \expandafter\let + \csname tabu@saved@\tabu@temp \endcsname \tabu@restored + \else {\tabu@save}% + \fi + \fi}% +}% \savetabu +\def\tabu@save {% + \toks0\expandafter{\tabu@saved@}% + \iftabu@negcoef + \let\tabu@wddef \relax \let\tabu@ \tabu@savewd \edef\tabu@savewd{\tabu@Xcoefs}% + \toks0\expandafter{\the\toks\expandafter0\tabu@savewd}\fi + \toks1\expandafter{\tabu@savedpream}% + \toks2\expandafter{\tabu@savedpreamble}% + \let\@preamble \relax + \let\tabu@savedpream \relax \let\tabu@savedparams \relax + \edef\tabu@preamble{% + \def\noexpand\tabu@aligndefault{\tabu@align}% + \def\tabu@savedparams {\noexpand\the\toks0}% + \def\tabu@savedpream {\noexpand\the\toks1}}% + \edef\tabu@usetabu{% + \def\@preamble {\noexpand\the\toks2}% + \tabu@target \the\tabu@target \relax + \tabucolX \the\tabucolX \relax + \tabu@nbcols \the\tabu@nbcols \relax + \def\noexpand\tabu@aligndefault{\tabu@align}% + \def\tabu@savedparams {\noexpand\the\toks0}% + \def\tabu@savedpream {\noexpand\the\toks1}}% + \let\tabu@aligndefault \relax \let\@sharp \relax + \edef\@tempa{\noexpand\tabu@s@ved + {\tabu@usetabu} + {\tabu@preamble} + {\the\toks1}}\@tempa + \tabu@message@save +}% \tabu@save +\long\def\tabu@s@ved #1#2#3{% + \def\tabu@usetabu{#1}% <for \tabu@message@save> + \expandafter\gdef\csname tabu@saved@\tabu@temp\endcsname ##1{% + \ifodd ##1% \usetabu + \tabu@measuringfalse \tabu@spreadfalse % Just in case... + \gdef\tabu@usetabu {% + \ifdim \tabu@target>\z@ \tabu@warn@usetabu \fi + \global\let\tabu@usetabu \@undefined + \def\@halignto {to\tabu@target}% + #1% + \ifx \tabu@align\tabu@aligndefault@text + \ifnum \tabu@nested=\z@ + \let\tabu@align \tabu@aligndefault \fi\fi}% + \else % \preamble + \gdef\tabu@preamble {% + \global\let\tabu@preamble \@undefined + #2% + \ifx \tabu@align\tabu@aligndefault@text + \ifnum \tabu@nested=\z@ + \let\tabu@align \tabu@aligndefault \fi\fi}% + \fi + #3}% +}% \tabu@s@ved +\def\tabu@aligndefault@text {\tabu@aligndefault}% +\def\tabu@warn@usetabu {\PackageWarning{tabu} + {Specifying a target with \string\usetabu\space is useless + \MessageBreak The target cannot be changed!}} +\def\tabu@savewd #1#2{\ifdim #2\p@<\z@ \tabu@wddef{#1}{\tabu@wd{#1}}\fi} +\def\tabu@savewarn#1#2{\PackageInfo{tabu} + {User-name `#1' already used for \string\savetabu + \MessageBreak #2}}% +\def\tabu@saveerr#1{\PackageError{tabu} + {User-name `#1' is unknown for \string\usetabu + \MessageBreak I cannot restore an unknown preamble!}\@ehd} +%% \rowfont --------------------------------------------------------- +\newskip \tabu@cellskip +\def\tabu@rowfont{\ifdim \baselineskip=\z@\noalign\fi + {\ifnum0=`}\fi \tabu@row@font} +\newcommand*\tabu@row@font[2][]{% + \ifnum7=\currentgrouptype + \global\let\tabu@@cellleft \tabu@cellleft + \global\let\tabu@@cellright \tabu@cellright + \global\let\tabu@@celllalign \tabu@celllalign + \global\let\tabu@@cellralign \tabu@cellralign + \global\let\tabu@@rowfontreset\tabu@rowfontreset + \fi + \global\let\tabu@rowfontreset \tabu@rowfont@reset + \expandafter\gdef\expandafter\tabu@cellleft\expandafter{\tabu@cellleft #2}% + \ifcsname tabu@cell@#1\endcsname % row alignment + \csname tabu@cell@#1\endcsname \fi + \ifnum0=`{\fi}% end of group / noalign group +}% \rowfont +\def\tabu@ifcolorleavevmode #1{\let\color \tabu@leavevmodecolor #1\let\color\tabu@color}% +\def\tabu@rowfont@reset{% + \global\let\tabu@rowfontreset \tabu@@rowfontreset + \global\let\tabu@cellleft \tabu@@cellleft + \global\let\tabu@cellright \tabu@@cellright + \global\let\tabu@cellfont \@empty + \global\let\tabu@celllalign \tabu@@celllalign + \global\let\tabu@cellralign \tabu@@cellralign +}% \tabu@@rowfontreset +\let\tabu@rowfontreset \@empty % overwritten \AtBeginDocument if colortbl +%% \tabu@prepnext@tok ----------------------------------------------- +\newif \iftabu@cellright +\def\tabu@prepnext@tok{% + \ifnum \count@<\z@ % <first initialisation> + \@tempcnta \@M % <not initialized by array.sty> + \tabu@nbcols\z@ + \let\tabu@fornoopORI \@fornoop + \tabu@cellrightfalse + \else + \ifcase \numexpr \count@-\@tempcnta \relax % (case 0): prev. token is left + \advance \tabu@nbcols \@ne + \iftabu@cellright % before-previous token is right and is finished + \tabu@cellrightfalse % <only once> + \tabu@righttok + \fi + \tabu@lefttok + \or % (case 1) previous token is right + \tabu@cellrighttrue \let\@fornoop \tabu@lastnoop + \else % special column: do not change the token + \iftabu@cellright % before-previous token is right + \tabu@cellrightfalse + \tabu@righttok + \fi + \fi % \ifcase + \fi + \tabu@prepnext@tokORI +}% \tabu@prepnext@tok +\long\def\tabu@lastnoop#1\@@#2#3{\tabu@lastn@@p #2\@nextchar \in@\in@@} +\def\tabu@lastn@@p #1\@nextchar #2#3\in@@{% + \ifx \in@#2\else + \let\@fornoop \tabu@fornoopORI + \xdef\tabu@mkpreambuffer{\tabu@nbcols\the\tabu@nbcols \tabu@mkpreambuffer}% + \toks0\expandafter{\expandafter\tabu@everyrowtrue \the\toks0}% + \expandafter\prepnext@tok + \fi +}% \tabu@lastnoop +\def\tabu@righttok{% + \advance \count@ \m@ne + \toks\count@\expandafter {\the\toks\count@ \tabu@cellright \tabu@cellralign}% + \advance \count@ \@ne +}% \tabu@righttok +\def\tabu@lefttok{\toks\count@\expandafter{\expandafter\tabu@celllalign + \the\toks\count@ \tabu@cellleft}% after because of $ +}% \tabu@lefttok +%% Neutralisation of glues ------------------------------------------ +\let\tabu@cellleft \@empty +\let\tabu@cellright \@empty +\tabu@celllalign@def{\tabu@cellleft}% +\let\tabu@cellralign \@empty +\def\tabu@cell@align #1#2#3{% + \let\tabu@maybesiunitx \toks@ \tabu@celllalign + \global \expandafter \tabu@celllalign@def \expandafter {\the\toks@ #1}% + \toks@\expandafter{\tabu@cellralign #2}% + \xdef\tabu@cellralign{\the\toks@}% + \toks@\expandafter{\tabu@cellleft #3}% + \xdef\tabu@cellleft{\the\toks@}% +}% \tabu@cell@align +\def\tabu@cell@l{% force alignment to left + \tabu@cell@align + {\tabu@removehfil \raggedright \tabu@cellleft}% left + {\tabu@flush1\tabu@ignorehfil}% right + \raggedright +}% \tabu@cell@l +\def\tabu@cell@c{% force alignment to center + \tabu@cell@align + {\tabu@removehfil \centering \tabu@flush{.5}\tabu@cellleft} + {\tabu@flush{.5}\tabu@ignorehfil} + \centering +}% \tabu@cell@c +\def\tabu@cell@r{% force alignment to right + \tabu@cell@align + {\tabu@removehfil \raggedleft \tabu@flush1\tabu@cellleft} + \tabu@ignorehfil + \raggedleft +}% \tabu@cell@r +\def\tabu@cell@j{% force justification (for p, m, b columns) + \tabu@cell@align + {\tabu@justify\tabu@cellleft} + {} + \tabu@justify +}% \tabu@cell@j +\def\tabu@justify{% + \leftskip\z@skip \@rightskip\leftskip \rightskip\@rightskip + \parfillskip\@flushglue +}% \tabu@justify +%% ragged2e settings +\def\tabu@cell@L{% force alignment to left (ragged2e) + \tabu@cell@align + {\tabu@removehfil \RaggedRight \tabu@cellleft} + {\tabu@flush 1\tabu@ignorehfil} + \RaggedRight +}% \tabu@cell@L +\def\tabu@cell@C{% force alignment to center (ragged2e) + \tabu@cell@align + {\tabu@removehfil \Centering \tabu@flush{.5}\tabu@cellleft} + {\tabu@flush{.5}\tabu@ignorehfil} + \Centering +}% \tabu@cell@C +\def\tabu@cell@R{% force alignment to right (ragged2e) + \tabu@cell@align + {\tabu@removehfil \RaggedLeft \tabu@flush 1\tabu@cellleft} + \tabu@ignorehfil + \RaggedLeft +}% \tabu@cell@R +\def\tabu@cell@J{% force justification (ragged2e) + \tabu@cell@align + {\justifying \tabu@cellleft} + {} + \justifying +}% \tabu@cell@J +\def\tabu@flush#1{% + \iftabu@colortbl % colortbl uses \hfill rather than \hfil + \hskip \ifnum13<\currentgrouptype \stretch{#1}% + \else \ifdim#1pt<\p@ \tabu@cellskip + \else \stretch{#1} + \fi\fi \relax + \else % array.sty + \ifnum 13<\currentgrouptype + \hfil \hskip1sp \relax \fi + \fi +}% \tabu@flush +\let\tabu@hfil \hfil +\let\tabu@hfill \hfill +\let\tabu@hskip \hskip +\def\tabu@removehfil{% + \iftabu@colortbl + \unkern \tabu@cellskip =\lastskip + \ifnum\gluestretchorder\tabu@cellskip =\tw@ \hskip-\tabu@cellskip + \else \tabu@cellskip \z@skip + \fi + \else + \ifdim\lastskip=1sp\unskip\fi + \ifnum\gluestretchorder\lastskip =\@ne + \hfilneg % \hfilneg for array.sty but not for colortbl... + \fi + \fi +}% \tabu@removehfil +\def\tabu@ignorehfil{\aftergroup \tabu@nohfil} +\def\tabu@nohfil{% \hfil -> do nothing + restore original \hfil + \def\hfil{\let\hfil \tabu@hfil}% local to (alignment template) group +}% \tabu@nohfil +\def\tabu@colortblalignments {% if colortbl + \def\tabu@nohfil{% + \def\hfil {\let\hfil \tabu@hfil}% local to (alignment template) group + \def\hfill {\let\hfill \tabu@hfill}% (colortbl uses \hfill) pfff... + \def\hskip ####1\relax{\let\hskip \tabu@hskip}}% local +}% \tabu@colortblalignments +%% Taking care of footnotes and hyperfootnotes ---------------------- +\long\def\tabu@footnotetext #1{% + \edef\@tempa{\the\tabu@footnotes + \noexpand\footnotetext [\the\csname c@\@mpfn\endcsname]}% + \global\tabu@footnotes\expandafter{\@tempa {#1}}}% +\long\def\tabu@xfootnotetext [#1]#2{% + \global\tabu@footnotes\expandafter{\the\tabu@footnotes + \footnotetext [{#1}]{#2}}} +\let\tabu@xfootnote \@xfootnote +\long\def\tabu@Hy@ftntext{\tabu@Hy@ftntxt {\the \c@footnote }} +\long\def\tabu@Hy@xfootnote [#1]{% + \begingroup + \value\@mpfn #1\relax + \protected@xdef \@thefnmark {\thempfn}% + \endgroup + \@footnotemark \tabu@Hy@ftntxt {#1}% +}% \tabu@Hy@xfootnote +\long\def\tabu@Hy@ftntxt #1#2{% + \edef\@tempa{% + \the\tabu@footnotes + \begingroup + \value\@mpfn #1\relax + \noexpand\protected@xdef\noexpand\@thefnmark {\noexpand\thempfn}% + \expandafter \noexpand \expandafter + \tabu@Hy@footnotetext \expandafter{\Hy@footnote@currentHref}% + }% + \global\tabu@footnotes\expandafter{\@tempa {#2}% + \endgroup}% +}% \tabu@Hy@ftntxt +\long\def\tabu@Hy@footnotetext #1#2{% + \H@@footnotetext{% + \ifHy@nesting + \hyper@@anchor {#1}{#2}% + \else + \Hy@raisedlink{% + \hyper@@anchor {#1}{\relax}% + }% + \def\@currentHref {#1}% + \let\@currentlabelname \@empty + #2% + \fi + }% +}% \tabu@Hy@footnotetext +%% No need for \arraybackslash ! ------------------------------------ +\def\tabu@latextwoe {% +\def\tabu@temp##1##2##3{{\toks@\expandafter{##2##3}\xdef##1{\the\toks@}}} +\tabu@temp \tabu@centering \centering \arraybackslash +\tabu@temp \tabu@raggedleft \raggedleft \arraybackslash +\tabu@temp \tabu@raggedright \raggedright \arraybackslash +}% \tabu@latextwoe +\def\tabu@raggedtwoe {% +\def\tabu@temp ##1##2##3{{\toks@\expandafter{##2##3}\xdef##1{\the\toks@}}} +\tabu@temp \tabu@Centering \Centering \arraybackslash +\tabu@temp \tabu@RaggedLeft \RaggedLeft \arraybackslash +\tabu@temp \tabu@RaggedRight \RaggedRight \arraybackslash +\tabu@temp \tabu@justifying \justifying \arraybackslash +}% \tabu@raggedtwoe +\def\tabu@normalcrbackslash{\let\\\@normalcr} +\def\tabu@trivlist{\expandafter\def\expandafter\@trivlist\expandafter{% + \expandafter\tabu@normalcrbackslash \@trivlist}} +%% Utilities: \fbox \fcolorbox and \tabudecimal ------------------- +\def\tabu@fbox {\leavevmode\afterassignment\tabu@beginfbox \setbox\@tempboxa\hbox} +\def\tabu@beginfbox {\bgroup \kern\fboxsep + \bgroup\aftergroup\tabu@endfbox} +\def\tabu@endfbox {\kern\fboxsep\egroup\egroup + \@frameb@x\relax} +\def\tabu@color@b@x #1#2{\leavevmode \bgroup + \def\tabu@docolor@b@x{#1{#2\color@block{\wd\z@}{\ht\z@}{\dp\z@}\box\z@}}% + \afterassignment\tabu@begincolor@b@x \setbox\z@ \hbox +}% \tabu@color@b@x +\def\tabu@begincolor@b@x {\kern\fboxsep \bgroup + \aftergroup\tabu@endcolor@b@x \set@color} +\def\tabu@endcolor@b@x {\kern\fboxsep \egroup + \dimen@\ht\z@ \advance\dimen@ \fboxsep \ht\z@ \dimen@ + \dimen@\dp\z@ \advance\dimen@ \fboxsep \dp\z@ \dimen@ + \tabu@docolor@b@x \egroup +}% \tabu@endcolor@b@x +%% Corrections (arydshln, delarray, colortbl) ----------------------- +\def\tabu@fix@arrayright {%% \@arrayright is missing from \endarray + \iftabu@colortbl + \ifdefined\adl@array % <colortbl + arydshln> + \def\tabu@endarray{% + \adl@endarray \egroup \adl@arrayrestore \CT@end \egroup %<original> + \@arrayright % <FC> + \gdef\@preamble{}}% <FC> + \else % <colortbl / no arydshln> + \def\tabu@endarray{% + \crcr \egroup \egroup %<original> + \@arrayright % <FC> + \gdef\@preamble{}\CT@end}% + \fi + \else + \ifdefined\adl@array % <arydshln / no colortbl> + \def\tabu@endarray{% + \adl@endarray \egroup \adl@arrayrestore \egroup %<original> + \@arrayright % <FC> + \gdef\@preamble{}}% <FC> + \else % <no arydshln / no colotbl + \@arrayright missing> + \PackageWarning{tabu} + {\string\@arrayright\space is missing from the + \MessageBreak definition of \string\endarray. + \MessageBreak Comptability with delarray.sty is broken.}% + \fi\fi +}% \tabu@fix@arrayright +\def\tabu@adl@xarraydashrule #1#2#3{% + \ifnum\@lastchclass=\adl@class@start\else + \ifnum\@lastchclass=\@ne\else + \ifnum\@lastchclass=5 \else % <FC> @-arg (class 5) and !-arg (class 1) + \adl@leftrulefalse \fi\fi % must be treated the same + \fi + \ifadl@zwvrule\else \ifadl@inactive\else + \@addtopreamble{\vrule\@width\arrayrulewidth + \@height\z@ \@depth\z@}\fi \fi + \ifadl@leftrule + \@addtopreamble{\adl@vlineL{\CT@arc@}{\adl@dashgapcolor}% + {\number#1}#3}% + \else \@addtopreamble{\adl@vlineR{\CT@arc@}{\adl@dashgapcolor}% + {\number#2}#3} + \fi +}% \tabu@adl@xarraydashrule +\def\tabu@adl@act@endpbox {% + \unskip \ifhmode \nobreak \fi \@finalstrut \@arstrutbox +%%TABU-FIXED +\color@endgroup + \egroup \egroup + \adl@colhtdp \box\adl@box \hfil +}% \tabu@adl@act@endpbox +\def\tabu@adl@fix {% + \let\adl@xarraydashrule \tabu@adl@xarraydashrule % <fix> arydshln + \let\adl@act@endpbox \tabu@adl@act@endpbox % <fix> arydshln + \let\adl@act@@endpbox \tabu@adl@act@endpbox % <fix> arydshln + \let\@preamerror \@preamerr % <fix> arydshln +}% \tabu@adl@fix +%% Correction for longtable' \@startbox definition ------------------ +%% => \everypar is ``missing'' : TeX should be in vertical mode +\def\tabu@LT@startpbox #1{% +%%TABU-FIXED add \color@begingroup + \bgroup\color@begingroup + \let\@footnotetext\LT@p@ftntext + \setlength\hsize{#1}% + \@arrayparboxrestore + \everypar{% + \vrule \@height \ht\@arstrutbox \@width \z@ + \everypar{}}% +}% \tabu@LT@startpbox +%% \tracingtabu and the package options ------------------ +\DeclareOption{delarray}{\AtEndOfPackage{\RequirePackage{delarray}}} +\DeclareOption{linegoal}{% + \AtEndOfPackage{% + \RequirePackage{linegoal}[2010/12/07]% + \let\tabudefaulttarget \linegoal% \linegoal is \linewidth if not pdfTeX +}} +\DeclareOption{scantokens}{\tabuscantokenstrue} +\DeclareOption{debugshow}{\AtEndOfPackage{\tracingtabu=\tw@}} +\def\tracingtabu {\begingroup\@ifnextchar=% + {\afterassignment\tabu@tracing\count@} + {\afterassignment\tabu@tracing\count@1\relax}} +\def\tabu@tracing{\expandafter\endgroup + \expandafter\tabu@tr@cing \the\count@ \relax +}% \tabu@tracing +\def\tabu@tr@cing #1\relax {% + \ifnum#1>\thr@@ \let\tabu@tracinglines\message + \else \let\tabu@tracinglines\@gobble + \fi + \ifnum#1>\tw@ \let\tabu@DBG \tabu@@DBG + \def\tabu@mkarstrut {\tabu@DBG@arstrut}% + \tabustrutrule 1.5\p@ + \else \let\tabu@DBG \@gobble + \def\tabu@mkarstrut {\tabu@arstrut}% + \tabustrutrule \z@ + \fi + \ifnum#1>\@ne \let\tabu@debug \message + \else \let\tabu@debug \@gobble + \fi + \ifnum#1>\z@ + \let\tabu@message \message + \let\tabu@tracing@save \tabu@message@save + \let\tabu@starttimer \tabu@pdftimer + \else + \let\tabu@message \@gobble + \let\tabu@tracing@save \@gobble + \let\tabu@starttimer \relax + \fi +}% \tabu@tr@cing +%% Setup \AtBeginDocument +\AtBeginDocument{\tabu@AtBeginDocument} +\def\tabu@AtBeginDocument{\let\tabu@AtBeginDocument \@undefined + \ifdefined\arrayrulecolor \tabu@colortbltrue % <colortbl> + \tabu@colortblalignments % different glues are used + \else \tabu@colortblfalse \fi + \ifdefined\CT@arc@ \else \let\CT@arc@ \relax \fi + \ifdefined\CT@drsc@\else \let\CT@drsc@ \relax \fi + \let\tabu@arc@L \CT@arc@ \let\tabu@drsc@L \CT@drsc@ + \ifodd 1\ifcsname siunitx_table_collect_begin:Nn\endcsname % <siunitx: ok> + \expandafter\ifx + \csname siunitx_table_collect_begin:Nn\endcsname\relax 0\fi\fi\relax + \tabu@siunitxtrue + \else \let\tabu@maybesiunitx \@firstofone % <not siunitx: setup> + \let\tabu@siunitx \tabu@nosiunitx + \tabu@siunitxfalse + \fi + \ifdefined\adl@array % <arydshln> + \else \let\tabu@adl@fix \relax + \let\tabu@adl@endtrial \@empty \fi + \ifdefined\longtable % <longtable> + \else \let\longtabu \tabu@nolongtabu \fi + \ifdefined\cellspacetoplimit \tabu@warn@cellspace\fi + \csname\ifcsname ifHy@hyperfootnotes\endcsname % <hyperfootnotes> + ifHy@hyperfootnotes\else iffalse\fi\endcsname + \let\tabu@footnotetext \tabu@Hy@ftntext + \let\tabu@xfootnote \tabu@Hy@xfootnote \fi + \ifdefined\FV@DefineCheckEnd% <fancyvrb> + \tabu@fancyvrb \fi + \ifdefined\color % <color / xcolor> + \let\tabu@color \color + \def\tabu@leavevmodecolor ##1{% + \def\tabu@leavevmodecolor {\leavevmode ##1}% + }\expandafter\tabu@leavevmodecolor\expandafter{\color}% + \else + \let\tabu@color \tabu@nocolor + \let\tabu@leavevmodecolor \@firstofone \fi + \tabu@latextwoe + \ifdefined\@raggedtwoe@everyselectfont % <ragged2e> + \tabu@raggedtwoe + \else + \let\tabu@cell@L \tabu@cell@l + \let\tabu@cell@R \tabu@cell@r + \let\tabu@cell@C \tabu@cell@c + \let\tabu@cell@J \tabu@cell@j \fi + \expandafter\in@ \expandafter\@arrayright \expandafter{\endarray}% + \ifin@ \let\tabu@endarray \endarray + \else \tabu@fix@arrayright \fi% <fix for colortbl & arydshln (delarray)> + \everyrow{}% +}% \tabu@AtBeginDocument +\def\tabu@warn@cellspace{% + \PackageWarning{tabu}{% + Package cellspace has some limitations + \MessageBreak And redefines some macros of array.sty. + \MessageBreak Please use \string\tabulinesep\space to control + \MessageBreak vertical spacing of lines inside tabu environnement}% +}% \tabu@warn@cellspace +%% tabu Package initialisation +\tabuscantokensfalse +\let\tabu@arc@G \relax +\let\tabu@drsc@G \relax +\let\tabu@evr@G \@empty +\let\tabu@rc@G \@empty +\def\tabu@ls@G {\tabu@linestyle@}% +\let\tabu@@rowfontreset \@empty % <init> +\let\tabu@@celllalign \@empty +\let\tabu@@cellralign \@empty +\let\tabu@@cellleft \@empty +\let\tabu@@cellright \@empty +\def\tabu@naturalXmin {\z@} +\def\tabu@naturalXmax {\z@} +\let\tabu@rowfontreset \@empty +\def\tabulineon {4pt}\let\tabulineoff \tabulineon +\tabu@everyrowtrue +\ifdefined\pdfelapsedtime % <pdfTeX> + \def\tabu@pdftimer {\xdef\tabu@starttime{\the\pdfelapsedtime}}% +\else \let\tabu@pdftimer \relax \let\tabu@message@etime \relax +\fi +\tracingtabu=\z@ +\newtabulinestyle {=\maxdimen}% creates the 'factory' settings \tabu@linestyle@ +\tabulinestyle{} +\taburowcolors{} +\let\tabudefaulttarget \linewidth +\ProcessOptions* % \ProcessOptions* is quicker ! +\endinput +%% +%% End of file `tabu.sty'. |