From fef4ece1788f2100ac3474d71832fa39da34a6ce Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 14 Jan 2013 23:32:42 +0000 Subject: xstring (14jan13) git-svn-id: svn://tug.org/texlive/trunk@28833 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/generic/xstring/README | 4 +- .../doc/generic/xstring/xstring_doc_en.pdf | Bin 242308 -> 242372 bytes .../doc/generic/xstring/xstring_doc_en.tex | 2 +- .../doc/generic/xstring/xstring_doc_fr.pdf | Bin 250157 -> 250223 bytes .../doc/generic/xstring/xstring_doc_fr.tex | 4 +- Master/texmf-dist/tex/generic/xstring/xstring.tex | 507 +++++++++++---------- 6 files changed, 265 insertions(+), 252 deletions(-) (limited to 'Master') diff --git a/Master/texmf-dist/doc/generic/xstring/README b/Master/texmf-dist/doc/generic/xstring/README index fbd26a12315..3adc920bf58 100644 --- a/Master/texmf-dist/doc/generic/xstring/README +++ b/Master/texmf-dist/doc/generic/xstring/README @@ -1,8 +1,8 @@ _________________ xstring package - v 1.6 - 2012/10/24 + v 1.7 + 2013/1/13 _________________ This package provides macros manipulating strings for programming use. diff --git a/Master/texmf-dist/doc/generic/xstring/xstring_doc_en.pdf b/Master/texmf-dist/doc/generic/xstring/xstring_doc_en.pdf index 0be656ec48c..a1e8d5d4559 100644 Binary files a/Master/texmf-dist/doc/generic/xstring/xstring_doc_en.pdf and b/Master/texmf-dist/doc/generic/xstring/xstring_doc_en.pdf differ diff --git a/Master/texmf-dist/doc/generic/xstring/xstring_doc_en.tex b/Master/texmf-dist/doc/generic/xstring/xstring_doc_en.tex index e35067df703..73da6555d24 100644 --- a/Master/texmf-dist/doc/generic/xstring/xstring_doc_en.tex +++ b/Master/texmf-dist/doc/generic/xstring/xstring_doc_en.tex @@ -175,7 +175,7 @@ This manual is a translation of the french manual. I apologize for my poor engli \subsection{Description} This extension\footnote{This extension does not require \LaTeX{} and can be compiled with Plain $\varepsilon$-\TeX{}.} provides macros and tests operating on "strings of tokens", as other programmation languages have. They provides the usual strings operations, such as: test if a string contains another, begins or ends with another, extractions of strings, calculation of the position of a substring, of the number of occurrences, etc.\medskip -A "string of tokens" is a list of tokens of any nature, except that braces must be balanced and tokens catcode 6 and 14 (usualy \verb|%| et \verb|#|) are not allowed. Apart from this, any token is allowed, in any order in the list, whatever be the resulting code.\medskip +A "string of tokens" is a list of tokens of any nature, except that braces must be balanced and tokens catcode 6 and 14 (usualy \verb|%| et \verb|#|) are not allowed. Apart from this, any token is allowed (including \verbinline|\par|), in any order in the list, whatever be the resulting code.\medskip \Xstring reads the arguments of the macros \US by \US\footnote{In the \TeX{} code, a \US is a control sequence, a group between brace or a single char. See also page~\pageref{developpementarguments}.} : when \USs are \guill{simple} chars (catcode 10, 11 and 12), \Xstring logically read the argument char by char. \Xstring can also be used for programming purpose, including in arguments other tokens such as control sequences, braces and tokens with other catcodes. See chapter on reading mode and arguments expansion (page~\pageref{developpementarguments}), the command \verbinline|\verbtocs| (page~\pageref{verbtocs}) and the command \verbinline|\scancs| (page~\pageref{scancs}).\medskip diff --git a/Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.pdf b/Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.pdf index c884440c06d..c82b359dd52 100644 Binary files a/Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.pdf and b/Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.pdf differ diff --git a/Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.tex b/Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.tex index ea701726af6..f808db42b29 100644 --- a/Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.tex +++ b/Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.tex @@ -1,6 +1,6 @@ % Ceci est xtring_doc_fr.tex, le manuel en français de xstring % -% Christian Tellechea 2008-2012 +% Christian Tellechea 2008-2013 % % email : unbonpetit@gmail.com %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -172,7 +172,7 @@ \subsection{Description} Cette extension\footnote{L'extension ne nécessite pas \LaTeX{} et peut être compilée sous Plain $\varepsilon$-\TeX{}.} regroupe des macros et des tests opérant sur des chaînes de tokens, un peu comme en disposent des langages dit \guill{évolués}. On y trouve les opérations habituelles sur les chaînes, comme par exemple : test si une chaîne en contient une autre, commence ou finit par une autre, test si une chaîne est un nombre entier ou décimal, extractions de sous-chaînes, calculs de position d'une sous-chaîne, calculs du nombre d'occurrences, etc.\medskip -On appelle \guill{chaîne de tokens} une suite de tokens quelconques, sachant qu'aucune supposition n'a été faite quant à leur nature, mis à part que dans les chaînes de tokens, les accolades doivent être équilibrées et que les tokens de catcode 6 et 14 (habituellement \verb|%| et \verb|#|) n'y sont pas admis. Tous les autres tokens sont \emph{à priori} permis dans n'importe quel ordre, quelque soit le code qu'ils représentent.\medskip +On appelle \guill{chaîne de tokens} une suite de tokens quelconques, sachant qu'aucune supposition n'a été faite quant à leur nature, mis à part que dans les chaînes de tokens, les accolades doivent être équilibrées et que les tokens de catcode 6 et 14 (habituellement \verb|%| et \verb|#|) n'y sont pas admis. Tous les autres tokens, y compris \verbinline|\par|, sont \emph{à priori} permis dans n'importe quel ordre, quelque soit le code qu'ils représentent.\medskip Les arguments contenant des chaînes de tokens sont lus par \Xstring \emph{\US par \US\footnote{Sauf cas particulier, une \US est un caractère lu dans le code à ces exceptions près : une séquence de contrôle est une \US, un groupe entre accolades est aussi une \US. Voir également page~\pageref{developpementarguments}.}}, ce qui revient à les lire caractère par caractère lorsque ceux-ci contiennent des tokens \guill{normaux}, c'est-à-dire dont les catcodes sont 10, 11 et 12. On peut également utiliser \Xstring à des fins de programmation en utilisant des arguments contenant des séquences de contrôle et des tokens dont les catcodes sont moins inoffensifs. Voir le chapitre sur le mode de lecture et de développement des arguments (page~\pageref{developpementarguments}), la commande \verbinline|\verbtocs| (page~\pageref{verbtocs}), la commande \verbinline|\scancs| (page~\pageref{scancs}).\medskip diff --git a/Master/texmf-dist/tex/generic/xstring/xstring.tex b/Master/texmf-dist/tex/generic/xstring/xstring.tex index 986616ce688..c9861c5c7fe 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.6 | +% | xstring v1.7 | % | | -% | October 24 2012 | +% | 13 Janvier 2013 | % | | % |__________________________________________________| % @@ -16,7 +16,7 @@ % xstring_doc_fr.tex, xstring_doc_fr.pdf (manual in french) % xstring_doc_en.tex, xstring_doc_en.pdf (manual in english) % -% Christian Tellechea 2008-2012 +% Christian Tellechea 2008-2013 % email : unbonpetit@gmail.com % ------------------------------------------------------------------- % This work may be distributed and/or modified under the @@ -33,15 +33,15 @@ % % The Current Maintainer of this work is Christian Tellechea % ------------------------------------------------------------------- -\def\xstringversion {1.6} -\def\xstringdate {2012/10/24} -\def\xstringfrenchdate {24 octobre 2012} -\def\xstringenglishdate {October $24^{\mathrm{th}}$ 2012} +\def\xstringversion {1.7} +\def\xstringdate {2013/1/13} +\def\xstringfrenchdate {13 janvier 2013} +\def\xstringenglishdate {$13^{\mathrm{th}}$ january 2013} \edef\CurrentAtCatcode {\the\catcode`\@} \catcode`\@=11 \newwrite\@xs@message% canal pour les messages -\newcount\integerpart\newcount\decimalpart% compteurs utilis\'es par xstring -\newif\if@xs@empty +\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)}% @@ -71,9 +71,13 @@ \def\@empty{} \fi% fin des d\'efinitions LaTeX -\def\@xs@testempty#1{% - \expandafter\ifx\expandafter\@empty\detokenize{#1}\@empty\@xs@emptytrue\else\@xs@emptyfalse\fi} - +\long\def\@xs@ifempty#1{% + \expandafter\ifx\expandafter\relax\detokenize{#1}\relax + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi +} % 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 @@ -86,15 +90,14 @@ % 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\@xs@testempty\expandafter{\@gobble#1}% - \if@xs@empty - \else - \begingroup + \expandafter\@xs@ifempty\expandafter{\@gobble#1}% + \relax + {\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 @@ -106,30 +109,15 @@ \@xs@MakeVerb } -% 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 % ...le caract\`ere 0 a 12 pour catcode - \gdef\tokenize#1#2{% - \begingroup - \@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 \`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 - -%%%% Nouvelle version de \tokenize \begingroup \catcode\z@3 \def\@xs@twochars{^^00}% \catcode\z@7 \xdef\@xs@twochars{\@xs@twochars^^00}% \endgroup -\edef\@xs@reserved@A{\def\noexpand\@xs@AssignResult##1\@xs@twochars} +\edef\@xs@reserved@A{\long\def\noexpand\@xs@AssignResult##1\@xs@twochars} + \@xs@reserved@A#2{\endgroup\expandafter\def\expandafter#2\expandafter{\@gobble#1}} + \def\tokenize#1#2{% \begingroup \@xs@def\@xs@reserved@A{#2}% on d\'eveloppe en accord avec \fullexpandarg ou \noexpandarg @@ -140,40 +128,42 @@ % 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{% +\long\def\@xs@ReturnResult#1#2{% \def\@xs@argument@A{#1}% - \@xs@testempty{#2}% - \if@xs@empty + \@xs@ifempty{#2}% \@xs@argument@A - \else - \let#2\@xs@argument@A - \fi + {\let#2\@xs@argument@A}% } +\def\@xs@ldef{\long\def} + +\def\@xs@ledef{\long\edef} + % Pas d'expansion des arguments \def\normalexpandarg{% - \let\@xs@def\def% on d\'efinit \@xs@call avec \def + \let\@xs@def\@xs@ldef% on d\'efinit \@xs@call avec \def \def\@xs@expand##1{\unexpanded\expandafter{##1}}} \let\noexpandarg\normalexpandarg% synonyme % 1-d\'eveloppement du premier token des arguments \def\expandarg{% - \let\@xs@def\def% on d\'efinit \@xs@call avec \def + \let\@xs@def\@xs@ldef% on d\'efinit \@xs@call avec \def \def\@xs@expand##1{\unexpanded\expandafter\expandafter\expandafter{##1}}% } % D\'eveloppement maximum des arguments \def\fullexpandarg{% - \let\@xs@def\edef% on d\'efinit\@xs@call avec \edef + \let\@xs@def\@xs@ledef% 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} % Macro interne renvoyant #2 si son argument commence par une accolade ouvrante "{" % et #3 sinon (Ulrich Diez sur comp.text.tex) -\def\@xs@ifbeginwithbrace#1{% +\long\def\@xs@ifbeginwithbrace#1{% \csname @% \expandafter\@gobble\string{% \expandafter\@gobble\expandafter{\expandafter{\string#1}% @@ -187,9 +177,9 @@ } % Cette macro interne prend la 1ere unit\'e syntaxique de #1 et assigne le r\'esultat \`a #2 -\def\@xs@returnfirstsyntaxunit#1#2{% +\long\def\@xs@returnfirstsyntaxunit#1#2{% \def\@xs@groupfound{\expandafter\def\expandafter#2\expandafter{\expandafter{#2}}\@xs@gobbleall}% on met #2 dans des accolades et on finit - \def\@xs@assignfirsttok##1##2\@xs@nil{\let\@xs@toks0\def#2{##1}}% + \long\def\@xs@assignfirsttok##1##2\@xs@nil{\let\@xs@toks0\def#2{##1}}% \def\@xs@testfirsttok{% \let\@xs@next\@xs@assignfirsttok \ifx\@xs@toks\bgroup @@ -198,7 +188,6 @@ \@xs@next}% \def\@xs@argument{#1}% \edef\@xs@next{\expandafter\@xs@beforespace\detokenize{#1} \@xs@nil}% #1 commence par un espace ? - %\expandafter\expandafter\expandafter\@xs@testempty\expandafter\expandafter\expandafter{\expandafter\@xs@beforespace\detokenize{#1} \@xs@nil} \ifx\@xs@next\@empty \def\@xs@next{\expandafter\ifx\expandafter\@empty\detokenize\expandafter{\@xs@argument}\@empty\let#2\@empty\else\def#2{ }\let\@xs@toks0\fi}% \else @@ -208,22 +197,23 @@ } % Cette macro interne enl\`eve la 1ere unit\'e syntaxique de #1 et assigne le r\'esultat \`a #2 -\def\@xs@testsecondtoken#1\@xs@nil{\@xs@ifbeginwithbrace{#1}} -\def\@xs@gobblespacebeforebrace#1#{}% supprime tout ce qui est avant la 1ere accolade ouvrante -\def\@xs@removefirstsyntaxunit#1#2{% +\long\def\@xs@testsecondtoken#1\@xs@nil{\@xs@ifbeginwithbrace{#1}} + +\long\def\@xs@gobblespacebeforebrace#1#{}% supprime tout ce qui est avant la 1ere accolade ouvrante + +\long\def\@xs@removefirstsyntaxunit#1#2{% \def\@xs@argument{#1}% \expandafter\expandafter\expandafter\ifx\expandafter\expandafter\expandafter\@empty\expandafter\@xs@beforespace\detokenize\expandafter{\@xs@argument} \@xs@nil\@empty% #1 commence par un espace ? - \expandafter\@xs@testempty\expandafter{\@xs@argument}% - \if@xs@empty - \let#2\@empty - \else + \expandafter\@xs@ifempty\expandafter{\@xs@argument}% + {\let#2\@empty} + { \afterassignment\@xs@testsecondtoken% après avoir mangé le 1er token, on va tester si la suite commence par «{» \expandafter\let\expandafter\@xs@secontoken\expandafter=\expandafter\@sptoken\@xs@argument\@xs@@nil\@xs@nil% on mange le 1er token et on rajoute \@xs@@nil à la fin pour éviter de perdre les accolades du groupe {\expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter#2% \expandafter\expandafter\expandafter{\expandafter\@xs@gobblespacebeforebrace\@xs@argument}}% {\expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter#2% \expandafter\expandafter\expandafter{\expandafter\@xs@behindspace\@xs@argument\@xs@nil}}% - \fi + }% \else \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter#2% \expandafter\expandafter\expandafter{\expandafter\@gobble\@xs@argument}% @@ -231,35 +221,44 @@ } % 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@returnfirstsyntaxunit@ii#1#2\@xs@nil{#1} -\def\@xs@gobbleall#1\@xs@nil{} +\long\def\@xs@beforespace#1 #2\@xs@nil{#1} + +\long\def\@xs@behindspace#1 #2\@xs@nil{#2} + +\long\def\@xs@returnfirstsyntaxunit@ii#1#2\@xs@nil{#1} + +\long\def\@xs@gobbleall#1\@xs@nil{} % 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}% +\long\def\@xs@expand@and@detokenize#1#2{% + \long\def#1{#2}% \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 + \long\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\'eveloppe #2 selon \fullexpandarg ou \normalexpandarg +\long\def\@xs@expand@and@assign#1#2{\@xs@def#1{#2}}% on d\'eveloppe #2 selon \fullexpandarg ou \normalexpandarg + +\long\def\@xs@edefaddtomacro#1#2{\edef#1{\unexpanded\expandafter{#1}#2}} -\def\@xs@edefaddtomacro#1#2{\edef#1{\unexpanded\expandafter{#1}#2}} -\def\@xs@addtomacro#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}} +\long\def\@xs@addtomacro#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}} \def\@xs@argstring{0########1########2########3########4########5########6########7########8########9} + % \@xs@DefArg{3} met dans la sc \@xs@myarg les tokens "####1####2####3" \def\@xs@DefArg#1{\def\@xs@defarg0##1#1##2\@xs@nil{\def\@xs@myarg{##1#1}}\expandafter\@xs@defarg\@xs@argstring\@xs@nil} + % \@xs@DefArg@{3} met dans la sc \@xs@myarg les tokens "[####1]####2####3####4" \def\@xs@DefArg@#1{\expandafter\@xs@defarg@\expandafter{\number\numexpr#1+1}} + \def\@xs@defarg@#1{\def\@xs@defarg0##11##2#1##3\@xs@nil{\def\@xs@myarg{[##11]##2#1}}\expandafter\@xs@defarg\@xs@argstring\@xs@nil} + % \@xs@OneArg{3} met dans la sc \@xs@myarg les tokens "####3" \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} % #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 @@ -270,14 +269,13 @@ \expandafter\@xs@OneArg\expandafter{\number\numexpr##1+#1-1}% \edef\@xs@reserved@B{\noexpand\@xs@expand\csname @xs@arg@\romannumeral\numexpr##1\endcsname}% \ifnum##1=\@ne% si c'est le premier argument - \@xs@testempty{#3}% - \if@xs@empty - \expandafter\@xs@addtomacro\expandafter\@xs@newargs\expandafter{\expandafter{\@xs@reserved@B}}% + \@xs@ifempty{#3}% + {\expandafter\@xs@addtomacro\expandafter\@xs@newargs\expandafter{\expandafter{\@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 - \expandafter\@xs@addtomacro\expandafter\@xs@newargs\expandafter{\expandafter[\@xs@reserved@B]}% + }% et s'il y a un argument optionnel alors, on met des crochets + {\expandafter\@xs@addtomacro\expandafter\@xs@newargs\expandafter{\expandafter[\@xs@reserved@B]}% \def\@xs@reserved@B{@xs@def}% ne pas d\'etok\'eniser l'argument optionnel grace au \@xs@def - \fi + } \else \expandafter\@xs@addtomacro\expandafter\@xs@newargs\expandafter{\expandafter{\@xs@reserved@B}}% \edef\@xs@reserved@B{\ifnum##1>#4 @xs@def\else @xs@assign\fi}% @@ -295,6 +293,7 @@ {\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 % #2 : nom de la macro publique % #3 : argument optionnel (vide si pas d'arg optionnel) @@ -316,14 +315,14 @@ \ifx\@empty#3\@empty \else \def\expandafter\noexpand\@xs@reserved@C{% - \noexpand\@testopt{\expandafter\noexpand\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\@xs@ledef#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@@}} % 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 + \long\@xs@reserved@B \ifx\@empty#3\@empty \@xs@BuildLines1{#4}{#3}{#1}% \@xs@DefArg{#4}% @@ -345,14 +344,14 @@ % 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 + \long\@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 }% % 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 + \long\@xs@reserved@B } % macro g\'en\'erique qui lit \@xs@reserved@C us par us @@ -361,15 +360,14 @@ % \@xs@atbegingroup (un groupe vient d'être ouvert) % \@xs@atnextsyntaxunit (la future US n'est pas un groupe) \def\@xs@read@reserved@C{% - \expandafter\@xs@testempty\expandafter{\@xs@reserved@C}% - \if@xs@empty - \ifnum\@xs@nestlevel=\z@ + \expandafter\@xs@ifempty\expandafter{\@xs@reserved@C}% + {\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@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 @@ -385,7 +383,7 @@ \global\advance\decimalpart\@ne \@xs@atnextsyntaxunit \fi - \fi + }% \@xs@next } @@ -394,15 +392,14 @@ % \@xs@atendofgroup (un groupe se finit, appel r\'ecursif) % \@xs@atoccurfound (une occurrence a \'et\'e trouv\'ee) \def\@xs@read@reserved@D{% - \expandafter\@xs@testempty\expandafter{\@xs@reserved@D}% - \if@xs@empty - \ifnum\@xs@nestlevel=\z@ + \expandafter\@xs@ifempty\expandafter{\@xs@reserved@D}% + {\ifnum\@xs@nestlevel=\z@ \let\@xs@next\relax \else \let\@xs@next\@xs@atendofgroup \fi - \else - \expandafter\expandafter\expandafter\@xs@IfBeginWith@i\expandafter\expandafter\expandafter{\expandafter\@xs@reserved@D\expandafter}\expandafter{\@xs@reserved@E}% + } + {\expandafter\expandafter\expandafter\@xs@IfBeginWith@i\expandafter\expandafter\expandafter{\expandafter\@xs@reserved@D\expandafter}\expandafter{\@xs@reserved@E}% {\global\advance\decimalpart\@ne \let\@xs@reserved@D\@xs@reserved@A \@xs@atoccurfound @@ -423,7 +420,7 @@ \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\@xs@reserved@A}% \fi }% - \fi + }% \@xs@next } @@ -436,17 +433,16 @@ } \def\@xs@StrRemoveBraces@i{% - \expandafter\@xs@testempty\expandafter{\@xs@reserved@C}% - \if@xs@empty - \ifnum\@xs@nestlevel=\z@ + \expandafter\@xs@ifempty\expandafter{\@xs@reserved@C}% + {\ifnum\@xs@nestlevel=\z@ \let\@xs@next\relax \else \expandafter\endgroup \expandafter\@xs@addtomacro\expandafter\@xs@reserved@B\expandafter{\@xs@reserved@B}% \let\@xs@next\@xs@StrRemoveBraces@i \fi - \else - \expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@A + } + {\expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@A \expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@C \let\@xs@next\@xs@StrRemoveBraces@i \ifx\bgroup\@xs@toks @@ -462,7 +458,7 @@ \else \expandafter\@xs@addtomacro\expandafter\@xs@reserved@B\expandafter{\@xs@reserved@A}% \fi - \fi + }% \@xs@next } @@ -471,15 +467,21 @@ % \@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{% +\long\def\@xs@cutafteroccur#1#2#3{% \ifnum#3<\@ne\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi - {\let\@xs@reserved@C\@empty\let\@xs@reserved@E\@empty\let\groupID\@empty} + {\let\@xs@reserved@C\@empty + \let\@xs@reserved@E\@empty + \global\let\groupID\@empty + } {\@xs@cutafteroccur@i{#1}{#2}{#3}}% } -\def\@xs@cutafteroccur@i#1#2#3{% +\long\def\@xs@cutafteroccur@i#1#2#3{% \def\@xs@reserved@D{#1}\let\@xs@reserved@C\@empty\def\@xs@reserved@E{#2}% - \decimalpart\z@\integerpart\z@\def\groupID{0}\let\@xs@nestlevel\z@ + \decimalpart\z@ + \integerpart\z@ + \gdef\groupID{0}% + \let\@xs@nestlevel\z@ \def\@xs@atendofgroup{% \expandafter\endgroup \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\expandafter{\@xs@reserved@C}}% @@ -488,7 +490,6 @@ \ifnum\decimalpart=\numexpr(#3)\relax \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 @@ -501,7 +502,9 @@ \let\@xs@reserved@E\@xs@reserved@D \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\@xs@reserved@D\expandafter\expandafter\expandafter{\expandafter\@xs@reserved@C\@xs@argument@A}% \else - \let\@xs@reserved@C\@empty\let\@xs@reserved@E\@empty\let\groupID\@empty + \let\@xs@reserved@C\@empty + \let\@xs@reserved@E\@empty + \global\let\groupID\@empty \fi } @@ -509,37 +512,33 @@ \def\@xs@argument@A{#2}\def\@xs@argument@B{#3}% \expandafter\expandafter\expandafter\@xs@cutafteroccur \expandafter\expandafter\expandafter{\expandafter\@xs@argument@A\expandafter}\expandafter{\@xs@argument@B}{#1}% - \expandafter\@xs@testempty\expandafter{\@xs@reserved@D}% - \if@xs@empty - \expandafter\@secondoftwo - \else - \expandafter\@firstoftwo - \fi + \expandafter\@xs@ifempty\expandafter{\@xs@reserved@D}% + \@secondoftwo + \@firstoftwo } \@xs@newmacro*2\IfBeginWith{}{2}{0}{% \def\@xs@argument@A{#1}\def\@xs@argument@B{#2}% - \expandafter\@xs@testempty\expandafter{\@xs@argument@B}% - \if@xs@empty - \let\@xs@next\@secondoftwo - \else - \def\@xs@next{\expandafter\expandafter\expandafter\@xs@IfBeginWith@i - \expandafter\expandafter\expandafter{\expandafter\@xs@argument@A\expandafter}\expandafter{\@xs@argument@B}}% - \fi + \expandafter\@xs@ifempty\expandafter{\@xs@argument@B}% + {\let\@xs@next\@secondoftwo + } + {\def\@xs@next{% + \expandafter\expandafter\expandafter\@xs@IfBeginWith@i\expandafter\expandafter\expandafter + {\expandafter\@xs@argument@A\expandafter}\expandafter + {\@xs@argument@B}}% + }% \@xs@next } -\def\@xs@IfBeginWith@i#1#2{% +\long\def\@xs@IfBeginWith@i#1#2{% \def\@xs@argument@A{#1}\def\@xs@argument@B{#2}% - \expandafter\@xs@testempty\expandafter{\@xs@argument@B}% - \if@xs@empty% #2 est vide, tous les tests sont pass\'es avec succ\`es : on renvoie #3 - \let\@xs@next\@firstoftwo - \else - \expandafter\@xs@testempty\expandafter{\@xs@argument@A}%\@xs@testempty{#1}% - \if@xs@empty - \let\@xs@next\@secondoftwo% #1 est vide, c'est que #2 est + long que #1 : on renvoie #4 - \else - \expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@argument@B}\@xs@reserved@B + \expandafter\@xs@ifempty\expandafter{\@xs@argument@B}% + {\let\@xs@next\@firstoftwo% #2 est vide, tous les tests sont pass\'es avec succ\`es : on renvoie #3 + } + {\expandafter\@xs@ifempty\expandafter{\@xs@argument@A}% + {\let\@xs@next\@secondoftwo% #1 est vide, c'est que #2 est + long que #1 : on renvoie #4 + } + {\expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@argument@B}\@xs@reserved@B \expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@argument@A}\@xs@reserved@A \ifx\@xs@reserved@A\@xs@reserved@B% il y a \'egalit\'e... \expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@argument@B}\@xs@reserved@B @@ -550,35 +549,32 @@ \else \let\@xs@next\@secondoftwo \fi - \fi - \fi + }% + }% \@xs@next } \@xs@newmacro*2\IfEndWith{}{2}{0}{% \def\@xs@argument@A{#1}\def\@xs@argument@B{#2}% - \@xs@testempty{#2}% - \if@xs@empty - \let\@xs@reserved@A\@secondoftwo - \else - \expandafter\expandafter\expandafter\@xs@StrCount + \@xs@ifempty{#2}% + {\let\@xs@reserved@A\@secondoftwo + } + {\expandafter\expandafter\expandafter\@xs@StrCount \expandafter\expandafter\expandafter{\expandafter\@xs@argument@A\expandafter}\expandafter {\@xs@argument@B}[\@xs@reserved@A]% \ifnum\@xs@reserved@A=\z@ \let\@xs@reserved@A\@secondoftwo \else - \expandafter\@xs@testempty\expandafter{\@xs@reserved@C}% - \if@xs@empty - \let\@xs@reserved@A\@firstoftwo - \else - \let\@xs@reserved@A\@secondoftwo - \fi + \expandafter\@xs@ifempty\expandafter{\@xs@reserved@C}% + {\let\@xs@reserved@A\@firstoftwo} + {\let\@xs@reserved@A\@secondoftwo}% \fi - \fi + }% \@xs@reserved@A } \@xs@newmacro*4\IfSubStrBefore{1,1}{3}{0}{\@xs@IfSubStrBefore@i[#1]{#2}{#3}{#4}} + \def\@xs@IfSubStrBefore@i[#1,#2]#3#4#5{% \def\@xs@reserved@C{#3}% \ifx\@xs@exploregroups\relax% si on explore les groupes @@ -591,49 +587,40 @@ \expandafter\expandafter\expandafter\@xs@cutafteroccur\expandafter\expandafter\expandafter{\expandafter\@xs@reserved@C\expandafter}\expandafter{\@xs@reserved@A}{#2}% \def\@xs@reserved@A{#4}% \expandafter\expandafter\expandafter\@xs@cutafteroccur\expandafter\expandafter\expandafter{\expandafter\@xs@reserved@C\expandafter}\expandafter{\@xs@reserved@A}{#1}% - \let\groupID\@empty - \expandafter\@xs@testempty\expandafter{\@xs@reserved@C}% - \if@xs@empty - \expandafter\@secondoftwo - \else - \expandafter\@firstoftwo - \fi + \global\let\groupID\@empty + \expandafter\@xs@ifempty\expandafter{\@xs@reserved@C}% + \@secondoftwo + \@firstoftwo } \@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{% +\long\def\@xs@IfSubStrBehind@i[#1,#2]#3#4#5{\@xs@IfSubStrBefore@i[#2,#1]{#3}{#5}{#4}} + +\long\def\@xs@formatnumber#1#2{% \def\@xs@argument@A{#1}% - \@xs@testempty{#1}% - \if@xs@empty - \def#2{0X}% si vide, renvoie 0X - \else - \@xs@returnfirstsyntaxunit{#1}\@xs@reserved@A + \@xs@ifempty{#1}% + {\def#2{0X}% si vide, renvoie 0X + } + {\@xs@returnfirstsyntaxunit{#1}\@xs@reserved@A \def\@xs@reserved@B{+}% \ifx\@xs@reserved@A\@xs@reserved@B \expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@argument@A}\@xs@reserved@C - \expandafter\@xs@testempty\expandafter{\@xs@reserved@C}% - \if@xs@empty - \def#2{+0X}% - \else - \expandafter\def\expandafter#2\expandafter{\expandafter+\expandafter0\@xs@reserved@C}% - \fi + \expandafter\@xs@ifempty\expandafter{\@xs@reserved@C}% + {\def#2{+0X}} + {\expandafter\def\expandafter#2\expandafter{\expandafter+\expandafter0\@xs@reserved@C}}% \else \def\@xs@reserved@B{-}% \ifx\@xs@reserved@A\@xs@reserved@B \expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@argument@A}\@xs@reserved@A - \expandafter\@xs@testempty\expandafter{\@xs@reserved@A}% - \if@xs@empty - \def#2{-0X}% - \else - \expandafter\def\expandafter#2\expandafter{\expandafter-\expandafter0\@xs@reserved@A}% - \fi + \expandafter\@xs@ifempty\expandafter{\@xs@reserved@A}% + {\def#2{-0X}}% + {\expandafter\def\expandafter#2\expandafter{\expandafter-\expandafter0\@xs@reserved@A}}% \else \expandafter\def\expandafter#2\expandafter{\expandafter0\@xs@argument@A}% \fi \fi - \fi + }% } \@xs@newmacro\IfInteger{}{1}{0}{% @@ -668,19 +655,22 @@ \fi } -\def\@xs@defafterinteger#1\relax\@xs@nil{\def\@xs@afterinteger{#1}} +\long\def\@xs@defafterinteger#1\relax\@xs@nil{\def\@xs@afterinteger{#1}} + \def\@xs@testdot{% \let\xs@decsep\@empty \@ifnextchar.% {\def\xs@decsep{.}\@xs@readdecimalpart}% {\@xs@testcomma}% } + \def\@xs@testcomma{% \@ifnextchar,% {\def\xs@dessep{,}\@xs@readdecimalpart}% {\@xs@endnumber}% } -\def\@xs@readdecimalpart#1#2\@xs@nil{% + +\long\def\@xs@readdecimalpart#1#2\@xs@nil{% \ifx\@empty#2\@empty \def\@xs@reserved@A{0X}% \else @@ -689,11 +679,12 @@ \afterassignment\@xs@defafterinteger\decimalpart\@xs@reserved@A\relax\@xs@nil \expandafter\@xs@endnumber\@xs@afterinteger\@xs@nil } -\def\@xs@endnumber#1\@xs@nil{\def\@xs@afterdecimal{#1}} + +\long\def\@xs@endnumber#1\@xs@nil{\def\@xs@afterdecimal{#1}} % 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\'ecimaux et s'ils sont \'egaux, faux sinon +\long\def\@xs@IfStrEqFalse@i#1#2{\let\@xs@reserved@A\@secondoftwo} +\long\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 @@ -707,7 +698,7 @@ {\let\@xs@reserved@A\@secondoftwo}% #1 n'est pas d\'ecimal } -\def\@xs@TestEqual#1#2{% teste si les 2 arguments sont \'egaux +\long\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% \'egalit\'e parfaite des 2 chaines @@ -732,6 +723,7 @@ {\def\@xs@reserved@E{\IfStrEq*}\@xs@IfStrCase}% {\def\@xs@reserved@E{\IfStrEq}\@xs@IfStrCase}% } + \def\@xs@IfStrCase#1#2{\@testopt{\@xs@IfStringCase{#1}{#2}}{}} \def\IfEqCase{% @@ -739,19 +731,16 @@ {\def\@xs@reserved@E{\IfEq*}\@xs@IfEqCase}% {\def\@xs@reserved@E{\IfEq}\@xs@IfEqCase}% } -\def\@xs@IfEqCase#1#2{\@testopt{\@xs@IfStringCase{#1}{#2}}{}} -\def\@xs@IfStringCase#1#2[#3]{% +\long\def\@xs@IfEqCase#1#2{\@testopt{\@xs@IfStringCase{#1}{#2}}{}} + +\long\def\@xs@IfStringCase#1#2[#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\'ecute le code correspondant - {\@xs@testempty{##3}% - \if@xs@empty% le test est n\'egatif - \def\@xs@next{#3}% s'il n'y a plus de cas, on ex\'ecute le code - \else - \def\@xs@next{\@xs@testcase##3\@xs@nil}% sinon, on recommence avec ce qui reste - \fi - \@xs@next + {\@xs@ifempty{##3}% + {#3}% s'il n'y a plus de cas, on ex\'ecute le code + {\@xs@testcase##3\@xs@nil}% sinon, on recommence avec ce qui reste }% }% \@xs@testcase#2\@xs@nil @@ -772,7 +761,8 @@ % 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*4\StrBetween{1,1}{3}{1}{\@xs@StrBetween@i[#1]{#2}{#3}{#4}[#5]} -\def\@xs@StrBetween@i[#1,#2]#3#4#5[#6]{% + +\long\def\@xs@StrBetween@i[#1,#2]#3#4#5[#6]{% \begingroup \noexploregroups \@xs@cutafteroccur{#3}{#5}{#2}% @@ -780,12 +770,15 @@ \expandafter \endgroup \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@E}{#6}% - \let\groupID\@empty + \global\let\groupID\@empty } \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\`eres occurences de la chaine #3 @@ -793,7 +786,10 @@ \@xs@newmacro\StrSubstitute{0}{3}{1}{% \def\@xs@reserved@D{#2}\let\@xs@reserved@C\@empty\def\@xs@reserved@E{#3}% \def\@xs@argument@C{#3}\def\@xs@argument@D{#4}% - \decimalpart\z@\integerpart\z@\def\groupID{0}\let\@xs@nestlevel\z@ + \decimalpart\z@ + \integerpart\z@ + \gdef\groupID{0}% + \let\@xs@nestlevel\z@ \def\@xs@atendofgroup{% \expandafter\endgroup \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\expandafter{\@xs@reserved@C}}% @@ -812,13 +808,12 @@ \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\@xs@reserved@A}% \@xs@read@reserved@D }% - \@xs@testempty{#3}% - \if@xs@empty - \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@D}{#5}% - \else - \@xs@read@reserved@D + \@xs@ifempty{#3}% + {\expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@D}{#5}% + } + {\@xs@read@reserved@D \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#5}% - \fi + }% } % Supprime les #1 premi\`eres occurrences de #3 dans #2 @@ -831,7 +826,7 @@ \def\@xs@reserved@C{#1}% \decimalpart\z@ \let\@xs@nestlevel\z@ - \def\groupID{0}% + \gdef\groupID{0}% \let\@xs@atbegingroup\relax \def\@xs@atendofgroup{\endgroup\@xs@read@reserved@C}% \let\@xs@atnextsyntaxunit\relax @@ -841,21 +836,22 @@ % Macro interne fermant autant de groupes que n\'ecessaire pour trouver une unit\'e syntaxique derri\`ere \def\@xs@continuetonext{% - \expandafter\@xs@testempty\expandafter{\@xs@reserved@C}% - \if@xs@empty - \ifnum\@xs@nestlevel>\z@ + \expandafter\@xs@ifempty\expandafter{\@xs@reserved@C}% + {\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 + \fi} + \relax }% \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 + \endgroup + \xdef\groupID{\number\integerpart}% on met simplement le niveau \else - \endgroup\expandafter\@xs@addtomacro\expandafter\groupID\expandafter{\expandafter,\number\integerpart}% + \endgroup + \expandafter\expandafter\expandafter\gdef\expandafter\expandafter\expandafter\groupID\expandafter\expandafter\expandafter{\expandafter\groupID\expandafter,\number\integerpart}% \fi } @@ -865,13 +861,21 @@ {\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 +\long\def\@xs@StrSplit@i#1#2{% + \def\@xs@reserved@D{#1}% + \def\@xs@reserved@C{#2}% + \let\@xs@reserved@B\@empty + \global\let\groupID\@empty \ifnum#1>\z@ - \decimalpart\z@\integerpart\z@\def\groupID{0}\let\@xs@nestlevel\z@ + \decimalpart\z@ + \integerpart\z@ + \gdef\groupID{0}% + \let\@xs@nestlevel\z@ \def\@xs@atendofgroup{% \expandafter\endgroup \expandafter\@xs@addtomacro\expandafter\@xs@reserved@B\expandafter{\expandafter{\@xs@reserved@B}}% @@ -884,7 +888,6 @@ \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 @@ -892,15 +895,15 @@ \@xs@read@reserved@C \fi } + \def\@xs@StrSplit@ii#1#2{\let#1\@xs@reserved@B\let#2\@xs@reserved@C} % StrCut[n]{}{}\macroA\macroB % \macroA reçoit ce qui se trouve avant la n ème occurrence dans % \macroB reçoit ce qui est après cette n ème occurrence \@xs@newmacro*3\StrCut{1}{2}{0}{% - \@xs@testempty{#3}% - \if@xs@empty\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi - {\let\groupID\@empty + \@xs@ifempty{#3}% + {\global\let\groupID\@empty \let\@xs@reserved@C\@empty \let\@xs@reserved@E\@empty } @@ -911,12 +914,12 @@ \@xs@StrCut@iii } -\def\@xs@StrCut@ii#1#2#3{% +\long\def\@xs@StrCut@ii#1#2#3{% \def\@xs@reserved@D{#1}% \let\@xs@reserved@C\@empty \def\@xs@reserved@E{#2}% \decimalpart\z@\integerpart\z@ - \def\groupID{0}% + \gdef\groupID{0}% \let\@xs@nestlevel\z@ \def\@xs@atendofgroup{% \expandafter\endgroup @@ -927,7 +930,6 @@ \ifnum\decimalpart=\numexpr(#3)\relax \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 @@ -946,7 +948,7 @@ {\expandafter\@xs@reserved@C\@xs@argument@A}% } -\def\@xs@StrCut@iii#1#2{\let#1\@xs@reserved@C\let#2\@xs@reserved@E} +\long\def\@xs@StrCut@iii#1#2{\let#1\@xs@reserved@C\let#2\@xs@reserved@E} % De la chaine #1, renvoie ce qui se trouve entre les positions % #2 et #3, unit\'es syntaxiques aux positions compris ! @@ -960,7 +962,7 @@ \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}% - \let\groupID\@empty + \global\let\groupID\@empty } % supprime #2 unit\'es syntaxiques \`a gauche dans la chaine #1 @@ -1003,26 +1005,27 @@ \def\@xs@atnextsyntaxunit{% \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 \let\@xs@next\relax \fi }% \@xs@read@reserved@C \fi - \expandafter\@xs@testempty\expandafter{\@xs@reserved@B}% - \if@xs@empty\let\groupID\@empty\fi + \expandafter\@xs@ifempty\expandafter{\@xs@reserved@B}% + {\global\let\groupID\@empty} + \relax \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@B}{#3}% } % Combien de fois compte t-on #2 dans #1 ? \@xs@newmacro\StrCount{}{2}{1}{% - \@xs@testempty{#2}% \def\@xs@reserved@D{#1}\def\@xs@reserved@E{#2}\let\@xs@reserved@C\@empty - \if@xs@empty - \@xs@ReturnResult{0}{#3}% - \else - \decimalpart\z@\integerpart\z@\def\groupID{0}\let\@xs@nestlevel\z@ + \@xs@ifempty{#2}% + {\@xs@ReturnResult{0}{#3}} + {\decimalpart\z@ + \integerpart\z@ + \gdef\groupID{0}% + \let\@xs@nestlevel\z@ \def\@xs@atendofgroup{% \expandafter\endgroup \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\expandafter{\@xs@reserved@C}}% @@ -1031,7 +1034,7 @@ \def\@xs@atoccurfound{\let\@xs@reserved@C\@empty\@xs@read@reserved@D}% \@xs@read@reserved@D \expandafter\@xs@ReturnResult\expandafter{\number\decimalpart}{#3}% - \fi + }% } % renvoie la position de l'occurrence #1 de la sous chaine #3 dans la chaine #2 @@ -1045,13 +1048,17 @@ \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 + \global\let\groupID\@xs@reserved@E } \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 \'egaux et renvoie la % position de la premiere unit\'e syntaxiques diff\'erente sinon @@ -1066,18 +1073,15 @@ \fi } -\def\@xs@StrCompare@i#1#2#3{% +\long\def\@xs@StrCompare@i#1#2#3{% \def\@xs@StrCompare@iii##1{% \let\@xs@reserved@A\@empty - \expandafter\@xs@testempty\expandafter{\@xs@reserved@C}% - \if@xs@empty - \def\@xs@reserved@A{*\@xs@comparecoeff}% - \else - \expandafter\@xs@testempty\expandafter{\@xs@reserved@D}% - \if@xs@empty - \def\@xs@reserved@A{*\@xs@comparecoeff}% - \fi - \fi + \expandafter\@xs@ifempty\expandafter{\@xs@reserved@C}% + {\def\@xs@reserved@A{*\@xs@comparecoeff}}% + {\expandafter\@xs@ifempty\expandafter{\@xs@reserved@D}% + {\def\@xs@reserved@A{*\@xs@comparecoeff}} + \relax + }% \def\@xs@next{% \expandafter\@xs@ReturnResult\expandafter {\number\numexpr##1\@xs@reserved@A\relax}{#3}% @@ -1087,14 +1091,13 @@ \expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@A \expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@D}\@xs@reserved@B \ifx\@xs@reserved@B\@xs@reserved@A - \expandafter\@xs@testempty\expandafter{\@xs@reserved@A}% - \if@xs@empty - \@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\'es syntaxiques sont \'egales et non vides, on recommence + \expandafter\@xs@ifempty\expandafter{\@xs@reserved@A}% + {\@xs@StrCompare@iii{##1}% les 2 unit\'es syntaxiques sont \'egales, on renvoie la position + } + {\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 unit\'es syntaxiques sont diff\'erentes : on renvoie la position \@xs@StrCompare@iii{##1}% \fi @@ -1114,13 +1117,12 @@ \@xs@next } -\def\@xs@StrFindGroup@i#1#2[#3]{% +\long\def\@xs@StrFindGroup@i#1#2[#3]{% \def\@xs@StrFindGroup@ii{% - \expandafter\@xs@testempty\expandafter{\@xs@reserved@C}% - \if@xs@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 + \expandafter\@xs@ifempty\expandafter{\@xs@reserved@C}% + {\def\@xs@next{\@xs@ReturnResult{}{#3}}% s'il ne reste plus rien, on renvoie vide + } + {\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\decimalpart\@ne% on augmente le compteur \ifnum\decimalpart=\@xs@reserved@A% on est au groupe cherch\'e lors de la profondeur courante ? @@ -1138,7 +1140,7 @@ \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 @@ -1154,14 +1156,18 @@ } \def\expandingroups{\let\@xs@expandingroups\exploregroups} + \def\noexpandingroups{\let\@xs@expandingroups\noexploregroups} + \def\StrExpand{\@testopt{\@xs@StrExpand}{1}} -\def\@xs@StrExpand[#1]#2#3{% +\long\def\@xs@StrExpand[#1]#2#3{% \begingroup \@xs@expandingroups \ifnum#1>\z@ \integerpart#1\relax - \decimalpart\z@\def\groupID{0}\let\@xs@nestlevel\z@ + \decimalpart\z@ + \gdef\groupID{0}% + \let\@xs@nestlevel\z@ \def\@xs@atendofgroup{% \expandafter\endgroup \expandafter\@xs@addtomacro\expandafter\@xs@reserved@B\expandafter{\expandafter{\@xs@reserved@B}}% @@ -1181,10 +1187,10 @@ \global\let\@xs@reserved@B\@xs@reserved@B \endgroup \let#3\@xs@reserved@B - \let\groupID\@empty + \global\let\groupID\@empty } -\def\@xs@StrExpand@i#1{% +\long\def\@xs@StrExpand@i#1{% \ifnum#1>\z@ \let\@xs@reserved@B\@empty \@xs@read@reserved@C @@ -1197,13 +1203,14 @@ } \def\scancs{\@testopt{\@xs@scancs}{1}} -\def\@xs@scancs[#1]#2#3{% +\long\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 % d\'efinit les diff\'erents modes et les m\'emorise \setverbdelim{|}% @@ -1211,6 +1218,7 @@ \comparenormal\savecomparemode \noexploregroups\saveexploremode \expandingroups + \endinput % % Historique @@ -1364,4 +1372,9 @@ % \'etait entre accolades % - Nouvelle macro \StrCut % - \@xs@cutafteroccur@i ne produit plus d'espace indésirable si #3 était -% évalué par \numexpr \ No newline at end of file +% évalué par \numexpr +%------------------------------------------------------------------------------ +% v1.7 13/1/2013 +% - Correction d'un manque de rigueur dans les assignations concernant +% \groupID : elles sont toutes globales d\'esormais +% - Les macros de xstring sont \long \ No newline at end of file -- cgit v1.2.3