From 65f1bea00b6756c4051bd992581aa4b97b84426e Mon Sep 17 00:00:00 2001
From: Karl Berry <karl@freefriends.org>
Date: Sun, 15 Feb 2009 00:43:17 +0000
Subject: xstring 1.5a (12feb09)

git-svn-id: svn://tug.org/texlive/trunk@12159 c570f23f-e606-0410-a88d-b1316a301751
---
 Master/texmf-dist/tex/generic/xstring/xstring.tex | 259 +++++++++++-----------
 1 file changed, 125 insertions(+), 134 deletions(-)

(limited to 'Master/texmf-dist/tex/generic/xstring/xstring.tex')

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
-- 
cgit v1.2.3

