summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/etextools
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-08-15 23:34:56 +0000
committerKarl Berry <karl@freefriends.org>2009-08-15 23:34:56 +0000
commit27f9cb520563a0b8df6d876f02cdb267be5b6116 (patch)
tree9ad3871f8a40fcf6450053e16e3f6f8b1addfb8a /Master/texmf-dist/tex/latex/etextools
parentbf8d9b1bb7480816950fe25c98685724d843378e (diff)
etextools update (15aug09)
git-svn-id: svn://tug.org/texlive/trunk@14694 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/etextools')
-rw-r--r--Master/texmf-dist/tex/latex/etextools/etextools.sty354
1 files changed, 268 insertions, 86 deletions
diff --git a/Master/texmf-dist/tex/latex/etextools/etextools.sty b/Master/texmf-dist/tex/latex/etextools/etextools.sty
index e11696396a5..791e2fd2c1c 100644
--- a/Master/texmf-dist/tex/latex/etextools/etextools.sty
+++ b/Master/texmf-dist/tex/latex/etextools/etextools.sty
@@ -21,29 +21,45 @@
%% etextools.sty, etextools.pdf, etextools.ins,
%% and etextools-examples.tex
%%
-%%% etextools : more e-TeX useful tools for LaTeX package writers
+%%% etextools : more e-TeX useful tools for LaTeX package writers (v.
+
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
\ProvidesPackage{etextools}
- [2009/07/14 v2e e-TeX more useful tools for LaTeX package writers]
+ [2009/08/14 v2h e-TeX more useful tools for LaTeX package writers]
\csname ettl@onlyonce\endcsname\let\ettl@onlyonce\endinput
\RequirePackage{etex,etoolbox}
-\edef\ettl@restore@space@catcode{\catcode`\ =\the\catcode`\ }
-\AtEndOfPackage{\ettl@restore@space@catcode
- \let\ettl@restore@space@catcode\ettl@undefined}
-\catcode`\ =10
+\let\ettl@AtEnd\@empty
+\def\TMP@EnsureCode#1#2{%
+ \edef\ettl@AtEnd{%
+ \ettl@AtEnd
+ \catcode#1 \the\catcode#1\relax
+ }%
+ \catcode#1 #2\relax
+}
+\TMP@EnsureCode{32}{10}% space
+\ifundef\pdfstrcmp{%
+ \TMP@EnsureCode{33}{9}% ! ignore
+ \TMP@EnsureCode{34}{14}% " comment
+}{\TMP@EnsureCode{33}{14}% ! comment
+ \TMP@EnsureCode{34}{9}% " ignore
+}
+\AtEndOfPackage{\ettl@AtEnd\undef\ettl@AtEnd}
% A few helper macros
\long\def\ettl@afterelse#1\else#2\fi{\fi#1}
\long\def\ettl@afterfi#1\fi{\fi#1}
\long\def\ettl@afterfifi#1\fi\fi{\fi\fi#1}
\long\def\ettl@afterelsefi#1\else#2\fi\fi{\fi#1}
-\begingroup\catcode`\|=4
-\long\gdef\ettl@cdr#1#2|{#2}
-\endgroup
+\long\def\ettl@afterorfi#1\or#2\fi{\fi#1}
+\def\ettl@ifstrcmp#1#2{\csname @%
+ \ifnum\pdfstrcmp{#1}{#2}=0 first\else second\fi oftwo\endcsname}
\newcommand*\@gobblescape{\expandafter\@gobble\string}
-\newcommand\str@gobblescape[1]{\expandafter\deblank\expandafter{%
- \expandafter\@gobble\detokenize{#1}}}
+\def\ettl@onlypdfTeX#1#2{\ifundef{#1}
+ {\def#2{\PackageError{etextools}{\string#1\space primitive not found\MessageBreak
+ pdfTeX seems not to be running}
+ {\string#2\space works only if used with pdfTeX (requires \string#1)}}}
+ {}}
\newcommand*\noexpandcs[1]{\expandafter\noexpand\csname #1\endcsname}
\newcommand\noexpandafter{\noexpand\expandafter}
@@ -64,47 +80,94 @@
\expandafter\ettl@afterfi#2#1#2{#3}%
\fi}
-\newcommand\deblank{}
-\newcommand\ifempty{}
-\begingroup\catcode`\|=4% a | as a tab array
-\long\gdef\deblank#1{\@deblank#1 |}
-\long\gdef\@deblank#1 #2|{\ifblank{#2}{#1}{#1\@deblank#2 |}}
% \ifempty{ text }{ true }{ false }
-\long\gdef\ifempty#1{\csname @\ifx|#1|first\else second\fi oftwo\endcsname}
-\endgroup% catcode group
+\newcommand\ifempty[1]{\csname @\expandafter\ifx
+ \expandafter\relax\detokenize{#1}\relax
+ first\else second\fi oftwo\endcsname}
+
+% \ifnotempty{ text }{ true }{ false }
+\newcommand\ifnotempty[1]{\csname @\expandafter\ifx
+ \expandafter\relax\detokenize{#1}\relax
+ second\else first\fi oftwo\endcsname}
+
+% \xifempty{ text }{ true }{ false }
+\newcommand\xifempty[1]{\xifstrcmp{#1}{}}
+\ettl@onlypdfTeX\pdfstrcmp\xifempty
+
+% \ifnotblank{ text }{ true }{ false }
+\begingroup\catcode`\&=3\catcode`\:=12
+\ifcsundef{ifnotblank}{%
+\long\gdef\ifnotblank#1{\etb@ifblank@i#1&&\@firstoftwo\@secondoftwo:}}
+\relax\endgroup
+% \xifblank{ string }{ true }{ false }
\newrobustcmd\xifblank[1]{\begingroup
\protected@edef\@xifblank{\endgroup
\noexpand\ifblank{#1}%
}\@xifblank}
-\newrobustcmd\xifstrequal[2]{%
- \begingroup\protected@edef\@tempa{#1}\protected@edef\@tempb{#2}%
- \ifx\@tempa\@tempb \aftergroup\@firstoftwo
- \else \aftergroup\@secondoftwo
- \fi\endgroup}
-\newcommand\iffirstchar[2]{%
- \if \expandafter\@car\string#2\relax\@nil\expandafter\@car#1\string\\\@nil
- \ettl@afterelse\ifblank{#2}\@secondoftwo\@firstoftwo
- \else \expandafter\@secondoftwo
- \fi}
-\newcommand\ifsinglechar{}
-\begingroup\catcode`\|=4
-\long\gdef\ifsinglechar#1#2{%
- \csname @\expandafter\expandafter\expandafter\ifx
- \expandafter\expandafter\expandafter|%
- \expandafter\ettl@cdr\string#2||first\else second\fi
- oftwo\endcsname
- {\iffirstchar{#1}{#2}}
- \@secondoftwo}
-\endgroup% catcode group
-%\FE@testopt{#1}{commands}{default option}
+% \iffirstchar{ string1 }{ string2 }{ true }{ false }
+\newcommand\iffirstchar[2]{\csname @%
+ \if \expandafter\@car\detokenize{#2}\relax\@nil\expandafter\@car\detokenize{#1}\string\\\@nil
+ \ifblank{#2}{second}{first}%
+ \else second%
+ \fi oftwo\endcsname}
+
+% \ifsinglechar character{ string }{ true }{ false }
+\newcommand\ifsinglechar[2]{%
+ \csname @\ifblank{#2}{second}{%
+" \ifnum\pdfstrcmp{\detokenize{#1}}{\detokenize{#2}}=0
+" \ifnum\pdfstrcmp{\detokenize{#2}}{\expandafter\@car\detokenize{#2}\relax\@nil}=0
+" first%
+" \else second%
+" \fi
+" \else second%
+" \fi oftwo\endcsname}}
+! \expandafter\expandafter\expandafter\ifx
+! \expandafter\expandafter\expandafter\relax\expandafter\@cdr\detokenize{#2}\@nil\relax
+! \iffirstchar{#1}{#2}{first}{second}\else second\fi oftwo\endcsname}}
+
+% \iflastchar{ string1 }{ string2 }{ true }{ false }
+\begingroup\catcode`\&=3
+\long\gdef\iflastchar#1#2{%
+ \long\def\ettl@iflastchar##1#1##2&{%
+ \ifstrcmp{##2}{#1}\@firstoftwo{%
+ \ifempty{##2}\@secondoftwo{\ettl@iflastchar##2&}}
+ }\ettl@iflastchar#2#1&}
+\endgroup
+
+% \ifstrcmp{ string1 }{ string2 }{ true }{ false }
+\newcommand\ifstrcmp[2]{\csname @%
+ \ifnum\pdfstrcmp{\detokenize{#1}}{\detokenize{#2}}=0 first\else second\fi
+ oftwo\endcsname}
+\ettl@onlypdfTeX\pdfstrcmp\ifstrcmp
+
+% \xifstrcmp{ string1 }{ string2 }{ true }{ false }
+\newcommand\xifstrcmp[2]{\csname @%
+ \ifnum\pdfstrcmp{#1}{#2}=0 first\else second\fi
+ oftwo\endcsname}
+\ettl@onlypdfTeX\pdfstrcmp\ifxstrcmp
+\newrobustcmd*\xifstrequal[2]{\begingroup
+ \protected@edef\@xifstrequal{\endgroup\noexpand\ifstrequal{#1}{#2}%
+ }\@xifstrequal}
+
+% \ifstrmatch{ pattern }{ true }{ false }
+\newcommand\ifstrmatch[2]{\csname @%
+ \ifnum\pdfmatch{\detokenize{#1}}{\detokenize{#2}}=1 first\else second\fi
+ oftwo\endcsname}
+\ettl@onlypdfTeX\pdfmatch\ifstrmatch
+%----------------------------------------------------------------------------
+% Purely Expandable Macros With Options / Star Forms / Variants
+% \FE@testopt{ #1 }{ commands }{ default option }
\newcommand\FE@testopt[3]{\ifsinglechar [{#1}{#2#1}{#2[{#3}]{#1}}}
-%\FE@ifstar{#1}{\StarredMacro}{\NotStarredMacro}
+% \FE@ifstar{ #1 } { \StarredMacro }{ \NotStarredMacro }
\newcommand\FE@ifstar[3]{\ifsinglechar *{#1}{#2}{#3{#1}}}
+% \FE@ifchar{#1}{#2}{ \SpecialFormMacro }{ \NormalMacro }
+\newcommand\FE@ifchar[4]{\ifsinglechar{#1}{#2}{#3}{#4{#2}}}
+
%% \iffalse
% \DeclareCmdListParser : general constructor for command-list parsers
@@ -118,16 +181,12 @@
\def\`##1`{\expandafter\noexpand\csname ##1\endcsname}%
\protected@edef\defineparser{\endgroup
\long\def#1####1{\noexpand\FE@ifstar{####1}
- {\`ettl@lst@star\string#1`}
- {\`ettl@lst@nost\string#1`}}%
- \long\csdef{ettl@lst@star\string#1}####1{\noexpand\FE@testopt{####1}
- {\`ettl@lst@star@pt\string#1`}{\noexpand\do}}%
- \long\csdef{ettl@lst@nost\string#1}####1{\noexpand\FE@testopt{####1}
- {\`ettl@lst@nost@pt\string#1`}{\noexpand\do}}%
- \long\csdef{ettl@lst@star@pt\string#1}[####1]####2{%
- \`ettl@lst\string#1`{####2}{####1}}%
- \long\csdef{ettl@lst@nost@pt\string#1}[####1]####2{%
- \noexpandafter\`ettl@lst\string#1`\noexpandafter{####2}{####1}}%
+ {\`ettl@lst@opt\string#1`{}}
+ {\`ettl@lst@opt\string#1`\noexpandafter}}%
+ \long\csdef{ettl@lst@opt\string#1}####1####2{\noexpand\FE@testopt{####2}
+ {\`ettl@lst@@pt\string#1`{####1}}{\noexpand\do}}%
+ \long\csdef{ettl@lst@@pt\string#1}####1[####2]####3{%
+ ####1\`ettl@lst\string#1`####1{####3}{####2}}%
\long\csdef{ettl@lst\string#1}####1####2{%
\`ettl@lst@\string#1`{####2}####1\unexpanded{#2}&}%
\long\csdef{ettl@lst@\string#1}####1####2\unexpanded{#2}####3&{%
@@ -149,20 +208,29 @@
\begingroup\catcode`\|=3
\def\do{\DeclareCmdListParser\listloop{|}}%
\expandafter\endgroup\do
+\DeclareCmdListParser\toksloop{}%
+
+% \csvtolist \ListMacro \csvListMacro
+% \csvtolist* \ListMacro {item,item,item}
+\newrobustcmd*\csvtolist{\@ifstar
+ {\ettl@tolist\z@{}\csvloop}
+ {\ettl@tolist\z@\expandnext\csvloop}}%
+\long\def\ettl@tolist#1#2#3#4#5{\ifx#1\z@\let#4\@empty\fi
+ \def\ettl@to@list{#3*[{\unexpanded{\listadd#4}}]%
+ }#2\ettl@to@list{#5}}
-%\csvtolist\csvListMacro
-%\csvtolist*{item,item,item}
-\newcommand\csvtolist{\@ifstar\star@csvtolist\nost@csvtolist}%
-\def\star@csvtolist#1{\let#1\@empty\csvloop*[{\unexpanded{\listadd#1}}]}%
-\def\nost@csvtolist#1{\let#1\@empty\csvloop[{\unexpanded{\listadd#1}}]}%
+\newrobustcmd*\tokstolist{\@ifstar{\ettl@tokstolist\z@{}}{\ettl@tokstolist\z@\expandnext}}
+\def\ettl@tokstolist#1#2#3#4{\ifx#1\z@\let#3\@empty\fi
+ \def\ettl@toks@tolist{\toksloop*[{\unexpanded{\listadd#3}}]}%
+ #2\ettl@toks@tolist{#4{}}}
-%\csvtolistadd\csvListMacro
-%\csvtolistadd*{item,item,item}
-\newcommand\csvtolistadd{\@ifstar\star@csvtolistadd\nost@csvtolistadd}%
-\def\star@csvtolistadd#1#2{\ifblank{#2}
- {\let#1\@empty}{\csvloop*[{\unexpanded{\listadd#1}}]{#2}}}%
-\def\nost@csvtolistadd#1#2{\ifblank{#2}
- {\let#1\@empty}{\csvloop[{\unexpanded{\listadd#1}}]{#2}}}%
+% \csvtolistadd \ListMacro \csvListMacro
+% \csvtolistadd* \ListMacro {item,item,item}
+\newrobustcmd*\csvtolistadd{\@ifstar
+ {\ettl@tolist\@ne{}\csvloop}
+ {\ettl@tolist\@ne\expandnext\csvloop}}
+
+\newrobustcmd*\tokstolistadd{\@ifstar{\ettl@tokstolist\@ne{}}{\ettl@tokstolist\@ne\expandnext}}%
%\listdel\listMacro{item}
%\listgdel\listMacro{item}
@@ -181,11 +249,11 @@
\begingroup\catcode`\|=3\catcode`\&=3
\long\gdef\@listdel#1#2#3{%
\begingroup
- \def\@tempa##1|#3|##2&{##1|##2\@tempb}%
- \def\@tempb|##1|\@tempb##2|\@tempb{%
+ \long\def\@tempa##1|#3|##2&{##1|##2\@tempb}%
+ \long\def\@tempb|##1|\@tempb##2|\@tempb{%
\ifblank{##2}{\unexpanded{##1}}
{\ifblank{##1}{}{\@tempx##1&}}}%
- \def\@tempx##1&{\expandafter\@tempb\@tempa|##1|\@tempb|#3|&}%
+ \long\def\@tempx##1&{\expandafter\@tempb\@tempa|##1|\@tempb|#3|&}%
\edef\@redef{\endgroup
\unexpanded{#1#2}{% ie: \def or \gdef \listmacro
\expandafter\@tempx\unexpanded\expandafter{#2}&}%
@@ -193,39 +261,153 @@
\endgroup
-% \getlistindex (result in \indexinlist)
+% \getlistindex[\indexmacro]{ \listmacro }
+% \getlistindex*[\indexmacro]{ expanded list }
+\newcommand\getlistindex[1]{\FE@ifstar{#1}
+ {\ettl@getlistindex{}\unexpanded}
+ {\ettl@getlistindex\expandnext\unexpanded}}
+\newcommand\xgetlistindex[1]{\FE@ifstar{#1}
+ {\ettl@getlistindex{}\@firstofone}
+ {\ettl@getlistindex\expandnext\@firstofone}}
\begingroup\catcode`\|=3\catcode`\&=3
-\gdef\getlistindex#1{\FE@ifstar{#1}{\ettl@getlistindex{}}
- {\ettl@getlistindex\expandnext}}
-\gdef\xgetlistindex#1{\FE@ifstar{#1}{\ettl@xgetlistindex{}}
- {\ettl@xgetlistindex\expandnext}}
-\gdef\ettl@xgetlistindex#1#2#3{\begingroup
- \protected@edef\next{\endgroup\unexpanded{\ettl@getlistindex{#1}{#2}}{#3}%
- }\next}
-\gdef\ettl@getlistindex#1#2#3{\begingroup#1\ettl@get@list@idx{#3}{#2}{\numexpr1}}
-\gdef\ettl@get@list@idx#1#2#3{% #1=expanded list, #2=item, #3=index
+\long\gdef\ettl@getlistindex#1#2#3{\FE@testopt{#3}{\ettl@get@listindex{#1}{#2}}{}}
+\long\gdef\ettl@get@listindex#1#2[#3]#4#5{#1\ettl@get@list@idx{#5}{#4}{\numexpr1}{#2}[{#3}]}
+\long\gdef\ettl@get@list@idx#1#2#3#4[#5]{% #1=expanded list, #2=item, #3=index, #4=\unexpanded (event., #5=indexmacro)
+ \ifblank{#1}0% the (remainder of) the list is empty
+" {\xifstrcmp{\expandonce{\ettl@list@first@item#1&}}{#4{#2}}}
+! {\ettl@listitem@cmp{\ettl@list@first@item#1&}{#2}{#4}}
+ {\ifblank{#5}{\number#3\relax}{\ettl@ifiscount{#5}{#5=\number#3\relax}{\edef#5{\number#3}}}}
+ {\expandnext\ettl@get@list@idx{\ettl@list@other@item#1&}{#2}{#3+1}{#4}[{#5}]}}
+\long\gdef\ettl@list@first@item#1|#2&{#1}
+\long\gdef\ettl@list@other@item#1|#2&{#2}
+!\long\gdef\ettl@listitem@cmp#1#2#3{%
+! \ifx#3\unexpanded\def\ettl@listitem@cmp@{#2}%
+! \else\protected@edef\ettl@listitem@cmp@{#2}%
+! \fi
+! \expandafter\ifstrequal\expandafter{#1}{#2}}
+\edef\ettl@ifiscount{%
+ \gdef\noexpand\ettl@ifiscount##1{%
+ \noexpand\expandafter\noexpand\ettl@ifiscount@i
+ \noexpand\meaning##1\string\count\noexpand\@nil}%
+}\ettl@ifiscount
+\edef\ettl@ifiscount@i{%
+ \gdef\noexpand\ettl@ifiscount@i##1\string\count##2\noexpand\@nil{%
+ \noexpand\ifempty{##1}}%
+}\ettl@ifiscount@i
+
+%\getcsvlistindex{ item }{ csvlistmacro }
+%\getcsvlistindex*{ item }{ item,item,item }
+\long\gdef\getcsvlistindex#1{\FE@ifstar{#1}
+ {\ettl@getcsvlistindex{}\unexpanded}
+ {\ettl@getcsvlistindex\expandnext\unexpanded}}
+\long\gdef\xgetcsvlistindex#1{\FE@ifstar{#1}
+ {\ettl@getcsvlistindex{}\@firstofone}
+ {\ettl@getcsvlistindex\expandnext\@firstofone}}
+\long\gdef\ettl@getcsvlistindex#1#2#3{\FE@testopt{#3}{\ettl@get@csvlistindex{#1}{#2}}{}}
+\long\gdef\ettl@get@csvlistindex#1#2[#3]#4#5{#1\ettl@get@csvlist@idx{#5}{#4}{\numexpr1}{#2}[{#3}]}
+\long\gdef\ettl@get@csvlist@idx#1#2#3#4[#5]{% #1=expanded list, #2=item, #3=index, #4=\unexpanded (event., #5=indexmacro)
+ \ifblank{#1}0% the (remainder of) the list is empty
+" {\xifstrcmp{\expandonce{\ettl@csvlist@first@item#1&}}{#4{#2}}}
+! {\ettl@listitem@cmp{\ettl@csvlist@first@item#1&}{#2}{#4}}
+ {\ifblank{#5}{\number#3\relax}{\ettl@ifiscount{#5}{#5=\number#3\relax}{\edef#5{\number#3}}}}
+ {\expandnext\ettl@get@csvlist@idx{\ettl@csvlist@other@item#1&}{#2}{#3+1}{#4}[{#5}]}}
+\long\gdef\ettl@csvlist@first@item#1,#2&{#1}
+\long\gdef\ettl@csvlist@other@item#1,#2&{#2}
+
+%\gettokslistindex{ item }{ tokenslistmacro }
+%\gettokslistindex*{ item }{ list of tokens }
+\long\gdef\gettokslistindex#1{\FE@ifstar{#1}
+ {\ettl@gettokslistindex{}}
+ {\ettl@gettokslistindex\expandnext}}
+\long\gdef\ettl@gettokslistindex#1#2{\FE@testopt{#2}{\ettl@get@tokslistindex{#1}}{}}
+\long\gdef\ettl@get@tokslistindex#1[#2]#3#4{#1\ettl@get@tokslist@idx{#4}{#3}{\numexpr1}[{#2}]}
+\long\gdef\ettl@get@tokslist@idx#1#2#3[#4]{% #1=expanded list, #2=item, #3=index
\ifblank{#1}0% the (remainder of) the list is empty
- {\expandnext\ifstrequal{\ettl@list@first@item#1&}{#2}
- {\endgroup\edef\indexinlist{\number#3\relax}}
- {\expandnext\ettl@get@list@idx{\ettl@list@other@item#1&}{#2}{#3+1}}}}
-\gdef\ettl@list@first@item#1|#2&{#1}
-\gdef\ettl@list@other@item#1|#2&{#2}
+ {\expandafter\ifx\expandafter#2\ettl@tokslist@first@item#1&%
+ \ettl@afterelse\ifblank{#4}{\number#3\relax}
+ {\ettl@ifiscount{#4}{#4=\number#3\relax}{\edef#4{\number#3}}}%
+ \else \ettl@afterfi
+ \expandnext\ettl@get@tokslist@idx{\ettl@tokslist@other@item#1&}{#2}{#3+1}[{#4}]%
+ \fi}}
+\long\gdef\ettl@tokslist@first@item#1#2&{#1}
+\long\gdef\ettl@tokslist@other@item#1#2&{#2}
\endgroup% catcode group
-\newcommand\getlistitem[1]{\FE@ifstar{#1}\ettl@getlistitem
- {\expandnext\ettl@getlistitem}}
+
+
+%\getlistitem{ number }{ listmacro }
+%\getlistitem*{ number }{ listmacro }
+\newcommand\getlistitem[1]{\FE@ifstar{#1}{\ettl@getlistitem{}}
+ {\ettl@getlistitem\expandnext}}
\begingroup\catcode`\&=3
-\long\gdef\ettl@getlistitem#1#2{%#1=listmacro, #2=index
- \ettl@get@list@item{#1}{\number\numexpr#2}}
+\long\gdef\ettl@getlistitem#1#2#3{%#2=index, #3=list or list-macro
+ #1\ettl@get@list@item{#3}{\numexpr#2}}
\long\gdef\ettl@get@list@item#1#2{%
\ifblank{#1}{}
{\ifnum#2=1 \ettl@afterelsefi
- \expandonce{\ettl@list@first@item#1&}
+ \expandonce{\ettl@list@first@item#1&}%
\else\ifnum#2>0 \ettl@afterfifi
- \expandnext\ettl@getlistitem{\ettl@list@other@item#1&}{#2-1}%
+ \expandnext\ettl@get@list@item{\ettl@list@other@item#1&}{#2-1}%
\fi\fi}}
\endgroup
+% \getcsvlistitem{ number }{ csvlistmacro }
+% \getcsvlistitem*{ number }{ item,item,item,... }
+\newcommand\getcsvlistitem[1]{\FE@ifstar{#1}{\ettl@getcsvlistitem{}}
+ {\ettl@getcsvlistitem\expandnext}}
+\begingroup\catcode`\&=3
+\long\gdef\ettl@getcsvlistitem#1#2#3{%#2=index, #3=list or list-macro
+ #1\ettl@get@csvlist@item{#3,}{\numexpr#2}}
+\long\gdef\ettl@get@csvlist@item#1#2{%
+ \ifblank{#1}{}
+ {\ifnum#2=1 \ettl@afterelsefi
+ \expandonce{\ettl@csvlist@first@item#1&}%
+ \else\ifnum#2>0 \ettl@afterfifi
+ \expandnext\ettl@get@csvlist@item{\ettl@csvlist@other@item#1&}{#2-1}%
+ \fi\fi}}
+\endgroup
+
+
+% \gettokslistitem{ number }{ tokslistmacro }
+% \gettokslistitem*{ number }{ list of tokens }
+\newcommand\gettokslistitem[1]{\FE@ifstar{#1}{\ettl@gettokslistitem{}}
+ {\ettl@gettokslistitem\expandnext}}
+\begingroup\catcode`\&=3
+\long\gdef\ettl@gettokslistitem#1#2#3{%#2=index, #3=list or list-macro
+ #1\ettl@get@tokslist@item{#3{}}{\numexpr#2}}
+\long\gdef\ettl@get@tokslist@item#1#2{%
+ \ifblank{#1}{}
+ {\ifnum#2=1 \ettl@afterelsefi
+ \expandonce{\ettl@tokslist@first@item#1&}%
+ \else\ifnum#2>0 \ettl@afterfifi
+ \expandnext\ettl@get@tokslist@item{\@gobble#1}{#2-1}%
+ \fi\fi}}
+\endgroup
+%----------------------------------------------------------------------------
+
+% \collectoks{ cs-token }{ list of allowed tokens }{ commands to expand after }
+
+\newrobustcmd*\collecttoks{\@ifstar\ettl@scantoks\ettl@collecttoks}
+\def\ettl@scantoks{\@latex@error{The starred version of \noexpand\collecttoks
+ \MessageBreak (i.e. scantoks) is NOT implemented YET.}\@ehd}
+
+\def\ettl@collecttoks#1#2#3{\begingroup
+ \def\ettl@collecttoks@list{#2}%
+ \let#1=\@empty
+ \def\Next{\ettl@collect@toks{#1}}%
+ \def\finale{#3}%
+ \futurelet\ettl@x\Next}
+\def\ettl@collect@toks#1{%
+ \edef\ettl@i{\gettokslistindex\ettl@x\ettl@collecttoks@list}%
+ \ifcase\ettl@i \edef\next{\endgroup
+ \def\noexpand#1{\expandonce{#1}}\expandonce{\finale}}%
+ \else \def\next{\ettl@collect@toks@next{#1}}%
+ \fi\next}
+\def\ettl@collect@toks@next#1#2{%
+ \edef#1{\expandonce{#1}\unexpanded{#2}}%
+ \futurelet\ettl@x\Next}
+
+
\endinput
%%
%% End of file `etextools.sty'.