summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/xstring
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2008-09-22 17:54:46 +0000
committerKarl Berry <karl@freefriends.org>2008-09-22 17:54:46 +0000
commit9da98529e177e6454863e2131dfdb16dc2c37e85 (patch)
tree6479c5cb3add13504bec3fb1a3ab0827addad819 /Master/texmf-dist/tex/latex/xstring
parent570886302e347e0b86dc0f5e8190aad8761c1595 (diff)
xstring 1.3 (21sep08)
git-svn-id: svn://tug.org/texlive/trunk@10688 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/xstring')
-rw-r--r--Master/texmf-dist/tex/latex/xstring/xstring.sty2
-rw-r--r--Master/texmf-dist/tex/latex/xstring/xstring.tex352
2 files changed, 224 insertions, 130 deletions
diff --git a/Master/texmf-dist/tex/latex/xstring/xstring.sty b/Master/texmf-dist/tex/latex/xstring/xstring.sty
index 62acadb45df..9dc5a187f7c 100644
--- a/Master/texmf-dist/tex/latex/xstring/xstring.sty
+++ b/Master/texmf-dist/tex/latex/xstring/xstring.sty
@@ -1,3 +1,3 @@
-\ProvidesPackage{xstring}
\input xstring.tex
+\ProvidesPackage{xstring}[\xstringdate\space\space v\xstringversion\space\space String manipulations (C Tellechea)]
\endinput \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/xstring/xstring.tex b/Master/texmf-dist/tex/latex/xstring/xstring.tex
index cfad44ca2fc..27ab19f1b6c 100644
--- a/Master/texmf-dist/tex/latex/xstring/xstring.tex
+++ b/Master/texmf-dist/tex/latex/xstring/xstring.tex
@@ -1,9 +1,9 @@
% __________________________________________________
% | |
% | |
-% | xstring v1.2 |
+% | xstring v1.3 |
% | |
-% | August 23 2008 |
+% | September 21 2008 |
% | |
% |__________________________________________________|
%
@@ -35,19 +35,18 @@
% test_latex.tex, test_latex.pdf (test file with LaTeX)
% test_etex.tex, test_etex.pdf (test file with Plain eTeX)
%
-\def\xstringversion {1.2}
-\def\xstringdate {2008/08/23}
-\def\xstringfrenchdate {23 ao\^ut 2008}
-\def\xstringenglishdate{August $23^{\mathrm{th}}$ 2008}
+\def\xstringversion {1.3}
+\def\xstringdate {2008/09/21}
+\def\xstringfrenchdate {21 septembre 2008}
+\def\xstringenglishdate{September $21^{\mathrm{st}}$ 2008}
\edef\CurrentAtCatcode{\the\catcode`\@}
\catcode`\@=11
\newwrite\@xs@unused% pour les messages
\newcount\integerpart% pour les tests sur les nombres
\newcount\decimalpart
-\immediate\write\@xs@unused{Package: xstring v\xstringversion\space<\xstringdate>\space Extended macros for strings (C Tellechea).}%
-
\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)}%
\long\def\@firstoftwo#1#2{#1}
\long\def\@secondoftwo#1#2{#2}
\long\def\@ifnextchar#1#2#3{%
@@ -129,12 +128,16 @@
\@xs@MakeVerb}
% A l'aide d'un pont d'\expandafter, développe d'un niveau toutes
-% les sc de #1 puis et assigne le résultat à \@xs@result@expandallonelevel
+% les lexèmes de #1 puis et assigne le résultat à \@xs@result@expandallonelevel
\def\@xs@expandallonelevel#1#2\@nil{%
\expandafter\expandafter\expandafter\def% plein d'expandafter
\expandafter\expandafter\expandafter\@xs@result@expandallonelevel% pour développer #1 d'un niveau
\expandafter\expandafter\expandafter{\expandafter\@xs@result@expandallonelevel#1}% et l'ajouter à \@xs@result@expandallonelevel
- \ifx\@empty#2\@empty\else\@xs@expandallonelevel#2\@nil\fi}% s'il reste des sc, on boucle
+ \ifx\@empty#2\@empty
+ \else
+ \def\@xs@next{\@xs@expandallonelevel#2\@nil}%
+ \expandafter\@xs@next
+ \fi}% s'il reste des sc, on boucle
\def\@xs@notestcs#1\@nil{\relax}%
\def\@xs@testcs#1#2\@nil{%
@@ -159,16 +162,17 @@
% #1 : profondeur à développer 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\@nil##2\@nil{% développe de #1 niveaux toutes les sc de #3 et l'assigne à \@xs@result@scancs
+ \def\@xs@expandalltodepth##1\@nil{% développe de #1 niveaux toutes les sc de #3 et l'assigne à \@xs@result@scancs
\def\@xs@result@expandallonelevel{}%
- \ifnum\numexpr##2<#1% tant que la profondeur de développement n'est pas atteinte
- \@xs@testornot##1\@nil% on teste éventuellement si le développement comporte 1 seule sc
+ \ifnum##1<#1\relax% tant que la profondeur de développement n'est pas atteinte
+ \expandafter\@xs@testornot\@xs@result@scancs\@nil% on teste éventuellement si le développement comporte 1 seule sc
\expandafter\@xs@expandallonelevel\@xs@result@scancs\@nil% on développe tout d'un niveau
\expandafter\def\expandafter\@xs@result@scancs\expandafter{\@xs@result@expandallonelevel}%
- \expandafter\@xs@expandalltodepth\@xs@result@scancs\@nil##2+1\@nil% et on recommence
+ \def\@xs@next{\expandafter\@xs@expandalltodepth\number\numexpr##1+1\relax\@nil}%
+ \expandafter\@xs@next% et on recommence
\fi}%
\def\@xs@result@scancs{#3}%
- \@xs@expandalltodepth#3\@nil0\@nil
+ \@xs@expandalltodepth0\@nil
\expandafter\def\expandafter#2\expandafter{\detokenize\expandafter{\@xs@result@scancs}}}
% Cette macro développe #2 au maximum (ce qui doit donner du texte),
@@ -241,9 +245,12 @@
\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}
+% \@xs@DefArg{3} met dans la sc \@xs@myarg le texte "####1####2####3"
\def\@xs@DefArg#1{\def\@xs@defarg0##1#1##2\@nil{\def\@xs@myarg{##1#1}}\expandafter\@xs@defarg\@xs@argstring\@nil}
+% \@xs@DefArg@{3} met dans la sc \@xs@myarg le texte "[####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\@nil{\def\@xs@myarg{[##11]##2#1}}\expandafter\@xs@defarg\@xs@argstring\@nil}
+% \@xs@OneArg{3} met dans la sc \@xs@myarg le texte "####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\@nil{\def\@xs@myarg{##2#2}}\expandafter\@xs@defarg\@xs@argstring\@nil}
@@ -254,7 +261,10 @@
\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}}%
\@xs@expand@and@addtomacro\@xs@newargs{{\noexpand\@xs@expand\expandafter\noexpand\csname @xs@arg@\romannumeral\numexpr##1\endcsname}}%
- \ifnum\numexpr##1<#2\@xs@buildlines##1+1\@nil\fi}
+ \ifnum##1<#2
+ \def\@xs@next{\expandafter\@xs@buildlines\number\numexpr##1+1\relax\@nil}%
+ \expandafter\@xs@next
+ \fi}
\@xs@buildlines1\@nil}
\def\@xs@newmacro#1#2#3#4#5{%
@@ -263,10 +273,6 @@
% #3 : nombre d'arguments obligatoires
% #4 : utilisation de testopt (1 si oui, 0 si non)
% #5 : code de la macro
-% Cette macro construit les macros privées suivantes :
-% 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]}}
\edef\@xs@macronameroot{@xs@\expandafter\@xs@gobblefirstchar\string#1\@nil}%
\edef\@macro@name{\expandafter\noexpand\csname\@xs@macronameroot @\ifx\@empty#2\@empty @\fi\endcsname}%
\edef\@xs@temp@{%
@@ -279,6 +285,10 @@
{\expandafter\noexpand\csname\@xs@macronameroot @@\endcsname}%
{\expandafter\noexpand\csname\@xs@macronameroot @@\endcsname[#2]}}%
\fi}%
+% Que fait \@xs@temp@ ? 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]}}
\@xs@temp@
\ifx\@empty#2\@empty
\@xs@BuildLines{1}{#3}%
@@ -293,8 +303,18 @@
\ifnum#4=\@ne\edef\@xs@temp@@@{\noexpand\noexpand\noexpand\@testopt{\unexpanded\expandafter{\@xs@temp@@@}}\unexpanded{{}}}\fi
\@xs@expand@and@addtomacro\@xs@temp@@{{\unexpanded\expandafter{\@xs@temp@@@}}\noexpand\@xs@call}%
\@xs@expand@and@addtomacro\@xs@temp@{{\unexpanded\expandafter{\@xs@temp@@}}}%
+% Que fait \@xs@temp@ ? Il définit par exemple pour 3 arguments obligatoires et 1 facultatif :
+% \def\@xs@NOM@@[##1]##2##3##4{%
+% \@xs@assign{\@xs@arg@i}{##2}%
+% \@xs@assign{\@xs@arg@ii}{##3}%
+% \@xs@assign{\@xs@arg@iii}{##4}%
+% si #4=0: \edef\@xs@call{\noexpand\@xs@NOM[\@xs@expand{##1}]{\@xs@expand\@xs@arg@i}{\@xs@expand\@xs@arg@ii}{\@xs@expand\@xs@arg@iii}}%
+% si #4=1: \edef\@xs@call{\noexpand\@testopt{\noexpand\@xs@NOM[\@xs@expand{##1}]{\@xs@expand\@xs@arg@i}{\@xs@expand\@xs@arg@ii}{\@xs@expand\@xs@arg@iii}}{}}%
+% \@xs@call}
\@xs@temp@
\edef\@xs@temp@{\def\expandafter\noexpand\csname\@xs@macronameroot\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@temp@ ? Il définit par exemple pour 3 arguments obligatoires et 1 facultatif :
+% \def \@xs@NOM[##1]##2##3##4[##5]{#5}
\@xs@temp@}
% Cette macro teste si une chaine (#2) en contient au moins (#1) fois une autre (#3)
@@ -303,7 +323,7 @@
% si elle existe,et contiennent des chaines vides sinon.
\def\@xs@strip@delimit#1\@delimit#2\@nil{#1}
\def\@xs@IfSubStr@case@false{%
- \def\@xs@result@IfSubStr{\expandafter\@secondoftwo}% on exécute #5
+ \let\@xs@result@If\@secondoftwo% on exécute #5
\def\@xs@behind@IfSubStr{}%
\def\@xs@before@IfSubStr{}}
\@xs@newmacro\IfSubStr{1}{2}{0}{%
@@ -317,56 +337,58 @@
\@xs@IfSubStr@case@false
\else
\def\@xs@before@IfSubStr{}%
- \def\@xs@IfSubStr@i##1#3##2\@nil##3\@nil{%
- \ifx\@empty##2\@empty% rien après la sous chaine ?
+ \def\@xs@IfSubStr@i##1\@nil##2#3##3\@nil{% ##1 est le compteur
+ \def\@xs@next{\relax}%
+ \ifx\@empty##3\@empty% rien après la sous chaine ?
\@xs@IfSubStr@case@false
\else% si ce qu'il est reste n'est pas vide
- \ifnum\numexpr##3<#1% tant que le nombre d'occurrence n'est pas atteint
- \edef\@xs@before@IfSubStr{\@xs@before@IfSubStr##1#3}%
- \@xs@IfSubStr@i##2\@nil##3+1\@nil% on recommence
+ \ifnum##1<#1% tant que le nombre d'occurrence n'est pas atteint
+ \edef\@xs@before@IfSubStr{\@xs@before@IfSubStr##2#3}% on ajoute la chaine restante à \@xs@before@IfSubStr
+ \def\@xs@next{\expandafter\@xs@IfSubStr@i\number\numexpr##1+1\relax\@nil##3\@nil}% on recommence après être sorti de \if...\fi
\else
- \def\@xs@result@IfSubStr{\expandafter\@firstoftwo}% nombre d'occurrences atteint : on renvoie #4
- \edef\@xs@before@IfSubStr{\@xs@before@IfSubStr##1}%
- \edef\@xs@behind@IfSubStr{\@xs@strip@delimit##2\@nil}%
+ \let\@xs@result@If\@firstoftwo% nombre d'occurrences atteint : on renvoie #4
+ \edef\@xs@before@IfSubStr{\@xs@before@IfSubStr##2}%
+ \edef\@xs@behind@IfSubStr{\@xs@strip@delimit##3\@nil}%
\fi
- \fi}%
- \@xs@IfSubStr@i#2\@delimit#3\@nil1\@nil% \@delimit pour éviter le cas de \IfSubStr{a}{aa}{V}{F} qui renverrait V
+ \fi
+ \@xs@next}%
+ \@xs@IfSubStr@i1\@nil#2\@delimit#3\@nil% \@delimit pour éviter le cas de \IfSubStr{a}{aa}{V}{F} qui renverrait V
\fi
\fi
- \@xs@result@IfSubStr}
+ \@xs@result@If}
\@xs@newmacro\IfBeginWith{}{2}{0}{%
\@xs@IfSubStr[\@ne]{#1}{#2}%
{\ifx\@empty\@xs@before@IfSubStr\@empty
- \def\@xs@result@IfBeginWith{\expandafter\@firstoftwo}%
+ \let\@xs@result@If\@firstoftwo%
\else
- \def\@xs@result@IfBeginWith{\expandafter\@secondoftwo}%
+ \let\@xs@result@If\@secondoftwo%
\fi}%
- {\def\@xs@result@IfBeginWith{\expandafter\@secondoftwo}}%
- \@xs@result@IfBeginWith}
+ {\let\@xs@result@If\@secondoftwo}%
+ \@xs@result@If}
\@xs@newmacro\IfEndWith{}{2}{0}{%
- \@xs@StrCount{#1}{#2}[\@xs@result@IfEndWith]%
- \ifnum\@xs@result@IfEndWith=\z@
- \def\@xs@result@IfEndWith{\expandafter\@secondoftwo}%
+ \@xs@StrCount{#1}{#2}[\@xs@result@If]%
+ \ifnum\@xs@result@If=\z@
+ \let\@xs@result@If\@secondoftwo%
\else
\ifx\@empty\@xs@after@StrCount\@empty
- \def\@xs@result@IfEndWith{\expandafter\@firstoftwo}%
+ \let\@xs@result@If\@firstoftwo%
\else
- \def\@xs@result@IfEndWith{\expandafter\@secondoftwo}%
+ \let\@xs@result@If\@secondoftwo%
\fi
\fi
- \@xs@result@IfEndWith}
+ \@xs@result@If}
\@xs@newmacro\IfSubStrBefore{1,1}{3}{0}{\@xs@IfSubStrBefore@i[#1]{#2}{#3}{#4}}
\def\@xs@IfSubStrBefore@i[#1,#2]#3#4#5{%
\@xs@IfSubStr[#2]{#3}{#5}%
{\expandafter\@xs@IfSubStr\expandafter[\expandafter#1\expandafter]\expandafter{\@xs@before@IfSubStr}{#4}%
- {\def\@xs@result@IfSubStrBefore{\expandafter\@firstoftwo}}%
- {\def\@xs@result@IfSubStrBefore{\expandafter\@secondoftwo}}%
+ {\let\@xs@result@If\@firstoftwo}%
+ {\let\@xs@result@If\@secondoftwo}%
}%
- {\def\@xs@result@IfSubStrBefore{\expandafter\@secondoftwo}}%
- \@xs@result@IfSubStrBefore}
+ {\let\@xs@result@If\@secondoftwo}%
+ \@xs@result@If}
\@xs@newmacro\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}}
@@ -375,15 +397,15 @@
\def\@xs@putXifempty#1{#1\ifx\@empty#1\@empty X\fi}
\def\@xs@formatnumber#1{%
\ifx\@empty#1\@empty
- 0X%
+ 0X% si vide, renvoie 0X
\else
- \expandafter\ifx\@xs@returnfirstchar#1\@nil+%
+ \expandafter\ifx\@xs@returnfirstchar#1\@nil+% si commence par un +, renvoie +0<nombre>
+0\expandafter\@xs@putXifempty\expandafter{\@xs@gobblefirstchar#1\@nil}%
\else
- \expandafter\ifx\@xs@returnfirstchar#1\@nil-%
+ \expandafter\ifx\@xs@returnfirstchar#1\@nil-% si commence par un -, renvoie -0<nombre>
-0\expandafter\@xs@putXifempty\expandafter{\@xs@gobblefirstchar#1\@nil}%
\else
- 0#1%
+ 0#1% si ne commence ni par + ni par -, renvoie 0<nombre>
\fi
\fi
\fi}
@@ -393,11 +415,10 @@
\decimalpart\z@
\afterassignment\@xs@defafterinteger\integerpart=\@xs@formattednumber\relax\@nil
\if\relax\@xs@afterinteger
- \def\@xs@result@IfInteger{\expandafter\@firstoftwo}%
+ \expandafter\@firstoftwo
\else
- \def\@xs@result@IfInteger{\expandafter\@secondoftwo}%
- \fi
- \@xs@result@IfInteger}
+ \expandafter\@secondoftwo
+ \fi}
\@xs@newmacro\IfDecimal{}{1}{0}{%
\@xs@def\@xs@formattednumber{\@xs@formatnumber{#1}}%
@@ -405,11 +426,10 @@
\afterassignment\@xs@defafterinteger\integerpart=\@xs@formattednumber\relax\@nil
\expandafter\@xs@testdot\@xs@afterinteger\@nil
\if\relax\@xs@afterdecimal
- \def\@xs@result@IfDecimal{\expandafter\@firstoftwo}%
+ \expandafter\@firstoftwo
\else
- \def\@xs@result@IfDecimal{\expandafter\@secondoftwo}%
- \fi
- \@xs@result@IfDecimal}
+ \expandafter\@secondoftwo
+ \fi}
\def\@xs@defafterinteger#1\@nil{\def\@xs@afterinteger{#1}}%
\def\@xs@testdot{\@ifnextchar.{\@xs@readdecimalpart}{\@xs@testcomma}}
@@ -421,26 +441,22 @@
\def\@xs@endnumber#1\@nil{\def\@xs@afterdecimal{#1}}
% test d'égalité sur des chaines (et des chaines contenant des nombres)
-\def\@xs@IfStrEqFalse@#1#2{\def\@xs@result@IfStrEq{\expandafter\@secondoftwo}}
+\def\@xs@IfStrEqFalse@#1#2{\let\@xs@result@If\@secondoftwo}
\def\@xs@IfStrEqFalse@@#1#2{% renvoie vrai si les 2 arg sont décimaux et s'ils sont égaux, faux sinon
\@xs@IfDecimal{#1}%
{\@xs@IfDecimal{#2}%
- {\ifdim#1pt=#2pt\def\@xs@result@IfStrEq{\expandafter\@firstoftwo}\else\def\@xs@result@IfStrEq{\expandafter\@secondoftwo}\fi}% les 2 sont décimaux
- {\def\@xs@result@IfStrEq{\expandafter\@secondoftwo}}}% un seul est décimal
- {\def\@xs@result@IfStrEq{\expandafter\@secondoftwo}}}% #1 n'est pas décimal
+ {\ifdim#1pt=#2pt\let\@xs@result@If\@firstoftwo\else\let\@xs@result@If\@secondoftwo\fi}% les 2 sont décimaux : on fait le test
+ {\let\@xs@result@If\@secondoftwo}}% un seul est décimal
+ {\let\@xs@result@If\@secondoftwo}}% #1 n'est pas décimal
+
\def\@xs@TestEqu@l#1#2{% teste si les 2 arguments sont égaux
- \expandafter\ifx\expandafter\@empty\detokenize{#1#2}\@empty
- \def\@xs@result@IfStrEq{\expandafter\@firstoftwo}% les 2 sont vides, on renvoie vrai
+ \def\@xs@tempa{#1}\def\@xs@tempb{#2}%
+ \ifx\@xs@tempa\@xs@tempb
+ \let\@xs@result@If\@firstoftwo% égalité parfaite des 2 chaines
\else
- \@xs@IfSubStr[\@ne]{#1}{#2}%
- {\expandafter\ifx\expandafter\@empty\detokenize\expandafter\expandafter\expandafter{\expandafter\@xs@before@IfSubStr\@xs@behind@IfSubStr}\@empty
- \def\@xs@result@IfStrEq{\expandafter\@firstoftwo}% égalité parfaite des 2 chaines
- \else
- \@xs@IfStrEqFalse{#1}{#2}%
- \fi}%
- {\@xs@IfStrEqFalse{#1}{#2}}%
+ \@xs@IfStrEqFalse{#1}{#2}%
\fi
- \@xs@result@IfStrEq}
+ \@xs@result@If}
\@xs@newmacro\IfStrEq{}{2}{0}{% teste si les deux chaines sont égales
\let\@xs@IfStrEqFalse\@xs@IfStrEqFalse@
@@ -449,6 +465,24 @@
\let\@xs@IfStrEqFalse\@xs@IfStrEqFalse@@
\@xs@TestEqu@l{#1}{#2}}
+\def\IfStrEqCase{\@ifstar{\def\@xs@IfEqName{\IfStrEq*}\@xs@IfStrCase@@}{\def\@xs@IfEqName{\IfStrEq}\@xs@IfStrCase@@}}
+\def\@xs@IfStrCase@@#1#2{\@testopt{\@xs@IfStringCase{#1}{#2}}{}}
+
+\def\IfEqCase{\@ifstar{\def\@xs@IfEqName{\IfEq*}\@xs@IfEqCase@@}{\def\@xs@IfEqName{\IfEq}\@xs@IfEqCase@@}}
+\def\@xs@IfEqCase@@#1#2{\@testopt{\@xs@IfStringCase{#1}{#2}}{}}
+
+\def\@xs@IfStringCase#1#2[#3]{%
+ \def\@xs@testcase##1##2##3\@nil{% lit les 2 premiers lexèmes dans ##1 et ##2. Les autres dans ##3
+ \@xs@IfEqName{#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>
+ \else
+ \def\@xs@next{\@xs@testcase##3\@nil}% sinon, on recommence avec ce qui reste
+ \fi
+ \@xs@next}}%
+ \@xs@testcase#2\@nil}
+
% 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@IfSubStr[#1]{#2}{#3}%
@@ -481,17 +515,18 @@
\else
\edef\@xs@result@StrSubstitute{}% on initialise à vide, histoire d'enlever le statut undefined
\ifnum#1>\z@
- \def\@xs@StrSubstitute@i##1#3##2\@nil##3\@nil{% ici, on compte les occurrences
- \edef\@xs@result@StrSubstitute{\@xs@result@StrSubstitute##1#4}% on recopie jusqu'à la 1ere occurrence, et on remplace #3 par #4
- \@xs@IfSubStr[1]{##2}{#3}% tant que la chaine restante contient #3
- {\ifnum\numexpr##3<#1% tant qu'on n'a pas atteint la bonne occurrence,
- \@xs@StrSubstitute@i##2\@nil##3+1\@nil% on recommence
+ \def\@xs@StrSubstitute@i##1\@nil##2#3##3\@nil{% ici, on compte les occurrences : ##1 est le compteur
+ \edef\@xs@result@StrSubstitute{\@xs@result@StrSubstitute##2#4}% on recopie jusqu'à la 1ere occurrence, et on remplace #3 par #4
+ \@xs@IfSubStr[1]{##3}{#3}% tant que la chaine restante contient #3
+ {\ifnum##1<#1% tant qu'on n'a pas atteint la bonne occurrence,
+ \def\@xs@next{\expandafter\@xs@StrSubstitute@i\number\numexpr##1+1\relax\@nil##3\@nil}%
\else
- \edef\@xs@result@StrSubstitute{\@xs@result@StrSubstitute##2}% l'occurrence est atteinte : on rajoute ce qui reste
- \fi}%
- {\edef\@xs@result@StrSubstitute{\@xs@result@StrSubstitute##2}}}% si on ne peut plus substituter, on rajoute ce qui reste
+ \def\@xs@next{\edef\@xs@result@StrSubstitute{\@xs@result@StrSubstitute##3}}%
+ \fi
+ \@xs@next}
+ {\edef\@xs@result@StrSubstitute{\@xs@result@StrSubstitute##3}}}% si on ne peut plus substituter, on rajoute ce qui reste
\@xs@IfSubStr[1]{#2}{#3}%
- {\@xs@StrSubstitute@i#2\@nil1\@nil}% si #2 contient #3, on exécute la macro
+ {\@xs@StrSubstitute@i1\@nil#2\@nil}% si #2 contient #3, on exécute la macro
{\edef\@xs@result@StrSubstitute{#2}}% sinon, on renvoie la chaine #2
\else
\def\@xs@StrSubstitute@i##1#3##2\@nil{% ici, on ne compte pas les occurrences
@@ -511,26 +546,33 @@
% Compte combien de caractères contient la chaine #1 ?
\@xs@newmacro\StrLen{}{1}{1}{\@xs@StrLen@i#1\@nil0\@nil#2\@nil}
-\def\@xs@StrLen@i#1\@nil#2\@nil#3\@nil{%
- \ifx\@empty#1\@empty%
+\def\@xs@StrLen@i#1\@nil#2\@nil#3\@nil{% #2 est le compteur
+ \ifx\@empty#1\@empty
\@xs@ReturnResult{\number\numexpr#2}{#3}%
\else
\@xs@RemoveFirst{#1}[\@xs@remain@StrLen]%
- \expandafter\@xs@StrLen@i\@xs@remain@StrLen\@nil#2+1\@nil#3\@nil
+ \def\@xs@next{\expandafter\expandafter\expandafter\@xs@StrLen@i\expandafter\@xs@remain@StrLen\expandafter\@nil\number\numexpr#2+1\relax\@nil#3\@nil}%
+ \expandafter\@xs@next
\fi}
-% Cette macro coupe la chaine #1 après le caractère n°#2
+\@xs@newmacro\StrSplit{}{2}{0}{\@xs@StrSplit@i{#2}{#1}}
+\def\@xs@StrSplit@i#1#2#3#4{%
+% Cette macro coupe la chaine #2 après le caractère n°#1
% Le début est assigné dans #3 et la fin dans #4
-\def\@xs@Split#1#2[#3,#4]{%
- \def#3{}\def#4{#1}%
- \@xs@Split@#1\@nil0\@nil#2[#3,#4]}
-\def\@xs@Split@#1\@nil#2\@nil#3[#4,#5]{%
- \ifnum\numexpr#2<\numexpr#3\relax% tant que c'est pas fini
- \@xs@ReturnFirst{#1}[#5]% prend le 1er caractère
- \edef#4{#4#5}% l'ajoute au résultat final
- \@xs@RemoveFirst{#1}[#5]% puis l'enlève de la chaine
- \ifx\@empty#5\@empty\else\expandafter\@xs@Split@#5\@nil#2+1\@nil#3[#4,#5]\fi% on recommence sauf s'il ne reste plus rien
- \fi}
+ \def\@xs@StrSplit@ii##1\@nil{%
+ \def\@xs@next{\relax}%
+ \ifnum##1<#1\relax% tant que c'est pas fini
+ \expandafter\@xs@ReturnFirst\expandafter{#4}[\@xs@next]% prend le 1er caractère
+ \edef#3{#3\@xs@next}% l'ajoute au résultat final
+ \expandafter\@xs@RemoveFirst\expandafter{#4}[#4]% puis l'enlève de la chaine
+ \ifx\@empty#4\@empty
+ \else
+ \def\@xs@next{\expandafter\@xs@StrSplit@ii\number\numexpr##1+1\relax\@nil}% on recommence sauf s'il ne reste plus rien
+ \fi
+ \fi
+ \@xs@next}%
+ \def#3{}\def#4{#2}%
+ \@xs@StrSplit@ii0\@nil}
\def\StrMid{\@ifstar{\let\@xs@assign\@xs@expand@and@detokenize\@xs@StrMid@@}{\let\@xs@assign\@xs@expand@and@assign\@xs@StrMid@@}}
\def\@xs@StrMid@@#1#2#3{%
@@ -555,38 +597,41 @@
\edef\@xs@Last@StrMid{\@len@StrMid}% on limite à la longueur de la chaine
\@xs@BadNumArg% avertissement
\fi
- \@xs@Split{#1}{\@xs@First@StrMid-1}[\@xs@before@StrMid,\@xs@behind@StrMid]%
- \expandafter\@xs@Split\expandafter{\@xs@behind@StrMid}{\@xs@Last@StrMid-\@xs@First@StrMid+1}[\@xs@result@StrMid,\@xs@before@StrMid]%
+ \expandafter\@xs@StrSplit@i\expandafter{\numexpr\@xs@First@StrMid-1}{#1}\@xs@before@StrMid\@xs@behind@StrMid
+ \expandafter\expandafter\expandafter
+ \@xs@StrSplit@i\expandafter\expandafter\expandafter
+ {\expandafter\expandafter\expandafter
+ \numexpr\@xs@Last@StrMid-\@xs@First@StrMid+2\relax\expandafter}\expandafter{\@xs@behind@StrMid}\@xs@result@StrMid\@xs@before@StrMid
\@xs@ReturnResult{\@xs@result@StrMid}{#2}%
\fi}
% supprime #2 caractères à gauche dans la chaine #1
\@xs@newmacro\StrGobbleLeft{}{2}{1}{%
- \@xs@Split{#1}{#2}[\@xs@call,\@xs@result@StrGobbleLeft]%
+ \@xs@StrSplit@i{#2}{#1}\@xs@call\@xs@result@StrGobbleLeft
\@xs@ReturnResult{\@xs@result@StrGobbleLeft}{#3}}
% extrait de #1 la chaine à gauche de longueur #2
\@xs@newmacro\StrLeft{}{2}{1}{%
- \@xs@Split{#1}{#2}[\@xs@result@StrLeft,\@xs@call]%
+ \@xs@StrSplit@i{#2}{#1}\@xs@result@StrLeft\@xs@call
\@xs@ReturnResult{\@xs@result@StrLeft}{#3}}
% supprime #2 caractères à droite dans la chaine #1
\@xs@newmacro\StrGobbleRight{}{2}{1}{%
\@xs@StrLen{#1}[\@xs@Len@StrGobbleRight]%
- \@xs@Split{#1}{\@xs@Len@StrGobbleRight-#2}[\@xs@result@StrGobbleRight,\@xs@call]%
+ \expandafter\@xs@StrSplit@i\expandafter{\numexpr\@xs@Len@StrGobbleRight-#2}{#1}\@xs@result@StrGobbleRight\@xs@call
\@xs@ReturnResult{\@xs@result@StrGobbleRight}{#3}}
% renvoie #2 caractères à la droite de la chaine #1
\@xs@newmacro\StrRight{}{2}{1}{%
\@xs@StrLen{#1}[\@xs@Len@StrRight]%
- \@xs@Split{#1}{\@xs@Len@StrRight-#2}[\@xs@call,\@xs@result@StrRight]%
+ \expandafter\@xs@StrSplit@i\expandafter{\numexpr\@xs@Len@StrRight-#2}{#1}\@xs@call\@xs@result@StrRight
\@xs@ReturnResult{\@xs@result@StrRight}{#3}}
\@xs@newmacro\StrChar{}{2}{1}{%
\ifnum#2<\@ne
\@xs@ReturnResult{}{#3}%
\else
- \@xs@Split{#1}{#2-1}[\@xs@call,\@xs@result@StrChar]%
+ \expandafter\@xs@StrSplit@i\expandafter{\numexpr#2-1}{#1}\@xs@call\@xs@result@StrChar
\expandafter\@xs@ReturnFirst\expandafter{\@xs@result@StrChar}[\@xs@result@StrChar@]%
\@xs@ReturnResult{\@xs@result@StrChar@}{#3}%
\fi}
@@ -598,18 +643,15 @@
\edef\@xs@after@StrCount{}%
\@xs@ReturnResult{0}{#3}%
\else
- \def\@xs@StrCount@i##1#2##2\@nil##3\@nil{%
- \ifx\@empty##2\@empty
- \ifnum\numexpr##3=\z@
- \edef\@xs@after@StrCount{}%
- \else
- \edef\@xs@after@StrCount{\@xs@strip@delimit##1\@nil}%
- \fi
- \@xs@ReturnResult{\number\numexpr##3}{#3}%
+ \def\@xs@StrCount@i##1\@nil##2#2##3\@nil{% ##1 est le compteur
+ \ifx\@empty##3\@empty
+ \edef\@xs@after@StrCount{\ifnum\numexpr##1=\z@\else\@xs@strip@delimit##2\@nil\fi}%
+ \@xs@ReturnResult{##1}{#3}%
\else
- \@xs@StrCount@i##2\@nil##3+1\@nil
+ \def\@xs@next{\expandafter\@xs@StrCount@i\number\numexpr##1+1\relax\@nil##3\@nil}%
+ \expandafter\@xs@next
\fi}%
- \@xs@StrCount@i#1\@delimit#2\@nil0\@nil
+ \@xs@StrCount@i0\@nil#1\@delimit#2\@nil
\fi}
% renvoie la position de l'occurrence #1 de la sous chaine #3 dans la chaine #2
@@ -624,11 +666,50 @@
}%
{\@xs@ReturnResult{0}{#4}}%
\fi}
+
+\def\comparestrict{\let\@xs@comparecoeff\@ne}
+\def\comparenormal{\let\@xs@comparecoeff\z@}
+% Compare les deux arguments #1 et #2
+% Renvoie 0 s'ils sont égaux et renvoie la position
+% du premier caractère différent sinon
+\@xs@newmacro\StrCompare{}{2}{1}{%
+ \@xs@IfStrEq{#1}{#2}%
+ {\@xs@ReturnResult{0}{#3}}%
+ {\ifx\@empty\@xs@stringB
+ \def\@xs@next{\@xs@ReturnResult{0}{#3}}% si la plus petite chaîne est vide, on renvoie 0
+ \else
+ \def\@xs@next{\@xs@StrCompare@i{#1}{#2}{#3}}%
+ \fi
+ \@xs@next}}
+\def\@xs@StrCompare@i#1#2#3{%
+ \def\@xs@StrCompare@ii##1\@nil{% ##1 est la position
+ \ifx\@empty\@xs@stringB% il n'y a plus de caractères à tester...
+ \def\@xs@next{\@xs@ReturnResult{\number\numexpr##1*\@xs@comparecoeff}{#3}}% ...on a passé tous les tests : #2 *en entier* apparaît exactement au début de #1 et on renvoie donc 0 ou la position
+ \else
+ \expandafter\@xs@StrSplit@i\expandafter\@ne\expandafter{\@xs@stringA}\@xs@currentcharA\@xs@stringA
+ \expandafter\@xs@StrSplit@i\expandafter\@ne\expandafter{\@xs@stringB}\@xs@currentcharB\@xs@stringB
+ \ifx\@xs@currentcharB\@xs@currentcharA
+ \def\@xs@next{\expandafter\@xs@StrCompare@ii\number\numexpr##1+1\relax\@nil}% les 2 caractères sont égaux, on recommence
+ \else
+ \def\@xs@next{\@xs@ReturnResult{##1}{#3}}% les 2 caractères sont différents : on renvoie la position
+ \fi
+ \fi
+ \@xs@next}%
+ \@xs@StrLen{#1}[\@xs@LenA@StrCompare]%
+ \@xs@StrLen{#2}[\@xs@LenB@StrCompare]%
+ \ifnum\@xs@LenB@StrCompare<\@xs@LenA@StrCompare
+ \def\@xs@stringA{#1}\def\@xs@stringB{#2}%
+ \else
+ \def\@xs@stringA{#2}\def\@xs@stringB{#1}%
+ \fi
+ \@xs@StrCompare@ii1\@nil}
+
% Restaure le code de @
\catcode`\@=\CurrentAtCatcode\relax
-% Définit le délimiteur verb et le développement des arguments par défaut
+% Définit le délimiteur verb et le développement des arguments par défaut et le mode de comparaison
\setverbdelim{|}
\fullexpandarg
+\comparenormal
\endinput
%
% Historique
@@ -639,16 +720,16 @@
% v1.1 15/8/2008
% - Le package ne nécessite plus LaTeX et est désormais
% 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
+% - 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
% - 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{éù}
+% 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.
@@ -656,17 +737,17 @@
% - Nouvelles fonctionnalités 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
+% l'occurrence testée 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@after@StrCount
-% b) la macro ne dépend plus d'aucune autre
+% a) ajout de ce qui se trouve après la dernière
+% occurrence dans la sc \@xs@after@StrCount
+% b) la macro ne dépend 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@Split
+% 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)
@@ -674,4 +755,17 @@
% n'envisageait pas le cas où son argument était vide
% ce qui faiasait planter \IfDecimal{}{V}{F} et
% \IfInteger{}{V}{F}
-%------------------------------------------------------------ \ No newline at end of file
+%------------------------------------------------------------
+% 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@TestEqu@l 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
+% - Nouvelle macro \StrCompare
+% Compare 2 chaînes et renvoie la position du
+% 1er caractère différent. Renvoie 0 si elles sont
+% égales \ No newline at end of file