%% %% This is file `etextools.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% etextools.dtx (with options: `package') %% %% This is a generated file. %% %% Copyright (C) 2009 by Florent Chervet %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either %% version 1.3 of this license or (at your option) any later %% version. The latest version of this license is in %% http://www.latex-project.org/lppl.txt %% %% 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 : more e-TeX useful tools for LaTeX package writers (v. \NeedsTeXFormat{LaTeX2e}[1996/12/01] \ProvidesPackage{etextools} [2009/08/14 v2h e-TeX more useful tools for LaTeX package writers] \csname ettl@onlyonce\endcsname\let\ettl@onlyonce\endinput \RequirePackage{etex,etoolbox} \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} \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} % \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}% \fi} \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} % \ifempty{ text }{ true }{ false } \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} % \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 } \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 % \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 % \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 \endgroup % \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 % \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'.