diff options
Diffstat (limited to 'Master/texmf-dist/tex/generic/xstring/xstring.tex')
-rw-r--r-- | Master/texmf-dist/tex/generic/xstring/xstring.tex | 259 |
1 files changed, 125 insertions, 134 deletions
diff --git a/Master/texmf-dist/tex/generic/xstring/xstring.tex b/Master/texmf-dist/tex/generic/xstring/xstring.tex index 7e2b35779e5..48320845680 100644 --- a/Master/texmf-dist/tex/generic/xstring/xstring.tex +++ b/Master/texmf-dist/tex/generic/xstring/xstring.tex @@ -1,9 +1,9 @@ % __________________________________________________ % | | % | | -% | xstring v1.5 | +% | xstring v1.5a | % | | -% | December 31 2008 | +% | February 9 2009 | % | | % |__________________________________________________| % @@ -18,7 +18,7 @@ % test_latex.tex, test_latex.pdf (test file with LaTeX) % test_etex.tex, test_etex.pdf (test file with Plain eTeX) % -% Christian Tellechea 2008-2009 +% Christian Tellechea 2009 % email : unbonpetit@gmail.com % ------------------------------------------------------------------- % This work may be distributed and/or modified under the @@ -35,16 +35,14 @@ % % The Current Maintainer of this work is Christian Tellechea % ------------------------------------------------------------------- -\def\xstringversion {1.5} -\def\xstringdate {2008/12/31} -\def\xstringfrenchdate {31 d\'ecembre 2008} -\def\xstringenglishdate{December $31^{\mathrm{st}}$ 2008} -\edef\CurrentAtCatcode{\the\catcode`\@} +\def\xstringversion {1.5a} +\def\xstringdate {2009/02/09} +\def\xstringfrenchdate {9 f\'evrier 2009} +\def\xstringenglishdate {February $9^{\mathrm{th}}$ 2009} +\edef\CurrentAtCatcode {\the\catcode`\@} \catcode`\@=11 -\newwrite\@xs@unused% pour les messages -\newcount\@xs@count -\newcount\integerpart% pour les tests sur les nombres -\newcount\decimalpart +\newwrite\@xs@message% canal pour les messages +\newcount\integerpart\newcount\decimalpart% compteurs utilis\'es par xstring \expandafter\ifx\csname @latexerr\endcsname\relax% on n'utilise pas LaTeX ? \immediate\write\m@ne{Package: xstring \xstringdate\space\space v\xstringversion\space\space String manipulations (C Tellechea)}% @@ -73,35 +71,6 @@ \def\@empty{} \fi% fin des d\'efinitions LaTeX -% Gestion des messages d'erreur -\def\@xs@linenumber{on input line \the\inputlineno} - -\def\@xs@errorwrite#1#2{% - \begingroup - \newlinechar`\^^J% - \errhelp{#2}% - \errmessage{Package xstring Error: \@xs@linenumber\space#1^^J% - See user manual for further information.^^J% - Type \space H <return> \space for immediate help.}% - \endgroup} - -\def\@xs@warningwrite#1{% - \begingroup - \newlinechar`\^^J% - \immediate\write\@xs@unused{Package xstring Warning: #1 \@xs@linenumber^^J}% - \endgroup} - -\def\@xs@infowrite#1{% - \begingroup - \newlinechar`\^^J% - \immediate\write\m@ne{Package xstring Info: #1}% - \endgroup} - -% Messages d'information pour situations particuli\`eres -\def\@xs@BadNumArg {\@xs@infowrite{numerical argument out of range}} -\def\@xs@ArgNotFound {\@xs@infowrite{substring not found in string}} -\def\@xs@ArgEmpty {\@xs@infowrite{empty argument}} - % Ouvre un groupe o\`u les catcodes sont \`a 12 et \`a 10 pour les espaces % ensuite, appelle \@xs@ReadVerb qui lit un argument entre d\'elimiteurs verb \def\@xs@MakeVerb{% lit 1 argument et le transforme en verb @@ -115,63 +84,21 @@ \def\setverbdelim#1{% d\'efinit quel est le d\'elimiteur de verb \expandafter\ifx\expandafter\@empty\detokenize\expandafter{\@xs@gobblefirstchar#1}\@empty \else - \@xs@warningwrite{verb delimiter is not a single char}% + \begingroup + \newlinechar`\^^J% + \immediate\write\@xs@message + {Package xstring Warning: verb delimiter is not a single token on input line \the\inputlineno^^J}% + \endgroup \fi \def\@xs@ReadVerb##1#1##2#1{% lit ##2 qui est entre les d\'elimiteurs de verb \endgroup% on ferme le groupe \@xs@afterreadverb{##2}}}% on appelle l'ex\'ecution de fin -% Assigne l'argument entre d\'elimiteur verb dans la sc #1 +% Assigne l'argument entre d\'elimiteur verb dans la sc #1' + \def\verbtocs#1{% - \def\@xs@afterreadverb##1{\edef#1{##1}}% + \def\@xs@afterreadverb##1{\def#1{##1}}% \@xs@MakeVerb} -% D\'eveloppe d'un niveau toutes les unit\'es syntaxiques -% de #1 puis et assigne le r\'esultat \`a \@xs@reserved@A -\def\@xs@expandallonelevel#1#2\@xs@nil{% - \expandafter\@xs@addtomacro\expandafter\@xs@reserved@A\expandafter{#1}% - \ifx\@empty#2\@empty - \else - \def\@xs@next{\@xs@expandallonelevel#2\@xs@nil}% - \expandafter\@xs@next - \fi}% s'il reste des sc, on boucle - -\def\@xs@notestcs#1\@xs@nil{\relax}% -\def\@xs@testcs#1#2\@xs@nil{% - \ifx\@empty#2\@empty - \else% si la s\'equence de contr\^ole n'est pas seule, on gueule - \@xs@errorwrite{third argument or its expansion^^Jis not a single control sequence! Use \string\scancs* instead of \string\scancs (see manual).}{With \scancs, the third argument (or one of its expansion) cannot contain^^Jmore than one control sequence. If so, use the starred version \scancs*,^^Jand read manual for more information about this starred version...}% - \fi} - -% \scancs d\'eveloppe #3 autant de fois que sp\'ecifi\'e en #1 -% puis le d\'eveloppement obtenu est verbatimis\'e. -% On utilise \@xs@expandalltodepth autant de fois que #1 le sp\'ecifie -% puis on invoque \detokenize \`a la fin -\def\scancs{% - \@ifstar% - {\@xs@warningwrite{\string\scancs* has limitations: ^^Jif third argument or its expansion have braces or spaces,^^Jthey will be removed when scanned}% - \def\@xs@testornot{\@xs@notestcs}% - \@xs@scancs}% - {\def\@xs@testornot{\@xs@testcs}% - \@xs@scancs}} -\def\@xs@scancs{\@ifnextchar[{\@xs@scancs@}{\@xs@scancs@[1]}} -\def\@xs@scancs@[#1]#2#3{% -% #1 : profondeur \`a d\'evelopper avant de verbatimiser -% #2 : nom de la sc recevant la chaine verb -% #3 : nom de la sc \`a d\'evelopper et \`a transformer en verb - \def\@xs@expandalltodepth##1{% d\'eveloppe de #1 niveaux toutes les sc de #3 et l'assigne \`a \@xs@reserved@B - \let\@xs@reserved@A\@empty% - \ifnum##1<#1\relax% tant que la profondeur de d\'eveloppement n'est pas atteinte - \expandafter\@xs@testornot\@xs@reserved@B\@xs@nil% on teste \'eventuellement si le d\'eveloppement comporte 1 seule sc - \expandafter\@xs@expandallonelevel\@xs@reserved@B\@xs@nil% on d\'eveloppe tout d'un niveau - \let\@xs@reserved@B\@xs@reserved@A% - \def\@xs@next{\expandafter\@xs@expandalltodepth\expandafter{\number\numexpr##1+1}}% - \expandafter\@xs@next% et on recommence - \fi}% - \def\@xs@reserved@B{#3}% - \@xs@expandalltodepth\z@ - \expandafter\def\expandafter#2\expandafter{\detokenize\expandafter{\@xs@reserved@B}}} - % Cette macro d\'eveloppe \'eventuellement #2 % puis le transforme en token et l'assigne \`a #1 \begingroup% on ouvre un groupe o\`u... @@ -190,10 +117,10 @@ % Macro tr\`es simple qui assigne ou affiche le r\'esultat, selon la pr\'esence % ou non de #2 qui est l'argument optionnel venant en derni\`ere position des macros \def\@xs@ReturnResult#1#2{% - \expandafter\ifx\expandafter\@empty\detokenize{#2}\@empty% pas de nom ? - #1% on affiche #1 - \else% il y a un nom donc - \def#2{#1}% on assigne #1 dans #2 avec edef + \expandafter\ifx\expandafter\@empty\detokenize{#2}\@empty + #1% + \else + \def#2{#1}% \fi} % Pas d'expansion des arguments @@ -308,9 +235,9 @@ % #4 : nombre d'arguments obligatoires % #5 : utilisation de testopt (1 si oui, 0 si non) % #6 : code de la macro -\def\@xs@newmacro@#1#2#3#4#5#6{% +\def\@xs@newmacro@#1#2#3#4#5{% \edef\@xs@reserved@A{@xs@\expandafter\@xs@gobblefirstchar\string#2}% - \edef\@xs@reserved@C{\csname\@xs@reserved@A @\ifx\@empty#3\@empty @\fi\endcsname}% + \edef\@xs@reserved@C{\expandafter\noexpand\csname\@xs@reserved@A @\ifx\@empty#3\@empty @\fi\endcsname}% \edef\@xs@reserved@B{% \ifx\@empty\@xs@reserved@D \def\noexpand#2{\noexpand\@ifstar @@ -322,7 +249,7 @@ \ifx\@empty#3\@empty \else \def\expandafter\noexpand\@xs@reserved@C{% - \noexpand\@testopt{\csname\@xs@reserved@A @@\endcsname}{\ifx\@xs@def\edef#3\else\unexpanded{#3}\fi}}% + \noexpand\@testopt{\expandafter\noexpand\csname\@xs@reserved@A @@\endcsname}{\ifx\@xs@def\edef#3\else\unexpanded{#3}\fi}}% \fi}% % Que fait \@xs@reserved@B ? Il d\'efinit : % si #3 est vide : \NOM{\@ifstar{\let\@xs@assign\@xs@expand@and@detokenize\@xs@NOM@@}{\let\@xs@assign\@xs@expand@and@assign\@xs@NOM@@}} @@ -336,9 +263,9 @@ \expandafter\@xs@BuildLines\expandafter1\expandafter{\number\numexpr#4+1}{#3}{#1}% \@xs@DefArg@{#4}% \fi - \edef\@xs@reserved@B{\def\csname\@xs@reserved@A @@\endcsname\@xs@myarg}% + \edef\@xs@reserved@B{\def\expandafter\noexpand\csname\@xs@reserved@A @@\endcsname\@xs@myarg}% \edef\@xs@reserved@C{\unexpanded\expandafter{\@xs@newlines}\edef\noexpand\@xs@call}% - \edef\@xs@reserved@D{\noexpand\noexpand\csname\@xs@reserved@A\endcsname\unexpanded\expandafter{\@xs@newargs}}% + \edef\@xs@reserved@D{\noexpand\noexpand\expandafter\noexpand\csname\@xs@reserved@A\endcsname\unexpanded\expandafter{\@xs@newargs}}% \ifnum#5=\@ne\edef\@xs@reserved@D{\noexpand\noexpand\noexpand\@testopt{\unexpanded\expandafter{\@xs@reserved@D}}\unexpanded{{}}}\fi \@xs@expand@and@addtomacro\@xs@reserved@C{{\unexpanded\expandafter{\@xs@reserved@D}}\noexpand\@xs@call}% \@xs@expand@and@addtomacro\@xs@reserved@B{{\unexpanded\expandafter{\@xs@reserved@C}}}% @@ -349,12 +276,12 @@ % si #5=1: \edef\@xs@call{\noexpand\@testopt{\noexpand\@xs@NOM[\@xs@expand\@xs@arg@i]{\@xs@expand\@xs@arg@i}{\@xs@expand\@xs@arg@ii}{\@xs@expand\@xs@arg@iii}{\@xs@expand\@xs@arg@iv}}{}}% % \@xs@call} \@xs@reserved@B - \edef\@xs@reserved@B{\def\expandafter\noexpand\csname\@xs@reserved@A\endcsname\@xs@myarg\ifnum#5=\@ne[\unexpanded{##}\number\numexpr\ifx\@empty#3\@empty#4+1\else#4+2\fi]\fi{\unexpanded{#6}}}% + \edef\@xs@reserved@B{\def\expandafter\noexpand\csname\@xs@reserved@A\endcsname\@xs@myarg\ifnum#5=\@ne[\unexpanded{##}\number\numexpr\ifx\@empty#3\@empty#4+1\else#4+2\fi]\fi}% % Que fait \@xs@reserved@B ? Il d\'efinit par exemple pour 3 arguments obligatoires et 1 facultatif : % \def \@xs@NOM[##2]##3##4##5[##6]{#6} \@xs@reserved@B} -% macro g\'en\'erique qui lit \@xs@reserved@C lex\`eme par lex\`eme +% macro g\'en\'erique qui lit \@xs@reserved@C us par us % 3 sous-routines sont appel\'ees \`a des moments cl\'e : % \@xs@atendofgroup (un groupe se finit, appel r\'ecursif) % \@xs@atbegingroup (un groupe vient d'être ouvert) @@ -380,7 +307,7 @@ \integerpart\z@ \@xs@atbegingroup \else - \global\advance\@xs@count\@ne + \global\advance\decimalpart\@ne \@xs@atnextsyntaxunit \fi \fi @@ -399,7 +326,7 @@ \fi \else \expandafter\expandafter\expandafter\@xs@IfBeginWith@i\expandafter\expandafter\expandafter{\expandafter\@xs@reserved@D\expandafter}\expandafter{\@xs@reserved@E}% - {\global\advance\@xs@count\@ne + {\global\advance\decimalpart\@ne \let\@xs@reserved@D\@xs@reserved@A \@xs@atoccurfound}% {\expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@D}\@xs@reserved@A @@ -454,8 +381,6 @@ \fi \@xs@next} -\def\@xs@strip@delimit#1\@delimit#2\@xs@nil{#1} - % \@xs@cutafteroccur coupe l'argument #1 apr\`es la #3\`eme occurrence de #2 % \@xs@reserved@C : contient ce qui se trouve avant cette occurrence % \@xs@reserved@D : contient ce qui se trouve avant cette occurrence y compris cette occurrence @@ -463,13 +388,13 @@ % si l'occurrence n'existe pas ou qu'un des arguments est vide, toutes les chaines renvoy\'ees sont vides \def\@xs@cutafteroccur#1#2#3{% \def\@xs@reserved@D{#1}\let\@xs@reserved@C\@empty\def\@xs@reserved@E{#2}% - \@xs@count\z@\integerpart\z@\decimalpart#3\def\groupID{0}\let\@xs@nestlevel\z@ + \decimalpart\z@\integerpart\z@\def\groupID{0}\let\@xs@nestlevel\z@ \def\@xs@atendofgroup{% \expandafter\endgroup \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\expandafter{\@xs@reserved@C}}% \@xs@read@reserved@D}% \def\@xs@atoccurfound{% - \ifnum\@xs@count=\decimalpart + \ifnum\decimalpart=#3 \global\let\@xs@reserved@D\@xs@reserved@D \global\let\@xs@reserved@C\@xs@reserved@C \global\let\groupID\groupID @@ -480,7 +405,7 @@ \let\@xs@next\@xs@read@reserved@D \fi}% \@xs@read@reserved@D - \ifnum\@xs@count=\decimalpart% occurrence trouv\'ee ? + \ifnum\decimalpart=#3% occurrence trouv\'ee ? \let\@xs@reserved@E\@xs@reserved@D \expandafter\def\expandafter\@xs@reserved@D\expandafter{\@xs@reserved@C#2}% \else @@ -514,7 +439,7 @@ \ifx\@xs@reserved@A\@xs@reserved@B% il y a \'egalit\'e... \@xs@removefirstsyntaxunit{#1}\@xs@reserved@A% on enl\`eve les 1ere unit\'es syntaxiques \@xs@removefirstsyntaxunit{#2}\@xs@reserved@B - \def\@xs@next{% et on recommence avec ces arguments racourcis d'1 token + \def\@xs@next{% et on recommence avec ces arguments racourcis d'1 unit\'e syntaxique \expandafter\expandafter\expandafter\@xs@IfBeginWith@i \expandafter\expandafter\expandafter{\expandafter\@xs@reserved@A\expandafter}\expandafter{\@xs@reserved@B}}% \else @@ -588,12 +513,12 @@ \expandafter\@xs@formatnumber\expandafter{\detokenize{#1}}\@xs@reserved@A \decimalpart\z@ \afterassignment\@xs@defafterinteger\integerpart\@xs@reserved@A\relax\@xs@nil - \ifx\@empty\@xs@afterinteger - \expandafter\@firstoftwo - \else - \expandafter\tokenize\expandafter\@xs@afterinteger\expandafter{\@xs@afterinteger}% - \expandafter\@secondoftwo - \fi} + \expandafter\@xs@testdot\@xs@afterinteger\@xs@nil + \let\@xs@next\@secondoftwo + \ifx\@empty\@xs@afterdecimal + \ifnum\decimalpart=\z@\let\@xs@next\@firstoftwo\fi + \fi + \@xs@next} \@xs@newmacro\IfDecimal{}{1}{0}{% \expandafter\@xs@formatnumber\expandafter{\detokenize{#1}}\@xs@reserved@A @@ -693,16 +618,16 @@ % par la chaine #4 dans la chaine #2 \@xs@newmacro\StrSubstitute{0}{3}{1}{% \def\@xs@reserved@D{#2}\let\@xs@reserved@C\@empty\def\@xs@reserved@E{#3}% - \@xs@count\z@\integerpart\z@\def\groupID{0}\let\@xs@nestlevel\z@ + \decimalpart\z@\integerpart\z@\def\groupID{0}\let\@xs@nestlevel\z@ \def\@xs@atendofgroup{% \expandafter\endgroup \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\expandafter{\@xs@reserved@C}}% \@xs@read@reserved@D}% \def\@xs@atoccurfound{% - \ifnum#1=\z@ + \ifnum#1<\@ne \def\@xs@reserved@A{#4}% \else - \ifnum\@xs@count>#1 + \ifnum\decimalpart>#1 \def\@xs@reserved@A{#3}% \else \def\@xs@reserved@A{#4}% @@ -725,14 +650,14 @@ % Compte combien d'unit\'es syntaxiques contient la chaine #1 ? \@xs@newmacro\StrLen{}{1}{1}{% \def\@xs@reserved@C{#1}% - \@xs@count\z@ + \decimalpart\z@ \let\@xs@nestlevel\z@ \def\groupID{0}% \let\@xs@atbegingroup\relax \def\@xs@atendofgroup{\endgroup\@xs@read@reserved@C}% \let\@xs@atnextsyntaxunit\relax \@xs@read@reserved@C - \expandafter\@xs@ReturnResult\expandafter{\number\@xs@count}{#2}} + \expandafter\@xs@ReturnResult\expandafter{\number\decimalpart}{#2}} % Macro interne fermant autant de groupes que n\'ecessaire pour trouver une unit\'e syntaxique derri\`ere \def\@xs@continuetonext{% @@ -759,7 +684,7 @@ \def\@xs@StrSplit@i#1#2{% \def\@xs@reserved@D{#1}\def\@xs@reserved@C{#2}\let\@xs@reserved@B\@empty\let\groupID\@empty \ifnum#1>\z@ - \@xs@count\z@\integerpart\z@\def\groupID{0}\let\@xs@nestlevel\z@ + \decimalpart\z@\integerpart\z@\def\groupID{0}\let\@xs@nestlevel\z@ \def\@xs@atendofgroup{% \expandafter\endgroup \expandafter\@xs@addtomacro\expandafter\@xs@reserved@B\expandafter{\expandafter{\@xs@reserved@B}}% @@ -767,7 +692,7 @@ \def\@xs@atbegingroup{\let\@xs@reserved@B\@empty}% \def\@xs@atnextsyntaxunit{% \expandafter\@xs@addtomacro\expandafter\@xs@reserved@B\expandafter{\@xs@reserved@A}% - \ifnum\@xs@count=\@xs@reserved@D\relax + \ifnum\decimalpart=\@xs@reserved@D\relax \ifx\@xs@reserved@C\@empty\@xs@reserved@E\fi \global\let\@xs@reserved@B\@xs@reserved@B \global\let\@xs@reserved@C\@xs@reserved@C @@ -784,8 +709,10 @@ \@xs@newmacro\StrMid{}{3}{1}{% \begingroup \noexploregroups + \let\@xs@reserved@E\relax \@xs@StrSplit@i{#3}{#1}% \edef\@xs@reserved@C{\number\numexpr#2-1}% + \let\@xs@reserved@E\relax \expandafter\expandafter\expandafter\@xs@StrSplit@i\expandafter\expandafter\expandafter{\expandafter\@xs@reserved@C\expandafter}\expandafter{\@xs@reserved@B}% \expandafter\endgroup \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#4}% @@ -793,35 +720,39 @@ % supprime #2 unit\'es syntaxiques \`a gauche dans la chaine #1 \@xs@newmacro\StrGobbleLeft{}{2}{1}{% + \let\@xs@reserved@E\relax \@xs@StrSplit@i{#2}{#1}% \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#3}} % extrait de #1 la chaine \`a gauche de longueur #2 \@xs@newmacro\StrLeft{}{2}{1}{% + \let\@xs@reserved@E\relax \@xs@StrSplit@i{#2}{#1}% \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@B}{#3}} % supprime #2 unit\'es syntaxiques \`a droite dans la chaine #1 \@xs@newmacro\StrGobbleRight{}{2}{1}{% - \@xs@StrLen{#1}[\@xs@reserved@E]% - \expandafter\@xs@StrSplit@i\expandafter{\number\numexpr\@xs@reserved@E-#2}{#1}% + \@xs@StrLen{#1}[\@xs@reserved@D]% + \let\@xs@reserved@E\relax + \expandafter\@xs@StrSplit@i\expandafter{\number\numexpr\@xs@reserved@D-#2}{#1}% \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@B}{#3}} % renvoie #2 unit\'es syntaxiques \`a la droite de la chaine #1 \@xs@newmacro\StrRight{}{2}{1}{% - \@xs@StrLen{#1}[\@xs@reserved@E]% - \expandafter\@xs@StrSplit@i\expandafter{\number\numexpr\@xs@reserved@E-#2}{#1}% + \@xs@StrLen{#1}[\@xs@reserved@D]% + \let\@xs@reserved@E\relax + \expandafter\@xs@StrSplit@i\expandafter{\number\numexpr\@xs@reserved@D-#2}{#1}% \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#3}} \@xs@newmacro\StrChar{}{2}{1}{% \let\@xs@reserved@B\@empty \ifnum#2>\z@ - \def\@xs@reserved@C{#1}\def\@xs@reserved@D{#2}\@xs@count\z@ + \def\@xs@reserved@C{#1}\def\@xs@reserved@D{#2}\decimalpart\z@ \def\groupID{0}\let\@xs@nestlevel\z@\integerpart\z@ \let\@xs@atbegingroup\relax \def\@xs@atendofgroup{\endgroup\@xs@read@reserved@C}% \def\@xs@atnextsyntaxunit{% - \ifnum\@xs@count=\@xs@reserved@D% la n i\`eme US est atteinte ? + \ifnum\decimalpart=\@xs@reserved@D% la n i\`eme US est atteinte ? \global\let\@xs@reserved@B\@xs@reserved@A% on capture l'US en cours qui est celle cherch\'ee \global\let\groupID\groupID \@xs@exitallgroups @@ -838,14 +769,14 @@ \@xs@ReturnResult{0}{#3}% \else \def\@xs@reserved@D{#1}\def\@xs@reserved@E{#2}\let\@xs@reserved@C\@empty - \@xs@count\z@\integerpart\z@\def\groupID{0}\let\@xs@nestlevel\z@ + \decimalpart\z@\integerpart\z@\def\groupID{0}\let\@xs@nestlevel\z@ \def\@xs@atendofgroup{% \expandafter\endgroup \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\expandafter{\@xs@reserved@C}}% \@xs@read@reserved@D}% \def\@xs@atoccurfound{\let\@xs@reserved@C\@empty\@xs@read@reserved@D}% \@xs@read@reserved@D - \expandafter\@xs@ReturnResult\expandafter{\number\@xs@count}{#3}% + \expandafter\@xs@ReturnResult\expandafter{\number\decimalpart}{#3}% \fi} % renvoie la position de l'occurrence #1 de la sous chaine #3 dans la chaine #2 @@ -916,8 +847,8 @@ \else \expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@D \ifx\bgroup\@xs@toks% si la 1\`ere unit\'e syntaxique est un groupe explicite - \advance\@xs@count\@ne% on augmente le compteur - \ifnum\@xs@count=\@xs@reserved@A% on est au groupe cherch\'e lors de la profondeur courante ? + \advance\decimalpart\@ne% on augmente le compteur + \ifnum\decimalpart=\@xs@reserved@A% on est au groupe cherch\'e lors de la profondeur courante ? \ifx\@empty\@xs@reserved@B% on est \`a la profondeur maximale ? \def\@xs@next{\expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@D}{#3}}% on renvoie ce groupe \else% sinon @@ -935,7 +866,7 @@ \fi \@xs@next}% \@xs@extractgroupnumber{#2}\@xs@reserved@A\@xs@reserved@B - \@xs@count\z@ + \decimalpart\z@ \ifnum\@xs@reserved@A>\z@\def\@xs@reserved@C{#1}\else\let\@xs@reserved@C\@empty\fi \@xs@StrFindGroup@ii} @@ -944,6 +875,49 @@ \@xs@extractgroupnumber@i#1,\@xs@nil \ifx\@empty#3\else\@xs@extractgroupnumber@i#1\@xs@nil\fi} +\def\expandingroups{\let\@xs@expandingroups\exploregroups} +\def\noexpandingroups{\let\@xs@expandingroups\noexploregroups} +\def\StrExpand{\@testopt{\@xs@StrExpand}{1}} +\def\@xs@StrExpand[#1]#2#3{% + \begingroup + \@xs@expandingroups + \ifnum#1>\z@ + \integerpart#1\relax + \decimalpart\z@\def\groupID{0}\let\@xs@nestlevel\z@ + \def\@xs@atendofgroup{% + \expandafter\endgroup + \expandafter\@xs@addtomacro\expandafter\@xs@reserved@B\expandafter{\expandafter{\@xs@reserved@B}}% + \@xs@read@reserved@C}% + \def\@xs@atbegingroup{\let\@xs@reserved@B\@empty}% + \def\@xs@atnextsyntaxunit{% + \expandafter\expandafter\expandafter\@xs@addtomacro + \expandafter\expandafter\expandafter\@xs@reserved@B + \expandafter\expandafter\expandafter{\@xs@reserved@A}}% + \def\@xs@reserved@C{#2}% + \@xs@StrExpand@i{#1}% Appel de la macro r\'ecursive + \else + \def\@xs@reserved@B{#2}% + \fi + \global\let\@xs@reserved@B\@xs@reserved@B + \endgroup + \let#3\@xs@reserved@B + \let\groupID\@empty} +\def\@xs@StrExpand@i#1{% + \ifnum#1>\z@ + \let\@xs@reserved@B\@empty + \@xs@read@reserved@C + \let\@xs@reserved@C\@xs@reserved@B + \def\@xs@reserved@A{\expandafter\@xs@StrExpand@i\expandafter{\number\numexpr#1-1}}% + \else + \let\@xs@reserved@A\relax + \fi + \@xs@reserved@A} + +\def\scancs{\@testopt{\@xs@scancs}{1}} +\def\@xs@scancs[#1]#2#3{% + \@xs@StrExpand[#1]{#3}{#2}% + \edef#2{\detokenize\expandafter{#2}}} + % Restaure le code de @ \catcode`\@=\CurrentAtCatcode\relax % D\'efinit le d\'elimiteur verb @@ -952,6 +926,7 @@ \fullexpandarg\saveexpandmode \comparenormal\savecomparemode \noexploregroups\saveexploremode +\expandingroups \endinput % % Historique @@ -1053,4 +1028,20 @@ % d\'etok\'enis\'e \`a tort dans les macros \'etoil\'ees. % - Dans \@xs@newmacro, on doit choisir le num\'ero du dernier argument devant % être d\'etok\'enis\'e dans le cas d'une macro \'etoil\'ee (sachant que -% l'argument optionnel ne l'est jamais)
\ No newline at end of file +% l'argument optionnel ne l'est jamais) +%------------------------------------------------------------------------------ +% v1.5a 09/2/2009 +% - Nouvelle macro \StrExpand, sensible au mode d'exploration. La macro est +% indépendante du mode d'exploration et dispose de ses propres commandes +% d'exploration : \expandingroups et \noexpandingroups +% - R\'e-\'ecriture de \scancs, qui devient triviale puisque d\'ependant de +% \StrExpand. Il n'y a plus de version \'étoil\'ee et d\'esormais, \scancs +% est sensible au mode d'exploration. +% - Correction d'un bug dans \IfInteger : \IfInteger{2.0}{V}{F} affichait F +% - Correction de bugs : mettre \let\@xs@reserved@E\relax avant d'appeler +% \@xs@StrSplit@i +% - Suppression des messages d'erreur, de warning et d'info. xstring devient +% donc silencieux ;) +% - Passage de 3 \'a 2 compteurs +% - Le manuel est d\'esormais plus color\'e, en esp\'erant qu'il sera un peu +% plus agr\'eable \`a lire !
\ No newline at end of file |