summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/xstring
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-01-02 00:43:24 +0000
committerKarl Berry <karl@freefriends.org>2009-01-02 00:43:24 +0000
commit6cd0243de7b3c69971e9b28712b6aa797c107952 (patch)
treeef7c2c40cea061352cbbeaabb15ee39a17e6c3c3 /Master/texmf-dist/tex/generic/xstring
parent655eb3cce978b5e2e426511addc107fe7b14d332 (diff)
xstring 1.5 (31dec08)
git-svn-id: svn://tug.org/texlive/trunk@11796 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/generic/xstring')
-rw-r--r--Master/texmf-dist/tex/generic/xstring/xstring.tex957
1 files changed, 529 insertions, 428 deletions
diff --git a/Master/texmf-dist/tex/generic/xstring/xstring.tex b/Master/texmf-dist/tex/generic/xstring/xstring.tex
index 9da9444bb2c..7e2b35779e5 100644
--- a/Master/texmf-dist/tex/generic/xstring/xstring.tex
+++ b/Master/texmf-dist/tex/generic/xstring/xstring.tex
@@ -1,15 +1,24 @@
% __________________________________________________
% | |
% | |
-% | xstring v1.4b |
+% | xstring v1.5 |
% | |
-% | November 16 2008 |
+% | December 31 2008 |
% | |
% |__________________________________________________|
%
% This is xtring.tex
%
-% Christian Tellechea 2008
+% "xstring" package consists of the 11 following files:
+% xstring.tex (this file)
+% xstring.sty
+% README
+% xstring_doc_fr.tex, xstring_doc_fr.pdf (manual in french)
+% xstring_doc_en.tex, xstring_doc_en.pdf (manual in english)
+% 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
% email : unbonpetit@gmail.com
% -------------------------------------------------------------------
% This work may be distributed and/or modified under the
@@ -26,19 +35,10 @@
%
% The Current Maintainer of this work is Christian Tellechea
% -------------------------------------------------------------------
-% This work consists of the files
-% xstring.tex (this file)
-% xstring.sty
-% README
-% xstring_doc_fr.tex, xstring_doc_fr.pdf (manual in french)
-% xstring_doc_en.tex, xstring_doc_en.pdf (manual in english)
-% test_latex.tex, test_latex.pdf (test file with LaTeX)
-% test_etex.tex, test_etex.pdf (test file with Plain eTeX)
-%
-\def\xstringversion {1.4b}
-\def\xstringdate {2008/11/16}
-\def\xstringfrenchdate {16 novembre 2008}
-\def\xstringenglishdate{November $16^{\mathrm{th}}$ 2008}
+\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`\@}
\catcode`\@=11
\newwrite\@xs@unused% pour les messages
@@ -71,7 +71,7 @@
\def\@ifstar#1{\@ifnextchar *{\@firstoftwo{#1}}}
\long\def\@testopt#1#2{\@ifnextchar[{#1}{#1[{#2}]}}
\def\@empty{}
-\fi% fin des définitions LaTeX
+\fi% fin des d\'efinitions LaTeX
% Gestion des messages d'erreur
\def\@xs@linenumber{on input line \the\inputlineno}
@@ -97,37 +97,37 @@
\immediate\write\m@ne{Package xstring Info: #1}%
\endgroup}
-% Messages d'information pour situations particulières
+% 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ù les catcodes sont à 12 et à 10 pour les espaces
-% ensuite, appelle \@xs@ReadVerb qui lit un argument entre délimiteurs verb
+% 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
- \begingroup% groupe où les catcodes sont à 12 pour la lecture suivante
+ \begingroup% groupe o\`u les catcodes sont \`a 12 pour la lecture suivante
\def\do##1{\catcode`##112\relax}%
\dospecials% on entre dans le mode verb
\obeyspaces% et on tient compte des espaces
\@xs@ReadVerb}% et on va lire l'argument
-% Définit \@xs@ReadVerb qui lit un argument entre délimiteurs verb
-\def\setverbdelim#1{% définit quel est le délimiteur de verb
+% D\'efinit \@xs@ReadVerb qui lit un argument entre d\'elimiteurs verb
+\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}%
\fi
- \def\@xs@ReadVerb##1#1##2#1{% lit ##2 qui est entre les délimiteurs de verb
+ \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écution de fin
+ \@xs@afterreadverb{##2}}}% on appelle l'ex\'ecution de fin
-% Assigne l'argument entre délimiteur 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}}%
\@xs@MakeVerb}
-% A l'aide d'un pont d'\expandafter, développe d'un niveau toutes
-% les uneités syntaxiques de #1 puis et assigne le résultat à \@xs@reserved@A
+% 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
@@ -139,14 +139,14 @@
\def\@xs@notestcs#1\@xs@nil{\relax}%
\def\@xs@testcs#1#2\@xs@nil{%
\ifx\@empty#2\@empty
- \else% si la séquence de contrôle n'est pas seule, on gueule
+ \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éveloppe #3 autant de fois que spécifié en #1
-% puis le développement obtenu est verbatimisé.
-% On utilise \@xs@expandalltodepth autant de fois que #1 le spécifie
-% puis on invoque \detokenize à la fin
+% \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}%
@@ -156,15 +156,15 @@
\@xs@scancs}}
\def\@xs@scancs{\@ifnextchar[{\@xs@scancs@}{\@xs@scancs@[1]}}
\def\@xs@scancs@[#1]#2#3{%
-% #1 : profondeur à développer avant de verbatimiser
+% #1 : profondeur \`a d\'evelopper avant de verbatimiser
% #2 : nom de la sc recevant la chaine verb
-% #3 : nom de la sc à développer et à transformer en verb
- \def\@xs@expandalltodepth##1{% développe de #1 niveaux toutes les sc de #3 et l'assigne à \@xs@reserved@B
- \let\@xs@reserved@A\@empty%\def\@xs@reserved@A{}%
- \ifnum##1<#1\relax% tant que la profondeur de développement n'est pas atteinte
- \expandafter\@xs@testornot\@xs@reserved@B\@xs@nil% on teste éventuellement si le développement comporte 1 seule sc
- \expandafter\@xs@expandallonelevel\@xs@reserved@B\@xs@nil% on développe tout d'un niveau
- \let\@xs@reserved@B\@xs@reserved@A%\expandafter\def\expandafter\@xs@reserved@B\expandafter{\@xs@reserved@A}%
+% #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}%
@@ -172,23 +172,23 @@
\@xs@expandalltodepth\z@
\expandafter\def\expandafter#2\expandafter{\detokenize\expandafter{\@xs@reserved@B}}}
-% Cette macro développe éventuellement #2
-% puis le transforme en token et l'assigne à #1
-\begingroup% on ouvre un groupe où...
-\catcode\z@12\relax% ...le caractère 0 a 12 pour catcode
+% Cette macro d\'eveloppe \'eventuellement #2
+% puis le transforme en token et l'assigne \`a #1
+\begingroup% on ouvre un groupe o\`u...
+\catcode\z@12\relax% ...le caract\`ere 0 a 12 pour catcode
\gdef\tokenize#1#2{%
\begingroup
- \@xs@def\@xs@reserved@A{#2}% on développe en accord avec \fullexpandarg ou \noexpandarg
+ \@xs@def\@xs@reserved@A{#2}% on d\'eveloppe en accord avec \fullexpandarg ou \noexpandarg
\def\@xs@AssignResult^^00##1^^00\@xs@nil{\gdef#1{##1}}% on assigne en tenant compte du \@xs@nil qui vient de la fin du fichier virtuel
- \everyeof{\@xs@nil}% met un \@xs@nil à la fin du fichier virtuel
+ \everyeof{\@xs@nil}% met un \@xs@nil \`a la fin du fichier virtuel
\endlinechar\m@ne
\catcode\z@12\relax
\expandafter\@xs@AssignResult\scantokens\expandafter{\expandafter^^00\@xs@reserved@A^^00}% on fait l'assignation
\endgroup}%
\endgroup
-% Macro très simple qui assigne ou affiche le résultat, selon la présence
-% ou non de #2 qui est l'argument optionnel venant en dernière position des macros
+% 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
@@ -198,31 +198,31 @@
% Pas d'expansion des arguments
\def\normalexpandarg{%
- \let\@xs@def\def% on définit \@xs@call avec \def
+ \let\@xs@def\def% on d\'efinit \@xs@call avec \def
\def\@xs@expand##1{\unexpanded\expandafter{##1}}}
\let\noexpandarg\normalexpandarg% synonyme
-% 1-développement de la 1è sc des arguments et non développement des autres
+% 1-d\'eveloppement du premier token des arguments
\def\expandarg{%
- \let\@xs@def\def% on définit \@xs@call avec \def
+ \let\@xs@def\def% on d\'efinit \@xs@call avec \def
\def\@xs@expand##1{\unexpanded\expandafter\expandafter\expandafter{##1}}}
-% Développement maximum des arguments
+% D\'eveloppement maximum des arguments
\def\fullexpandarg{%
- \let\@xs@def\edef% on définit\@xs@call avec \edef
+ \let\@xs@def\edef% on d\'efinit\@xs@call avec \edef
\def\@xs@expand##1{##1}}% et on neutralise \@xs@expand
\def\saveexpandmode{\let\@xs@saved@def\@xs@defarg\let\@xs@saved@expand\@xs@expand}
\def\restoreexpandmode{\let\@xs@defarg\@xs@saved@def\let\@xs@expand\@xs@saved@expand}
-% Cette macro interne prend la 1ere unité syntaxique de #1 et assigne le résultat à #2
+% Cette macro interne prend la 1ere unit\'e syntaxique de #1 et assigne le r\'esultat \`a #2
\def\@xs@returnfirstsyntaxunit#1#2{%
\def\@xs@returnfirstsyntaxunit@i##1##2\@xs@nil{%
\ifx\@xs@toks\bgroup
\begingroup
- \escapechar48\relax% 0 est le caractère d'échappement
+ \escapechar48\relax% 0 est le caract\`ere d'\'echappement
\expandafter\expandafter\expandafter\ifx\expandafter\@xs@returnfirstsyntaxunit@ii\detokenize{#1}\@xs@nil0%
- \def\@xs@reserved@A{\def#2{##1}\let\@xs@toks0\relax}% si commence par 0, ##1 est un «\bgroup»
+ \def\@xs@reserved@A{\def#2{##1}\let\@xs@toks0}% si commence par 0, ##1 est un «\bgroup»
\else
\def\@xs@reserved@A{\def#2{{##1}}}% si ne commence pas par 0, ##1 est un groupe {...}
\fi
@@ -238,7 +238,7 @@
\futurelet\@xs@toks\@xs@returnfirstsyntaxunit@i#1\@xs@nil
\fi}
-% Cette macro interne enlève la 1ere unité syntaxique de #1 et assigne le résultat à #2
+% Cette macro interne enl\`eve la 1ere unit\'e syntaxique de #1 et assigne le r\'esultat \`a #2
\def\@xs@removefirstsyntaxunit#1#2{%
\expandafter\ifx\expandafter\@empty\@xs@beforespace#1 \@xs@nil\@empty
\ifx\@empty#1\@empty\def#2{}\else\expandafter\def\expandafter#2\expandafter{\@xs@behindspace#1\@xs@nil}\fi
@@ -246,23 +246,23 @@
\expandafter\def\expandafter#2\expandafter{\@xs@gobblefirstchar#1}%
\fi}
-% Macros à arguments délimités pour les macros ci dessus
+% Macros \`a arguments d\'elimit\'es pour les macros ci dessus
\def\@xs@beforespace#1 #2\@xs@nil{#1}
\def\@xs@behindspace#1 #2\@xs@nil{#2}
\def\@xs@gobblefirstchar#1{}
\def\@xs@returnfirstsyntaxunit@ii#1#2\@xs@nil{#1}
-% Cette macro interne est utilisée dans les macros étoilées pour :
-% 1) développer l'argument selon qu'on a choisit \fullexpandarg
-% ou \normalexpandarg, et ceci à l'aide de la macro \@xs@def
-% 2) Ensuite, on détokenize ce développement de façon n'avoir plus que
+% Cette macro interne est utilis\'ee dans les macros \'etoil\'ees pour :
+% 1) d\'evelopper l'argument selon qu'on a choisit \fullexpandarg
+% ou \normalexpandarg, et ceci \`a l'aide de la macro \@xs@def
+% 2) Ensuite, on d\'etokenize ce d\'eveloppement de façon n'avoir plus que
% des catcodes de 10 pour les espaces et 12 pour le reste.
\def\@xs@expand@and@detokenize#1#2{%
\def#1{#2}%
- \expandafter\edef\expandafter#1\expandafter{\@xs@expand#1}% on développe #2 selon le mode de développement
- \edef#1{\detokenize\expandafter{#1}}}% puis on détokenize et on assigne à #1
+ \expandafter\edef\expandafter#1\expandafter{\@xs@expand#1}% on d\'eveloppe #2 selon le mode de d\'eveloppement
+ \edef#1{\detokenize\expandafter{#1}}}% puis on d\'etokenize et on assigne \`a #1
-\def\@xs@expand@and@assign#1#2{\@xs@def#1{#2}}% on développe #2 selon \fullexpandarg ou \normalexpandarg
+\def\@xs@expand@and@assign#1#2{\@xs@def#1{#2}}% on d\'eveloppe #2 selon \fullexpandarg ou \normalexpandarg
\def\@xs@expand@and@addtomacro#1#2{\edef#1{\unexpanded\expandafter{#1}#2}}
\def\@xs@argstring{0########1########2########3########4########5########6########7########8########9}
@@ -275,160 +275,227 @@
\def\@xs@OneArg#1{\expandafter\@xs@onearg\expandafter{\number\numexpr#1-1}{#1}}
\def\@xs@onearg#1#2{\def\@xs@defarg##1#1##2#2##3\@xs@nil{\def\@xs@myarg{##2#2}}\expandafter\@xs@defarg\@xs@argstring\@xs@nil}
-\def\@xs@BuildLines#1#2#3{% #1 : numéro du 1er argument; #2 : nombre de lignes; #3 argument optionnel
+% #1 : num\'ero du 1er argument; #2 : nombre de lignes; #3 argument optionnel; #4 : dernier num\'ero de l'argument devant être d\'etokenis\'e si \'etoile
+\def\@xs@BuildLines#1#2#3#4{%
\def\@xs@newlines{}%
\def\@xs@newargs{}%
\def\@xs@buildlines##1{%
\expandafter\@xs@OneArg\expandafter{\number\numexpr##1+#1-1}%
- \@xs@expand@and@addtomacro\@xs@newlines{\noexpand\@xs@assign\expandafter\noexpand\csname @xs@arg@\romannumeral\numexpr##1\endcsname{\@xs@myarg}}%
+ \def\@xs@reserved@B{\noexpand\@xs@expand\csname @xs@arg@\romannumeral\numexpr##1\endcsname}%
\ifnum##1=\@ne% si c'est le premier argument
\ifx\@empty#3\@empty
- \@xs@expand@and@addtomacro\@xs@newargs{{\noexpand\@xs@expand\expandafter\noexpand\csname @xs@arg@\romannumeral\numexpr##1\endcsname}}%
+ \@xs@expand@and@addtomacro\@xs@newargs{{\@xs@reserved@B}}%
+ \edef\@xs@reserved@B{\ifnum##1>#4 @xs@def\else @xs@assign\fi}%
\else% et s'il y a un argument optionnel alors, on met des crochets
- \@xs@expand@and@addtomacro\@xs@newargs{[\noexpand\@xs@expand\expandafter\noexpand\csname @xs@arg@\romannumeral\numexpr##1\endcsname]}%
+ \@xs@expand@and@addtomacro\@xs@newargs{[\@xs@reserved@B]}%
+ \def\@xs@reserved@B{@xs@def}% ne pas d\'etok\'eniser l'argument optionnel grace au \@xs@def
\fi
\else
- \@xs@expand@and@addtomacro\@xs@newargs{{\noexpand\@xs@expand\expandafter\noexpand\csname @xs@arg@\romannumeral\numexpr##1\endcsname}}%
+ \@xs@expand@and@addtomacro\@xs@newargs{{\@xs@reserved@B}}%
+ \edef\@xs@reserved@B{\ifnum##1>#4 @xs@def\else @xs@assign\fi}%
\fi
+ \@xs@expand@and@addtomacro\@xs@newlines{\csname\@xs@reserved@B\endcsname\csname @xs@arg@\romannumeral\numexpr##1\endcsname{\@xs@myarg}}%
\ifnum##1<#2\relax
\def\@xs@next{\expandafter\@xs@buildlines\expandafter{\number\numexpr##1+1}}%
\expandafter\@xs@next
\fi}%
\@xs@buildlines\@ne}
-\def\@xs@newmacro#1#2#3#4#5{%
-% #1 : nom de la macro publique
-% #2 : argument optionnel (vide si pas d'arg optionnel)
-% #3 : nombre d'arguments obligatoires
-% #4 : utilisation de testopt (1 si oui, 0 si non)
-% #5 : code de la macro
- \edef\@xs@reserved@A{@xs@\expandafter\@xs@gobblefirstchar\string#1}%
- \edef\@xs@reserved@C{\expandafter\noexpand\csname\@xs@reserved@A @\ifx\@empty#2\@empty @\fi\endcsname}%
+\def\@xs@newmacro{\@ifstar{\let\@xs@reserved@D\@empty\@xs@newmacro@}{\let\@xs@reserved@D\relax\@xs@newmacro@0}}
+% #1 : dernier num\'ero de l'argument devant être d\'etokenis\'e si \'etoile
+% #2 : nom de la macro publique
+% #3 : argument optionnel (vide si pas d'arg optionnel)
+% #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{%
+ \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@B{%
- \def\noexpand#1{\noexpand\@ifstar
+ \ifx\@empty\@xs@reserved@D
+ \def\noexpand#2{\noexpand\@ifstar
{\let\noexpand\@xs@assign\noexpand\@xs@expand@and@detokenize\expandafter\noexpand\@xs@reserved@C}%
{\let\noexpand\@xs@assign\noexpand\@xs@expand@and@assign\expandafter\noexpand\@xs@reserved@C}}%
- \ifx\@empty#2\@empty
\else
- \def\expandafter\noexpand\@xs@reserved@C{\noexpand\@ifnextchar[%
- {\expandafter\noexpand\csname\@xs@reserved@A @@\endcsname}%
- {\expandafter\noexpand\csname\@xs@reserved@A @@\endcsname[#2]}}%
+ \def\noexpand#2{\let\noexpand\@xs@assign\noexpand\@xs@expand@and@assign\expandafter\noexpand\@xs@reserved@C}%
+ \fi
+ \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}}%
\fi}%
- % Que fait \@xs@reserved@B ? Il définit :
- % si #2 est vide : \NOM{\@ifstar{\let\@xs@assign\@xs@expand@and@detokenize\@xs@NOM@@}{\let\@xs@assign\@xs@expand@and@assign\@xs@NOM@@}}
- % si #2 existe : \NOM{\@ifstar{\let\@xs@assign\@xs@expand@and@detokenize\@xs@NOM@}{\let\@xs@assign\@xs@expand@and@assign\@xs@NOM@}}
- % \@xs@NOM@{\@ifnextchar[{\@xs@NOM@@}{\@xs@NOM@@[#2]}}
+ % 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@@}}
+ % si #3 existe : \NOM{\@ifstar{\let\@xs@assign\@xs@expand@and@detokenize\@xs@NOM@}{\let\@xs@assign\@xs@expand@and@assign\@xs@NOM@}}
+ % \@xs@NOM@{\@testopt{\@xs@NOM@@}{#3}}}
\@xs@reserved@B
- \ifx\@empty#2\@empty
- \@xs@BuildLines1{#3}{#2}%
- \@xs@DefArg{#3}%
+ \ifx\@empty#3\@empty
+ \@xs@BuildLines1{#4}{#3}{#1}%
+ \@xs@DefArg{#4}%
\else
- \expandafter\@xs@BuildLines\expandafter1\expandafter{\number\numexpr#3+1}{#2}%
- \@xs@DefArg@{#3}%
+ \expandafter\@xs@BuildLines\expandafter1\expandafter{\number\numexpr#4+1}{#3}{#1}%
+ \@xs@DefArg@{#4}%
\fi
- \edef\@xs@reserved@B{\def\expandafter\noexpand\csname\@xs@reserved@A @@\endcsname\@xs@myarg}%
+ \edef\@xs@reserved@B{\def\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\expandafter\noexpand\csname\@xs@reserved@A\endcsname\unexpanded\expandafter{\@xs@newargs}}%
- \ifnum#4=\@ne\edef\@xs@reserved@D{\noexpand\noexpand\noexpand\@testopt{\unexpanded\expandafter{\@xs@reserved@D}}\unexpanded{{}}}\fi
+ \edef\@xs@reserved@D{\noexpand\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}}}%
- % Que fait \@xs@reserved@B ? Il définit par exemple pour 3 arguments obligatoires et 1 facultatif :
- % \def\@xs@NOM@@[##1]##2##3##4{%
- % \@xs@def\@xs@arg@i{##1}\@xs@assign\@xs@arg@ii{##2}\@xs@assign\@xs@arg@iii{##3}\@xs@asign\@xs@arg@iv{##4}%
- % si #4=0: \edef\@xs@call{\noexpand\@xs@NOM[\@xs@expand\@xs@arg@i]{\@xs@expand\@xs@arg@ii}{\@xs@expand\@xs@arg@iii}{\@xs@expand\@xs@arg@iv}}%
- % si #4=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}}{}}%
+ % Que fait \@xs@reserved@B ? Il d\'efinit par exemple pour 3 arguments obligatoires et 1 facultatif :
+ % \def\@xs@NOM@@[##2]##3##4##5{%
+ % \@xs@def\@xs@arg@i{##2}\@xs@assign\@xs@arg@ii{##3}\@xs@assign\@xs@arg@iii{##4}\@xs@asign\@xs@arg@iv{##5}%
+ % si #5=0: \edef\@xs@call{\noexpand\@xs@NOM[\@xs@expand\@xs@arg@i]{\@xs@expand\@xs@arg@ii}{\@xs@expand\@xs@arg@iii}{\@xs@expand\@xs@arg@iv}}%
+ % 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#4=\@ne[\unexpanded{##}\number\numexpr\ifx\@empty#2\@empty#3+1\else#3+2\fi]\fi{\unexpanded{#5}}}%
- % Que fait \@xs@reserved@B ? Il définit par exemple pour 3 arguments obligatoires et 1 facultatif :
- % \def \@xs@NOM[##1]##2##3##4[##5]{#5}
+ \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}}}%
+ % 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}
-\@xs@newmacro\StrRemoveBraces{}{1}{1}{%
- \let\@xs@reserved@C\@empty
- \def\@xs@reserved@A{#1}%
- \@xs@StrRemoveBraces@i
- \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#2}}
-\def\@xs@StrRemoveBraces@i{%
- \expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@A}\@xs@reserved@B
- \expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@reserved@A}\@xs@reserved@A
- \ifx\bgroup\@xs@toks
- \ifx\@xs@exploregroups\@empty% on explore les groupes ?
+% macro g\'en\'erique qui lit \@xs@reserved@C lex\`eme par lex\`eme
+% 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)
+% \@xs@atnextsyntaxunit (la future US n'est pas un groupe)
+\def\@xs@read@reserved@C{%
+ \ifx\@xs@reserved@C\@empty
+ \ifnum\@xs@nestlevel=\z@
+ \let\@xs@next\relax
+ \else
+ \let\@xs@next\@xs@atendofgroup
+ \fi
+ \else
+ \expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@A
+ \expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@C
+ \let\@xs@next\@xs@read@reserved@C
+ \@xs@exploregroups
+ \ifx\bgroup\@xs@toks
+ \advance\integerpart\@ne
\begingroup
- \let\@xs@reserved@C\@empty
- \expandafter\def\expandafter\@xs@reserved@A\@xs@reserved@B
- \@xs@StrRemoveBraces@i
- \expandafter
- \endgroup
- \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\@xs@reserved@C}%
+ \expandafter\def\expandafter\@xs@reserved@C\@xs@reserved@A
+ \@xs@manage@groupID
+ \let\@xs@nestlevel\@ne
+ \integerpart\z@
+ \@xs@atbegingroup
\else
- \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\@xs@reserved@B
+ \global\advance\@xs@count\@ne
+ \@xs@atnextsyntaxunit
+ \fi
+ \fi
+ \@xs@next}
+
+% macro g\'en\'erique qui lit \@xs@reserved@D en proc\'edant \`a des tests avec \IfBeginWith
+% 2 sous-routines sont appel\'ees \`a des moments cl\'e :
+% \@xs@atendofgroup (un groupe se finit, appel r\'ecursif)
+% \@xs@atoccurfound (une occurrence a \'et\'e trouv\'ee)
+\def\@xs@read@reserved@D{%
+ \ifx\@xs@reserved@D\@empty
+ \ifnum\@xs@nestlevel=\z@
+ \let\@xs@next\relax
+ \else
+ \let\@xs@next\@xs@atendofgroup
\fi
\else
- \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\@xs@reserved@B}%
+ \expandafter\expandafter\expandafter\@xs@IfBeginWith@i\expandafter\expandafter\expandafter{\expandafter\@xs@reserved@D\expandafter}\expandafter{\@xs@reserved@E}%
+ {\global\advance\@xs@count\@ne
+ \let\@xs@reserved@D\@xs@reserved@A
+ \@xs@atoccurfound}%
+ {\expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@D}\@xs@reserved@A
+ \expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@reserved@D}\@xs@reserved@D
+ \let\@xs@next\@xs@read@reserved@D
+ \@xs@exploregroups
+ \ifx\bgroup\@xs@toks
+ \advance\integerpart\@ne
+ \begingroup
+ \expandafter\def\expandafter\@xs@reserved@D\@xs@reserved@A
+ \@xs@manage@groupID
+ \let\@xs@reserved@C\@empty
+ \let\@xs@nestlevel\@ne
+ \integerpart\z@
+ \else
+ \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\@xs@reserved@A}%
+ \fi}%
\fi
- \expandafter\let\expandafter\@xs@next\ifx\@empty\@xs@reserved@A\relax\else\@xs@StrRemoveBraces@i\fi
- \@xs@next}%
+ \@xs@next}
-\def\@xs@strip@delimit#1\@delimit#2\@xs@nil{#1}
-% \@xs@cutafteroccur coupe l'argument #1 après la #3ème occurrence de #2
-% #4 : contient ce qui se trouve avant cette occurrence y compris l'occurrence
-% #5 : idem mais sans l'occurrence
-% #6 : contient ce qui se trouve après l'occurrence
-% si l'occurrence n'existe pas ou qu'un des arguments est vide, toutes les chaines renvoyées sont vides
-% utilise \@xs@reserved@A -> \@xs@reserved@B
-\def\@xs@cutafteroccur#1#2#3#4#5#6{%
- \def\@xs@cutafteroccur@i{%
- \ifx#6\@empty% on a fini de parcourir #6 ?
- \let\@xs@next\relax% on sort de la macro
+\@xs@newmacro\StrRemoveBraces{}{1}{1}{%
+ \def\@xs@reserved@C{#1}%
+ \let\@xs@reserved@B\@empty
+ \let\@xs@nestlevel\z@
+ \@xs@StrRemoveBraces@i
+ \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@B}{#2}}
+\def\@xs@StrRemoveBraces@i{%
+ \let\@xs@next\@xs@StrRemoveBraces@i
+ \ifx\@xs@reserved@C\@empty
+ \ifnum\@xs@nestlevel=\z@
+ \let\@xs@next\relax
\else
- \expandafter\@xs@IfBeginWith@i\expandafter{#6}{#2}%
- {\global\advance\@xs@count\@ne
- \ifnum\@xs@count<#3\relax\@xs@addtomacro#5{#2}\@xs@gaddtomacro\@xs@beforeoccur{#2}\fi
- \let#6\@xs@reserved@A}% on enlève le motif à #6
- {\expandafter\@xs@returnfirstsyntaxunit\expandafter{#6}\@xs@reserved@A% #6 ne commence pas par le motif : on prend la 1ere unité syntaxique
- \expandafter\@xs@removefirstsyntaxunit\expandafter{#6}#6% puis on l'enlève
- \@xs@exploregroups
- \ifx\bgroup\@xs@toks% si cette unité syntaxique est un groupe {...}
- \begingroup% alors on ouvre un groupe
- \expandafter\def\expandafter#6\@xs@reserved@A%
- \let#4\@empty\let#5\@empty% on initialise dans ce nouveau groupe
- \@xs@cutafteroccur@i% puis une récursivité
- \ifx#4\@empty% si l'occurrence n'est pas trouvée dans ce groupe
- \def\@xs@next{% on en sort après avoir rajouté à #5 du groupe de niveau au dessus le #5 de ce groupe
- \expandafter\endgroup
- \expandafter\@xs@addtomacro\expandafter#5\expandafter{\expandafter{#5}}}%
- \else
- \let\@xs@next\endgroup% sinon, on sort du groupe
- \fi
- \@xs@next
- \else
- \expandafter\@xs@gaddtomacro\expandafter\@xs@beforeoccur\expandafter{\@xs@reserved@A}%
- \expandafter\@xs@addtomacro\expandafter#5\expandafter{\@xs@reserved@A}%
- \fi}%
- \ifnum\@xs@count=#3\relax% l'occurrence est atteinte...
- \global\let#5#5\global\let#6#6% on passe à la globalité si jamais on est dans un groupe
- \expandafter\gdef\expandafter#4\expandafter{#5#2}% on rajoute le pattern à #5
- \let\@xs@next\relax% et on sort de la macro
+ \expandafter\endgroup
+ \expandafter\@xs@addtomacro\expandafter\@xs@reserved@B\expandafter{\@xs@reserved@B}%
+ \fi
+ \else
+ \expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@A
+ \expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@C
+ \ifx\bgroup\@xs@toks
+ \ifx\@xs@exploregroups\relax% on explore les groupes ?
+ \begingroup
+ \expandafter\def\expandafter\@xs@reserved@C\@xs@reserved@A
+ \let\@xs@nestlevel\@ne
+ \integerpart\z@
+ \let\@xs@reserved@B\@empty
\else
- \let\@xs@next\@xs@cutafteroccur@i%
+ \expandafter\@xs@addtomacro\expandafter\@xs@reserved@B\@xs@reserved@A
\fi
+ \else
+ \expandafter\@xs@addtomacro\expandafter\@xs@reserved@B\expandafter{\@xs@reserved@A}%
\fi
- \@xs@next}%
- \let#4\@empty\let#5\@empty\def#6{#1}\let\@xs@beforeoccur\@empty\@xs@count\z@
- \@xs@cutafteroccur@i
- \ifx\@empty#4\let#5#4\let#6#4\fi}% occurrence pas trouvée
+ \fi
+ \@xs@next}
-% utilise \@xs@reserved@A -> \@xs@reserved@D
-\@xs@newmacro\IfSubStr{1}{2}{0}{%
- \@xs@cutafteroccur{#2}{#3}{#1}\@xs@reserved@C\@xs@reserved@D\@xs@reserved@E
- \ifx\@xs@reserved@C\@empty
+\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
+% \@xs@reserved@E : contient ce qui se trouve apr\`es l'occurrence
+% 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@
+ \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
+ \global\let\@xs@reserved@D\@xs@reserved@D
+ \global\let\@xs@reserved@C\@xs@reserved@C
+ \global\let\groupID\groupID
+ \@xs@exitallgroups
+ \let\@xs@next\relax
+ \else
+ \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\@xs@reserved@E}%
+ \let\@xs@next\@xs@read@reserved@D
+ \fi}%
+ \@xs@read@reserved@D
+ \ifnum\@xs@count=\decimalpart% occurrence trouv\'ee ?
+ \let\@xs@reserved@E\@xs@reserved@D
+ \expandafter\def\expandafter\@xs@reserved@D\expandafter{\@xs@reserved@C#2}%
+ \else
+ \let\@xs@reserved@C\@empty\let\@xs@reserved@E\@empty\let\groupID\@empty
+ \fi}
+
+\@xs@newmacro*3\IfSubStr{1}{2}{0}{%
+ \@xs@cutafteroccur{#2}{#3}{#1}%
+ \ifx\@xs@reserved@D\@empty
\expandafter\@secondoftwo
\else
\expandafter\@firstoftwo
\fi}
-\@xs@newmacro\IfBeginWith{}{2}{0}{%
+\@xs@newmacro*2\IfBeginWith{}{2}{0}{%
\ifx\@empty#2\@empty
\let\@xs@next\@secondoftwo
\else
@@ -436,7 +503,7 @@
\fi
\@xs@next}
\def\@xs@IfBeginWith@i#1#2{%
- \ifx\@empty#2\@empty% #2 est vide, tous les tests sont passés avec succès : on renvoie #3
+ \ifx\@empty#2\@empty% #2 est vide, tous les tests sont pass\'es avec succ\`es : on renvoie #3
\let\@xs@next\@firstoftwo
\else
\ifx\@empty#1\@empty
@@ -444,8 +511,8 @@
\else
\@xs@returnfirstsyntaxunit{#1}\@xs@reserved@A
\@xs@returnfirstsyntaxunit{#2}\@xs@reserved@B
- \ifx\@xs@reserved@A\@xs@reserved@B% il y a égalité...
- \@xs@removefirstsyntaxunit{#1}\@xs@reserved@A% on enlève les 1ere unités syntaxiques
+ \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
\expandafter\expandafter\expandafter\@xs@IfBeginWith@i
@@ -457,31 +524,36 @@
\fi
\@xs@next}
-\@xs@newmacro\IfEndWith{}{2}{0}{%
- \@xs@StrCount{#1}{#2}[\@xs@reserved@A]%
- \ifnum\@xs@reserved@A=\z@
- \let\@xs@reserved@A\@secondoftwo%
+\@xs@newmacro*2\IfEndWith{}{2}{0}{%
+ \ifx\@empty#2\@empty
+ \let\@xs@reserved@A\@secondoftwo
\else
- \ifx\@empty\@xs@StrCount@afterlastocccur
- \let\@xs@reserved@A\@firstoftwo%
+ \@xs@StrCount{#1}{#2}[\@xs@reserved@A]%
+ \ifnum\@xs@reserved@A=\z@
+ \let\@xs@reserved@A\@secondoftwo
\else
- \let\@xs@reserved@A\@secondoftwo%
+ \ifx\@xs@reserved@C\@empty
+ \let\@xs@reserved@A\@firstoftwo
+ \else
+ \let\@xs@reserved@A\@secondoftwo
+ \fi
\fi
\fi
\@xs@reserved@A}
-\@xs@newmacro\IfSubStrBefore{1,1}{3}{0}{\@xs@IfSubStrBefore@i[#1]{#2}{#3}{#4}}
+\@xs@newmacro*4\IfSubStrBefore{1,1}{3}{0}{\@xs@IfSubStrBefore@i[#1]{#2}{#3}{#4}}
\def\@xs@IfSubStrBefore@i[#1,#2]#3#4#5{%
- \ifx\@xs@exploregroups\@empty\let\@xs@reserved@C\@empty\def\@xs@reserved@A{#3}\@xs@StrRemoveBraces@i\else\def\@xs@reserved@C{#3}\fi
- \expandafter\@xs@cutafteroccur\expandafter{\@xs@reserved@C}{#5}{#2}\@xs@reserved@C\@xs@reserved@D\@xs@reserved@E
- \expandafter\@xs@cutafteroccur\expandafter{\@xs@reserved@D}{#4}{#1}\@xs@reserved@C\@xs@reserved@D\@xs@reserved@E
+ \ifx\@xs@exploregroups\relax\let\@xs@reserved@C\@empty\def\@xs@reserved@A{#3}\@xs@StrRemoveBraces@i\else\def\@xs@reserved@C{#3}\fi
+ \expandafter\@xs@cutafteroccur\expandafter{\@xs@reserved@C}{#5}{#2}%
+ \expandafter\@xs@cutafteroccur\expandafter{\@xs@reserved@C}{#4}{#1}%
+ \let\groupID\@empty
\ifx\@xs@reserved@C\@empty
\expandafter\@secondoftwo
\else
\expandafter\@firstoftwo
\fi}
-\@xs@newmacro\IfSubStrBehind{1,1}{3}{0}{\@xs@IfSubStrBehind@i[#1]{#2}{#3}{#4}}
+\@xs@newmacro*4\IfSubStrBehind{1,1}{3}{0}{\@xs@IfSubStrBehind@i[#1]{#2}{#3}{#4}}
\def\@xs@IfSubStrBehind@i[#1,#2]#3#4#5{\@xs@IfSubStrBefore@i[#2,#1]{#3}{#5}{#4}}
\def\@xs@formatnumber#1#2{%
@@ -544,28 +616,28 @@
\expandafter\@xs@endnumber\@xs@afterinteger\@xs@nil}
\def\@xs@endnumber#1\@xs@nil{\def\@xs@afterdecimal{#1}}
-% test d'égalité sur des chaines (et des chaines contenant des nombres)
+% test d'\'egalit\'e sur des chaines (et des chaines contenant des nombres)
\def\@xs@IfStrEqFalse@i#1#2{\let\@xs@reserved@A\@secondoftwo}
-\def\@xs@IfStrEqFalse@ii#1#2{% renvoie vrai si les 2 arg sont décimaux et s'ils sont égaux, faux sinon
+\def\@xs@IfStrEqFalse@ii#1#2{% renvoie vrai si les 2 arg sont d\'ecimaux et s'ils sont \'egaux, faux sinon
\@xs@IfDecimal{#1}%
{\@xs@IfDecimal{#2}%
- {\ifdim#1pt=#2pt\let\@xs@reserved@A\@firstoftwo\else\let\@xs@reserved@A\@secondoftwo\fi}% les 2 sont décimaux : on fait le test
- {\let\@xs@reserved@A\@secondoftwo}}% un seul est décimal
- {\let\@xs@reserved@A\@secondoftwo}}% #1 n'est pas décimal
+ {\ifdim#1pt=#2pt\let\@xs@reserved@A\@firstoftwo\else\let\@xs@reserved@A\@secondoftwo\fi}% les 2 sont d\'ecimaux : on fait le test
+ {\let\@xs@reserved@A\@secondoftwo}}% un seul est d\'ecimal
+ {\let\@xs@reserved@A\@secondoftwo}}% #1 n'est pas d\'ecimal
-\def\@xs@TestEqual#1#2{% teste si les 2 arguments sont égaux
+\def\@xs@TestEqual#1#2{% teste si les 2 arguments sont \'egaux
\def\@xs@reserved@A{#1}\def\@xs@reserved@B{#2}%
\ifx\@xs@reserved@A\@xs@reserved@B
- \let\@xs@reserved@A\@firstoftwo% égalité parfaite des 2 chaines
+ \let\@xs@reserved@A\@firstoftwo% \'egalit\'e parfaite des 2 chaines
\else
\@xs@reserved@D{#1}{#2}%
\fi
\@xs@reserved@A}
-\@xs@newmacro\IfStrEq{}{2}{0}{% teste si les deux chaines sont égales
+\@xs@newmacro*2\IfStrEq{}{2}{0}{% teste si les deux chaines sont \'egales
\let\@xs@reserved@D\@xs@IfStrEqFalse@i
\@xs@TestEqual{#1}{#2}}
-\@xs@newmacro\IfEq{}{2}{0}{% teste si les 2 arguments (chaine ou nombre) sont égaux
+\@xs@newmacro*2\IfEq{}{2}{0}{% teste si les 2 arguments (chaine ou nombre) sont \'egaux
\let\@xs@reserved@D\@xs@IfStrEqFalse@ii
\@xs@TestEqual{#1}{#2}}
@@ -576,259 +648,227 @@
\def\@xs@IfEqCase#1#2{\@testopt{\@xs@IfStringCase{#1}{#2}}{}}
\def\@xs@IfStringCase#1#2[#3]{%
- \def\@xs@testcase##1##2##3\@xs@nil{% lit les 2 premieres unités syntaxiques dans ##1 et ##2. Les autres dans ##3
+ \def\@xs@testcase##1##2##3\@xs@nil{% lit les 2 premieres unit\'es syntaxiques dans ##1 et ##2. Les autres dans ##3
\@xs@reserved@E{#1}{##1}%
- {##2}% le test est positif, on exécute le code correspondant
- {\ifx\@empty##3\@empty% le test est négatif
- \def\@xs@next{#3}% s'il n'y a plus de cas, on exécute le code <autres cas>
+ {##2}% le test est positif, on ex\'ecute le code correspondant
+ {\ifx\@empty##3\@empty% le test est n\'egatif
+ \def\@xs@next{#3}% s'il n'y a plus de cas, on ex\'ecute le code <autres cas>
\else
\def\@xs@next{\@xs@testcase##3\@xs@nil}% sinon, on recommence avec ce qui reste
\fi
\@xs@next}}%
\@xs@testcase#2\@xs@nil}
+% Renvoie ce qui est \`a gauche de l'occurence n°#1 de la sous chaine #3 dans la chaine
+\@xs@newmacro*3\StrBefore{1}{2}{1}{%
+ \@xs@cutafteroccur{#2}{#3}{#1}%
+ \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#4}}
-% Renvoie ce qui est à gauche de l'occurence n°#1 de la sous chaine #3 dans la chaine
-\@xs@newmacro\StrBefore{1}{2}{1}{%
- \@xs@cutafteroccur{#2}{#3}{#1}\@xs@reserved@C\@xs@reserved@D\@xs@reserved@E
- \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@D}{#4}}
-
-% Renvoie ce qui est à droite de l'occurence n°#1 de la sous chaine #3 dans la chaine #2
-\@xs@newmacro\StrBehind{1}{2}{1}{%
- \@xs@cutafteroccur{#2}{#3}{#1}\@xs@reserved@C\@xs@reserved@D\@xs@reserved@E
+% Renvoie ce qui est \`a droite de l'occurence n°#1 de la sous chaine #3 dans la chaine #2
+\@xs@newmacro*3\StrBehind{1}{2}{1}{%
+ \@xs@cutafteroccur{#2}{#3}{#1}%
\expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@E}{#4}}
% Renvoie ce qui est strictement compris entre les occurrences n°#1 et n°#2
% des chaines #4 et #5 dans la chaine #3
-\@xs@newmacro\StrBetween{1,1}{3}{1}{\@xs@StrBetween@i[#1]{#2}{#3}{#4}[#5]}
+\@xs@newmacro*4\StrBetween{1,1}{3}{1}{\@xs@StrBetween@i[#1]{#2}{#3}{#4}[#5]}
\def\@xs@StrBetween@i[#1,#2]#3#4#5[#6]{%
\begingroup
\noexploregroups
- \@xs@cutafteroccur{#3}{#5}{#2}\@xs@reserved@C\@xs@reserved@D\@xs@reserved@E
- \expandafter\@xs@cutafteroccur\expandafter{\@xs@reserved@D}{#4}{#1}\@xs@reserved@C\@xs@reserved@D\@xs@reserved@E
+ \@xs@cutafteroccur{#3}{#5}{#2}%
+ \expandafter\@xs@cutafteroccur\expandafter{\@xs@reserved@C}{#4}{#1}%
\expandafter
\endgroup
- \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@E}{#6}}
+ \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@E}{#6}%
+ \let\groupID\@empty}
\def\@xs@addtomacro#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
-\def\@xs@gaddtomacro#1#2{\expandafter\gdef\expandafter#1\expandafter{#1#2}}
-\def\exploregroups{\def\@xs@exploregroups{}}
+
+\def\exploregroups{\let\@xs@exploregroups\relax}
\def\noexploregroups{\def\@xs@exploregroups{\let\@xs@toks0\relax}}
\def\saveexploremode{\let\@xs@saveexploremode\@xs@exploregroups}
\def\restoreexploremode{\let\@xs@exploregroups\@xs@saveexploremode}
-% Remplace les #1 premières occurences de la chaine #3
+
+% Remplace les #1 premi\`eres occurences de la chaine #3
% par la chaine #4 dans la chaine #2
-% utilise \@xs@reserved@A -> \@xs@reserved@E
\@xs@newmacro\StrSubstitute{0}{3}{1}{%
- \ifx\@empty#3\@empty% si #4 est vide, on ne fait rien
- \@xs@ArgEmpty% warning
- \@xs@ReturnResult{#2}{#5}%
- \else
- \@xs@StrSubstitute@i[#1]{#2}{#3}{#4}{#5}%
- \fi}%
-\def\@xs@StrSubstitute@i[#1]#2#3#4#5{%
- \def\@xs@StrSubstitute@ii{%
- \ifx\@xs@reserved@C\@empty% on a fini de parcourir \@xs@reserved@C ?
- \let\@xs@next\relax% on sort de la macro
+ \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@
+ \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@
+ \def\@xs@reserved@A{#4}%
\else
- \ifnum\@xs@count=#1\relax
- \expandafter\@xs@addtomacro\expandafter\@xs@reserved@D\expandafter{\@xs@reserved@C}%
- \let\@xs@next\relax
+ \ifnum\@xs@count>#1
+ \def\@xs@reserved@A{#3}%
\else
- \expandafter\@xs@IfBeginWith@i\expandafter{\@xs@reserved@C}{#3}%
- {\@xs@addtomacro\@xs@reserved@D{#4}% \@xs@reserved@C commence par le motif --> on substitue
- \global\advance\@xs@count\@ne
- \let\@xs@reserved@C\@xs@reserved@A}% on enlève le motif à \@xs@reserved@C
- {\expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@A% \@xs@reserved@C ne commence pas par le motif : on prend la 1ere unité syntaxique
- \expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@C% puis on l'enlève
- \@xs@exploregroups
- \ifx\bgroup\@xs@toks% si cette unité syntaxique est un groupe {...}
- \begingroup% alors on ouvre un groupe
- \expandafter\def\expandafter\@xs@reserved@C\@xs@reserved@A% \@xs@reserved@C devient l'intérieur de {...}
- \let\@xs@reserved@D\@empty% #4 est initialisé à vide dans ce nouveau groupe
- \@xs@StrSubstitute@ii% on lance la macro avec ces nouvelles définitions
- \expandafter% on retarde la fermeture du groupe
- \endgroup% pour ajouter \@xs@reserved@D de ce groupe au \@xs@reserved@D du groupe supérieur
- \expandafter\@xs@addtomacro\expandafter\@xs@reserved@D\expandafter{\expandafter{\@xs@reserved@D}}%
- \else
- \expandafter\@xs@addtomacro\expandafter\@xs@reserved@D\expandafter{\@xs@reserved@A}%
- \fi}%
- \let\@xs@next\@xs@StrSubstitute@ii%
+ \def\@xs@reserved@A{#4}%
\fi
\fi
- \@xs@next}%
- \def\@xs@reserved@D{}\def\@xs@reserved@C{#2}%
- \@xs@count\ifnum#1>\z@\z@\else\@ne\fi
- \@xs@StrSubstitute@ii
- \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@D}{#5}}
+ \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\@xs@reserved@A}%
+ \@xs@read@reserved@D}%
+ \ifx\@empty#3\@empty
+ \@xs@ReturnResult{#2}{#5}%
+ \else
+ \@xs@read@reserved@D
+ \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#5}%
+ \fi}
-% Supprime les #1 premières occurrences de #3 dans #2
+% Supprime les #1 premi\`eres occurrences de #3 dans #2
\@xs@newmacro\StrDel{0}{2}{1}{\@xs@StrSubstitute[#1]{#2}{#3}{}[#4]}
-% Compte combien d'unités syntaxiques contient la chaine #1 ?
+\def\@xs@exitallgroups{\ifnum\@xs@nestlevel>\z@\endgroup\expandafter\@xs@exitallgroups\fi}
+
+% Compte combien d'unit\'es syntaxiques contient la chaine #1 ?
\@xs@newmacro\StrLen{}{1}{1}{%
\def\@xs@reserved@C{#1}%
\@xs@count\z@
- \@xs@StrLen@i
+ \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}}
-\def\@xs@StrLen@i{%
+
+% Macro interne fermant autant de groupes que n\'ecessaire pour trouver une unit\'e syntaxique derri\`ere
+\def\@xs@continuetonext{%
\ifx\@xs@reserved@C\@empty
+ \ifnum\@xs@nestlevel>\z@
+ \expandafter\endgroup\expandafter\@xs@addtomacro\expandafter\@xs@reserved@B\expandafter{\expandafter{\@xs@reserved@B}}% on concat\`ene
+ \expandafter\expandafter\expandafter\@xs@continuetonext% on recommence
+ \fi
+ \fi}%
+
+\def\@xs@manage@groupID{%
+ \begingroup\def\@xs@reserved@A{0}%
+ \ifx\@xs@reserved@A\groupID% si on arrive du groupe de niveau 0
+ \endgroup\edef\groupID{\number\integerpart}% on met simplement le niveau
\else
- \expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@A
- \expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@C
- \@xs@exploregroups
- \ifx\bgroup\@xs@toks
- \begingroup
- \expandafter\def\expandafter\@xs@reserved@C\@xs@reserved@A
- \@xs@StrLen@i
- \endgroup
- \else
- \global\advance\@xs@count\@ne
- \fi%
- \expandafter\@xs@StrLen@i
+ \endgroup\expandafter\@xs@addtomacro\expandafter\groupID\expandafter{\expandafter,\number\integerpart}%
\fi}
-% % Cette macro coupe la chaine #2 après l'unité syntaxique n°#1
-% % Le début est assigné dans #3 et la fin dans #4
-\@xs@newmacro\StrSplit{}{2}{0}{\@xs@StrSplit@i{#2}{#1}}
-\def\@xs@StrSplit@i#1#2#3#4{%
- \def\@xs@StrSplit@ii{%
- \ifx#4\@empty
- \let\@xs@next\relax
- \else
- \expandafter\@xs@returnfirstsyntaxunit\expandafter{#4}\@xs@reserved@A
- \expandafter\@xs@removefirstsyntaxunit\expandafter{#4}#4%
- \@xs@exploregroups
- \ifx\bgroup\@xs@toks
- \begingroup
- \expandafter\def\expandafter#4\@xs@reserved@A
- \let#3\@empty
- \@xs@StrSplit@ii
- \ifx#4\@empty
- \def\@xs@next{%
- \expandafter\endgroup
- \expandafter\@xs@addtomacro\expandafter#3\expandafter{\expandafter{#3}}}%
- \else
- \let\@xs@next\endgroup
- \fi
- \@xs@next
- \else
- \global\advance\@xs@count\@ne
- \expandafter\@xs@addtomacro\expandafter#3\expandafter{\@xs@reserved@A}%
- \fi
- \ifnum\@xs@count=#1\relax
- \global\let#3#3\global\let#4#4%
- \let\@xs@next\relax
- \else
- \let\@xs@next\@xs@StrSplit@ii
- \fi
- \fi
- \@xs@next}%
- \def#4{#2}\let#3\@empty
+% Cette macro coupe la chaine #1 apr\`es l'unit\'e syntaxique n°#2
+\def\StrSplit{\@ifstar{\let\@xs@reserved@E\@xs@continuetonext\StrSpl@t}{\let\@xs@reserved@E\relax\StrSpl@t}}
+\@xs@newmacro\StrSpl@t{}{2}{0}{\@xs@StrSplit@i{#2}{#1}\@xs@StrSplit@ii}
+% Cette macro interne coupe la chaine #2 apr\`es l'unit\'e syntaxique n°#1
+% Le d\'ebut est assign\'e dans \@xs@reserved@B et la fin dans \@xs@reserved@C
+\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@
- \@xs@StrSplit@ii
+ \@xs@count\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}}%
+ \@xs@read@reserved@C}%
+ \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
+ \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
+ \global\let\groupID\groupID
+ \@xs@exitallgroups
+ \let\@xs@next\relax
+ \fi}%
+ \@xs@read@reserved@C
\fi}
+\def\@xs@StrSplit@ii#1#2{\let#1\@xs@reserved@B\let#2\@xs@reserved@C}
% De la chaine #1, renvoie ce qui se trouve entre les positions
-% #2 et #3, caractères aux positions compris !
+% #2 et #3, unit\'es syntaxiques aux positions compris !
\@xs@newmacro\StrMid{}{3}{1}{%
\begingroup
\noexploregroups
- \@xs@StrSplit{#1}{#3}\@xs@reserved@B\@xs@reserved@C
- \expandafter\expandafter\expandafter\@xs@StrSplit\expandafter\expandafter\expandafter{\expandafter\@xs@reserved@B\expandafter}\expandafter{\number\numexpr#2-1}\@xs@reserved@B\@xs@reserved@C
+ \@xs@StrSplit@i{#3}{#1}%
+ \edef\@xs@reserved@C{\number\numexpr#2-1}%
+ \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}}
+ \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#4}%
+ \let\groupID\@empty}
-% supprime #2 caractères à gauche dans la chaine #1
+% supprime #2 unit\'es syntaxiques \`a gauche dans la chaine #1
\@xs@newmacro\StrGobbleLeft{}{2}{1}{%
- \@xs@StrSplit@i{#2}{#1}\@xs@reserved@B\@xs@reserved@C
+ \@xs@StrSplit@i{#2}{#1}%
\expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#3}}
-% extrait de #1 la chaine à gauche de longueur #2
+% extrait de #1 la chaine \`a gauche de longueur #2
\@xs@newmacro\StrLeft{}{2}{1}{%
- \@xs@StrSplit@i{#2}{#1}\@xs@reserved@B\@xs@reserved@C
+ \@xs@StrSplit@i{#2}{#1}%
\expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@B}{#3}}
-% supprime #2 caractères à droite dans la chaine #1
+% 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@reserved@C\@xs@reserved@D
- \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#3}}
+ \expandafter\@xs@StrSplit@i\expandafter{\number\numexpr\@xs@reserved@E-#2}{#1}%
+ \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@B}{#3}}
-% renvoie #2 caractères à la droite de la chaine #1
+% 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@reserved@C\@xs@reserved@D
- \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@D}{#3}}
+ \expandafter\@xs@StrSplit@i\expandafter{\number\numexpr\@xs@reserved@E-#2}{#1}%
+ \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#3}}
\@xs@newmacro\StrChar{}{2}{1}{%
- \ifnum#2<\@ne
- \@xs@ReturnResult{}{#3}%
- \else
- \expandafter\@xs@StrSplit@i\expandafter{\number\numexpr#2-1}{#1}\@xs@reserved@C\@xs@reserved@D
- \expandafter\@xs@StrSplit@i\expandafter{\expandafter1\expandafter}\expandafter{\@xs@reserved@D}\@xs@reserved@C\@xs@reserved@D
- \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#3}%
- \fi}
+ \let\@xs@reserved@B\@empty
+ \ifnum#2>\z@
+ \def\@xs@reserved@C{#1}\def\@xs@reserved@D{#2}\@xs@count\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 ?
+ \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
+ \let\@xs@next\relax
+ \fi}%
+ \@xs@read@reserved@C
+ \fi
+ \ifx\@xs@reserved@B\@empty\let\groupID\@empty\fi
+ \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@B}{#3}}
% Combien de fois compte t-on #2 dans #1 ?
-% utilise \@xs@reserved@A -> \@xs@reserved@C en mode arg
\@xs@newmacro\StrCount{}{2}{1}{%
\ifx\@empty#2\@empty
- \@xs@ArgEmpty
- \def\@xs@StrCount@afterlastocccur{}%
\@xs@ReturnResult{0}{#3}%
\else
- \@xs@StrCount@i{#1}{#2}{#3}%
+ \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@
+ \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}%
\fi}
-\def\@xs@StrCount@i#1#2#3{%
- \def\@xs@StrCount@ii{%
- \ifx\@xs@reserved@C\@empty% on a fini de parcourir \@xs@reserved@C ?
- \let\@xs@next\relax% on sort de la macro
- \else
- \expandafter\@xs@IfBeginWith@i\expandafter{\@xs@reserved@C}{#2}%
- {\global\advance\@xs@count\@ne
- \let\@xs@StrCount@afterlastocccur\@xs@reserved@A
- \let\@xs@reserved@C\@xs@reserved@A}% on enlève le motif à \@xs@reserved@C
- {\expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@A% \@xs@reserved@C ne commence pas par le motif : on prend la 1ere unité syntaxique
- \expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@C% puis on l'enlève
- \@xs@exploregroups
- \ifx\bgroup\@xs@toks% si cette unité syntaxique est un groupe {...}
- \begingroup% alors on ouvre un groupe
- \expandafter\def\expandafter\@xs@reserved@C\@xs@reserved@A% \@xs@reserved@C devient l'intérieur de {...}
- \@xs@StrCount@ii% on lance la macro avec ces nouvelles définitions
- \endgroup
- \fi}%
- \let\@xs@next\@xs@StrCount@ii
- \fi
- \@xs@next}%
- \def\@xs@reserved@C{#1}\def\@xs@StrCount@afterlastocccur{#1}%
- \@xs@count\z@
- \@xs@StrCount@ii
- \expandafter\@xs@ReturnResult\expandafter{\number\@xs@count}{#3}}
% renvoie la position de l'occurrence #1 de la sous chaine #3 dans la chaine #2
\@xs@newmacro\StrPosition{1}{2}{1}{%
- \@xs@cutafteroccur{#2}{#3}{#1}\@xs@reserved@C\@xs@reserved@D\@xs@reserved@E
+ \@xs@cutafteroccur{#2}{#3}{#1}%
+ \let\@xs@reserved@E\groupID
\ifx\@xs@reserved@C\@xs@reserved@D
\@xs@ReturnResult{0}{#4}%
+ \let\@xs@reserved@E\@empty
\else
- \ifx\@empty\@xs@exploregroups% on explore les groupes ?
- \expandafter\@xs@StrLen\expandafter{\@xs@beforeoccur}[\@xs@reserved@D]%
- \else
- \expandafter\@xs@StrLen\expandafter{\@xs@reserved@D}[\@xs@reserved@D]%
- \fi
- \expandafter\@xs@ReturnResult\expandafter{\number\numexpr\@xs@reserved@D+1}{#4}%
- \fi}
+ \expandafter\@xs@StrLen\expandafter{\@xs@reserved@C}[\@xs@reserved@C]%
+ \expandafter\@xs@ReturnResult\expandafter{\number\numexpr\@xs@reserved@C+1}{#4}%
+ \fi
+ \let\groupID\@xs@reserved@E}
-\def\comparestrict{\def\@xs@comparecoeff{1}}
-\def\comparenormal{\def\@xs@comparecoeff{0}}
+\def\comparestrict{\let\@xs@comparecoeff\@ne}
+\def\comparenormal{\let\@xs@comparecoeff\z@}
\def\savecomparemode{\let\@xs@saved@comparecoeff\@xs@comparecoeff}
\def\restorecomparemode{\let\@xs@comparecoeff\@xs@saved@comparecoeff}
% Compare les deux arguments #1 et #2
-% Renvoie 0 s'ils sont égaux et renvoie la
-% position du premier token différent sinon
-\@xs@newmacro\StrCompare{}{2}{1}{%
+% Renvoie 0 s'ils sont \'egaux et renvoie la
+% position de la premiere unit\'e syntaxiques diff\'erente sinon
+\@xs@newmacro*2\StrCompare{}{2}{1}{%
\def\@xs@reserved@A{#1}%
\def\@xs@reserved@B{#2}%
\ifx\@xs@reserved@B\@xs@reserved@A
@@ -848,23 +888,66 @@
\expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@D}\@xs@reserved@B
\ifx\@xs@reserved@B\@xs@reserved@A
\ifx\@xs@reserved@A\@empty
- \@xs@StrCompare@iii{##1}% les 2 unités syntaxiques sont égales, on renvoie la position
+ \@xs@StrCompare@iii{##1}% les 2 unit\'es syntaxiques sont \'egales, on renvoie la position
\else
- \def\@xs@next{\expandafter\@xs@StrCompare@ii\expandafter{\number\numexpr##1+1}}% les 2 unités syntaxiques sont égales et non vides, on recommence
+ \def\@xs@next{\expandafter\@xs@StrCompare@ii\expandafter{\number\numexpr##1+1}}% les 2 unit\'es syntaxiques sont \'egales et non vides, on recommence
\expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@C
\expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@reserved@D}\@xs@reserved@D
\fi
- \else% les 2 caractères sont différents : on renvoie la position
+ \else% les 2 unit\'es syntaxiques sont diff\'erentes : on renvoie la position
\@xs@StrCompare@iii{##1}%
\fi
\@xs@next}%
\def\@xs@reserved@C{#1}\def\@xs@reserved@D{#2}%
\@xs@StrCompare@ii1}
+\@xs@newmacro\StrFindGroup{}{2}{1}{%
+ \def\@xs@reserved@A{#2}\def\@xs@reserved@B{0}%
+ \ifx\@xs@reserved@A\@xs@reserved@B
+ \def\@xs@next{\@xs@ReturnResult{{#1}}{#3}}%
+ \else
+ \def\@xs@next{\@xs@StrFindGroup@i{#1}{#2}[#3]}%
+ \fi
+ \@xs@next}
+\def\@xs@StrFindGroup@i#1#2[#3]{%
+ \def\@xs@StrFindGroup@ii{%
+ \ifx\@xs@reserved@C\@empty
+ \def\@xs@next{\@xs@ReturnResult{}{#3}}% s'il ne reste plus rien, on renvoie vide
+ \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 ?
+ \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
+ \expandafter\def\expandafter\@xs@next\expandafter{\expandafter\@xs@StrFindGroup@i\@xs@reserved@D}% on recommence avec ce groupe
+ \expandafter\@xs@addtomacro\expandafter\@xs@next\expandafter{\expandafter{\@xs@reserved@B}[#3]}% et les profondeurs de recherche restantes
+ \fi
+ \else
+ \expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@C
+ \let\@xs@next\@xs@StrFindGroup@ii
+ \fi
+ \else
+ \expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@C
+ \let\@xs@next\@xs@StrFindGroup@ii
+ \fi
+ \fi
+ \@xs@next}%
+ \@xs@extractgroupnumber{#2}\@xs@reserved@A\@xs@reserved@B
+ \@xs@count\z@
+ \ifnum\@xs@reserved@A>\z@\def\@xs@reserved@C{#1}\else\let\@xs@reserved@C\@empty\fi
+ \@xs@StrFindGroup@ii}
+
+\def\@xs@extractgroupnumber#1#2#3{%
+ \def\@xs@extractgroupnumber@i##1,##2\@xs@nil{\def#2{##1}\def#3{##2}}%
+ \@xs@extractgroupnumber@i#1,\@xs@nil
+ \ifx\@empty#3\else\@xs@extractgroupnumber@i#1\@xs@nil\fi}
+
% Restaure le code de @
\catcode`\@=\CurrentAtCatcode\relax
-% Définit le délimiteur verb
-% définit les différents modes et les mémorise
+% D\'efinit le d\'elimiteur verb
+% d\'efinit les diff\'erents modes et les m\'emorise
\setverbdelim{|}%
\fullexpandarg\saveexpandmode
\comparenormal\savecomparemode
@@ -873,83 +956,101 @@
%
% Historique
%------------------------------------------------------------------------------
-%% v1.0 4/7/2008 : - Package achevé.
-% 7/7/2008 : - Package publié sur CTAN.
+%% v1.0 4/7/2008 : - Package achev\'e.
+% 7/7/2008 : - Package publi\'e sur CTAN.
%------------------------------------------------------------------------------
% v1.1 15/8/2008
-% - Le package ne nécessite plus LaTeX et est désormais utilisable sous Plain
-% eTeX.
+% - Le package ne n\'ecessite plus LaTeX et est d\'esormais utilisable sous
+% Plain eTeX.
% - Ajout des macros \IfInteger et \IfDecimal.
-% Pour cette dernière, la partie entière et la partie décimale sont
-% récupérables dans les compteurs \integerpart et \decimalpart. Ce qu'il
-% reste après qu'un caractère non attendu soit rencontré est dispo dans
-% \@xs@remainafterdecimal
+% Pour cette derni\`ere, la partie enti\`ere et la partie d\'ecimale sont
+% r\'ecup\'erables dans les compteurs \integerpart et \decimalpart. Ce
+% qu'il reste apr\`es qu'un caract\`ere non attendu soit rencontr\'e est
+% dispo dans \@xs@remainafterdecimal
% - Correction d'un bug dans \tokenize :
-% suppression de l'expansion avec \normalexpandarg pour éviter le bug
-% avec les lettres accentuées dans l'exemple : \tokenize\aa{éù}
-% - Amélioration du code de la plupart des macros.
-% - Écriture d'une routine \@xs@newmacro définissant les macros.
-% - Suppression de tous les compteurs grace à \numexpr.
-% - Nouvelles fonctionnalités internes dans :
+% suppression de l'expansion avec \normalexpandarg pour \'eviter le bug
+% avec les lettres accentu\'ees dans l'exemple : \tokenize\aa{\'e\`u}
+% - Am\'elioration du code de la plupart des macros.
+% - \'Ecriture d'une routine \@xs@newmacro d\'efinissant les macros.
+% - Suppression de tous les compteurs grace \`a \numexpr.
+% - Nouvelles fonctionnalit\'es internes dans :
% \IfSubStr
-% ajout des chaines se trouvant avant et après l'occurrence testée dans
-% les sc \@xs@behind@IfSubStr et \@xs@before@IfSubStr
+% ajout des chaines se trouvant avant et apr\`es l'occurrence test\'ee
+% dans les sc \@xs@behind@IfSubStr et \@xs@before@IfSubStr
% \StrCount
-% a) ajout de ce qui se trouve après la dernière occurrence dans la sc%
-% \@xs@StrCount@afterlastocccur
-% b) la macro ne dépend plus d'aucune autre
+% a) ajout de ce qui se trouve apr\`es la derni\`ere occurrence dans la
+% sc \@xs@StrCount@afterlastocccur
+% b) la macro ne d\'epend plus d'aucune autre
%------------------------------------------------------------------------------
% v1.2 23/8/2008
-% - Amélioration du code de \StrMid \StrGobbleLeft, \StrLeft, \StrGobbleRight
-% et \StrRight à l'aide de la nouvelle macro \@xs@StrSplit@i
+% - Am\'elioration du code de \StrMid \StrGobbleLeft, \StrLeft,
+% \StrGobbleRight et \StrRight \`a l'aide de la nouvelle macro
+% \@xs@StrSplit@i
% - Nouveau test \IfStrEq qui compare 2 chaines
% - Nouveau test \IfEq qui compare 2 chaines (ou 2 nombres si les 2 chaines
% contiennent un nombre)
% - Correction d'un bug dans \@xs@formatnumber. La macro n'envisageait pas le
-% cas où son argument était vide ce qui faiasait planter \IfDecimal{}{V}{F}
-% et \IfInteger{}{V}{F}
+% cas o\`u son argument \'etait vide ce qui faiasait planter
+% \IfDecimal{}{V}{F} et \IfInteger{}{V}{F}
%------------------------------------------------------------------------------
% v1.3 21/9/2008
-% - Amélioration du code, mise en place de récursivités terminales dans toutes
-% les macros récursives, simplification de \@xs@TestEqual en utilisant \ifx
+% - Am\'elioration du code, mise en place de r\'ecursivit\'es terminales dans
+% toutes les macros r\'ecursives, simplification de \@xs@TestEqual en
+% utilisant \ifx
% - Nouvelles macros \IfStrEqCase et \IfEqCase
-% Teste si une chaîne est égale à plusieurs chaînes donnée et exécute un
-% code spécifique
-% - Création de la macro publique \StrSplit
-% Coupe la chaine en 2 à une position donnée
+% Teste si une chaîne est \'egale \`a plusieurs chaînes donn\'ee et
+% ex\'ecute un code sp\'ecifique
+% - Cr\'eation de la macro publique \StrSplit
+% Coupe la chaine en 2 \`a une position donn\'ee
% - Nouvelle macro \StrCompare
-% Compare 2 chaînes et renvoie la position du 1er caractère différent.
-% Renvoie 0 si elles sont égales.
+% Compare 2 chaînes et renvoie la position du 1er caract\`ere diff\'erent.
+% Renvoie 0 si elles sont \'egales.
%------------------------------------------------------------------------------
% v1.3a 29/9/2008
% - Correction d'un bug : \expandafter#1
% dans les macros \IfSubStrBefore et \StrBetween qui buggue si #1 est un
% nombre > 9 !
-% - Ré écriture de \@xs@returnfirstsyntaxunit et \@xs@gobblefirstchar qui
-% deviennent purement développables.
-% - Ré écriture de \StrLen
+% - R\'e \'ecriture de \@xs@returnfirstsyntaxunit et \@xs@gobblefirstchar qui
+% deviennent purement d\'eveloppables.
+% - R\'e \'ecriture de \StrLen
% - Nouvelle macro interne \@xs@cutafteroccur
-% Coupe la chaine après la nième occurrence d'une sous chaine.
-% - Code amélioré de \StrMid, \StrLeft, \StrGobbleLeft, \StrRight,
-% \StrGobbleRight grace à \@xs@cutafteroccur
+% Coupe la chaine apr\`es la ni\`eme occurrence d'une sous chaine.
+% - Code am\'elior\'e de \StrMid, \StrLeft, \StrGobbleLeft, \StrRight,
+% \StrGobbleRight grace \`a \@xs@cutafteroccur
%------------------------------------------------------------------------------
% v1.4 4/11/2008
-% - xstring traite ses arguments par unité syntaxique, et donc toutes les
-% macros internes ont été ré-écrites à cette fin.
-% - Le manuel a été ré-écrit, rendu plus clair et mieux structuré.
-% - Nouvelle fonctionnalité : \expandarg
-% le 1er lexème de chaque argument est 1-développé avant que la macro ne
-% soit appelée. Si un argument comporte plus qu'1 lexème, il faut passer
-% par \scancs*[1] pour 1-développer toutes les unités syntaxiques.
+% - xstring traite ses arguments par unit\'e syntaxique, et donc toutes les
+% macros internes ont \'et\'e r\'e-\'ecrites \`a cette fin.
+% - Le manuel a \'et\'e r\'e-\'ecrit, rendu plus clair et mieux structur\'e.
+% - Nouvelle fonctionnalit\'e : \expandarg
+% le 1er lex\`eme de chaque argument est 1-d\'evelopp\'e avant que la
+% macro ne soit appel\'ee. Si un argument comporte plus qu'1 lex\`eme,
+% il faut passer par \scancs*[1] pour 1-d\'evelopper toutes les unit\'es
+% syntaxiques.
% - Correction de 2 erreurs dans le manuel anglais : 0 est la valeur par
-% défaut dans \StrSubstitute et \StrDel
-% - Cohérence dans les nom des séquences de contrôles temporaires qui sont
-% \@xs@reserved@A -> \@xs@reserved@E
+% d\'efaut dans \StrSubstitute et \StrDel
+% - Coh\'erence dans les nom des s\'equences de contr\^oles temporaires qui
+% sont d\'esormais : \@xs@reserved@A \`a \@xs@reserved@E
%------------------------------------------------------------------------------
% v1.4a 12/11/2008
-% - Correction d'un bug dans \@xs@StrSplit dans le cas où l'argument numérique
-% est <1 : la 1ere coupure doit être vide et le seconde doit être égale à
-% l'argument.
+% - Correction d'un bug dans \@xs@StrSplit dans le cas o\`u l'argument
+% num\'erique est <1 : la 1ere coupure doit être vide et le seconde doit
+% être \'egale \`a l'argument.
%------------------------------------------------------------------------------
% v1.4b 16/11/2008
-% - Correction de 2 bugs dans \@xs@returnfirstsyntaxunit \ No newline at end of file
+% - Correction de 2 bugs dans \@xs@returnfirstsyntaxunit
+%------------------------------------------------------------------------------
+% v1.5 31/12/2008
+% - Nouvelles fonctionnalit\'es dans la recherche de groupes par un
+% identificateur caract\'erisant leur imbrication. Impl\'ementation de :
+% 1) \StrFindGroup
+% 2) \groupID
+% - Ajout des nouvelles macros g\'en\'eriques \@xs@read@reserved@C et
+% \@xs@read@reserved@D
+% - Correction d'un bug dans \StrSplit : \StrSplit{{a}bc}{1}[\truc] faisait
+% que \truc contenait «a{a}».
+% - Correction d'un bug dans \@xs@newmacro : l'argument optionnel \'etait
+% 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