From 5c080945d173a7b1f59e45af275fbc681489fe04 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 28 Feb 2011 00:25:39 +0000 Subject: collcell (27feb11) git-svn-id: svn://tug.org/texlive/trunk@21539 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/source/latex/collcell/README | 3 +- .../texmf-dist/source/latex/collcell/collcell.dtx | 409 ++++++++++++++++++--- 2 files changed, 365 insertions(+), 47 deletions(-) (limited to 'Master/texmf-dist/source/latex/collcell') 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 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 %\ProvidesPackage{collcell} %<*driver> \ProvidesFile{collcell.dtx} % - [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 @@ % % \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} -- cgit v1.2.3