From bb7ef4b993327dd47fb8f1848e1603f93f12eb64 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 5 Mar 2018 22:11:19 +0000 Subject: tabstackengine (5mar18) git-svn-id: svn://tug.org/texlive/trunk@46848 c570f23f-e606-0410-a88d-b1316a301751 --- .../doc/latex/tabstackengine/tabstackengine.pdf | Bin 569190 -> 598495 bytes .../doc/latex/tabstackengine/tabstackengine.tex | 208 +++++++++++++++++---- .../tex/latex/tabstackengine/tabstackengine.sty | 204 ++++++++++++++++++-- 3 files changed, 361 insertions(+), 51 deletions(-) (limited to 'Master') diff --git a/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.pdf b/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.pdf index c288ddfd20f..66dd8ba232b 100644 Binary files a/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.pdf and b/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.pdf differ diff --git a/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.tex b/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.tex index fa4be38a47b..02e3bf02bb4 100644 --- a/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.tex +++ b/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.tex @@ -1,7 +1,7 @@ \documentclass{article} \usepackage[T1]{fontenc} \usepackage{lmodern} -\usepackage{tabstackengine} +\usepackage[TABcline]{tabstackengine} \usepackage{verbatimbox} \usepackage{xcolor} \parindent 0in\parskip 1em \newlength\dotscale @@ -20,12 +20,16 @@ \catcode`<=\active % \catcode`!=\active % \def\vbspecial#1>{\textit{\rmfamily#1}} -\def\vbdelim{\catcode`<=\active \catcode`>=\active \catcode`!=\active \def<{\vbspecial}\def>{}\def!{\textrm{(provided by \ste)}}} +\def\vbdelim{\catcode`<=\active \catcode`>=\active \catcode`!=\active \def<{\vbspecial}\def>{}\def!{\stringrms}} \catcode`!=12 % \catcode`>=12 % \catcode`<=12 % \def\endvbdelim{\catcode`>=12 \catcode`<=12 } +\def\stringrms#1{% + \ifx1#1\relax\textrm{(provided by \ste)}\fi% + \ifx2#1\relax\textrm{(only with \texttt{TABcline} package option)}\fi% +} \begin{document} \begin{center} \LARGE The {\tst} Package\\ \rule{0em}{.7em}\small @@ -45,12 +49,12 @@ such a way that the end-of-line (EOL) character in certain stacking arguments will be taken, by default, as \vb|\\|, rather than a space (which is the default EOL separator in \ste). -The EOL separator can be changed using \ste{}'s \vb|\setstackEOL| macro. +The EOL separator can be changed using \ste{}'s \cmd{setstackEOL} macro. With \tst, command variations are introduced to allow several variants of tabbing within the macro arguments. The default tabbing character is the ampersand (\vb|&|); however, the tabbing character can be reset to -other tokens using the \verb|\setstackTAB| macro. +other tokens using the \vb|\setstackTAB| macro. \begin{sloppypar} In most cases (where it makes sense), a {\ste} macro name may be @@ -145,6 +149,99 @@ Note that these \cmd{setstack...gap} macros are for setting horizontal gaps between columns of a stack. They should not be confused with the \cmd{setstackgap} macro of {\ste} that sets the vertical gap for long and short stacks. + +\section{Horizontal Rules}\label{s:hr} + +As of version 2.10, \tst{} provides the facility to lay down horizontal rules + that fill up the TABstack cell width. +There are two ways that this may be accomplished. +First, the macro \vb|\TABrule[<|\textit{vertical shift}\vb|>]|% +\margcmd{TABrule} + may be specified as the entry in a cell, in order to place a horizontal + rule, of thickness \vb|\fboxrule| across the width of the cell.% +\footnote{The width of the \cmd{TABrule} will actually be the width of + the widest data in that column. This has implications when the + \cmd{fixTABwidth} switch is set true, in that some columns will + be typeset wider than their widest data.} +The optional argument specifies the vertical shift of the rule. +The default vertical shift, initially 0pt, may also be specified in the + length \cmd{TABruleshift}.\margcmd{TABruleshift} + +So, for example, + +\vb|\tabbedstackon{a&bb&CCC&dddd}{&\TABrule&&\TABrule}| + + will yield this result: + \tabbedstackon{a&bb&CCC&dddd}{&\TABrule&&\TABrule}. +Note that the vertical spacing around the \vb|\TABrule| will conform + to the stackengine rules set by \vb|\setstackgap|, for both ``short'' and + ``long'' stacks. +In essence, the \vb|\TABrule|s literally constitute their own row in the stack. + +A \vb|\TABrule| may also constitute a cell that contains actual [non-rule] + data elsewhere on the row. +So, for example, + +\vb|\tabbedLongstack{aa&\TABrule\\\TABrule&bbb}| + +produces the result \tabbedLongstack{aa&\TABrule\\\TABrule&bbb}. + +If a row of the TABstack is to be composed solely of rules, then these rules + can also be achieved in a second way. + +\subsection{The \texttt{TABcline} Package Option}\label{s:rtx} + +There is also introduced in version 2.10, a package option \vb|TABcline|, + invoked in the standard way via \vb|\usepackage[TABcline]{tabstackengine}|. +This option reduces the efficiency of the package slightly, but provides + two macros that can enhance convenience. +The two macros that are activated with this package option are \vb|\TABcline{}|% +\margcmd{TABcline} + and \vb|\relaxTABsyntax|. +The macro + +\vb|\TABcline{<|\textit{col1}\vb|>,<|\textit{col2}\vb|>,<|% + \textit{col3--col4}\vb|>,...}| + +provides a shorthand notation for creating a row of \vb|\TABrule|s. +For example, in a five-column TABstack, the shorthand + +\vb|\TABcline{1,3-4}| + +is equivalent to (assuming column separator as \vb|&|, spaces +inserted for clarity) + +\vb|\TABrule & & \TABrule & \TABrule &| + +Furthermore, if the \vb|\TABcline| occurs prior to the last row of the + TABstack, an end-of-line (EOL) token (\textit{e.g.}, \vb|\\|) is also + suffixed to the replacement. +Thus, + +\vb|\tabbedShortstack{\TABcline{2-3}\TABcline{1,3-4}a&bb&CCC&dddd}| + +produces \tabbedShortstack{\TABcline{2-3}\TABcline{1,3-4}a&bb&CCC&dddd}. + +When the \texttt{TABcline} package option is selected, + the \vb|\relaxTABsyntax|% +\margcmd{relaxTABsyntax} + switch may also be invoked to address an issue of + bad syntax. +Some users have a tendency to tack a trailing stack-EOL to the end of + an input argument, in the manner of \vb|\tabbedLongstack{a&bb\\cc&d\\}|. +This rightfully provokes a \loi{} invalid-index error in \tst{}, because + the syntax implies the creation of a third row of a 2-column TABstack, + for which no column separators have been specified. + +However, some may find the error message difficult to understand, especially + because similar syntax is benign in the \texttt{tabular} environment and + non-fatal in the \texttt{align} family of environments. +If the switch \vb|\relaxTABsyntax| is in force, the compilation will instead + succeed, with the trailing row of the TABstack left blank, in the manner + of {\relaxTABsyntax\tabbedLongstack{a&bb\\cc&d\\}}. +Such syntax is still considered bad form, but by compiling without error, + the visual result may make the source of the problem more obvious to the + user. \clearpage \section{Command Summary} @@ -200,15 +297,20 @@ In the syntax shown below, when there are multiple commands delimited by \rmfamily\normalsize -The macro\margcmd{ensureTABstackMath} +The ``\textit{tabbed EOL separated string}'' can contain not only regular + \LaTeX{} content, but + it may also contain \cmd{TABrule}s and/or \cmd{TABcline}s as discussed + in section~\ref{s:hr}. +The macro\margcmd{ensureTABstackMath}\vspace{-8pt} \begin{verbnobox}[\footnotesize\vbdelim] \ensureTABstackMath{} \end{verbnobox} +\vspace{-8pt} will force any \tst{} stacks within its argument to be processed in math mode, even if the prevailing mode is otherwise \vb|\TABstackText|. The package also provides a set of declarations that can be used to define the - manner in which subsequent TABstacks will be processed: + manner in which subsequent TABstacks will be processed:\vspace{-8pt} \begin{verbnobox}[\footnotesize\vbdelim] \fixTABwidth{T F} \TABstackMath @@ -216,15 +318,17 @@ The package also provides a set of declarations that can be used to define the \TABstackMathstyle{} \TABstackTextstyle{} \clearTABstyle -\setstackEOL{} ! +\setstackEOL{} !1 \setstackTAB{} \TABunaryLeft (\TABbinaryRight) \TABunaryRight (\TABbinaryLeft) \TABbinary +\relaxTABsyntax !2 \end{verbnobox} The following macros can be used for parsing tabbed data outside of a TABstack and also provide various stack metrics for the most recently parsed \tst{} data. +\vspace{-6pt} \begin{verbnobox}[\footnotesize\vbdelim] \readTABstack{} \TABcellRaw[,] @@ -237,6 +341,7 @@ The following macros can be used for parsing tabbed data outside of a \TABht{} \TABdp{} \end{verbnobox} +\vspace{-12pt} \subsection{Command Examples} @@ -249,10 +354,12 @@ Here, the optional argument \vb|[l]| defines the alignment of \textit{all} the columns as ``left.'' The default alignment is \vb|[c]|. \vb|\TABstackTextstyle{\scshape}|\\ -\vb|\tabbedShortunderstack[l]{This& Is &The\\Time & Of&Man's\\ Great&Dis&content}| +\vb|\tabbedShortunderstack[l]{This& Is &The\\Time & Of&Man's\\ |\\ +\vb| Great&Dis&content}| {\small\TABstackTextstyle{\scshape}% - \tabbedShortunderstack[l]{This& Is &The\\Time & Of&Man's\\ Great&Dis&content}} + \tabbedShortunderstack[l]{This& Is &The\\Time & Of&Man's\\ + Great&Dis&content}} Note that spaces around the arguments are absorbed and discarded. Furthermore, the text style has been set to \vb|\scshape|. @@ -310,26 +417,25 @@ This is for stacking two items with \texttt{rlrl...} alignment pattern. \subsection*{Tabular Stack} -This is for stacking two items with specifiable alignment pattern. +This is for stacking items with specifiable alignment pattern. + +\vb|\TABbinary\TABstackMath\setstackgap{S}{0pt}\fboxrule=1pt\relax|\\ +\vb|\tabularShortstack{lcr}{1 + 2(4-3) &=& 6 - 6/2\\|\\ +\vb| \TABcline{1-3}\kern6em & \triangle & \kern6em}| -\vb|\TABbinary\TABstackMath\setstacktabulargap{1ex}%|\\ -\vb| \tabularstackanchor[-1pt]{rcl}%|\\ -\vb| {\rule{7ex}{1pt}&\belowbaseline[0pt]{$\triangle$}%|\\ -\vb| &\rule{7ex}{1pt}}{1 + 3(4-3) &=& 7 - 6/2}|\vspace{1ex} -{\small\TABbinary\TABstackMath\setstacktabulargap{1ex} -\tabularstackanchor[-1pt]{rcl}{\rule{7ex}{1pt}&\belowbaseline[0pt]{% -$\triangle$}&\rule{7ex}{1pt}}{1 + 2(4-3) &=& 6 - 6/2}} +{\small\TABbinary\TABstackMath\setstackgap{S}{0pt}\fboxrule=1pt\relax +\tabularShortstack{lcr}{1 + 2(4-3) &=& 6 - 6/2\\ + \TABcline{1-3}\kern6em & \triangle & \kern6em}} Note the use of \vb|\TABbinary|, which applies a group to the beginning and end of each cell, in the event a binary treatment of leading/trailing operators is desired. So, in this case, a cell containing \vb|=| will be set as \vb|{}={}|. In the absence of that declaration, the cell containing -the equal sign would have to have been explicitly defined as \vb|{}=| - in order to override the \vb|\unaryLeft| default setting of the package, - which only places a group at the end of each cell. -Note also the use of a negative stacking gap, which is a perfectly +the equal sign would have to have been explicitly defined as \vb|={}| + (in accordance with the \vb|\TABunaryLeft| default setting of the package). +Negative vertical stacking gap, while not used here, is a perfectly acceptable syntax and can be used to achieve overlap, if desired. \subsection*{Fixed Tab Width (equal width columns, based on largest)} @@ -356,22 +462,32 @@ By default, for the parsing of columns within a given row, this package employs This value can be changed via \vb|\setstackTAB{|\vb|}|,% \margcmd{setstackTAB} where the argument is the newly desired tabbing token. -It can be any of various tokens, including a space token, if one wishes to +It can be any of various tokens\footnote{% +Since \tst{} uses the \loi{} package for parsing rows and columns, + see the \loi{} package documentation for limitations on the tokens that + can be used as a valid parsing separator.} +, including a space token, if one wishes to parse a space-separated list of columns. \end{sloppypar} -\subsection*{TABstacks Inside the \texttt{tabular} Environment} +\subsection*{TABstacks Inside the \texttt{tabular} or \texttt{align} + Environments} When invoking a TABstack inside another tabbed environment, such as - \vb|tabular|, \vb|align|, or other similar environments, one must group - the TABstacks in their own braces \vb|{}|: + \vb|tabular|, \vb|align|, or other similar environments, one + \textbf{no longer}\footnote{% + As of version 2.10, the problem of properly scoping TABstack argument + was resolved with the use of ``brace hacks'' described on p.\,385 of the + \TeX book, and suggested to the author by Prof. Enrico Gregorio. +} + needs to group the TABstacks in their own braces \vb|{}|: \begin{verbnobox}[\footnotesize\vbdelim] \ensureTABstackMath{% \begin{tabular}{c|c} Left Eqn. & Right Eqn.\\ \hline -{\tabularCenterstack{lr}{a_1 & 12\\c & 1234}} & \ -{\tabularCenterstack{rl}{a_1 & 12\\c & 1234}}\\ +\tabularCenterstack{lr}{a_1 & 12\\c & 1234} & \ +\tabularCenterstack{rl}{a_1 & 12\\c & 1234}\\ \hline \end{tabular} } @@ -381,8 +497,8 @@ Left Eqn. & Right Eqn.\\ \begin{tabular}{c|c} Left Eqn. & Right Eqn.\\ \hline -{\tabularCenterstack{lr}{a_1 & 12\\c & 1234}} & -{\tabularCenterstack{rl}{a_1 & 12\\c & 1234}}\\ +\tabularCenterstack{lr}{a_1 & 12\\c & 1234} & +\tabularCenterstack{rl}{a_1 & 12\\c & 1234}\\ \hline \end{tabular} } @@ -540,7 +656,7 @@ Since the \vb|\readTABstack| macro, itself, neither knows nor determines the Therefore, if \vb|\TABcellBox| is called following an independent invocation of \vb|\readTABstack|, center alignment of the cell content will be provided, by default, which can be overridden - with the optional argment to \vb|\TABcellBox|. + with the optional argument to \vb|\TABcellBox|. Note that the height/depth of the \vb|\TABcellBox| reflects the height and depth of the row content of the TABstack. @@ -624,15 +740,13 @@ However, in that case, \vb|\TABcells{2}| would still, in fact, yield \section{Absent Features/Tricky Syntax} -\textbf{1. Nothing Equivalent to} \vb|\hline| or \vb`|` +\textbf{1. Nothing Equivalent to} \vb`|` This is not a bug, but rather a notation of a missing feature. Currently -there is nothing equivalent to \vb|\hline| available for use in -\tst{} arguments. -Furthermore, vertical lines may \textbf{not} be added to a tabular stack +vertical lines may \textbf{not} be added to a tabular stack with the use of \vb`|` elements in the column specifier. -\textbf{2. Empty Items Are Not Ignored (by Default)} +\textbf{2. Trailing Row Separator/Empty Items Are Not Ignored (by Default)} The \loi{} package used to parse TABstack input, does not, by default, ignore empty items. @@ -641,12 +755,12 @@ Take, for example, the well formed TABstack invocation, \vb|\tabularLongstack{rc}{11&12\\21&22\\31&32}|. -Adding a trailing \vb|\\| to the input, as in: +Adding a trailing \vb|\\| row separator to the input, as in: \vb|\tabularLongstack{rc}{11&12\\21&22\\31&32\\}|, however, breaks the parsing because 2 columns of data are expected - following the final \vb|\\| (even though such syntax is accepted + following the final \vb|\\| (even though such syntax is benign in, for example, the \texttt{tabular} environment). This syntax can be immediately made acceptable by invoking the \loi{} declaration \cmd{ignoreemptyitems}, in which case @@ -663,11 +777,22 @@ To make this latter case work, when empty items are ignored, an \vb|\tabularLongstack{rc}{11&12\\21&{}\\31&32\\}|. -These problems can be wholly avoided if care is used in the - construction of TABstack input. +As of V2.1, the case of the trailing row separator can also be addressed + in a 2nd way, if the \texttt{TABcline} package option has been + declared. +In that case, the switch \cmd{relaxTABsyntax} will automatically + add the necessary column separators to \tst{} macro input, in + order to avoid compilation error for the case of a trailing row + separator. +See section~\ref{s:rtx} for more details. + +These problems arising from syntax can be wholly avoided, + without the need to resort to + \cmd{ignoreemptyitems} or \cmd{relaxTABsyntax}, if care is used in the + construction of the TABstack input. \endvbdelim -\section*{Acknowledgements} +\section*{Acknowledgments} I would like to thank Christian Tellechea for his development of the \loi{} package (which was directly inspired by my deficient @@ -681,6 +806,9 @@ helping me to understand some of the details of the \textsf{etoolbox} package: \vb|http://tex.stackexchange.com/questions/140372/|\\ \vb|loop-multi-contingency-using-etoolbox| +Professor Enrico Gregorio is a constant source of knowledge and assistance + for which I am very grateful. + \section{Code Listing} \verbfilenobox[\footnotesize]{tabstackengine.sty} diff --git a/Master/texmf-dist/tex/latex/tabstackengine/tabstackengine.sty b/Master/texmf-dist/tex/latex/tabstackengine/tabstackengine.sty index 977bc1bca08..f559b7ab87b 100644 --- a/Master/texmf-dist/tex/latex/tabstackengine/tabstackengine.sty +++ b/Master/texmf-dist/tex/latex/tabstackengine/tabstackengine.sty @@ -1,4 +1,4 @@ -\def\tabstackengineversionnumber{V2.01} +\def\tabstackengineversionnumber{V2.10} % % THIS MATERIAL IS SUBJECT TO THE LaTeX Project Public License % @@ -34,8 +34,11 @@ % -\TABcell and \TABcellBox modified to remember recent use of % \ensureTABstackMath, which otherwise changes temporarily the % prevailing mode and style of the TABstack. +% V2.10 -Introduces \TABrule and [optionally] \TABcline{} +% -Allows tabbed nesting within other tabbed environments (achieved via +% replacing select \bgroup and \egroup with \ifnum brace hacks (TeXbook p.385) \ProvidesPackage{tabstackengine} -[2016/11/30 (\tabstackengineversionnumber) tabbed stacking] +[2018/03/05 (\tabstackengineversionnumber) tabbed stacking] \RequirePackage{stackengine}[2016-10-04] \RequirePackage{listofitems}[2016/11/18] \RequirePackage{etoolbox} @@ -48,6 +51,8 @@ \newtoks\TABcoltoks \newtoks\LstrutTABtoks \newtoks\RstrutTABtoks +\newtoks\TAB@toks +\newlength\TABruleshift \def\getTABcelltoks[#1,#2]{% \TABcelltoks=\expandafter\expandafter\expandafter{\TABcellRaw[#1,#2]}} @@ -68,7 +73,7 @@ \newcommand\setstackTAB[1]{\ifstrempty{#1}{\def\TAB@char{ }}{\def\TAB@char{#1}}} -\newcommand\readTABstack[1]{% +\newcommand\readTABstack@ORIG[1]{% \expandafter\expandafter\expandafter\setsepchar\expandafter\expandafter% \expandafter{\expandafter\SEP@char\expandafter/\TAB@char}% \greadlist*\TABcellRaw{#1}% @@ -106,7 +111,9 @@ \newcommand\TABstrut[1]{\ifnum#1<1\relax{}\else% \protect\rule[-\TABdp{#1}]{0pt}{\dimexpr\TABdp{#1}+\TABht{#1}\relax}\fi} -\newcommand\TABcell[2]{\stack@delim\recent@TAB@delim{\TABcellRaw[#1,#2]}\stack@delim} +\newcommand\TABcell[2]{% + \setTABrulecolumn{#2}% THIS LINE ADDED TO SET COLUMN FOR POSSIBLE \TABrule + \stack@delim\recent@TAB@delim{\TABcellRaw[#1,#2]}\stack@delim} \newcommand\TABcellBox[3][\relax]{\ifx\relax#1\relax% \TABcellBox@aux{\csuse{col#3TAB@stackalignment}}{#2}{#3}\else @@ -202,7 +209,8 @@ \newcommand\vertMatrixstack[2][\stackalignment]{% \ensureTABstackMath{\left|\@TAB@stack{#1}{#2}{D}{\Vectorstack}\right|}} -\newcommand\@TAB@stack[4]{\bgroup% +\newcommand\@TAB@stack[4]{{\ifnum`}=\z@\fi% + \set@TABrule@gap{#3}% \readTABstack{#2}% \edef\stackalignment{#1}% \setcounter{TABcolindex@}{0}% @@ -227,7 +235,7 @@ \expandafter#4\expandafter{\the\TABcoltoks}}}% {\expandafter#4\expandafter{\the\TABcoltoks}}% }% -\egroup} +\ifnum`{=\z@\fi}} \newcommand\tabbedstackon[3][\stackgap]{% \@TABstackonunder{#1}{#2}{#3}{D}{\stackon}} @@ -256,10 +264,14 @@ \newcommand\tabularstackanchor[4][\stackgap]{% \@TABstackonunder{#1}{#3}{#4}{#2}{\stackanchor}} -\newcommand\@TABstackonunder[5]{\bgroup% +\newcommand\@TABstackonunder[5]{{\ifnum`}=\z@\fi% + \set@TABrule@gap{#4}% \def\TAB@tmp{#2}% - \expandafter\g@addto@macro\expandafter\TAB@tmp\expandafter{\SEP@char#3}% - \readTABstack{\TAB@tmp}% + \ifnum\TAB@testcline#2\relax=0\relax + \expandafter\g@addto@macro\expandafter\TAB@tmp\expandafter{\SEP@char}% + \fi% + \g@addto@macro\TAB@tmp{#3}% + \expandafter\readTABstack\expandafter{\TAB@tmp}% \setcounter{TABcolindex@}{0}% \whileboolexpr{test {\ifnumless{\theTABcolindex@}{\TABstack@cols}}}{% COL LOOP \stepcounter{TABcolindex@}% @@ -275,7 +287,9 @@ {\TAB@delim{\TAB@strutL{1}\TABcellRaw[1,\theTABcolindex@]\TAB@strutR{1}}}% {\TAB@delim{\TAB@strutL{1}\TABcellRaw[2,\theTABcolindex@]\TAB@strutR{2}}}}% }% -\egroup} +\ifnum`{=\z@\fi}} + +\def\TAB@testcline#1#2\relax{\ifx\TABcline#1 1\else0\fi} \newcommand\@getTABalignment[2]{% \ifstrequal{#1}{D}{}{% T, DO NOTHING (USE \stackalignment) @@ -325,6 +339,160 @@ \newcommand\ensureTABstackMath[1]{% \let\sv@TABmode\TAB@delim\TABstackMath#1\let\TAB@delim\sv@TABmode} +%%% \TABrule + +\newcommand\TABrule[1][\TABruleshift]{% + \ifnum1=\value{TABcolindex@}\relax% + \makebox[\TABwd{\theTABcolindex@}][l]{% + \rule[\TABruleshift]{% + \dimexpr\TABwd{\theTABcolindex@}+.5\dimexpr\TAB@gap\relax}{\fboxrule}}% + \else% + \ifnum\TABcells{1}=\value{TABcolindex@}\relax% + \makebox[\TABwd{\theTABcolindex@}][r]{% + \rule[\TABruleshift]{% + \dimexpr\TABwd{\theTABcolindex@}+.5\dimexpr\TAB@gap\relax}{\fboxrule}}% + \else% + \makebox[\TABwd{\theTABcolindex@}][c]{% + \rule[\TABruleshift]{% + \dimexpr\TABwd{\theTABcolindex@}+1.\dimexpr\TAB@gap\relax}{\fboxrule}}% + \fi% + \fi% +} + +\newcommand\set@TABrule@gap[1]{% + \ifstrequal{#1}{D}{\gdef\TAB@gap{\tabbed@gap}}{% + \ifstrequal{#1}{A}{\gdef\TAB@gap{0pt}}{\gdef\TAB@gap{\tabular@gap}}% + }% +} + +\newcommand\setTABrulecolumn[1]{\setcounter{TABcolindex@}{#1}} + +%% \TABcline + +\newcommand\readTABstack@cline[1]{% + \expandafter\expandafter\expandafter\setsepchar\expandafter\expandafter% + \expandafter{\expandafter\SEP@char\expandafter/\TAB@char}% +% REMEMBER # COLUMNS IN ADVANCE + \greadlist*\TABcellRaw{#1}% + \edef\TABstack@cols{\listlen\TABcellRaw[1]}%[\TABstack@cols]% + \TAB@toks={}% + \setcounter{TABrowindex@}{0}% + \TAB@preread#1\relax\TABcline\relax\TAB@end% + \expandafter\expandafter\expandafter\setsepchar\expandafter\expandafter% + \expandafter{\expandafter\SEP@char\expandafter/\TAB@char}% +% THE FOLLOWING WILL FIX LINES ENDING IN EOL SEPARATOR (SHOULDN'T DO THAT!) + \pad@cols% +%% + \expandafter\greadlist\expandafter*\expandafter\TABcellRaw\expandafter{\the\TAB@toks}% + \edef\TABstack@rows{\TABcellRawlen}% + \def\maxTABwd{0pt}% + \setcounter{TABrowindex@}{0}% + \whileboolexpr{test {\ifnumless{\theTABrowindex@}{\TABstack@rows}}}{% ROW LOOP + \def\@accumulatedTAB{}% + \stepcounter{TABrowindex@}% + \setcounter{TABcolindex@}{0}% + \whileboolexpr{test {\ifnumless{\theTABcolindex@}{\TABstack@cols}}}{% COL LOOP + \stepcounter{TABcolindex@}% + \ifnum\value{TABrowindex@}=1\relax\csxdef{col\theTABcolindex@ TAB@wd}{0pt}\fi% + \getTABcelltoks[\theTABrowindex@,\theTABcolindex@]% + \expandafter\g@addto@macro\expandafter\@accumulatedTAB\expandafter{% + \the\TABcelltoks{}}% + \setbox0=\hbox{\stack@delim\TAB@delim{% + \TAB@strutL{0}\the\TABcelltoks\TAB@strutR{0}}\stack@delim}% + \ifdim\wd0>\csuse{col\theTABcolindex@ TAB@wd}\relax% + \csxdef{col\theTABcolindex@ TAB@wd}{\the\wd0}% + \ifdim\wd0>\maxTABwd\relax\xdef\maxTABwd{\the\wd0}\fi\fi% + \csxdef{col\theTABcolindex@ TAB@stackalignment}{c}% DEFAULT, LATER CHANGED + }% + \setbox0=\hbox{\stack@delim\TAB@delim{\@accumulatedTAB}\stack@delim}% + \csxdef{row\theTABrowindex@ TAB@ht}{\the\ht0}% + \csxdef{row\theTABrowindex@ TAB@dp}{\the\dp0}% + \global\let\recent@TAB@delim\TAB@delim% + }% +} + +\def\TAB@preread#1\TABcline#2#3\TAB@end{\TAB@toks=\expandafter{\the\TAB@toks#1}% + \stepcounter{TABrowindex@}% + \ifx\relax#2\relax% + \TAB@toks=\expandafter{\the\TAB@toks\unskip}% + \let\next\relax% + \else% + \discern@TABlines{#2}% + \setcounter{TABcolindex@}{0}% + \whileboolexpr{test {\ifnumless{\theTABcolindex@}{\TABline@colcount}}}{% COLUMN LOOP + \stepcounter{TABcolindex@}% + \ifnum\theTABcolindex@=1\relax\else% + \TAB@toks=\expandafter\expandafter\expandafter{% + \expandafter\the\expandafter\TAB@toks\TAB@char}% + \fi + \TAB@toks=\expandafter\expandafter\expandafter\expandafter\expandafter% + \expandafter\expandafter{\expandafter\expandafter\expandafter% + \the\expandafter\expandafter\expandafter\TAB@toks% + \csname TABline@[\theTABcolindex@]\endcsname}% + }% + \ifnum0=\TAB@testend#3\relax\relax% + \TAB@toks=\expandafter\expandafter\expandafter{% + \expandafter\the\expandafter\TAB@toks\SEP@char}% + \fi% + \def\next{\TAB@preread#3\TAB@end}% + \fi% + \next% +} + +\newcommand\discern@TABlines[1]{% + \setcounter{TABcolindex@}{0}% + \whileboolexpr{test {\ifnumless{\theTABcolindex@}{\TABstack@cols}}}{% COLUMN LOOP + \stepcounter{TABcolindex@}% + \expandafter\def\csname TABline@[\theTABcolindex@]\endcsname{\relax}% + }% + \setsepchar{,/-}% + \readlist\TABline@cols{#1}% + \def\TAB@endindex{0}% + \foreachitem\@TABindex\in\TABline@cols{% + \edef\TAB@startindex{\TABline@cols[\@TABindexcnt,1]}% + \ifnum\listlen\TABline@cols[\@TABindexcnt]=2\relax% + \edef\TAB@endindex{\TABline@cols[\@TABindexcnt,2]}% + \else + \edef\TAB@endindex{\TABline@cols[\@TABindexcnt,1]}% + \fi + \setcounter{TABcolindex@}{\numexpr\TAB@startindex-1\relax}% + \whileboolexpr{test {\ifnumless{\theTABcolindex@}{\TAB@endindex}}}{% COLUMN LOOP + \stepcounter{TABcolindex@}% + \expandafter\def\csname TABline@[\theTABcolindex@]\endcsname{% + \TABrule}% + }% + }% + \edef\TABline@colcount{\TABstack@cols}% +} + + +\def\TAB@testend#1#2\relax{\ifx\relax#1 1\else0\fi} + +\newcommand\relaxTABsyntax{% + \def\pad@cols{% + \setcounter{TABcolindex@}{1}% + \whileboolexpr{test {\ifnumless{\theTABcolindex@}{\TABstack@cols}}}{% COLUMN LOOP + \stepcounter{TABcolindex@}% + \TAB@toks=\expandafter\expandafter\expandafter{% + \expandafter\the\expandafter\TAB@toks\TAB@char}% + }% + }% +} + +\newcommand\@strictTABsyntax{\let\pad@cols\relax} + +\newcommand\TABcline@off{% + \def\TABcline##1{\ignorespaces}% + \let\readTABstack\readTABstack@ORIG% +} + +\newcommand\TABcline@on{% + \def\TABcline{}% + \let\readTABstack\readTABstack@cline% +} + +%% INITIALIZATIONS + \setstackEOL{\\}% DEFAULT ROW SEP \setstackTAB{&}% DEFAULT COL SEP \def\TAB@mathstyle{}% NOTHING ADDED TO DEFAULT TAB MATH STYLE @@ -335,5 +503,19 @@ \def\align@gap{1em}% DEFAULT ALIGN COL GAP \def\tabular@gap{\tabcolsep}% DEFAULT TABULAR COL GAP \fixTABwidth{F}% DEFAULT NON-FIXED WIDTH COLUMNS - +\setlength\TABruleshift{-0pt}% RELATIVE VERTICAL SHIFT OF \TABrule +\@strictTABsyntax% WITH \relaxTABsyntax, ADDS NCOL-1 COLUMN SEPARATORS TO END +% OF INPUT TOKEN LIST, TO AVOID ERROR ENDING INPUT WITH EOL. +% BASICALLY, ALLOWS BAD CODING STYLE WITH NEW \readTABstack + +% PROCESS PACKAGE OPTIONS +\newif\iftabstackengine@TABcline +\DeclareOption{TABcline}{\tabstackengine@TABclinetrue} +\ProcessOptions\relax +\iftabstackengine@TABcline% + \TABcline@on% ALLOW USE OF \TABcline +\else + \TABcline@off% DISALLOW USE OF \TABcline +\fi +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endinput -- cgit v1.2.3