summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Master/texmf-dist/doc/latex/etextools/etextools-examples.pdfbin79220 -> 80209 bytes
-rw-r--r--Master/texmf-dist/doc/latex/etextools/etextools-examples.tex97
-rw-r--r--Master/texmf-dist/doc/latex/etextools/etextools.pdfbin564537 -> 635108 bytes
-rw-r--r--Master/texmf-dist/source/latex/etextools/etextools.dtx1047
-rw-r--r--Master/texmf-dist/source/latex/etextools/etextools.ins5
-rw-r--r--Master/texmf-dist/tex/latex/etextools/etextools.sty354
6 files changed, 1222 insertions, 281 deletions
diff --git a/Master/texmf-dist/doc/latex/etextools/etextools-examples.pdf b/Master/texmf-dist/doc/latex/etextools/etextools-examples.pdf
index 2ed2e95f2c5..3906cf7c21e 100644
--- a/Master/texmf-dist/doc/latex/etextools/etextools-examples.pdf
+++ b/Master/texmf-dist/doc/latex/etextools/etextools-examples.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/etextools/etextools-examples.tex b/Master/texmf-dist/doc/latex/etextools/etextools-examples.tex
index 97c800e3fe3..572e76e479d 100644
--- a/Master/texmf-dist/doc/latex/etextools/etextools-examples.tex
+++ b/Master/texmf-dist/doc/latex/etextools/etextools-examples.tex
@@ -21,15 +21,16 @@
%% etextools.sty, etextools.pdf, etextools.ins,
%% and etextools-examples.tex
%%
-%%% etextools : more e-TeX useful tools for LaTeX package writers
+%%% etextools : more e-TeX useful tools for LaTeX package writers (v.
+
\documentclass[11pt,french,a4paper,oneside]{scrartcl}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[american]{babel}
-\usepackage{geometry,doc,ltxdockit,txfonts,fancyhdr}
+\usepackage{geometry,doc,ltxdockit,txfonts,fancyhdr,stmaryrd,graphicx,fancyvrb}
\usepackage{etextools}
\hypersetup{colorlinks,pdfstartview={FitH}}
-\geometry{top=2cm,bottom=2cm,left=2.5cm,right=1cm}
+\geometry{top=1.5cm,bottom=1.2cm,left=2.5cm,right=1cm}
\fancyhf{}
\fancyhead[L]{Examples for the \sty{etextools} package}
\pagestyle{fancy}
@@ -37,6 +38,9 @@
\makeatletter
\def\smex{\leavevmode\hb@xt@2em{\hfil$\longrightarrow$\hfil}}
+\def\FE{\setbox8\hbox{$\m@th\bindnasrepma$}%
+ \textcolor{fecc}{\scalebox{2}{$\copy8\mkern-13.5mu\copy8\mkern-13.5mu\copy8$}}}
+\definecolor{fecc}{rgb}{.2,.6,.2}
\def\strip@meaning{\expandafter\strip@prefix\meaning}
\def\strip@macro{\expandafter\strip@macroprefix\meaning}
\def\get@params#1{\expandafter\@get@params\meaning#1\@nil}
@@ -49,12 +53,14 @@
\def\meaningcs#1{\expandafter\meaning\csname#1\endcsname}
\def\Meaningcs#1{\expandafter\strip@meaning\csname #1\endcsname}
+\@ifundefined{pdfstrcmp}{\let\ifpdfTeX\iffalse}{\let\ifpdfTeX\iftrue}
-\newcommand\test[1]{%
+\newcommand*\test{\@ifstar{\let\fe\relax\testi}{\let\fe\FE\testi}}
+\newcommand\testi[1]{%
\csname test#1\endcsname
\edef\usercmd{\Meaningcs{test#1}}\edef\result{\meaningcs{#1Test}}\noindent
\begin{tabular}{lp{15cm}}
- \multicolumn{2}{l}{\textcolor{blue}{\llap\smex\tt \usercmd}} \\[1.5ex]
+ \multicolumn{2}{l}{\textcolor{blue}{\llap{\fe\,\smex}\tt \usercmd}} \\[1.5ex]
\cmd{#1Test}= & \tt\bfseries\result
\end{tabular}\par\nobreak\hrulefill\null\goodbreak}
@@ -157,7 +163,9 @@
\test{FE@testopt}
\section{Lists management}
+
\subsection{\cmd{csvloop} and \cmd{csvloop*} examples}
+
\subsubsection{\cmd{makequotes}}
\def\makequotes#1{"#1"\space}
\def\testcsvloop{%
@@ -165,11 +173,13 @@
}
\preline\makequotes
\test{csvloop}
+
\subsubsection{\cmd{detokenize}}
\def\testcsvloop{%
\edef\csvloopTest{\csvloop*[\detokenize]{\un,\deux}}
}\hrulefill\par
\test{csvloop}
+
\subsubsection{\cmd{numexpr}}
\def\mylist{1,2,3,4,5}\def\BySeven#1{$#1\times 7 = \number\numexpr#1*7\relax$\par}
\def\testcsvloop{%
@@ -177,26 +187,91 @@
\preline\mylist
\preline*\BySeven
\test{csvloop}
+
\subsubsection{protected \cmd{textbf}}
\def\testcsvloop{%
\protected@edef\csvloopTest{\csvloop*[\textbf]{hello ,my ,friends}}
}\hrulefill\par
\test{csvloop}
-\subsection{\cmd{getlistitem}}
+\subsection{Index in lists and items by index}
+
+\subsubsection{\cmd{getlistitem}}
\csvtolist*\mylist{one,two,three,four,five,alpha,beta,gamma}
\def\testgetlistitem{%
- \edef\getlistitemTest{\getlistitem\mylist{4}}
+ \edef\getlistitemTest{\getlistitem{4}\mylist}
}\hrulefill\par
\noindent\hskip6pt|\csvtolist*\mylist{one,two,three,four,five,alpha,beta,gamma}|\par\vskip1.5ex
\test{getlistitem}
-\subsection{\cmd{getlistindex} {\mdseries(not expandable)}}
-\getlistindex{four}\mylist
+\subsubsection{\cmd{getlistindex}}
+\ifpdfTeX
+\leavevmode\vadjust{\textsl{Require the }\string\pdfstrcmp\ \textsl{primitive (pdf\TeX{}) :}}
+\def\testgetlistindex{%
+ \edef\getlistindexTest{\getlistindex{alpha}\mylist}
+}\hrulefill\par
+\noindent\hskip6pt|\csvtolist*\mylist{one,two,three,four,five,alpha,beta,gamma}|\par\vskip1.5ex
+\test{getlistindex}
+
+\leavevmode\vadjust{\textsl{Require the }\string\pdfstrcmp\ \textsl{primitive (pdf\TeX{}) :}}
+\def\testgetlistindex{%
+ \edef\getlistindexTest{\getcsvlistindex*{alpha}{one,two,three,four,five,alpha,beta}}
+}\hrulefill\par
+\test{getlistindex}
+\fi
+
\hrulefill\par
+\getlistindex[\myindex]{alpha}\mylist
+{\color{blue}\noindent\hskip6pt\llap\smex|\getlistindex[\myindex]{alpha}\mylist|\par\vskip1.5ex}
+{\tt\string\myindex=\quad\textbf{\meaning\myindex}}
+\hrulefill\par\vskip.5ex
+
+\hrulefill\par
+\newcount\myindex
+\getcsvlistindex*[\myindex]{alpha}{one,two,three,four,five,alpha,beta}
+\noindent\hskip6pt|\newcount\myindex|\par
+{\color{blue}\noindent\hskip6pt\llap\smex|\getcsvlistindex*[\myindex]{alpha}{one,two,three,four,five,alpha,beta}|}\par\vskip.5ex
+{\tt\string\the\string\myindex=\qquad\textbf{\the\myindex}}
+\hrulefill\par\vskip.5ex
+
+\subsubsection{\cmd{xgetlistindex}}
+\ifpdfTeX
+\leavevmode\vadjust{\textsl{Require the }\string\pdfstrcmp\ \textsl{primitive (pdf\TeX{}) :}}
+\def\x{beta}
+\def\testxgetlistindex{%
+ \edef\xgetlistindexTest{\xgetlistindex{\x}\mylist}
+}\hrulefill\par
\noindent\hskip6pt|\csvtolist*\mylist{one,two,three,four,five,alpha,beta,gamma}|\par\vskip1.5ex
-\noindent\hskip6pt\textcolor{blue}{\llap\smex\cmd{getlistindex}\string{four\string}\cmd{mylist}}\par\vskip1.5ex
-\noindent\hskip6pt\cmd{indexinlist}=\quad{\bfseries\meaning\indexinlist}\par\hrulefill\par
+\preline*\x
+\test{xgetlistindex}
+\fi
+
+\subsubsection{\cmd{getlistindex} with \cmd{ifcase}}
+
+\leavevmode\vadjust{Always purely expandable (no need of |\pdfstrcmp|, comparison done by |\ifx|):}
+\hrulefill\par\noindent
+\llap{\FE\,\smex}\par\vskip-2.5\baselineskip\strut
+\begin{Verbatim}
+ \ifcase \gettokslistindex*{D}{LRDF\relax O}
+ Problem
+ \or What do to if L
+ \or What do to if R
+ \or What do to if D
+ \or What do to if F
+ \or What do to if \relax
+ \or What do to if O
+ \fi
+\end{Verbatim}
+
+{\tt Result=\qquad\bfseries
+\ifcase\gettokslistindex*{D}{LRDF}
+ Problem
+\or What do to if L
+\or What do to if R
+\or What do to if D
+\or What do to if F
+\fi}\par
+\hrulefill\par\vskip.5ex
\end{document}
diff --git a/Master/texmf-dist/doc/latex/etextools/etextools.pdf b/Master/texmf-dist/doc/latex/etextools/etextools.pdf
index 1a20a8f26f6..5e82e254a98 100644
--- a/Master/texmf-dist/doc/latex/etextools/etextools.pdf
+++ b/Master/texmf-dist/doc/latex/etextools/etextools.pdf
Binary files differ
diff --git a/Master/texmf-dist/source/latex/etextools/etextools.dtx b/Master/texmf-dist/source/latex/etextools/etextools.dtx
index 3c335b7296d..6dded5c5e0a 100644
--- a/Master/texmf-dist/source/latex/etextools/etextools.dtx
+++ b/Master/texmf-dist/source/latex/etextools/etextools.dtx
@@ -1,5 +1,5 @@
% \iffalse meta-comment
-%%% etextools : more e-TeX useful tools for LaTeX package writers
+%%% etextools : more e-TeX useful tools for LaTeX package writers (v.
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
@@ -37,7 +37,7 @@
\input docstrip.tex
\Msg{************************************************************************}
\Msg{* Installation}
-\Msg{* Package: etextools 2009/07/14 v2e e-TeX more useful tools for LaTeX package writers}
+\Msg{* Package: etextools 2009/07/14 v2h e-TeX more useful tools for LaTeX package writers}
\Msg{************************************************************************}
\keepsilent
@@ -96,17 +96,17 @@ and etextools-examples.tex
\documentclass[a4paper,oneside]{ltxdockit}
\usepackage[latin9]{inputenc}
\usepackage[american]{babel}
-\usepackage{doc,tocloft,stmaryrd,amsmath,graphics,geometry,fancyhdr,framed,bbding,trace,embedfile,etoolbox,marvosym}
+\usepackage{doc,tocloft,stmaryrd,amsmath,graphics,geometry,fancyhdr,framed,bbding,trace,embedfile,etoolbox,marvosym,fancyvrb}
\CodelineNumbered\CodelineIndex
\embedfile{\thisfile.dtx}
-\geometry{left=4.5cm,marginparwidth=14pt,right=2cm,totalheight=26cm}
+\geometry{left=4.5cm,marginparwidth=14pt,right=2cm,totalheight=26.5cm}
\titlepage{%
title={The \sty{etextools} package},
subtitle={An \etex package providing useful tools for LaTeX Users \\ and package Writers},
url={http://www.ctan.org/tex-archive/macros/latex/contrib/etextools/},
author={Florent CHERVET},
email={florent.chervet@free.fr},
- revision={2\:$\boldsymbol{\zeta}$},
+ revision={2\:$\boldsymbol{\eta}$},
date={12 août 2009}}
\hypersetup{%
hyperindex=true,
@@ -122,7 +122,7 @@ and etextools-examples.tex
%</driver>
% \fi
%
-% \CheckSum{887}
+% \CheckSum{0}
%
% \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
@@ -210,20 +210,29 @@ and etextools-examples.tex
% \hbox{\rlap{\kern.4em\hyperref{}{cmdlabel}{#1}{\colorbox{green}{\textcolor{red}{\SunshineOpenCircled}}}}}}}}
% \def\FE{\setbox8\hbox{$\m@th\bindnasrepma$}%
% \marginpar{\raisebox{-2pt}{{\fecccolor\scalebox{2}{$\copy8\mkern-13.5mu\copy8\mkern-13.5mu\copy8$}}}}\space}
+% \def\pdfFE{\setbox8\hbox{$\m@th\bindnasrepma$}%
+% \marginpar{\raisebox{-2pt}{{\fecccolor\llap{\textsf{pdf}\TeX{}\,}\scalebox{2}{$\copy8\mkern-13.5mu\copy8\mkern-13.5mu\copy8$}}}}}
+% \def\clap#1{\hb@xt@\z@{\hss#1\hss}}
% \def\smex{\leavevmode\hb@xt@2em{\hfil\spotcolor$\longrightarrow$\hfil}}
% \font\manual=manfnt\def\dbend{\marginpar{\manual\char127}\space}
+% \def\CS#1{\texttt{\expandafter\@gobble\string\\#1}}
+% \def\CSbf#1{\textbf{\CS{#1}}}
+% \def\Xpackage{\@dblarg\X@package}
+% \def\X@package[#1]#2{%
+% \sty{#2\footnote{\noindent\sty{#2}: \href{http://www.ctan.org/tex-archive/macros/latex/contrib/#1}{\nolinkurl{CTAN:macros/latex/contrib/#1}}}}}
% \parindent\z@\topsep\z@\partopsep\z@\parskip.3\baselineskip
% \cftbeforesecskip=4pt
% \cftbeforepartskip=11pt
% \let\footnoterule\relax
+% \footskip=0pt
% \lastlinefit999
% \makeatother
%
% \thispagestyle{plain}\printtitlepage\medskip
% \fontfamily{ua1}\selectfont
-% \tableofcontents\medskip\enlargethispage{\baselineskip}\thispagestyle{plain}
+% \tableofcontents\medskip\thispagestyle{plain}\enlargethispage{2.5\baselineskip}
%
-% \begin{shaded}\parindent0pt\noindent\large
+% \begin{shaded}\parindent0pt\noindent\normalsize\topsep=-\parskip\itemsep=-\parskip
%
% {\bfseries\catcode`\ \active\let =\,\hfil\NibSolidRight A b s t r a c t \NibSolidLeft\hfil}\par
%
@@ -236,18 +245,18 @@ and etextools-examples.tex
% and the \sty{etoolbox} package from Philipp Lehman. Both of them
% are available on CTAN under the \sty{/latex/contrib/} directory \footnotemark.
%
-% The main contributions of this package are :
+% \underline{The main contributions of this package are :}
% \begin{itemize}
-% \item the \cmdref{expandnext} macro and the \cmdref{ifempty} macro
+% \item the \cmdref{expandnext} macro and the \cmdref{ifempty} and \cmdref{xifempty} macros
% \item the ability to define fully expandable macros with parameter and/or star version (with a small restriction)
% -- see \cmdref{FE@testopt}, \cmdref{FE@ifstar}
-% \item a Command-List Parser constructor that fully uses this new feature : command-list parser are fully expandable
-% -- see \cmdref{csvloop} and \cmdref{listloop}
-% \item three macros that are lacking from the \sty{etoolbox} package for removing elements from lists :
+% \item a Command-List Parser constructor that uses this new feature : command-list parsers are fully expandable:
+% \cmdref{csvloop}, \cmdref{listloop}, \cmdref{toksloop} and more...
+% \item four macros that are lacking from the \sty{etoolbox} package for removing elements from lists :
% \cmdref{listdel} and \cmdref{listgdel}, \cmdref{listedel}, \cmdref{listxdel}
-% \item macros that return the index of an item in a list: \cmdref{getlistindex} and \cmdref{xgetlistindex} and conversely
+% \item get the index of an item in a list: \cmdref{getlistindex} and \cmdref{xgetlistindex} and conversely
% the item at a given position in a list: \cmdref{getlistitem}
-%
+% \item a vectorized form of \cmd{futurelet}: \cmdref{collecttoks} is a standard token scanner.
% \end{itemize}
%
% \end{shaded}
@@ -257,7 +266,8 @@ and etextools-examples.tex
% \begin{tabbing}
% \qquad\=\smex\=To get the documentation, \= run (twice):\quad\= \sty{pdflatex etextools.dtx} \\
% \>\smex\>To get the package, \> run:\> \sty{etex etextools.dtx}
-% \end{tabbing}}
+% \end{tabbing}
+% The .dtx file is embeded in this pdf thank to \sty{embedfile} by H. Oberdiek.}
%
% \vfil\eject
%
@@ -372,25 +382,35 @@ and etextools-examples.tex
%
% |\ifempty|\FE is similar to |\ifblank| but it test if a string is really empty
% (it shall not contain any character nor spaces). To test if the replacement
-% text of a macro is empty, one may use |\ifempty| in conjunction with |\expandnext|:
+% text of a macro is empty, one may use |\ifempty| in conjunction with \cmdref{expandnext}:
% \begin{tabbing}
% \quad\=|\expandnext\ifempty{\macro}| \prm{true}\prm{false}
% \end{tabbing}
%
+% |\ifempty| is based on |\detokenize| and accept anything in its argument.
%
-% \cmditem{deblank}{string} \cmdlabel{deblank} \seeimpl{deblank}
%
-% |\deblank|\FE removes all leading and trailing blank spaces from its argument.\medbreak
+% \cmditem{xifempty}{string or cs-token}{true}{false} \cmdlabel{xifempty} \seeimpl{xifempty}
%
-% \cmditem{xifblank}{string}{true}{false} \seeimpl{xifblank}
+% |\xifempty|\pdfFE is similar to |\ifempty| but the argument is expanded during comparison.
%
-% |\xifblank| is similar to |\ifblank| except that the \prm{string} is first expanded
-% with |\protected@edef|.\medbreak
+% \begin{tabbing}
+% \quad\=|\def\x{\@empty}\def\y{}| \\
+% \>|\xifempty{\x\y}| \prm{true}\prm{false}
+% \end{tabbing}
%
-% \cmditem{xifstrequal}{string1}{string2}{true}{false}\cmdlabel{xifstrequal}\seeimpl{xifstrequal}
+% {\rmk The macro is based on the \cs{pdfstrcmp} primitive.}
%
-% |\xifstrequal| is similar to |\ifstrequal| but each \prm{string} argument
-% is expanded with |\protected@edef| before comparison.\medbreak
+% \cmditem{ifnotempty}{string}{true}{false} \cmdlabel{ifnotempty}\seeimpl{ifnotempty}
+%
+% |\ifnotempty|\FE reverses the test of |\ifempty|
+%
+%
+% \cmditem{xifblank}{string}{true}{false} \seeimpl{xifblank}
+%
+% |\xifblank| is similar to |\ifblank| except that the \prm{string} is first expanded
+% with |\protected@edef|.
+% \medbreak
%
% \cmditem{iffirstchar}{string1}{string2}{true}{false} \cmdlabel{iffirstchar}\seeimpl{iffirstchar}
% \cmditem*{iffirstchar}{}{string}{true}{false}
@@ -400,6 +420,8 @@ and etextools-examples.tex
% is expanded before comparison. Example:§
% \qquad|\iffirstchar *{*hello*}{begins with a star}{begins with something else}|
%
+% Alternatively, you may use the \cmdref{ifstrmatch} test.
+%
% There is a ``special'' use of this command when one want to test if a \prm{string} begins
% with an \emph{escape} character (\,\textbackslash\,) one may say:
% \begin{tabbing}
@@ -419,6 +441,46 @@ and etextools-examples.tex
%
% |\ifsinglechar|\FE performs the test |\iffirstchar| but only if \prm{string2} has one single character.
%
+% Note that there is a small difference if you run on pdf\TeX{} or on another system:§
+% \DeleteShortVerb{\|}
+% \hfil
+% \begin{tabular}{|c|c|}\hline
+% pdf\TeX{} (use \cs{pdfstrcmp}) & Other \\ \hline
+% \cs{ifsinglechar} *\{\textvisiblespace*\} is \textbf{false} & \cs{ifsinglechar} *\{\textvisiblespace*\} is \textbf{true} \\ \hline
+% \end{tabular}\hfil
+%
+% \MakeShortVerb{\|}
+% But: \cs{ifsinglechar} *\{*\textvisiblespace\}\quad is \textbf{always false}.
+%
+%
+% \cmditem{iflastchar}{string1}{string2}{true}{false} \cmdlabel{iflastchar}\seeimpl{impl:iflastchar}
+%
+% |\iflastchar| compares the end of \prm{string2} with the totality of \prm{string1} (\prm{string1} is not
+% necessarily a single character but the macro has been designed for this purpose first, hence the name).
+%
+% |\iflastchar| is NOT purely expandable (use \cmdref{ifstrmatch} for purely expandable test).
+%
+%
+% \cmditem{ifstrcmp}{string1}{string2}{true}{false} \cmdlabel{ifstrcmp}\seeimpl{ifstrcmp}
+%
+% |\ifstrcmp|\pdfFE is the \LaTeX{} form of |\pdfstrcmp| primitive.
+%
+% Neither \prm{string1} not \prm{string2} is expanded during comparison. The comparison is
+% \textit{catcode agnostic} (use of |\detokenize |).
+%
+% \cmditem{ifstrmatch}{pattern}{string}{true}{false} \cmdlabel{ifstrmatch}\seeimpl{ifstrmatch}
+%
+% |\ifstrmatch|\pdfFE is based on the |\pdfmatch| primitive that implements POSIX-regex.
+%
+% You can test the last character of a string in a purely expandable way by:
+% \begin{tabbing}
+% \quad\=\cs{ifstrmatch}\{[\textasteriskcentered]\$\}\{\prm{string}\}
+% \end{tabbing}
+% for example to test \raise2pt\hbox{\textasteriskcentered}.
+% \end{ltxsyntax}
+%
+% \section{Fully expandable macros with options}
+% \vskip-\baselineskip
% Now with the macro |\ifsinglechar| it becomes possible to write fully expandable macros with an option, \textbf{provided
% that this macro has at least one non-optional argument}, as far as we don't use |\futurelet| nor any assignation.
% The ``trick'' is the following:
@@ -430,7 +492,6 @@ and etextools-examples.tex
% \> |\def\MacroNoOption#1|...\>\textit{definition}
% \end{tabbing}
%
-% \clearpage
% Moreover (in the style of |\@testopt|):
% \begin{tabbing}
% \qquad\= |\def\MacroWithOption#1{\ifsing|\=|lechar|\=|[{#1}|\\
@@ -438,10 +499,6 @@ and etextools-examples.tex
% \>\>|{\MacroHasOption[default]{#1}}}|
% \end{tabbing}
%
-% \end{ltxsyntax}
-%
-% \section{Fully expandable macros with options}
-%
% \begin{ltxsyntax}
%
% \cmditem{FE@testopt}{argument to be tested}{commands}{default option} \cmdlabel{FE@testopt}\seeimpl{FE@testopt}
@@ -465,8 +522,21 @@ and etextools-examples.tex
%
% Remember that |\StarredCommand| and |\NotStarredCommand| \textbf{must have at least one mandatory argument.}
%
-% % {\rmk |\FE@ifstar| is used in the definitions of \cmdref{DeclareCmdListParser}, \cmdref{csvloop}, \cmdref{listloop}
-% and \cmdref{csvtolist}.}
+% {\rmk |\FE@ifstar| is used in the definitions of \cmdref{DeclareCmdListParser}, \cmdref{csvloop}, \cmdref{listloop}
+% and \cmdref{toksloop}.}
+%
+% \cmditem{FE@ifchar}{Variant Mark Character}{argument to be tested}{special-commands}{normal-commands}\cmdlabel{FE@ifchar}\seeimpl{FE@ifchar}
+%
+% As a\FE generalisation of \cs{FE@ifstar} \sty{etextools} provides \cmd{FE@ifchar} for use with other variants than the star-form.
+%
+% For example, to define a `\,$\boldsymbol{+}$\,` variant:
+% \begin{tabbing}
+% \qquad\=|\def\SpecialMacro#1{\FE@|\=|ifchar|{+}\=|{#1}|\\
+% \>\>|{\SpecialFormMacro}|\\
+% \>\>|{\NormalFormMacro}}|
+% \end{tabbing}
+%
+% |\SpecialMacro| must have at least one mandatory argument.
%
% \end{ltxsyntax}
%
@@ -524,6 +594,8 @@ and etextools-examples.tex
% \cmditem*{csvloop*}[auxiliary commands]{item,item,item,...}
% \cmditem*{listloop}[auxiliary commands]{listmacro} \cmdlabel{listloop}
% \cmditem*{listloop*}[auxiliary commands]{expanded list}
+% \cmditem{toksloop}[auxiliary commands]{tokenslistmacro} \cmdlabel{toksloop}
+% \cmditem*{toksloop*}[auxiliary commands]{list of tokens}
%
% |\listloop|\FE acts exactly as \sty{etoolbox}-|\dolistloop| with an optional argument to change
% the default auxiliary command |\do| to apply to each item of the list :
@@ -533,6 +605,9 @@ and etextools-examples.tex
% \>\>\> |\expandafter\docsvlist\expandafter{\csvlist}|
% \end{tabbing}
%
+% The token list is a list without delimiter.
+%
+%
%
% \subsection{Converting csv lists to \sty{etoolbox}-lists}
%
@@ -548,8 +623,23 @@ and etextools-examples.tex
% \cmditem{csvtolistadd}{listmacro}{csvlistmacro} \cmdlabel{csvtolistadd}\seeimpl{csvtolistadd}
% \cmditem*{csvtolistadd*}{listmacro}{item,item,item...}
%
-% |\csvtolistadd| acts similarly but does not reset the \prm{listmacro} to |\@empty|:
+% |\csvtolistadd| acts similarly but does not reset the \prm{listmacro} to |\@empty|.
+%
+%
+% \subsection{Converting lists of tokens to \sty{etoolbox}-lists}
+%
+% \cmditem{tokstolist}{listmacro}{tokenslistmacro} \cmdlabel{tokstolist}\seeimpl{tokstolist}
+% \cmditem*{tokstolist*}{listmacro}{list of tokens}
%
+% |\tokstolist| converts a list of tokens (no separator) into an internal \sty{etoolbox} list.
+%
+% It's also the first application of the \cmdref{toksloop} macro just defined.
+%
+% \cmditem{tokstolistadd}{listmacro}{tokslistmacro} \cmdlabel{tokstolistadd}\seeimpl{tokstolistadd}
+% \cmditem*{tokstolistadd*}{listmacro}{list of tokens}
+%
+% |\tokstolistadd| acts similarly but does not reset the \prm{listmacro} to |\@empty|.
+
%
% \subsection{Removing elements from \sty{etoolbox}-lists}
%
@@ -569,32 +659,106 @@ and etextools-examples.tex
% Commands |\listgdel| and |\listxdel| are similar, except that the assignment (\ie the redefinition
% of the list) is global; for the latter, the \prm{item} is first expanded using |\protected@edef|:
%
+% \end{ltxsyntax}
%
% \subsection{Index of an element in a list}
%
+% \subsubsection{\sty{etoolbox}-lists}
+%
+% \begin{ltxsyntax}
+%
+% \cmditem{getlistindex}[myindex]{item}{listmacro} \cmdlabel{getlistindex}\seeimpl{getlistindex}
+% \cmditem*{xgetlistindex}[myindex]{item}{listmacro} \cmdlabel{xgetlistindex}
+% \cmditem*{getlistindex*}[myindex]{item}{list}
+% \cmditem*{xgetlistindex*}[myindex]{item}{list}
%
-% \cmditem{getlistindex}{item}{listmacro} \cmdlabel{getlistindex}\seeimpl{getlistindex}
-% \cmditem*{xgetlistindex}{item}{listmacro} \cmdlabel{xgetlistindex}
-% \cmditem*{getlistindex*}{item}{list}
-% \cmditem*{xgetlistindex*}{item}{list}
+% \end{ltxsyntax}
%
% Sometimes it is interesting to know at which offset in a list lies a given item. |\getlistindex| answers to this question.
-% |\xgetlistindex| does the same thing but expand the \prm{item} (using |\protected@edef|) prior looking for it in the list.
-% The result (\ie the position of \prm{item} in \prm{list}) is stored in |\indexinlist|.
+% |\xgetlistindex| does the same thing but expands the \prm{item} while looking for it in the list.
+%
+% The comparison is \textit{catcode agnostic}.
+%
+% As for the command-list-parser, the star versions are designed in case the list (in the second argument) is already expanded.
+%
+% When used\pdfFE on pdf\TeX{}, |\pdfstrcmp| does the comparison and the macros are purely expandable:
+%
% \begin{itemize}
-% \item \ If \prm{item} is not found in the \prm{list} then |\indexinlist| is 0
-% \item \ If \prm{item} is found in first position then |\indexinlit| is 1 and so on.
+% \item \ If \prm{item} is not found in the list, \cs{getlistindex} expands to 0
+% \item \ If \prm{item} is found in first position then \cs{getlistindex} expands to 1 and so on.
% \end{itemize}
%
+%
+% Those macros are purely expandable only if |\pdfstrcmp| exists.
+% Otherwise, the comparison is done with \sty{etoolbox}-|\ifstrequal| and you shall use the optional argument
+% to let the result in:
+% \begin{tabbing}
+% \qquad\=|\getlistindex[\myindex]{|\prm{item}|}{|\prm{listmacro}|}| \\
+% \end{tabbing}
+%
+% \textbf{N.B. If \cs{myindex} is not a counter it is (possibly \textit{re-})defined as macro.}
+%
+% \subsubsection{Comma-separated lists}
+%
+% \begin{ltxsyntax}
+% \cmditem{getcsvlistindex}[myindex]{item}{csvlistmacro} \cmdlabel{getcsvlistindex}\seeimpl{getcsvlistindex}
+% \cmditem*{xgetcsvlistindex}[myindex]{item}{csvlistmacro} \cmdlabel{xgetcsvlistindex}
+% \cmditem*{getcsvlistindex*}[myindex]{item}{item,item,item,...}
+% \cmditem*{xgetcsvlistindex*}[myindex]{item}{item,item,item,...}
+% \end{ltxsyntax}
+%
+% This is the same as \cmdref{getlistindex} but for comma-separated lists.
+%
% As for the command-list-parser, the star versions are designed in case the list (in the second argument) is already expanded.
%
+% Those macros\pdfFE are purely expandable only if |\pdfstrcmp| exists.
+%
+% Otherwise, use the optional argument to let the result in:
+% \begin{tabbing}
+% \qquad\=|\getcsvlistindex*[\myindex]{|\prm{item}|}{|\prm{item,item,item...}|}| \\
+% \end{tabbing}
+%
+% If \cs{myindex} is not a counter it is (possibly \textit{re-})defined as macro.
+%
+% \subsubsection{Lists of tokens}
+%
+% \begin{ltxsyntax}
+% \cmditem{gettokslistindex}[myindex]{item}{tokenslistmacro} \cmdlabel{gettokslistindex}\seeimpl{gettokslistindex}
+% \cmditem*{gettokslistindex*}[myindex]{item}{list of tokens}
+% \end{ltxsyntax}
+%
+% There\FE is no x- version for those macros. They work in a different way: the comparison if done by \cs{ifx} and
+% not \cmd{pdfstrcmp}.
+%
+% Therefore, \cs{gettokslistindex} is \textbf{always purely expandable}, but for symmetry reasons, the optional form:§
+% \begin{tabbing}
+% \qquad\=|\gettokslistindex[\myindex]{|\prm{item}|}{|\prm{tokenslistmacro}|}| \\
+% and:\> |\gettokslistindex*[\myindex]{|\prm{item}|}{|\prm{list of tokens}|}|
+% \end{tabbing}
+% are defined.
+%
+% An interesting application is the following:
+%
+% \begin{Verbatim}[gobble=1,commandchars=!\[\]]
+% !textbf[\ifcase \gettokslistindex*{R}{LORG}]
+% Not in the list: Error ?%
+% \or Here it's L%
+% \or Here it's O%
+% \or Here it's R%
+% \or Here it's G%
+% !textbf[\fi]
+% \end{Verbatim}
+%
+% Please, refer to the examples...
%
% \subsection{Extract by index from a list}
%
% \begin{ltxsyntax}
%
-% \cmditem{getlistitem}{listmacro}{index [numexpr expression]} \cmdlabel{getlistitem}\seeimpl{getlistitem}
-% \cmditem*{getlistitem*}{list}{index [numexpr expression]}
+% \subsubsection{\sty{etoolbox}-lists}
+%
+% \cmditem{getlistitem}{index [numexpr expression]}{listmacro} \cmdlabel{getlistitem}\seeimpl{getlistitem}
+% \cmditem*{getlistitem*}{index [numexpr expression]}{list}
%
% Now\FE the reverse operation of ``getting the index'' is ``getting the element'' whose index is known. Note that this macro
% is fully expandable for we don't have to compare the items (just count the loop using |\numexpr| -- no counter). Therefore we use the
@@ -604,8 +768,71 @@ and etextools-examples.tex
% \item \ If the \prm{index} is non positive or $>n$ then the macro expands to nothing (|{}|).
% \end{itemize}
%
+% \subsubsection{Comma-separated lists}
+%
+% \cmditem{getcsvlistitem}{index [numexpr expression]}{csvlistmacro} \cmdlabel{getcsvlistitem}\seeimpl{getcsvlistitem}
+% \cmditem*{getcsvlistitem*}{index [numexpr expression]}{item,item,item,...}
+%
+% This is\FE the same as \cmdref{getlistitem} but for comma-separated lists.
+%
+% \subsubsection{Lists of tokens}
+%
+% \cmditem{gettokslistitem}{index [numexpr expression]}{tokenslistmacro} \cmdlabel{gettokslistitem}\seeimpl{gettokslistitem}
+% \cmditem*{gettokslistitem*}{index [numexpr expression]}{list of tokens}
+%
+% The same\FE as \cmdref{getlistitem} for list of tokens.
% \end{ltxsyntax}
%
+% \section{Vectorized \cmd{futurelet}}
+%
+%
+% \sty{etextools} defines a vectorized version of \cs{futurelet}. The idea is to say:
+%
+% \quad|\collecttoks\macro{|\prm{list of allowed tokens}|}{|\prm{commands to execute next}|}|
+%
+% Then \cs{collecttoks} is a kind of simple scanner for tokens. It can be used to define an \textbf{\textit{undelimited macro}}
+% \ie a macro that has no delimiter but whose content of arguments is restricted.
+%
+% \begin{ltxsyntax}
+% \cmditem{collecttoks}{cs-token}{list of tokens}{commands to expand after} \cmdlabel{collecttoks}\seeimpl{collecttoks}
+% \end{ltxsyntax}
+%
+% The macro \cs{collecttoks} will read the following tokens with \cs{futurelet}. If that token is in the allowed
+% list, then it will append it to \cs{macro} (\prm{cs-token}) and continue, scanning the tokens one after another.
+%
+% Until it founds a token which is not in the list. Then it stops reading and execute the \prm{commands to expand}.
+% Those commands may use the \cs{macro} defined for analyse or whatever the user want.
+%
+% \medskip
+% As an application, it can be used to define an easy interface for |\hdashline| (the dashed lines in tabulars and arrays
+% provided by the \sty{arydshln} package): modifying \cmd{hline} in order to give sense to the following:
+% \begin{tabbing}
+% \qquad\=|\hline..|\qquad\=|\hline--|\qquad\=|\hline==|\qquad\= |\hline.-|\qquad\=|\hline.-.|\ \= etc.
+% \end{tabbing}
+%
+% After having collected the allowed tokens with:§
+% |\collecttoks\nexttokens{.-=}{|\prm{commands next}|}| \quad it is possible to
+% test the pattern given using \cs{pdfstrcmp} and, for example, the \CSbf{switch} construction of the \sty{boolexpr} package:
+%
+% \begin{Verbatim}[gobble=1,commandchars=!()]
+% !textbf(\switch[\pdfstrcmp{\nexttokens}])
+% \case{{..}}\hdashline[parameters]%
+% \case{{--}}\hdashline[parameters]%
+% \case{{==}}\hdashline[parameters]%
+% \case{[.-.}}\hdashline[parameters]%
+% \otherwise \original@hline%
+% !textbf(\endswitch)
+% \end{Verbatim}
+%
+% \CSbf{switch} is purely expandable.
+%
+% If you replace \cs{pdfstrcmp} by |\ifstrequal|, \cs{switch} works but is not purely expandable.
+%
+% See \sty{boolexpr} (\CTAN{macros/latex/contrib/boolexpr/}) for more information on \cs{switch}.
+%
+%
+%
+%
% \StopEventually{
% }
%
@@ -620,7 +847,7 @@ and etextools-examples.tex
%<*package>
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
\ProvidesPackage{etextools}
- [2009/07/14 v2e e-TeX more useful tools for LaTeX package writers]
+ [2009/08/14 v2h e-TeX more useful tools for LaTeX package writers]
\csname ettl@onlyonce\endcsname\let\ettl@onlyonce\endinput
% \end{macrocode}
%
@@ -636,10 +863,22 @@ and etextools-examples.tex
% Furthermore, the space token must have its natural catcode (10) all along this package.
%
% \begin{macrocode}
-\edef\ettl@restore@space@catcode{\catcode`\ =\the\catcode`\ }
-\AtEndOfPackage{\ettl@restore@space@catcode
- \let\ettl@restore@space@catcode\ettl@undefined}
-\catcode`\ =10
+\let\ettl@AtEnd\@empty
+\def\TMP@EnsureCode#1#2{%
+ \edef\ettl@AtEnd{%
+ \ettl@AtEnd
+ \catcode#1 \the\catcode#1\relax
+ }%
+ \catcode#1 #2\relax
+}
+\TMP@EnsureCode{32}{10}% space
+\ifundef\pdfstrcmp{%
+ \TMP@EnsureCode{33}{9}% ! ignore
+ \TMP@EnsureCode{34}{14}% " comment
+}{\TMP@EnsureCode{33}{14}% ! comment
+ \TMP@EnsureCode{34}{9}% " ignore
+}
+\AtEndOfPackage{\ettl@AtEnd\undef\ettl@AtEnd}
% \end{macrocode}
%
% \subsection{A few (7) ``helper'' macros}
@@ -653,21 +892,21 @@ and etextools-examples.tex
\long\def\ettl@afterfi#1\fi{\fi#1}
\long\def\ettl@afterfifi#1\fi\fi{\fi\fi#1}
\long\def\ettl@afterelsefi#1\else#2\fi\fi{\fi#1}
+\long\def\ettl@afterorfi#1\or#2\fi{\fi#1}
% \end{macrocode}
%
-% \begin{macro}{\ettl@cdr}
-% {\rmk \cmd{ettl@cdr} is only used in \cmdref{ifsinglechar}}
-% \begin{macrocode}
-\begingroup\catcode`\|=4
-\long\gdef\ettl@cdr#1#2|{#2}
-\endgroup
-% \end{macrocode}
-% \end{macro}
-%
% \iffalse
%<package>
% \fi
%
+% \begin{macro}{\ettl@ifstrcmp}
+% Use of the pdf\TeX{} primitive \cs{pdfstrcmp} and design a \LaTeX{} form.
+% \begin{macrocode}
+\def\ettl@ifstrcmp#1#2{\csname @%
+ \ifnum\pdfstrcmp{#1}{#2}=0 first\else second\fi oftwo\endcsname}
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\@gobblescape}
%
% This sequence of command is very often used, even in \sty{latex.ltx}. So
@@ -680,20 +919,13 @@ and etextools-examples.tex
% \end{macro}
%
%
-% \begin{macro}{\str@gobblescape}
-%
-% With \eTeX{} |\detokenize| it is now possible to invoke a |\string| on an arbitrary
-% sequence of tokens. Unfortunately, |\detokenize| adds a
-% space tokens at the very end of the sequence. |\str@gobblescape| acts exactly
-% the same way as |\@gobblescape| \ie it removes the first character from a string, but removes
-% the trailing spaces as well:
-%
% \begin{macrocode}
-\newcommand\str@gobblescape[1]{\expandafter\deblank\expandafter{%
- \expandafter\@gobble\detokenize{#1}}}
+\def\ettl@onlypdfTeX#1#2{\ifundef{#1}
+ {\def#2{\PackageError{etextools}{\string#1\space primitive not found\MessageBreak
+ pdfTeX seems not to be running}
+ {\string#2\space works only if used with pdfTeX (requires \string#1)}}}
+ {}}
% \end{macrocode}
-% \end{macro}
-%
%
% \subsection{Expansion control}
%
@@ -748,39 +980,67 @@ and etextools-examples.tex
% \fi
%
%
-% \subsection{String manipulation}
+% \subsection{Character and Strings}
%
-% \begin{macro}{\deblank} \cmdlabel{impl:deblank}
+% \iffalse
+%<package>
+%<package>% \ifempty{ text }{ true }{ false }
+% \fi
%
-% Note that the leading spaces \seedesc{deblank}are automatically removed by \TeX's mastication mechanism.
+% \begin{macro}{\ifempty} \cmdlabel{impl:ifempty}
+% |\ifempty| is based on |\detokenize| and can manage with any argument.\seedesc{ifempty}
+% \begin{macrocode}
+\newcommand\ifempty[1]{\csname @\expandafter\ifx
+ \expandafter\relax\detokenize{#1}\relax
+ first\else second\fi oftwo\endcsname}
+% \end{macrocode}
+% \end{macro}
+%
+% \iffalse
+%<package>
+%<package>% \ifnotempty{ text }{ true }{ false }
+% \fi
%
+% \begin{macro}{\ifnotempty} \cmdlabel{impl:ifnotempty}
+% |\ifnotempty| is based on |\detokenize| and can manage with any argument.\seedesc{ifnotempty}
% \begin{macrocode}
-\newcommand\deblank{}
-\newcommand\ifempty{}
-\begingroup\catcode`\|=4% a | as a tab array
-\long\gdef\deblank#1{\@deblank#1 |}
-\long\gdef\@deblank#1 #2|{\ifblank{#2}{#1}{#1\@deblank#2 |}}
+\newcommand\ifnotempty[1]{\csname @\expandafter\ifx
+ \expandafter\relax\detokenize{#1}\relax
+ second\else first\fi oftwo\endcsname}
% \end{macrocode}
% \end{macro}
%
% \iffalse
%<package>
-%<package>% \ifempty{ text }{ true }{ false }
+%<package>% \xifempty{ text }{ true }{ false }
% \fi
-% \begin{macro}{\ifempty} \cmdlabel{impl:ifempty}
-% |\ifempty| is amazing because the code is so concise!\seedesc{ifempty}
+% \begin{macro}{\xifempty} \cmdlabel{impl:xifempty}
+% |\xifempty| is based on pdf-TeX{} |\pdfstrcmp| and work with any argument.\seedesc{xifempty}
% \begin{macrocode}
-\long\gdef\ifempty#1{\csname @\ifx|#1|first\else second\fi oftwo\endcsname}
-\endgroup% catcode group
+\newcommand\xifempty[1]{\xifstrcmp{#1}{}}
+\ettl@onlypdfTeX\pdfstrcmp\xifempty
% \end{macrocode}
% \end{macro}
+%
% \iffalse
%<package>
+%<package>% \ifnotblank{ text }{ true }{ false }
% \fi
%
-% \goodbreak
+% \begin{macro}{\ifnotblank} \cmdlabel{impl:ifnotblank}
+% |\ifnotblank| reverses the test of |\ifblank|.\seedesc{ifnotblank}
+% \begin{macrocode}
+\begingroup\catcode`\&=3\catcode`\:=12
+\ifcsundef{ifnotblank}{%
+\long\gdef\ifnotblank#1{\etb@ifblank@i#1&&\@firstoftwo\@secondoftwo:}}
+\relax\endgroup
+% \end{macrocode}
+% \end{macro}
%
-% \subsection{Expanded string comparison}
+% \iffalse
+%<package>
+%<package>% \xifblank{ string }{ true }{ false }
+% \fi
%
% \begin{macro}{\xifblank}\cmdlabel{impl:xifblank}
% Just expands the parameter using |\protected@edef| before testing for |\ifblank|: \seedesc{xifblank}
@@ -792,61 +1052,135 @@ and etextools-examples.tex
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\xifstrequal}\cmdlabel{impl:xifstrequal}
-% Same idea: protected expansion before testing: \seedesc{xifstrequal}
-% \begin{macrocode}
-\newrobustcmd\xifstrequal[2]{%
- \begingroup\protected@edef\@tempa{#1}\protected@edef\@tempb{#2}%
- \ifx\@tempa\@tempb \aftergroup\@firstoftwo
- \else \aftergroup\@secondoftwo
- \fi\endgroup}
-% \end{macrocode}
-% \end{macro}
+%
+% \iffalse
+%<package>
+%<package>% \iffirstchar{ string1 }{ string2 }{ true }{ false }
+% \fi
%
% \begin{macro}{\iffirstchar}\cmdlabel{impl:iffirstchar}
% |\iffirstchar| test if |#1| and |#2| begins with the same character. \seedesc{iffirstchar}
% \begin{macrocode}
-\newcommand\iffirstchar[2]{%
- \if \expandafter\@car\string#2\relax\@nil\expandafter\@car#1\string\\\@nil
- \ettl@afterelse\ifblank{#2}\@secondoftwo\@firstoftwo
- \else \expandafter\@secondoftwo
- \fi}
+\newcommand\iffirstchar[2]{\csname @%
+ \if \expandafter\@car\detokenize{#2}\relax\@nil\expandafter\@car\detokenize{#1}\string\\\@nil
+ \ifblank{#2}{second}{first}%
+ \else second%
+ \fi oftwo\endcsname}
% \end{macrocode}
% \end{macro}
%
+% \iffalse
+%<package>
+%<package>% \ifsinglechar character{ string }{ true }{ false }
+% \fi
+%
% \begin{macro}{\ifsinglechar}\cmdlabel{impl:ifsinglechar}
% Test if |#2| is a single character equal to |#1|: \seedesc{ifsinglechar}
% \begin{macrocode}
-\newcommand\ifsinglechar{}
-\begingroup\catcode`\|=4
-\long\gdef\ifsinglechar#1#2{%
+\newcommand\ifsinglechar[2]{%
% \end{macrocode}
%
% \begin{codecomment}
% Remember that neither \prm{string1} nor \prm{string2} is expanded.§
% First: test if |#2| is a single character:
% \begin{macrocode}
- \csname @\expandafter\expandafter\expandafter\ifx
- \expandafter\expandafter\expandafter|%
- \expandafter\ettl@cdr\string#2||first\else second\fi
- oftwo\endcsname
+ \csname @\ifblank{#2}{second}{%
+" \ifnum\pdfstrcmp{\detokenize{#1}}{\detokenize{#2}}=0
+" \ifnum\pdfstrcmp{\detokenize{#2}}{\expandafter\@car\detokenize{#2}\relax\@nil}=0
+" first%
+" \else second%
+" \fi
+" \else second%
+" \fi oftwo\endcsname}}
+! \expandafter\expandafter\expandafter\ifx
+! \expandafter\expandafter\expandafter\relax\expandafter\@cdr\detokenize{#2}\@nil\relax
+! \iffirstchar{#1}{#2}{first}{second}\else second\fi oftwo\endcsname}}
% \end{macrocode}
-% The test returned \prm{true}: therefore test further the character codes of |#2| and |#1|, and
-% switch to \prm{true} only in case of equality:
+% \end{codecomment}
+% \end{macro}
+%
+% \iffalse
+%<package>
+%<package>% \iflastchar{ string1 }{ string2 }{ true }{ false }
+% \fi
+%
+% \begin{macro}{\iflastchar} \cmdlabel{impl:iflastchar}
+% This macro is not purely expandable. \seedesc{iflastchar}
% \begin{macrocode}
- {\iffirstchar{#1}{#2}}
+\begingroup\catcode`\&=3
+\long\gdef\iflastchar#1#2{%
+ \long\def\ettl@iflastchar##1#1##2&{%
+ \ifstrcmp{##2}{#1}\@firstoftwo{%
+ \ifempty{##2}\@secondoftwo{\ettl@iflastchar##2&}}
+ }\ettl@iflastchar#2#1&}
+\endgroup
% \end{macrocode}
-% Otherwise, switch to \prm{false}
+% \end{macro}
+%
+%
+% \iffalse
+%<package>
+%<package>% \ifstrcmp{ string1 }{ string2 }{ true }{ false }
+% \fi
+%
+% \begin{macro}{\ifstrcmp}\cmdlabel{impl:ifstrcmp}
+% The macro is base on the |\pdfstrcmp| primitive.\seedesc{ifstrcmp}
% \begin{macrocode}
- \@secondoftwo}
-\endgroup% catcode group
+\newcommand\ifstrcmp[2]{\csname @%
+ \ifnum\pdfstrcmp{\detokenize{#1}}{\detokenize{#2}}=0 first\else second\fi
+ oftwo\endcsname}
+\ettl@onlypdfTeX\pdfstrcmp\ifstrcmp
+% \end{macrocode}
+% \end{macro}
+%
+% \iffalse
+%<package>
+%<package>% \xifstrcmp{ string1 }{ string2 }{ true }{ false }
+% \fi
+%
+% \begin{macro}{\xifstrcmp}\cmdlabel{impl:xifstrcmp}
+% The macro is based on the |\pdfstrcmp| primitive.\seedesc{ifxstrcmp}
+% \begin{macrocode}
+\newcommand\xifstrcmp[2]{\csname @%
+ \ifnum\pdfstrcmp{#1}{#2}=0 first\else second\fi
+ oftwo\endcsname}
+\ettl@onlypdfTeX\pdfstrcmp\ifxstrcmp
% \end{macrocode}
-% \end{codecomment}
% \end{macro}
%
+% \begin{macro}{\xifstrequal}\cmdlabel{impl:xifstrequal}
+% The macro is based on \sty{etoolbox}-|\ifstrequal|.\seedesc{ifxstrequal}
+% \begin{macrocode}
+\newrobustcmd*\xifstrequal[2]{\begingroup
+ \protected@edef\@xifstrequal{\endgroup\noexpand\ifstrequal{#1}{#2}%
+ }\@xifstrequal}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
% \iffalse
%<package>
-%<package>%\FE@testopt{#1}{commands}{default option}
+%<package>% \ifstrmatch{ pattern }{ true }{ false }
+% \fi
+%
+% \begin{macro}{\ifstrmatch}\cmdlabel{impl:ifstrmatch}
+% The macro is base on the |\pdfmatch| primitive.\seedesc{ifstrmatch}
+% \begin{macrocode}
+\newcommand\ifstrmatch[2]{\csname @%
+ \ifnum\pdfmatch{\detokenize{#1}}{\detokenize{#2}}=1 first\else second\fi
+ oftwo\endcsname}
+\ettl@onlypdfTeX\pdfmatch\ifstrmatch
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Purely expandable macros with options}
+%
+% \iffalse
+%<package>%----------------------------------------------------------------------------
+%<package>% Purely Expandable Macros With Options / Star Forms / Variants
+%<package>% \FE@testopt{ #1 }{ commands }{ default option }
% \fi
% \begin{macro}{\FE@testopt}\cmdlabel{impl:FE@testopt}
% Fully expandable |\@testopt|-like test:\seedesc{FE@testopt}
@@ -858,7 +1192,7 @@ and etextools-examples.tex
%
% \iffalse
%<package>
-%<package>%\FE@ifstar{#1}{\StarredMacro}{\NotStarredMacro}
+%<package>% \FE@ifstar{ #1 } { \StarredMacro }{ \NotStarredMacro }
% \fi
% \begin{macro}{\FE@ifstar}\cmdlabel{impl:FE@ifstar}
% Fully expandable |\@ifstar|-like test:\seedesc{FE@ifstar}
@@ -867,6 +1201,19 @@ and etextools-examples.tex
% \end{macrocode}
%
% \end{macro}
+%
+% \iffalse
+%<package>
+%<package>% \FE@ifchar{#1}{#2}{ \SpecialFormMacro }{ \NormalMacro }
+% \fi
+% \begin{macro}{\FE@ifchar}\cmdlabel{impl:FE@ifchar}
+% Plus généralement, on peut tester si une macro est suivie d'un caractère donné:\seedesc{FE@ifchar}
+% \begin{macrocode}
+\newcommand\FE@ifchar[4]{\ifsinglechar{#1}{#2}{#3}{#4{#2}}}
+% \end{macrocode}
+% \end{macro}
+%
+%
% \iffalse
%<package>
% \fi
@@ -910,27 +1257,23 @@ and etextools-examples.tex
% This is possible because the list-parser has always a mandatory argument (the \prm{list} itself or the \prm{listmacro}) :
% \begin{macrocode}
\long\def#1####1{\noexpand\FE@ifstar{####1}
- {\`ettl@lst@star\string#1`}
- {\`ettl@lst@nost\string#1`}}%
+ {\`ettl@lst@opt\string#1`{}}
+ {\`ettl@lst@opt\string#1`\noexpandafter}}%
% \end{macrocode}
% Both starred and not-starred versions have an optional argument which is the auxiliary command, whose name is |\do| if not specified.
% It is possible to test the option for the same reason:
% \begin{macrocode}
- \long\csdef{ettl@lst@star\string#1}####1{\noexpand\FE@testopt{####1}
- {\`ettl@lst@star@pt\string#1`}{\noexpand\do}}%
- \long\csdef{ettl@lst@nost\string#1}####1{\noexpand\FE@testopt{####1}
- {\`ettl@lst@nost@pt\string#1`}{\noexpand\do}}%
+ \long\csdef{ettl@lst@opt\string#1}####1####2{\noexpand\FE@testopt{####2}
+ {\`ettl@lst@@pt\string#1`{####1}}{\noexpand\do}}%
% \end{macrocode}
% Definition of the parser with its arguments :\quad |[optional command]{list or listmacro}|. If the starred version
% was used, then we do not have to expand the (mandatory) \prm{list}:
% \begin{macrocode}
- \long\csdef{ettl@lst@star@pt\string#1}[####1]####2{%
- \`ettl@lst\string#1`{####2}{####1}}%
+ \long\csdef{ettl@lst@@pt\string#1}####1[####2]####3{%
+ ####1\`ettl@lst\string#1`####1{####3}{####2}}%
% \end{macrocode}
% On the other hand, if the parser was not starred, the (mandatory) \prm{listmacro} is expanded once:
% \begin{macrocode}
- \long\csdef{ettl@lst@nost@pt\string#1}[####1]####2{%
- \noexpandafter\`ettl@lst\string#1`\noexpandafter{####2}{####1}}%
% \end{macrocode}
% ListParser is defined and leads to |\`ettl@lst\string\ListParser`| in all cases; here the \prm{list} is in first position,
% the auxiliary commands come after, so we reverse the order and add a \prm{separator} in case the \prm{list} is empty:
@@ -993,38 +1336,71 @@ and etextools-examples.tex
% \end{macrocode}
% \end{codecomment}
%
+% \begin{codecomment}
+% Definition of |\toksloop| (with no delimiter):
+% \begin{macrocode}
+\DeclareCmdListParser\toksloop{}%
+% \end{macrocode}
+% \end{codecomment}
%
% \iffalse
%<package>
-%<package>%\csvtolist\csvListMacro
-%<package>%\csvtolist*{item,item,item}
+%<package>% \csvtolist \ListMacro \csvListMacro
+%<package>% \csvtolist* \ListMacro {item,item,item}
% \fi
% \begin{macro}{\csvtolist}\cmdlabel{impl:csvtolist}
% This is the first application of |\csvloop|:\seedesc{csvtolist}
% \begin{macrocode}
-\newcommand\csvtolist{\@ifstar\star@csvtolist\nost@csvtolist}%
-\def\star@csvtolist#1{\let#1\@empty\csvloop*[{\unexpanded{\listadd#1}}]}%
-\def\nost@csvtolist#1{\let#1\@empty\csvloop[{\unexpanded{\listadd#1}}]}%
+\newrobustcmd*\csvtolist{\@ifstar
+ {\ettl@tolist\z@{}\csvloop}
+ {\ettl@tolist\z@\expandnext\csvloop}}%
+\long\def\ettl@tolist#1#2#3#4#5{\ifx#1\z@\let#4\@empty\fi
+ \def\ettl@to@list{#3*[{\unexpanded{\listadd#4}}]%
+ }#2\ettl@to@list{#5}}
% \end{macrocode}
% \end{macro}
%
% \iffalse
%<package>
-%<package>%\csvtolistadd\csvListMacro
-%<package>%\csvtolistadd*{item,item,item}
+% \fi
+%
+% \begin{macro}{\tokstolist}\cmdlabel{impl:tokstolist}
+% This is the first application of |\toksloop|:\seedesc{tokstolist}
+% \begin{macrocode}
+\newrobustcmd*\tokstolist{\@ifstar{\ettl@tokstolist\z@{}}{\ettl@tokstolist\z@\expandnext}}
+\def\ettl@tokstolist#1#2#3#4{\ifx#1\z@\let#3\@empty\fi
+ \def\ettl@toks@tolist{\toksloop*[{\unexpanded{\listadd#3}}]}%
+ #2\ettl@toks@tolist{#4{}}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \iffalse
+%<package>
+%<package>% \csvtolistadd \ListMacro \csvListMacro
+%<package>% \csvtolistadd* \ListMacro {item,item,item}
% \fi
% \begin{macro}{\csvtolistadd}\cmdlabel{impl:csvtolistadd}
% It's quite the same\seedesc{csvtolistadd} as the latter except it does not
% reset the list to empty at the very beginning:
% \begin{macrocode}
-\newcommand\csvtolistadd{\@ifstar\star@csvtolistadd\nost@csvtolistadd}%
-\def\star@csvtolistadd#1#2{\ifblank{#2}
- {\let#1\@empty}{\csvloop*[{\unexpanded{\listadd#1}}]{#2}}}%
-\def\nost@csvtolistadd#1#2{\ifblank{#2}
- {\let#1\@empty}{\csvloop[{\unexpanded{\listadd#1}}]{#2}}}%
+\newrobustcmd*\csvtolistadd{\@ifstar
+ {\ettl@tolist\@ne{}\csvloop}
+ {\ettl@tolist\@ne\expandnext\csvloop}}
% \end{macrocode}
% \end{macro}
%
+% \iffalse
+%<package>
+% \fi
+%
+% \begin{macro}{\tokstolistadd}\cmdlabel{impl:tokstolistadd}
+% It's quite the same\seedesc{tokstolistadd} as the latter except it does not
+% reset the list to empty at the very beginning:
+% \begin{macrocode}
+\newrobustcmd*\tokstolistadd{\@ifstar{\ettl@tokstolist\@ne{}}{\ettl@tokstolist\@ne\expandnext}}%
+% \end{macrocode}
+% \end{macro}
%
% \iffalse
%<package>
@@ -1068,7 +1444,7 @@ and etextools-examples.tex
% In order to preserve the hash-table from temporary definitions, a group is opened:
% \begin{macrocode}
\begingroup
- \def\@tempa##1|#3|##2&{##1|##2\@tempb}%
+ \long\def\@tempa##1|#3|##2&{##1|##2\@tempb}%
% \end{macrocode}
%
% |\@tempa| is a delimited macro whose aim is to remove the first \prm{item} found in the list
@@ -1079,7 +1455,7 @@ and etextools-examples.tex
% The result of |\@tempa| expansion is then given to |\@tempb| whose purpose is to cancel out
% whatever is found between the two delimiters: \textbar|\@tempb|...\textbar|\@tempb|:
% \begin{macrocode}
- \def\@tempb|##1|\@tempb##2|\@tempb{%
+ \long\def\@tempb|##1|\@tempb##2|\@tempb{%
\ifblank{##2}{\unexpanded{##1}}
% \end{macrocode}
% If the \prm{item} \textbf{was not} is the list, then |##2| will be empty, and§
@@ -1096,7 +1472,7 @@ and etextools-examples.tex
% the expansion of |\@tempa|. The macro |\@tempx| itself has an argument: it is (at first stage) the
% replacement text of \prm{listmacro}:
% \begin{macrocode}
- \def\@tempx##1&{\expandafter\@tempb\@tempa|##1|\@tempb|#3|&}%
+ \long\def\@tempx##1&{\expandafter\@tempb\@tempa|##1|\@tempb|#3|&}%
\edef\@redef{\endgroup
\unexpanded{#1#2}{% ie: \def or \gdef \listmacro
% \end{macrocode}
@@ -1118,7 +1494,8 @@ and etextools-examples.tex
%\iffalse
%<package>
%<package>
-%<package>% \getlistindex (result in \indexinlist)
+%<package>% \getlistindex[\indexmacro]{ \listmacro }
+%<package>% \getlistindex*[\indexmacro]{ expanded list }
% \fi
%
%
@@ -1129,63 +1506,264 @@ and etextools-examples.tex
%
% We first need to get into a group where delimiter `\,\textbar\,' and `\,\&\,' have catcode 3:
% \begin{macrocode}
+\newcommand\getlistindex[1]{\FE@ifstar{#1}
+ {\ettl@getlistindex{}\unexpanded}
+ {\ettl@getlistindex\expandnext\unexpanded}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xgetlistindex}\cmdlabel{impl:xgetlistindex}
+% |\xgetlistindex| is similar but the \prm{item} is expanded during string comparison (inside |\pdfstrcmp| is pdf\TeX{},
+% or before the test if this primitive is not found).
+% \begin{macrocode}
+\newcommand\xgetlistindex[1]{\FE@ifstar{#1}
+ {\ettl@getlistindex{}\@firstofone}
+ {\ettl@getlistindex\expandnext\@firstofone}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% Then the following macro does the job in a loop, which is fully expandable when we can use |\pdfstrcmp|:
+%
+% \begin{macrocode}
\begingroup\catcode`\|=3\catcode`\&=3
-\gdef\getlistindex#1{\FE@ifstar{#1}{\ettl@getlistindex{}}
- {\ettl@getlistindex\expandnext}}
-% \@ifstar{\ettl@getlistindex{}}{\ettl@getlistindex{\expandnext}}}
+\long\gdef\ettl@getlistindex#1#2#3{\FE@testopt{#3}{\ettl@get@listindex{#1}{#2}}{}}
+\long\gdef\ettl@get@listindex#1#2[#3]#4#5{#1\ettl@get@list@idx{#5}{#4}{\numexpr1}{#2}[{#3}]}
+\long\gdef\ettl@get@list@idx#1#2#3#4[#5]{% #1=expanded list, #2=item, #3=index, #4=\unexpanded (event., #5=indexmacro)
+ \ifblank{#1}0% the (remainder of) the list is empty
+" {\xifstrcmp{\expandonce{\ettl@list@first@item#1&}}{#4{#2}}}
+! {\ettl@listitem@cmp{\ettl@list@first@item#1&}{#2}{#4}}
+ {\ifblank{#5}{\number#3\relax}{\ettl@ifiscount{#5}{#5=\number#3\relax}{\edef#5{\number#3}}}}
+ {\expandnext\ettl@get@list@idx{\ettl@list@other@item#1&}{#2}{#3+1}{#4}[{#5}]}}
+% \end{macrocode}
+%
+% \begin{codecomment}
+%
+% The next two macros expand to the first item in a list or the remainder of the list respectively:
+%
+% \begin{macrocode}
+\long\gdef\ettl@list@first@item#1|#2&{#1}
+\long\gdef\ettl@list@other@item#1|#2&{#2}
+!\long\gdef\ettl@listitem@cmp#1#2#3{%
+! \ifx#3\unexpanded\def\ettl@listitem@cmp@{#2}%
+! \else\protected@edef\ettl@listitem@cmp@{#2}%
+! \fi
+! \expandafter\ifstrequal\expandafter{#1}{#2}}
+\edef\ettl@ifiscount{%
+ \gdef\noexpand\ettl@ifiscount##1{%
+ \noexpand\expandafter\noexpand\ettl@ifiscount@i
+ \noexpand\meaning##1\string\count\noexpand\@nil}%
+}\ettl@ifiscount
+\edef\ettl@ifiscount@i{%
+ \gdef\noexpand\ettl@ifiscount@i##1\string\count##2\noexpand\@nil{%
+ \noexpand\ifempty{##1}}%
+}\ettl@ifiscount@i
+% \end{macrocode}
+%
+% \end{codecomment}
+%
+% \iffalse
+%<package>
+%<package>%\getcsvlistindex{ item }{ csvlistmacro }
+%<package>%\getcsvlistindex*{ item }{ item,item,item }
+% \fi
+% \begin{macro}{\getcsvlistindex} \cmdlabel{impl:getcsvlistindex}
+% \strut\seedesc{getcsvlistindex}
+% \begin{macrocode}
+\long\gdef\getcsvlistindex#1{\FE@ifstar{#1}
+ {\ettl@getcsvlistindex{}\unexpanded}
+ {\ettl@getcsvlistindex\expandnext\unexpanded}}
% \end{macrocode}
% \end{macro}
%
-% |\xgetlistindex| is similar with prior expansion of \prm{item}:
+% |\xgetcsvlistindex| is similar but the \prm{item} is expanded during string comparison (inside |\pdfstrcmp| is pdf\TeX{},
+% or before the test if this primitive is not found).
+%
% \begin{macrocode}
-\gdef\xgetlistindex#1{\FE@ifstar{#1}{\ettl@xgetlistindex{}}
- {\ettl@xgetlistindex\expandnext}}
-\gdef\ettl@xgetlistindex#1#2#3{\begingroup
- \protected@edef\next{\endgroup\unexpanded{\ettl@getlistindex{#1}{#2}}{#3}%
- }\next}
+\long\gdef\xgetcsvlistindex#1{\FE@ifstar{#1}
+ {\ettl@getcsvlistindex{}\@firstofone}
+ {\ettl@getcsvlistindex\expandnext\@firstofone}}
% \end{macrocode}
%
-% Then the following macro does the job in a loop, which is not fully expandable because the use of |\ifstrequal|:
+% Then the following macro does the job in a loop, which is fully expandable when we can use |\pdfstrcmp|:
%
% \begin{macrocode}
-\gdef\ettl@getlistindex#1#2#3{\begingroup#1\ettl@get@list@idx{#3}{#2}{\numexpr1}}
-\gdef\ettl@get@list@idx#1#2#3{% #1=expanded list, #2=item, #3=index
+\long\gdef\ettl@getcsvlistindex#1#2#3{\FE@testopt{#3}{\ettl@get@csvlistindex{#1}{#2}}{}}
+\long\gdef\ettl@get@csvlistindex#1#2[#3]#4#5{#1\ettl@get@csvlist@idx{#5}{#4}{\numexpr1}{#2}[{#3}]}
+\long\gdef\ettl@get@csvlist@idx#1#2#3#4[#5]{% #1=expanded list, #2=item, #3=index, #4=\unexpanded (event., #5=indexmacro)
\ifblank{#1}0% the (remainder of) the list is empty
- {\expandnext\ifstrequal{\ettl@list@first@item#1&}{#2}
- {\endgroup\edef\indexinlist{\number#3\relax}}
- {\expandnext\ettl@get@list@idx{\ettl@list@other@item#1&}{#2}{#3+1}}}}
+" {\xifstrcmp{\expandonce{\ettl@csvlist@first@item#1&}}{#4{#2}}}
+! {\ettl@listitem@cmp{\ettl@csvlist@first@item#1&}{#2}{#4}}
+ {\ifblank{#5}{\number#3\relax}{\ettl@ifiscount{#5}{#5=\number#3\relax}{\edef#5{\number#3}}}}
+ {\expandnext\ettl@get@csvlist@idx{\ettl@csvlist@other@item#1&}{#2}{#3+1}{#4}[{#5}]}}
% \end{macrocode}
%
% \begin{codecomment}
-% The next two macros expand to the first item in a list or the remainder of the list respectively :
+% The next two macros expand to the first item in a list or the remainder of the list respectively:
% \begin{macrocode}
-\gdef\ettl@list@first@item#1|#2&{#1}
-\gdef\ettl@list@other@item#1|#2&{#2}
+\long\gdef\ettl@csvlist@first@item#1,#2&{#1}
+\long\gdef\ettl@csvlist@other@item#1,#2&{#2}
+% \end{macrocode}
+% \end{codecomment}
+%
+%
+% \iffalse
+%<package>
+%<package>%\gettokslistindex{ item }{ tokenslistmacro }
+%<package>%\gettokslistindex*{ item }{ list of tokens }
+% \fi
+% \begin{macro}{\gettokslistindex}\cmdlabel{impl:gettokslistindex}
+% \strut\seedesc{gettokslistindex}
+% \begin{macrocode}
+\long\gdef\gettokslistindex#1{\FE@ifstar{#1}
+ {\ettl@gettokslistindex{}}
+ {\ettl@gettokslistindex\expandnext}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\long\gdef\ettl@gettokslistindex#1#2{\FE@testopt{#2}{\ettl@get@tokslistindex{#1}}{}}
+\long\gdef\ettl@get@tokslistindex#1[#2]#3#4{#1\ettl@get@tokslist@idx{#4}{#3}{\numexpr1}[{#2}]}
+\long\gdef\ettl@get@tokslist@idx#1#2#3[#4]{% #1=expanded list, #2=item, #3=index
+ \ifblank{#1}0% the (remainder of) the list is empty
+ {\expandafter\ifx\expandafter#2\ettl@tokslist@first@item#1&%
+ \ettl@afterelse\ifblank{#4}{\number#3\relax}
+ {\ettl@ifiscount{#4}{#4=\number#3\relax}{\edef#4{\number#3}}}%
+ \else \ettl@afterfi
+ \expandnext\ettl@get@tokslist@idx{\ettl@tokslist@other@item#1&}{#2}{#3+1}[{#4}]%
+ \fi}}
+% \end{macrocode}
+%
+% \begin{codecomment}
+% The next two macros expand to the first item in a list or the remainder of the list respectively:
+% \begin{macrocode}
+\long\gdef\ettl@tokslist@first@item#1#2&{#1}
+\long\gdef\ettl@tokslist@other@item#1#2&{#2}
\endgroup% catcode group
% \end{macrocode}
% \end{codecomment}
%
%
+%
+% \iffalse
+%<package>
+%<package>
+%<package>%\getlistitem{ number }{ listmacro }
+%<package>%\getlistitem*{ number }{ listmacro }
+% \fi
% \begin{macro}{\getlistitem}\cmdlabel{impl:getlistitem}
% \strut\seedesc{getlistitem}
% \begin{macrocode}
-\newcommand\getlistitem[1]{\FE@ifstar{#1}\ettl@getlistitem
- {\expandnext\ettl@getlistitem}}
+\newcommand\getlistitem[1]{\FE@ifstar{#1}{\ettl@getlistitem{}}
+ {\ettl@getlistitem\expandnext}}
\begingroup\catcode`\&=3
-\long\gdef\ettl@getlistitem#1#2{%#1=listmacro, #2=index
- \ettl@get@list@item{#1}{\number\numexpr#2}}
+\long\gdef\ettl@getlistitem#1#2#3{%#2=index, #3=list or list-macro
+ #1\ettl@get@list@item{#3}{\numexpr#2}}
\long\gdef\ettl@get@list@item#1#2{%
\ifblank{#1}{}
{\ifnum#2=1 \ettl@afterelsefi
- \expandonce{\ettl@list@first@item#1&}
+ \expandonce{\ettl@list@first@item#1&}%
\else\ifnum#2>0 \ettl@afterfifi
- \expandnext\ettl@getlistitem{\ettl@list@other@item#1&}{#2-1}%
+ \expandnext\ettl@get@list@item{\ettl@list@other@item#1&}{#2-1}%
\fi\fi}}
\endgroup
% \end{macrocode}
% \end{macro}
%
-% \end{ltxsyntax}
+% \iffalse
+%<package>
+%<package>
+%<package>% \getcsvlistitem{ number }{ csvlistmacro }
+%<package>% \getcsvlistitem*{ number }{ item,item,item,... }
+% \fi
+% \begin{macro}{\getcsvlistitem}\cmdlabel{impl:getcsvlistitem}
+% \strut\seedesc{getcsvlistitem}
+% \begin{macrocode}
+\newcommand\getcsvlistitem[1]{\FE@ifstar{#1}{\ettl@getcsvlistitem{}}
+ {\ettl@getcsvlistitem\expandnext}}
+\begingroup\catcode`\&=3
+\long\gdef\ettl@getcsvlistitem#1#2#3{%#2=index, #3=list or list-macro
+ #1\ettl@get@csvlist@item{#3,}{\numexpr#2}}
+\long\gdef\ettl@get@csvlist@item#1#2{%
+ \ifblank{#1}{}
+ {\ifnum#2=1 \ettl@afterelsefi
+ \expandonce{\ettl@csvlist@first@item#1&}%
+ \else\ifnum#2>0 \ettl@afterfifi
+ \expandnext\ettl@get@csvlist@item{\ettl@csvlist@other@item#1&}{#2-1}%
+ \fi\fi}}
+\endgroup
+% \end{macrocode}
+% \end{macro}
+%
+% \iffalse
+%<package>
+%<package>
+%<package>% \gettokslistitem{ number }{ tokslistmacro }
+%<package>% \gettokslistitem*{ number }{ list of tokens }
+% \fi
+% \begin{macro}{\gettokslistitem}\cmdlabel{impl:gettokslistitem}
+% \strut\seedesc{gettokslistitem}
+% \begin{macrocode}
+\newcommand\gettokslistitem[1]{\FE@ifstar{#1}{\ettl@gettokslistitem{}}
+ {\ettl@gettokslistitem\expandnext}}
+\begingroup\catcode`\&=3
+\long\gdef\ettl@gettokslistitem#1#2#3{%#2=index, #3=list or list-macro
+ #1\ettl@get@tokslist@item{#3{}}{\numexpr#2}}
+\long\gdef\ettl@get@tokslist@item#1#2{%
+ \ifblank{#1}{}
+ {\ifnum#2=1 \ettl@afterelsefi
+ \expandonce{\ettl@tokslist@first@item#1&}%
+ \else\ifnum#2>0 \ettl@afterfifi
+ \expandnext\ettl@get@tokslist@item{\@gobble#1}{#2-1}%
+ \fi\fi}}
+\endgroup
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+% \iffalse
+%<package>%----------------------------------------------------------------------------
+%<package>
+%<package>% \collectoks{ cs-token }{ list of allowed tokens }{ commands to expand after }
+%<package>
+% \fi
+% \begin{macro}{\collecttoks}\cmdlabel{impl:collecttoks}
+% A simple token scanner, vectorized version of \cs{futurelet}.\seedesc{collecttoks}
+% \begin{macrocode}
+\newrobustcmd*\collecttoks{\@ifstar\ettl@scantoks\ettl@collecttoks}
+\def\ettl@scantoks{\@latex@error{The starred version of \noexpand\collecttoks
+ \MessageBreak (i.e. scantoks) is NOT implemented YET.}\@ehd}
+% \end{macrocode}
+% \end{macro}
+%
+% \iffalse
+%<package>
+% \fi
+%
+% \begin{macro}{\ettl@collecttoks}
+% \begin{macrocode}
+\def\ettl@collecttoks#1#2#3{\begingroup
+ \def\ettl@collecttoks@list{#2}%
+ \let#1=\@empty
+ \def\Next{\ettl@collect@toks{#1}}%
+ \def\finale{#3}%
+ \futurelet\ettl@x\Next}
+\def\ettl@collect@toks#1{%
+ \edef\ettl@i{\gettokslistindex\ettl@x\ettl@collecttoks@list}%
+ \ifcase\ettl@i \edef\next{\endgroup
+ \def\noexpand#1{\expandonce{#1}}\expandonce{\finale}}%
+ \else \def\next{\ettl@collect@toks@next{#1}}%
+ \fi\next}
+\def\ettl@collect@toks@next#1#2{%
+ \edef#1{\expandonce{#1}\unexpanded{#2}}%
+ \futurelet\ettl@x\Next}
+% \end{macrocode}
+% \end{macro}
+%
+%
%
% \begin{macrocode}
%</package>
@@ -1199,10 +1777,10 @@ and etextools-examples.tex
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[american]{babel}
-\usepackage{geometry,doc,ltxdockit,txfonts,fancyhdr}
+\usepackage{geometry,doc,ltxdockit,txfonts,fancyhdr,stmaryrd,graphicx,fancyvrb}
\usepackage{etextools}
\hypersetup{colorlinks,pdfstartview={FitH}}
-\geometry{top=2cm,bottom=2cm,left=2.5cm,right=1cm}
+\geometry{top=1.5cm,bottom=1.2cm,left=2.5cm,right=1cm}
\fancyhf{}
\fancyhead[L]{Examples for the \sty{etextools} package}
\pagestyle{fancy}
@@ -1210,6 +1788,9 @@ and etextools-examples.tex
\makeatletter
\def\smex{\leavevmode\hb@xt@2em{\hfil$\longrightarrow$\hfil}}
+\def\FE{\setbox8\hbox{$\m@th\bindnasrepma$}%
+ \textcolor{fecc}{\scalebox{2}{$\copy8\mkern-13.5mu\copy8\mkern-13.5mu\copy8$}}}
+\definecolor{fecc}{rgb}{.2,.6,.2}
\def\strip@meaning{\expandafter\strip@prefix\meaning}
\def\strip@macro{\expandafter\strip@macroprefix\meaning}
\def\get@params#1{\expandafter\@get@params\meaning#1\@nil}
@@ -1222,16 +1803,19 @@ and etextools-examples.tex
\def\meaningcs#1{\expandafter\meaning\csname#1\endcsname}
\def\Meaningcs#1{\expandafter\strip@meaning\csname #1\endcsname}
+\@ifundefined{pdfstrcmp}{\let\ifpdfTeX\iffalse}{\let\ifpdfTeX\iftrue}
-\newcommand\test[1]{%
+\newcommand*\test{\@ifstar{\let\fe\relax\testi}{\let\fe\FE\testi}}
+\newcommand\testi[1]{%
\csname test#1\endcsname
\edef\usercmd{\Meaningcs{test#1}}\edef\result{\meaningcs{#1Test}}\noindent
\begin{tabular}{lp{15cm}}
- \multicolumn{2}{l}{\textcolor{blue}{\llap\smex\tt \usercmd}} \\[1.5ex]
+ \multicolumn{2}{l}{\textcolor{blue}{\llap{\fe\,\smex}\tt \usercmd}} \\[1.5ex]
\cmd{#1Test}= & \tt\bfseries\result
\end{tabular}\par\nobreak\hrulefill\null\goodbreak}
+
\begin{document}
\title{etextools examples}
\subtitle{Examples for some macros provided by the \sty{etextools} package}
@@ -1335,8 +1919,11 @@ and etextools-examples.tex
\hrulefill\par
\test{FE@testopt}
+
\section{Lists management}
+
\subsection{\cmd{csvloop} and \cmd{csvloop*} examples}
+
\subsubsection{\cmd{makequotes}}
\def\makequotes#1{"#1"\space}
\def\testcsvloop{%
@@ -1344,11 +1931,13 @@ and etextools-examples.tex
}
\preline\makequotes
\test{csvloop}
+
\subsubsection{\cmd{detokenize}}
\def\testcsvloop{%
\edef\csvloopTest{\csvloop*[\detokenize]{\un,\deux}}
}\hrulefill\par
\test{csvloop}
+
\subsubsection{\cmd{numexpr}}
\def\mylist{1,2,3,4,5}\def\BySeven#1{$#1\times 7 = \number\numexpr#1*7\relax$\par}
\def\testcsvloop{%
@@ -1356,26 +1945,94 @@ and etextools-examples.tex
\preline\mylist
\preline*\BySeven
\test{csvloop}
+
\subsubsection{protected \cmd{textbf}}
\def\testcsvloop{%
\protected@edef\csvloopTest{\csvloop*[\textbf]{hello ,my ,friends}}
}\hrulefill\par
\test{csvloop}
-\subsection{\cmd{getlistitem}}
+\subsection{Index in lists and items by index}
+
+\subsubsection{\cmd{getlistitem}}
\csvtolist*\mylist{one,two,three,four,five,alpha,beta,gamma}
\def\testgetlistitem{%
- \edef\getlistitemTest{\getlistitem\mylist{4}}
+ \edef\getlistitemTest{\getlistitem{4}\mylist}
}\hrulefill\par
\noindent\hskip6pt|\csvtolist*\mylist{one,two,three,four,five,alpha,beta,gamma}|\par\vskip1.5ex
\test{getlistitem}
-\subsection{\cmd{getlistindex} {\mdseries(not expandable)}}
-\getlistindex{four}\mylist
+\subsubsection{\cmd{getlistindex}}
+\ifpdfTeX
+\leavevmode\vadjust{\textsl{Require the }\string\pdfstrcmp\ \textsl{primitive (pdf\TeX{}) :}}
+\def\testgetlistindex{%
+ \edef\getlistindexTest{\getlistindex{alpha}\mylist}
+}\hrulefill\par
+\noindent\hskip6pt|\csvtolist*\mylist{one,two,three,four,five,alpha,beta,gamma}|\par\vskip1.5ex
+\test{getlistindex}
+
+\leavevmode\vadjust{\textsl{Require the }\string\pdfstrcmp\ \textsl{primitive (pdf\TeX{}) :}}
+\def\testgetlistindex{%
+ \edef\getlistindexTest{\getcsvlistindex*{alpha}{one,two,three,four,five,alpha,beta}}
+}\hrulefill\par
+\test{getlistindex}
+\fi
+
+\hrulefill\par
+\getlistindex[\myindex]{alpha}\mylist
+{\color{blue}\noindent\hskip6pt\llap\smex|\getlistindex[\myindex]{alpha}\mylist|\par\vskip1.5ex}
+{\tt\string\myindex=\quad\textbf{\meaning\myindex}}
+\hrulefill\par\vskip.5ex
+
\hrulefill\par
+\newcount\myindex
+\getcsvlistindex*[\myindex]{alpha}{one,two,three,four,five,alpha,beta}
+\noindent\hskip6pt|\newcount\myindex|\par
+{\color{blue}\noindent\hskip6pt\llap\smex|\getcsvlistindex*[\myindex]{alpha}{one,two,three,four,five,alpha,beta}|}\par\vskip.5ex
+{\tt\string\the\string\myindex=\qquad\textbf{\the\myindex}}
+\hrulefill\par\vskip.5ex
+
+
+\subsubsection{\cmd{xgetlistindex}}
+\ifpdfTeX
+\leavevmode\vadjust{\textsl{Require the }\string\pdfstrcmp\ \textsl{primitive (pdf\TeX{}) :}}
+\def\x{beta}
+\def\testxgetlistindex{%
+ \edef\xgetlistindexTest{\xgetlistindex{\x}\mylist}
+}\hrulefill\par
\noindent\hskip6pt|\csvtolist*\mylist{one,two,three,four,five,alpha,beta,gamma}|\par\vskip1.5ex
-\noindent\hskip6pt\textcolor{blue}{\llap\smex\cmd{getlistindex}\string{four\string}\cmd{mylist}}\par\vskip1.5ex
-\noindent\hskip6pt\cmd{indexinlist}=\quad{\bfseries\meaning\indexinlist}\par\hrulefill\par
+\preline*\x
+\test{xgetlistindex}
+\fi
+
+\subsubsection{\cmd{getlistindex} with \cmd{ifcase}}
+
+\leavevmode\vadjust{Always purely expandable (no need of |\pdfstrcmp|, comparison done by |\ifx|):}
+\hrulefill\par\noindent
+\llap{\FE\,\smex}\par\vskip-2.5\baselineskip\strut
+\begin{Verbatim}
+ \ifcase \gettokslistindex*{D}{LRDF\relax O}
+ Problem
+ \or What do to if L
+ \or What do to if R
+ \or What do to if D
+ \or What do to if F
+ \or What do to if \relax
+ \or What do to if O
+ \fi
+\end{Verbatim}
+
+{\tt Result=\qquad\bfseries
+\ifcase\gettokslistindex*{D}{LRDF}
+ Problem
+\or What do to if L
+\or What do to if R
+\or What do to if D
+\or What do to if F
+\fi}\par
+\hrulefill\par\vskip.5ex
+
+
\end{document}
%</example>
@@ -1383,12 +2040,36 @@ and etextools-examples.tex
%
% \section{Revision history}
%
-% \begin{changelog}
+% \begin{changelog}\footnotesize
%
-% \begin{release}{2z}{2009-08-12}
-% \item Addition of \cmdref{ifempty}
+% \begin{release}{2t}{2009-08-15}
+% \item
+% Addition of \cmdref{ifnotempty}, \cmdref{iflastchar}, \cmdref{ifstrcmp}, \cmdref{ifstrmatch}
+%
+%
+% \end{release}
+%
+% \begin{release}{2h}{2009-08-14}
+% \item
+% \cmdref{getlistindex} is now fully expandable
%
-% \item Modification of \cmdref{ifsinglechar}\\
+% \item Addition of\\
+% \cmdref{toksloop} and \cmd{toksloop*} \\
+% \cmdref{tokstolist} and \cmd{tokstolist*} \\
+% \cmdref{getcsvlistindex} and \cmdref{getcsvlistitem} \\
+% \cmdref{gettokslistindex} and \cmdref{gettokslistitem} \\
+%
+% \item Addition of\\
+% \cmdref{collecttoks} -- a vectorized version of \cs{futurelet}.\\
+% \cmdref{FE@ifchar} as a generalization of \cmdref{FE@ifstar}.
+%
+% \end{release}
+%
+% \begin{release}{2z}{2009-08-12}
+% \item Addition of \\
+% \cmdref{ifempty}, \cmdref{toksloop}, \cmdref{tokstolist} and \cmdref{tokstolistadd}
+% \item
+% Modification of \cmdref{ifsinglechar}\\
% |\ifsinglechar| now works with |\ifempty| so that:\\
% \begin{tabbing}
% \quad\=|\macro{ * }|\quad\= is no more considered as a starred form \\
@@ -1397,11 +2078,13 @@ and etextools-examples.tex
% \>\>as does |\@ifnextchar| from the \LaTeX{} kernel.
% \end{tabbing}
%
-% \item Index added to this documentation paper.
+% \item
+% Index added to this documentation paper.
% \end{release}
% \begin{release}{2e}{2009-07-14}
-% \item First version (include an example file)
+% \item
+% First version (include an example file)
% \end{release}
%
% \end{changelog}
diff --git a/Master/texmf-dist/source/latex/etextools/etextools.ins b/Master/texmf-dist/source/latex/etextools/etextools.ins
index ca83a61febb..f922c22757f 100644
--- a/Master/texmf-dist/source/latex/etextools/etextools.ins
+++ b/Master/texmf-dist/source/latex/etextools/etextools.ins
@@ -21,11 +21,11 @@
%% etextools.sty, etextools.pdf, etextools.ins,
%% and etextools-examples.tex
%%
-%%% etextools : more e-TeX useful tools for LaTeX package writers
+%%% etextools : more e-TeX useful tools for LaTeX package writers (v.
\input docstrip.tex
\Msg{************************************************************************}
\Msg{* Installation}
-\Msg{* Package: etextools 2009/07/14 v2e e-TeX more useful tools for LaTeX package writers}
+\Msg{* Package: etextools 2009/07/14 v2h e-TeX more useful tools for LaTeX package writers}
\Msg{************************************************************************}
\keepsilent
@@ -76,6 +76,7 @@ and etextools-examples.tex
\endbatchfile
+
\endinput
%%
%% End of file `etextools.ins'.
diff --git a/Master/texmf-dist/tex/latex/etextools/etextools.sty b/Master/texmf-dist/tex/latex/etextools/etextools.sty
index e11696396a5..791e2fd2c1c 100644
--- a/Master/texmf-dist/tex/latex/etextools/etextools.sty
+++ b/Master/texmf-dist/tex/latex/etextools/etextools.sty
@@ -21,29 +21,45 @@
%% etextools.sty, etextools.pdf, etextools.ins,
%% and etextools-examples.tex
%%
-%%% etextools : more e-TeX useful tools for LaTeX package writers
+%%% etextools : more e-TeX useful tools for LaTeX package writers (v.
+
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
\ProvidesPackage{etextools}
- [2009/07/14 v2e e-TeX more useful tools for LaTeX package writers]
+ [2009/08/14 v2h e-TeX more useful tools for LaTeX package writers]
\csname ettl@onlyonce\endcsname\let\ettl@onlyonce\endinput
\RequirePackage{etex,etoolbox}
-\edef\ettl@restore@space@catcode{\catcode`\ =\the\catcode`\ }
-\AtEndOfPackage{\ettl@restore@space@catcode
- \let\ettl@restore@space@catcode\ettl@undefined}
-\catcode`\ =10
+\let\ettl@AtEnd\@empty
+\def\TMP@EnsureCode#1#2{%
+ \edef\ettl@AtEnd{%
+ \ettl@AtEnd
+ \catcode#1 \the\catcode#1\relax
+ }%
+ \catcode#1 #2\relax
+}
+\TMP@EnsureCode{32}{10}% space
+\ifundef\pdfstrcmp{%
+ \TMP@EnsureCode{33}{9}% ! ignore
+ \TMP@EnsureCode{34}{14}% " comment
+}{\TMP@EnsureCode{33}{14}% ! comment
+ \TMP@EnsureCode{34}{9}% " ignore
+}
+\AtEndOfPackage{\ettl@AtEnd\undef\ettl@AtEnd}
% A few helper macros
\long\def\ettl@afterelse#1\else#2\fi{\fi#1}
\long\def\ettl@afterfi#1\fi{\fi#1}
\long\def\ettl@afterfifi#1\fi\fi{\fi\fi#1}
\long\def\ettl@afterelsefi#1\else#2\fi\fi{\fi#1}
-\begingroup\catcode`\|=4
-\long\gdef\ettl@cdr#1#2|{#2}
-\endgroup
+\long\def\ettl@afterorfi#1\or#2\fi{\fi#1}
+\def\ettl@ifstrcmp#1#2{\csname @%
+ \ifnum\pdfstrcmp{#1}{#2}=0 first\else second\fi oftwo\endcsname}
\newcommand*\@gobblescape{\expandafter\@gobble\string}
-\newcommand\str@gobblescape[1]{\expandafter\deblank\expandafter{%
- \expandafter\@gobble\detokenize{#1}}}
+\def\ettl@onlypdfTeX#1#2{\ifundef{#1}
+ {\def#2{\PackageError{etextools}{\string#1\space primitive not found\MessageBreak
+ pdfTeX seems not to be running}
+ {\string#2\space works only if used with pdfTeX (requires \string#1)}}}
+ {}}
\newcommand*\noexpandcs[1]{\expandafter\noexpand\csname #1\endcsname}
\newcommand\noexpandafter{\noexpand\expandafter}
@@ -64,47 +80,94 @@
\expandafter\ettl@afterfi#2#1#2{#3}%
\fi}
-\newcommand\deblank{}
-\newcommand\ifempty{}
-\begingroup\catcode`\|=4% a | as a tab array
-\long\gdef\deblank#1{\@deblank#1 |}
-\long\gdef\@deblank#1 #2|{\ifblank{#2}{#1}{#1\@deblank#2 |}}
% \ifempty{ text }{ true }{ false }
-\long\gdef\ifempty#1{\csname @\ifx|#1|first\else second\fi oftwo\endcsname}
-\endgroup% catcode group
+\newcommand\ifempty[1]{\csname @\expandafter\ifx
+ \expandafter\relax\detokenize{#1}\relax
+ first\else second\fi oftwo\endcsname}
+
+% \ifnotempty{ text }{ true }{ false }
+\newcommand\ifnotempty[1]{\csname @\expandafter\ifx
+ \expandafter\relax\detokenize{#1}\relax
+ second\else first\fi oftwo\endcsname}
+
+% \xifempty{ text }{ true }{ false }
+\newcommand\xifempty[1]{\xifstrcmp{#1}{}}
+\ettl@onlypdfTeX\pdfstrcmp\xifempty
+
+% \ifnotblank{ text }{ true }{ false }
+\begingroup\catcode`\&=3\catcode`\:=12
+\ifcsundef{ifnotblank}{%
+\long\gdef\ifnotblank#1{\etb@ifblank@i#1&&\@firstoftwo\@secondoftwo:}}
+\relax\endgroup
+% \xifblank{ string }{ true }{ false }
\newrobustcmd\xifblank[1]{\begingroup
\protected@edef\@xifblank{\endgroup
\noexpand\ifblank{#1}%
}\@xifblank}
-\newrobustcmd\xifstrequal[2]{%
- \begingroup\protected@edef\@tempa{#1}\protected@edef\@tempb{#2}%
- \ifx\@tempa\@tempb \aftergroup\@firstoftwo
- \else \aftergroup\@secondoftwo
- \fi\endgroup}
-\newcommand\iffirstchar[2]{%
- \if \expandafter\@car\string#2\relax\@nil\expandafter\@car#1\string\\\@nil
- \ettl@afterelse\ifblank{#2}\@secondoftwo\@firstoftwo
- \else \expandafter\@secondoftwo
- \fi}
-\newcommand\ifsinglechar{}
-\begingroup\catcode`\|=4
-\long\gdef\ifsinglechar#1#2{%
- \csname @\expandafter\expandafter\expandafter\ifx
- \expandafter\expandafter\expandafter|%
- \expandafter\ettl@cdr\string#2||first\else second\fi
- oftwo\endcsname
- {\iffirstchar{#1}{#2}}
- \@secondoftwo}
-\endgroup% catcode group
-%\FE@testopt{#1}{commands}{default option}
+% \iffirstchar{ string1 }{ string2 }{ true }{ false }
+\newcommand\iffirstchar[2]{\csname @%
+ \if \expandafter\@car\detokenize{#2}\relax\@nil\expandafter\@car\detokenize{#1}\string\\\@nil
+ \ifblank{#2}{second}{first}%
+ \else second%
+ \fi oftwo\endcsname}
+
+% \ifsinglechar character{ string }{ true }{ false }
+\newcommand\ifsinglechar[2]{%
+ \csname @\ifblank{#2}{second}{%
+" \ifnum\pdfstrcmp{\detokenize{#1}}{\detokenize{#2}}=0
+" \ifnum\pdfstrcmp{\detokenize{#2}}{\expandafter\@car\detokenize{#2}\relax\@nil}=0
+" first%
+" \else second%
+" \fi
+" \else second%
+" \fi oftwo\endcsname}}
+! \expandafter\expandafter\expandafter\ifx
+! \expandafter\expandafter\expandafter\relax\expandafter\@cdr\detokenize{#2}\@nil\relax
+! \iffirstchar{#1}{#2}{first}{second}\else second\fi oftwo\endcsname}}
+
+% \iflastchar{ string1 }{ string2 }{ true }{ false }
+\begingroup\catcode`\&=3
+\long\gdef\iflastchar#1#2{%
+ \long\def\ettl@iflastchar##1#1##2&{%
+ \ifstrcmp{##2}{#1}\@firstoftwo{%
+ \ifempty{##2}\@secondoftwo{\ettl@iflastchar##2&}}
+ }\ettl@iflastchar#2#1&}
+\endgroup
+
+% \ifstrcmp{ string1 }{ string2 }{ true }{ false }
+\newcommand\ifstrcmp[2]{\csname @%
+ \ifnum\pdfstrcmp{\detokenize{#1}}{\detokenize{#2}}=0 first\else second\fi
+ oftwo\endcsname}
+\ettl@onlypdfTeX\pdfstrcmp\ifstrcmp
+
+% \xifstrcmp{ string1 }{ string2 }{ true }{ false }
+\newcommand\xifstrcmp[2]{\csname @%
+ \ifnum\pdfstrcmp{#1}{#2}=0 first\else second\fi
+ oftwo\endcsname}
+\ettl@onlypdfTeX\pdfstrcmp\ifxstrcmp
+\newrobustcmd*\xifstrequal[2]{\begingroup
+ \protected@edef\@xifstrequal{\endgroup\noexpand\ifstrequal{#1}{#2}%
+ }\@xifstrequal}
+
+% \ifstrmatch{ pattern }{ true }{ false }
+\newcommand\ifstrmatch[2]{\csname @%
+ \ifnum\pdfmatch{\detokenize{#1}}{\detokenize{#2}}=1 first\else second\fi
+ oftwo\endcsname}
+\ettl@onlypdfTeX\pdfmatch\ifstrmatch
+%----------------------------------------------------------------------------
+% Purely Expandable Macros With Options / Star Forms / Variants
+% \FE@testopt{ #1 }{ commands }{ default option }
\newcommand\FE@testopt[3]{\ifsinglechar [{#1}{#2#1}{#2[{#3}]{#1}}}
-%\FE@ifstar{#1}{\StarredMacro}{\NotStarredMacro}
+% \FE@ifstar{ #1 } { \StarredMacro }{ \NotStarredMacro }
\newcommand\FE@ifstar[3]{\ifsinglechar *{#1}{#2}{#3{#1}}}
+% \FE@ifchar{#1}{#2}{ \SpecialFormMacro }{ \NormalMacro }
+\newcommand\FE@ifchar[4]{\ifsinglechar{#1}{#2}{#3}{#4{#2}}}
+
%% \iffalse
% \DeclareCmdListParser : general constructor for command-list parsers
@@ -118,16 +181,12 @@
\def\`##1`{\expandafter\noexpand\csname ##1\endcsname}%
\protected@edef\defineparser{\endgroup
\long\def#1####1{\noexpand\FE@ifstar{####1}
- {\`ettl@lst@star\string#1`}
- {\`ettl@lst@nost\string#1`}}%
- \long\csdef{ettl@lst@star\string#1}####1{\noexpand\FE@testopt{####1}
- {\`ettl@lst@star@pt\string#1`}{\noexpand\do}}%
- \long\csdef{ettl@lst@nost\string#1}####1{\noexpand\FE@testopt{####1}
- {\`ettl@lst@nost@pt\string#1`}{\noexpand\do}}%
- \long\csdef{ettl@lst@star@pt\string#1}[####1]####2{%
- \`ettl@lst\string#1`{####2}{####1}}%
- \long\csdef{ettl@lst@nost@pt\string#1}[####1]####2{%
- \noexpandafter\`ettl@lst\string#1`\noexpandafter{####2}{####1}}%
+ {\`ettl@lst@opt\string#1`{}}
+ {\`ettl@lst@opt\string#1`\noexpandafter}}%
+ \long\csdef{ettl@lst@opt\string#1}####1####2{\noexpand\FE@testopt{####2}
+ {\`ettl@lst@@pt\string#1`{####1}}{\noexpand\do}}%
+ \long\csdef{ettl@lst@@pt\string#1}####1[####2]####3{%
+ ####1\`ettl@lst\string#1`####1{####3}{####2}}%
\long\csdef{ettl@lst\string#1}####1####2{%
\`ettl@lst@\string#1`{####2}####1\unexpanded{#2}&}%
\long\csdef{ettl@lst@\string#1}####1####2\unexpanded{#2}####3&{%
@@ -149,20 +208,29 @@
\begingroup\catcode`\|=3
\def\do{\DeclareCmdListParser\listloop{|}}%
\expandafter\endgroup\do
+\DeclareCmdListParser\toksloop{}%
+
+% \csvtolist \ListMacro \csvListMacro
+% \csvtolist* \ListMacro {item,item,item}
+\newrobustcmd*\csvtolist{\@ifstar
+ {\ettl@tolist\z@{}\csvloop}
+ {\ettl@tolist\z@\expandnext\csvloop}}%
+\long\def\ettl@tolist#1#2#3#4#5{\ifx#1\z@\let#4\@empty\fi
+ \def\ettl@to@list{#3*[{\unexpanded{\listadd#4}}]%
+ }#2\ettl@to@list{#5}}
-%\csvtolist\csvListMacro
-%\csvtolist*{item,item,item}
-\newcommand\csvtolist{\@ifstar\star@csvtolist\nost@csvtolist}%
-\def\star@csvtolist#1{\let#1\@empty\csvloop*[{\unexpanded{\listadd#1}}]}%
-\def\nost@csvtolist#1{\let#1\@empty\csvloop[{\unexpanded{\listadd#1}}]}%
+\newrobustcmd*\tokstolist{\@ifstar{\ettl@tokstolist\z@{}}{\ettl@tokstolist\z@\expandnext}}
+\def\ettl@tokstolist#1#2#3#4{\ifx#1\z@\let#3\@empty\fi
+ \def\ettl@toks@tolist{\toksloop*[{\unexpanded{\listadd#3}}]}%
+ #2\ettl@toks@tolist{#4{}}}
-%\csvtolistadd\csvListMacro
-%\csvtolistadd*{item,item,item}
-\newcommand\csvtolistadd{\@ifstar\star@csvtolistadd\nost@csvtolistadd}%
-\def\star@csvtolistadd#1#2{\ifblank{#2}
- {\let#1\@empty}{\csvloop*[{\unexpanded{\listadd#1}}]{#2}}}%
-\def\nost@csvtolistadd#1#2{\ifblank{#2}
- {\let#1\@empty}{\csvloop[{\unexpanded{\listadd#1}}]{#2}}}%
+% \csvtolistadd \ListMacro \csvListMacro
+% \csvtolistadd* \ListMacro {item,item,item}
+\newrobustcmd*\csvtolistadd{\@ifstar
+ {\ettl@tolist\@ne{}\csvloop}
+ {\ettl@tolist\@ne\expandnext\csvloop}}
+
+\newrobustcmd*\tokstolistadd{\@ifstar{\ettl@tokstolist\@ne{}}{\ettl@tokstolist\@ne\expandnext}}%
%\listdel\listMacro{item}
%\listgdel\listMacro{item}
@@ -181,11 +249,11 @@
\begingroup\catcode`\|=3\catcode`\&=3
\long\gdef\@listdel#1#2#3{%
\begingroup
- \def\@tempa##1|#3|##2&{##1|##2\@tempb}%
- \def\@tempb|##1|\@tempb##2|\@tempb{%
+ \long\def\@tempa##1|#3|##2&{##1|##2\@tempb}%
+ \long\def\@tempb|##1|\@tempb##2|\@tempb{%
\ifblank{##2}{\unexpanded{##1}}
{\ifblank{##1}{}{\@tempx##1&}}}%
- \def\@tempx##1&{\expandafter\@tempb\@tempa|##1|\@tempb|#3|&}%
+ \long\def\@tempx##1&{\expandafter\@tempb\@tempa|##1|\@tempb|#3|&}%
\edef\@redef{\endgroup
\unexpanded{#1#2}{% ie: \def or \gdef \listmacro
\expandafter\@tempx\unexpanded\expandafter{#2}&}%
@@ -193,39 +261,153 @@
\endgroup
-% \getlistindex (result in \indexinlist)
+% \getlistindex[\indexmacro]{ \listmacro }
+% \getlistindex*[\indexmacro]{ expanded list }
+\newcommand\getlistindex[1]{\FE@ifstar{#1}
+ {\ettl@getlistindex{}\unexpanded}
+ {\ettl@getlistindex\expandnext\unexpanded}}
+\newcommand\xgetlistindex[1]{\FE@ifstar{#1}
+ {\ettl@getlistindex{}\@firstofone}
+ {\ettl@getlistindex\expandnext\@firstofone}}
\begingroup\catcode`\|=3\catcode`\&=3
-\gdef\getlistindex#1{\FE@ifstar{#1}{\ettl@getlistindex{}}
- {\ettl@getlistindex\expandnext}}
-\gdef\xgetlistindex#1{\FE@ifstar{#1}{\ettl@xgetlistindex{}}
- {\ettl@xgetlistindex\expandnext}}
-\gdef\ettl@xgetlistindex#1#2#3{\begingroup
- \protected@edef\next{\endgroup\unexpanded{\ettl@getlistindex{#1}{#2}}{#3}%
- }\next}
-\gdef\ettl@getlistindex#1#2#3{\begingroup#1\ettl@get@list@idx{#3}{#2}{\numexpr1}}
-\gdef\ettl@get@list@idx#1#2#3{% #1=expanded list, #2=item, #3=index
+\long\gdef\ettl@getlistindex#1#2#3{\FE@testopt{#3}{\ettl@get@listindex{#1}{#2}}{}}
+\long\gdef\ettl@get@listindex#1#2[#3]#4#5{#1\ettl@get@list@idx{#5}{#4}{\numexpr1}{#2}[{#3}]}
+\long\gdef\ettl@get@list@idx#1#2#3#4[#5]{% #1=expanded list, #2=item, #3=index, #4=\unexpanded (event., #5=indexmacro)
+ \ifblank{#1}0% the (remainder of) the list is empty
+" {\xifstrcmp{\expandonce{\ettl@list@first@item#1&}}{#4{#2}}}
+! {\ettl@listitem@cmp{\ettl@list@first@item#1&}{#2}{#4}}
+ {\ifblank{#5}{\number#3\relax}{\ettl@ifiscount{#5}{#5=\number#3\relax}{\edef#5{\number#3}}}}
+ {\expandnext\ettl@get@list@idx{\ettl@list@other@item#1&}{#2}{#3+1}{#4}[{#5}]}}
+\long\gdef\ettl@list@first@item#1|#2&{#1}
+\long\gdef\ettl@list@other@item#1|#2&{#2}
+!\long\gdef\ettl@listitem@cmp#1#2#3{%
+! \ifx#3\unexpanded\def\ettl@listitem@cmp@{#2}%
+! \else\protected@edef\ettl@listitem@cmp@{#2}%
+! \fi
+! \expandafter\ifstrequal\expandafter{#1}{#2}}
+\edef\ettl@ifiscount{%
+ \gdef\noexpand\ettl@ifiscount##1{%
+ \noexpand\expandafter\noexpand\ettl@ifiscount@i
+ \noexpand\meaning##1\string\count\noexpand\@nil}%
+}\ettl@ifiscount
+\edef\ettl@ifiscount@i{%
+ \gdef\noexpand\ettl@ifiscount@i##1\string\count##2\noexpand\@nil{%
+ \noexpand\ifempty{##1}}%
+}\ettl@ifiscount@i
+
+%\getcsvlistindex{ item }{ csvlistmacro }
+%\getcsvlistindex*{ item }{ item,item,item }
+\long\gdef\getcsvlistindex#1{\FE@ifstar{#1}
+ {\ettl@getcsvlistindex{}\unexpanded}
+ {\ettl@getcsvlistindex\expandnext\unexpanded}}
+\long\gdef\xgetcsvlistindex#1{\FE@ifstar{#1}
+ {\ettl@getcsvlistindex{}\@firstofone}
+ {\ettl@getcsvlistindex\expandnext\@firstofone}}
+\long\gdef\ettl@getcsvlistindex#1#2#3{\FE@testopt{#3}{\ettl@get@csvlistindex{#1}{#2}}{}}
+\long\gdef\ettl@get@csvlistindex#1#2[#3]#4#5{#1\ettl@get@csvlist@idx{#5}{#4}{\numexpr1}{#2}[{#3}]}
+\long\gdef\ettl@get@csvlist@idx#1#2#3#4[#5]{% #1=expanded list, #2=item, #3=index, #4=\unexpanded (event., #5=indexmacro)
+ \ifblank{#1}0% the (remainder of) the list is empty
+" {\xifstrcmp{\expandonce{\ettl@csvlist@first@item#1&}}{#4{#2}}}
+! {\ettl@listitem@cmp{\ettl@csvlist@first@item#1&}{#2}{#4}}
+ {\ifblank{#5}{\number#3\relax}{\ettl@ifiscount{#5}{#5=\number#3\relax}{\edef#5{\number#3}}}}
+ {\expandnext\ettl@get@csvlist@idx{\ettl@csvlist@other@item#1&}{#2}{#3+1}{#4}[{#5}]}}
+\long\gdef\ettl@csvlist@first@item#1,#2&{#1}
+\long\gdef\ettl@csvlist@other@item#1,#2&{#2}
+
+%\gettokslistindex{ item }{ tokenslistmacro }
+%\gettokslistindex*{ item }{ list of tokens }
+\long\gdef\gettokslistindex#1{\FE@ifstar{#1}
+ {\ettl@gettokslistindex{}}
+ {\ettl@gettokslistindex\expandnext}}
+\long\gdef\ettl@gettokslistindex#1#2{\FE@testopt{#2}{\ettl@get@tokslistindex{#1}}{}}
+\long\gdef\ettl@get@tokslistindex#1[#2]#3#4{#1\ettl@get@tokslist@idx{#4}{#3}{\numexpr1}[{#2}]}
+\long\gdef\ettl@get@tokslist@idx#1#2#3[#4]{% #1=expanded list, #2=item, #3=index
\ifblank{#1}0% the (remainder of) the list is empty
- {\expandnext\ifstrequal{\ettl@list@first@item#1&}{#2}
- {\endgroup\edef\indexinlist{\number#3\relax}}
- {\expandnext\ettl@get@list@idx{\ettl@list@other@item#1&}{#2}{#3+1}}}}
-\gdef\ettl@list@first@item#1|#2&{#1}
-\gdef\ettl@list@other@item#1|#2&{#2}
+ {\expandafter\ifx\expandafter#2\ettl@tokslist@first@item#1&%
+ \ettl@afterelse\ifblank{#4}{\number#3\relax}
+ {\ettl@ifiscount{#4}{#4=\number#3\relax}{\edef#4{\number#3}}}%
+ \else \ettl@afterfi
+ \expandnext\ettl@get@tokslist@idx{\ettl@tokslist@other@item#1&}{#2}{#3+1}[{#4}]%
+ \fi}}
+\long\gdef\ettl@tokslist@first@item#1#2&{#1}
+\long\gdef\ettl@tokslist@other@item#1#2&{#2}
\endgroup% catcode group
-\newcommand\getlistitem[1]{\FE@ifstar{#1}\ettl@getlistitem
- {\expandnext\ettl@getlistitem}}
+
+
+%\getlistitem{ number }{ listmacro }
+%\getlistitem*{ number }{ listmacro }
+\newcommand\getlistitem[1]{\FE@ifstar{#1}{\ettl@getlistitem{}}
+ {\ettl@getlistitem\expandnext}}
\begingroup\catcode`\&=3
-\long\gdef\ettl@getlistitem#1#2{%#1=listmacro, #2=index
- \ettl@get@list@item{#1}{\number\numexpr#2}}
+\long\gdef\ettl@getlistitem#1#2#3{%#2=index, #3=list or list-macro
+ #1\ettl@get@list@item{#3}{\numexpr#2}}
\long\gdef\ettl@get@list@item#1#2{%
\ifblank{#1}{}
{\ifnum#2=1 \ettl@afterelsefi
- \expandonce{\ettl@list@first@item#1&}
+ \expandonce{\ettl@list@first@item#1&}%
\else\ifnum#2>0 \ettl@afterfifi
- \expandnext\ettl@getlistitem{\ettl@list@other@item#1&}{#2-1}%
+ \expandnext\ettl@get@list@item{\ettl@list@other@item#1&}{#2-1}%
\fi\fi}}
\endgroup
+% \getcsvlistitem{ number }{ csvlistmacro }
+% \getcsvlistitem*{ number }{ item,item,item,... }
+\newcommand\getcsvlistitem[1]{\FE@ifstar{#1}{\ettl@getcsvlistitem{}}
+ {\ettl@getcsvlistitem\expandnext}}
+\begingroup\catcode`\&=3
+\long\gdef\ettl@getcsvlistitem#1#2#3{%#2=index, #3=list or list-macro
+ #1\ettl@get@csvlist@item{#3,}{\numexpr#2}}
+\long\gdef\ettl@get@csvlist@item#1#2{%
+ \ifblank{#1}{}
+ {\ifnum#2=1 \ettl@afterelsefi
+ \expandonce{\ettl@csvlist@first@item#1&}%
+ \else\ifnum#2>0 \ettl@afterfifi
+ \expandnext\ettl@get@csvlist@item{\ettl@csvlist@other@item#1&}{#2-1}%
+ \fi\fi}}
+\endgroup
+
+
+% \gettokslistitem{ number }{ tokslistmacro }
+% \gettokslistitem*{ number }{ list of tokens }
+\newcommand\gettokslistitem[1]{\FE@ifstar{#1}{\ettl@gettokslistitem{}}
+ {\ettl@gettokslistitem\expandnext}}
+\begingroup\catcode`\&=3
+\long\gdef\ettl@gettokslistitem#1#2#3{%#2=index, #3=list or list-macro
+ #1\ettl@get@tokslist@item{#3{}}{\numexpr#2}}
+\long\gdef\ettl@get@tokslist@item#1#2{%
+ \ifblank{#1}{}
+ {\ifnum#2=1 \ettl@afterelsefi
+ \expandonce{\ettl@tokslist@first@item#1&}%
+ \else\ifnum#2>0 \ettl@afterfifi
+ \expandnext\ettl@get@tokslist@item{\@gobble#1}{#2-1}%
+ \fi\fi}}
+\endgroup
+%----------------------------------------------------------------------------
+
+% \collectoks{ cs-token }{ list of allowed tokens }{ commands to expand after }
+
+\newrobustcmd*\collecttoks{\@ifstar\ettl@scantoks\ettl@collecttoks}
+\def\ettl@scantoks{\@latex@error{The starred version of \noexpand\collecttoks
+ \MessageBreak (i.e. scantoks) is NOT implemented YET.}\@ehd}
+
+\def\ettl@collecttoks#1#2#3{\begingroup
+ \def\ettl@collecttoks@list{#2}%
+ \let#1=\@empty
+ \def\Next{\ettl@collect@toks{#1}}%
+ \def\finale{#3}%
+ \futurelet\ettl@x\Next}
+\def\ettl@collect@toks#1{%
+ \edef\ettl@i{\gettokslistindex\ettl@x\ettl@collecttoks@list}%
+ \ifcase\ettl@i \edef\next{\endgroup
+ \def\noexpand#1{\expandonce{#1}}\expandonce{\finale}}%
+ \else \def\next{\ettl@collect@toks@next{#1}}%
+ \fi\next}
+\def\ettl@collect@toks@next#1#2{%
+ \edef#1{\expandonce{#1}\unexpanded{#2}}%
+ \futurelet\ettl@x\Next}
+
+
\endinput
%%
%% End of file `etextools.sty'.