diff options
author | Karl Berry <karl@freefriends.org> | 2012-10-25 22:11:07 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2012-10-25 22:11:07 +0000 |
commit | f7bda182fe73ce45159eb3d7263c0a2343411f59 (patch) | |
tree | da01712cba9a9ece00c87c9114e06bf497ef906c /Master | |
parent | bbe35c83c2f2607cd6671d6afaf0cfe4be54f947 (diff) |
xstring (25oct12)
git-svn-id: svn://tug.org/texlive/trunk@28078 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r-- | Master/texmf-dist/doc/generic/xstring/README | 4 | ||||
-rw-r--r-- | Master/texmf-dist/doc/generic/xstring/xstring_doc_en.pdf | bin | 772855 -> 242308 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/generic/xstring/xstring_doc_en.tex | 53 | ||||
-rw-r--r-- | Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.pdf | bin | 791211 -> 250157 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.tex | 104 | ||||
-rw-r--r-- | Master/texmf-dist/tex/generic/xstring/xstring.tex | 445 |
6 files changed, 443 insertions, 163 deletions
diff --git a/Master/texmf-dist/doc/generic/xstring/README b/Master/texmf-dist/doc/generic/xstring/README index 7cd8ca61ad5..fbd26a12315 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.5d - 2010/03/28 + v 1.6 + 2012/10/24 _________________ 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 Binary files differindex d48edf585cd..0be656ec48c 100644 --- a/Master/texmf-dist/doc/generic/xstring/xstring_doc_en.pdf +++ b/Master/texmf-dist/doc/generic/xstring/xstring_doc_en.pdf 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 19b9c760278..e35067df703 100644 --- a/Master/texmf-dist/doc/generic/xstring/xstring_doc_en.tex +++ b/Master/texmf-dist/doc/generic/xstring/xstring_doc_en.tex @@ -21,7 +21,8 @@ \usepackage[a4paper,dvips,margin=1.9cm]{geometry} \usepackage{amsmath,amssymb,amsfonts} \usepackage{color} -\usepackage{lmodern} +\usepackage{fourier} +\usepackage[scaled=.8]{luximono} \usepackage{eurosym} \usepackage{xspace} \usepackage{listings} @@ -29,7 +30,7 @@ \usepackage[bottom]{footmisc} \usepackage[french]{babel} \makeatletter -\definecolor{@xs@bckgcolor}{rgb}{1,1,0.875} +\definecolor{@xs@bckgcolor}{rgb}{1,1,0.9} \definecolor{@xs@keywordsxstring}{rgb}{0.7,0,0} \definecolor{@xs@keywordslatex}{rgb}{0,0,1} \definecolor{@xs@arguments}{rgb}{0,0,0} @@ -66,7 +67,7 @@ IfBeginWith,IfEndWith,% IfInteger,IfDecimal,integerpart,decimalpart,% IfStrEq,IfEq,IfStrEqCase,IfEqCase,% - StrBefore,StrBehind,StrBetween,% + StrBefore,StrBehind,StrCut,StrBetween,% StrSubstitute,StrDel,% StrGobbleLeft,StrGobbleRight,StrRight,StrLeft,StrMid,StrChar,% StrSplit,% @@ -688,6 +689,50 @@ In \argu{string}, returns what is rightwards the \argu{number}\th occurrence of |\StrBehind[3]{1b2b3}{b}| \end{minipage}% +\subsubsection{\ttfamily\textbackslash StrCut} +Here is the syntax of this macro:\par\nobreak\smallskip +\verbinline|\StrCut|\etoile\arguC{nunber}\ARGU{string}\ARGU{stringA}\ARGU{macroA}\ARGU{macroB} +\smallskip + +The optional argument \argu{number} is 1 by default.\par\nobreak\smallskip +The \argu{string} is cut in two parts at the occurrence \no\arguC{number} of \ARGU{stringA}. The left part is stored in the control sequence \argu{macroA} and the right part in \argu{macroB}. + +Since this macro returns \emph{two strings}, it does \emph{not} display anything. Consequently, it does not provide the optional argument in last position.\medskip + +\begin{Conditions} + \item If \argu{string} or \argu{stringA} is empty, \argu{macroA} and \argu{macroB} are empty; + \item If \argu{number}${}<1$, the macro behaves as if \argu{number}${}=1$; + \item If the occurrence is not found, \argu{macroA} receives the whole \argu{string} while \argu{macroB} is empty. +\end{Conditions} +\begin{minipage}[t]{0.65\linewidth} +\begin{lstlisting} +\StrCut{abracadabra}{a}\csA\csB |\csA|\csB|\par +\StrCut[2]{abracadabra}{a}\csA\csB |\csA|\csB|\par +\StrCut[3]{abracadabra}{a}\csA\csB |\csA|\csB|\par +\StrCut[4]{abracadabra}{a}\csA\csB |\csA|\csB|\par +\StrCut[5]{abracadabra}{a}\csA\csB |\csA|\csB|\par +\StrCut[6]{abracadabra}{a}\csA\csB |\csA|\csB|\par +\StrCut[-4]{abracadabra}{a}\csA\csB |\csA|\csB|\par +\StrCut{abracadabra}{brac}\csA\csB |\csA|\csB|\par +\StrCut{abracadabra}{foo}\csA\csB |\csA|\csB|\par +\StrCut{abracadabra}{}\csA\csB |\csA|\csB| +\end{lstlisting}% +\end{minipage}\hfill +\begin{minipage}[t]{0.35\linewidth} + \def\seprouge{{\color{red}|}} + \styleexemple + \StrCut{abracadabra}{a}\csA\csB |\csA\seprouge\csB|\par + \StrCut[2]{abracadabra}{a}\csA\csB |\csA\seprouge\csB|\par + \StrCut[3]{abracadabra}{a}\csA\csB |\csA\seprouge\csB|\par + \StrCut[4]{abracadabra}{a}\csA\csB |\csA\seprouge\csB|\par + \StrCut[5]{abracadabra}{a}\csA\csB |\csA\seprouge\csB|\par + \StrCut[6]{abracadabra}{a}\csA\csB |\csA\seprouge\csB|\par + \StrCut[-4]{abracadabra}{a}\csA\csB |\csA\seprouge\csB|\par + \StrCut{abracadabra}{brac}\csA\csB |\csA\seprouge\csB|\par + \StrCut{abracadabra}{foo}\csA\csB |\csA\seprouge\csB|\par + \StrCut{abracadabra}{}\csA\csB |\csA\seprouge\csB| +\end{minipage}% + \subsubsection{\ttfamily\textbackslash StrBetween} \verbinline|\StrBetween|\etoile\arguCC{number1}{number2}\ARGU{string}\ARGU{stringA}\ARGU{stringB}\arguC{name} @@ -1696,7 +1741,7 @@ The macro expands each token consecutively, and does not see what follows: token \hfil\verbinline|\StrExpand{\iftrue A\else B\fi}\resultat|\hfil{}\par\nobreak\smallskip provokes an error because the first token "\verbinline|\iftrue|" is expanded \emph{alone} without seeing its \verbinline-\fi- which makes \TeX{} angry. -Expansion inside groups is \emph{independant} of the exploration mode: this macro has its own command to expand or not what is inside the groups. By default, tokens inside groups are expanded, but this can be changed with \verbinline-\noexpandingroups-. The default behaviour can be recoverd with \verbinline-\expandingroups-.\bigskip +Expansion inside groups is \emph{independant} of the exploration mode: this macro has its own command to expand or not what is inside the groups. By default, tokens inside groups are expanded, but this can be changed with the macro \verbinline-\noexpandingroups-. The default behaviour can be recoverd with \verbinline-\expandingroups-.\bigskip The \verbinline-\scancs- macro returns the detokenized result:\par\nobreak\medskip \verbinline|\scancs|\arguC{number}\ARGU{name}\ARGU{string}\par\nobreak\smallskip diff --git a/Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.pdf b/Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.pdf Binary files differindex 67b73684722..c884440c06d 100644 --- a/Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.pdf +++ b/Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.pdf 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 987d90a85d3..ea701726af6 100644 --- a/Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.tex +++ b/Master/texmf-dist/doc/generic/xstring/xstring_doc_fr.tex @@ -1,7 +1,6 @@ % Ceci est xtring_doc_fr.tex, le manuel en français de xstring -% This is xtring_doc_fr.tex, the french manual of xstring % -% Christian Tellechea 2009 +% Christian Tellechea 2008-2012 % % email : unbonpetit@gmail.com %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -22,7 +21,8 @@ \usepackage[a4paper,dvips,margin=1.9cm]{geometry} \usepackage{amsmath,amssymb,amsfonts} \usepackage{color} -\usepackage{lmodern} +\usepackage{fourier} +\usepackage[scaled=.8]{luximono} \usepackage{eurosym} \usepackage{xspace} \usepackage{listings} @@ -30,7 +30,7 @@ \usepackage[bottom]{footmisc} \usepackage[frenchb]{babel} \makeatletter -\definecolor{@xs@bckgcolor}{rgb}{1,1,0.875} +\definecolor{@xs@bckgcolor}{rgb}{1,1,0.9} \definecolor{@xs@keywordsxstring}{rgb}{0.7,0,0} \definecolor{@xs@keywordslatex}{rgb}{0,0,1} \definecolor{@xs@arguments}{rgb}{0,0,0} @@ -67,7 +67,7 @@ IfBeginWith,IfEndWith,% IfInteger,IfDecimal,integerpart,decimalpart,% IfStrEq,IfEq,IfStrEqCase,IfEqCase,% - StrBefore,StrBehind,StrBetween,% + StrBefore,StrBehind,StrCut,StrBetween,% StrSubstitute,StrDel,% StrGobbleLeft,StrGobbleRight,StrRight,StrLeft,StrMid,StrChar,% StrSplit,% @@ -80,18 +80,6 @@ setverbdelim},% keywordstyle=\color{@xs@keywordsxstring},% classoffset=0} -% redéfinition de l'écriture des textes des footnote -\long\def\@makefntextFB#1{% - \ifx\thefootnote\ftnISsymbol - \@makefntextORI{#1}% - \else - \rule\z@\footnotesep - \setbox\@tempboxa\hbox{\@thefnmark}% - \ifdim\wd\@tempboxa>\z@ - \kern2em\llap{\@thefnmark.\kern0.5em}% - \fi - \hangindent2em\hangafter\@ne#1 - \fi} \makeatother \newcommand\guill[1]{\og{}#1\fg{}} @@ -686,6 +674,50 @@ Dans \argu{chaine}, renvoie ce qui se trouve après l'occurrence \no\argu{nombre |\StrBehind[3]{1b2b3}{b}| \end{minipage}% +\subsubsection{\ttfamily\textbackslash StrCut} +Voici la syntaxe de cette macro :\par\nobreak\smallskip +\verbinline|\StrCut|\etoile\arguC{nombre}\ARGU{chaine}\ARGU{chaineA}\ARGU{macroA}\ARGU{macroB} +\smallskip + +L'argument optionnel \argu{nombre} vaut 1 par défaut.\par\nobreak\smallskip +La \argu{chaine} est coupée en deux chaînes à l'occurrence \no\arguC{nombre} de la \ARGU{chaineA}. Ce qui se trouve à gauche de cette occurrence est assigné à la séquence de contrôle \argu{macroA} et ce qui se trouve à droite à \argu{macroB}. + +Cette macro renvoie \emph{deux chaînes} et donc \textbf{n'affiche rien}. Par conséquent, elle ne dispose pas de l'argument optionnel en dernière position.\medskip + +\begin{Conditions} + \item Si \argu{chaine} ou \argu{chaineA} est vide, \argu{macroA} et\argu{macroB} seront vides ; + \item Si \argu{nombre}${}<1$ alors, la macro se comporte comme si \argu{nombre}${}=1$; + \item Si l'occurrence n'est pas trouvée, \argu{macroA} reçoit la totalité de \argu{chaine} tandis que \argu{macroB} est vide. +\end{Conditions} +\begin{minipage}[t]{0.65\linewidth} +\begin{lstlisting} +\StrCut{abracadabra}{a}\csA\csB |\csA|\csB|\par +\StrCut[2]{abracadabra}{a}\csA\csB |\csA|\csB|\par +\StrCut[3]{abracadabra}{a}\csA\csB |\csA|\csB|\par +\StrCut[4]{abracadabra}{a}\csA\csB |\csA|\csB|\par +\StrCut[5]{abracadabra}{a}\csA\csB |\csA|\csB|\par +\StrCut[6]{abracadabra}{a}\csA\csB |\csA|\csB|\par +\StrCut[-4]{abracadabra}{a}\csA\csB |\csA|\csB|\par +\StrCut{abracadabra}{brac}\csA\csB |\csA|\csB|\par +\StrCut{abracadabra}{foo}\csA\csB |\csA|\csB|\par +\StrCut{abracadabra}{}\csA\csB |\csA|\csB| +\end{lstlisting}% +\end{minipage}\hfill +\begin{minipage}[t]{0.35\linewidth} + \def\seprouge{{\color{red}|}} + \styleexemple + \StrCut{abracadabra}{a}\csA\csB |\csA\seprouge\csB|\par + \StrCut[2]{abracadabra}{a}\csA\csB |\csA\seprouge\csB|\par + \StrCut[3]{abracadabra}{a}\csA\csB |\csA\seprouge\csB|\par + \StrCut[4]{abracadabra}{a}\csA\csB |\csA\seprouge\csB|\par + \StrCut[5]{abracadabra}{a}\csA\csB |\csA\seprouge\csB|\par + \StrCut[6]{abracadabra}{a}\csA\csB |\csA\seprouge\csB|\par + \StrCut[-4]{abracadabra}{a}\csA\csB |\csA\seprouge\csB|\par + \StrCut{abracadabra}{brac}\csA\csB |\csA\seprouge\csB|\par + \StrCut{abracadabra}{foo}\csA\csB |\csA\seprouge\csB|\par + \StrCut{abracadabra}{}\csA\csB |\csA\seprouge\csB| +\end{minipage}% + \subsubsection{\ttfamily\textbackslash StrBetween} \verbinline|\StrBetween|\etoile\arguCC{nombre1}{nombre2}\ARGU{chaine}\ARGU{chaineA}\ARGU{chaineB}\arguC{nom} \smallskip @@ -727,6 +759,8 @@ Dans \argu{chaine}, renvoie ce qui se trouve entre\footnote{Au sens strict, c'es \StrBetween[3,2]{abracadabra}{a}{bra}\par \end{minipage}% + + \subsubsection{\ttfamily\textbackslash StrSubstitute} \verbinline|\StrSubstitute|\arguC{nombre}\ARGU{chaine}\ARGU{chaineA}\ARGU{chaineB}\arguC{nom} \smallskip @@ -1060,7 +1094,7 @@ Dans \argu{chaine}, renvoie la position de l'occurrence \no\argu{nombre} de \arg \verbinline|\StrCompare|\etoile\ARGU{chaineA}\ARGU{chaineB}\arguC{nom} \smallskip -Cette macro peut fonctionner avec 2 tolérances : la tolérance \guill{normale} sélectionnée par défaut, et la tolérance \guill{stricte}.\medskip +Cette macro peut fonctionner avec 2 tolérances, la tolérance \guill{normale} qui est sélectionnée par défaut et la tolérance \guill{stricte}.\medskip \begin{itemize} \item La tolérance normale, activée par la commande \verbinline|\comparenormal|.\par @@ -1488,24 +1522,24 @@ Cette macro renvoie \emph{deux chaînes} et donc \textbf{n'affiche rien}. Par co \begin{minipage}[c]{0.65\linewidth} \hfill \begin{lstlisting} - \def\seprouge{{\color{red}|}} - \StrSplit{abcdef}{4}{\csA}{\csB}|\csA\seprouge\csB|\par - \StrSplit{a b c }{2}{\csA}{\csB}|\csA\seprouge\csB|\par - \StrSplit{abcdef}{1}{\csA}{\csB}|\csA\seprouge\csB|\par - \StrSplit{abcdef}{5}{\csA}{\csB}|\csA\seprouge\csB|\par - \StrSplit{abcdef}{9}{\csA}{\csB}|\csA\seprouge\csB|\par - \StrSplit{abcdef}{-3}{\csA}{\csB}|\csA\seprouge\csB| +\def\seprouge{{\color{red}|}} +\StrSplit{abcdef}{4}{\csA}{\csB}|\csA\seprouge\csB|\par +\StrSplit{a b c }{2}{\csA}{\csB}|\csA\seprouge\csB|\par +\StrSplit{abcdef}{1}{\csA}{\csB}|\csA\seprouge\csB|\par +\StrSplit{abcdef}{5}{\csA}{\csB}|\csA\seprouge\csB|\par +\StrSplit{abcdef}{9}{\csA}{\csB}|\csA\seprouge\csB|\par +\StrSplit{abcdef}{-3}{\csA}{\csB}|\csA\seprouge\csB| \end{lstlisting}% \end{minipage}\hfill \begin{minipage}[c]{0.35\linewidth} - \styleexercice - \def\seprouge{{\color{red}|}} - \StrSplit{abcdef}{4}{\csA}{\csB}|\csA\seprouge\csB|\par - \StrSplit{a b c }{2}{\csA}{\csB}|\csA\seprouge\csB|\par - \StrSplit{abcdef}{1}{\csA}{\csB}|\csA\seprouge\csB|\par - \StrSplit{abcdef}{5}{\csA}{\csB}|\csA\seprouge\csB|\par - \StrSplit{abcdef}{9}{\csA}{\csB}|\csA\seprouge\csB|\par - \StrSplit{abcdef}{-3}{\csA}{\csB}|\csA\seprouge\csB| +\styleexercice +\def\seprouge{{\color{red}|}} +\StrSplit{abcdef}{4}{\csA}{\csB}|\csA\seprouge\csB|\par +\StrSplit{a b c }{2}{\csA}{\csB}|\csA\seprouge\csB|\par +\StrSplit{abcdef}{1}{\csA}{\csB}|\csA\seprouge\csB|\par +\StrSplit{abcdef}{5}{\csA}{\csB}|\csA\seprouge\csB|\par +\StrSplit{abcdef}{9}{\csA}{\csB}|\csA\seprouge\csB|\par +\StrSplit{abcdef}{-3}{\csA}{\csB}|\csA\seprouge\csB| \end{minipage}% \setverbdelim{|}\medskip @@ -1674,7 +1708,7 @@ D\'eveloppement de \string\csD\ au\par \end{minipage}% \medskip -La macro opère séquentiellement et chaque token est développé isolément sans tenir compte de ce qui suit. On ne peut donc développer que des tokens se suffisant à eux même et n'en nécessitant aucun autre. Ainsi, \og\hbox{\verbinline|\iftrue A\else B\fi|}\fg, bien que se développant en \guill{A} ne peut être mis dans l'argument de \verbinline|\StrExpand|, et l'instruction :\par\nobreak\smallskip +La macro agit séquentiellement et chaque token est développé isolément sans tenir compte de ce qui suit. On ne peut donc développer que des tokens qui se suffisent à eux même et dont le développement ne nécessite aucun autre token. Ainsi, \og\hbox{\verbinline|\iftrue A\else B\fi|}\fg, bien que se développant en \guill{A} ne peut être mis dans l'argument de \verbinline|\StrExpand|, et l'instruction :\par\nobreak\smallskip \hfil\verbinline|\StrExpand{\iftrue A\else B\fi}\resultat|\hfil{}\par\nobreak\smallskip fera échouer la compilation puisque le premier token \og\verbinline|\iftrue|\fg{} sera développé \emph{seul}, c'est-à-dire sans son \verbinline-\fi- correspondant, ce qui fâchera \TeX{} !\smallskip @@ -1815,7 +1849,7 @@ On va appeler cette macro \verb|StringDel| et lui donner la syntaxe :\par\nobrea \hfil\verb|\StringDel{chaine}{position}{n}{\nom_resultat}|\hfil{} \medskip -On peut procéder ainsi : prendre la chaîne se trouvant juste avant la position, la sauvegarder. Ensuite enlever \verb|n + position| \USs à la chaîne initiale, et concaténer ce résultat à ce qui a été sauvegardé auparavant. Cela donne le code suivant :\par\nobreak\medskip +On peut procéder ainsi : sauvegarder la chaîne se trouvant juste avant la position. Ensuite enlever \verb|n + position| \USs à la chaîne initiale, et concaténer ce résultat à ce qui a été sauvegardé auparavant. Cela donne le code suivant :\par\nobreak\medskip \begin{minipage}[c]{0.65\linewidth} \begin{lstlisting} diff --git a/Master/texmf-dist/tex/generic/xstring/xstring.tex b/Master/texmf-dist/tex/generic/xstring/xstring.tex index cbad33e6490..986616ce688 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.5d | +% | xstring v1.6 | % | | -% | March 28 2010 | +% | October 24 2012 | % | | % |__________________________________________________| % @@ -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-2010 +% Christian Tellechea 2008-2012 % email : unbonpetit@gmail.com % ------------------------------------------------------------------- % This work may be distributed and/or modified under the @@ -33,10 +33,10 @@ % % The Current Maintainer of this work is Christian Tellechea % ------------------------------------------------------------------- -\def\xstringversion {1.5d} -\def\xstringdate {2010/03/28} -\def\xstringfrenchdate {28 mars 2010} -\def\xstringenglishdate {March $28^{\mathrm{th}}$ 2010} +\def\xstringversion {1.6} +\def\xstringdate {2012/10/24} +\def\xstringfrenchdate {24 octobre 2012} +\def\xstringenglishdate {October $24^{\mathrm{th}}$ 2012} \edef\CurrentAtCatcode {\the\catcode`\@} \catcode`\@=11 \newwrite\@xs@message% canal pour les messages @@ -81,7 +81,8 @@ \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 + \@xs@ReadVerb% et on va lire l'argument +} % D\'efinit \@xs@ReadVerb qui lit un argument entre d\'elimiteurs verb \def\setverbdelim#1{% d\'efinit quel est le d\'elimiteur de verb @@ -96,27 +97,46 @@ \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 + \@xs@afterreadverb{##2}}% on appelle l'ex\'ecution de fin +} % Assigne l'argument entre d\'elimiteur verb dans la sc #1' + \def\verbtocs#1{% \def\@xs@afterreadverb##1{\def#1{##1}}% - \@xs@MakeVerb} + \@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\relax% ...le caract\`ere 0 a 12 pour catcode -\gdef\tokenize#1#2{% + \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} +\@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 - \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 + \everyeof\expandafter{\@xs@twochars#1}% met "^^@^^@#1" \`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 + \expandafter\@xs@AssignResult\scantokens\expandafter{\expandafter\relax\@xs@reserved@A}% on fait l'assignation +}% % 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 @@ -127,7 +147,8 @@ \@xs@argument@A \else \let#2\@xs@argument@A - \fi} + \fi +} % Pas d'expansion des arguments \def\normalexpandarg{% @@ -138,12 +159,14 @@ % 1-d\'eveloppement du premier token des arguments \def\expandarg{% \let\@xs@def\def% on d\'efinit \@xs@call avec \def - \def\@xs@expand##1{\unexpanded\expandafter\expandafter\expandafter{##1}}} + \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 - \def\@xs@expand##1{##1}}% et on neutralise \@xs@expand + \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} @@ -152,7 +175,7 @@ % et #3 sinon (Ulrich Diez sur comp.text.tex) \def\@xs@ifbeginwithbrace#1{% \csname @% - \expandafter\@gobble\string{% ne sert à rien si ce n'est \'equilibrer les accolades dans la d\'efinition + \expandafter\@gobble\string{% \expandafter\@gobble\expandafter{\expandafter{\string#1}% \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\@firstoftwo \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\@gobble @@ -160,7 +183,8 @@ \expandafter\expandafter\expandafter{\expandafter\string\expandafter}\string}% \expandafter\@gobble\string}% \@secondoftwo{first}{second}oftwo% - \endcsname} + \endcsname +} % Cette macro interne prend la 1ere unit\'e syntaxique de #1 et assigne le r\'esultat \`a #2 \def\@xs@returnfirstsyntaxunit#1#2{% @@ -180,7 +204,8 @@ \else \def\@xs@next{\expandafter\futurelet\expandafter\@xs@toks\expandafter\@xs@testfirsttok\@xs@argument\@xs@nil}% \fi - \@xs@next} + \@xs@next +} % 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}} @@ -202,7 +227,8 @@ \else \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter#2% \expandafter\expandafter\expandafter{\expandafter\@gobble\@xs@argument}% - \fi} + \fi +} % Macros \`a arguments d\'elimit\'es pour les macros ci dessus \def\@xs@beforespace#1 #2\@xs@nil{#1} @@ -218,7 +244,8 @@ \def\@xs@expand@and@detokenize#1#2{% \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 + \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 @@ -260,9 +287,14 @@ \def\@xs@next{\expandafter\@xs@buildlines\expandafter{\number\numexpr##1+1}}% \expandafter\@xs@next \fi}% - \@xs@buildlines\@ne} - -\def\@xs@newmacro{\@ifstar{\let\@xs@reserved@D\@empty\@xs@newmacro@}{\let\@xs@reserved@D\relax\@xs@newmacro@0}} + \@xs@buildlines\@ne +} + +\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 % #2 : nom de la macro publique % #3 : argument optionnel (vide si pas d'arg optionnel) @@ -276,7 +308,8 @@ \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}}% + {\let\noexpand\@xs@assign\noexpand\@xs@expand@and@assign\expandafter\noexpand\@xs@reserved@C}% + }% \else \def\noexpand#2{\let\noexpand\@xs@assign\noexpand\@xs@expand@and@assign\expandafter\noexpand\@xs@reserved@C}% \fi @@ -284,7 +317,8 @@ \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}}% - \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@}} @@ -299,7 +333,9 @@ \fi \edef\@xs@reserved@B{\def\expandafter\noexpand\csname\@xs@reserved@A @@\endcsname\@xs@myarg}% \edef\@xs@reserved@C{\unexpanded\expandafter{\@xs@newlines}\edef\noexpand\@xs@call}% - \edef\@xs@reserved@D{\noexpand\noexpand\expandafter\noexpand\csname\@xs@reserved@A\endcsname\unexpanded\expandafter{\@xs@newargs}}% + \edef\@xs@reserved@D{% + \noexpand\noexpand\expandafter\noexpand\csname\@xs@reserved@A\endcsname\unexpanded\expandafter{\@xs@newargs}% + }% \ifnum#5=\@ne\edef\@xs@reserved@D{\noexpand\noexpand\noexpand\@testopt{\unexpanded\expandafter{\@xs@reserved@D}}{}}\fi \@xs@edefaddtomacro\@xs@reserved@C{{\unexpanded\expandafter{\@xs@reserved@D}}\noexpand\@xs@call}% \@xs@edefaddtomacro\@xs@reserved@B{{\unexpanded\expandafter{\@xs@reserved@C}}}% @@ -310,10 +346,14 @@ % si #5=1: \edef\@xs@call{\noexpand\@testopt{\noexpand\@xs@NOM[\@xs@expand\@xs@arg@i]{\@xs@expand\@xs@arg@i}{\@xs@expand\@xs@arg@ii}{\@xs@expand\@xs@arg@iii}{\@xs@expand\@xs@arg@iv}}{}}% % \@xs@call} \@xs@reserved@B - \edef\@xs@reserved@B{\def\expandafter\noexpand\csname\@xs@reserved@A\endcsname\@xs@myarg\ifnum#5=\@ne[\unexpanded{##}\number\numexpr\ifx\@empty#3\@empty#4+1\else#4+2\fi]\fi}% + \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} + \@xs@reserved@B +} % macro g\'en\'erique qui lit \@xs@reserved@C us par us % 3 sous-routines sont appel\'ees \`a des moments cl\'e : @@ -346,7 +386,8 @@ \@xs@atnextsyntaxunit \fi \fi - \@xs@next} + \@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 : @@ -362,33 +403,37 @@ \fi \else \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}% - {\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}% + {\global\advance\decimalpart\@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 - \@xs@next} + \@xs@next +} \@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}} + \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@B}{#2}% +} \def\@xs@StrRemoveBraces@i{% \expandafter\@xs@testempty\expandafter{\@xs@reserved@C}% @@ -418,7 +463,8 @@ \expandafter\@xs@addtomacro\expandafter\@xs@reserved@B\expandafter{\@xs@reserved@A}% \fi \fi - \@xs@next} + \@xs@next +} % \@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 @@ -426,6 +472,12 @@ % \@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{% + \ifnum#3<\@ne\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi + {\let\@xs@reserved@C\@empty\let\@xs@reserved@E\@empty\let\groupID\@empty} + {\@xs@cutafteroccur@i{#1}{#2}{#3}}% +} + +\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@ \def\@xs@atendofgroup{% @@ -433,7 +485,7 @@ \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\expandafter{\@xs@reserved@C}}% \@xs@read@reserved@D}% \def\@xs@atoccurfound{% - \ifnum\decimalpart=#3 + \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 @@ -445,12 +497,13 @@ \fi}% \@xs@read@reserved@D \def\@xs@argument@A{#2}% - \ifnum\decimalpart=#3% occurrence trouv\'ee ? + \ifnum\decimalpart=\numexpr(#3)\relax % occurrence trouv\'ee ? \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 - \fi} + \fi +} \@xs@newmacro*3\IfSubStr{1}{2}{0}{% \def\@xs@argument@A{#2}\def\@xs@argument@B{#3}% @@ -461,7 +514,8 @@ \expandafter\@secondoftwo \else \expandafter\@firstoftwo - \fi} + \fi +} \@xs@newmacro*2\IfBeginWith{}{2}{0}{% \def\@xs@argument@A{#1}\def\@xs@argument@B{#2}% @@ -472,7 +526,8 @@ \def\@xs@next{\expandafter\expandafter\expandafter\@xs@IfBeginWith@i \expandafter\expandafter\expandafter{\expandafter\@xs@argument@A\expandafter}\expandafter{\@xs@argument@B}}% \fi - \@xs@next} + \@xs@next +} \def\@xs@IfBeginWith@i#1#2{% \def\@xs@argument@A{#1}\def\@xs@argument@B{#2}% @@ -488,7 +543,7 @@ \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 - \expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@argument@A}\@xs@reserved@A% on enl\`eve les 1ere unit\'es syntaxiques + \expandafter\@xs@removefirstsyntaxunit\expandafter{\@xs@argument@A}\@xs@reserved@A% on enl\`eve les 1ere unit\'es syntaxiques \def\@xs@next{% et on recommence avec ces arguments racourcis d'1 unit\'e syntaxique \expandafter\expandafter\expandafter\@xs@IfBeginWith@i \expandafter\expandafter\expandafter{\expandafter\@xs@reserved@A\expandafter}\expandafter{\@xs@reserved@B}}% @@ -497,7 +552,8 @@ \fi \fi \fi - \@xs@next} + \@xs@next +} \@xs@newmacro*2\IfEndWith{}{2}{0}{% \def\@xs@argument@A{#1}\def\@xs@argument@B{#2}% @@ -519,7 +575,8 @@ \fi \fi \fi - \@xs@reserved@A} + \@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{% @@ -540,7 +597,8 @@ \expandafter\@secondoftwo \else \expandafter\@firstoftwo - \fi} + \fi +} \@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}} @@ -575,7 +633,8 @@ \expandafter\def\expandafter#2\expandafter{\expandafter0\@xs@argument@A}% \fi \fi - \fi} + \fi +} \@xs@newmacro\IfInteger{}{1}{0}{% \@xs@formatnumber{#1}\@xs@reserved@A @@ -594,10 +653,11 @@ \let\@xs@afterinteger\@xs@after@intpart \let\@xs@next\@secondoftwo \fi - \@xs@next} + \@xs@next +} \@xs@newmacro\IfDecimal{}{1}{0}{% - \expandafter\@xs@formatnumber\expandafter{\detokenize{#1}}\@xs@reserved@A + \@xs@formatnumber{#1}\@xs@reserved@A \decimalpart\z@ \afterassignment\@xs@defafterinteger\integerpart\@xs@reserved@A\relax\@xs@nil \expandafter\@xs@testdot\@xs@afterinteger\@xs@nil @@ -605,15 +665,30 @@ \expandafter\@firstoftwo \else \expandafter\@secondoftwo - \fi} + \fi +} \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@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{% - \ifx\@empty#2\@empty\def\@xs@reserved@A{0X}\else\def\@xs@reserved@A{0#2}\fi + \ifx\@empty#2\@empty + \def\@xs@reserved@A{0X}% + \else + \def\@xs@reserved@A{0#2}% + \fi \afterassignment\@xs@defafterinteger\decimalpart\@xs@reserved@A\relax\@xs@nil - \expandafter\@xs@endnumber\@xs@afterinteger\@xs@nil} + \expandafter\@xs@endnumber\@xs@afterinteger\@xs@nil +} \def\@xs@endnumber#1\@xs@nil{\def\@xs@afterdecimal{#1}} % test d'\'egalit\'e sur des chaines (et des chaines contenant des nombres) @@ -621,9 +696,16 @@ \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\'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 + {\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 \'egaux \def\@xs@reserved@A{#1}\def\@xs@reserved@B{#2}% @@ -632,20 +714,31 @@ \else \expandafter\expandafter\expandafter\@xs@reserved@D\expandafter\expandafter\expandafter{\expandafter\@xs@reserved@A\expandafter}\expandafter{\@xs@reserved@B}% \fi - \@xs@reserved@A} + \@xs@reserved@A +} \@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@TestEqual{#1}{#2}% +} \@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}} - -\def\IfStrEqCase{\@ifstar{\def\@xs@reserved@E{\IfStrEq*}\@xs@IfStrCase}{\def\@xs@reserved@E{\IfStrEq}\@xs@IfStrCase}} + \@xs@TestEqual{#1}{#2}% +} + +\def\IfStrEqCase{% + \@ifstar + {\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{\@ifstar{\def\@xs@reserved@E{\IfEq*}\@xs@IfEqCase}{\def\@xs@reserved@E{\IfEq}\@xs@IfEqCase}} +\def\IfEqCase{% + \@ifstar + {\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]{% @@ -658,18 +751,23 @@ \else \def\@xs@next{\@xs@testcase##3\@xs@nil}% sinon, on recommence avec ce qui reste \fi - \@xs@next}}% - \@xs@testcase#2\@xs@nil} + \@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 +% Renvoie ce qui est \`a gauche de l'occurence n°#1 de la sous chaine #3 dans la chaine #2 \@xs@newmacro*3\StrBefore{1}{2}{1}{% \@xs@cutafteroccur{#2}{#3}{#1}% - \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#4}} + \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#4}% +} % 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}} + \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 @@ -682,7 +780,8 @@ \expandafter \endgroup \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@E}{#6}% - \let\groupID\@empty} + \let\groupID\@empty +} \def\exploregroups{\let\@xs@exploregroups\relax} \def\noexploregroups{\def\@xs@exploregroups{\let\@xs@toks0\relax}} @@ -698,7 +797,8 @@ \def\@xs@atendofgroup{% \expandafter\endgroup \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\expandafter{\@xs@reserved@C}}% - \@xs@read@reserved@D}% + \@xs@read@reserved@D + }% \def\@xs@atoccurfound{% \ifnum#1<\@ne \let\@xs@reserved@A\@xs@argument@D @@ -710,14 +810,16 @@ \fi \fi \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\@xs@reserved@A}% - \@xs@read@reserved@D}% + \@xs@read@reserved@D + }% \@xs@testempty{#3}% \if@xs@empty \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@D}{#5}% \else \@xs@read@reserved@D \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#5}% - \fi} + \fi +} % Supprime les #1 premi\`eres occurrences de #3 dans #2 \@xs@newmacro\StrDel{0}{2}{1}{\@xs@StrSubstitute[#1]{#2}{#3}{}[#4]} @@ -734,7 +836,8 @@ \def\@xs@atendofgroup{\endgroup\@xs@read@reserved@C}% \let\@xs@atnextsyntaxunit\relax \@xs@read@reserved@C - \expandafter\@xs@ReturnResult\expandafter{\number\decimalpart}{#2}} + \expandafter\@xs@ReturnResult\expandafter{\number\decimalpart}{#2}% +} % Macro interne fermant autant de groupes que n\'ecessaire pour trouver une unit\'e syntaxique derri\`ere \def\@xs@continuetonext{% @@ -744,7 +847,8 @@ \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 +}% \def\@xs@manage@groupID{% \begingroup\def\@xs@reserved@A{0}% @@ -752,10 +856,15 @@ \endgroup\edef\groupID{\number\integerpart}% on met simplement le niveau \else \endgroup\expandafter\@xs@addtomacro\expandafter\groupID\expandafter{\expandafter,\number\integerpart}% - \fi} + \fi +} % 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}} +\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 @@ -766,7 +875,8 @@ \def\@xs@atendofgroup{% \expandafter\endgroup \expandafter\@xs@addtomacro\expandafter\@xs@reserved@B\expandafter{\expandafter{\@xs@reserved@B}}% - \@xs@read@reserved@C}% + \@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}% @@ -777,11 +887,67 @@ \global\let\groupID\groupID \@xs@exitallgroups \let\@xs@next\relax - \fi}% + \fi + }% \@xs@read@reserved@C - \fi} + \fi +} \def\@xs@StrSplit@ii#1#2{\let#1\@xs@reserved@B\let#2\@xs@reserved@C} +% StrCut[n]{<texte>}{<motif>}\macroA\macroB +% \macroA reçoit ce qui se trouve avant la n ème occurrence <motif> dans <texte> +% \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 + \let\@xs@reserved@C\@empty + \let\@xs@reserved@E\@empty + } + {\ifnum#1<\@ne\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi + {\@xs@StrCut@ii{#2}{#3}1} + {\@xs@StrCut@ii{#2}{#3}{#1}}% + }% + \@xs@StrCut@iii +} + +\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}% + \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\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 + \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\@xs@reserved@E}% + \let\@xs@next\@xs@read@reserved@D + \fi + }% + \@xs@read@reserved@D + \def\@xs@argument@A{#2}% + \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}% +} + +\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 ! \@xs@newmacro\StrMid{}{3}{1}{% @@ -794,33 +960,38 @@ \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} + \let\groupID\@empty +} % supprime #2 unit\'es syntaxiques \`a gauche dans la chaine #1 \@xs@newmacro\StrGobbleLeft{}{2}{1}{% \let\@xs@reserved@E\relax \@xs@StrSplit@i{#2}{#1}% - \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#3}} + \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#3}% +} % extrait de #1 la chaine \`a gauche de longueur #2 \@xs@newmacro\StrLeft{}{2}{1}{% \let\@xs@reserved@E\relax \@xs@StrSplit@i{#2}{#1}% - \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@B}{#3}} + \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@B}{#3}% +} % supprime #2 unit\'es syntaxiques \`a droite dans la chaine #1 \@xs@newmacro\StrGobbleRight{}{2}{1}{% \@xs@StrLen{#1}[\@xs@reserved@D]% \let\@xs@reserved@E\relax \expandafter\@xs@StrSplit@i\expandafter{\number\numexpr\@xs@reserved@D-#2}{#1}% - \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@B}{#3}} + \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@B}{#3}% +} % renvoie #2 unit\'es syntaxiques \`a la droite de la chaine #1 \@xs@newmacro\StrRight{}{2}{1}{% \@xs@StrLen{#1}[\@xs@reserved@D]% \let\@xs@reserved@E\relax \expandafter\@xs@StrSplit@i\expandafter{\number\numexpr\@xs@reserved@D-#2}{#1}% - \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#3}} + \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@C}{#3}% +} \@xs@newmacro\StrChar{}{2}{1}{% \let\@xs@reserved@B\@empty @@ -835,12 +1006,14 @@ \global\let\groupID\groupID \@xs@exitallgroups \let\@xs@next\relax - \fi}% + \fi + }% \@xs@read@reserved@C \fi \expandafter\@xs@testempty\expandafter{\@xs@reserved@B}% \if@xs@empty\let\groupID\@empty\fi - \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@B}{#3}} + \expandafter\@xs@ReturnResult\expandafter{\@xs@reserved@B}{#3}% +} % Combien de fois compte t-on #2 dans #1 ? \@xs@newmacro\StrCount{}{2}{1}{% @@ -853,11 +1026,13 @@ \def\@xs@atendofgroup{% \expandafter\endgroup \expandafter\@xs@addtomacro\expandafter\@xs@reserved@C\expandafter{\expandafter{\@xs@reserved@C}}% - \@xs@read@reserved@D}% + \@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\decimalpart}{#3}% - \fi} + \fi +} % renvoie la position de l'occurrence #1 de la sous chaine #3 dans la chaine #2 \@xs@newmacro\StrPosition{1}{2}{1}{% @@ -870,7 +1045,8 @@ \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} + \let\groupID\@xs@reserved@E +} \def\comparestrict{\let\@xs@comparecoeff\@ne} \def\comparenormal{\let\@xs@comparecoeff\z@} @@ -887,7 +1063,8 @@ \else \def\@xs@next{\@xs@StrCompare@i{#1}{#2}{#3}}% \expandafter\@xs@next - \fi} + \fi +} \def\@xs@StrCompare@i#1#2#3{% \def\@xs@StrCompare@iii##1{% @@ -903,7 +1080,9 @@ \fi \def\@xs@next{% \expandafter\@xs@ReturnResult\expandafter - {\number\numexpr##1\@xs@reserved@A\relax}{#3}}}% + {\number\numexpr##1\@xs@reserved@A\relax}{#3}% + }% + }% \def\@xs@StrCompare@ii##1{% ##1 est la position \expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@C}\@xs@reserved@A \expandafter\@xs@returnfirstsyntaxunit\expandafter{\@xs@reserved@D}\@xs@reserved@B @@ -919,9 +1098,11 @@ \else% les 2 unit\'es syntaxiques sont diff\'erentes : on renvoie la position \@xs@StrCompare@iii{##1}% \fi - \@xs@next}% + \@xs@next + }% \def\@xs@reserved@C{#1}\def\@xs@reserved@D{#2}% - \@xs@StrCompare@ii1} + \@xs@StrCompare@ii1% +} \@xs@newmacro\StrFindGroup{}{2}{1}{% \def\@xs@reserved@A{#2}\def\@xs@reserved@B{0}% @@ -930,7 +1111,9 @@ \else \def\@xs@next{\@xs@StrFindGroup@i{#1}{#2}[#3]}% \fi - \@xs@next} + \@xs@next +} + \def\@xs@StrFindGroup@i#1#2[#3]{% \def\@xs@StrFindGroup@ii{% \expandafter\@xs@testempty\expandafter{\@xs@reserved@C}% @@ -956,16 +1139,19 @@ \let\@xs@next\@xs@StrFindGroup@ii \fi \fi - \@xs@next}% + \@xs@next + }% \@xs@extractgroupnumber{#2}\@xs@reserved@A\@xs@reserved@B \decimalpart\z@ \ifnum\@xs@reserved@A>\z@\def\@xs@reserved@C{#1}\else\let\@xs@reserved@C\@empty\fi - \@xs@StrFindGroup@ii} + \@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} + \ifx\@empty#3\else\@xs@extractgroupnumber@i#1\@xs@nil\fi +} \def\expandingroups{\let\@xs@expandingroups\exploregroups} \def\noexpandingroups{\let\@xs@expandingroups\noexploregroups} @@ -979,12 +1165,14 @@ \def\@xs@atendofgroup{% \expandafter\endgroup \expandafter\@xs@addtomacro\expandafter\@xs@reserved@B\expandafter{\expandafter{\@xs@reserved@B}}% - \@xs@read@reserved@C}% + \@xs@read@reserved@C + }% \def\@xs@atbegingroup{\let\@xs@reserved@B\@empty}% \def\@xs@atnextsyntaxunit{% \expandafter\expandafter\expandafter\@xs@addtomacro \expandafter\expandafter\expandafter\@xs@reserved@B - \expandafter\expandafter\expandafter{\@xs@reserved@A}}% + \expandafter\expandafter\expandafter{\@xs@reserved@A}% + }% \def\@xs@reserved@C{#2}% \@xs@StrExpand@i{#1}% Appel de la macro r\'ecursive \else @@ -993,7 +1181,9 @@ \global\let\@xs@reserved@B\@xs@reserved@B \endgroup \let#3\@xs@reserved@B - \let\groupID\@empty} + \let\groupID\@empty +} + \def\@xs@StrExpand@i#1{% \ifnum#1>\z@ \let\@xs@reserved@B\@empty @@ -1003,12 +1193,14 @@ \else \let\@xs@reserved@A\relax \fi - \@xs@reserved@A} + \@xs@reserved@A +} \def\scancs{\@testopt{\@xs@scancs}{1}} \def\@xs@scancs[#1]#2#3{% \@xs@StrExpand[#1]{#3}{#2}% - \edef#2{\detokenize\expandafter{#2}}} + \edef#2{\detokenize\expandafter{#2}}% +} % Restaure le code de @ \catcode`\@=\CurrentAtCatcode\relax @@ -1163,4 +1355,13 @@ % - \xs@formatnumber ne detokenize plus ses arguments (que m'est-il pass\'e % par la t\^ete pour que je code un truc comme ca ?), et donc % \@xs@afterinteger et \@xs@afterdecimal ont des tokens ayant le bon -% catcode
\ No newline at end of file +% catcode +%------------------------------------------------------------------------------ +% v1.6 24/10/2012 +% - Correction d'un bug dans \@xs@cutafteroccur au cas o\`u #3<1 +% - \IfDecimal ne \detokenize plus l'argument. +% - Nouvelle version de \tokenize qui enlevait les accolades si son argument +% \'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 |