diff options
author | Karl Berry <karl@freefriends.org> | 2014-02-11 23:44:27 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2014-02-11 23:44:27 +0000 |
commit | 9c4953f7ee1a441f6db0c463d8e21c09513a0386 (patch) | |
tree | ec7bffbe868b2bfa8f8d353b699121fcffe9a49c | |
parent | 9a1be5b98214a77966642ba65ac76f1105dafba1 (diff) |
tabstackengine (11feb14)
git-svn-id: svn://tug.org/texlive/trunk@32944 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r-- | Master/texmf-dist/doc/latex/tabstackengine/README | 18 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.pdf | bin | 0 -> 334466 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.tex | 477 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/tabstackengine/tabstackengine.sty | 300 | ||||
-rwxr-xr-x | Master/tlpkg/bin/tlpkg-ctan-check | 2 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc | 1 | ||||
-rw-r--r-- | Master/tlpkg/tlpsrc/tabstackengine.tlpsrc | 0 |
7 files changed, 797 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/tabstackengine/README b/Master/texmf-dist/doc/latex/tabstackengine/README new file mode 100644 index 00000000000..1ff865d98fc --- /dev/null +++ b/Master/texmf-dist/doc/latex/tabstackengine/README @@ -0,0 +1,18 @@ +The tabstackengine Package + + +The tabstackengine package provides a front end to the stackengine +package, to allow tabbed stacking. In most cases, an existing +stackengine command may be prepended with the word "tabbed", "align" or +"tabular" to create a new tabbed version of a stacking macro. + +Additionally, hooks are provided into the package's parser, so that +(completely outside of any stacking constructions) tabbed strings of +data may be parsed, extracted, and reconstituted + +Steven B. Segletes +steven.b.segletes.civ@mail.mil + + +THIS MATERIAL IS SUBJECT TO THE LaTeX Project Public License + diff --git a/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.pdf b/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.pdf Binary files differnew file mode 100644 index 00000000000..28ac8d460c6 --- /dev/null +++ b/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.pdf diff --git a/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.tex b/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.tex new file mode 100644 index 00000000000..81264dd36cd --- /dev/null +++ b/Master/texmf-dist/doc/latex/tabstackengine/tabstackengine.tex @@ -0,0 +1,477 @@ +\documentclass{article} +\usepackage{tabstackengine} +\usepackage{verbatimbox} +\usepackage{xcolor} + \parindent 0in\parskip 1em \newlength\dotscale + + +% FOR CLOSE-BOXING ARGUMENTS \fboxsep=0pt\fboxrule=.6pt +\def\rl{\rule[-.3pt]{2ex}{.6pt}} \def\tst{\textsf{tabstackengine}} +\def\ste{\textsf{stackengine}} \def\bs{\texttt{\char'134}} \let\vb\verb +\reversemarginpar \marginparwidth 1.6in +\newcommand\margtt[1]{\marginpar{\hfill\ttfamily#1}} +\newcommand\margcmd[1]{\marginpar{\hfill\ttfamily\char'134#1}} +\newcommand\cmd[1]{\texttt{\char'134#1}} + +\begin{document} + +\begin{center} \LARGE The {\tst} Package\\ \rule{0em}{.7em}\small +Front-end to the {\ste} package, allowing tabbed stacking\\ \rule{0em}{2.7em}\large +Steven B. Segletes\\ steven.b.segletes.civ@mail.mil\\ +\rule{0em}{1.7em}\today\\ \tabstackengineversionnumber \end{center} + +\tableofcontents + +\section{Introduction} + +The {\tst} package provides a front end to the {\ste} package that +allows for the use of tabbing characters within the stacking arguments. +\textbf{Familiarity with the syntax of the {\ste} package is assumed.} +When invoked, {\tst} loads the {\ste} package with the +\texttt{[usestackEOL]} option set, so 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). + +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 values. + +In most cases (where it makes sense), a {\ste} macro name may be +prepended with the word \texttt{tabbed}, \texttt{align}, or +\texttt{tabular} to create a new {\tst} macro that allows for tabbed +arguments. + +\section{Tabbing Variations within \tst} + +The {\tst} package syntax allows three types of tabbing variation +denoted by the words \texttt{tabbed}, \texttt{align}, and +\texttt{tabular} in the macro name itself. In the case of +\texttt{tabbed} macros, the tabbed columns all share the same alignment, +as dictated by the \vb|\stackalignment| setting or perhaps provided as +an optional argument in some macro forms. + +In the case of \texttt{align} macros, the alignment in columns is +alternately specified as right, then left, \textit{etc.}, in the manner +of the \texttt{align} environment of the \textsf{amsmath} package. + +Finally, in the case of \texttt{tabular} macros, an extra argument is +passed to the macro that specifies the left-center-right alignment for +each individual column, in the manner of \vb|{lccr}|. + +\section{Column Spacing within \tst} + +Intercolumn space can be introduced to {\tst} output in one of two ways. +\margcmd{fixTABwidth}First, there is a macro setting to force all columns to be the same +width (namely, the width of the widest entry in the stack), using the +syntax +\vb|\fixTABwidth{T| \textit{or} \vb|F}|. +When set true, column space will be introduced to all but the widest +column of a stack, so as to make all columns of a width equal to that +of the widest column. + +Secondly,\margcmd{setstacktabbedgap} +each of the tabbing variations has the means to introduce a +fixed amount of space between columns. By default, the \texttt{tabbed} +stacking macros add no space (\texttt{0pt}) between adjacent columns, +but this value can be reset with the macro +\vb|\setstacktabbedgap{|\textit{length}\vb|}|. + +In\margcmd{setstackaligngap} +the case of the \texttt{align} stacking macros, there is never any +gap introduced after the right-aligned columns. However, the default +gap introduced after the left-aligned columns is, by default, +\texttt{1em} (the same gap as \cmd{quad}). It can be reset with the +macro \vb|\setstackaligngap{|\textit{length}\vb|}|. + +For\margcmd{setstacktabulargap} +the \texttt{tabular} stacks, the default intercolumn gap is the +value of \cmd{tabcolsep}. The default value may be reset with the macro +\vb|\setstacktabulargap{|\textit{length}\vb|}|. + +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. + +\clearpage +\section{Command Summary} + +Below are the new commands introduced by this package. When there are +multiple commands delimited by braces, any one of the commands within the +brace may be selected. + +\ttfamily\footnotesize +\(\left.\Centerstack[r]{% + \textcolor{red}{\cmd tabbed}\\\\ + \textcolor{teal}{\cmd align}\\\\ + \textcolor{blue}{\cmd tabular} +}\right\}% +\left\{ +\Centerstack[c]{Shortstack\\Shortunderstack\\Longstack\\ + Longunderstack\\Centerstack\\Vectorstack} +\right\}% +\left\{\Centerstack[c]{ + \textcolor{red}{[alignment]}\\\\ + \\\\ + \textcolor{blue}{\{column alignments\}} +}\right\}\)\{tabbed EOL-separated string\} + +\(\displaystyle\$\left\{\Centerstack[r]{\cmd paren\\\cmd brace\\\cmd bracket\\\cmd vert}\right\}\)% +\textcolor{red}{Matrix}stack[alignment]\{tabbed EOL-separated string\}\$ + +\(\left.\Centerstack[r]{ + \textcolor{red}{\cmd tabbed}\\\\ + \textcolor{teal}{\cmd align}\\\\ + \textcolor{blue}{\cmd tabular}}\right\}% +\left\{ +\Centerstack[c]{stackon\\stackunder\\stackanchor} +\right\}% +\mathtt{[stack gap]}\left\{\Centerstack[l]{ +\\\\ +\\\\ +\textcolor{blue}{\{col.\ alignments\}} +}\right\}\)\{tabbed anchor\}\{tabbbed~argument\} + +\cmd setstack\(\left\{\Centerstack{ + \textcolor{red}{tabbed}\\\\ + \textcolor{teal}{align}\\\\ + \textcolor{blue}{tabular} +}\right\}\)gap\{length\} +\hspace{3em}Initial Defaults:\(\left\{\Centerstack{ + \textcolor{red}{0pt}\\\\ + \textcolor{teal}{1em}\\\\ + \textcolor{blue}{\cmd tabcolsep} +}\right\}\) + +\rmfamily\normalsize + +\begin{verbnobox}[\footnotesize] +\fixTABwidth{T or F} +\setstackTAB{tabbing character} +\end{verbnobox} +The following macros are macros that can be used for parsing tabbed data outside of a +TABstack. +\begin{verbnobox}[\footnotesize] +\readTABrow{row ID}{tab-separated string} +\TABcell{row ID}{column number} +\TABcells{row ID} +\TABstrut{row ID} +\TABstackMath +\TABstackText +\ensureTABstackMath{} +\end{verbnobox} + +\subsection{Command Examples} + +Below we give examples of the various types of commands made available through +the \textsf{stackengine} package. + +\subsection*{Tabbed End-of-Line (EOL)-delimited Stacks} + +Here, the optional argument \verb|[l]| defines the alignment of \textit{all} the +columns. The default alignment is \verb|[c]|. + +\verb|\tabbedShortunderstack[l]{A&B&CCC\\aaa&bbb&c\\1111&2&3}| + +{\small\tabbedShortunderstack[l]{A&B&CCC\\aaa&bbb&c\\1111&2&3}} + +\subsection*{Align End-of-Line (EOL)-delimited Stacks} + +In an \texttt{align}-stack, the column alignments will always be \verb|rlrl...| +The gap following the left-aligned columns is set by \verb|\setstackaligngap|. + +\verb|\stackMath$Z:\left\{\alignCenterstack{%|\\ +\verb| y&=mx+b,&0&=Ax+By+C\\y_1&=W_1,&y_2&=W_2}\right.$| + +{\small\stackMath$Z:\left\{\alignCenterstack{y&=mx+b,&0&=Ax+By+C\\y_1&=W_1,&y_2&=W_2}\right.$} + +\subsection*{Tabular End-of-Line (EOL)-delimited Stacks} + +In a \texttt{tabular}-stack, the alignment of each column is specified in a separate +leading argument. + +\verb|\stackText\tabularLongstack{rllc}{%|\\ +\verb| 9)& $y_1=mx+b$ &linear&*\\10)& $y_2=e^x$ &exponential&[23]}| + +{\small\stackText\tabularLongstack{rllc}{9)& $y_1=mx+b$ &linear&*\\10)& $y_2=e^x$ &exponential&[23]}} + +\subsection*{Matrix Stack} + +The \texttt{Matrix}-stacks are a tabbed variant of \textsf{stackengine}'s \texttt{Vector}-stacks. + +\verb|\setstacktabbedgap{1.5ex}|\\ +\verb|$I = \bracketMatrixstack{1&0&0\\0&1&0\\0&0&1}$| + +{\small\setstacktabbedgap{1.5ex} $I = \bracketMatrixstack{1&0&0\\0&1&0\\0&0&1}$} + +\subsection*{Tabbed Stack} + +This variant of a \texttt{tabbed}-stack stacks exactly two items. +Its arguments don't need to be protected. The optional argument is a stacking gap, +as in the syntax of the \textsf{stackengine} package. + +\verb|\setstacktabbedgap{1ex}|\\ +\verb|\tabbedstackon[4pt]{Jack&drove&the car&home.}{SN&V&DO&IO}| + +{\small\stackText\setstacktabbedgap{1ex}\tabbedstackon[4pt]{Jack&drove&the car&home.}{SN&V&DO&IO}} + +\subsection*{Align Stack} + +This is for stacking two items with \texttt{rlrl...} alignment pattern. + +\verb|\stackMath\setstackaligngap{3em}|\\ +\verb|\alignstackunder[10pt]{y&=mx+b,&0&=Ax+By+C}{y_1&=W_1,&y_2&=W_2}| + +{\small\stackMath\setstackaligngap{3em} +\alignstackunder[10pt]{y&=mx+b,&0&=Ax+By+C}{y_1&=W_1,&y_2&=W_2}} + +\subsection*{Tabular Stack} + +This is for stacking two items with specifiable alignment pattern. + +\verb|\stackMath\setstacktabulargap{1ex}\tabularstackanchor[4pt]{rcl}%|\\ +\verb| {\bullet\bullet\bullet\bullet&\belowbaseline[-2pt]{\triangle}%|\\ +\verb| &\bullet\bullet\bullet\bullet}%|\\ +\verb| {1 + 3(4-3) & = & 7 - 6/2}|\vspace{1ex} + +{\small\stackMath\setstacktabulargap{1ex} +\tabularstackanchor[4pt]{rcl}{\bullet\bullet\bullet&\belowbaseline[-2pt]{% +\triangle}&\bullet\bullet\bullet}{1 + 2(4-3) & = & 6 - 6/2}} + +\clearpage +\subsection*{Fixed Tab Width (equal width columns, based on largest)} + +With this mode set, the stack will have fixed-width columns, based on the overall +widest entry. + +\verb|\fixTABwidth{T}\setstacktabbedgap{1ex}%|\\ +\verb|$\left(\tabbedCenterstack[r]{1&34&544\\4324329&0&8\\89&123&1}\right)$| + +{\small\setstacktabbedgap{1ex}\fixTABwidth{T}$\left(\tabbedCenterstack[r]{1&34&544\\4324329&0&8\\89&123&1}\right)$} + +\subsection*{Setting the Stack Tabbing Character} + +By default, for the parsing of columns within a row, this package employs the \verb|&| character to delimit the +columns. This value can be changed via \verb|\setstackTAB{}|, where the argument is the +newly desired tabbing character. It can be any of various characters, including a space token, +if one wishes to use a space-separated +list to parse the columns. Generally, it may need to be changed if you are building a TABstack +inside of an environment that already uses the \verb|&| character as a tab, such as the +\verb|tabular| environment for text or the various math environments in the \textsf{amsmath} +package. + +\subsection*{The Macros \texttt{\textbackslash readTABrow}, \texttt{\textbackslash TABcell(s)}, +and \texttt{\textbackslash TABstrut}} + +One of the nice features of \textsf{tabstackengine} is that it gives you access to its parser, +which can be used for tasks unrelated to building stacks. +It provides several macros, including +{\itshape\verb|\readTABrow{|ident\verb|}{|tab-separated-string\verb|}|} for +digesting a list and assigning it a global ID, in this case, ``{\itshape ident}''. It also provides +{\itshape\verb|\TABcells{|ident\verb|}|} to tell you how many items are in the list named +``{\itshape ident}'', as well as the macro {\itshape\verb|\TABcell{|ident\verb|}{|column number\verb|}|} to +provide the value of the specified column from the ID'ed row. For example, + +\begin{verbatim} +\setstackTAB{,} +\TABstackMath +\readTABrow{myident}{1,2, 3x , 4, 5,x^2,,g,\textbf{bold 9}} +\TABcells{myident} items in dataset ``myident''\\ +The 6th data item is \TABcell{myident}{6}\\ +The 9th data item is \TABcell{myident}{9} +\end{verbatim} + +will yield the following result: + +\TABstackMath +{\setstackTAB{,} +\readTABrow{myident}{1,2, 3x , 4, 5,x^2,,g,\textbf{bold 9}} +\TABcells{myident} items in dataset ``myident''\\ +The 6th data item is \TABcell{myident}{6}\\ +The 9th data item is \TABcell{myident}{9}} + +{\fboxsep=1pt% +The result provided by {\itshape\verb|\TABcell{|ident\verb|}{|column number\verb|}|} has +been processed in the following way: 1) leading and trailing spaces have been removed +from the column's data, and 2) the column will have been processed in math mode if +\verb|\TABstackMath| (see below) had been in force. Thus, placing the cell contents in +a box, \verb|\fbox{\TABcell{myident}{3}}| +is \fbox{\TABcell{myident}{3}}. + +If one, however, wished to access the raw +data, with leading/trailing spaces still intact (and ignoring the \verb|\TABstackMath| setting), +one can compose the macro, +{\itshape\verb|\csname TABX|ident\verb|X\romannumeral| column number\verb|\endcsname|}, +such that \verb|\fbox{\csname TABXmyidentX\romannumeral 3\endcsname}|, using the above example, +would give \fbox{\csname TABXmyidentX\romannumeral 3\endcsname}.% +} + +Finally, the macro \verb|\TABstrut{myident}| provides a strut that spans the vertical height of the +complete row content. +Here is \verb|\TABstrut{myident}| (that has been boxed with \verb|\fboxsep=0pt|) +compared to the boxed content of the row itself:\\ +{\TABstackMath\fboxsep=0pt\fboxrule=.2pt\fbox{\TABstrut{myident}} +\fbox{$12 3x 4 5x^2g\textbf{bold 9}$}}. As you can see, the \verb|\TABstrut{myident}| +captures the vertical extent of the complete row data, including the descending $g$ and +the superscript of the $x^2$. The \verb|\TABstrut{}|, when paired with the column content, +is useful when one wishes to make all column entries of a row display with equal height and depth, +even when their native height varies from column to column. +\TABstackText + +\subsection*{\texttt{\textbackslash TABstackMath}, \texttt{\textbackslash ensureTABstackMath}, and +\texttt{\textbackslash TABstackText}} + +These macros are \textit{not} needed when building stacks in \textsf{tabstackengine}. +When constructing TABstacks, their presence is superfluous +because their companion macros, \verb|\stackMath|, \verb|\ensurestackMath|, +and \verb|\stackText|, will +carry over from the \textsf{stackengine} package. + +However, there is one application where their use is required. And that is when you +use the facilities of this package \textit{not} to build TABstacks, but \textit{instead} use it to parse +data with \verb|\readTABrow{}{}| and present it with \verb|\TABcell{}{}|, respectively. +Notably \verb|\TABcell{}{}| does not access the \textsf{stackengine} setting for +the status of \verb|\stackMath| and therefore pays attention only to the current setting +specified by \verb|\TABstackMath|. + +One should note, however, that TABstacks pay attention to both settings. Therefore, +\bfseries if EITHER \verb|\stackMath| or \verb|\TABstackMath| have been +invoked, the TABstack argument will be processed by \verb|\TABcell| in math +mode\mdseries. This is a good reason to avoid the ``TAB'' versions of these +macros, unless employing them to parse data (and then, reset to +\verb|\TABstackText| when you are done with parsing). + +\clearpage +\section{Known Bugs/Missing Features} + +\begin{enumerate} + +\item \textbf{Ending on a} \verb|\frac| + +The following code demonstrates a bug when a row ends in \verb|\frac|, +when not followed by a space: + +\begin{verbnobox}[\footnotesize] +\documentclass{article} +\usepackage{tabstackengine} +\stackMath +\setstackgap{S}{6pt} +\newcommand\tfrac[2]{\frac{\textrm{#1}}{\textrm{#2}}} +\scriptsize +\begin{document} +\noindent space after tfrac, all is OK: +\par\medskip\noindent\tabbedShortstack[l]{ +\rho &= 2.04 &\tfrac{g}{cm$^3$} \\ +M &= 56.10 &\tfrac{g}{mol} \\ +c &= 0.05 &\tfrac{mol}{L} \\ +} +\par\noindent no space after tfrac results in tfrac set in displaystyle\\ +while the rest of the stack is in textstyle: +\par\medskip\noindent\tabbedShortstack[l]{ +\rho &= 2.04 &\tfrac{g}{cm$^3$}\\ +M &= 56.10 &\tfrac{g}{mol}\\ +c &= 0.05 &\tfrac{mol}{L}\\ +} +\end{document} +\end{verbnobox} + +Here is the result of the above code, showing the difference when a space +is included after the \verb|\frac| versus when one is omitted: + +{\stackMath +\setstackgap{S}{6pt} +\newcommand\tfrac[2]{\frac{\textrm{#1}}{\textrm{#2}}} +\scriptsize +\noindent space after tfrac, all is OK: +\par\medskip\noindent\tabbedShortstack[l]{ +\rho &= 2.04 &\tfrac{g}{cm$^3$} \\ +M &= 56.10 &\tfrac{g}{mol} \\ +c &= 0.05 &\tfrac{mol}{L} \\ +} +\par\noindent no space after tfrac results in tfrac set in displaystyle\\ +while the rest of the stack is in textstyle: +\par\medskip\noindent\tabbedShortstack[l]{ +\rho &= 2.04 &\tfrac{g}{cm$^3$}\\ +M &= 56.10 &\tfrac{g}{mol}\\ +c &= 0.05 &\tfrac{mol}{L}\\ +}} + +When the space is omitted, the stack is constructed in \verb|\textstyle|, whereas the +closing fractions appear to be constructed in \verb|\displaystyle|. The workaround is to not end +the \textsf{tabstackengine} field in a \verb|\frac| without an extra space. + +\item \textbf{Unary versus Binary Minus Sign} + +The package seems to want to use the minus sign that leads a number in binary +mode, that is, as an minus operator rather than as a negative sign. + +\begin{verbnobox}[\footnotesize] +\setstacktabbedgap{1ex} +$\bracketMatrixstack[r]{ +-0.84 & 0.21 & -0.11 & 0.110 & 0.13 & 0.34\\ +0.21 & -0.43 & 0.14 & 0.06 & 0.30 & -0.22\\ +0.27 & 0.13 & -0.54 & 0.25 & -0.27 & 0.16\\ +-0.27 & -0.23 & 0.43 & -0.46 & 0.53 & -0.05\\ +0.05 & 0.13 & -0.02 & -0.10 & -0.03 & -0.02\\ +0.23 & -0.32 & 0.21 & -0.11 & 0.41 & -0.34 +}$ +\end{verbnobox} + +\setstacktabbedgap{1ex} +$\bracketMatrixstack[r]{ +-0.84 & 0.21 & -0.11 & 0.110 & 0.13 & 0.34\\ +0.21 & -0.43 & 0.14 & 0.06 & 0.30 & -0.22\\ +0.27 & 0.13 & -0.54 & 0.25 & -0.27 & 0.16\\ +-0.27 & -0.23 & 0.43 & -0.46 & 0.53 & -0.05\\ +0.05 & 0.13 & -0.02 & -0.10 & -0.03 & -0.02\\ +0.23 & -0.32 & 0.21 & -0.11 & 0.41 & -0.34 +}$ + +\vspace*{\baselineskip} +The workaround is to enclose the minus signs in braces: + +\begin{verbnobox}[\footnotesize] +\setstacktabbedgap{1ex} +$\bracketMatrixstack[r]{ +{-}0.84 & 0.21 & {-}0.11 & 0.110 & 0.13 & 0.34\\ +0.21 & {-}0.43 & 0.14 & 0.06 & 0.30 & {-}0.22\\ +0.27 & 0.13 & {-}0.54 & 0.25 & {-}0.27 & 0.16\\ +{-}0.27 & {-}0.23 & 0.43 & {-}0.46 & 0.53 & {-}0.05\\ +0.05 & 0.13 & {-}0.02 & {-}0.10 & {-}0.03 & {-}0.02\\ +0.23 & {-}0.32 & 0.21 & {-}0.11 & 0.41 & {-}0.34 +}$ +\end{verbnobox} + +$\bracketMatrixstack[r]{ +{-}0.84 & 0.21 & {-}0.11 & 0.110 & 0.13 & 0.34\\ +0.21 & {-}0.43 & 0.14 & 0.06 & 0.30 & {-}0.22\\ +0.27 & 0.13 & {-}0.54 & 0.25 & {-}0.27 & 0.16\\ +{-}0.27 & {-}0.23 & 0.43 & {-}0.46 & 0.53 & {-}0.05\\ +0.05 & 0.13 & {-}0.02 & {-}0.10 & {-}0.03 & {-}0.02\\ +0.23 & {-}0.32 & 0.21 & {-}0.11 & 0.41 & {-}0.34 +}$ + +\item \textbf{No Horizontal Equivalent of \textbackslash TABstrut} + +As of the initial package release, there is no macro that provides the width of a +column's content. I hope to remedy this deficiency in a future release. + +\item \textbf{Nothing Equivalent to} \verb|\hline| + +This is not a bug, so much as a notation of a missing feature. Currently +there is nothing equivalent to \verb|\hline| available for use in +\textsf{tabstackengine} arguments. + +\end{enumerate} + + +\section{Code Listing} + +\verbfilenobox[\footnotesize]{tabstackengine.sty} + +\end{document} + + + diff --git a/Master/texmf-dist/tex/latex/tabstackengine/tabstackengine.sty b/Master/texmf-dist/tex/latex/tabstackengine/tabstackengine.sty new file mode 100644 index 00000000000..511bad54eb9 --- /dev/null +++ b/Master/texmf-dist/tex/latex/tabstackengine/tabstackengine.sty @@ -0,0 +1,300 @@ +\def\tabstackengineversionnumber{V1.00} +% +% tabstackengine initial release +% +% THIS MATERIAL IS SUBJECT TO THE LaTeX Project Public License +% +% V1.00 - Adopted beta version 0.21 as initial release version 1.0 +% +\ProvidesPackage{tabstackengine} +[2014/02/11 (\tabstackengineversionnumber) tabbed stacking] +\RequirePackage[usestackEOL]{stackengine}[2013-10-15] +\RequirePackage{calc} + +\newtoggle{@doneTABreads} +\newcounter{TAB@stackindex} +\newcounter{TABcellindex@} +\newlength\maxTAB@width + +\newcommand\setstackTAB[1]{% + \ifstrempty{#1}{\def\TAB@char{ }}{\def\TAB@char{#1}}% + \expandafter\define@processTABrow\expandafter{\TAB@char}% +} + +\newcommand\define@processTABrow[1]{% + \def\@processTABrow##1#1##2||{% + \def\@preTAB{##1}% + \def\@postTAB{##2}% + }% +} +\setstackTAB{&} + +\newcommand\readTABrow[2]{% + \edef\row@ID{#1}% + \togglefalse{@doneTABreads}% + \edef\@postTAB{\unexpanded{#2}\expandonce{\TAB@char}}% + \setcounter{TABcellindex@}{0}% + \whileboolexpr{ test {\nottoggle{@doneTABreads}}}{% + \stepcounter{TABcellindex@}% + \expandafter\@processTABrow\@postTAB||% + \global\csedef{TABX\row@ID X\roman{TABcellindex@}}{\expandonce\@preTAB}% + \setbox0=\hbox{% + \stack@delim\TABcell{\row@ID}{\theTABcellindex@}\stack@delim}% + \ifdim\wd0>\maxTAB@width\setlength{\maxTAB@width}{\the\wd0}\fi% + \expandafter\ifstrempty\expandafter{\@postTAB}{% + \toggletrue{@doneTABreads}% + }{}% + }% + \expandafter\xdef\csname \row@ID TABcells\endcsname{\arabic{TABcellindex@}}% + \find@TABstrut{#1}% +} + +\newcommand\find@TABstrut[1]{% + \def\@accumulatedTAB{}% + \setcounter{TABcellindex@}{0}% + \expandafter\protected@edef\csname @#1TABtextblob\endcsname{}% + \whileboolexpr{test {\ifnumless{\theTABcellindex@}{\TABcells{#1}}}}{% + \stepcounter{TABcellindex@}% + \protected@edef\@accumulatedTAB{% + \@accumulatedTAB\TABcell{#1}{\theTABcellindex@}}% + }% + \global\csedef{@#1TABtextblob}{\expandonce\@accumulatedTAB}% +} + +\newcommand\TAB@delim[1]{#1}% +\newcommand\TABstackMath{% + \renewcommand\TAB@delim[1]{\ensuremath{##1}}% +} +\newcommand\TABstackText{% + \renewcommand\TAB@delim[1]{##1}% +} + +\newcommand\TABcell[2]{\TAB@delim{% + \ignorespaces\csname TABX#1X\romannumeral#2\endcsname\unskip}} + +\newcommand\TABcells[1]{\csname #1TABcells\endcsname} + +% NOTE THAT THE STRUT IS NOT YET TYPESET, SINCE WE DO NOT YET KNOW +% WHETHER \@#1textblob IS TO BE INVOKED IN MATH MODE OR NOT +\newcommand\TABstrut[1]{\vphantom{\csname @#1TABtextblob\endcsname}} + +\newcommand\tabbedShortstack[2][\stackalignment]{% + \@TAB@stack{#1}{#2}{D}{\Shortstack}} + +\newcommand\alignShortstack[1]{% + \@TAB@stack{}{#1}{A}{\Shortstack}} + +\newcommand\tabularShortstack[2]{% + \@TAB@stack{}{#2}{#1}{\Shortstack}} + +\newcommand\tabbedShortunderstack[2][\stackalignment]{% + \@TAB@stack{#1}{#2}{D}{\Shortunderstack}} + +\newcommand\alignShortunderstack[1]{% + \@TAB@stack{}{#1}{A}{\Shortunderstack}} + +\newcommand\tabularShortunderstack[2]{% + \@TAB@stack{}{#2}{#1}{\Shortunderstack}} + +\newcommand\tabbedLongstack[2][\stackalignment]{% + \@TAB@stack{#1}{#2}{D}{\Longstack}} + +\newcommand\alignLongstack[1]{% + \@TAB@stack{}{#1}{A}{\Longstack}} + +\newcommand\tabularLongstack[2]{% + \@TAB@stack{}{#2}{#1}{\Longstack}} + +\newcommand\tabbedLongunderstack[2][\stackalignment]{% + \@TAB@stack{#1}{#2}{D}{\Longunderstack}} + +\newcommand\alignLongunderstack[1]{% + \@TAB@stack{}{#1}{A}{\Longunderstack}} + +\newcommand\tabularLongunderstack[2]{% + \@TAB@stack{}{#2}{#1}{\Longunderstack}} + +\newcommand\tabbedCenterstack[2][\stackalignment]{% + \@TAB@stack{#1}{#2}{D}{\Centerstack}} + +\newcommand\alignCenterstack[1]{% + \@TAB@stack{}{#1}{A}{\Centerstack}} + +\newcommand\tabularCenterstack[2]{% + \@TAB@stack{}{#2}{#1}{\Centerstack}} + +\newcommand\tabbedVectorstack[2][\stackalignment]{% + \ensureTABstackMath{\@TAB@stack{#1}{#2}{D}{\Vectorstack}}} + +\newcommand\alignVectorstack[1]{% + \ensureTABstackMath{\@TAB@stack{}{#1}{A}{\Vectorstack}}} + +\newcommand\tabularVectorstack[2]{% + \ensureTABstackMath{\@TAB@stack{}{#2}{#1}{\Vectorstack}}} + +\newcommand\parenMatrixstack[2][\stackalignment]{% + \ensureTABstackMath{\left(\@TAB@stack{#1}{#2}{D}{\Vectorstack}\right)}} + +\newcommand\braceMatrixstack[2][\stackalignment]{% + \ensureTABstackMath{\left\{\@TAB@stack{#1}{#2}{D}{\Vectorstack}\right\}}} + +\newcommand\bracketMatrixstack[2][\stackalignment]{% + \ensureTABstackMath{\left[\@TAB@stack{#1}{#2}{D}{\Vectorstack}\right]}} + +\newcommand\vertMatrixstack[2][\stackalignment]{% + \ensureTABstackMath{\left|\@TAB@stack{#1}{#2}{D}{\Vectorstack}\right|}} + +\newcommand\@TAB@stack[4]{% + \setlength{\maxTAB@width}{0pt}% + \let\sv@stackalignment\stackalignment% + \edef\stackalignment{#1}% + \@readMANYrows{#2}% + \edef\TAB@narg{\narg}% + \setcounter{TAB@stackindex}{0}% + \whileboolexpr{test {\ifnumless{\theTAB@stackindex}{\TAB@narg}}}{% + \stepcounter{TAB@stackindex}% + \edef\TAB@prefix{\roman{TAB@stackindex}}% + \protected@edef\TABrow@data{\csname arg\TAB@prefix\endcsname}% + \def\@tmp{\readTABrow{\TAB@prefix}}% + \expandafter\@tmp\expandafter{\TABrow@data}% + }% +% + \setcounter{TABcellindex@}{0}% + \whileboolexpr{test {\ifnumless{\theTABcellindex@}{\TABcells{i}}}}{% + \def\col@stack{% + \protect\TABstrut{i}% + \TABcell{i}{\theTABcellindex@}% + \protect\TABstrut{i}% +}% + \stepcounter{TABcellindex@}% + \@getTABalignment{#3}{\theTABcellindex@}% + \ifboolexpr{% + test {\ifnumgreater{\theTABcellindex@}{1}}% + }{\add@TAB@gap{#3}{\theTABcellindex@}}{}% + \setcounter{TAB@stackindex}{1}% + \whileboolexpr{test {\ifnumless{\theTAB@stackindex}{\TAB@narg}}}{% + \stepcounter{TAB@stackindex}% + \edef\TAB@prefix{\roman{TAB@stackindex}}% + \protected@edef\col@stack{\col@stack\SEP@char% + \protect\TABstrut{\TAB@prefix}% + \TABcell{\TAB@prefix}{\theTABcellindex@}% + \protect\TABstrut{\TAB@prefix}% + }% + }% + \iftoggle{fixed@TABwidth}% + {\makebox[\the\maxTAB@width][\stackalignment]{% + \expandafter#4\expandafter{\col@stack}}}% + {\expandafter#4\expandafter{\col@stack}}% + }% + \let\stackalignment\sv@stackalignment% +} + +\newcommand\tabbedstackon[3][\stackgap]{% + \@TABstackonunder{#1}{#2}{#3}{D}{\stackon}} + +\newcommand\alignstackon[3][\stackgap]{% + \@TABstackonunder{#1}{#2}{#3}{A}{\stackon}} + +\newcommand\tabularstackon[4][\stackgap]{% + \@TABstackonunder{#1}{#3}{#4}{#2}{\stackon}} + +\newcommand\tabbedstackunder[3][\stackgap]{% + \@TABstackonunder{#1}{#2}{#3}{D}{\stackunder}} + +\newcommand\alignstackunder[3][\stackgap]{% + \@TABstackonunder{#1}{#2}{#3}{A}{\stackunder}} + +\newcommand\tabularstackunder[4][\stackgap]{% + \@TABstackonunder{#1}{#3}{#4}{#2}{\stackunder}} + +\newcommand\tabbedstackanchor[3][\stackgap]{% + \@TABstackonunder{#1}{#2}{#3}{D}{\stackanchor}} + +\newcommand\alignstackanchor[3][\stackgap]{% + \@TABstackonunder{#1}{#2}{#3}{A}{\stackanchor}} + +\newcommand\tabularstackanchor[4][\stackgap]{% + \@TABstackonunder{#1}{#3}{#4}{#2}{\stackanchor}} + +\newcommand\@TABstackonunder[5]{% + \setlength{\maxTAB@width}{0pt}% + \let\sv@stackalignment\stackalignment% + \readTABrow{i}{#2}% + \readTABrow{ii}{#3}% + \setcounter{TABcellindex@}{0}% + \whileboolexpr{test {\ifnumless{\theTABcellindex@}{\TABcells{i}}}}{% + \stepcounter{TABcellindex@}% + \@getTABalignment{#4}{\theTABcellindex@}% + \ifboolexpr{% + test {\ifnumgreater{\theTABcellindex@}{1}}% + }{\add@TAB@gap{#4}{\theTABcellindex@}}{}% + \iftoggle{fixed@TABwidth}% + {\makebox[\the\maxTAB@width][\stackalignment]{% + #5[#1]{\TABstrut{i}\TABcell{i}{\theTABcellindex@}\TABstrut{i}}% + {\TABstrut{ii}\TABcell{ii}{\theTABcellindex@}\TABstrut{ii}}}}% + {#5[#1]{\TABstrut{i}\TABcell{i}{\theTABcellindex@}\TABstrut{i}}% + {\TABstrut{ii}\TABcell{ii}{\theTABcellindex@}\TABstrut{ii}}}% + }% + \let\stackalignment\sv@stackalignment% +} + +\newcommand\@getTABalignment[2]{% + \ifstrequal{#1}{D}{}{% T, DO NOTHING (USE \stackalignment) + \ifstrequal{#1}{A}{% + \ifnumequal{1}{#2}{% + \def\stackalignment{r}}{% A, 1st ELEMENT, SET TO r + \if l\stackalignment% + \def\stackalignment{r}\else% A, SWITCH l TO r + \def\stackalignment{l}\fi}}{% A, SWITCH r TO l + \set@tabularcellalignment{#1}{#2}% tabular, READ #2 location + }% + }% +} + +\def\tabbed@gap{0pt} +\def\align@gap{1em} +\def\tabular@gap{\tabcolsep} + +\newcommand\setstacktabbedgap[1]{\def\tabbed@gap{#1}} +\newcommand\setstackaligngap[1]{\def\align@gap{#1}} +\newcommand\setstacktabulargap[1]{\def\tabular@gap{#1}} + +\newcommand\add@TAB@gap[2]{% + \ifstrequal{#1}{D}{\hspace{\tabbed@gap}}{% + \ifstrequal{#1}{A}{% + \if r\stackalignment\hspace{\align@gap}\fi% + }{% + \hspace{\tabular@gap}% + }% + }% +} + +\newcounter{TABalignmentindex@} + +\newcommand\set@tabularcellalignment[2]{% + \setcounter{TABalignmentindex@}{1}% + \edef\tabular@settings{#1.}% + \whileboolexpr{test {\ifnumless{\theTABalignmentindex@}{#2}}}{% + \stepcounter{TABalignmentindex@}% + \edef\tabular@settings{\expandafter\@gobble\tabular@settings.}% + }% + \expandafter\@getnextTABchar\tabular@settings\\% GET NEXT TAB ALIGNMENT + \if l\@nextTABchar\edef\stackalignment{l}\else% + \if r\@nextTABchar\edef\stackalignment{r}\else% + \if c\@nextTABchar\edef\stackalignment{c}\fi% + \fi% IGNORE IF NOT l, c, OR r + \fi% +} + +\def\@getnextTABchar#1#2\\{\gdef\@nextTABchar{#1}} + + +\newtoggle{fixed@TABwidth} +\newcommand\fixTABwidth[1]{% + \if T#1\toggletrue{fixed@TABwidth}\else\togglefalse{fixed@TABwidth}\fi% +} +\fixTABwidth{F} + +\newcommand\ensureTABstackMath[1]{\TABstackMath#1\TABstackText} + +\endinput diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index c71dc285019..52405720125 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -449,7 +449,7 @@ my @TLP_working = qw( systeme t-angles t2 tabfigures tableaux tablefootnote tablists tableof tablor tabls - tabriz-thesis tabto-generic tabto-ltx + tabriz-thesis tabstackengine tabto-generic tabto-ltx tabu tabularborder tabularcalc tabularew tabulars-e tabulary tabvar tagging talk tamefloats tamethebeast tap tapir tcldoc tcolorbox tdclock tdsfrmath diff --git a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc index 45c603c07af..512f8799cc5 100644 --- a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc @@ -801,6 +801,7 @@ depend tablefootnote depend tableof depend tablists depend tabls +depend tabstackengine depend tabto-ltx depend tabu depend tabularborder diff --git a/Master/tlpkg/tlpsrc/tabstackengine.tlpsrc b/Master/tlpkg/tlpsrc/tabstackengine.tlpsrc new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/Master/tlpkg/tlpsrc/tabstackengine.tlpsrc |