texlive[46848] Master/texmf-dist: tabstackengine (5mar18)

commits+karl at tug.org commits+karl at tug.org
Mon Mar 5 23:11:20 CET 2018


Revision: 46848
          http://tug.org/svn/texlive?view=revision&revision=46848
Author:   karl
Date:     2018-03-05 23:11:19 +0100 (Mon, 05 Mar 2018)
Log Message:
-----------
tabstackengine (5mar18)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.pdf
    trunk/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.tex
    trunk/Master/texmf-dist/tex/latex/tabstackengine/tabstackengine.sty

Modified: trunk/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.tex	2018-03-05 22:11:07 UTC (rev 46847)
+++ trunk/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.tex	2018-03-05 22:11:19 UTC (rev 46848)
@@ -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 @@
 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 @@
 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 @@
 
 \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{<commands involving TABstacks>}
 \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 <or> F}
 \TABstackMath
@@ -216,15 +318,17 @@
 \TABstackMathstyle{<directive>}
 \TABstackTextstyle{<directive>}
 \clearTABstyle
-\setstackEOL{<end-of-line character>}      !
+\setstackEOL{<end-of-line character>}      !1
 \setstackTAB{<tabbing character>}
 \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{<tabbed EOL-separated string>}
 \TABcellRaw[<row>,<column>]
@@ -237,6 +341,7 @@
 \TABht{<row>}
 \TABdp{<row>}
 \end{verbnobox}
+\vspace{-12pt}
 
 \subsection{Command Examples}
 
@@ -249,10 +354,12 @@
 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 @@
 
 \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\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}
+\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}|
 
