summaryrefslogtreecommitdiff
path: root/Master/texmf-dist
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-08-14 23:52:07 +0000
committerKarl Berry <karl@freefriends.org>2009-08-14 23:52:07 +0000
commite5bc967eb0517b8377d70914cc45484e5f4f2c7c (patch)
treec84dda99e2c37af655bc79627867111ec6bb2ba9 /Master/texmf-dist
parent3cda51c4ea4ac2affd9b693c6f071d884ab6b951 (diff)
etextools (11aug09)
git-svn-id: svn://tug.org/texlive/trunk@14676 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist')
-rw-r--r--Master/texmf-dist/doc/latex/etextools/README2
-rw-r--r--Master/texmf-dist/doc/latex/etextools/etextools-examples.pdfbin76753 -> 79220 bytes
-rw-r--r--Master/texmf-dist/doc/latex/etextools/etextools-examples.tex36
-rw-r--r--Master/texmf-dist/doc/latex/etextools/etextools.pdfbin531368 -> 564537 bytes
-rw-r--r--Master/texmf-dist/source/latex/etextools/etextools.dtx1093
-rw-r--r--Master/texmf-dist/source/latex/etextools/etextools.ins2
-rw-r--r--Master/texmf-dist/tex/latex/etextools/etextools.sty112
7 files changed, 810 insertions, 435 deletions
diff --git a/Master/texmf-dist/doc/latex/etextools/README b/Master/texmf-dist/doc/latex/etextools/README
index 3a58e58ebe2..e8d69bc75ea 100644
--- a/Master/texmf-dist/doc/latex/etextools/README
+++ b/Master/texmf-dist/doc/latex/etextools/README
@@ -1,7 +1,7 @@
% This work consists of the main source file etextools.dtx
% and the derived files
% etextools.sty, etextools.pdf, etextools.ins,
-% and etextools-examples.tex
+% etextools-examples.tex and etextools-examples.pdf
%
% Unpacking:
% (a) If etextools.ins is present:
diff --git a/Master/texmf-dist/doc/latex/etextools/etextools-examples.pdf b/Master/texmf-dist/doc/latex/etextools/etextools-examples.pdf
index 12efa0070df..2ed2e95f2c5 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 a8b96ae1837..97c800e3fe3 100644
--- a/Master/texmf-dist/doc/latex/etextools/etextools-examples.tex
+++ b/Master/texmf-dist/doc/latex/etextools/etextools-examples.tex
@@ -22,7 +22,6 @@
%% and etextools-examples.tex
%%
%%% etextools : more e-TeX useful tools for LaTeX package writers
-%%% Florent CHERVET
\documentclass[11pt,french,a4paper,oneside]{scrartcl}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
@@ -70,6 +69,20 @@
\section{\cmd{expandnext} examples}
+\subsection{Test if the replacement text of macro is really empty}
+
+\def\xx{ }
+\def\testexpandnext{%
+ \edef\expandnextTest{\string\xx\ is \expandnext\ifempty{\xx}{}{not} empty}
+}
+\preline\xx
+\test{expandnext}
+
+\def\xx{}
+\preline\xx
+\test{expandnext}
+
+\clearpage
\subsection{Test if the replacement text of a macro is blank (empty or spaces)}
\def\xx{something}
@@ -83,7 +96,6 @@
\preline\xx
\test{expandnext}
-\clearpage
\subsection{Detokenize the replacement text of a named-sequence}
\def\detokenizecs#1{\expandnext\expandnext\detokenize{\csname #1\endcsname}}
\def\testexpandnext{%
@@ -98,6 +110,17 @@
}\hrulefill\par
\test{ifsinglechar}
+\def\testifsinglechar{%
+ \edef\ifsinglecharTest{\ifsinglechar *{ *}{ single star }{ something else }}
+}\hrulefill\par
+\test{ifsinglechar}
+
+\def\testifsinglechar{%
+ \edef\ifsinglecharTest{\ifsinglechar *{ * }{ single star }{ something else }}
+}\hrulefill\par
+\test{ifsinglechar}
+{\small Note the space \textbf{after} the star $\uparrow$.}
+
\def\testiffirstchar{%
\edef\iffirstcharTest{\iffirstchar *{*hello*}{ first char is star }{ something else }}
}\hrulefill\par
@@ -105,8 +128,8 @@
\subsection{Fully Expandable starred macros}
\def\starmacro#1{\FE@ifstar{#1}\starred\notstarred}
-\def\starred#1{your "#1" will be processed by the STAR form}
-\def\notstarred#1{your "#1" will be processed by the NORMAL form}
+\def\starred#1{your "#1" will be processed by the STAR form}
+\def\notstarred#1{your "#1" will be processed by the NORMAL form}
\def\testFE@ifstar{%
\edef\FE@ifstarTest{\starmacro{sample text}}}
\preline\starmacro
@@ -154,7 +177,7 @@
\preline\mylist
\preline*\BySeven
\test{csvloop}
-\subsubsection{protected \cmd{testbf}}
+\subsubsection{protected \cmd{textbf}}
\def\testcsvloop{%
\protected@edef\csvloopTest{\csvloop*[\textbf]{hello ,my ,friends}}
}\hrulefill\par
@@ -172,11 +195,12 @@
\getlistindex{four}\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}{four}\cmd{mylist}}\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
\end{document}
+
\endinput
%%
%% End of file `etextools-examples.tex'.
diff --git a/Master/texmf-dist/doc/latex/etextools/etextools.pdf b/Master/texmf-dist/doc/latex/etextools/etextools.pdf
index 77103fd7539..1a20a8f26f6 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 5a8c2dcef83..3c335b7296d 100644
--- a/Master/texmf-dist/source/latex/etextools/etextools.dtx
+++ b/Master/texmf-dist/source/latex/etextools/etextools.dtx
@@ -1,6 +1,5 @@
% \iffalse meta-comment
%%% etextools : more e-TeX useful tools for LaTeX package writers
-%%% Florent CHERVET
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
@@ -97,18 +96,20 @@ and etextools-examples.tex
\documentclass[a4paper,oneside]{ltxdockit}
\usepackage[latin9]{inputenc}
\usepackage[american]{babel}
-\usepackage{doc,stmaryrd,amsmath,graphics,geometry,fancyhdr,framed,bbding,trace,embedfile}\CodelineNumbered
+\usepackage{doc,tocloft,stmaryrd,amsmath,graphics,geometry,fancyhdr,framed,bbding,trace,embedfile,etoolbox,marvosym}
+\CodelineNumbered\CodelineIndex
\embedfile{\thisfile.dtx}
-\geometry{totalheight=26cm,marginparwidth=14pt}
+\geometry{left=4.5cm,marginparwidth=14pt,right=2cm,totalheight=26cm}
\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{\varepsilon}$},
- date={14 July 2009}}
+ revision={2\:$\boldsymbol{\zeta}$},
+ date={12 août 2009}}
\hypersetup{%
+ hyperindex=true,
pdftitle={The etextools package},
pdfsubject={An e-TeX package for more useful tools for LaTeX package writers},
pdfauthor={Florent CHERVET},
@@ -121,13 +122,65 @@ and etextools-examples.tex
%</driver>
% \fi
%
+% \CheckSum{887}
+%
+% \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
+% Lower-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
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+% \DoNotIndex{\begin,\CodelineIndex,\CodelineNumbered,\def,\DisableCrossrefs,\if}
+% \DoNotIndex{\DocInput,\documentclass,\EnableCrossrefs,\end,\GetFileInfo}
+% \DoNotIndex{\NeedsTeXFormat,\OnlyDescription,\RecordChanges,\usepackage}
+% \DoNotIndex{\ProvidesClass,\ProvidesPackage,\ProvidesFile,\RequirePackage}
+% \DoNotIndex{\filename,\fileversion,\filedate,\let}
+% \DoNotIndex{\@listctr,\@nameuse,\csname,\else,\endcsname,\expandafter}
+% \DoNotIndex{\gdef,\global,\if,\item,\newcommand,\nobibliography}
+% \DoNotIndex{\par,\providecommand,\relax,\renewcommand,\renewenvironment}
+% \DoNotIndex{\stepcounter,\usecounter,\nocite,\fi}
+% \DoNotIndex{\@fileswfalse,\@gobble,\@ifstar,\@unexpandable@protect}
+% \DoNotIndex{\AtBeginDocument,\AtEndDocument,\begingroup,\endgroup}
+% \DoNotIndex{\frenchspacing,\MessageBreak,\newif,\PackageWarningNoLine}
+% \DoNotIndex{\protect,\string,\xdef,\ifx,\texttt,\@biblabel,\bibitem}
+% \DoNotIndex{\z@,\wd,\wheremsg,\vrule,\voidb@x,\verb,\bibitem}
+% \DoNotIndex{\FrameCommand,\MakeFramed,\FrameRestore,\hskip,\hfil,\hfill,\hsize,\hspace,\hss,\hbox,\hb@xt@,\endMakeFramed,\escapechar}
+% \DoNotIndex{\do,\date,\if@tempswa,\@tempdima,\@tempboxa,\@tempswatrue,\@tempswafalse,\ifdefined,\ifhmode,\ifmmode,\cr}
+% \DoNotIndex{\box,\author,\advance,\multiply,\Command,\outer,\next,\leavevmode,\kern,\title,\toks@,\trcg@where,\tt}
+% \DoNotIndex{\the,\width,\star,\space,\section,\subsection,\textasteriskcentered,\textwidth}
+% \DoNotIndex{\",\:,\@empty,\@for,\@gtempa,\@latex@error,\@namedef,\@nameuse,\@tempa,\@testopt,\@width,\\,\m@ne,\makeatletter,\makeatother}
+% \DoNotIndex{\maketitle,\parindent,\setbox,\x,\kernel@ifnextchar}
+% \DoNotIndex{\un,\deux,\xx,\tt,\title,\times,\texttt,\tableofcontents,\&,\@preline,\@redef,\\,\`,\|,\ ,\author}
+% \DoNotIndex{\bfseries,\clearpage,\cmd,\csvloopTest,\defineparser,\endinput,\expandnextTest}
+% \DoNotIndex{\fancyhf,\fancyhead,\FE@testoptTest,\FE@ifstarTest,\get@params,\goodbreak,\hypersetup,\iffirstcharTest,\ifsinglecharTest}
+% \DoNotIndex{\llap,\rlap,\longrightarrow,\make@macro,\makequotes,\MakeShortVerb,\mdseries,\multicolumn,\mylist}
+% \DoNotIndex{\nobreak,\noindent,\null,\OPTmacro,\notstarred,\pagestyle,\preline,\quad,\result,\smex,\starmacro,\starred,\strip@macro}
+% \DoNotIndex{\strip@macroprefix,\strip@meaning,\strip@prefix,\sty,\subsubsection,\subtitle,\test}
+% \DoNotIndex{\testcsvloop,\testexpandnext,\testFE@testopt,\testFE@ifstar,\testgetlistitem,\testiffirstchar,\testifsinglechar,\getlistitemTest}
+% \DoNotIndex{\textbf,\textcolor,\vskip,\long,\hrulefill,\&,\@get@params,\geometry,\edef,\BySeven,\optmacro,\@xifblank,\ettl@onlyonce,\ettl@undefined,\usercmd,\noexpand}
+% \DoNotIndex{\@listedel,\@listgdel,\@listxdel}
+%
% \makeatletter
% \def\thispackage{\sty{\thisfile}}
% \font\ding=dingbat scaled 800
+% \hypersetup{hyperindex=true}
% \fancyhf{}\fancyhead[L]{The \sty{etextools} package -- an \eTeX\, package for \LaTeX}
% \fancyfoot[L]{\color[gray]{.35}\scriptsize\thispackage\quad\copyright\,\lower.3ex\hbox{\NibRight}\,Florent Chervet}
% \fancyfoot[R]{\oldstylenums{\thepage} / \oldstylenums{\pageref{LastPage}}}
% \pagestyle{fancy}
+% \fancypagestyle{plain}{%
+% \fancyhf{}\let\headrulewidth\z@
+% \fancyfoot[R]{\oldstylenums{\thepage} / \oldstylenums{\pageref{LastPage}}}}
% \def\CTAN#1{\href{http://www.ctan.org/tex-archive/#1}{\nolinkurl{CTAN:#1}}}
% \definecolor{spot}{rgb}{.7,0.1,0.2}
% \newcommand\fecccolor{\color{fecc}}\definecolor{fecc}{rgb}{.2,.6,.2}
@@ -145,22 +198,34 @@ and etextools-examples.tex
% \catcode`\§\active\def§{\par\nobreak\vskip-\parskip}
% \renewcommand\partformat{}\let\thepart\partformat\renewcommand\raggedpart{\centering}
% \newcommand\cmdref[1]{\hyperref[#1]{\underline{\sty{\reflinkcolor\textbackslash #1}}}}
-% \newcommand\cmdlabel[1]{\label{#1}}
-% \def\FE{\setbox8\hbox{$\m@th\bindnasrepma$}%
-% \marginpar{\fecccolor\scalebox{2}{$\copy8\mkern-13.5mu\copy8\mkern-13.5mu\copy8$}}\space}
+% \newcommand\cmdlabel[1]{\label{#1}\hyperdef{cmdlabel}{#1}{}}
+% \newcommand\seeimpl[1]{%
+% \ifblank{#1}{\colorbox{yellow}{\textcolor{red}{\LARGE\Laserbeam}}}
+% {\hfill \hyperref{}{cmdlabel}{impl:#1}{\colorbox{yellow}{\textcolor{red}{\LARGE\Laserbeam}}}}}
+% \newsavebox\seedescbox
+% \setbox\seedescbox\hbox{\rlap{\kern.4em\colorbox{green}{\textcolor{red}{\SunshineOpenCircled}}}}
+% \newcommand\seedesc[1]{%
+% \ifblank{#1}{\copy\seedescbox}
+% {\vadjust{\vskip-1.5\ht\seedescbox\hfill
+% \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\smex{\leavevmode\hb@xt@2em{\hfil\spotcolor$\longrightarrow$\hfil}}
% \font\manual=manfnt\def\dbend{\marginpar{\manual\char127}\space}
% \parindent\z@\topsep\z@\partopsep\z@\parskip.3\baselineskip
+% \cftbeforesecskip=4pt
+% \cftbeforepartskip=11pt
+% \let\footnoterule\relax
% \lastlinefit999
% \makeatother
%
-% \thispagestyle{plain}\printtitlepage
+% \thispagestyle{plain}\printtitlepage\medskip
% \fontfamily{ua1}\selectfont
-% \tableofcontents\vfil
+% \tableofcontents\medskip\enlargethispage{\baselineskip}\thispagestyle{plain}
%
% \begin{shaded}\parindent0pt\noindent\large
%
-% {\bfseries\catcode`\ \active\let =\,\hfil \* A b s t r a c t \*\hfil}\par
+% {\bfseries\catcode`\ \active\let =\,\hfil\NibSolidRight A b s t r a c t \NibSolidLeft\hfil}\par
%
% The \sty{etextools} package is based on the \sty{etex} and \sty{etoolbox}
% packages and defines more tools for \LaTeX\ Users or package Writers.
@@ -173,15 +238,15 @@ and etextools-examples.tex
%
% The main contributions of this package are :
% \begin{itemize}
-% \item the \cmdref{expandnext} macro;
+% \item the \cmdref{expandnext} macro and the \cmdref{ifempty} macro
% \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};
+% -- 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};
+% -- see \cmdref{csvloop} and \cmdref{listloop}
% \item three macros that are lacking from the \sty{etoolbox} package for removing elements from lists :
-% \cmdref{listdel} and \cmdref{listgdel}, \cmdref{listxdel};
+% \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
-% the item at a given position in a list: \cmdref{getlistitem};
+% the item at a given position in a list: \cmdref{getlistitem}
%
% \end{itemize}
%
@@ -198,7 +263,358 @@ and etextools-examples.tex
%
% \section{Introduction}
%
-% \subsection{Identification}
+% \subsection{Motivation}
+%
+% The first motivation for this package was to define a list-parser macro:
+% \begin{itemize}
+% \item just like the \cs{docsvlist} and \cs{dolistloop} macros from \sty{etoolbox}
+% \item fully expandable (\ie in an |\edef|)
+% \item that take the auxiliary command(s) (\cs{do} in \sty{etextools}) as an optional argument.
+% \end{itemize}
+%
+% As a result, a method for defining fully expandable macros with optional parameter is built here.
+%
+% \subsection{Purely Expandable macros}
+%
+% The \FE fully expandable (or purely expandable) commands defined in this package
+% can be easily spotted with the special marker displayed here in the margin for information.
+% \medskip
+%
+% Go directly to the implementation of a\marginpar{\llap{\seeimpl{}\hskip-1.5em}} command by clicking
+% on the symbol displayed here in the margin for information.
+% \medskip
+%
+% Now from the implementation, \marginpar{\llap{\seedesc{}\kern4pt}} you can return to the description
+% section just by clicking on the symbol displayed here in the margin for information.
+%
+% \subsection{The example file}
+%
+% The example file provided with \thispackage\ illustrates the macros defined here.
+%
+% \subsection{Requirements}
+%
+% This package requires the packages \sty{etex} package by David Carlisle and
+% \sty{etoolbox} by Philipp Lehman.
+%
+% \subsection{Acknowledgements -- Thank You !}
+%
+% Thanks to Philipp Lehman for the \sty{etoolbox} package (and also for this nice class of documentation).
+% Much of my work on lists are based on his work and package.
+%
+% \clearpage
+% \part*{All User Commands}
+% \addtocontents{toc}{\protect\contentsline{part}{All User Commands}{}{}}
+%
+% \section{Expansion control}
+%
+% \begin{ltxsyntax}
+%
+% \cmditem{expandnext}{cstoken}{first parameter of cstoken} \cmdlabel{expandnext} \seeimpl{expandnext}
+%
+% We\FE often want a control sequence to be expanded after its first argument. For example, if you
+% want to test if a command |\foo| has a blank replacement text you will say:
+%
+% \qquad |\expandafter\ifblank\expandafter{\foo}{|\prm{true part}|}{|\prm{false part}|}|
+%
+% With |\expandnext| you'll just have to say:
+%
+% \qquad |\expandnext\ifblank{\foo}{|\prm{true part}|}{|\prm{false part}|}|
+%
+% Now observe the following game :
+% \begin{tabbing}
+% \qquad\= |\def\foo{foo}| \qquad \= \smex \qquad \= |\def\Foo{\foo}| \quad \= \eol \\
+% \> |\def\\FOo{\Foo}| \> \smex \> |\def\FOO{\FOo}| \> \eol \\
+% \> |\def\fool{\FOO}|
+% \end{tabbing}
+% Guess how many \cmd{expandafter} are needed to test ``|\ifblank{foo}|'' directly from |\fool| ???
+%
+% |\expandnext| solves this problem : |\fool| has 5 degrees of expansion until it expands to ``foo'', therefore exactly 5
+% |\expandnext| are required. The solution is:
+%
+% \qquad |\expandnext\expandnext\expandnext\expandnext\expandnext\ifblank{\fool}|
+%
+% Other example: suppose you want to define a macro |\detokenizecs{|\prm{csname}|}| that expands to the detokenized content
+% of |\csname |\prm{csname}|\endcsname|. Without |\expandnext| you will have to say:
+% \begin{tabbing}
+% \qquad\= |\expandafter\expandafter\expandafter\detokenize| \\
+% \> |\expandafter\expandafter\expandafter{\csname |\prm{csname}|\endcsname}|
+% \end{tabbing}
+% \textbf{six} \cmd{expandafter}(s). With |\expandnext| you just have to say:§
+% \qquad|\expandnext\expandnext\detokenize{\csname #1\endcsname}|
+%
+% \cmditem{noexpandcs}{csname} \cmdlabel{noexpandcs}\seeimpl{noexpandcs}
+%
+% In an \FE expansion context (|\edef|) we often want a control sequence whose name results
+% from the expansion of some macros and/or other tokens to be created, but not expanded at that point.
+% Roughly:§
+% \qquad |\edef{\noexpandcs{<balanced text to be expanded as a cs-name>}}|§
+% will expand to: |\"cs-name"| but this (new) control sequence itself will not be expanded.
+% A typical use is shown in the following code:§
+% \smex |\edef\abc{\noexpandcs{abc@\@gobblescape\controlword}}|§
+% \smex if equivalent to:\quad|\def\abc{\abc@controlword}|.
+%
+% {\rmk|\noexpandcs| may be abbreviated f.ex. in |\`#1`| in |\edef| that take place in a group. }
+%
+% \cmditem{noexpandafter}\cmdlabel{noexpandafter}\seeimpl{noexpandafter}
+%
+% |\noexpandafter|\FE only means |\noexpand\expandafter| and is shorter to type.
+%
+% {\rmk This command is used in the definition of \cmdref{DeclareCmdListParser}.}
+%
+% \end{ltxsyntax}
+%
+% \clearpage
+% \section{Characters and Strings}
+%
+% \begin{ltxsyntax}
+%
+% \cmditem{ifempty}{string}{true}{false} \cmdlabel{ifempty} \seeimpl{ifempty}
+%
+% |\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|:
+% \begin{tabbing}
+% \quad\=|\expandnext\ifempty{\macro}| \prm{true}\prm{false}
+% \end{tabbing}
+%
+%
+% \cmditem{deblank}{string} \cmdlabel{deblank} \seeimpl{deblank}
+%
+% |\deblank|\FE removes all leading and trailing blank spaces from its argument.\medbreak
+%
+% \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{xifstrequal}{string1}{string2}{true}{false}\cmdlabel{xifstrequal}\seeimpl{xifstrequal}
+%
+% |\xifstrequal| is similar to |\ifstrequal| but each \prm{string} argument
+% is expanded with |\protected@edef| before comparison.\medbreak
+%
+% \cmditem{iffirstchar}{string1}{string2}{true}{false} \cmdlabel{iffirstchar}\seeimpl{iffirstchar}
+% \cmditem*{iffirstchar}{}{string}{true}{false}
+%
+% |\iffirstchar| \FE compares the character codes of the \textbf{first} characters of each \prm{string}. The
+% comparison is \emph{catcode agnostic} and the macro is fully expandable. Neither \prm{string1} nor \prm{string2}
+% is expanded before comparison. Example:§
+% \qquad|\iffirstchar *{*hello*}{begins with a star}{begins with something else}|
+%
+% 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}
+%\qquad\= |\iffirstchar \@backslashchar{|\prm{string}|}|\qquad\= or even easier:\\
+% \>|\iffirstchar {}{|\prm{string}|}|
+% \end{tabbing}
+%
+% Please note that the tests:
+% \begin{tabbing}
+% \qquad\qquad\=|\iffirstchar |\=|{|\prm{whatever string1 is}|}{}|\\
+% and:\>|\iffirstchar |\>|{}{}|
+% \end{tabbing}
+% are \textbf{always expanded into \underline{\prm{false}}}
+% (for consistency with the shortcut-test for |\@backslashchar|).\medbreak
+%
+% \cmditem{ifsinglechar}{string1}{string2}{true}{false} \cmdlabel{ifsinglechar}\seeimpl{ifsinglechar}
+%
+% |\ifsinglechar|\FE performs the test |\iffirstchar| but only if \prm{string2} has one single character.
+%
+% 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:
+% \begin{tabbing}
+% \qquad\= |\def\MacroWithOption#1{\ifsing|\=|lechar|\=|[{#1}| \\
+% \>\>|{\MacroHasOption[}| \\
+% \>\>|{\MacroNoOption{#1}}}}|\\
+% \> |\def\MacroHasOption[#1]#2|... \>\textit{definition} \\
+% \> |\def\MacroNoOption#1|...\>\textit{definition}
+% \end{tabbing}
+%
+% \clearpage
+% Moreover (in the style of |\@testopt|):
+% \begin{tabbing}
+% \qquad\= |\def\MacroWithOption#1{\ifsing|\=|lechar|\=|[{#1}|\\
+% \>\>|{\MacroHasOption#1}|\\
+% \>\>|{\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}
+%
+% |\FE@testopt|\FE mimics the behaviour of |\@testopt| but is Fully Expandable (\sty{FE}) and can be used as follow:§
+% \qquad |\def\MacroWithOption#1{\FE@testopt{#1}\MacroHasOption{default}}|\par
+%
+% Note that |\MacroWithOption| \textbf{must have at least one mandatory argument.}\medbreak
+%
+% {\rmk |\FE@testopt| is used in the definition of \cmdref{DeclareCmdListParser}.}
+%
+% \cmditem{FE@ifstar}{argument to be tested}{star-commands}{non-star commands} \cmdlabel{FE@ifstar}\seeimpl{FE@ifstar}
+%
+% Similarly,\FE it becomes possible to mimic the behaviour of |\@ifstar| but in a fully expandable(\sty{FE}) way.
+% |\FE@ifstar| can be used as follow :§
+% \begin{tabbing}
+% \qquad\= |\def\StarOrNotCommand#1{\FE@|\=|ifstar|\=|{#1}|\\
+% \>\>|{\StarredCommand}|\\
+% \>\>|{\NotStarredCommand}}|
+% \end{tabbing}
+%
+% 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}.}
+%
+% \end{ltxsyntax}
+%
+% \section{Lists management}
+%
+% \subsection{The Command-List Parser}
+%
+% The \sty{etoolbox} package provides a way to define list parsers a fully expandable macros:
+% the list parser is able to expand the auxiliary command |\do| on each item of a list.
+% \iffalse
+% Declaration of a list parser is done via the |\DeclareListParser| macro\footnotemark.
+% \footnotetext{besides, \sty{etoolbox} defines the \sty{\textbackslash docsvlist} and the
+% \sty{\textbackslash dolistloop} macros: the choice of this name is not very friendly
+% and we expected to have a \sty{\textbackslash docsvloop} macro instead...}.
+% \fi
+%
+% Here we provide a |\DeclareCmdListParser| macro that is compatible and slightly different, because the auxiliary
+% command is not necessarily |\do|. Such a command-list-parser is fully expandable.
+%
+% The idea is that if |\csvloop| has been defined as a command-parser then, thank to the fully expandable macro |\FE@testopt|
+% we can call for expansion:
+% \begin{tabbing}
+% \qquad\= |\csvloop*{item,item,...}|\,\= as a shortcut for\,\= |\csvloop*[\do]{item,...}|\\
+% or:\> |\csvloop*[\listadd\mylist]{item,item,...}|\quad
+% \end{tabbing}
+% for example to convert the csv-list into internal \sty{etoolbox} list.
+%
+% {\rmk The star-form of \cmdref{csvloop} will be explained below.}
+%
+% \begin{ltxsyntax}
+%
+% \cmditem{DeclareCmdListParser}{command}{separator}\cmdlabel{DeclareCmdListParser}\seeimpl{DeclareCmdListParser}
+%
+% |\DeclareCmdListParser| acts in the same way as \sty{etoolbox}-|\DeclareListParser| and the command-list-parser
+% are sensitive to the category code of the \prm{separator}
+% {\catcode`\ =13\let =-\it(which is not necessarily a single character and shall not be a {\tt\string&} with a catcode of 3)}.
+%
+% A Command-List-Parser is then defined as a purely expandable macro. It has a \textit{star form} for the case
+% of the list given is already expanded, and a \textit{normal form} if the list is given as a macro name.
+%
+% You may then use the following syntaxes:
+% \begin{tabbing}
+% \qquad\=|\CmdListParser\mylist| \\
+% \>|\CmdListParser*{item|\prm{sep}|item|\prm{sep}|item}| \\
+% \>|\CmdListParser[\Commands]\mylist| \\
+% or:\>|\CmdListParser*[\Commands]{item|\prm{sep}|item|\prm{sep}|item}|
+% \end{tabbing}
+%
+% \subsection{Loops into lists}
+%
+% Now we have to declare two command-list-parsers : |\listloop| for \sty{etoolbox} lists
+% and |\csvloop| for comma-separated lists.
+%
+% \cmditem{csvloop}[auxiliary commands]{csvlistmacro} \cmdlabel{csvloop}\seeimpl{csvloop}
+% \cmditem*{csvloop*}[auxiliary commands]{item,item,item,...}
+% \cmditem*{listloop}[auxiliary commands]{listmacro} \cmdlabel{listloop}
+% \cmditem*{listloop*}[auxiliary commands]{expanded list}
+%
+% |\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 :
+% \begin{tabbing}
+% \qquad\=|\listloop\mylist|\;\=\textit{is}\;\= |\listloop[\do]\mylist|\;\=\textit{and is also}\;\= |\dolistloop\mylist|\\
+% \> |\csvloop\csvlist|\> \textit{is}\> |\csvloop[\do]\csvlist|\> \textit{and is also}: \eol \\
+% \>\>\> |\expandafter\docsvlist\expandafter{\csvlist}|
+% \end{tabbing}
+%
+%
+% \subsection{Converting csv lists to \sty{etoolbox}-lists}
+%
+% \cmditem{csvtolist}{listmacro}{csvlistmacro} \cmdlabel{csvtolist}\seeimpl{csvtolist}
+% \cmditem*{csvtolist*}{listmacro}{item,item,item...}
+%
+% |\csvtolist| converts a comma separated list into an internal \sty{etoolbox} list. It is useful to insert more than one item
+% at a time in a list. Those macros are not fully expandable because of the redefinition of \prm{listmacro} done by |\listadd|...
+%
+% It's also the first application of the \cmdref{csvloop} macro just defined.
+%
+%
+% \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|:
+%
+%
+% \subsection{Removing elements from \sty{etoolbox}-lists}
+%
+% The \sty{etoolbox} package provides |\listadd|, |\listgadd| and |\listxadd| commands
+% to add items to a list. However, no command is designed to remove an element from a
+% list.
+%
+%
+% \cmditem{listdel}{listmacro}{item} \cmdlabel{listdel}\seeimpl{listdel}
+% \cmditem*{listgdel}{listmacro}{item} \cmdlabel{listgdel}
+% \cmditem*{listedel}{listmacro}{item} \cmdlabel{listedel}
+% \cmditem*{listxdel}{listmacro}{item} \cmdlabel{listxdel}
+%
+% The |\listdel| command removes the element \prm{item} from the list \prm{listmacro}. Note that the
+% \prm{listmacro} is redefined after deletion:
+%
+% 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|:
+%
+%
+% \subsection{Index of an element in a list}
+%
+%
+% \cmditem{getlistindex}{item}{listmacro} \cmdlabel{getlistindex}\seeimpl{getlistindex}
+% \cmditem*{xgetlistindex}{item}{listmacro} \cmdlabel{xgetlistindex}
+% \cmditem*{getlistindex*}{item}{list}
+% \cmditem*{xgetlistindex*}{item}{list}
+%
+% 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|.
+% \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.
+% \end{itemize}
+%
+% As for the command-list-parser, the star versions are designed in case the list (in the second argument) is already expanded.
+%
+%
+% \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]}
+%
+% 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
+% fully expandable version of |\ifstar| : \cmdref{FE@ifstar} to keep the ``fully-expand-ability'' of the star-form as well:
+% \begin{itemize}
+% \item \ If the \prm{index} is in the range $[1\dots n]$ then the macro expands to \prm{item}$_n$
+% \item \ If the \prm{index} is non positive or $>n$ then the macro expands to nothing (|{}|).
+% \end{itemize}
+%
+% \end{ltxsyntax}
+%
+% \StopEventually{
+% }
+%
+% \part*{\LaTeX{} code}
+% \addtocontents{toc}{\protect\contentsline{part}{\large\LaTeX{} code}{}{}}
+%
+% \section{Implementation}
+%
+% \subsection{Package identification}
%
% \begin{macrocode}
%<*package>
@@ -210,8 +626,8 @@ and etextools-examples.tex
%
% \subsection{Requirements}
%
-% This package requires both the \sty{etex} package by David Carlisle and
-% the \sty{etoolbox} package by Philipp Lehman.
+% This package requires the packages \sty{etex} package by David Carlisle and
+% \sty{etoolbox} by Philipp Lehman.
%
% \begin{macrocode}
\RequirePackage{etex,etoolbox}
@@ -226,40 +642,12 @@ and etextools-examples.tex
\catcode`\ =10
% \end{macrocode}
%
-% \subsection{Acknowledgements -- Thank You !}
-%
-% Thanks to Philipp Lehman for the \sty{etoolbox} package (and also for this nice class of documentation).
-% Much of my work on lists are based on his work and package.
-%
-% Thank to Heiko Oberdiek who has done so much for the \TeX\ and \LaTeX\ community, and allows me to
-% produce a package in one only \sty{.dtx} file.
-%
-% \subsection{Hint for the reader}
-%
-% Every command provided in this \sty{etextools} package are fully expandable
-% unless explicitly specified. As it (one of) the philosophy of \sty{etoolbox}
-% to make the most of its commands fully expandable (and this is very useful for package
-% writing and/or document-style programming) the \FE fully expandable commands
-% have a special sign in the margin (displayed here for information).
-%
-% Remain what a control sequence, a control word and a control character are...
-%
-% \iffalse The commands have been (extensively, more or less) tested.\fi
-%
-%
-% \part*{User commands}
-% \addtocontents{toc}{\protect\contentsline{part}{\large User commands}{}{}}
-%
-% \section{A few (\texorpdfstring{\oldstylenums{7}}{7}) ``helper'' macros}
-%
-% \begin{ltxsyntax}
-%
-% \cmditem{ettl@afterelse} \cmdlabel{ettl@afterelse}
-% \cmditem*{ettl@afterfi} \cmdlabel{ettl@afterfi}\hfil\par
-%
-% Those two commands\FE are the copies of |\bbl@afterelse| and |\bbl@afterfi| from the \sty{babel} package.
-% They allow to get out of |\if|...|\fi| conditionals.
+% \subsection{A few (7) ``helper'' macros}
%
+% \iffalse
+%<package>
+%<package>% A few helper macros
+% \fi
% \begin{macrocode}
\long\def\ettl@afterelse#1\else#2\fi{\fi#1}
\long\def\ettl@afterfi#1\fi{\fi#1}
@@ -267,20 +655,34 @@ and etextools-examples.tex
\long\def\ettl@afterelsefi#1\else#2\fi\fi{\fi#1}
% \end{macrocode}
%
-% {\rmk Those commands are used in \cmdref{iffirstchar} and \cmdref{expandnext} }
+% \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
%
-% \cmditem*{@gobblescape}\hfil\par
+% \begin{macro}{\@gobblescape}
%
-% This sequence\FE of command is very often used, even in \sty{latex.ltx}. So
+% This sequence of command is very often used, even in \sty{latex.ltx}. So
% it appears to be better to put it in a macro. It's aim is to reverse the
% mechanism of |\csname|...|\endcsname|:
% \begin{macrocode}
\newcommand*\@gobblescape{\expandafter\@gobble\string}
% \end{macrocode}
+% {\rmk May be we could do better, testing first if the next token is a control sequence...}
+% \end{macro}
+%
%
-% \cmditem{str@gobblescape}{string}\hfil\par
+% \begin{macro}{\str@gobblescape}
%
-% With \FE \eTeX\space |\detokenize| it is now possible to invoke a |\string| on an arbitrary
+% 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
@@ -290,165 +692,108 @@ and etextools-examples.tex
\newcommand\str@gobblescape[1]{\expandafter\deblank\expandafter{%
\expandafter\@gobble\detokenize{#1}}}
% \end{macrocode}
+% \end{macro}
%
-% The \cmdref{deblank} command will be desbribed later.
%
-% \end{ltxsyntax}
-%
-% \section{Expansion control}
+% \subsection{Expansion control}
%
-% NOTA BENE: Pay attention\dbend that the expansion control macros are not \emph{primitives}!
-% Therefore:
-% \begin{tabbing}
-% \qquad\= |\expandafter\controlsequence\noexpandcs{|\prm{csname}|}|\\
-% \> |\expandafter\controlsequence\expandonce{|\prm{command}|}|
-% \end{tabbing}
-% etc. etc. may not lead to the result you expected.
-% The |\expandonce| macro from \sty{etoolbox} worth the same warning.
-%
-% For expansion control, it's better to use primitives, unless you clearly knows what
-% you do and what will happen... \textbf{In particular,\dbend you'd very better avoid to use
-% expansion control macros at the very beginning of the definition of a command, for if this command
-% is preceded (in the user's code) by \sty{\textbackslash expandafter}, you will be lead
-% to undesirable result and most probably to an error !}
-
-% \begin{ltxsyntax}
-%
-% \cmditem{noexpandcs}{csname}
-%
-% In an \FE expansion context (|\edef|) we often want a control sequence whose name results
-% from the expansion of some macros and/or other tokens to be created, but not expanded at that point.
-% Roughly:§
-% \qquad |\edef{\noexpandcs{<balanced text to be expanded as a cs-name>}}|§
-% will expand to: |\"cs-name"| but this (new) control sequence itself will not be expanded.
-% A typical use is shown in the following code:§
-% \smex |\edef\abc{\noexpandcs{abc@\@gobblescape\controlword}}|§
-% \smex if equivalent to:\quad|\def\abc{\abc@controlword}|.
%
+% \begin{macro}{\noexpandcs}\cmdlabel{impl:noexpandcs}
+% {\rmk|\noexpandcs| may be abbreviated f.ex. in |\`#1`| or |\"#1"| in |\edef| that take place in a group.}\seedesc{noexpandcs}
% \begin{macrocode}
\newcommand*\noexpandcs[1]{\expandafter\noexpand\csname #1\endcsname}
% \end{macrocode}
+% \end{macro}
%
-% {\rmk|\noexpandcs| can be abbreviated in |\`#1`| in |\edef| that take place in a group. }
-%
-% \cmditem{noexpandafter}\hfil\par
-%
-% |\noexpandafter|\FE only means |\noexpand\expandafter| and is shorter to type.
-%
+% \begin{macro}{\noexpandafter}\cmdlabel{impl:noexpandafter}
+% {\rmk \cmd{noexpandafter} only means \cmd{noexpand}\cmd{expandafter} and is shorter to type.}\seedesc{noexpandafter}
% \begin{macrocode}
\newcommand\noexpandafter{\noexpand\expandafter}
% \end{macrocode}
%
-% {\rmk This command is used in the definition of \cmdref{DeclareCmdListParser}.}
-% \iffalse
-% \cmditem{afterexpandafter}
-%
-% |\afterexpandafter|\FE means to delay the expansion twice :§
-% \qquad |\afterexpandafter\a\expandafter\b\c|\quad will replace |\c| by its \prm{replacement text}, then
-% expand place |\b| before and replace it by its \prm{replacement text} as well, eventually consuming its
-% parameters, and after that, place |\a| before the whole thing; then expansion goes further.
-%
-% \begin{macrocode}
-% \newcommand\afterexpandafter{\expandafter\expandafter\expandafter}
-% \end{macrocode}
-% \fi
-%
-% \cmditem{expandnext}{cstoken}{first parameter of cstoken} \cmdlabel{expandnext}
-%
-% We\FE often want a control sequence to be expanded after its first argument. For example, if we want to test if a command
-% |\foo| has a blank replacement text we will type :
-%
-% \qquad |\expandafter\ifblank\expandafter{\foo}|
-%
-% Now suppose you wish to define a macro |\detokenizecs{|\prm{csname}|}| that expands to the detokenized content
-% of |\csname |\prm{csname}|\endcsname|. Without |\expandnext| you will have to say:
-% \begin{tabbing}
-% \qquad\= |\expandafter\expandafter\expandafter\detokenize| \\
-% \> |\expandafter\expandafter\expandafter{\csname |\prm{csname}|\endcsname}|
-% \end{tabbing}
-% \textbf{six} \cmd{expandafter}(s). With |\expandnext| you will just have to say:§
-% \qquad|\expandnext\expandnext\detokenize{\csname #1\endcsname}|
-%
-% Now observe the following game :
-% \begin{tabbing}
-% \qquad\= |\def\foo{foo}| \qquad \= \smex \qquad \= |\def\Foo{\foo}| \quad \= \eol \\
-% \> |\def\\FOo{\Foo}| \> \smex \> |\def\FOO{\FOo}| \> \eol \\
-% \> |\def\FOOL{\FOO}|
-% \end{tabbing}
-% And {\bfseries guess how many \cmd{expandafter} you will need in order to test ``|\ifblank{foo}|'' directly from |\FOOL| ??? }
+% \end{macro}
%
-% |\expandnext| solves this problem : |\FOOL| has 5 degrees of expansion until it expands to ``foo'', so one require exactly 5
-% |\expandnext| : the solution is :
+% \begin{macro}{\expandnext}\cmdlabel{impl:expandnext}
%
-% \qquad |\expandnext\expandnext\expandnext\expandnext\expandnext\ifblank{\FOOL}|
+% This code is not properly \seedesc{expandnext} tricky but if you're eager to understand the job of each expandafter,
+% it's best to go straight at the log.
%
-% And now : if you define, say : |\csdef{bloody fool}{\FOO}| you just require 2 more |\expandnext| in order
-% to test ``foo'' from ``|\csname bloody fool\endcsname|'' ! \emph{just test it!}
+% Note that the first argument of |\expandnext| must be a single \prm{cstoken} (for \cmd{expandafter} acts
+% only on the first following token).
%
+% \iffalse
+%<package>
+%<package>% \expandnext : expansion control
+%<package>% level 1 : \expandnext#1{...} <=> \expandafter#1\expandafter{...}
+%<package>% level 2 : \expandnext\expandnext#1{...} etc.
+% \fi
% \begin{macrocode}
\newcommand\expandnext[2]{%
\ifx#1\expandnext
\ettl@afterelse\expandafter\expandafter\expandafter
- \expandafter\@expandnext{#2}{\expandafter\expandafter\expandafter}
- \else\ettl@afterfi\expandafter#1\expandafter{#2}
+ \expandafter\@expandnext{#2}{\expandafter\expandafter\expandafter}%
+ \else\ettl@afterfi\expandafter#1\expandafter{#2}%
\fi}
\long\def\@expandnext#1#2#3{%
\ifx#1\expandnext
\expandafter\ettl@afterelse\expandafter\expandafter\expandafter
- \expandafter\@expandnext{#3}{\expandafter#2#2}
+ \expandafter\@expandnext{#3}{\expandafter#2#2}%
\else
- \expandafter\ettl@afterfi#2#1#2{#3}
+ \expandafter\ettl@afterfi#2#1#2{#3}%
\fi}
% \end{macrocode}
+% \end{macro}
+% \iffalse
+%<package>
+% \fi
%
-% This code is not very tricky but difficult to explain. The better is to watch at the log if the reader is eager
-% to understand the job of each \cmd{expandafter}.
-%
-% Note that the first argument of |\expandnext| must be a single \prm{cstoken} (for \cmd{expandafter} acts
-% only on the first following token).
-%
-% \end{ltxsyntax}
-%
-% \section{String manipulation}
-%
-% \subsection{String trimming}
%
-% \begin{ltxsyntax}
+% \subsection{String manipulation}
%
-% \cmditem{deblank}{string} \cmdlabel{deblank}
+% \begin{macro}{\deblank} \cmdlabel{impl:deblank}
%
-% The macro \FE |\deblank| will remove the extra blank space inserted by |\detokenize| at the
-% very end of the \prm{string}. Actually, it removes all trailing spaces (charcode 32, catcode 10)
-% from its argument:
+% Note that the leading spaces \seedesc{deblank}are automatically removed by \TeX's mastication mechanism.
%
% \begin{macrocode}
\newcommand\deblank{}
-\begingroup\catcode`\&=3% a & as a math shift
-\long\gdef\deblank#1{\@deblank#1 &}
-\long\gdef\@deblank#1 #2&{\ifblank{#2}{#1}{#1\@deblank#2 &}}
-\endgroup
+\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 |}}
+% \end{macrocode}
+% \end{macro}
+%
+% \iffalse
+%<package>
+%<package>% \ifempty{ text }{ true }{ false }
+% \fi
+% \begin{macro}{\ifempty} \cmdlabel{impl:ifempty}
+% |\ifempty| is amazing because the code is so concise!\seedesc{ifempty}
+% \begin{macrocode}
+\long\gdef\ifempty#1{\csname @\ifx|#1|first\else second\fi oftwo\endcsname}
+\endgroup% catcode group
% \end{macrocode}
+% \end{macro}
+% \iffalse
+%<package>
+% \fi
%
-% Note, by the way, that the leading spaces are also removed by \TeX's mastication mechanism.
% \goodbreak
%
% \subsection{Expanded string comparison}
%
-% \cmditem{xifblank}{string}{true}{false}
-%
-% |\xifblank| is similar to |\ifblank| except that the \prm{string} is first expanded
-% with |\protected@edef|:
+% \begin{macro}{\xifblank}\cmdlabel{impl:xifblank}
+% Just expands the parameter using |\protected@edef| before testing for |\ifblank|: \seedesc{xifblank}
% \begin{macrocode}
\newrobustcmd\xifblank[1]{\begingroup
\protected@edef\@xifblank{\endgroup
\noexpand\ifblank{#1}%
}\@xifblank}
% \end{macrocode}
+% \end{macro}
%
-% \cmditem{xifstrequal}{string1}{string2}{true}{false}
-%
-% In the same way, |\xifstrequal| is similar to |\ifstrequal| but both \prm{string} arguments
-% are expanded with |\protected@edef| before comparison:
+% \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}%
@@ -456,30 +801,10 @@ and etextools-examples.tex
\else \aftergroup\@secondoftwo
\fi\endgroup}
% \end{macrocode}
+% \end{macro}
%
-% \subsection{Testing characters}
-%
-% \cmditem{iffirstchar}{string1}{string2}{true}{false} \cmdlabel{iffirstchar}
-% \cmditem*{iffirstchar}{}{string}{true}{false}
-%
-% |\iffirstchar| will\FE compare the character codes of the \textbf{first} characters of each \prm{string}. The
-% comparison is \emph{catcode agnostic} and the macro is fully expandable. Neither \prm{string1} not \prm{string2}
-% is expanded before comparison.
-%
-% There is a ``special'' use of this command when the user want to test if a \prm{string} begins
-% with an \emph{escape} character (\,\textbackslash\,) one may say:
-% \begin{tabbing}
-%\qquad\= |\iffirstchar \@backslashchar{|\prm{string}|}|\qquad\= or even easier:\\
-% \>|\iffirstchar {}{|\prm{string}|}|
-% \end{tabbing}
-% Please note that the tests:
-% \begin{tabbing}
-% \qquad\qquad\=|\iffirstchar |\=|{|\prm{whatever string1 is}|}{}|\\
-% and:\>|\iffirstchar |\>|{}{}|
-% \end{tabbing}
-% are \textbf{always expanded into \underline{\prm{false}}}
-% (for consistency with the shortcut-test for |\@backslashchar|):
-%
+% \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
@@ -487,21 +812,24 @@ and etextools-examples.tex
\else \expandafter\@secondoftwo
\fi}
% \end{macrocode}
+% \end{macro}
%
-%
-% \cmditem{ifsinglechar}{string1}{string2}{true}{false} \cmdlabel{ifsinglechar}
-%
-% |\ifsinglechar|\FE will perform the test |\iffirstchar| but will also check that \prm{string2} has only one character.
-%
+% \begin{macro}{\ifsinglechar}\cmdlabel{impl:ifsinglechar}
+% Test if |#2| is a single character equal to |#1|: \seedesc{ifsinglechar}
% \begin{macrocode}
-\newcommand\ifsinglechar[2]{%
+\newcommand\ifsinglechar{}
+\begingroup\catcode`\|=4
+\long\gdef\ifsinglechar#1#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}
- \expandnext\expandnext\ifblank{\expandafter\@cdr\string#2 \@nil}
+ \csname @\expandafter\expandafter\expandafter\ifx
+ \expandafter\expandafter\expandafter|%
+ \expandafter\ettl@cdr\string#2||first\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:
@@ -511,107 +839,51 @@ and etextools-examples.tex
% Otherwise, switch to \prm{false}
% \begin{macrocode}
\@secondoftwo}
+\endgroup% catcode group
% \end{macrocode}
% \end{codecomment}
+% \end{macro}
%
-% 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:
-% \begin{tabbing}
-% \qquad\= |\def\MacroWithOption#1{\ifsing|\=|lechar|\=|[{#1}| \\
-% \>\>|{\MacroHasOption[}| \\
-% \>\>|{\MacroNoOption{#1}}}}|\\
-% \> |\def\MacroHasOption[#1]#2|... \>\textit{definition} \\
-% \> |\def\MacroNoOption#1|...\>\textit{definition}
-% \end{tabbing}
-%
-% Moreover (in the style of |\@testopt|):
-% \begin{tabbing}
-% \qquad\= |\def\MacroWithOption#1{\ifsing|\=|lechar|\=|[{#1}|\\
-% \>\>|{\MacroHasOption#1}|\\
-% \>\>|{\MacroHasOption[default]{#1}}}|
-% \end{tabbing}
-%
-% Therefore, the following macro is defined:
-%
-% \subsection{Fully expandable macros with options}
-%
-% \cmditem{FE@testopt}{argument to be tested}{commands}{default option} \cmdlabel{FE@testopt}
-%
-% |\FE@testopt| mimics the behaviour of |\@testopt| but is Fully Expandable (\sty{FE})\FE and can be used as follow:§
-% \qquad |\def\MacroWithOption#1{\FE@testopt{#1}\MacroHasOption{default}}|\par
-%
-% Remember that |\MacroWithOption| \textbf{must have at least one mandatory argument.}
-%
+% \iffalse
+%<package>
+%<package>%\FE@testopt{#1}{commands}{default option}
+% \fi
+% \begin{macro}{\FE@testopt}\cmdlabel{impl:FE@testopt}
+% Fully expandable |\@testopt|-like test:\seedesc{FE@testopt}
% \begin{macrocode}
\newcommand\FE@testopt[3]{\ifsinglechar [{#1}{#2#1}{#2[{#3}]{#1}}}
% \end{macrocode}
%
-% \textbf{Limitation :}\dbend if you call such an option command without option and with |{[}| as mandatory
-% argument, it will be considered that the command has an option, whose end will be at the next `\,]\,' found in the input string.
-%
-% {\rmk |\FE@testopt| is used in the definition of \cmdref{DeclareCmdListParser}.}
-%
-% \cmditem{FE@ifstar}{argument to be tested}{star-commands}{non-star commands} \cmdlabel{FE@ifstar}
-%
-% Similarly,\FE it becomes possible to mimic the behaviour of |\@ifstar| but in a fully expandable(\sty{FE}) way.
-% |\FE@ifstar| can be used as follow :§
-% \begin{tabbing}
-% \qquad\= |\def\StarOrNotCommand#1{\FE@|\=|ifstar|\=|{#1}|\\
-% \>\>|{\StarredCommand}|\\
-% \>\>|{\NotStarredCommand}}|
-% \end{tabbing}
-%
-% Remember that |\StarredCommand| and |\NotStarredCommand| \textbf{must have at least one mandatory argument.}
+% \end{macro}
%
+% \iffalse
+%<package>
+%<package>%\FE@ifstar{#1}{\StarredMacro}{\NotStarredMacro}
+% \fi
+% \begin{macro}{\FE@ifstar}\cmdlabel{impl:FE@ifstar}
+% Fully expandable |\@ifstar|-like test:\seedesc{FE@ifstar}
% \begin{macrocode}
\newcommand\FE@ifstar[3]{\ifsinglechar *{#1}{#2}{#3{#1}}}
% \end{macrocode}
%
-% \textbf{Limitation :}\dbend if you call such a command with |{*}| as mandatory argument,
-% it will be considered that the command is starred, and the mandatory argument will be found next inside the input string.
-%
-% \textbf{This ``limitation'' is in fact a benediction:} thank to it we can have
-% {\it\catcode`\ \active\let =-Fully Expandable starred macros with option\/}!\nobreak
-% {\rmk |\FE@ifstar| is used in the definitions of \cmdref{DeclareCmdListParser}, \cmdref{csvloop}, \cmdref{listloop}
-% and \cmdref{csvtolist}.}
-% \goodbreak
-% \end{ltxsyntax}
-%
-% \section{List management}
-%
-% \subsection{The Command-List Parser}
-%
-% The \sty{etoolbox} package provides a way to define list parsers a fully expandable macros:
-% the list parser is able to expand the auxiliary command |\do| on each item of a list.
+% \end{macro}
% \iffalse
-% Declaration of a list parser is done via the |\DeclareListParser| macro\footnotemark.
-% \footnotetext{besides, \sty{etoolbox} defines the \sty{\textbackslash docsvlist} and the
-% \sty{\textbackslash dolistloop} macros: the choice of this name is not very friendly
-% and we expected to have a \sty{\textbackslash docsvloop} macro instead...}.
+%<package>
% \fi
%
-% Here we provide a |\DeclareCmdListParser| macro that is compatible and slightly different, because the auxiliary
-% command is not necessarily |\do|. Such a command-list-parser is fully expandable.
-%
-% The idea is that if |\csvloop| has been defined as a command-parser then, thank to the fully expandable macro |\FE@testopt|
-% we can call for expansion:
-% \begin{tabbing}
-% \qquad\= |\csvloop*{item,item,...}|\,\= as a shortcut for\,\= |\csvloop*[\do]{item,...}|\\
-% or:\> |\csvloop*[\listadd\mylist]{item,item,...}|\quad
-% \end{tabbing}
-% for example to convert the csv-list into internal \sty{etoolbox} list.
-%
-% {\rmk The star-form of \cmdref{csvloop} will be explained below.}
-%
-% \begin{ltxsyntax}
+% \goodbreak
%
-% \cmditem{DeclareCmdListParser}{command}{separator} \cmdlabel{DeclareCmdListParser}
+% \begin{macro}{\DeclareCmdListParser}\cmdlabel{impl:DeclareCmdListParser}
%
-% |\DeclareCmdListParser| acts in the same way as \sty{etoolbox}-|\DeclareListParser| and the command-list-parser
+% |\DeclareCmdListParser|\seedesc{DeclareCmdListParser} acts in the same way as
+% \sty{etoolbox}-|\DeclareListParser| and the command-list-parser
% are sensitive to the category code of the \prm{separator}
-% {\catcode`\ =13\let =-\it(which is not necessarily a single character and shall not be a {\tt\&} with a catcode of 3)}.
%
+%% \iffalse
+%<package>
+%<package>% \DeclareCmdListParser : general constructor for command-list parsers
+%<package>% \DeclareCmdListParser\ParserName{separator}
+% \fi
% \begin{codecomment}
% The command-list-parser will be defined only if it is definable:
%
@@ -625,7 +897,7 @@ and etextools-examples.tex
% and globally define the macro inside a purposeful group:
%
% \begin{macrocode}
-\begingroup\catcode`\&=3
+\begingroup\catcode`\&=3\catcode`\`=3
\gdef\etextools@defcmdparser#1#2{%
\begingroup
\def\`##1`{\expandafter\noexpand\csname ##1\endcsname}%
@@ -697,97 +969,88 @@ and etextools-examples.tex
\endgroup
% \end{macrocode}
% \end{codecomment}
+% \end{macro}
+% \iffalse
+%<package>
+%<package>
+%<package>% \csvloop[\command]\csvListMacro
+%<package>% \csvloop*[\command]{item,item,item}
+% \fi
%
-% \subsection{Loops into lists}
-%
-% Now we have to declare two command-list-parsers : |\listloop| for \sty{etoolbox} lists
-% and |\csvloop| for comma-separated lists.
-%
-% \cmditem{csvloop}[auxiliary commands]{csvlistmacro} \cmdlabel{csvloop}
-% \cmditem*{csvloop*}[auxiliary commands]{item,item,item,...}
-% \cmditem*{listloop}[auxiliary commands]{listmacro} \cmdlabel{listloop}
-% \cmditem*{listloop*}[auxiliary commands]{expanded list}
-%
-% |\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 :
-% \begin{tabbing}
-% \qquad\=|\listloop\mylist|\;\=\textit{is}\;\= |\listloop[\do]\mylist|\;\=\textit{and is also}\;\= |\dolistloop\mylist|\\
-% \> |\csvloop\csvlist|\> \textit{is}\> |\csvloop[\do]\csvlist|\> \textit{and is also}: \eol \\
-% \>\>\> |\expandafter\docsvlist\expandafter{\csvlist}|
-% \end{tabbing}
-% Definition of |\csvloop| :
+% \begin{macro}{\csvloop}\cmdlabel{impl:csvloop}
+% Definition of |\csvloop|:\seedesc{csvloop}
% \begin{macrocode}
\DeclareCmdListParser\csvloop{,}
% \end{macrocode}
+% \end{macro}
%
% \begin{codecomment}
% Definition of |\listloop| (with a `\,\textbar\,' of catcode 3 -- cf.\sty{etoolbox}):
% \begin{macrocode}
\begingroup\catcode`\|=3
- \gdef\do{\DeclareCmdListParser\listloop{|}\undef\do}\aftergroup\do
-\endgroup
+ \def\do{\DeclareCmdListParser\listloop{|}}%
+\expandafter\endgroup\do
% \end{macrocode}
% \end{codecomment}
%
-% \subsection{Converting csv lists to \sty{etoolbox}-lists}
-%
-% \cmditem{csvtolist}{listmacro}{csvlistmacro} \cmdlabel{csvtolist}
-% \cmditem*{csvtolist*}{listmacro}{item,item,item...}
-%
-% |\csvtolist| converts a comma separated list into an internal \sty{etoolbox} list. It is useful to insert more than one item
-% at a time in a list. Those macros are not fully expandable because of the redefinition of \prm{listmacro} done by |\listadd|...
-%
-% It's also the first application of the \cmdref{csvloop} macro just defined:
%
+% \iffalse
+%<package>
+%<package>%\csvtolist\csvListMacro
+%<package>%\csvtolist*{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}}]}
+\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}}]}%
% \end{macrocode}
+% \end{macro}
%
-% \cmditem{csvtolistadd}{listmacro}{csvlistmacro} \cmdlabel{csvtolistadd}
-% \cmditem*{csvtolistadd*}{listmacro}{item,item,item...}
-%
-% |\csvtolistadd| acts similarly but does not reset the \prm{listmacro} to |\@empty|:
-%
+% \iffalse
+%<package>
+%<package>%\csvtolistadd\csvListMacro
+%<package>%\csvtolistadd*{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}
+\newcommand\csvtolistadd{\@ifstar\star@csvtolistadd\nost@csvtolistadd}%
\def\star@csvtolistadd#1#2{\ifblank{#2}
- {\let#1\@empty}{\csvloop*[{\unexpanded{\listadd#1}}]{#2}}}
+ {\let#1\@empty}{\csvloop*[{\unexpanded{\listadd#1}}]{#2}}}%
\def\nost@csvtolistadd#1#2{\ifblank{#2}
- {\let#1\@empty}{\csvloop[{\unexpanded{\listadd#1}}]{#2}}}
+ {\let#1\@empty}{\csvloop[{\unexpanded{\listadd#1}}]{#2}}}%
% \end{macrocode}
+% \end{macro}
%
-% \end{ltxsyntax}
-%
-% \subsection{Removing elements from \sty{etoolbox}-lists}
-%
-% The \sty{etoolbox} package provides |\listadd|, |\listgadd| and |\listxadd| commands
-% to add items to a list. However, no command is designed to remove an element from a
-% list.
-%
-% \begin{ltxsyntax}
-%
-% \cmditem{listdel}{listmacro}{item} \cmdlabel{listdel}
-% \cmditem*{listgdel}{listmacro}{item} \cmdlabel{listgdel}
-% \cmditem*{listxdel}{listmacro}{item} \cmdlabel{listxdel}
-%
-% The |\listdel| command removes the element \prm{item} from the list \prm{listmacro}. Note that the
-% \prm{listmacro} is redefined after deletion:
%
+% \iffalse
+%<package>
+%<package>%\listdel\listMacro{item}
+%<package>%\listgdel\listMacro{item}
+%<package>%\listedel\listMacro{item}
+%<package>%\listxdel\listMacro{item}
+% \fi
+% \begin{macro}{\listdel}\cmdlabel{impl:listdel}
+% |\listdel| removes an item from a list:\seedesc{listdel}
% \begin{macrocode}
-\newrobustcmd\listdel[2]{\@listdel\def{#1}{#2}}
+\newrobustcmd\listdel[2]{\@listdel\def{#1}{#2}}%
% \end{macrocode}
+% \end{macro}
%
-% 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|:
%
% \begin{macrocode}
-\newrobustcmd\listgdel[2]{\@listdel\gdef{#2}{#2}}
+\newrobustcmd\listgdel[2]{\@listdel\gdef{#1}{#2}}%
\newrobustcmd\listxdel[2]{\begingroup
\protected@edef\@listxdel{\endgroup
- \unexpanded{\@listdel\gdef#1}{#2}%
- }\@listxdel}
+ \unexpanded{\@listdel\gdef{#1}}{#2}%
+ }\@listxdel}%
+\newrobustcmd\listedel[2]{\begingroup
+ \protected@edef\@listedel{\endgroup
+ \unexpanded{\@listdel\def{#1}}{#2}%
+ }\@listedel}
% \end{macrocode}
%
% \begin{codecomment}
@@ -795,18 +1058,19 @@ and etextools-examples.tex
% We need first to be placed in an environment where the `\,\textbar\,' delimiter has a category code of 3
% (cf \sty{etoolbox}-lists definitions):
% \begin{macrocode}
- \begingroup\catcode`\|=3\catcode`\&=3
+\begingroup\catcode`\|=3\catcode`\&=3
% \end{macrocode}
% Inside this ``catcode-group'' the definition of |\@listdel| ought to be global:
% \begin{macrocode}
- \long\gdef\@listdel#1#2#3{%
+\long\gdef\@listdel#1#2#3{%
% \end{macrocode}
% \qquad |#1|=|\def| or |\gdef|, |#2|=\prm{listmacro}, |#3|=\prm{item} to remove.\par
% In order to preserve the hash-table from temporary definitions, a group is opened:
% \begin{macrocode}
- \begingroup
+\begingroup
\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
% and it adds |\@tempb| after the result. If the \prm{item} was not in the list, then |##2|
% will be empty. Note that |\@tempa| is the only macro whose definition depends on the \prm{item}
@@ -841,7 +1105,7 @@ and etextools-examples.tex
% \begin{macrocode}
\expandafter\@tempx\unexpanded\expandafter{#2}&}%
% \end{macrocode}
-% Then just expand |\@redef| (fully expandable):
+% Then just expand |\@redef| to proceed the redefinition of \prm{listmacro}:
% \begin{macrocode}
}\@redef}% end of \@listdel
% \end{macrocode}
@@ -850,43 +1114,28 @@ and etextools-examples.tex
\endgroup
% \end{macrocode}
% \end{codecomment}
-% \end{ltxsyntax}
%
-% \subsection{Index of an element in a list}
+%\iffalse
+%<package>
+%<package>
+%<package>% \getlistindex (result in \indexinlist)
+% \fi
%
-% \begin{ltxsyntax}
%
-% \cmditem{getlistindex}{item}{listmacro} \cmdlabel{getlistindex}
-% \cmditem*{xgetlistindex}{item}{listmacro} \cmdlabel{xgetlistindex}
-% \cmditem*{getlistindex*}{item}{list}
-% \cmditem*{xgetlistindex*}{item}{list}
-%
-% 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|.
-% \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.
-% \end{itemize}
+% \begin{macro}{\getlistindex}\cmdlabel{impl:getlistindex}
+% \cmd{getlistindex} may be defined, with its star form (no expansion of the list)\seedesc{getlistindex}
+% and normal form (\prm{listmacro} expanded once);
+% The search-index is initialised at 1:
%
-% As for the command-list-parser, the star versions are designed in case the list (in the second argument) is already expanded.
-% \begin{codecomment}
% We first need to get into a group where delimiter `\,\textbar\,' and `\,\&\,' have catcode 3:
% \begin{macrocode}
\begingroup\catcode`\|=3\catcode`\&=3
-% \end{macrocode}
-% The next two macros expands 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}
-% \end{macrocode}
-% |\getlistindex| may be defined, with its star form (no expansion of the list) and normal form (\prm{listmacro} expanded once);
-% The search-index is initialised at 1:
-% \begin{macrocode}
\gdef\getlistindex#1{\FE@ifstar{#1}{\ettl@getlistindex{}}
{\ettl@getlistindex\expandnext}}
% \@ifstar{\ettl@getlistindex{}}{\ettl@getlistindex{\expandnext}}}
% \end{macrocode}
+% \end{macro}
+%
% |\xgetlistindex| is similar with prior expansion of \prm{item}:
% \begin{macrocode}
\gdef\xgetlistindex#1{\FE@ifstar{#1}{\ettl@xgetlistindex{}}
@@ -895,7 +1144,9 @@ and etextools-examples.tex
\protected@edef\next{\endgroup\unexpanded{\ettl@getlistindex{#1}{#2}}{#3}%
}\next}
% \end{macrocode}
+%
% Then the following macro does the job in a loop, which is not fully expandable because the use of |\ifstrequal|:
+%
% \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
@@ -903,26 +1154,20 @@ and etextools-examples.tex
{\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}}}}
+% \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}
+\gdef\ettl@list@first@item#1|#2&{#1}
+\gdef\ettl@list@other@item#1|#2&{#2}
\endgroup% catcode group
% \end{macrocode}
% \end{codecomment}
-% \end{ltxsyntax}
%
-% \subsection{Extract by index from a list}
-%
-% \begin{ltxsyntax}
-%
-% \cmditem{getlistitem}{listmacro}{index [numexpr expression]} \cmdlabel{getlistitem}
-% \cmditem*{getlistitem*}{list}{index}
-%
-% 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
-% fully expandable version of |\ifstar| : \cmdref{FE@ifstar} to keep the ``fully-expand-ability'' of the star-form as well:
-% \begin{itemize}
-% \item \ If the \prm{index} is in the range $[1\dots n]$ then the macro expands to \prm{item}$_n$
-% \item \ If the \prm{index} is non positive or $>n$ then the macro expands to nothing (|{}|).
-% \end{itemize}
%
+% \begin{macro}{\getlistitem}\cmdlabel{impl:getlistitem}
+% \strut\seedesc{getlistitem}
% \begin{macrocode}
\newcommand\getlistitem[1]{\FE@ifstar{#1}\ettl@getlistitem
{\expandnext\ettl@getlistitem}}
@@ -938,6 +1183,7 @@ and etextools-examples.tex
\fi\fi}}
\endgroup
% \end{macrocode}
+% \end{macro}
%
% \end{ltxsyntax}
%
@@ -945,7 +1191,7 @@ and etextools-examples.tex
%</package>
% \end{macrocode}
%
-% \section{Example}
+% \subsection{Example}
%
% \begin{macrocode}
%<*example>
@@ -998,6 +1244,21 @@ and etextools-examples.tex
\section{\cmd{expandnext} examples}
+\subsection{Test if the replacement text of macro is really empty}
+
+\def\xx{ }
+\def\testexpandnext{%
+ \edef\expandnextTest{\string\xx\ is \expandnext\ifempty{\xx}{}{not} empty}
+}
+\preline\xx
+\test{expandnext}
+
+\def\xx{}
+\preline\xx
+\test{expandnext}
+
+
+\clearpage
\subsection{Test if the replacement text of a macro is blank (empty or spaces)}
\def\xx{something}
@@ -1011,7 +1272,8 @@ and etextools-examples.tex
\preline\xx
\test{expandnext}
-\clearpage
+
+
\subsection{Detokenize the replacement text of a named-sequence}
\def\detokenizecs#1{\expandnext\expandnext\detokenize{\csname #1\endcsname}}
\def\testexpandnext{%
@@ -1027,6 +1289,17 @@ and etextools-examples.tex
}\hrulefill\par
\test{ifsinglechar}
+\def\testifsinglechar{%
+ \edef\ifsinglecharTest{\ifsinglechar *{ *}{ single star }{ something else }}
+}\hrulefill\par
+\test{ifsinglechar}
+
+\def\testifsinglechar{%
+ \edef\ifsinglecharTest{\ifsinglechar *{ * }{ single star }{ something else }}
+}\hrulefill\par
+\test{ifsinglechar}
+{\small Note the space \textbf{after} the star $\uparrow$.}
+
\def\testiffirstchar{%
\edef\iffirstcharTest{\iffirstchar *{*hello*}{ first char is star }{ something else }}
}\hrulefill\par
@@ -1034,8 +1307,8 @@ and etextools-examples.tex
\subsection{Fully Expandable starred macros}
\def\starmacro#1{\FE@ifstar{#1}\starred\notstarred}
-\def\starred#1{your "#1" will be processed by the STAR form}
-\def\notstarred#1{your "#1" will be processed by the NORMAL form}
+\def\starred#1{your "#1" will be processed by the STAR form}
+\def\notstarred#1{your "#1" will be processed by the NORMAL form}
\def\testFE@ifstar{%
\edef\FE@ifstarTest{\starmacro{sample text}}}
\preline\starmacro
@@ -1083,7 +1356,7 @@ and etextools-examples.tex
\preline\mylist
\preline*\BySeven
\test{csvloop}
-\subsubsection{protected \cmd{testbf}}
+\subsubsection{protected \cmd{textbf}}
\def\testcsvloop{%
\protected@edef\csvloopTest{\csvloop*[\textbf]{hello ,my ,friends}}
}\hrulefill\par
@@ -1101,29 +1374,55 @@ and etextools-examples.tex
\getlistindex{four}\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}{four}\cmd{mylist}}\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
\end{document}
%</example>
% \end{macrocode}
%
+% \section{Revision history}
+%
+% \begin{changelog}
+%
+% \begin{release}{2z}{2009-08-12}
+% \item Addition of \cmdref{ifempty}
+%
+% \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 \\
+% \>\>because of the spaces following the |*| \\
+% \>\> however, the spaces \textbf{before} are skipped, \\
+% \>\>as does |\@ifnextchar| from the \LaTeX{} kernel.
+% \end{tabbing}
+%
+% \item Index added to this documentation paper.
+% \end{release}
+
+% \begin{release}{2e}{2009-07-14}
+% \item First version (include an example file)
+% \end{release}
+%
+% \end{changelog}
+%
% \begin{thebibliography}{9}
%
% \bibitem{etex}
% David Carlisle and Peter Breitenlohner
% \textit{The \sty{etex} package};
% 1998/03/26 v2.0;
-% \CTAN{macros/latex/contrib/etex-pkg/etex.sty}.
+% \CTAN{macros/latex/contrib/etex-pkg/}.
%
% \bibitem{etoolbox}
% Philipp Lehman
% \textit{The \sty{etoolbox} package};
% 2008/06/28 v1.7;
-% \CTAN{macros/latex/contrib/etoolbox/etoolbox.dtx}.
+% \CTAN{macros/latex/contrib/etoolbox/}.
%
% \end{thebibliography}
%
+% \setcounter{IndexColumns}{2}\clearpage
% \PrintIndex
%
% \label{LastPage}
diff --git a/Master/texmf-dist/source/latex/etextools/etextools.ins b/Master/texmf-dist/source/latex/etextools/etextools.ins
index 79b0985e6af..ca83a61febb 100644
--- a/Master/texmf-dist/source/latex/etextools/etextools.ins
+++ b/Master/texmf-dist/source/latex/etextools/etextools.ins
@@ -22,7 +22,6 @@
%% and etextools-examples.tex
%%
%%% etextools : more e-TeX useful tools for LaTeX package writers
-%%% Florent CHERVET
\input docstrip.tex
\Msg{************************************************************************}
\Msg{* Installation}
@@ -76,6 +75,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 0a2382ba988..e11696396a5 100644
--- a/Master/texmf-dist/tex/latex/etextools/etextools.sty
+++ b/Master/texmf-dist/tex/latex/etextools/etextools.sty
@@ -22,7 +22,6 @@
%% and etextools-examples.tex
%%
%%% etextools : more e-TeX useful tools for LaTeX package writers
-%%% Florent CHERVET
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
\ProvidesPackage{etextools}
[2009/07/14 v2e e-TeX more useful tools for LaTeX package writers]
@@ -32,34 +31,49 @@
\AtEndOfPackage{\ettl@restore@space@catcode
\let\ettl@restore@space@catcode\ettl@undefined}
\catcode`\ =10
+
+% 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
+
\newcommand*\@gobblescape{\expandafter\@gobble\string}
\newcommand\str@gobblescape[1]{\expandafter\deblank\expandafter{%
\expandafter\@gobble\detokenize{#1}}}
-
\newcommand*\noexpandcs[1]{\expandafter\noexpand\csname #1\endcsname}
\newcommand\noexpandafter{\noexpand\expandafter}
+
+% \expandnext : expansion control
+% level 1 : \expandnext#1{...} <=> \expandafter#1\expandafter{...}
+% level 2 : \expandnext\expandnext#1{...} etc.
\newcommand\expandnext[2]{%
\ifx#1\expandnext
\ettl@afterelse\expandafter\expandafter\expandafter
- \expandafter\@expandnext{#2}{\expandafter\expandafter\expandafter}
- \else\ettl@afterfi\expandafter#1\expandafter{#2}
+ \expandafter\@expandnext{#2}{\expandafter\expandafter\expandafter}%
+ \else\ettl@afterfi\expandafter#1\expandafter{#2}%
\fi}
\long\def\@expandnext#1#2#3{%
\ifx#1\expandnext
\expandafter\ettl@afterelse\expandafter\expandafter\expandafter
- \expandafter\@expandnext{#3}{\expandafter#2#2}
+ \expandafter\@expandnext{#3}{\expandafter#2#2}%
\else
- \expandafter\ettl@afterfi#2#1#2{#3}
+ \expandafter\ettl@afterfi#2#1#2{#3}%
\fi}
+
\newcommand\deblank{}
-\begingroup\catcode`\&=3% a & as a math shift
-\long\gdef\deblank#1{\@deblank#1 &}
-\long\gdef\@deblank#1 #2&{\ifblank{#2}{#1}{#1\@deblank#2 &}}
-\endgroup
+\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
+
\newrobustcmd\xifblank[1]{\begingroup
\protected@edef\@xifblank{\endgroup
\noexpand\ifblank{#1}%
@@ -74,16 +88,31 @@
\ettl@afterelse\ifblank{#2}\@secondoftwo\@firstoftwo
\else \expandafter\@secondoftwo
\fi}
-\newcommand\ifsinglechar[2]{%
- \expandnext\expandnext\ifblank{\expandafter\@cdr\string#2 \@nil}
+\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}
\newcommand\FE@testopt[3]{\ifsinglechar [{#1}{#2#1}{#2[{#3}]{#1}}}
+
+%\FE@ifstar{#1}{\StarredMacro}{\NotStarredMacro}
\newcommand\FE@ifstar[3]{\ifsinglechar *{#1}{#2}{#3{#1}}}
+
+%% \iffalse
+
+% \DeclareCmdListParser : general constructor for command-list parsers
+% \DeclareCmdListParser\ParserName{separator}
\newrobustcmd*\DeclareCmdListParser[2]{%
\@ifdefinable#1
{\expandafter\etextools@defcmdparser\expandafter{#1}{#2}}}
-\begingroup\catcode`\&=3
+\begingroup\catcode`\&=3\catcode`\`=3
\gdef\etextools@defcmdparser#1#2{%
\begingroup
\def\`##1`{\expandafter\noexpand\csname ##1\endcsname}%
@@ -112,27 +141,46 @@
\long\gdef\ettl@lst@doitem#1#2{#1{#2}}%
\long\gdef\ettl@listbreak#1&{}%
\endgroup
+
+
+% \csvloop[\command]\csvListMacro
+% \csvloop*[\command]{item,item,item}
\DeclareCmdListParser\csvloop{,}
\begingroup\catcode`\|=3
- \gdef\do{\DeclareCmdListParser\listloop{|}\undef\do}\aftergroup\do
-\endgroup
-\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}}]}
-\newcommand\csvtolistadd{\@ifstar\star@csvtolistadd\nost@csvtolistadd}
+ \def\do{\DeclareCmdListParser\listloop{|}}%
+\expandafter\endgroup\do
+
+%\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}}]}%
+
+%\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}}}
+ {\let#1\@empty}{\csvloop*[{\unexpanded{\listadd#1}}]{#2}}}%
\def\nost@csvtolistadd#1#2{\ifblank{#2}
- {\let#1\@empty}{\csvloop[{\unexpanded{\listadd#1}}]{#2}}}
-\newrobustcmd\listdel[2]{\@listdel\def{#1}{#2}}
-\newrobustcmd\listgdel[2]{\@listdel\gdef{#2}{#2}}
+ {\let#1\@empty}{\csvloop[{\unexpanded{\listadd#1}}]{#2}}}%
+
+%\listdel\listMacro{item}
+%\listgdel\listMacro{item}
+%\listedel\listMacro{item}
+%\listxdel\listMacro{item}
+\newrobustcmd\listdel[2]{\@listdel\def{#1}{#2}}%
+\newrobustcmd\listgdel[2]{\@listdel\gdef{#1}{#2}}%
\newrobustcmd\listxdel[2]{\begingroup
\protected@edef\@listxdel{\endgroup
- \unexpanded{\@listdel\gdef#1}{#2}%
- }\@listxdel}
- \begingroup\catcode`\|=3\catcode`\&=3
- \long\gdef\@listdel#1#2#3{%
- \begingroup
+ \unexpanded{\@listdel\gdef{#1}}{#2}%
+ }\@listxdel}%
+\newrobustcmd\listedel[2]{\begingroup
+ \protected@edef\@listedel{\endgroup
+ \unexpanded{\@listdel\def{#1}}{#2}%
+ }\@listedel}
+\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{%
\ifblank{##2}{\unexpanded{##1}}
@@ -143,9 +191,10 @@
\expandafter\@tempx\unexpanded\expandafter{#2}&}%
}\@redef}% end of \@listdel
\endgroup
+
+
+% \getlistindex (result in \indexinlist)
\begingroup\catcode`\|=3\catcode`\&=3
-\gdef\ettl@list@first@item#1|#2&{#1}
-\gdef\ettl@list@other@item#1|#2&{#2}
\gdef\getlistindex#1{\FE@ifstar{#1}{\ettl@getlistindex{}}
{\ettl@getlistindex\expandnext}}
\gdef\xgetlistindex#1{\FE@ifstar{#1}{\ettl@xgetlistindex{}}
@@ -159,6 +208,8 @@
{\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}
\endgroup% catcode group
\newcommand\getlistitem[1]{\FE@ifstar{#1}\ettl@getlistitem
{\expandnext\ettl@getlistitem}}
@@ -174,6 +225,7 @@
\fi\fi}}
\endgroup
+
\endinput
%%
%% End of file `etextools.sty'.