summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/etextools
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-09-24 00:09:27 +0000
committerKarl Berry <karl@freefriends.org>2009-09-24 00:09:27 +0000
commit3f39a4fbdf08fa724e5047b82e3437ddf9b83bf4 (patch)
treeee6cb8c37626cf0b68201a5cb9da34a62fa2b326 /Master/texmf-dist/tex/latex/etextools
parentaf45cd2890473eac240e9e1aa27996cdbcf16192 (diff)
etextools update (23sep09)
git-svn-id: svn://tug.org/texlive/trunk@15437 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/etextools')
-rw-r--r--Master/texmf-dist/tex/latex/etextools/etextools.sty1260
1 files changed, 938 insertions, 322 deletions
diff --git a/Master/texmf-dist/tex/latex/etextools/etextools.sty b/Master/texmf-dist/tex/latex/etextools/etextools.sty
index 791e2fd2c1c..35f78a71ff1 100644
--- a/Master/texmf-dist/tex/latex/etextools/etextools.sty
+++ b/Master/texmf-dist/tex/latex/etextools/etextools.sty
@@ -21,13 +21,12 @@
%% etextools.sty, etextools.pdf, etextools.ins,
%% and etextools-examples.tex
%%
-%%% etextools : more e-TeX useful tools for LaTeX package writers (v.
-
+%%% etextools : e-TeX tools for LaTeX Users and package Writers (v.3.0)
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
\ProvidesPackage{etextools}
- [2009/08/14 v2h e-TeX more useful tools for LaTeX package writers]
+ [2009/08/27 v3.0 e-TeX more useful tools for LaTeX package writers]
\csname ettl@onlyonce\endcsname\let\ettl@onlyonce\endinput
-\RequirePackage{etex,etoolbox}
+\RequirePackage{etex,etoolbox,letltxmacro}
\let\ettl@AtEnd\@empty
\def\TMP@EnsureCode#1#2{%
\edef\ettl@AtEnd{%
@@ -36,376 +35,993 @@
}%
\catcode#1 #2\relax
}
-\TMP@EnsureCode{32}{10}% space
+\TMP@EnsureCode{32}{10}% space... just in case
+\TMP@EnsureCode{47}{8}% /
+\TMP@EnsureCode{167}{7}% §
+\TMP@EnsureCode{164}{7}% ¤
+\TMP@EnsureCode{42}{12}% *
+\TMP@EnsureCode{43}{12}% +
+\TMP@EnsureCode{45}{12}% -
+\TMP@EnsureCode{46}{12}% .
+\TMP@EnsureCode{60}{12}% <
+\TMP@EnsureCode{61}{12}% =
+\TMP@EnsureCode{62}{12}% >
+\TMP@EnsureCode{33}{12}% !
+\TMP@EnsureCode{152}{13}% ~ for the character test
\ifundef\pdfstrcmp{%
- \TMP@EnsureCode{33}{9}% ! ignore
- \TMP@EnsureCode{34}{14}% " comment
-}{\TMP@EnsureCode{33}{14}% ! comment
- \TMP@EnsureCode{34}{9}% " ignore
+ \TMP@EnsureCode{163}{9}% £ ignore
+ \TMP@EnsureCode{128}{14}% \texteuro comment €
+}{\TMP@EnsureCode{163}{14}% £ comment
+ \TMP@EnsureCode{128}{9}% \texteuro 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}
-\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}
-\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}
+\let\ettl@ifdefined\iffalse%\ifdefined% turn to \iffalse to test other implementation on pdfTeX
+\long\def\ettl@fi#1\fi{\fi#1}
+\long\def\ettl@else#1\else#2\fi{\fi#1}
+\long\def\ettl@or#1\or#2\fi{\fi#1}
+\def\ettl@expandaftwo{\expandafter\expandafter\expandafter}
+\def\ettl@expandafthree{\expandafter\expandafter\expandafter%
+ \expandafter\expandafter\expandafter\expandafter}
+\cslet{ettl@1of1}\@firstofone %% for internal use only
+\cslet{ettl@1of2}\@firstoftwo %% for internal use only
+\cslet{ettl@2of2}\@secondoftwo %% for internal use only
+\long\def\rmn@firstoftwo#1#2{\z@#1} %% for romannumeral
+\long\def\rmn@secondoftwo#1#2{\z@#2}%% for romannumeral
+\long\def\ettl@cdr#1#2\@nil{#2} %% \@cdr should be a LONG macro
+\long\def\ettl@car#1#2\@nil{#1} %% \@car should be a LONG macro
+\long\csdef{ettl@1of3}#1#2#3{#1}
+\long\csdef{ettl@2of3}#1#2#3{#2}
+\long\csdef{ettl@3of3}#1#2#3{#3}
+\long\csdef{ettl@12of3}#1#2#3{{#1}{#2}}
+\long\def\ettl@carcar#1#2#3#4{#4}
+\long\def\ettl@firstspace#1#2#3{\expandafter\ettl@firstsp@ce\detokenize{#1} \\{#3}{#2}//}
+\long\def\ettl@firstsp@ce#1 #2\\{\ettl@nbk#1//}
+\long\def\ettl@csname#1\endcsname{\fi\endcsname}%% useful to get out of \if
+\long\def\ettl@char#1{\csname ettl@\if\relax\expandafter\ettl@cdr\detokenize{#1}\@nil\relax
+ 1\else2\fi of2\endcsname}
+\providecommand*\@intmax{2147483647}
+\def\ettl@intmax{2147483647}
+
+%% \ettl@onlypdfTeX for internal use
+\def\ettl@onlypdfTeX#1#2{\@testopt{\ettl@only@pdfTeX{#1}{#2}}{}}
+\def\ettl@only@pdfTeX#1#2[#3]{\ifundef{#1}
+ {\ifblank{#3}
+ {\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)}}}
+ {\AtEndOfPackage{\let#2=#3}%
+ \PackageWarning{etextools}{\string#1\space primitive not found\MessageBreak
+ Macro \string#2\space has been replaced by \string#3\space\MessageBreak
+ It is not purely expandable}}
+ }\relax}
+
+%% \ettl@nbk argument to be tested//{ true }{ false }//
+% `/` has a catcode of 3 all along this package
+\long\def\ettl@nbk #1#2/#3#4#5//{#4}
+\long\def\ettl@nbk@else#1#2/#3#4#5//#6\else#7\fi{\fi#4}
+\long\def\ettl@ney#1//#2#3//{\romannumeral 0\csname @%
+ \if\relax\detokenize{#1}\relax first\else second\fi oftwo\endcsname
+ { #2}{ #3}}
+
+% The following macros are not used (here just for memory, in case of...)
+\long\def\ettl@nbk@cat#1#2#3/#4#5#6//{\ettl@nbk#6//%
+ {\ifcat#1#2\ettl@else#5\else\ettl@fi#6\fi}{#5}//}
+\long\def\ettl@nbk@ifx#1#2#3/#4#5#6//{\ettl@nbk#6//%
+ {\ifx#1#2\ettl@else#5\else\ettl@fi#6\fi}{#5}//}
+\long\def\ettl@nbk@if#1#2#3/#4#5#6//%
+ {\ettl@nbk#6//{\if#1#2\ettl@else#5\else\ettl@fi#6\fi}{#5}//}
+\long\def\ettl@nbk@IF[#1]#2#3#4/#5#6#7//{\ettl@nbk#7//%
+ {\csname if#1\endcsname\ettl@else#6\else\ettl@fi#7\fi}{#6}//}
+
+%% \@gobblespace and The Space Token
+\long\def\@gobblespace#1 {#1}
-% \expandnext : expansion control
-% level 1 : \expandnext#1{...} <=> \expandafter#1\expandafter{...}
-% level 2 : \expandnext\expandnext#1{...} etc.
+%% \@gobblescape \cs-token
+\newcommand*\@gobblescape{\romannumeral0\expandafter\@gobble\string}
+
+% The swap macros
+\newcommand\@swap[2]{#2#1}
+\@swap{ }{\let\ettl@sptoken= }% This makes \ettl@sptoken a space token
+\newcommand\@swaparg[2]{#2{#1}}
+\newcommand\@swaplast[3]{#1#3#2}
+\newcommand\@swaptwo[2]{{#2}{#1}}
+
+%% \expandaftercmds : expansion control
+% level 1 : \expandaftercmds { code }{ cs-token }
+% level 2 : \expandaftercmds\expandaftercmds { code }{ cs-token }
+\newcommand\expandaftercmds[2]{%
+ \ifsingletoken\expandaftercmds{#1}
+ {\expandafter@cmds{#2}{\expandafter\expandafter\expandafter}}
+ {\expandafter\@swap\expandafter{#2}{#1}}}
+\long\def\expandafter@cmds#1#2#3{%
+ \ifsingletoken\expandafter@cmds{#1}
+ {\expandafter@cmds{#3}{\expandafter#2#2}}
+ {\@swap#2{#3}{#1}}}
+
+%% \expandnext : expansion control
+% level 1 : \expandnext { code }{ control sequences : the first is expanded before code }
+% level 2 : \expandnext\expandnext{ code }{ control sequences }
\newcommand\expandnext[2]{%
- \ifx#1\expandnext
- \ettl@afterelse\expandafter\expandafter\expandafter
- \expandafter\@expandnext{#2}{\expandafter\expandafter\expandafter}%
- \else\ettl@afterfi\expandafter#1\expandafter{#2}%
- \fi}
+ \ifsingletoken\expandnext{#1}
+ {\@expandnext{#2}{\expandafter\expandafter\expandafter}}
+ {\expandafter\@swaparg\expandafter{#2}{#1}}}
\long\def\@expandnext#1#2#3{%
- \ifx#1\expandnext
- \expandafter\ettl@afterelse\expandafter\expandafter\expandafter
- \expandafter\@expandnext{#3}{\expandafter#2#2}%
- \else
- \expandafter\ettl@afterfi#2#1#2{#3}%
- \fi}
+ \ifsingletoken\expandnext{#1}
+ {\@expandnext{#3}{\expandafter#2#2}}
+ {#2\@swaparg#2{#3}{#1}}}
+%% \expandnexttwo{ code }{ control sequences }{ control sequences }
+\newcommand\expandnexttwo[3]{\expandnext{\expandnext{#1}{#2}}{#3}}
-% \ifempty{ text }{ true }{ false }
-\newcommand\ifempty[1]{\csname @\expandafter\ifx
- \expandafter\relax\detokenize{#1}\relax
+%% \ExpandAfter { code } { cs-token }
+\newcommand\ExpandAftercmds[2]{\expandafter\@swap\expandafter{\romannumeral-`\q#2}{#1}}
+
+%% \ExpandNext { code } { argument }
+ % I'm not sure it is interesting to use \expandnext here...
+ %\newcommand\ExpandNext[2]{\expandnext{#1}{\romannumeral-`\q#2}}
+\newcommand\ExpandNext[2]{\expandafter\@swaparg\expandafter{\romannumeral-`\q#2}{#1}}
+
+%% \ExpandNextTwo { code } { arg1 }{ arg2 }
+\newcommand\ExpandNextTwo[3]{\ExpandNext{\ExpandNext{#1}{#2}}{#3}}
+
+% noexpandcs { csname }
+\newcommand*\noexpandcs[1]{\expandafter\noexpand\csname #1\endcsname}
+
+% noexpandafter
+\newcommand*\noexpandafter{\noexpand\expandafter}
+
+%% \showcs { csname }
+\providecommand*\showcs[1]{\expandafter\show\csname#1\endcsname}
+
+%% \meaningcs { csname }
+\providecommand\meaningcs[1]{\romannumeral-`\q
+ \csname\ifcsdef{#1}{ettl@meaningcs\endcsname{#1}}
+ {meaning\endcsname\@undefined}}
+\def\ettl@meaningcs#1{\expandafter\meaning\csname#1\endcsname}% here we don't need \z@ to stop \romannumeral
+ % because \meaning is never blank nor begins with a space...
+
+%% \strip@meaning { cs-token }
+%% \strip@meaningcs { csname }
+\newcommand*\strip@meaning[1]{\romannumeral\csname\ifdef{#1}%
+ {\ifdefmacro{#1}{ettl@strip@meaning}{ettl@meaning}\endcsname#1}{z@\endcsname}}
+\providecommand*\strip@meaningcs[1]{\romannumeral\csname\ifcsdef{#1}%
+ {\ifcsmacro{#1}{ettl@strip@meaning}{ettl@meaning}%
+ \expandafter\endcsname\csname#1\endcsname}
+ {z@\endcsname}}
+\def\ettl@strip@meaning{\expandafter\expandafter\expandafter\z@% for \romannumeral in case the \meaning is blank...
+ \expandafter\strip@prefix\meaning}
+\def\ettl@meaning{\expandafter\z@\meaning}
+
+%% \parameters@meaning { cs-token }
+%% \parameters@meaningcs { csname }
+\providecommand*\parameters@meaning[1]{}
+\edef\parameters@meaning#1{\unexpanded{\romannumeral\expandafter
+ \expandafter\expandafter\z@\expandafter\ettl@params@meaning%
+ \meaning}#1\detokenize{macro:->}/}
+\providecommand*\parameters@meaningcs[1]{}
+\edef\parameters@meaningcs#1{\unexpanded{\romannumeral\ettl@expandafthree\z@
+ \expandafter\expandafter\expandafter\ettl@params@meaning%
+ \expandafter\meaning\csname}#1\endcsname\detokenize{macro:->}/}
+\edef\ettl@params@meaning{%
+ \def\noexpand\ettl@params@meaning\detokenize{macro:}##1\detokenize{->}##2/{##1}%
+}\ettl@params@meaning
+
+%% \ifdefcount { cs-token }{ true }{ false } \FEII
+%% \ifdefdimen { cs-token }{ true }{ false } \FEII
+%% \ifdeftoks { cs-token }{ true }{ false } \FEII
+%% \ifdefskip { cs-token }{ true }{ false } \FEII
+%% \ifdefmuskip { cs-token }{ true }{ false } \FEII
+%% \ifdefchar { cs-token }{ true }{ false } \FEII
+%% \ifdefmathchar { cs-token }{ true }{ false } \FEII
+\def\ettl@ifdef[#1]{\expandafter\ettl@ifd@f\expandafter{#1}}
+\def\ettl@ifd@f#1#2{%
+ \csdef{ettl@ifdef#2}##1#1##2/End§Meaning/{\ettl@nbk##2//{\rmn@firstoftwo}{\rmn@secondoftwo}//}
+ \csedef{ifdef#2}##1{\noexpand\romannumeral\noexpandafter%
+ \noexpandcs{ettl@ifdef#2}\noexpand\meaning##1#1/End§Meaning/}%//{##2}{##3}//}
+}
+\ettl@ifdef[\string\count]{count} % defines \def\ifdefcount
+\ettl@ifdef[\string\toks]{toks} % \def\ifdeftoks
+\ettl@ifdef[\string\dimen]{dimen} % \def\ifdefdimen
+\ettl@ifdef[\string\skip]{skip} % \def\ifdefskip
+\ettl@ifdef[\string\muskip]{muskip} % \def\ifdefmuskip
+\ettl@ifdef[\string\char]{char} % \def\ifdefchar
+\ettl@ifdef[\string\mathchar]{mathchar} % \def\ifdefmathchar
+\ettl@ifdef[\detokenize{blank space}]{blankspace}% \def\ifdefblankspace
+\ettl@ifdef[\detokenize{the character}]{thechar}% \def\ifdefthechar
+\ettl@ifdef[\detokenize{the letter}]{theletter} % \def\ifdeftheletter
+\undef\ettl@ifdef\undef\ettl@ifd@f
+
+%% \avoidvoid [ replacement code ]{ cs-token / string }
+%% \avoidvoid*[ replacement code ]{ cs-token / string }
+\newcommand\avoidvoid[1]{\romannumeral\FE@ifstar{#1}
+ {\ettl@voidvoid{\ettl@ifdefempty\ifempty}}
+ {\ettl@voidvoid{\ettl@ifdefvoid\ifblank}}}
+\long\def\ettl@voidvoid#1#2{\FE@testopt{#2}{\ettl@voidv@id#1}{}}
+\long\def\ettl@voidv@id#1#2[#3]#4{\ifiscs{#4}{#1{#4}}{#2{#4}}{\z@#3}{\z@#4}}
+\long\def\ettl@ifdefvoid#1{\csname @\ifx#1\relax first%
+ \else\expandafter\expandafter\expandafter\ettl@nbk\strip@meaning#1//{second}{first}//%
+ \fi oftwo\endcsname}
+\long\def\ettl@ifdefempty#1{\expandafter\expandafter\expandafter\ifempty%
+ \expandafter\expandafter\expandafter{\strip@meaning#1}}
+
+%% \avoidvoidcs [ replacement code ]{ cs-name }
+%% \avoidvoidcs*[ replacement code ]{ cs-name }
+\newcommand\avoidvoidcs[1]{\romannumeral\FE@ifstar{#1}
+ {\ettl@avoidvoidcs{\ettl@ifdefempty}}
+ {\ettl@avoidvoidcs{\ettl@ifdefvoid}}}
+\long\def\ettl@avoidvoidcs#1#2{\FE@testopt{#2}{\ettl@@voidvoidcs#1}{}}
+\long\def\ettl@@voidvoidcs#1[#2]#3{\csname @\ifcsname#3\endcsname
+ \expandafter#1\csname#3\endcsname{first}{second}\else first\fi
+ oftwo\endcsname{\z@#2}{\z@\csname#3\endcsname}}
+
+%% The ifx-test and the character-test
+\long\def\ettl@ifx#1#2#3#4{\ifx#1#2#3\else#4\fi}
+\long\def\ettl@ifchar#1#2{\csname ettl@\if\noexpand#2\string#11of2\ettl@csname\fi
+ \unless\ifcat\noexpand#1\noexpand#22of2\ettl@csname\fi
+ \ifx#1#21\else2\fi of2\endcsname}
+
+%% \ifsingletoken{ tokenA }{ tokenB }{ true }{ false }
+\newcommand\ifsingletoken[2]{\csname @\ettl@firstspace{#2}
+ {\ettl@nbk#1#2//{second}{\if\relax\detokenize{#1#2}\relax first\else\ifx#1#2first\else second\fi\fi}//}
+ {\if\relax\detokenize\expandafter{\ettl@cdr#2\@nil}\relax
+ \expandafter\ettl@ifxsingle
+ \else\expandafter\ettl@carcar
+ \fi{#1}{#2}{first}{second}}%
+ oftwo\endcsname}
+\def\ettl@ifxsingle#1#2#3#4{\ettl@nbk#1//{\ifx#1#2#3\else#4\fi}{#4}//}
+
+%% \ifOneToken{ token }{ true }{ false }
+\newcommand\ifOneToken[1]{\romannumeral\csname rmn@\ettl@firstspace{#1}
+ {\ettl@nbk#1//{second}{\if\relax\detokenize{#1}\relax second\else first\fi}//}
+ {\if\relax\detokenize\expandafter{\ettl@cdr#1\@nil}\relax
+ first\else second\fi}oftwo\endcsname}
+
+%% \ifsinglechar character{ string }{ true }{ false }
+\newcommand\ifsinglechar[2]{\romannumeral\csname rmn@\ettl@firstspace{#2}
+ {\ettl@nbk#2//{second}{\if\relax\detokenize{#1#2}\relax first\else\ifx#1#2first\else second\fi\fi}//}
+ {\if\relax\detokenize\expandafter{\ettl@cdr#2\@nil}\relax
+ \expandafter\ettl@ifchar
+ \else\expandafter\ettl@carcar
+ \fi{#1}{#2}{first}{second}}%
+ oftwo\endcsname}
+
+%% \ifOneChar{ string }{ true }{ false }
+\ettl@ifdefined\pdfmatch
+\newcommand\ifOneChar[1]{\romannumeral\csname rmn@%
+ \ifnum\pdfmatch{\detokenize{^.$}}{\detokenize{#1}}=1 first\else second\fi
+ oftwo\endcsname}
+\else
+\newcommand\ifOneChar[1]{\romannumeral\csname rmn@\ettl@firstspace{#1}
+ {\ettl@nbk#1//{second}{\if\relax\detokenize{#1}\relax second\else first\fi}//}
+ {\if\relax\expandafter\ettl@cdr\detokenize{#1}\@nil\relax
+ first\else second\fi}oftwo\endcsname}
+\fi%\pdfmatch
+
+%% \ifOneCharWithBlanks{ string }{ true }{ false }
+\ettl@ifdefined\pdfmatch
+\newcommand\ifOneCharWithBlanks[1]{\romannumeral\csname rmn@%
+ \ifnum\pdfmatch{\detokenize{^[[:space:]]*[^[:space:]][[:space:]]*$}}{\detokenize{#1}}=1 %
+ first\else second\fi oftwo\endcsname}
+\else
+\newcommand\ifOneCharWithBlanks[1]{\romannumeral\csname rmn@\ettl@nbk#1//%
+ {\expandafter\expandafter\expandafter\ettl@nbk
+ \expandafter\ettl@cdr\detokenize{#1}\@nil//{second}{first}//}%
+ {second}//oftwo\endcsname}
+\fi
+
+%% \iffirstchar{ string1 }{ string2 }{ true }{ false }
+\newcommand\iffirstchar[2]{\romannumeral\csname rmn@%
+ \ettl@nbk#2//%
+ {\ettl@nbk#1//%
+ {\expandnexttwo\ettl@ifchar{\ettl@car#2\@nil}{\ettl@car#1\@nil}{first}{second}}
+ {\if\relax\detokenize{#1}\relax secondoftwo\ettl@csname\fi
+ \ettl@firstspace{#2}{first}{second}}//}%
+ {\ettl@nbk#1//%
+ {\if\relax\detokenize{#2}\relax secondoftwo\ettl@csname\fi
+ \ettl@firstspace{#1}{first}{second}}
+ {\if\relax\detokenize{#1#2}\relax first\else second\fi}}//%
+ oftwo\endcsname}
+
+%% \ifiscs { string }{ true }{ false }
+\newcommand\ifiscs[1]{\romannumeral\csname rmn@\ettl@nbk#1//%
+ {\if\relax\expandafter\ettl@cdr\detokenize{#1}\@nil\relax secondoftwo\ettl@csname\fi
+ \if\relax\detokenize\expandafter{\ettl@cdr#1\@nil}\relax
+ \expandafter\ettl@firstspace
+ \else secondoftwo\ettl@csname\fi{#1}{second}{first}}
+ {second}//oftwo\endcsname}
+
+%% \detokenizeChars { list of single tokens }
+\newcommand\detokenizeChars[1]{\expandafter\ettl@dosinglelist
+ \expandafter\ettl@do@detokenChars\expandafter{\romannumeral0\protectspace{#1}}}
+\long\def\ettl@do@detokenChars#1{\ifOneChar{#1}\detokenize\unexpanded{#1}}
+
+%% \protectspace { string }
+\newcommand\protectspace[1]{\romannumeral\ettl@protectspace#1 /End§String/}
+\long\def\ettl@protectspace#1 #2/End§String/{\ifempty{#2}{\z@#1}
+ {\expandafter\@swap\expandafter{\romannumeral\ettl@protectspace#2/End§String/}{\z@#1{ }}}}
+
+%% \ifempty{ text }{ true }{ false }
+\newcommand\ifempty[1]{\romannumeral\csname rmn@\if\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
+%% \ifnotempty{ text }{ true }{ false }
+\newcommand\ifnotempty[1]{\romannumeral\csname rmn@\if\relax\detokenize{#1}\relax
second\else first\fi oftwo\endcsname}
-% \xifempty{ text }{ true }{ false }
+%% \xifempty{ text }{ true }{ false }
\newcommand\xifempty[1]{\xifstrcmp{#1}{}}
-\ettl@onlypdfTeX\pdfstrcmp\xifempty
+\ettl@onlypdfTeX\pdfstrcmp\xifempty[\xifstrempty]
-% \ifnotblank{ text }{ true }{ false }
-\begingroup\catcode`\&=3\catcode`\:=12
-\ifcsundef{ifnotblank}{%
-\long\gdef\ifnotblank#1{\etb@ifblank@i#1&&\@firstoftwo\@secondoftwo:}}
-\relax\endgroup
+%% \ifnotblank{ text }{ true }{ false }
+\long\def\ifnotblank#1#2#3{\ettl@nbk#1//{#2}{#3}//}
-% \xifblank{ string }{ true }{ false }
+%% \xifblank{ string }{ true }{ false }
\newrobustcmd\xifblank[1]{\begingroup
\protected@edef\@xifblank{\endgroup
\noexpand\ifblank{#1}%
}\@xifblank}
-% \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
+%% \deblank{ string }
+\newcommand\deblank[1]{\romannumeral-`\q\ettl@deblank#1/ /}
+\long\def\ettl@deblank#1 /{\ettl@deblank@i#1/}
+\long\def\ettl@deblank@i#1/#2{ #1}
+\newcommand\ettl@stringify[1]{\romannumeral-`\q\ettl@expandafthree\@gobblescape%
+ \expandafter\ettl@deblank\detokenize{#1}/ /}
-% \ifstrcmp{ string1 }{ string2 }{ true }{ false }
-\newcommand\ifstrcmp[2]{\csname @%
+%% \ifstrcmp{ string1 }{ string2 }{ true }{ false }
+\newcommand\ifstrcmp[2]{\romannumeral\csname rmn@%
\ifnum\pdfstrcmp{\detokenize{#1}}{\detokenize{#2}}=0 first\else second\fi
oftwo\endcsname}
-\ettl@onlypdfTeX\pdfstrcmp\ifstrcmp
+\ettl@onlypdfTeX\pdfstrcmp\ifstrcmp[\ifstrequal]
-% \xifstrcmp{ string1 }{ string2 }{ true }{ false }
+%% \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
+\ettl@onlypdfTeX\pdfstrcmp\xifstrcmp[\xifstrequal]
+\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}
+%% \ifcharupper{ string }{ true }{ false }
+%% \ifcharlower{ string }{ true }{ false }
+\newcommand\ifcharupper[1]{\romannumeral\csname rmn@%
+ \ifnum`\#1=\uccode`\#1 first\else second\fi oftwo\endcsname}
+\newcommand\ifcharlower[1]{\romannumeral\csname rmn@%
+ \ifnum`\#1=\lccode`\#1 first\else second\fi oftwo\endcsname}
+
+%% \ifuppercase{ string }{ true }{ false }
+%% \iflowercase{ string }{ true }{ false }
+\newrobustcmd\ifuppercase[1]{\uppercase{\ifstrcmp{#1}}{#1}}
+\newrobustcmd\iflowercase[1]{\lowercase{\ifstrcmp{#1}}{#1}}
+
+%% \ifstrmatch{ pattern }{ string }{ true }{ false }
+\newcommand\ifstrmatch[2]{\romannumeral\csname rmn@%
+ \ifnum\pdfmatch{#1}{#2}=1 first\else second\fi oftwo\endcsname}
\ettl@onlypdfTeX\pdfmatch\ifstrmatch
+
+%% \ifstrdigit{ string }{ true }{ false }
+\ettl@ifdefined\pdfmatch
+\newcommand\ifstrdigit[1]{\romannumeral\csname rmn@\ifnum\pdfmatch{\detokenize{^[[:digit:]]$}}%
+ {\detokenize{#1}}=1 first\else second\fi oftwo\endcsname}
+\else
+\def\do#1{\cslet{ettl@number#1}=#1%
+}\docsvlist{0,1,2,3,4,5,6,7,8,9}
+\newcommand\ifstrdigit[1]{\romannumeral\csname rmn@%
+ \ifcsname ettl@number\detokenize{#1}\endcsname first\else second\fi oftwo\endcsname}
+\fi%\pdfmatch
+
+%% \ifstrnum{ string }{ true }{ false }
+\ettl@ifdefined\pdfmatch
+\newcommand\ifstrnum[1]{\romannumeral\csname rmn@\ifnum\pdfmatch
+ {\detokenize{^([[:space:]]*-?)*+[[:digit:]]+[[:space:]]*$}}{\detokenize{#1}}=1 %
+ first\else second\fi oftwo\endcsname}
+\else
+\newcommand\ifstrnum[1]{\romannumeral\csname rmn@\ettl@nbk#1//%
+ {\expandafter\ettl@numberminus\detokenize{#1}-/End§String/}{second}//oftwo\endcsname}
+\long\def\ettl@numberminus#1-#2/End§String/{\ettl@nbk#2//%
+ {\ettl@nbk#1//{second}{\ettl@numberminus#2/End§String/}//}%
+ {\expandafter\expandafter\expandafter\ettl@numberspace\deblank{#1} /End§String/}//}%
+\long\def\ettl@numberspace#1 #2/End§String/{\ettl@nbk#2//{second}{\ettl@ifstrnum#1/End§String/}//}
+\long\def\ettl@ifstrnum#1#2/End§String/{%
+ \ifcsname ettl@number#1\endcsname% #1 detokenized before, ok
+ \ettl@nbk#2//{\ettl@ifstrnum#2/End§String/}{first}//%
+ \else second%
+ \fi}
+\fi%\pdfmatch
+
+%% \DeclareStringFilter[\global]{ \StringFilterMacro }{ string }
+\newrobustcmd\DeclareStringFilter[3][\global]{\@ifdefinable#2%
+ {\expandnext\ettl@declarestrfilter%
+ {\csname\@gobblescape#2\detokenize{->"#3"}\endcsname}{#1}{#2}{#3}}}
+\newcommand\ettl@declarestrfilter[4]{%
+ #2\csdef{\@gobblescape#1}##1#4##2/End§String/{##1/##2}% This the FILTER
+ #2\long\def#3##1{\FE@modifiers{=<>?-+!}{##1}
+ {\ettl@strfilt@mod 0{{#4}{}{#1}[1]}}%=
+ {\ettl@strfilt@mod 1{{#4}{}{#1}[1]}}%<
+ {\ettl@strfilt@mod 2{{#4}{}{#1}[\ettl@intmax]}}%>
+ {\ettl@strfilt@mod 3{{#4}{}{#1}}}%?
+ {\ettl@strfilt@mod 4{{#4}{}{#1}}}%-
+ {\ettl@strfilt@mod 5{{#4}{}{#1}}}%+
+ {\ettl@strfilt\ettl@strfilt@count{#4}{}{#1}[\ettl@intmax]}%!
+ {\ettl@strfilt\ettl@strfilt@equal{#4}{}{#1}[1]}}}% default
+\long\def\ettl@ifchardot#1{\csname\ettl@BasicFilter\ettl@ifchardot@filt.#1/End§String/\endcsname}
+\long\def\ettl@ifchardot@filt#1.#2/End§String/{#1/#2}
+\def\ettl@strfilt@mod #1#2#3{%
+ \ifcase#1 \ettl@or\ettl@ifchardot{#3}%
+ {\ettl@strfilt\ettl@strfilt@equal#2}
+ {\FE@ifcharequal{#3}%
+ {\ettl@strfilt\ettl@strfilt@equaleq#2}%
+ {\ettl@strfilt\ettl@strfilt@equal#2}}%
+ \or\ettl@or\ettl@ifchardot{#3}%
+ {\ettl@strfilt\ettl@strfilt@start#2}%
+ {\FE@ifcharequal{#3}
+ {\ettl@strfilt\ettl@strfilt@starteq#2}%
+ {\ettl@strfilt\ettl@strfilt@start#2}}%
+ \or\ettl@or\ettl@ifchardot{#3}%
+ {\ettl@strfilt\ettl@strfilt@endby#2}%
+ {\FE@ifcharequal{#3}
+ {\ettl@strfilt\ettl@strfilt@endbyeq#2}%
+ {\ettl@strfilt\ettl@strfilt@endby#2}}%
+ \or\ettl@or\ettl@ifchardot{#3}%
+ {\ettl@strfilt\ettl@strfilt@instr#2[1]}
+ {\FE@testopt{#3}{\ettl@strfilt\ettl@strfilt@instr#2}{1}}%
+ \or\ettl@or\ettl@ifchardot{#3}%
+ {\ettl@strfilt@REMOVE{#2}[\ettl@intmax]}%
+ {\FE@testopt{#3}{\ettl@strfilt@REMOVE{#2}}{\ettl@intmax}}%
+ \or\ettl@fi\ettl@ifchardot{#3}%
+ {\ettl@strfilt@REPLACE#2[\ettl@intmax]}%
+ {\FE@testopt{#3}{\ettl@strfilt@REPLACE#2}{\ettl@intmax}}%
+ \fi}
+\long\def\ettl@strfilt#1#2#3#4[#5]#6{% % #1 = test macro
+ \ExpandAftercmds#1{\ettl@Remove #6/End§String/{#2}{#3}[{#5}]{#4}}}
+\long\def\ettl@strfilt@REMOVE #1[#2]{%
+ \ifnum\numexpr#2>0 \ettl@else\ettl@strfilt\ettl@strfilt@remove#1[#2]%
+ \else\expandafter\@firstofone%
+ \fi}
+\long\def\ettl@strfilt@REPLACE #1#2#3#4[#5]#6#7{%
+ \ifnum\numexpr#5>0 \ettl@else\ettl@strfilt\ettl@strfilt@replace{#1}{#7}{#3}[{#5}]{#6}%
+ \else\expandafter\@firstoftwo%
+ \fi}
+\long\def\ettl@Remove#1/End§String/#2#3[#4]#5{%
+ \expandafter\ettl@Remove@loop #5#1//#2/End§String//End§String/{#3}[{#4-1}]{#5}}
+\long\def\ettl@Remove@loop#1/#2//#3/End§String/#4[#5]#6{%
+ \ifnum\numexpr#5>0 \ettl@nbk@else#2//%
+ {\ettl@Remove #1#4#2/End§String/{#3}{#4}[{#5}]{#6}}
+ {{#1}{#4#2}{#3}{#5}}//%
+ \else\ettl@fi{#1}{#4#2}{#3}{#5}%
+ \fi}
+\long\def\ettl@strfilt@equal #1#2#3#4{\csname @%
+ \ettl@nbk#3//{\ettl@nbk#1#2//{second}{first}//}{second}//oftwo\endcsname}
+\long\def\ettl@strfilt@equaleq #1#2#3#4{\csname @%
+ \ettl@nbk#3//{\ifnotempty{#1#2}{second}{first}}{second}//oftwo\endcsname}
+\long\def\ettl@strfilt@start #1#2#3#4{\csname @%
+ \ettl@nbk#1//{second}{first}//oftwo\endcsname}
+\long\def\ettl@strfilt@starteq #1#2#3#4{\csname @%
+ \ifnotempty{#1}{second}{first}oftwo\endcsname}
+\long\def\ettl@strfilt@endby #1#2#3#4{\csname @%
+ \ettl@nbk#3//{first}{second}//oftwo\endcsname}
+\long\def\ettl@strfilt@endbyeq #1#2#3#4{\csname @%
+ \ettl@nbk#3//{\ifempty{#2}{first}{second}}{second}//oftwo\endcsname}
+\long\def\ettl@strfilt@count #1#2#3#4{\number\numexpr\ettl@intmax-(#4)-\ettl@nbk#3//01//}
+\long\def\ettl@strfilt@instr #1#2#3#4{\csname @%
+ \ifnum\numexpr#4>0 second%
+ \else\ifnum\numexpr#4<0 first%
+ \else\ettl@nbk#3//{first}{second}//%
+ \fi\fi oftwo\endcsname}
+\long\def\ettl@strfilt@remove #1#2#3#4{#1#2}
+\long\def\ettl@strfilt@replace #1#2#3#4{#1\ettl@nbk#3//{#2}{}//}
%----------------------------------------------------------------------------
% 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@testopt{ #1 }{ commands }{ default option }
+\long\def\ettl@BasicFilter#1#2#3/End§String/{\expandafter\ettl@B@sicFilter #1#3//#2/End§String//End§String/}
+\long\def\ettl@B@sicFilter#1/#2//#3/End§String/{@\ettl@nbk#3//%
+ {\if\relax\detokenize{#1#2}\relax first\else second\fi}
+ {second}//oftwo}
+\newcommand\FE@testopt[3]{\csname\ettl@BasicFilter\ettl@FE@testopt[#1/End§String/\endcsname
+ {#2#1}%
+ {#2[{#3}]{#1}}}%]
+\long\def\ettl@FE@testopt#1[#2/End§String/{#1/#2}
-% \FE@ifstar{ #1 } { \StarredMacro }{ \NotStarredMacro }
-\newcommand\FE@ifstar[3]{\ifsinglechar *{#1}{#2}{#3{#1}}}
+%% \FE@ifstar{ #1 } { \StarredMacro }{ \NotStarredMacro }
+\newcommand\FE@ifstar[3]{\csname\ettl@BasicFilter\ettl@FE@ifstar*#1/End§String/\endcsname
+ {#2}%
+ {#3{#1}}}
+\long\def\ettl@FE@ifstar#1*#2/End§String/{#1/#2}
-% \FE@ifchar{#1}{#2}{ \SpecialFormMacro }{ \NormalMacro }
+%% \FE@charequal{ #1 } { \MacroWith= }{ \NormalMacro } % used by the string filters
+\ettl@ifdefined\pdfmatch% use \ettl@ifdefined to test both on pdfTeX (make \ettl@ifdefined=\iffalse)
+\newcommand\FE@ifcharequal[3]{\ifsinglechar ={#1}{#2}{#3{#1}}}
+\else
+\newcommand\FE@ifcharequal[3]{\csname\ettl@BasicFilter\ettl@FE@charequal=#1/End§String/\endcsname
+ {#2}%
+ {#3{#1}}}
+\long\def\ettl@FE@charequal#1=#2/End§String/{#1/#2}
+\fi
+
+%% \FE@ifchar{ <Character> }{ #1 }{ \SpecialFormMacro }{ \NormalMacro }
\newcommand\FE@ifchar[4]{\ifsinglechar{#1}{#2}{#3}{#4{#2}}}
-%% \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\catcode`\`=3
-\gdef\etextools@defcmdparser#1#2{%
- \begingroup
- \def\`##1`{\expandafter\noexpand\csname ##1\endcsname}%
- \protected@edef\defineparser{\endgroup
- \long\def#1####1{\noexpand\FE@ifstar{####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&{%
- \noexpand\ifblank{####2}
- {}
- {\noexpand\ettl@lst@doitem{####1}{####2}}%
- \noexpand\ifblank{####3}
- {\noexpand\ettl@listbreak}
- {\`ettl@lst@\string#1`{####1}####3}&}%
- }\defineparser}%
- \long\gdef\ettl@lst@doitem#1#2{#1{#2}}%
- \long\gdef\ettl@listbreak#1&{}%
-\endgroup
+%% \FE@modifiers{ Allowed Characters }{ #1 }{ \MacroA }{ \MacroB }{ \MacroC }...{ \MacroZ }{ \MacroDefault }
+\newcommand\FE@modifiers[2]{%
+ \ifOneToken{#2}%
+ {\ExpandAftercmds\ettl@FE@modifiers%
+ {\ExpandAftercmds{\ettl@setresult 12of3><}
+ {\ettl@getsinglelist{\ettl@ifchar{#2}}{#1}}}{#2}}
+ {\ExpandNextTwo{\ettl@supergobble[{{#2}}]}{-1}{\getcharlistcount{#1}+1}}}
+\long\def\ettl@FE@modifiers#1#2#3{\expandafter\ettl@supergobble%
+ \expandafter[\romannumeral-`\q\ifnum#2<0 {#3}\fi]{#2}{#1+1}}
+%% \ettl@supergobble{ p }{ q }{token_1}{token_2}...{token_p}{TOKEN_p+1}{token_p+2}...{token_p+q+1}
+\newcommand\ettl@supergobble[1]{\FE@testopt{#1}\ettl@superg@bble{}}
+\long\def\ettl@superg@bble[#1]#2#3{%
+ \ifnum\numexpr#3>0
+ \ifnum\numexpr#3-(#2)=0
+ \ettl@supergobble@loop{#3+2}0{\ettl@supergobble@end{}{}}%
+ \else
+ \expandafter\ettl@supergobble@loop\expandafter{%
+ \number\numexpr\ifnum\numexpr#2*(#2-(#3))>0 #3+1\else#2+2\fi}{#3+2}%
+ {\ettl@supergobble@next{}{#1}}%
+ \fi\fi}
+\long\def\ettl@supergobble@loop#1#2#3{%
+ \ifcsname ettl@supergobble\number\numexpr#1\endcsname
+ \csname ettl@supergobble\number\numexpr#1\endcsname
+ {#3{#2-(#1)-1}}%
+ \else\ettl@supergobbleheight{\ettl@supergobble@loop{#1-8}{#2-8}{#3}}%
+ \fi}
+\long\def\ettl@supergobble@end#1#2#3{\fi\fi\fi#1#2}
+\long\csdef{ettl@supergobbleheight}#1\fi#2#3#4#5#6#7#8#9{\fi#1}
+\long\csdef{ettl@supergobble7}#1#2\fi#3#4#5#6#7#8#9{#1}
+\long\csdef{ettl@supergobble6}#1#2\fi#3#4#5#6#7#8{#1}
+\long\csdef{ettl@supergobble5}#1#2\fi#3#4#5#6#7{#1}
+\long\csdef{ettl@supergobble4}#1#2\fi#3#4#5#6{#1}
+\long\csdef{ettl@supergobble3}#1#2\fi#3#4#5{#1}
+\long\csdef{ettl@supergobble2}#1#2\fi#3#4{#1}
+\long\csdef{ettl@supergobble1}#1#2\fi#3{#1}
+\long\csdef{ettl@supergobble0}#1#2\fi{#1}
+\long\def\ettl@supergobble@next#1#2#3#4{\fi
+ \ettl@supergobble@loop{#3}0{\ettl@supergobble@end{#4}{#2}}}
+
+%% \AfterGroup{ code } / \AfterGroup*{ code } the star form expands its argument once
+\newcount\ettl@fter
+\newrobustcmd\AfterGroup{\@ifstar{\ettl@AfterGroup\@firstofone}{\ettl@AfterGroup\unexpanded}}
+\newrobustcmd\ettl@AfterGroup[2]{%
+ \csxdef{ettl@aftergroup@hook\number\numexpr\the\ettl@fter+1}%
+ {\global\csundef{ettl@fterGroup\number\numexpr\the\ettl@fter+1}#1{#2}}%
+ \global\advance\ettl@fter\@ne
+ \expandafter\aftergroup\csname ettl@fterGroup\the\ettl@fter\endcsname}
+
+%% \AfterAssignment{ code }
+\newrobustcmd\AfterAssignment{\@ifstar{\ettl@AfterAssignment\@firstofone}{\ettl@AfterAssignment\unexpanded}}
+\newrobustcmd\ettl@AfterAssignment[2]{%
+ \csedef{ettl@afterassignment@hook\number\numexpr\the\ettl@fter}{#1{#2}}%
+ \global\advance\ettl@fter\@ne
+ \expandafter\afterassignment\csname ettl@afterassignment@hook\the\ettl@fter\endcsname}
+
+%% \aftergroup@def{ cs-token }
+\newrobustcmd\aftergroup@def[1]{%
+ \let\etex@let@primitive\let \def\let{\global\etex@let@primitive}%
+ \expandafter\LetLtxMacro\csname ettl@ftergroup@def\number\numexpr\the\ettl@fter+1\endcsname#1%
+ \global\advance\ettl@fter\@ne
+ \etex@let@primitive\let=\etex@let@primitive
+ \aftergroup\LetLtxMacro \aftergroup#1%
+ \expandafter\aftergroup\csname ettl@ftergroup@def\the\ettl@fter\endcsname
+ \aftergroup\global \aftergroup\undef
+ \expandafter\aftergroup\csname ettl@ftergroup@def\the\ettl@fter\endcsname}
+%----------------------------------------------------------------------------
+
+%% \@ifchar{ single token }{ true }{ false }
-% \csvloop[\command]\csvListMacro
-% \csvloop*[\command]{item,item,item}
+\long\def\@ifchar#1#2{\ettl@ifnextchar #1{\@firstoftwo{#2}}}
+
+%% \ettl@ifnextchar{ character token }{ true }{ false }
+
+\newrobustcmd\ettl@ifnextchar[3]{\begingroup
+ \edef\1##1/##2/##3{##1\endgroup\unexpanded{#2}##3}%
+ \edef\2##1/##2/##3{##1\endgroup\unexpanded{#3}##3}%
+ \ifOneToken{#1}
+ {\csname ettl@\if\relax\expandafter\ettl@cdr\detokenize{#1}\@nil\relax % OneChar
+ xifnch\else xifntk\fi\endcsname{#1}}
+ {\2//{}}}
+\long\def\ettl@xifnch#1{%
+ \ifx#1\@sptoken \def\ettl@xifnch{\ifx\@let@token\@sptoken\1\else\2\fi//{}}%
+ \else \def\ettl@xifnch{%
+ \ifx\@let@token\bgroup \2
+ \else\ifx\@let@token\egroup \2
+ \else\ifx\@let@token\@sptoken \ettl@ifnspace\ettl@xifnch%
+ \else\ettl@ifnch%
+ \fi\fi\fi/{#1}/{}}%
+ \fi\futurelet\@let@token\ettl@xifnch}
+\long\def\ettl@ifnch#1/#2/#3{#1\long\def\ettl@ifnch##1{\ettl@char{##1}
+ {\if\string##1\string#2\1\else\2\fi}\2//{##1}}\ettl@ifnch}
+\long\def\ettl@xifntk#1{%
+ \ifx#1\bgroup\def\ettl@xifntk{\ifx\@let@token\bgroup\1\else\2\fi//{}}%
+ \else\ifx#1\egroup\def\ettl@xifntk{\ifx\@let@token\egroup\1\else\2\fi//{}}%
+ \else\def\ettl@xifntk{%
+ \ifx\@let@token\bgroup \2
+ \else\ifx\@let@token\egroup \2
+ \else\ifx\@let@token\@sptoken \ettl@ifnspace\ettl@xifntk%
+ \else\ettl@ifntk%
+ \fi\fi\fi/{#1}/{}}%
+ \fi\futurelet\@let@token\ettl@xifntk}
+\long\def\ettl@ifntk#1/#2/#3{#1\long\def\ettl@ifntk##1{\ettl@char{##1}
+ \2{\ifx##1#2\1\else\2\fi}//{##1}}\ettl@ifntk}
+\long\def\ettl@ifnspace#1#2/#3/#4 {#2\futurelet\@let@token#1}
+
+%% \futuredef[list of allowed tokens]{ command }{ commands to expand after }
+%% \futuredef*[list of allowed tokens]{ command }{ commands to expand after }
+%% \futuredef=[list of allowed tokens]{ command }{ commands to expand after }
+%% \futuredef*=[list of allowed tokens]{ command }{ commands to expand after } (or \futuredef=*[...] )
+\newrobustcmd*\futuredef{\begingroup\ettl@futdef\ettl@futuredef\detokenize}
+\protected\def\ettl@futdef#1#2{\@ifstar%
+ {\ettl@futdef\ettl@futurd@f#2}
+ {\@ifchar={\ettl@futdef#1\unexpanded}
+ {\@testopt{\ettl@futur@def#1#2}}}}
+\long\def\ettl@futur@def#1#2[#3]{%
+ \csname ettl@\if\relax\detokenize{#3}\relax1\else2\fi of2\endcsname
+ {\let \ettl@x \@empty \letcs \ettl@futur@def@collect{\@gobblescape#1@collectall}}%
+ {\def \ettl@x {#3}\edef \ettl@y {#2{#3}}%
+ \ifx\ettl@x\ettl@y \let\ettl@y\@gobble
+ \else \ifx#2\unexpanded \let\ettl@y\@gobble
+ \else \def\ettl@y{\edef\ettl@x}%
+ \fi\fi\ettl@y{\detokenizeChars{#3}}%
+ \letcs\ettl@futur@def@collect{\@gobblescape#1@collect}}%
+ \expandafter#1\expandafter#2\expandafter{\ettl@x}}
+\long\def\ettl@futuredef#1#2#3#4{% #1=detokenize #2=list, #3=macro result, #4=code-next
+ \def \ettl@futuredef@loop{\ettl@futuredef@test{}}%
+ \long \def \ettl@futuredef@test##1{%
+ \ifcat\noexpand\ettl@x\bgroup\ettl@futuredef@end{}\else
+ \ifcat\noexpand\ettl@x\egroup\ettl@futuredef@end{}\else
+ \ifcat\noexpand\ettl@x\ettl@sptoken\ettl@futuredef@space#1\else
+ \ettl@futur@def@collect#1\fi\fi\fi/Ne¤t/{#2}{##1}}%
+ \long \def \ettl@futuredef@end##1##2/Ne¤t/##3##4{##2\endgroup\def#3{##4}#4##1}%
+ \futurelet \ettl@x \ettl@futuredef@loop}
+\long\def\ettl@futuredef@collect#1#2/Ne¤t/#3#4#5{#2%
+ \ifcat\noexpand#5\relax \ettl@futuredef@filt\unexpanded
+ \else \ettl@futuredef@filt#1
+ \fi{#5}{#3}
+ {\def\ettl@futuredef@loop{\ettl@futuredef@test{#4#5}}\futurelet\ettl@x\ettl@futuredef@loop}
+ {\ettl@futuredef@end{#5}/Ne¤t/{}{#4}}/Ne¤t/}
+\long\def\ettl@futuredef@space#1#2/Ne¤t/#3#4 {\ettl@futur@def@collect#1#2/Ne¤t/{#3}{#4}{ }}
+\long\def\ettl@futuredef@collectall#1#2/Ne¤t/#3#4#5{#2%
+ \def\ettl@futuredef@loop{\ettl@futuredef@test{#4#5}}\futurelet\ettl@x\ettl@futuredef@loop}
+\long\def\ettl@futur@def@filt#1#2{% #1=token to check, #2=allowed list
+ \long\def\ettl@futdef@filt##1#1##2##3/##4##5##6/Ne¤t/{##5}%
+ \ettl@futdef@filt#2#1//}
+\long\def\ettl@futuredef@filt#1#2\fi#3#4{\fi % #1=detokenize/unexpanded, #2=discard, #3=token,#4=allowed list
+ \expandafter\ettl@futur@def@filt\expandafter{#1{#3}}{#4}}
+\long\def\ettl@futured@f#1#2#3#4{\begingroup%#1=test macro,#2=list,#3=macro,#4=code-next
+ \let\ettl@y\@undefined
+ \def \ettl@futured@f@loop{\ettl@futured@f@test{}}%
+ \long \def \ettl@futured@f@test##1{%
+ \csname @\ettl@ifinsinglelist#1\ettl@x#2/End§List/oftwo\endcsname
+ {\ifcat\noexpand\ettl@x\bgroup\ettl@futuredef@end{##1}\fi
+ \ifcat\noexpand\ettl@x\egroup\ettl@futuredef@end{##1}\fi
+ \ifcat\noexpand\ettl@x\ettl@sptoken\ettl@futured@f@space{##1}{ }\fi
+ \ettl@futured@f@collect{##1}/Ne¤t/}
+ {\ettl@futured@f@expand{##1}}}%
+ \long \def \ettl@futuredef@end##1\fi##2/Ne¤t/{\fi\endgroup\def#3{##1}#4}%
+ \futurelet \ettl@x \ettl@futured@f@loop}
+\long\def\ettl@futured@f@collect#1#2/Ne¤t/#3{%
+ #2\def\ettl@futured@f@loop{\ettl@futured@f@test{#1#3}}\let\ettl@y\@undefined%
+ \futurelet\ettl@x\ettl@futured@f@loop}
+\long\def\ettl@futured@f@expand@nbk#1{%
+ \ifcat\noexpand\ettl@x\ettl@sptoken\ettl@futured@f@space{#1}{}\fi
+ \ifx\ettl@x\ettl@y\ettl@futuredef@end{#1}%
+ \else\let\ettl@y\ettl@x\ettl@futured@f@exp@nd\fi/Ne¤t/}
+\long\def\ettl@futured@f@expand@bk#1{%
+ \ifcat\noexpand\ettl@x\bgroup\ettl@futuredef@end{#1}\fi
+ \ifcat\noexpand\ettl@x\egroup\ettl@futuredef@end{#1}\fi
+ \ifcat\noexpand\ettl@x\ettl@sptoken\ettl@futured@f@space{#1}{ }\fi
+ \ifx\ettl@x\ettl@y\ettl@futured@f@collect{#1}%
+ \else\let\ettl@y\ettl@x\ettl@futured@f@exp@nd%
+ \fi/Ne¤t/}
+\long\def\ettl@futured@f@exp@nd#1/Ne¤t/{%
+ #1\expandafter\futurelet\expandafter\ettl@x\expandafter\ettl@futured@f@loop}
+\csdef{ettl@futured@f@space}#1#2\fi#3/Ne¤t/ {%
+ \def\ettl@futured@f@loop{\ettl@futured@f@test{#1#2}}\let\ettl@y\@undefined
+ \futurelet\ettl@x\ettl@futured@f@loop}
+
+%----------------------------------------------------------------------------
+
+%% \naturalloop [ auxiliary commands (default \do) ]{ n times }{ argument }
+\newcommand\naturalloop[1]{\FE@testopt{#1}\ettl@naturalloop{\do}}
+\def\ettl@naturalloop[#1]#2#3{%
+ \ifnum\numexpr#2>0 \ExpandNext{\ettl@naturall@@p[{#1}]{#2-1}{1}{#3}}{#1[1]{#3}{#3}}%
+ \else\ettl@fi#3%
+ \fi}
+\def\ettl@naturall@@p[#1]#2#3#4#5#6\fi{\fi%
+ \ifnum\numexpr#2>0 \ExpandNext{\ettl@naturall@@p[{#1}]{#2-1}{#3+1}{#4}}{#1[#3+1]{#4}{#5}}%
+ \else\ettl@fi#5%
+ \fi}
+
+%% \ifinttokslist{ item }{ list of tokens }{ true }{ false }
+\newcommand\ifintokslist[4]{\romannumeral\csname @%
+ \expandafter\ettl@nbk\romannumeral\ettl@dosinglelist{\ettl@ifintokslist{#1}}{#2}//{first}{second}//%
+ oftwo\endcsname{\z@#3}{\z@#4}}
+\long\def\ettl@ifintokslist#1#2{\ettl@ifx{#1}{#2}{\expandafter\z@\ettl@breakloop}{}}
+\newcommand\ifincharlist[4]{\romannumeral\csname @%
+ \expandafter\ettl@nbk\romannumeral\ettl@dosinglelist{\ettl@ifincharlist{#1}}{#2}\z@//{first}{second}//%
+ oftwo\endcsname{\z@#3}{\z@#4}}
+\long\def\ettl@ifincharlist#1#2{\ettl@ifchar{#1}{#2}{\expandafter\z@\ettl@breakloop}{}}
+\long\def\ettl@dosinglelist#1#2{\ettl@nbk#2//%
+ {\ettl@dosinglelist@loop{#1}#2//{\ettl@dosinglelist@loop{#1}}\ettl@breakloop}
+ \ettl@breakloop///End§List/}
+\long\def\ettl@dosinglelist@loop#1#2#3#4/#5#6#7/End§List/{%
+ #1{#2}#6{#3}#4//{#6}#7/End§List/}
+
+%% \gettokslistindex { item }{ list of tokens }
+%% \gettokslistcount { item }{ list of tokens }
+%% \gettokslisttoken { item }{ list of tokens }
+\newcommand\gettokslistindex[2]{\number\ifnotempty{#2}{\ettl@nbk#1//%
+ {\ExpandAftercmds{\ettl@setresult 2of3><}{\ettl@getsinglelist{\ettl@ifx{#1}}{#2}}}
+ {-1}//}{-1}}
+\newcommand\getcharlistindex[2]{\number\ifnotempty{#2}{\ettl@nbk#1//%
+ {\ExpandAftercmds{\ettl@setresult 2of3><}{\ettl@getsinglelist{\ettl@ifchar{#1}}{#2}}}
+ {-1}//}{-1}}
+\newcommand\gettokslistcount[1]{\number\ifnotempty{#1}%
+ {\ExpandAftercmds{\ettl@setresult 1of3><}{\ettl@getsinglelist{\ettl@ifx{\\}}{#1}}}
+ 0}
+\newcommand\getcharlistcount[1]{}%
+\let\getcharlistcount=\gettokslistcount
+\newcommand\gettokslisttoken[2]{\ifnotempty{#2}{\ettl@nbk#1//%
+ {\ExpandAftercmds{\ettl@setresult 3of3><}{\ettl@getsinglelist{\ettl@ifx{#1}}{#2}}}
+ {}//}{}}
+\newcommand\getcharlisttoken[2]{\ifnotempty{#2}{\ettl@nbk#1//%
+ {\ExpandAftercmds{\ettl@setresult 3of3><}{\ettl@getsinglelist{\ettl@ifchar{#1}}{#2}}}
+ {}//}{}}
+\long\def\ettl@getsinglelist#1#2{\ettl@singlelist@loop{#1}{-1}{-1}{}#2//%
+ \ettl@singlelist@loop\ettl@singlelist@result/End§List/}
+\long\def\ettl@singlelist@loop#1#2#3#4#5#6/#7#8#9/End§List/{%
+ \csname @#1#5{first}{second}oftwo\endcsname
+ {#8{#1}{#2+1}{#3+1+0*(0}{#5}#6//#8#9}
+ {#8{#1}{#2+1}{#3+1}{#4}#6//#8#9}/End§List/}
+
+\def\ettl@singlelist@result#1#2#3#4#5/End§List/{\ExpandNextTwo\@swaptwo%
+ {\number\numexpr\ifempty{#4}{-1}{#3)}}{\number\numexpr#2}{#4}}
+\def\ettl@setresult#1of#2>#3<{\ettl@nbk #3//%
+ {\ifdefcount{#3}{#3=\csname ettl@#1of#2\endcsname}
+ {\edef#3{\csname ettl@#1of#2\endcsname}}}%
+ {\csname ettl@#1of#2\endcsname}//}
+
+%% \DeclareCmdListParser : general constructor for command-list parsers
+%% \DeclareCmdListParser\ParserName{separator}
+\newrobustcmd\DeclareCmdListParser[3][\global]{\@ifdefinable{#2}{\begingroup
+ \protected\def\ettl@defcmdparser##1{%
+ \edef\ettl@defcmdparser{\endgroup\ettl@defcmdparser
+ {#1}{\noexpand#2}{\unexpanded{#3}}
+ {\noexpandcs{##1->start}}
+ {\noexpandcs{##1->loop}}
+ {\noexpandcs{##1->loop+}}
+ {\noexpandcs{for##1}}%
+ }\ettl@defcmdparser
+ }\expandafter\ettl@defcmdparser\expandafter{\romannumeral-`\q\@gobblescape#2}}}
+\protected\long\def\ettl@defcmdparser#1#2#3#4#5#6#7{%#1=global,#2=command,#3=sep,#4=start,#5=loop,#6=loop+
+ #1\long\def#4##1##2[##3]##4{% ##1=case, ##2=expandafter??? , ##3=do, ##4=list
+ ##2{##4}% ifiscs or @thirdofthree
+ {\expandafter\@swaparg\expandafter{##4}{#4{##1}\@thirdofthree[{##3}]}}
+ {\ettl@nbk##4//%
+ {\ifcase##1 \ettl@or\@swaplast{#60{\ettl@lst@count}}#6%
+ \or \ettl@or\@swaplast{#60{\ettl@lst@getitem{##3}}}#6%
+ \or \ettl@or\@swaplast{#5{##3}}#5%
+ \or \ettl@fi\@swaplast{#60{##3}}#6%
+ \fi{##4#3//}\ettl@breakloop
+ }\ettl@breakloop///End§List/}}%
+ #1\long\def#5##1##2#3##3##4/##5##6##7/End§List/{%
+ \if\relax\detokenize{##2}\relax\expandafter\@gobbletwo\fi\@firstofone{##1{##2}}%
+ ##6{##1}##3##4//{##6}##7/End§List/}
+ #1\long\def#6##1##2##3#3##4##5/##6##7##8/End§List/{%
+ \if\relax\detokenize{##3}\relax\expandafter\@gobbletwo\fi\@firstofone{##2[##1]{##3}}%
+ \expandafter##7\expandafter{\number\numexpr##1+1}{##2}##4##5//{##7}##8/End§List/}
+ #1\protected\def#7{\@ifchar*%
+ {\@ifchar+{\ettl@forloop{\expandafter#2\expandafter*\expandafter+}{[####1]####2}}
+ {\ettl@forloop{\expandafter#2\expandafter*\expandafter+}{####1}}}
+ {\@ifchar+{\@ifchar*%
+ {\ettl@forloop{\expandafter#2\expandafter*\expandafter+}{[####1]####2}}
+ {\ettl@forloop{\expandafter#2\expandafter+}{[####1]####2}}}
+ {\ettl@forloop{\expandafter#2}{####1}}}}
+ #1\def#2{\ettl@lst@modif#423\ifiscs}}
+\long\def\ettl@lst@getitem#1[#2]#3{%
+ \ifnum\numexpr#1<0 \expandafter\breakloop\fi
+ \ifnum\numexpr#1=#2 \ettl@fi#3\breakloop\fi}
+\long\def\ettl@lst@count[#1]#2{+\ettl@nbk#2//10//}
+\long\def\ettl@lst@modif#1#2#3#4#5{\FE@modifiers{*+![}{#5}%
+ {\ettl@lst@modif{#1}#2#3\@thirdofthree}% * case
+ {\ettl@lst@modif{#1}#3#2{#4}}% + (case 3/default 2)
+ {\ettl@lst@modif{\number\numexpr#1}00{#4}}% ! (case 0)
+ {\ettl@lst@opt{#1}{#2}{#4}#5}% [ (option)
+ {\ettl@lst@opt{#1}{#2}{#4}[\do]}}% (default option)
+\long\def\ettl@lst@opt#1#2#3[#4]{%
+ \expandafter#1\expandafter{\number\ifnum#2=0 0\else\ifstrnum{#4}{1}{#2}\fi}{#3}[{#4}]}
+\long\def\ettl@breakloop#1/End§List/{}
+\let\breakloop\ettl@breakloop
+\globcount\ettl@for@nested
+\long\def\ettl@forloop#1#2#3\do{%
+ \global\advance\ettl@for@nested\@ne\relax
+ \csdef{ettl@for@loop\the\ettl@for@nested}{%
+ #1\expandafter[\csname ettl@for@do\the\ettl@for@nested\endcsname]{#3}%
+ \csundef{ettl@for@do\the\ettl@for@nested}%
+ \csundef{ettl@for@loop\the\ettl@for@nested}%
+ \global\advance\ettl@for@nested\m@ne\relax}
+ \expandafter\afterassignment\csname ettl@for@loop\the\ettl@for@nested\endcsname
+ \long\csdef{ettl@for@do\the\ettl@for@nested}#2}
+
+
+%% \csvloop[\command]\csvListMacro
+%% \csvloop*[\command]{item,item,item}
\DeclareCmdListParser\csvloop{,}
\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}}
-
-\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 \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}
-%\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}%
-\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
- \long\def\@tempa##1|#3|##2&{##1|##2\@tempb}%
- \long\def\@tempb|##1|\@tempb##2|\@tempb{%
- \ifblank{##2}{\unexpanded{##1}}
- {\ifblank{##1}{}{\@tempx##1&}}}%
- \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}&}%
- }\@redef}% end of \@listdel
+\DeclareCmdListParser\listloop{|}% global declaration
\endgroup
+\DeclareCmdListParser\toksloop{}
+%% \forcsvloop\csvListMacro\do{...#1...}
+%% \forcsvloop*{item,item,item,...}\do{...#1...}
-% \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
-\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
- {\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
-
-
-%\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#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&}%
- \else\ifnum#2>0 \ettl@afterfifi
- \expandnext\ettl@get@list@item{\ettl@list@other@item#1&}{#2-1}%
- \fi\fi}}
-\endgroup
+%% \csvlistadd \csvListMacro { item }
+%% \csvlist(g|e|x)add \csvListMacro { item }
+\providerobustcmd\csvlistadd[2]{\ettl@nbk#2//{\appto#1{#2,}}{}//}
+\providerobustcmd\csvlistgadd[2]{\ettl@nbk#2//{\gappto#2{#2,}}{}//}
+\providerobustcmd\csvlisteadd[2]{\begingroup \protected@edef#1{#2}%
+ \expandafter\ettl@nbk#1//{\expandafter\endgroup
+ \expandafter\appto\expandafter#1\expandafter{#1,}}\endgroup//}
+\providerobustcmd\csvlistxadd[2]{\begingroup \protected@edef#1{#2}%
+ \expandafter\ettl@nbk#1//{\expandafter\endgroup
+ \expandafter\gappto\expandafter#1\expandafter{#1,}}\endgroup//}
+%% \csvtolist [\ListMacro] \csvListMacro
+%% \csvtolist* [\ListMacro] {item,item,item}
+% Recommended use: \edef\ListMacro{\csvtolist{item,item,item}}
+\newcommand\csvtolist[1]{\FE@ifstar{#1}{\ettl@convertlist{{\csvloop*}\ettl@do@csvtolist}}
+ {\ettl@convertlist{\csvloop\ettl@do@csvtolist}}}
+\long\def\ettl@convertlist#1#2{\FE@testopt{#2}{\ettl@convert@list#1}{}}
+\long\def\ettl@convert@list#1#2[#3]#4{\ettl@nbk#3//%
+ {\edef#3{#1[#2]{#4}}}
+ {#1[#2]{#4}}//}
+\begingroup\catcode`\|=3% etb catcode
+\long\gdef\ettl@do@csvtolist#1{\unexpanded{#1}|}
+\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}}
+%% \listtocsv [\csvListMacro] \ListMacro
+%% \listtocsv* [\csvListMacro] { expanded List }
+% Recommended use: \edef\csvListMacro{\listtocsv\ListMacro}
+\newcommand\listtocsv[1]{\FE@ifstar{#1}{\ettl@convertlist{{\listloop*}\ettl@do@listtocsv}}
+ {\ettl@convertlist{\listloop\ettl@do@listtocsv}}}
+\long\def\ettl@do@listtocsv#1{\unexpanded{#1,}}
+%% \tokstolist [\ListMacro] { \toksListMacro / token token token }
+\newcommand\tokstolist[1]{\FE@ifstar{#1}{\ettl@convertlist{{\toksloop*}\ettl@do@tokstolist}}
+ {\ettl@convertlist{\toksloop\ettl@do@tokstolist}}}
+\begingroup\catcode`\|=3% etb catcode
+\long\gdef\ettl@do@tokstolist#1{\unexpanded{#1}|}
\endgroup
+%% \csvtolistadd \ListMacro \csvListMacro
+%% \csvtolistadd* \ListMacro {item,item,item}
+\newrobustcmd*\csvtolistadd{\@ifstar{\ettl@csvtolistadd*}{\ettl@csvtolistadd{}}}
+\long\def\ettl@csvtolistadd#1#2#3{\eappto#2{\csvtolist#1[]{#3}}}
+
+%% \tokstolistadd \ListMacro { \toksListMacro / token token token }
+\newrobustcmd*\tokstolistadd{\@ifstar{\ettl@tokstolistadd*}{\ettl@tokstolistadd{}}}
+\long\def\ettl@tokstolistadd#1#2#3{\eappto#2{\tokstolist#1[]{#3}}}
+\newrobustcmd\ettl@RemoveInList[2]{\begingroup
+ \def\ettl@RemoveInList##1{%
+ \edef\ettl@RemoveInList####1####2{%
+ \ettl@Rem@veInList{####1}####2\noexpandcs{##1->remove}\noexpandcs{##1->result}%
+ }\ettl@RemoveInList{#1}#2%
+ }\expandafter\ettl@RemoveInList\expandafter{\romannumeral0\@gobblescape#2}}
+\protected\long\def\ettl@Rem@veInList#1#2#3#4#5#6#7#8{%
+ \long\def#3[##1]##2#5#8#5##3##4/##5##6##7/End§List/{##6[##1+1]##2#5##3##4//##6##7/End§List/}%
+ \ifnotempty{#5}%% special case if no separator
+ {\long\def#4[##1]#5##2#5#5##3//##4/End§List/{\unexpanded{#1\def#7{##2#5}}%
+ \ettl@nbk#6//\ettl@setresult 1of1>#6<{\number\numexpr##1-1\relax}{}//}}%
+ {\long\def#4[##1]##2//##3/End§List/{\unexpanded{#1\def#7{##2}}%
+ \ettl@nbk#6//\ettl@setresult 1of1>#6<{\number\numexpr##1-1\relax}{}//}}%
+ \long\def#2##1{#3[0]#5##1#5#5#8#5//#3#4/End§List/}%
+ \edef#7{\endgroup\expandafter#2\expandafter{#7}}#7}
+\def\ettl@gobble@relax#1\relax{}
+
+%% \listdel \listMacro { item }
+%% \listgdel \listMacro { item }
+%% \listedel \listMacro { item }
+%% \listxdel \listMacro { item }
+\begingroup\catcode`\|=3
+\newrobustcmd\listdel[1][]{\ettl@RemoveInList{}\listdel|{#1}}
+\newrobustcmd\listgdel[1][]{\ettl@RemoveInList\global\listdel|{#1}}
+\newrobustcmd\listedel[1][]{\ettl@listedel{}\listdel|{#1}}
+\newrobustcmd\listxdel[1][]{\ettl@listedel\global\listdel|{#1}}
+\aftergroup@def\listdel
+\aftergroup@def\listgdel
+\aftergroup@def\listedel
+\aftergroup@def\listxdel
+\endgroup% \catcode group
+\newrobustcmd\ettl@listedel[6]{\begingroup\protected@edef#5{#6}\expandafter\endgroup
+ \expandafter\@swaparg\expandafter{#5}{\ettl@RemoveInList#1#2{#3}{#4}#5}}
+
+%% \csvdel \listMacro { item }
+%% \csvgdel \listMacro { item }
+%% \csvedel \listMacro { item }
+%% \csvxdel \listMacro { item }
+\newrobustcmd\csvdel[1][]{\ettl@RemoveInList{}\csvdel,{#1}}
+\newrobustcmd\csvgdel[1][]{\ettl@RemoveInList\global\csvdel,{#1}}
+\newrobustcmd\csvedel[1][]{\ettl@listedel{}\csvdel,{#1}}
+\newrobustcmd\csvxdel[1][]{\ettl@listedel\global\csvdel,{#1}}
+
+%% \toksdel \listMacro { item }
+%% \toksgdel \listMacro { item }
+%% \toksedel \listMacro { item }
+%% \toksxdel \listMacro { item }
+\newrobustcmd\toksdel[1][]{\ettl@RemoveInList{}\toksdel{}{#1}}
+\newrobustcmd\toksgdel[1][]{\ettl@RemoveInList\global\toksdel{}{#1}}
+\newrobustcmd\toksedel[1][]{\ettl@listedel{}\toksdel{}{#1}}
+\newrobustcmd\toksxdel[1][]{\ettl@listedel\global\toksdel{}{#1}}
+
+
+%% \getlistindex[\indexmacro]{ \Listmacro }
+%% \getlistindex*[\indexmacro]{ expanded List }
+\newrobustcmd\ettl@getlistindex[6][]{% #1=result, #2=\expandafter, #3=loop macro, #4=separator, #5=list of list macro, #6=item
+ \begingroup\def\ettl@getlistindex##1#4#6#4##2/End§List/{\endgroup
+ \romannumeral-`\q\ettl@setresult 1of1>#1<{\ettl@nbk##2//{#3*!{##1}}{-1}//}%
+ }#2\ettl@getlistindex#2#5#4#6#4/End§List/}
+\begingroup\catcode`\|=3% etb catcode
+\newrobustcmd\getlistindex[3][]{\@ifstar%
+ {\ettl@getlistindex{}\listloop{|}{#1}{#2}{#3}}
+ {\ifiscs{#1}{\ettl@getlistindex\expandafter\listloop|{#1}{#2}{#3}}
+ {\ettl@getlistindex{}\listloop|{#1}{#2}{#3}}}}
+\aftergroup@def\getlistindex
+\endgroup%\catcode group
+
+%\getcsvlistindex [\result]{ item }{ csvlistmacro }
+%\getcsvlistindex*[\result]{ item }{ item,item,item }
+\newrobustcmd\getcsvlistindex[3][]{\@ifstar%
+ {\ettl@getlistindex{}\csvloop{,}{#1}{#2}}
+ {\ifiscs{#1}{\ettl@getlistindex\expandafter\csvloop,{#1}{#2}}
+ {\ettl@getlistindex{}\csvloop,{#1}{#2}}}}
+\def\ettl@if@inlist#1#2{%#1=macro,#2=separator
+\newrobustcmd*#1{\@ifstar{\ettl@ifinlist{#2}{}}{\ettl@ifinlist{#2}\expandafter}}}
+\def\ettl@xif@inlist#1#2{%
+\newrobustcmd*#1{\@ifstar{\ettl@xifinlist{#2}{}}{\ettl@xifinlist{#2}\expandafter}}}
+\protected\long\def\ettl@ifinlist#1#2#3#4{\begingroup
+ \def\ettl@tempa##1#1##2#1/End§List/{\endgroup\ifnotblank{##2}%
+ }#2\ettl@tempa#2#1#3#1#4#1/End§List/}
+\protected\long\def\ettl@xifinlist#1#2#3#4{\begingroup
+ \protected@edef\ettl@tempa{\endgroup\ettl@ifinlist{#1}{#2}{#3}{#4}%
+ }\ettl@tempa}
-% \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}
+%% \ifincsvlist{ item }{ csvlistmacro }{ true }{ false }
+%% \ifincsvlist*{ item }{ item,item,item,... }{ true }{ false }
+%% \xifincsvlist{ item }{ csvlistmacro }{ true }{ false }
+%% \xifincsvlist*{ item }{ item,item,item,... }{ true }{ false }
+\ettl@if@inlist\ifincsvlist{,}
+\ettl@xif@inlist\xifincsvlist{,}
+\undef\ettl@if@inlist
+\undef\ettl@xif@inlist
+\DeclareOption{etoolbox}{%
+\renewcommand\ifblank[3]{\ettl@nbk #1//{#2}{#3}//}
+\renewcommand\ifdef[1]{\csname @\ifdefined#1first\else second\fi oftwo\endcsname}
+\renewcommand\ifcsdef[1]{\csname @\ifcsname#1\endcsname first\else second\fi oftwo\endcsname}
+\renewcommand\ifundef[1]{\csname @%
+ \ifdefined#1\ifx#1\relax first\else second\fi\else first\fi oftwo\endcsname}
+\renewcommand\ifcsundef[1]{\csname @%
+ \ifcsname#1\endcsname\expandafter\ifx\csname#1\endcsname\relax
+ first\else second\fi\else first\fi oftwo\endcsname}
+\edef\ifdefmacro#1{\unexpanded{\csname @%
+ \expandafter\ettl@ifdefmacro\meaning}#1\detokenize{macro:}/oftwo\endcsname}
+\edef\ettl@ifdefmacro{%
+ \def\noexpand\ettl@ifdefmacro##1\detokenize{macro:}##2/{\noexpand\ettl@nbk##2//{first}{second}//}%
+}\ettl@ifdefmacro
+\long\edef\ifcsmacro#1{\unexpanded{\csname @%
+ \expandafter\expandafter\expandafter\ettl@ifdefmacro\meaningcs}{#1}\detokenize{macro:}/oftwo\endcsname}
+\renewcommand\ifdefparam[1]{\csname @%
+ \ettl@expandaftwo\ettl@nbk\expandafter\ettl@params@meaning\meaning#1///{first}{second}//oftwo\endcsname}
+\renewcommand\ifcsparam[1]{\csname @%
+ \expandafter\expandafter\expandafter\ettl@nbk\parameters@meaningcs{#1}//{first}{second}//oftwo\endcsname}
+\renewcommand\ifnumcomp[3]{\csname @%
+ \ifnum\numexpr#1#2\numexpr#3 first\else second\fi oftwo\endcsname}
+}% etoolbox option
+\ProcessOptions
\endinput