summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/collcell
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2011-02-28 00:25:39 +0000
committerKarl Berry <karl@freefriends.org>2011-02-28 00:25:39 +0000
commit5c080945d173a7b1f59e45af275fbc681489fe04 (patch)
treea136483fceae85ae28a4ebfa104b3ba24d2f017e /Master/texmf-dist/source/latex/collcell
parent995f56a40c36079b6c2cc498da5f3f152c42fb8d (diff)
collcell (27feb11)
git-svn-id: svn://tug.org/texlive/trunk@21539 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/collcell')
-rw-r--r--Master/texmf-dist/source/latex/collcell/README3
-rw-r--r--Master/texmf-dist/source/latex/collcell/collcell.dtx409
2 files changed, 365 insertions, 47 deletions
diff --git a/Master/texmf-dist/source/latex/collcell/README b/Master/texmf-dist/source/latex/collcell/README
index a187804e29a..8201f91aa2e 100644
--- a/Master/texmf-dist/source/latex/collcell/README
+++ b/Master/texmf-dist/source/latex/collcell/README
@@ -2,9 +2,8 @@ The collcell Package
--------------------
Copyright (C) 2009-2011 by Martin Scharrer <martin@scharrer-online.de>
http://www.ctan.org/pkg/collcell/
-Version v0.1a -- 2011/02/05
-This small package provides macros which collect the cell content of
+This package provides macros which collect the cell content of
a tabular and provide it to a macro as argument. It was inspired by the
\collect@body macro defined by the amsmath or the environ package,
which can be used to collect the body of an environment. Special care
diff --git a/Master/texmf-dist/source/latex/collcell/collcell.dtx b/Master/texmf-dist/source/latex/collcell/collcell.dtx
index b6523aa4d45..6a0846c3219 100644
--- a/Master/texmf-dist/source/latex/collcell/collcell.dtx
+++ b/Master/texmf-dist/source/latex/collcell/collcell.dtx
@@ -21,18 +21,20 @@
% and the derived file collcell.sty.
%
% \fi
-%%^^A $Id: collcell.dtx 2135 2011-02-05 13:45:59Z martin $
+%%^^A $Id: collcell.dtx 2188 2011-02-27 14:22:06Z martin $
%
% \iffalse
%<package>\ProvidesPackage{collcell}
%<*driver>
\ProvidesFile{collcell.dtx}
%</driver>
- [2011/02/05 v0.1a Collect the content of a tabular cell]
+ [2011/02/27 v0.5 Collect the content of a tabular cell]
%<*driver>
\documentclass{ydoc}
\GetFileInfo{\jobname.dtx}
-\usepackage{collcell}[\filedate]
+\usepackage[robustcr]{collcell}[\filedate]
+\usepackage{tikz-timing}
+\lstset{language=[latex]tex,basicstyle=\ttfamily}
\EnableCrossrefs
%\CodelineIndex
@@ -46,7 +48,7 @@
%</driver>
% \fi
%
-% \CheckSum{0}
+% \CheckSum{334}
%
% \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
@@ -68,6 +70,7 @@
% \changes{v0.0}{2009/08/13}{Created package}
% \changes{v0.1}{2011/02/04}{First released version}
% \changes{v0.1a}{2011/02/05}{Fixed unwanted spaces. Fixed misspelled macros in example.}
+% \changes{v0.5}{2011/02/27}{Fixed several bugs and limitations. (Complete list to be inserted)}
%
%
% \DoNotIndex{\newcommand,\newenvironment,\def,\edef,\xdef,\DeclareRobustCommand}
@@ -94,12 +97,17 @@
% \vspace{1.2em}%
%
% \begin{abstract}
-% This small package provides macros which collect the cell content of a tabular
+% This package provides macros which collect the cell content of a tabular
% and provide it to a macro as argument. It was inspired by the |\collect@body|
% macro defined by the \pkg{amsmath} or the \pkg{environ} package, which can be used
% to collect the body of an environment. Special care is taken to remove all aligning
% macros inserted by tabular from the cell content. The macros also work in the last
-% column of a table. They do not support verbatim material inside the cells.
+% column of a tabular. They do not support verbatim material inside the cells, except of a
+% special almost-verbatim version of \verb+\verb+.
+%
+% This package is relatively new and might still not work in all possible situations which can arise
+% in a tabular. The implementation might change in future versions. Please do not hesitate to contact the
+% author about any issue and suggestions.
% \end{abstract}
%
% \section{Usage}
@@ -134,6 +142,94 @@
% Note that if such a cell contains a tabular environment by itself, the environment must be wrapped
% in braces `|{ }|' to ensure proper operation.
%
+% \subsection{Options}
+% The following options are supported:
+% \begin{description}
+% \item[verb] \null
+% \item[noverb] (Default |noverb|) Enables or disables the definition of a special almost-verbatim version of \verb+\verb+.
+% At the moment the one defined by the \pkg{tabularx} package is used, which is therefore loaded when this feature is enabled.
+% Future versions of \pkg{collcell} might provide this macro in a different way, so the visual result might be different.
+% The \pkg{tabularx} should be loaded explicitly if it is used.
+% This version of \verb+\verb+ will read the content first normally, i.e. non-verbatim, and then print the included tokens in a verbatim format.
+% The content must include a balanced number of |{ }| and must not be end with |\|. Macros inside the content will be followed by a space.
+% See the manual of \pkg{tabularx} (page 8 in the version from 1999/01/07) for a more detailed description.
+% \item[robustcr]
+% \item[norobustcr] (Default |robustcr|) This options enable or disable the redefinition of |\\| to a robust version, i.e. this macro
+% will be prefixed with eTeX's |\protected| to ensure that it isn't expanded by the underlying |\halign|. If this feature disabled the
+% last cell of a tabular must not be empty or only hold empty macros (like |\empty|).
+% \end{description}
+%
+% \subsection{Limitations}
+%
+% \DescribeMacro\ccunskip
+% The macro |\unskip| should not be included inside the cell directly, but only inside a |{ }| group or a macro.
+% Otherwise it will be taken as part of the internal cell code and ignored. Leading spaces will however be removed.
+% This macro can be used as a replacement of |\unskip| inside the cells.
+%
+% \DescribeMacro\cci
+% The content of every cell is expanded by TeX itself until the first non-expandable token (macro, character, \ldots) is found. This happens to check if a |\noalign| follows
+% with e.g.\ is used inside |\hrule| and other rule drawing macros. There is nothing what \pkg{collcell} could do about this.
+% If this expansion is unwanted the non-expandable token \Macro\cci should be placed at the beginning of the cell. This macro will be ignored (discarded) by \pkg{collcell} and
+% will not be provided to the user macro (|cci| = collect cell; ignore).
+%
+% \section{Tests and Examples}
+%
+% \begin{example}
+% \caption{Framebox, texttiming, expanded tokens, sub-tabular}
+% \begin{examplecode}
+% \makeatletter
+% \newcommand*\Meaning[1]
+% {\def\CODE{#1}\texttt{\expandafter\strip@prefix\meaning\CODE}}%
+% \newcolumntype{F}{>{\collectcell\fbox}l<{\endcollectcell}}%
+% \newcolumntype{M}{>{\collectcell\Meaning}l<{\endcollectcell}}%
+% \newcolumntype{T}{>{\collectcell\texttiming}l<{\endcollectcell}}%
+% \begin{tabular}{@{}F@{}|@{}M@{}|@{}T@{}}
+% A & B & HLDZ 2{HZLZ} \\
+% A & \empty\relax Z5D{TEST}Z & Z5D{TEST}Z \\
+% A & \cci\empty Z5D{TEST}Z & Z5D{TEST}Z \\
+% {\begin{tabular}{cFc} a & b & c \end{tabular}} &
+% \relax\begin{quote}AA\end{quote} & $5+5${C} \\
+% A & B \ccunskip B & 3{ttz} \\
+% \end{tabular}%
+% \end{examplecode}
+% \end{example}
+%
+% \makeatletter
+% \newcommand*\Meaning[1]{\def\CODE{#1}\texttt{\expandafter\strip@prefix\meaning\CODE}}%
+% \newcolumntype{M}{>{\collectcell\Meaning}l<{\endcollectcell}}%
+% \newcolumntype{F}{>{\collectcell\fbox}l<{\endcollectcell}}%
+% \makeatother
+%
+% \begin{example}
+% \caption{Multicolumn, expanded row macro}
+% \begin{examplecode}
+% \def\abc{ \empty A & \empty B & \empty C }
+% \begin{tabular}{MMM}
+% \multicolumn{2}{M}{\empty Multi} & \empty single \\
+% \abc \\
+% \end{tabular}
+% \end{examplecode}
+% \end{example}
+%
+% \begin{example}
+% \caption{Empty cells, missing `\texttt{\textbackslash\textbackslash}' at end}
+% \begin{examplecode}
+% \begin{tabular}{|F|F|F|}
+% \\
+% A & \\
+% A & B \\
+% A & B & \\
+% A & B & C \\
+% & \\
+% & B \\
+% & B & \\
+% & B & C \\
+% & & \\
+% & & C \\
+% A & B & C
+% \end{tabular}
+% \end{examplecode}
+% \end{example}
%
% \StopEventually{}
% \clearpage
@@ -141,26 +237,75 @@
%<*package>
% \fi
% \section{Implementation}
+%
+% \begin{macrocode}
+\RequirePackage{array}
+\def\collcell@beforeuser{\ignorespaces}
+\def\collcell@afteruser{\unskip}
+
+\newif\if@collcell@verb
+\newif\if@collcell@robustcr
+\@collcell@robustcrtrue
+% \end{macrocode}
+%
+% \subsection{Options}
+% \begin{macrocode}
+\DeclareOption{verb}{\@collcell@verbtrue}
+\DeclareOption{noverb}{\@collcell@verbfalse}
+\DeclareOption{robustcr}{\@collcell@robustcrtrue}%
+\DeclareOption{norobustcr}{\@collcell@robustcrfalse}%
+\ProcessOptions\relax
+\if@collcell@verb
+ \RequirePackage{tabularx}
+ \def\collcell@beforeuser{%
+ \let\collcell@savedverb\verb
+ \let\verb\TX@verb
+ \let\TX@vwarn\collcell@vwarn
+ \ignorespaces
+ }%
+ \def\collcell@afteruser{\unskip\let\verb\collcell@savedverb}%
+ \def\collcell@vwarn{%
+ \PackageWarning{collcell}{\noexpand\verb may be unreliable inside a collected cell}%
+ }%
+\fi
+\if@collcell@robustcr
+ \RequirePackage{etoolbox}
+ \robustify\@arraycr
+\fi
+% \end{macrocode}
+%
+% \subsection{Collect cell content}
% \begin{macrocode}
-\newtoks\collect@cell@toks
+\let\collect@cell@toks\@temptokena
+\newcount\collect@cell@count
% \end{macrocode}
%
-% \begin{macro}{\collectcell}
+% \begin{macro}{\collectcell}[2]{user macro(s)}{ignored tokens, possible empty}
% \begin{macrocode}
\newenvironment{collectcell}{}{}
\def\collectcell#1#2\ignorespaces{%
+ \begingroup
+ \collect@cell@count\z@
\collect@cell@toks{}%
\let\collect@cell@spaces\empty
\def\collect@cell@end{%
- \expandafter\scantokens\expandafter
- {\expandafter#1\expandafter{\the\collect@cell@toks}}%
+ \expandafter\endgroup
+ \expandafter\collcell@beforeuser
+ \expandafter\ccell@swap\expandafter{\the\collect@cell@toks}{#1}%
+ \collcell@afteruser
}%
- \def\collect@cell@next{\collect@cell@look}%
- \collect@cell@next
+ \collect@cell@look#2%
}
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\ccell@swap}
+% Swaps the two arguments. The second one (user macro(s)) is added without braces.
+% \begin{macrocode}
+\def\ccell@swap#1#2{#2{#1}}
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\endcollectcell}
% Holds unique signature which will expand to nothing.
% \begin{macrocode}
@@ -170,6 +315,7 @@
%
%
% \begin{macro}{\collect@cell@look}
+% Looks ahead to the next token and call the next macro to handle it.
% \begin{macrocode}
\def\collect@cell@look{%
\futurelet\collect@cell@lettoken\collect@cell@look@
@@ -178,51 +324,53 @@
% \end{macro}
%
% \begin{macro}{\collect@cell@eatspace}
+% Eats a following space and call the 'look' macro again.
% \begin{macrocode}
-\begingroup
-\def\:{\collect@cell@eatspace}
-\expandafter\gdef\: {\collect@cell@look}
-\endgroup
+\@firstofone{\def\collect@cell@eatspace} {\collect@cell@look}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\collect@cell@look@}
+% Handles special tokens which should not be read as argument.
+% All other are handled by \Macro\collect@cell@arg.
% \begin{macrocode}
\def\collect@cell@look@{%
- \ifx\collect@cell@lettoken\@sptoken
- \edef\collect@cell@spaces{\collect@cell@spaces\space}%
- \def\collect@cell@next{\collect@cell@eatspace}%
- \else
- \ifx\collect@cell@lettoken\bgroup
- \def\collect@cell@next{\collect@cell@group}%
- \else
- \def\collect@cell@next{\collect@cell@arg}%
- \fi
- \fi
- \collect@cell@next
+ \cc@case
+ \@sptoken{%
+ \edef\collect@cell@spaces{\collect@cell@spaces\space}%
+ \collect@cell@eatspace
+ }%
+ \bgroup{\collect@cell@group}%
+ \default{\collect@cell@arg}%
+ \endcc@case
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\collect@cell@group}
+% Tests if the previous discovered |begin-group character {| token was a |\bgroup| or a |{|.
+% In the first case the command sequence is simply added but in the second case the surrounding
+% braces must be added again.
+% The use of |\unexpanded| allows |#| in the cells, e.g. for in-cell macro definitions.
% \begin{macrocode}
\def\collect@cell@group#1{%
\begingroup
- \def\@tempa{#1}%
+ \edef\@tempa{\unexpanded{#1}}%
\def\@tempb{\bgroup}%
\ifx\@tempa\@tempb
\endgroup
- \def\collect@cell@next{\collect@cell@arg\bgroup}%
+ \collect@cell@addarg{#1}%
\else
\endgroup
- \def\collect@cell@next{\collect@cell@arg{{#1}}}%
+ \collect@cell@addarg{{#1}}%
\fi
- \collect@cell@next
+ \collect@cell@look
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\collect@cell@addarg}
+% Adds the given argument to the token list.
% \begin{macrocode}
\def\collect@cell@addarg#1{%
\expandafter\expandafter\expandafter\collect@cell@toks
@@ -233,24 +381,195 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\collect@cell@addcc}
+% This macro is called when another |\collectcell| is found in the preamble
+% (at the moment also inside the cell). The argument of it is placed into the
+% token register and all following tokens are placed in an own token list which content
+% is then added with surrounding braces in the outer token list once the |\endcollectcell|
+% is found. TeX scoping mechanism is used for this so only one token register is required.
+% \begin{macrocode}
+\def\collect@cell@addcc#1{%
+ \collect@cell@addarg{#1}%
+ \begingroup
+ \collect@cell@toks{}%
+ \collect@cell@look
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\collect@cell@checkcsname}
+% For support of |\end{tabularx}| without trailing |\\|.
+% \begin{macrocode}
+\def\collect@cell@checkcsname#1\endcsname{%
+ \begingroup
+ \expandafter\ccell@swap\expandafter
+ {\expandafter,\@currenvir,endtabular,endtabular*,array,tabularx,}%
+ {\in@{,#1,}}%
+ \ifin@
+ \endgroup
+ \expandafter\@firstoftwo
+ \else
+ \endgroup
+ \expandafter\@secondoftwo
+ \fi
+ {\collect@cell@cr\\\csname#1\endcsname}%
+ {\collect@cell@addarg{\csname#1\endcsname}\collect@cell@look}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\collect@cell@checkend}[1]{The argument of an \string\end~macro}
+% Reads the argument of |\end| and checks if it is identical to the current environment (|tabular|, |array|, |tabularx|, ...).
+% If so the collecting of token is ended, otherwise the |\end| and its argument are added to the
+% \begin{macrocode}
+\def\collect@cell@checkend#1{%
+ \begingroup
+ \def\@tempa{#1}%
+ \ifx\@tempa\@currenvir
+ \endgroup
+ \expandafter\@firstoftwo
+ \else
+ \endgroup
+ \expandafter\@secondoftwo
+ \fi
+ {\collect@cell@cr\\\end{#1}}%
+ {\collect@cell@addarg{\end{#1}}\collect@cell@look}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cc@iftoken}
+% Compares the |\collect@cell@lettoken| with the token given as argument.
+% \begin{macrocode}
+\def\cc@iftoken#1{%
+ \ifx#1\collect@cell@lettoken
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cc@case}
+% Case statement over |\collect@cell@lettoken|.
+% \begin{macrocode}
+\def\cc@case{%
+ \begingroup
+ \let\default= \collect@cell@lettoken
+ \cc@@case
+}
+\def\cc@@case#1{%
+ \ifx#1\collect@cell@lettoken
+ \expandafter\cc@@truecase
+ \else
+ \expandafter\cc@@falsecase
+ \fi
+}
+\def\cc@@truecase#1#2\endcc@case{\endgroup#1}
+\def\cc@@falsecase#1{\cc@@case}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\collcell@unskip}
+% Wrapper around |\unskip| to protect it from the eyes of the token scanner.
+% It is protected to avoid trouble if the user wrongly uses it at the beginning of the cell.
+% The macro is first defined using |\newcommand| to warn the user about name collisions.
+% \begin{macrocode}
+\newcommand*\ccunskip{}
+\protected\def\ccunskip{\unskip}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cci}
+% Protected empty macro usable to stop the expansion of tokens at the beginning of the
+% cell. It is ignored (gobbled) by the token scanner.
+% The macro is first defined using |\newcommand| to warn the user about name collisions.
+% \begin{macrocode}
+\newcommand*\cci{}
+\protected\def\cci{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\collect@cell@cr}
+% Redefines the table line/row end macro |\cr| so that
+% token collection is restarted after the real |\cr| is expanded
+% and the end material defined by `<{}` is inserted.
+%
+% This redefinition must be done around some \emph{dirty tricks}
+% otherwise the |\cr| will be wrongly taken as end of the
+% row.
+%
+% Because the redefinition is done just at the end of a cell inside the group
+% opened by |collcell| it will only be locally.
+% \begin{macrocode}
+\def\collect@cell@cr{%
+ \iffalse{\fi
+ \let\collcell@realcr\cr
+ \def\cr{%
+ \expandafter
+ \collect@cell@look
+ \collcell@realcr
+ }%
+ \iffalse}\fi
+}
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\collect@cell@arg}
+% Handles the arguments.
+% The first token of the argument is still in the |lettoken| macro which is compared
+% against a list of possible end tokens.
+% Then either the cell end is handled or the argument is added to the token register
+% and the rest of the cell is processed.
% \begin{macrocode}
\def\collect@cell@arg#1{%
- \ifx\collect@cell@lettoken\\%
- \def\collect@cell@next{\collect@cell@end#1}%
- \else
- \ifx\collect@cell@lettoken\unskip
- \def\collect@cell@next{%
- \@ifnextchar\endcollectcell
- {\collect@cell@end#1}%
- {\collect@cell@addarg{#1}\collect@cell@look}%
+ \cc@case
+ \\{\collect@cell@cr#1}%
+ \end{\collect@cell@checkend}%
+ \csname{\collect@cell@checkcsname}%
+ \unskip{%
+ \let\collect@cell@spaces\empty
+ %\collect@cell@addarg{#1}% do not include the \unskip
+ \collect@cell@look%
+ }%
+ \@sharp{%
+ \expandafter\collect@cell@addarg\expandafter{#1}%
+ \collect@cell@look
+ }%
+ \collectcell{%
+ \advance\collect@cell@count by \@ne
+ \collect@cell@addcc%
+ }%
+ \endcollectcell{%
+ \ifnum\collect@cell@count=\z@
+ \expandafter\collect@cell@end
+ \else
+ \expandafter\endgroup
+ \expandafter\collect@cell@addarg\expandafter
+ {\expandafter{\the\collect@cell@toks}}%
+ \advance\collect@cell@count by \m@ne%
+ \expandafter\collect@cell@look
+ \fi
+ }%
+ \cci{%
+ \collect@cell@look
+ }%
+ \default{%
+ \expandafter\ccell@swap\expandafter
+ {\csname endtabular*\endcsname\endtabular\endarray}{\in@{#1}}%
+ \ifin@
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+ {\collect@cell@cr\\#1}%
+ {%
+ \collect@cell@addarg{#1}%
+ \collect@cell@look
}%
- \else
- \collect@cell@addarg{#1}%
- \def\collect@cell@next{\collect@cell@look}%
- \fi
- \fi
- \collect@cell@next
+ }%
+ \endcc@case
}
% \end{macrocode}
% \end{macro}