-{\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 @@
 This value can be changed via \vb|\setstackTAB{|<tabbing character>\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 @@
 \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 @@
 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 @@
 
 \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 @@
 
 \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 @@
 
 \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 @@
 \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}

Modified: trunk/Master/texmf-dist/tex/latex/tabstackengine/tabstackengine.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/tabstackengine/tabstackengine.sty	2018-03-05 22:11:07 UTC (rev 46847)
+++ trunk/Master/texmf-dist/tex/latex/tabstackengine/tabstackengine.sty	2018-03-05 22:11:19 UTC (rev 46848)
@@ -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 at 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 at char{ }}{\def\TAB at char{#1}}}
 
-\newcommand\readTABstack[1]{%
+\newcommand\readTABstack at ORIG[1]{%
   \expandafter\expandafter\expandafter\setsepchar\expandafter\expandafter%
     \expandafter{\expandafter\SEP at char\expandafter/\TAB at 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 at delim\recent at TAB@delim{\TABcellRaw[#1,#2]}\stack at delim}
+\newcommand\TABcell[2]{%
+  \setTABrulecolumn{#2}% THIS LINE ADDED TO SET COLUMN FOR POSSIBLE \TABrule
+  \stack at delim\recent at TAB@delim{\TABcellRaw[#1,#2]}\stack at delim}
 
 \newcommand\TABcellBox[3][\relax]{\ifx\relax#1\relax%
   \TABcellBox at aux{\csuse{col#3TAB at stackalignment}}{#2}{#3}\else
@@ -202,7 +209,8 @@
 \newcommand\vertMatrixstack[2][\stackalignment]{%
   \ensureTABstackMath{\left|\@TAB at stack{#1}{#2}{D}{\Vectorstack}\right|}}
 
-\newcommand\@TAB at stack[4]{\bgroup%
+\newcommand\@TAB at stack[4]{{\ifnum`}=\z@\fi%
+  \set at 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 at TABrule@gap{#4}%
   \def\TAB at tmp{#2}%
-  \expandafter\g at addto@macro\expandafter\TAB at tmp\expandafter{\SEP at char#3}%
-  \readTABstack{\TAB at tmp}%
+  \ifnum\TAB at testcline#2\relax=0\relax
+    \expandafter\g at addto@macro\expandafter\TAB at tmp\expandafter{\SEP at char}%
+  \fi%
+  \g at addto@macro\TAB at tmp{#3}%
+  \expandafter\readTABstack\expandafter{\TAB at tmp}%
   \setcounter{TABcolindex@}{0}%
   \whileboolexpr{test {\ifnumless{\theTABcolindex@}{\TABstack at cols}}}{% COL LOOP
     \stepcounter{TABcolindex@}%
@@ -275,8 +287,10 @@
          {\TAB at delim{\TAB at strutL{1}\TABcellRaw[1,\theTABcolindex@]\TAB at strutR{1}}}%
          {\TAB at delim{\TAB at strutL{1}\TABcellRaw[2,\theTABcolindex@]\TAB at strutR{2}}}}%
   }%
-\egroup}
+\ifnum`{=\z@\fi}}
 
+\def\TAB at testcline#1#2\relax{\ifx\TABcline#1 1\else0\fi}
+
 \newcommand\@getTABalignment[2]{%
   \ifstrequal{#1}{D}{}{%                     T, DO NOTHING (USE \stackalignment)
     \ifstrequal{#1}{A}{%
@@ -325,6 +339,160 @@
 \newcommand\ensureTABstackMath[1]{%
   \let\sv at TABmode\TAB at delim\TABstackMath#1\let\TAB at delim\sv at TABmode}
 
+%%% \TABrule
+
+\newcommand\TABrule[1][\TABruleshift]{%
+  \ifnum1=\value{TABcolindex@}\relax%
+    \makebox[\TABwd{\theTABcolindex@}][l]{%
+      \rule[\TABruleshift]{%
+        \dimexpr\TABwd{\theTABcolindex@}+.5\dimexpr\TAB at gap\relax}{\fboxrule}}%
+  \else%
+    \ifnum\TABcells{1}=\value{TABcolindex@}\relax%
+      \makebox[\TABwd{\theTABcolindex@}][r]{%
+        \rule[\TABruleshift]{%
+          \dimexpr\TABwd{\theTABcolindex@}+.5\dimexpr\TAB at gap\relax}{\fboxrule}}%
+    \else%
+      \makebox[\TABwd{\theTABcolindex@}][c]{%
+        \rule[\TABruleshift]{%
+          \dimexpr\TABwd{\theTABcolindex@}+1.\dimexpr\TAB at gap\relax}{\fboxrule}}%
+    \fi%
+  \fi%
+}
+
+\newcommand\set at TABrule@gap[1]{%
+  \ifstrequal{#1}{D}{\gdef\TAB at gap{\tabbed at gap}}{%
+      \ifstrequal{#1}{A}{\gdef\TAB at gap{0pt}}{\gdef\TAB at gap{\tabular at gap}}%
+  }%
+}
+
+\newcommand\setTABrulecolumn[1]{\setcounter{TABcolindex@}{#1}}
+
+%% \TABcline
+
+\newcommand\readTABstack at cline[1]{%
+  \expandafter\expandafter\expandafter\setsepchar\expandafter\expandafter%
+    \expandafter{\expandafter\SEP at char\expandafter/\TAB at char}%
+% REMEMBER # COLUMNS IN ADVANCE
+  \greadlist*\TABcellRaw{#1}%
+  \edef\TABstack at cols{\listlen\TABcellRaw[1]}%[\TABstack at cols]%
+  \TAB at toks={}%
+  \setcounter{TABrowindex@}{0}%
+  \TAB at preread#1\relax\TABcline\relax\TAB at end%
+  \expandafter\expandafter\expandafter\setsepchar\expandafter\expandafter%
+    \expandafter{\expandafter\SEP at char\expandafter/\TAB at char}%
+% THE FOLLOWING WILL FIX LINES ENDING IN EOL SEPARATOR (SHOULDN'T DO THAT!)
+  \pad at cols%
+%%
+  \expandafter\greadlist\expandafter*\expandafter\TABcellRaw\expandafter{\the\TAB at toks}%
+  \edef\TABstack at rows{\TABcellRawlen}%
+  \def\maxTABwd{0pt}%
+  \setcounter{TABrowindex@}{0}%
+  \whileboolexpr{test {\ifnumless{\theTABrowindex@}{\TABstack at rows}}}{% ROW LOOP
+    \def\@accumulatedTAB{}%
+    \stepcounter{TABrowindex@}%
+    \setcounter{TABcolindex@}{0}%
+    \whileboolexpr{test {\ifnumless{\theTABcolindex@}{\TABstack at cols}}}{% COL LOOP
+      \stepcounter{TABcolindex@}%
+      \ifnum\value{TABrowindex@}=1\relax\csxdef{col\theTABcolindex@ TAB at wd}{0pt}\fi%
+      \getTABcelltoks[\theTABrowindex@,\theTABcolindex@]%
+      \expandafter\g at addto@macro\expandafter\@accumulatedTAB\expandafter{%
+        \the\TABcelltoks{}}%
+      \setbox0=\hbox{\stack at delim\TAB at delim{%
+        \TAB at strutL{0}\the\TABcelltoks\TAB at strutR{0}}\stack at delim}%
+      \ifdim\wd0>\csuse{col\theTABcolindex@ TAB at wd}\relax%
+        \csxdef{col\theTABcolindex@ TAB at wd}{\the\wd0}%
+      \ifdim\wd0>\maxTABwd\relax\xdef\maxTABwd{\the\wd0}\fi\fi%
+      \csxdef{col\theTABcolindex@ TAB at stackalignment}{c}% DEFAULT, LATER CHANGED
+    }%
+    \setbox0=\hbox{\stack at delim\TAB at delim{\@accumulatedTAB}\stack at delim}%
+    \csxdef{row\theTABrowindex@ TAB at ht}{\the\ht0}%
+    \csxdef{row\theTABrowindex@ TAB at dp}{\the\dp0}%
+    \global\let\recent at TAB@delim\TAB at delim%
+  }%
+}
+
+\def\TAB at preread#1\TABcline#2#3\TAB at end{\TAB at toks=\expandafter{\the\TAB at toks#1}%
+  \stepcounter{TABrowindex@}%
+  \ifx\relax#2\relax%
+    \TAB at toks=\expandafter{\the\TAB at toks\unskip}%
+    \let\next\relax%
+  \else%
+    \discern at TABlines{#2}%
+    \setcounter{TABcolindex@}{0}%
+    \whileboolexpr{test {\ifnumless{\theTABcolindex@}{\TABline at colcount}}}{% COLUMN LOOP
+      \stepcounter{TABcolindex@}%
+      \ifnum\theTABcolindex@=1\relax\else%
+        \TAB at toks=\expandafter\expandafter\expandafter{%
+          \expandafter\the\expandafter\TAB at toks\TAB at char}%
+      \fi
+      \TAB at toks=\expandafter\expandafter\expandafter\expandafter\expandafter%
+        \expandafter\expandafter{\expandafter\expandafter\expandafter%
+        \the\expandafter\expandafter\expandafter\TAB at toks%
+          \csname TABline@[\theTABcolindex@]\endcsname}%
+    }%
+    \ifnum0=\TAB at testend#3\relax\relax%
+      \TAB at toks=\expandafter\expandafter\expandafter{%
+        \expandafter\the\expandafter\TAB at toks\SEP at char}%
+    \fi%
+    \def\next{\TAB at preread#3\TAB at end}%
+  \fi%
+  \next%
+}
+
+\newcommand\discern at TABlines[1]{%
+  \setcounter{TABcolindex@}{0}%
+  \whileboolexpr{test {\ifnumless{\theTABcolindex@}{\TABstack at cols}}}{% COLUMN LOOP
+    \stepcounter{TABcolindex@}%
+    \expandafter\def\csname TABline@[\theTABcolindex@]\endcsname{\relax}%
+  }%
+  \setsepchar{,/-}%
+  \readlist\TABline at cols{#1}%
+  \def\TAB at endindex{0}%
+  \foreachitem\@TABindex\in\TABline at cols{%
+    \edef\TAB at startindex{\TABline at cols[\@TABindexcnt,1]}%
+    \ifnum\listlen\TABline at cols[\@TABindexcnt]=2\relax%
+      \edef\TAB at endindex{\TABline at cols[\@TABindexcnt,2]}%
+    \else
+      \edef\TAB at endindex{\TABline at cols[\@TABindexcnt,1]}%
+    \fi
+    \setcounter{TABcolindex@}{\numexpr\TAB at startindex-1\relax}%
+    \whileboolexpr{test {\ifnumless{\theTABcolindex@}{\TAB at endindex}}}{% COLUMN LOOP
+      \stepcounter{TABcolindex@}%
+      \expandafter\def\csname TABline@[\theTABcolindex@]\endcsname{%
+        \TABrule}%
+    }%
+  }%
+  \edef\TABline at colcount{\TABstack at cols}%
+}
+
+
+\def\TAB at testend#1#2\relax{\ifx\relax#1 1\else0\fi}
+
+\newcommand\relaxTABsyntax{%
+  \def\pad at cols{%
+    \setcounter{TABcolindex@}{1}%
+    \whileboolexpr{test {\ifnumless{\theTABcolindex@}{\TABstack at cols}}}{% COLUMN LOOP
+      \stepcounter{TABcolindex@}%
+      \TAB at toks=\expandafter\expandafter\expandafter{%
+        \expandafter\the\expandafter\TAB at toks\TAB at char}%
+    }%
+  }%
+}
+
+\newcommand\@strictTABsyntax{\let\pad at cols\relax}
+
+\newcommand\TABcline at off{%
+  \def\TABcline##1{\ignorespaces}%
+  \let\readTABstack\readTABstack at ORIG%
+}
+
+\newcommand\TABcline at on{%
+  \def\TABcline{}%
+  \let\readTABstack\readTABstack at cline%
+}
+
+%% INITIALIZATIONS
+
 \setstackEOL{\\}%              DEFAULT ROW SEP
 \setstackTAB{&}%               DEFAULT COL SEP
 \def\TAB at mathstyle{}%          NOTHING ADDED TO DEFAULT TAB MATH STYLE
@@ -335,5 +503,19 @@
 \def\align at gap{1em}%           DEFAULT ALIGN COL GAP
 \def\tabular at 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 at TABcline
+\DeclareOption{TABcline}{\tabstackengine at TABclinetrue}
+\ProcessOptions\relax
+\iftabstackengine at TABcline%
+  \TABcline at on% ALLOW USE OF \TABcline
+\else
+  \TABcline at off% DISALLOW USE OF \TABcline
+\fi
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \endinput



More information about the tex-live-commits mailing list