% \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 %<*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 % %<*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 { preamble } => target specified \string\begin{tabu} spread { 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= \string\extrarowdepth= or: \string\extrarowsep= => may be prefixed by \string\global Dynamic vertical spacing adjustment: \string\abovetabulinesep= \string\belowtabulinesep= or: \string\tabulinesep= => 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 \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 % %<*ignore> \fi % %<*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} % % \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} %¤%% 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} %¤%% 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 % @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}} %¤%% 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} % %¤%% 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} % %¤%% \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} %¤%% 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} %¤%% 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} %¤%% 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 % @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 % \else \in@false % \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} % %¤%% 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}} %¤%% \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 % \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} %¤%% 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} % %¤%% \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 % \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 % \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 % 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 % \let\tabu@drsc@Gsave \tabu@drsc@G \let\tabu@drsc@G \tabu@drsc@L % \let\tabu@ls@Gsave \tabu@ls@G \let\tabu@ls@G \tabu@ls@L % \let\tabu@rc@Gsave \tabu@rc@G \let\tabu@rc@G \tabu@rc@L % \let\tabu@evr@Gsave \tabu@evr@G \let\tabu@evr@G \tabu@evr@L % \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 % \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''} %¤%% 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} %¤%% 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} %¤%% \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} %¤%% 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\\% \def\tabu@rewritten{p}\tabucolX \p@ % \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}} %¤%% \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} % %¤%% 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 % \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 % \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 \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} %¤%% 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} %¤%% 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.}% %¤%% 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 % \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} %¤%% 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} %¤%% 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{% \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 % }% \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} %¤%% 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 % \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})} %¤%% 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)} %¤%% 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 % \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} %¤%% 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 % \@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}} %¤%% \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{% \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{% \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}} %¤%% 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}} %¤%% 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} %¤%% 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% \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}} % %¤%% \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}% \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} %¤%% \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}} %¤%% \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$$) % is the right one of a ``normal'' column. The switch \cs\iftabu@cellright is set to \textt{true}. \\ % The \emph{previous} token (\cs\toks$=$\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$$). % This token is finished and will not change afterwards. % % \item[or: $\mathbf{i=}$\cs\count@$\,=$\cs\@tempcnta$+1$]: the token to prepare (\cs\toks$$) 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$$ 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$=$\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$$ % 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$$) to an empty one. % % \begin{macrocode} \newif \iftabu@cellright \def\tabu@prepnext@tok{% \ifnum \count@<\z@ % \@tempcnta \@M % \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 % \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} %¤%% 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} %¤%% 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}} %¤%% 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}} %¤%% 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} %¤%% 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 % \def\tabu@endarray{% \adl@endarray \egroup \adl@arrayrestore \CT@end \egroup % \@arrayright % \gdef\@preamble{}}% \else % \def\tabu@endarray{% \crcr \egroup \egroup % \@arrayright % \gdef\@preamble{}\CT@end}% \fi \else \ifdefined\adl@array % \def\tabu@endarray{% \adl@endarray \egroup \adl@arrayrestore \egroup % \@arrayright % \gdef\@preamble{}}% \else % \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 % @-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 % arydshln \let\adl@act@endpbox \tabu@adl@act@endpbox % arydshln \let\adl@act@@endpbox \tabu@adl@act@endpbox % arydshln \let\@preamerror \@preamerr % arydshln }% \tabu@adl@fix % \end{macrocode} % % \subsubsection{\xpackage{longtable} \cs{@startpbox}: \cs{everypar} needed} %¤%% Correction for longtable' \@startbox definition ------------------ %¤%% => \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} %¤%% \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}} %¤%% 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 % \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 % \expandafter\ifx \csname siunitx_table_collect_begin:Nn\endcsname\relax 0\fi\fi\relax \tabu@siunitxtrue \else \let\tabu@maybesiunitx \@firstofone % \let\tabu@siunitx \tabu@nosiunitx \tabu@siunitxfalse \fi \ifdefined\adl@array % \else \let\tabu@adl@fix \relax \let\tabu@adl@endtrial \@empty \fi \ifdefined\longtable % \else \let\longtabu \tabu@nolongtabu \fi \ifdefined\cellspacetoplimit \tabu@warn@cellspace\fi \csname\ifcsname ifHy@hyperfootnotes\endcsname % ifHy@hyperfootnotes\else iffalse\fi\endcsname \let\tabu@footnotetext \tabu@Hy@ftntext \let\tabu@xfootnote \tabu@Hy@xfootnote \fi \ifdefined\FV@DefineCheckEnd% \tabu@fancyvrb \fi \ifdefined\color % \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 % \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% \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} % %¤%% 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 % \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 % \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} % % \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