%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                                                                          %%
%%                        Codes donn�s dans le livre                        %%
%%                    � Apprendre � programmer en TeX �                     %%
%%                                                                          %%
%%                           Encodage ISO 8859-1                            %%
%%                                   _____                                  %%
%%                                                                          %%
%%                     � 2014-2020 Christian Tellechea                      %%
%%                                                                          %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Les codes et les macros comment�s donn�s dans ce fichier sont diffus�s sous
% la licence LaTeX project public license (LPPL) 1.2
%
% https://www.latex-project.org/lppl/lppl-1-2/
% https://www.latex-project.org/lppl/lppl-1-2.txt
%
% Attention : ce fichier n'a pas vocation � �tre compil�
\endinput


****************** Code 1 ******************
Voici le code en \TeX{} du premier exemple.% ceci est un commentaire

On peut observer l'affichage qu'il produit juste au-dessous !
****************** Fin code ******************


****************** Code 2 ******************
3 tailles : $% entre en mode math�matique (espaces ignor�s)
1^{2^3}% 2 est en taille "\scriptstyle" et 3 en taille "\scriptscriptstyle"
$% fin du mode math

normal $1$, petit $\scriptstyle 2$, tr�s petit $\scriptscriptstyle 3$.
****************** Fin code ******************


****************** Code 3 ******************
%%% comportement normal %%%
a) comportement normal :
Ligne 1
Ligne 2

Ligne 3
\medbreak
b) Aucun caract�re de fin de ligne :
%%% aucune insertion en fin de ligne %%%
\endlinechar=-1
Ligne 1
Ligne 2

Ligne 3\endlinechar13

\medbreak
c) "X" comme caract�re de fin de ligne :
%%% "X" est ins�r� � chaque fin de ligne
\endlinechar=88
Ligne 1
Ligne 2

Ligne 3
****************** Fin code ******************


****************** Code 4 ******************
a) \number"1A \qquad b) \number"AB3FE \qquad c) \number"78
****************** Fin code ******************


****************** Code 5 ******************
a) \number'15 \qquad b) \number'674 \qquad c) \number'46
****************** Fin code ******************


****************** Code 6 ******************
a) \number`\a \quad %code de caract�re de "a"
b) \number`\\ \quad % code de caract�re de "\"
c) \number`\$ \quad % code de caract�re de "$"
d) \number`\  \quad % code de caract�re de l'espace
e) \number`\5 \quad % code de caract�re de "5"
f) \number`\{ \quad % code de caract�re de l'accolade ouvrante
g) \number`\}       % code de caract�re de accolade fermante
****************** Fin code ******************


****************** Code 7 ******************
a) \number\catcode`\a \quad %code de cat�gorie de "a"
b) \number\catcode`\\ \quad % code de cat�gorie de "\"
c) \number\catcode`\$ \quad % code de cat�gorie de "$"
d) \number\catcode`\  \quad % code de cat�gorie de l'espace
e) \number\catcode`\5 \quad % code de cat�gorie de "5"
f) \number\catcode`\{ \quad % code de cat�gorie de l'accolade ouvrante
g) \number\catcode`\}       % code de cat�gorie de accolade fermante
****************** Fin code ******************


****************** Code 8 ******************
Ici, W est une lettre...\par
\catcode`\W=3 % W devient le signe de bascule en mode math
Wx+y=3W\par
$a+b=cW\par
W2^3=8$\par
\catcode`\W=11 % W redevient une lettre
De nouveau, W est une lettre...
****************** Fin code ******************


****************** Code 9 ******************
$3+4=7$ \par % $ est la bascule math
\catcode`\$=12 % $ devient un caract�re affichable
$ s'affiche sans probl�me : $\par
\catcode`\$=3 % $ redevient la bascule math
$4+3=7$
****************** Fin code ******************


****************** Code 10 ******************
Voici les premiers mots de chaque ligne :

\catcode`\ =5 % l'espace est d�ormais de catcode 5
Cette premi�re ligne sera tronqu�e...

La deuxi�me aussi !

Et la derni�re �galement.
\catcode`\ =10 % l'espace reprend son catcode

Le comportement normal est restaur�.
****************** Fin code ******************


****************** Code 11 ******************
\def\foo{Bonjour}% d�finit le texte de remplacement de \foo
a) \foo Alice.\qquad% espace ignor�
b) {\foo} Bob.\qquad% espace non ignor�
c) \foo{} Chris.\qquad% espace non ignor�
d) \foo\space Daniel.% \space est remplac� par un espace
****************** Fin code ******************


****************** Code 12 ******************
\def\startbold{\begingroup \bf}
\def\stopbold{\endgroup}
Voici \startbold du texte en gras\stopbold{} et la suite.
****************** Fin code ******************


****************** Code 13 ******************
\def\foo{foo}
\begingroup A\aftergroup\foo B\endgroup\par
{A\aftergroup X\aftergroup\foo B}
****************** Fin code ******************


****************** Code 14 ******************
1) (un {\it cheval})\par% sans correction d'italique
2) (un {\it\aftergroup\/cheval})\par% avec correction d'italique
% on peut d�finir une macro \itacorr qui effectue automatiquement la correction
\def\itacorr{\it\aftergroup\/}
3) (un {\itacorr cheval})% avec correction d'italique
****************** Fin code ******************


****************** Code 15 ******************
\def\bar{Je suis bar.}
\let\foo\bar % \foo devient �gal � \bar
\def\bar{ABC}% \bar est red�finie
\foo\par% affiche "Je suis bar"
\bar% affiche "ABC"
****************** Fin code ******************


****************** Code 16 ******************
Initialement, c'est \TeX.\par
\let\TeXsauve\TeX% sauvegarde
\def\TeX{tEx}% red�finition
Ici, on a modifi� \TeX.\par
\let\TeX\TeXsauve% retauration
De nouveau, c'est \TeX.
****************** Fin code ******************


****************** Code 17 ******************
\let\sptoken=  %2 espaces avant le "%"

La commande \sptoken compose le paragraphe
****************** Fin code ******************


****************** Code 18 ******************
{% d�but du groupe
\catcode`\W=13 \def W{wagons}
Les W constituent le train.
}% fin du groupe
****************** Fin code ******************


****************** Code 19 ******************
\begingroup \catcode`\W=13
\gdef\actiw{%
       \catcode`\W=13
       \def W{wagons}}
\endgroup
a) Les trains ne sont pas constitu�s de W !\par
b) \begingroup\actiw Ici, les W forment les trains.\endgroup\par
c) Ici, les W sont redevenus des lettres.
****************** Fin code ******************


****************** Code 20 ******************
\begingroup
       \catcode`\ =13 % rend l'espace actif
       \gdef\>{\begingroup
               \catcode`\ =13
               \def {\hskip5mm\relax}}
\endgroup
\let\<=\endgroup
a) Du texte normal\par
b) \>Des mots tr�s espac�s\<\par
c) Du texte normal
****************** Fin code ******************


****************** Code 21 ******************
\begingroup
       \catcode`\,=13 \def,{\unskip\string,\space\ignorespaces}
       La rue assourdissante autour de moi hurlait.

       Longue , mince,en grand deuil  ,  douleur majestueuse ,

       Une femme passa   ,d'une main fastueuse

       Soulevant,balan�ant le feston et l'ourlet ;

\endgroup\medbreak\hfill Charles {\sc Baudelaire}
****************** Fin code ******************


****************** Code 22 ******************
\begingroup
       \catcode`\,=13 \def,{\unskip\string, \ignorespaces}
       \catcode`\^^M=13 \let ^^M\par % rend le retour charriot �gal � \par
       La rue assourdissante autour de moi hurlait.
       Longue , mince,en grand deuil  , douleur majestueuse ,
       Une femme passa   ,   d'une main fastueuse
       Soulevant,balan�ant le feston et l'ourlet ;
\endgroup\medbreak\hfill Charles {\sc Baudelaire}
****************** Fin code ******************


****************** Code 23 ******************
{% ouvre un groupe
       \let\AA=a \let\EE=e \let\II=i \let\OO=o \let\UU=u \let\YY=y
       % sauvegarder avant de modifier le catcode de a et e :
       \let\lEt=\let \let\cAtcOdE=\catcode
       \cAtcOdE`\a=13 \lEt a=\EE \cAtcOdE`\e=13 \lEt e=\II
       \cAtcOdE`\i=13 \lEt i=\OO \cAtcOdE`\o=13 \lEt o=\UU
       \cAtcOdE`\u=13 \lEt u=\YY \cAtcOdE`\y=13 \lEt y=\AA
       Ce texte devenu \`a peine reconnaissable montre que le r\'esultat
       contient des sonorit\'es catalanes, corses ou grecques assez
       inattendues.
}% ferme le groupe
****************** Fin code ******************


****************** Code 24 ******************
{%
       \let\AA=a \let\lEt=\let \let~=\catcode
       ~`a=13 \lEt a=e ~`e=13 \lEt e=i ~`i=13 \lEt i=o
       ~`o=13 \lEt o=u ~`u=13 \lEt u=y ~`y=13 \lEt y=\AA
       Ce texte devenu \`a peine reconnaissable...
}
****************** Fin code ******************


****************** Code 25 ******************
a) \def\foo{Bonjour}\meaning\foo\par
b) \let\bar=\foo\meaning\bar\par% \foo est "copi�e" vers \bar
c) \def\baz{\foo}\meaning\baz\par
d) \catcode`\W=13 \def W{Wagons}% W est un caract�re actif
  \meaning W\par
e) \meaning\def% \def est une primitive
****************** Fin code ******************


****************** Code 26 ******************
a) \def\foo{

}Signification de \string\foo{} : \meaning\foo

b) Signification de deux retours charriots cons�cutifs : \meaning

****************** Fin code ******************


****************** Code 27 ******************
a) \meaning\relax\par% primitive
b) \meaning {\par% catcode 1
c) \meaning }\par% catcode 2
d) \meaning $\par% catcode 3
e) \meaning &\par% catcode 4
g) \meaning #\par% catcode 6
h) \meaning ^\par% catcode 7
i) \meaning _\par% catcode 8
j) \meaning a\par% catcode 11 (une lettre)
k) \meaning +\par% catcode 12 (caract�re "autre")
l) \meaning ~\par% catcode 13 (caract�re actif)
****************** Fin code ******************


****************** Code 28 ******************
\begingroup% dans un groupe
       \let\*=\meaning% rendre \* �gal � \meaning
       \* %<- espace pris en compte
\endgroup% fermer le groupe
****************** Fin code ******************


****************** Code 29 ******************
\begingroup
\catcode`\*0
\catcode`\\12 % \ n'est plus un caract�re d'�chappement
*def*foo{bar}
*LaTeX{} et la macro *string*foo : *foo.

L'ancien caract�re d'�chappement  "\" et \TeX.
*endgroup
****************** Fin code ******************


****************** Code 30 ******************
\def\foo{\bar}
\begingroup
a) \escapechar=-1  \meaning\foo\qquad% pas de caract�re d'�chappement
b) \escapechar=`\@ \meaning\foo\qquad% "@" est le caract�re d'�chappement
\endgroup
c) \meaning\foo% caract�re d'�chappement par d�faut
****************** Fin code ******************


****************** Code 31 ******************
\begingroup
       \catcode`\|=0 |catcode`|\=11 |catcode`|2=11 |catcode`|1=11
       |gdef|1\2\a{foo}
|endgroup
Voici la macro : \csname 1\string\2\string\a\endcsname
****************** Fin code ******************


****************** Code 32 ******************
\newtoks\foo% allocation d'un nouveau registre
\foo={Bonjour le monde}% assignation
Contenu du registre {\tt\string\foo} : \the\foo.

\newtoks\bar% allocation d'un autre registre
\bar=\foo% assigne � \bar les tokens du registre \foo
Contenu du registre {\tt\string\bar} : \the\bar.
****************** Fin code ******************


****************** Code 33 ******************
\def\hello#1#2{Bonjour #1 et #2.\par}% d�finition
\hello ab% #1=a et #2=b
\hello a b% #1=a et #2=b
\hello{foo}{bar}% #1=foo et #2=bar
\hello foobar% #1=f et #2=o
% (le reste "obar" est lu apr�s que la macro est termin�e)
****************** Fin code ******************


****************** Code 34 ******************
\def\tenlist#1#2#3#4#5#6#7#8#9{(#1,#2,#3,#4,#5,#6,#7,#8,#9\endlist}
\def\endlist#1{,#1)}
Une liste \tenlist abcdefghij de lettres.
****************** Fin code ******************


****************** Code 35 ******************
\def\foo#1#2{Bonjour #1 et #2.\par}
\begingroup\tt% passer en fonte � chasse fixe
a) \foo{monsieur}{madame}
b) \foo{{\bf toi}}{moi}
c) \foo{}{{}}
d) \foo{ }{ }
e) \foo{$\pi$} {$\delta$}
f) \foo ab
g) \foo X       Y
\endgroup% fin de la fonte � chasse fixe
****************** Fin code ******************


****************** Code 36 ******************
\def\foo{Programmer  en \TeX {} est   facile}
\meaning\foo\par
\def\foo{Program^^6der en   \TeX{} est facile}
\meaning\foo
****************** Fin code ******************


****************** Code 37 ******************
a) \gobone XY - \secondoftwo XY\par
b) \gobone{ab}{xy} - \secondoftwo{ab}{xy}\par
c) \gobone{123}4 - \secondoftwo{123}4\par
d) \gobone A{BCD} - \secondoftwo A{BCD}
****************** Fin code ******************


****************** Code 38 ******************
\gobone     {a}{\catcode`\~12 Le <<~>> est un espace ?} Et ici <<~>> ?

\secondoftwo{a}{\catcode`\~12 Le <<~>> est un espace ?} Et ici <<~>> ?
****************** Fin code ******************


****************** Code 39 ******************
\def\visible{\let\choix=\firstoftwo}
\def\cache{\let\choix=\secondoftwo}
\def\?#1{\choix{#1}{...}}%
\def\interro{J'ai �t\?{�} invit\?{�} � gout\?{er} chez Max. Apr�s s'�tre
            bien amus\?{�}, nous avons rang\?{�} et il a fallu rentr\?{er}.}
Compl�ter avec << � >> ou << er >> :\par
\cache\interro\par\medskip
Correction :\par
\visible\interro
****************** Fin code ******************


****************** Code 40 ******************
\def\visible{\let\?=\identity}
\def\cache{\def\?##1{...}}
\def\interro{J'ai �t\?{�} invit\?{�} � go�t\?{er} chez Max. On s'est
            bien amus\?{�} et ensuite, il a fallu rentr\?{er}.}
Compl�ter avec << � >> ou << er >> :\par
\cache\interro\par\medskip
Correction :\par
\visible\interro
****************** Fin code ******************


****************** Code 41 ******************
\def\makemacro#1#2{\def#1##1{##1 #2}}
\makemacro\LL{Lamport}
\makemacro\juin{juin 2014}
Paris, le \juin{3}.\medbreak
\LL{Cher Monsieur},\smallbreak
Vous �tes convoqu� � un examen sur \TeX{} le \juin{21} �
9h00 pr�cise dans le bureau de D. Knuth.\smallbreak
Veuillez croire, \LL{Monsieur}, en mes sentiments \TeX iens.
****************** Fin code ******************


****************** Code 42 ******************
\def\showcodes#1{\string#1 : $\number`#1 \rightarrow \number\lccode`#1$}
\showcodes A\qquad \showcodes B\qquad
\showcodes a\qquad \showcodes b\qquad \showcodes ^
****************** Fin code ******************


****************** Code 43 ******************
\lowercase{CACAO foobar}\par
\lowercase{\def\foo{Bonjour}}% d�finit une commande \foo
\foo % la commande d�finie pr�c�demment
****************** Fin code ******************


****************** Code 44 ******************
\begingroup
       \lccode`A=`* % change le code minuscule de A
       \lowercase{CACAO ABRACADABRA}\par
\endgroup
\lowercase{CACAO ABRACADABRA}
****************** Fin code ******************


****************** Code 45 ******************
\def\defactive#1{%
       \catcode`#1=13
       \begingroup
       \lccode`~=`#1
       \lowercase{\endgroup\def~}%
}
\begingroup% les modifications restent locales
       \defactive W{wagons}% d�finit le caract�re actif "W"
       Les W constituent les trains.
\endgroup %fermeture du groupe, "W" redevient une lettre
\par Les W sont des lettres
****************** Fin code ******************


****************** Code 46 ******************
\defactive W{wagon}
1) Les W constituent le train.\par
2) \catcode`W=11 Les W sont des lettres.\par
3) \catcode`\W=13 Les W constituent-ils le train ?
****************** Fin code ******************


****************** Code 47 ******************
\def\defactive#1#2{%
       \catcode`#1=13 % #1 sera actif apr�s la fin du texte de remplacement
       \begingroup
       \lccode`~=`#1  % dans \lowercase, changer les ~ (actifs) en "#1", ceux-ci �tant actifs
       \lowercase{\endgroup\def~}{#2}%
       }
\defactive W{Wagon}
Un W.
****************** Fin code ******************


****************** Code 48 ******************
\def\defactive#1{%
       \catcode`#1=13 % #1 sera actif apr�s la fin du texte de remplacement
       \begingroup
       \lccode`~=`#1 % dans \lowercase, changer les ~ (actifs) en "#1", ceux-ci �tant actifs
       \lowercase{\endgroup\def~}%
       }
\defactive W{Wagon}
Un W.
****************** Fin code ******************


****************** Code 49 ******************
\def\defactive#1#2{%
       \catcode`#1=13 % #1 sera actif apr�s la fin du texte de remplacement
       \begingroup
       \uccode`~=`#1 % dans \uppercase, changer les ~ (actifs) en "#1", ceux-ci �tant actifs
       \uppercase{\endgroup\def~}{#2}%
}
\defactive W{Wagon}
Un W.
****************** Fin code ******************


****************** Code 50 ******************
\def\letactive#1{%
       \catcode`#1=13 % #1 sera actif apr�s la fin du texte de remplacement
       \begingroup
       \uccode`~=`#1 % dans \uppercase, changer les ~ (actifs) en "#1", ceux-ci �tant actifs
       \uppercase{\endgroup\let~}%
}
\def\W{wagon}%
\letactive X\W
Un X.
****************** Fin code ******************


****************** Code 51 ******************
\def\litterate#1{% #1=lit le token fronti�re choisi
       \begingroup% ouvre un groupe pour y faire les modifications
               \def\do##1{\catcode`##1=12 }% \do change le catcode de son argument � 12
               \dospecials% rend inoffensifs tous les tokens sp�ciaux
               \defactive\^^M{\leavevmode\par}% d�finit le retour charriot
               \letactive#1\endgroup% d�finit #1 qui sera un \endgroup
               \tt% passe en fonte � chasse fixe
}
essai 1 : \litterate*\foo # #34{ } &_\ *
\medbreak
essai 2 : \litterate/une premi�re ligne  ,, >>

un saut de ligne et la seconde --/
****************** Fin code ******************


****************** Code 52 ******************
\def\litterate#1{% #1=lit le token fronti�re choisi
       \begingroup% ouvre un groupe pour y faire les modifications
               \def\do##1{\catcode`##1=12 }% \do change le catcode de son argument � 12
               \dospecials% rend inoffensifs tous les tokens sp�ciaux
               \defactive\^^M{\leavevmode\par}% d�finit le retour charriot
               \defactive\ {\ }% l'espace est actif et devient "\ "
               \defactive<{\string<{}}\defactive>{\string>{}}% emp�che
               \defactive-{\string-{}}\defactive`{\string`{}}% les
               \defactive,{\string,{}}\defactive'{\string'{}}% ligatures
               \letactive#1\endgroup% #1 sera un \endgroup
               \tt% passe en fonte � chasse fixe
}
essai 1 : \litterate*\foo # #34{ %} &_\ *
\medbreak
essai 2 : \litterate/une premi�re      ligne  ,, >>

un saut de ligne et la seconde --/
****************** Fin code ******************


****************** Code 53 ******************
\def\baz#1#2#3#{"#1", puis "#2" et enfin "#3".}
\baz{abc}def{gh}ij
****************** Fin code ******************


****************** Code 54 ******************
\catcode`\@11
\long\def\firstto@nil#1#2\@nil{#1}
\long\def\remainto@nil#1#2\@nil{#2}
a) \firstto@nil foobar\@nil   \qquad b) \remainto@nil foobar\@nil  \par
c) \firstto@nil {foo}bar\@nil \qquad d) \remainto@nil {foo}bar\@nil
****************** Fin code ******************


****************** Code 55 ******************
\catcode`\@=11 % "@" devient une lettre
\def\rightof#1#2{%
       \def\right@of##1#2##2\@nil{##2}% d�finit la macro auxiliaire
       \right@of#1\@nil% appelle la macro auxiliaire o� #1 est la <chaine>
}
\catcode`\@=12 %"@" redevient un signe
--\rightof{Programmation}{g}--\par
--\rightof{Programmation}{gram}--\par
--\rightof{Programmation}{on}--
****************** Fin code ******************


****************** Code 56 ******************
\catcode`\@=11 % "@" devient une lettre
\def\rightof#1#2{%
       \def\right@of##1#2##2\@nil{##2}% d�finit la macro auxiliaire
       \right@of#1\@nil% appelle la macro auxiliaire
}
\catcode`\@=12 %"@" redevient un signe
--\rightof{Programmation}{z}--\par
--\rightof{Programmation}{Gram}
****************** Fin code ******************


****************** Code 57 ******************
\catcode`\@=11 % "@" devient une lettre
\def\rightof#1#2{%
       \def\right@of##1#2##2\@nil{##2}% d�finit la macro auxiliaire
       \right@of#1#2\@nil% appelle la macro auxiliaire avec le motif #2
}
\catcode`\@=12 %"@" redevient un signe
--\rightof{Programmation}{g}--\par
--\rightof{Programmation}{ti}--\par
--\rightof{Programmation}{z}--\par
--\rightof{Programmation}{Gram}--
****************** Fin code ******************


****************** Code 58 ******************
\catcode`\@=11 % "@" devient une lettre
\def\gobto@@nil#1\@@nil{}
\def\rightof#1#2{%
       \def\right@of##1#2##2\@nil{##2}% d�finit la macro auxiliaire
       \right@of#1\gobto@@nil#2\gobto@@nil\@@nil\@nil% appelle la macro auxiliaire
}
\catcode`\@=12 %"@" redevient un signe
--\rightof{Programmation}{g}--\par
--\rightof{Programmation}{ti}--\par
--\rightof{Programmation}{z}--\par
--\rightof{Programmation}{Gram}--
****************** Fin code ******************


****************** Code 59 ******************
\catcode`\@=11 % "@" devient une lettre

\def\rightof#1#2{%
       \ifin{#1}{#2}%
               {% si #1 contient le #2
               \def\right@of##1#2##2\@nil{##2}% d�finit la macro auxiliaire
               \right@of#1\@nil% appelle la macro auxiliaire
               }%
               {}% sinon, ne rien faire
}
\catcode`\@=12 %"@" redevient un signe
--\rightof{Programmation}{g}--\par
--\rightof{Programmation}{z}--\par
--\rightof{Programmation}{o}--
****************** Fin code ******************


****************** Code 60 ******************
\catcode`\@=11
\def\leftof#1#2{%
       \def\leftof@i##1#2##2\@nil{##1}% renvoie ce qui est � gauche de #2
       \leftof@i #1#2\@nil% ajoute #2 apr�s #1
}
\catcode`\@=12
--\leftof{Programmation}{ram}--\par
--\leftof{Programmation}{zut}--
****************** Fin code ******************


****************** Code 61 ******************
\catcode`\@=11
\def\leftof#1#2{%
       \def\leftof@i##1#2##2\@nil{\leftof@ii##1#1\@nil}%
       \def\leftof@ii##1#1##2\@nil{##1}%
       \leftof@i #1#2\@nil
}
\catcode`\@=12
--\leftof{Programmation}{ram}--\par
--\leftof{Programmation}{zut}--
****************** Fin code ******************


****************** Code 62 ******************
\catcode`\@=11
\def\rightof#1#2{%
       \def\rightof@i##1#2##2\@nil{\rightof@ii##2#2\@nil}%
       \def\rightof@ii##1#2##2\@nil{##1}%
       \rightof@i#1#2\@nil
}
\catcode`\@=12
--\rightof{Programmation}{g}--\par
--\rightof{Programmation}{z}--
****************** Fin code ******************


****************** Code 63 ******************
\catcode`\@=11
\def\gobto@@nil#1\@@nil{}
\def\rightof#1#2{%
       \def\right@of##1#2##2\@nil{##2}% d�finit la macro auxiliaire
       \right@of#1\gobto@@nil#2\gobto@@nil\@@nil\@nil% appelle la macro auxiliaire
}
\catcode`\@=12
\rightof{abc{1}def}{c{1}d}% affiche ce qui est � droite de "c{1}d"
****************** Fin code ******************


****************** Code 64 ******************
\expandafter\def\csname ab1c\endcsname{Bonjour}
Texte de remplacement de la macro : \csname ab1c\endcsname
****************** Fin code ******************


****************** Code 65 ******************
\def\defname#1{\expandafter\def\csname#1\endcsname}
\defname{ab1c}{Bonjour}
Texte de remplacement de \litterate|\abc1| : \csname ab1c\endcsname\par
\def\letname#1{\expandafter\let\csname#1\endcsname}
\def\foo{abc}\letname{foo1}=\foo% rend la macro "\foo1" �gale � \foo
Texte de remplacement de \litterate|\foo1| : \csname foo1\endcsname
****************** Fin code ******************


****************** Code 66 ******************
\def\foo{Bonjour}\catcode`@=11
R�sultat : \firstto@nil\foo\@nil
\catcode`@=12
****************** Fin code ******************


****************** Code 67 ******************
\def\foo{Bonjour}\catcode`@=11
R�sultat : \expandafter\firstto@nil\foo\@nil
\catcode`@=12
****************** Fin code ******************


****************** Code 68 ******************
\newtoks\testtoks \testtoks={Bonjour}
\catcode`@=11
R�sultat : \expandafter\firstto@nil\the\testtoks\@nil
\catcode`@=12
****************** Fin code ******************


****************** Code 69 ******************
\def\foo{bonjour}
a) \>\csname foo\endcsname< \par
b) \>\foo< \par
c) \expandafter\>\foo< \par
d) \>\foo\foo< \par
e) \expandafter\>\foo\foo<
****************** Fin code ******************


****************** Code 70 ******************
\def\foo{Bonjour} \expandafter\>\expandafter\foo\foo<
****************** Fin code ******************


****************** Code 71 ******************
\def\foo{Bonjour}
\expandafter\def\expandafter\bar\expandafter{\expandafter\foo\foo}
\meaning\bar
****************** Fin code ******************


****************** Code 72 ******************
\def\foo{\foo Bonjour}% d�finition r�cursive
\foo% l'ex�cution provoque un d�passement de la capacit� de la pile
****************** Fin code ******************


****************** Code 73 ******************
\long\def\addtomacro#1#2{%
       \expandafter\def\expandafter#1\expandafter{#1#2}%
}
\def\foo{Bonjour}
\addtomacro\foo{ le monde}
\meaning\foo
****************** Fin code ******************


****************** Code 74 ******************
\long\def\eaddtomacro#1#2{%
       \expandafter\addtomacro\expandafter#1\expandafter{#2}%
}
\def\foo{Bonjour} \def\world{ le monde}
\eaddtomacro\foo\world
\meaning\foo
****************** Fin code ******************


****************** Code 75 ******************
\long\def\addtotoks#1#2{#1= \expandafter{\the#1#2}}
\newtoks\bar
\bar={Bonjour}% met "Bonjour" dans le registre
\addtotoks\bar{ le monde}% ajoute " le monde"
\the\bar% affiche le registre
****************** Fin code ******************


****************** Code 76 ******************
\long\def\eaddtotoks#1#2{\expandafter\addtotoks\expandafter#1\expandafter{#2}}
\bar={Bonjour}
\def\macrofoo{ le monde}
\eaddtotoks\bar\macrofoo
\the\bar
****************** Fin code ******************


****************** Code 77 ******************
\def\X{Bonjour} \def\Y{\X}
\expandafter\expandafter\expandafter\>\Y<
****************** Fin code ******************


****************** Code 78 ******************
\long\def\swaparg#1#2{#2{#1}}
\long\def\expsecond#1#2{\expandafter\swaparg\expandafter{#2}{#1}}
\def\X{Bonjour}
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter
\>\expsecond{\X}{\X}<
****************** Fin code ******************


****************** Code 79 ******************
\expsecond{\def\foo}\secondoftwo{A}{B}
****************** Fin code ******************


****************** Code 80 ******************
\expsecond{\def\foo}{\secondoftwo{A}{B}}
\meaning\foo
****************** Fin code ******************


****************** Code 81 ******************
\def\exptwoargs#1#2{\expsecond{\expsecond{#1}{#2}}}
\def\foo{Bonjour}\def\bar{ le monde}
\def\displaytwoargs#1#2{\detokenize{#1#2}}% affiche tels quels les arguments
\exptwoargs\displaytwoargs\foo\bar
****************** Fin code ******************


****************** Code 82 ******************
\def\aa{Bonjour}\def\bb{\aa}
\def\cc{ le monde}
\edef\foo{\bb\cc}
\meaning\foo
****************** Fin code ******************


****************** Code 83 ******************
\def\aa{Bonjour } \def\bb{\aa} \def\cc{le } \def\dd{ monde}
\edef\ee#1{\bb\cc#1 !!!}
\meaning\ee\par
\expandafter\>\ee{\dd}<
****************** Fin code ******************


****************** Code 84 ******************
\def\foo{123xyz}
a) signification du 1-d�veloppement d'un \litterate-\noexpand- :
  \expandafter\meaning\noexpand\foo

b) ex�cution d'un \litterate-\noexpand- : \noexpand\foo% identique � \relax

c) 1-d�veloppement de \litterate-\noexpand- dans le texte de remplacement de
  \litterate-\bar- :
  \expandafter\def\expandafter\bar\expandafter{\noexpand\foo}
  \meaning\bar
****************** Fin code ******************


****************** Code 85 ******************
\def\aa{Bonjour}\def\bb{\aa}\def\cc{\bb}
a) \edef\foo{\aa\noexpand\bb\cc}\meaning\foo  \qquad b) ex�cution : \foo\par
c) \edef\foo{\aa\noexpand{\aa\cc}}\meaning\foo\qquad d) ex�cution : \foo
****************** Fin code ******************


****************** Code 86 ******************
\def\aa{Bonjour}\def\bb{Au revoir}
a) \edef\truc{\aa\noexpand\bb\noexpand\aa\bb}\meaning\truc \par
b) \edef\truc{\aa\unexpanded{\bb\aa}\bb}\meaning\truc
****************** Fin code ******************


****************** Code 87 ******************
\def\aa{Bonjour}\def\bb{Au revoir}
\toks0={\aa\bb}
\edef\foo{\aa\the\toks0 \bb}
\meaning\foo
****************** Fin code ******************


****************** Code 88 ******************
\def\aa{Bonjour}
\protected\def\bb{ le}% \ bb est prot�g�e !
\def\cc{ monde}

\edef\foo{\aa\bb\cc}
Signification de \string\foo~: \meaning\foo \par
Ex�cution de \string\foo~: \foo
****************** Fin code ******************


****************** Code 89 ******************
\def\aa{Bonjour}
\protected\def\bb{ le}
\def\cc{ monde}

\edef\foo{\expandafter\aa\bb\cc}% le \expandafter 1-d�veloppe \bb
\meaning\foo
****************** Fin code ******************


****************** Code 90 ******************
\def\foo{Bonjour}% d�finition
\foo% ex�cution
****************** Fin code ******************


****************** Code 91 ******************
\def\foo{abc}
\edef\bar{\def\foo{Bonjour}\foo}
\meaning\bar
****************** Fin code ******************


****************** Code 92 ******************
\def\foo{abc}
\edef\bar{\def\noexpand\foo{Bonjour}\noexpand\foo}
Signification : \meaning\bar\par
Ex�cution : \bar
****************** Fin code ******************


****************** Code 93 ******************
\long\def\>#1<{\detokenize{#1}}
\expandafter\>% provoque le 1-d�veloppement de :
\csname foo\expandafter\endcsname
\csname bar\expandafter\endcsname
\csname wee\expandafter\endcsname
\csname fin\endcsname<
****************** Fin code ******************


****************** Code 94 ******************
\long\def\>#1<{\detokenize{#1}}
\def\fin{YY} \def\wee{\weeA} \def\weeA{XX}
\expandafter\>%
\csname foo\expandafter\endcsname
\csname bar\expandafter\expandafter\expandafter\expandafter
          \expandafter\expandafter\expandafter\endcsname
\csname wee\expandafter\expandafter\expandafter\endcsname
\csname fin\endcsname<
****************** Fin code ******************


****************** Code 95 ******************
\long\def\>#1<{\detokenize{#1}}
\def\fin{YYY} \def\wee{\weeA} \def\weeA{XXX}
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter
\>%
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter
\foo
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter
\bar
\expandafter\wee\fin<
****************** Fin code ******************


****************** Code 96 ******************
\chardef\foo65
a) |\foo|\qquad % employ�e seule, \foo affiche un A
b) |\number\foo|\qquad % si TeX lit un nombre, \foo est le nombre 65
****************** Fin code ******************


****************** Code 97 ******************
\mathchardef\foo4944
a) |$\foo$|\qquad % en mode math, affiche le signe "somme" (uniquement en mode maths)
b) |\number\foo|\qquad % si TeX lit un nombre, \foo est 4944
****************** Fin code ******************


****************** Code 98 ******************
a) "\romannumeral 27 "\quad
b) "\romannumeral 4687 "\quad
c) "\romannumeral 0 "\quad% 0 donc d�veloppement vide
d) "\romannumeral -2014 "\quad% n�gatif donc d�veloppement vide
e) \def\foo{7}\def\bar{\foo}%
  "\romannumeral \foo\foo\bar"\quad% 777
f) "\romannumeral 1\bar8\foo"\quad% 1787
g) "\romannumeral 1\bar8 \foo"% 178 (stopp� par l'espace) puis 7
****************** Fin code ******************


****************** Code 99 ******************
\long\def\>#1<{\detokenize{#1}}
\def\swaparg#1#2{#2{#1}}
\def\expsecond#1#2{\expandafter\swaparg\expandafter{#2}{#1}}
\def\X{Bonjour}
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter
\>\expsecond\X\X<
****************** Fin code ******************


****************** Code 100 ******************
\long\def\>#1<{\detokenize{#1}}
\def\swaparg#1#2{0 #2{#1}}% le "0 " stoppe ici le d�veloppement maximal
\def\expsecond#1#2{\expandafter\swaparg\expandafter{#2}{#1}}
\def\X{Bonjour}
\expandafter\>\romannumeral\expsecond\X\X<
****************** Fin code ******************


****************** Code 101 ******************
\long\def\>#1<{\detokenize{#1}}
\def\swaparg#1#2{#2{#1}}
\def\expsecond#1#2{\expandafter\swaparg\expandafter{#2}{#1}}
\def\X{Bonjour}
\expandafter\>\romannumeral\expsecond{0 \X}\X<
****************** Fin code ******************


****************** Code 102 ******************
\long\def\>#1<{\detokenize{#1}}
\def\X{Bonjour}
\catcode`\@=11
\expandafter\>\romannumeral\expsecond{\z@\X}{\X}<
\catcode`\@=12
****************** Fin code ******************


****************** Code 103 ******************
\def\newunivar#1{\def#1[##1]{\csname\string#1[##1]\endcsname}}
\def\defunivar#1[#2]{\defname{\string#1[#2]}}
\newunivar\foobar
\defunivar\foobar[0]{abcd}
\defunivar\foobar[1]{1 23}
\defunivar\foobar[3]{XY Z}
Cellule 0 : \foobar[0]\par
Cellule 1 : \foobar[1]\par
Cellule 2 : \foobar[2]\par% cellule non d�finie : \foobar[2] donne \relax
Cellule 3 : \foobar[3]\bigbreak

\newunivar\client
\defunivar\client[nom]{M. Raymond {\sc  Tartempion}}
\defunivar\client[adr]{5 rue de la paix}
\defunivar\client[cod_post]{75000}
\defunivar\client[ville]{Paris}
% fin des d�finitions, affichage de l'adresse :
\client[nom]\par
\client[adr]\par
\client[cod_post] \client[ville]
****************** Fin code ******************


****************** Code 104 ******************
\newcount\foo \newcount\bar
\foo=42 \bar=\foo \string\bar\ vaut : \the\bar \par
\bar=\foo57 \string\bar\ vaut : \number\bar\par
\bar=2014 \string\bar\ vaut : \romannumeral\bar
****************** Fin code ******************


****************** Code 105 ******************
\newcount\foo
\def\fonction#1{%
 \foo=#1 % assigne l'entier #1 au compteur puis
 \multiply\foo3 % multiplie par 3
 \advance\foo-4 % soustrait 4
 \multiply\foo\foo% �l�ve au carr� (lmultiplie \foo par lui m�me)
 \number\foo% enfin, afficher le r�sultat
}
a) \fonction5\qquad b) \fonction{-13}
****************** Fin code ******************


****************** Code 106 ******************
\newcount\foo
\def\fonction#1{%
 \foo=#1 \multiply\foo3 \advance\foo-4 \multiply\foo\foo
 \number\foo}
\edef\bar{\fonction{5}}%
a) Signification : \meaning\bar\par
b) Ex�cution : \bar
****************** Fin code ******************


****************** Code 107 ******************
a) \number\numexpr2+3*4\relax\qquad
b) \romannumeral\numexpr2*3\relax\qquad
c) \number\numexpr(6-2*4)*(1-(2-6))\relax\qquad
d) \number\numexpr7/4\relax\qquad %7/4 vaut 1,75
e) \edef\foo{\number\numexpr2+3*4\relax}\meaning\foo
****************** Fin code ******************


****************** Code 108 ******************
\number\numexpr3*\numexpr1+2*5\relax+2\relax
****************** Fin code ******************


****************** Code 109 ******************
\def\fonction#1{\number\numexpr(3*#1-4)*(3*#1-4)\relax}
a) \fonction5\qquad
b) \fonction{-13}\qquad
c) \edef\bar{\fonction5}\meaning\bar
****************** Fin code ******************


****************** Code 110 ******************
\def\fonction#1{\exparg\carre{\number\numexpr3*#1-4\relax}}
\def\carre#1{\number\numexpr#1*#1\relax}
a) \fonction{5}\qquad
b) \fonction{-13}\qquad
c) \edef\bar{\fonction5}\meaning\bar
****************** Fin code ******************


****************** Code 111 ******************
\def\truncdiv#1#2{\numexpr(#1-(#2-1)/2)/#2\relax}
8/3 :
a) \number\truncdiv83\qquad      % doit donner 2
b) \number\truncdiv{-8}3\qquad   % doit donner -2
c) \number\truncdiv8{-3}\qquad   % doit donner -2
d) \number\truncdiv{-8}{-3}\par  % doit donner 2
4/3 :
e) \number\truncdiv43\qquad      % doit donner 1
f) \number\truncdiv{-4}3\qquad   % doit donner -1
g) \number\truncdiv4{-3}\qquad   % doit donner -1
h) \number\truncdiv{-4}{-3}      % doit donner 1
****************** Fin code ******************


****************** Code 112 ******************
a) \ifnum 15=14 vrai\else faux\fi\qquad% test faux
b) \ifnum4<200 vrai\else faux\fi\qquad% test vrai
c) \newcount\foo \foo=9
  \ifnum\foo>9 nombre\else chiffre\fi% test faux
****************** Fin code ******************


****************** Code 113 ******************
\long\def\>#1<{\detokenize{#1}}
\expandafter\>\ifnum5=5 vrai\else faux\fi<\par% test vrai
\expandafter\>\ifnum5=6 vrai\else faux\fi<% test faux
\fi\fi% r�tablir l'�quilibre \ifnum et \fi
****************** Fin code ******************


****************** Code 114 ******************
\def\numtest#1{%
       \ifnum#1>-10
               \ifnum#1<10
                       chiffre%
               \else
                       nombre positif%
               \fi
       \else
               nombre n�gatif%
       \fi
}
a) \numtest{3}\qquad
b) \numtest{-67}\qquad
c) \numtest{-8}\qquad
d) \numtest{21}\qquad
e) \edef\foo{\numtest{2014}}\meaning\foo
****************** Fin code ******************


****************** Code 115 ******************
\def\normalise#1{%
       \ifnum#1>-1 % ne faire quelque chose que si #1 est positif ou nul
               \ifnum#1<100 % si <100
                       0% afficher un 0
                       \ifnum#1<10 % si <10
                               0%afficher un autre 0
                       \fi
               \fi
               \number#1 %afficher le nombre
       \fi}% affiche le nombre
a) \normalise{749}\qquad
b) \normalise{0017}\qquad
c) \normalise8\qquad
d) \normalise{1789}\qquad
e) \normalise{-18}\qquad
f) \normalise{0}
****************** Fin code ******************


****************** Code 116 ******************
\def\mois#1{%
       \ifcase#1\relax
           \char`\#\char`\#% afficher "##" si argument = 0
       \or janvier\or f\'evrier\or mars\or avril%
       \or mai\or juin\or juillet\or aout%
       \or septembre\or octobre\or novembre\or d\'ecembre%
       \else
           \char`\#\char`\#% afficher "##" sinon
       \fi
}
a) \mois{-4}\qquad
b) \mois{3}\qquad
c) \mois{11}\qquad
d) \mois{20}\qquad
e) \edef\foo{\mois{\month}}\meaning\foo% mois en cours
****************** Fin code ******************


****************** Code 117 ******************
\def\ifletter#1#2#3{%
       \ifnum`#1<`a% si le caract�re est avant "a"
               #3% ex�cuter "<code faux>"
       \else% sinon
               \ifnum`#1>`z% si le caract�re est apr�s "z"
                       #3% ex�cuter "<code faux>"
               \else% dans tous les autres cas
                       #2% "#1" est une lettre : ex�cuter "<code vrai>"
               \fi
       \fi}
a) \ifletter{4}{vrai}{faux}\qquad
b) \ifletter{t}{vrai}{faux}\qquad
c) \ifletter{D}{vrai}{faux}
****************** Fin code ******************


****************** Code 118 ******************
\def\ifletter#1{%
       \ifnum`#1<`a
               \expandafter\secondoftwo% \expandafter 1-d�veloppe "\else...\fi"
       \else
               \ifnum`#1>`z
                       \expandafter\expandafter\expandafter% 1-d�veloppe "\else...\fi" puis "\fi"
                       \secondoftwo
               \else
                       \expandafter\expandafter\expandafter%1-d�veloppe "\fi" puis "\fi"
                       \firstoftwo
               \fi
       \fi}
a) \ifletter{4}{vrai}{faux}\qquad
b) \ifletter{t}{vrai}{faux}\qquad
c) \ifletter{D}{vrai}{faux}
****************** Fin code ******************


****************** Code 119 ******************
\def\ifletter#1#2#3{%
       \romannumeral % <- initie le d�veloppement maximal
       \ifnum`#1<`a
               \expandafter\secondoftwo
       \else
               \ifnum`#1>`z
                       \expandafter\expandafter\expandafter\secondoftwo
               \else
                       \expandafter\expandafter\expandafter\firstoftwo
               \fi
       \fi{0 #2}{0 #3}% <- "0 " stoppe le d�veloppement maximal
}
\long\def\>#1<{\detokenize{#1}}
a) \expandafter\expandafter\expandafter\>\ifletter{0}{vrai}{faux}<\qquad
b) \expandafter\expandafter\expandafter\>\ifletter{x}{vrai}{faux}<
****************** Fin code ******************


****************** Code 120 ******************
\def\ifletter#1{%
       \ifnum`#1<`a
               \let\donext=\secondoftwo
       \else
               \ifnum`#1>`z
                       \let\donext=\secondoftwo
               \else
                       \let\donext=\firstoftwo
               \fi
       \fi
       \donext% ex�cuter l'action d�cid�e ci-dessus
}
a) \ifletter{4}{vrai}{faux}\qquad
b) \ifletter{t}{vrai}{faux}\qquad
c) \ifletter{D}{vrai}{faux}
****************** Fin code ******************


****************** Code 121 ******************
\def\ifletter#1{%
       \csname
               \ifnum`#1<`a
                       second% <- commenter la fin de ligne pour �viter un
               \else%          espace parasite dans le nom de la macro cr��e
                       \ifnum`#1>`z
                               second%
                       \else
                               first%
                       \fi
               \fi
               oftwo%
       \endcsname
}
a) \ifletter{4}{vrai}{faux}\qquad
b) \ifletter{t}{vrai}{faux}\qquad
c) \ifletter{D}{vrai}{faux}
****************** Fin code ******************


****************** Code 122 ******************
\def\ifletter#1{%
       \lowercase{\csname
               \ifnum`#1<`a second%
               \else
                       \ifnum`#1>`z second\else first\fi
               \fi
       oftwo\endcsname
       }%
}
a) \ifletter{4}{vrai}{faux}\qquad
b) \ifletter{t}{vrai}{faux}\qquad
c) \ifletter{D}{vrai}{faux}
****************** Fin code ******************


****************** Code 123 ******************
\edef\foo{\lowercase{AbCd}}\meaning\foo
****************** Fin code ******************


****************** Code 124 ******************
\def\ifletter#1{%
       \csname
               \ifnum`#1<`A second%
               \else
                       \ifnum`#1<`Z first%
                       \else
                               \ifnum`#1>`a
                                       \ifnum`#1<`z
                                               first%
                                       \else
                                               second%
                                       \fi
                               \else
                                       second%
                               \fi
                       \fi
               \fi
               oftwo%
       \endcsname
}
a) \ifletter{4}{vrai}{faux}\qquad
b) \ifletter{t}{vrai}{faux}\qquad
c) \ifletter{D}{vrai}{faux}\qquad
d) \edef\foo{\ifletter{x}{vrai}{faux}}\meaning\foo\qquad
e) \edef\foo{\ifletter{=}{vrai}{faux}}\meaning\foo
****************** Fin code ******************


****************** Code 125 ******************
\def\ifinside#1[#2,#3]{%
       \csname
               \ifnum#1<#2 second% si n<a, <code faux>
               \else
                       \ifnum#1>#3 second% si n>b, <code faux>
                       \else       first%  sinon, <code vrai>
                       \fi
               \fi
       oftwo%
       \endcsname
}
a) \ifinside 3[1,8]{oui}{non}\qquad
b) \ifinside -7[-20,-11]{oui}{non}\qquad
c) \ifinside 9[0,6]{oui}{non}\qquad
d) \ifinside -1[-5,1]{oui}{non}
****************** Fin code ******************


****************** Code 126 ******************
\def\ifinside#1[#2,#3]{%
       \ifnum\numexpr(#1-#2)*(#1-#3)\relax>0
               \expandafter\secondoftwo
       \else
               \expandafter\firstoftwo
       \fi
}
a) \ifinside 3[1,8]{oui}{non}\qquad
b) \ifinside -7[-20,-11]{oui}{non}\qquad
c) \ifinside 9[0,6]{oui}{non}\qquad
d) \ifinside -1[-5,1]{oui}{non}
****************** Fin code ******************


****************** Code 127 ******************
\def\absval#1{%
       \ifnum#1<0 \number-#1
       \else      \number#1
       \fi}
a) \absval{-87}\qquad b) \absval{75}\qquad c) \absval{0}
****************** Fin code ******************


****************** Code 128 ******************
\def\absval#1{\number\ifnum#1<0 -\fi#1 }
a) \absval{-87}\qquad b) \absval{75}\qquad c) \absval{0}
****************** Fin code ******************


****************** Code 129 ******************
\def\absval#1{\number\ifnum\numexpr#1\relax<0 -\fi\numexpr#1\relax}
a) \absval{-87}\qquad
b) \absval{75}\qquad
c) \absval{0}\qquad
d) \absval{-20+13}\qquad% -7 affich� 7
e) \absval{5-3*(-4)+10-50}% -23 affich� 23
****************** Fin code ******************


****************** Code 130 ******************
\catcode`\@11
\def\absval#1{\exparg\absval@i{\number\numexpr#1\relax}}
\def\absval@i#1{\number\ifnum#1<\z@-\fi#1 }
\catcode`\@12
a) \absval{-87}\qquad
b) \absval{75}\qquad
c) \absval{0}\qquad
d) \absval{-20+13}\qquad% r�sultat -7 qui est affich� 7
e) \absval{5-3*(-4)+10-50}% r�sultat -23 qui est affich� 23
****************** Fin code ******************


****************** Code 131 ******************
\def\sgn#1{\ifnum#1<0 -\fi}
\def\truncdiv#1#2{%
       \numexpr
               \sgn{#1}\sgn{#2}1*% multiplie le quotient ci-dessous par +1 ou -1
               (2*\absval{#1}-\absval{#2}+1)/(2*\absval{#2})
       \relax
}
a) \number\truncdiv{-8}3\qquad
b) \number\truncdiv{-8}{-3}\qquad
c) \number\truncdiv8{-3}\qquad
d) \number\truncdiv{0}{-5}
****************** Fin code ******************


****************** Code 132 ******************
\catcode`\@11
\def\sgn#1{\ifnum#1<\z@-\fi}
\def\truncdiv#1#2{%
       \exptwoargs\truncdiv@i{\number\numexpr#1\relax}{\number\numexpr#2\relax}%
}
\def\truncdiv@i#1#2{%
       \numexpr(2*\sgn{#1}#1-\sgn{#2}#2+1)/(\sgn{#1}2*#2)\relax
}
\catcode`\@12
a) \number\truncdiv{-8}3\qquad
b) \number\truncdiv{-8}{-3}\qquad
c) \number\truncdiv8{-3}\qquad
d) \number\truncdiv{0}{-5}\qquad
e) \number\truncdiv{20+2*3}{4-5*2}% 26/(-6) doit donner -4
****************** Fin code ******************


****************** Code 133 ******************
\def\siecle#1{%
       \unless\ifnum#1=0 % ne faire quelque chose que si #1 diff�rent de 0
               \uppercase\expandafter{\romannumeral\absval{#1}}% chiffres romains majuscules
               \raise 1ex \hbox{e\ifnum\absval{#1}=1 r\fi} si�cle% affiche l'exposant puis "si�cle"
               \ifnum#1<0 {} av. J.-C.\fi% affiche si besoin "av. J.-C."
       \fi
}
a) \siecle{19}\qquad
b) \siecle{-3}\qquad
c) \siecle{1}\qquad
d) \siecle{0}\qquad
e) \siecle{-1}
****************** Fin code ******************


****************** Code 134 ******************
\catcode`\@11
\edef\saved@catcode{\number\catcode`\:}% sauvegarde du catcode de ":"
\catcode`\:12 % ":" est d�sormais un caract�re non actif normal
\def\hdif{%
       \begingroup% ouvrir un groupe semi-simple
               \catcode`\:12 % modifier le catcode de ":"
               \hdif@i% aller lire les deux arguments
}

\def\hdif@i#1#2{% lit les 2 arguments
               \hdif@ii#1-#2\@nil% et les transmet � la macro � argument d�limit�s
}

\def\hdif@ii#1:#2:#3-#4:#5:#6\@nil{%
               %%%%%% calcul des nombres � afficher %%%%%%
               \edef\nb@hrs{\number\numexpr#1-#4\relax}% diff�rence des heures
               \edef\nb@min{\number\numexpr#2-#5\relax}% diff�rence des minutes
               \edef\nb@sec{\number\numexpr#3-#6\relax}% diff�rence des secondes
               \ifnum\nb@sec<\z@ % si la diff�rence des secondes est <0
                       \edef\nb@sec{\number\numexpr\nb@sec+60\relax}% ajouter 60 sec
                       \edef\nb@min{\number\numexpr\nb@min-1\relax}% enlever 1 aux minutes
               \fi
               \ifnum\nb@min<\z@ % si les minutes sont <0
                       \edef\nb@min{\number\numexpr\nb@min+60\relax}% ajouter 60 min
                       \edef\nb@hrs{\number\numexpr\nb@hrs-1\relax}% enlever 1 aux heures
               \fi
               %%%%%% affichage du r�sultat %%%%%%
               \let\inter@space\empty% pas d'espace avant un nombre pour l'instant
               \ifnum\nb@hrs>\z@ % si les heures sont >0
                       \nb@hrs h% afficher les heures et "h"
                       \let\inter@space\space% espace pour plus tard
               \fi
               \ifnum\nb@min>\z@ % si les minutes sont >0
                       \inter@space% afficher une espace �ventuelle
                       \nb@min min% afficher les minutes et "min"
                       \let\inter@space\space
               \fi
               \ifnum\nb@sec>\z@ % si les secondes sont >0
                       \inter@space% afficher une espace �ventuelle
                       \nb@sec s% afficher les secondes et "s"
               \fi
       \endgroup% fermer le groupe ouvert au d�but
}
\catcode`\:=\saved@catcode\relax% restaure le code de cat�gorie de ":"
\catcode`\@12
a) \hdif{10:51:20}{9:20:10}\par
b) \hdif{14:20:0}{13:50:0}\par
c) \hdif{7:50:20}{5:50:20}\par
d) \hdif{7:50:10}{6:50:20}\par
e) \hdif{20:00:00}{19:59:15}\par
f) \hdif{17:13:15}{14:12:45}
****************** Fin code ******************


****************** Code 135 ******************
\newcount\ii
\catcode`\@=11
\def\ncar#1#2{%
   \ii=0 % initialise le compteur � 0
   \def\val@max{#1}% stocke la valeur maximale
   \def\car@save{#2}% stocke le caract�re � afficher
   \ncar@i% appelle la macro r�cursive
}
\def\ncar@i{%
 \ifnum\ii<\val@max% si la valeur maxi n'est pas atteinte
   \car@save% afficher le caract�re
   \advance\ii 1 % incr�menter le compteur
   \ncar@i% recommencer
 \fi
}
\catcode`\@=12
\ncar{7}{*}\par
\ncar{13}W\par
\ncar{10}{foobar }
****************** Fin code ******************


****************** Code 136 ******************
\newcount\ii
\catcode`\@=11
\def\ncar#1#2{%
   \ii=0 % initialise le compteur � 0
   \def\val@max{#1}% stocke la valeur maximale
   \def\car@save{#2}% stocke le caract�re � afficher
   \ncar@i% appelle la macro r�cursive
}
\def\ncar@i{%
 \ifnum\ii<\val@max% si la valeur maxi n'est pas atteinte
   \car@save% afficher le caract�re
   \advance\ii 1 % incr�menter le compteur
   \ncar@i% recommencer
 \fi
}
\catcode`\@=12
\ncar{2}{3a}
****************** Fin code ******************


****************** Code 137 ******************
a) \romannumeral 9600 \qquad b) \romannumeral 12000
****************** Fin code ******************


****************** Code 138 ******************
\def\ncar#1#2{%
       \begingroup
       \lccode`\m=`#2 % dans \lowercase, les "m" deviennent des "#2"
       \lowercase\expandafter{\expandafter\endgroup\romannumeral#1000 }%
}
a) \ncar{7}{*}\qquad
b) \ncar{15}{\%}\qquad
c) \ncar{10}{4}
****************** Fin code ******************


****************** Code 139 ******************
\def\ncar#1#2{%
 \ifnum#1>0 % <- espace apr�s le "0"
   #2% affiche le caract�re
   \exparg\ncar{\number\numexpr#1-1}{#2}% appel r�cursif
 \fi
}
a) \ncar{7}{*}\qquad
b) \ncar{13}{W}\qquad
c) \edef\foo{\ncar{5}{7}}\meaning\foo
****************** Fin code ******************


****************** Code 140 ******************
\def\ncar#1#2{%
       \ifnum#1>0 \expandafter\identity% si #1>0 ex�cuter...
       \else      \expandafter\gobone% ...sinon manger
       \fi% ce qui est entre ces accolades :
               {#2% afficher le caract�re
               \exparg\ncar{\number\numexpr#1-1}{#2}% appel r�cursif
               }%
}
a) \ncar{7}{*}\qquad
b) \ncar{13}{W}\qquad
c) \edef\foo{\ncar{5}X}\meaning\foo
****************** Fin code ******************


****************** Code 141 ******************
\long\def\antefi#1\fi{\fi#1}
\def\ncar#1#2{%
       \ifnum#1>0
               \antefi% comme si le \fi �tait "d�plac�" ici
               #2% affiche le caract�re
               \exparg\ncar{\number\numexpr#1-1}{#2}% appel r�cursif
       \fi
}
a) \ncar{7}{*}\qquad
b) \ncar{13}{W}\qquad
c) \edef\foo{\ncar{5}X}\meaning\foo
****************** Fin code ******************


****************** Code 142 ******************
\long\def\afterfi#1#2\fi{#2\fi#1}
\def\ncar#1#2{%
       \ifnum#1>0
               \afterfi{\exparg\ncar{\number\numexpr#1-1}{#2}}% <- argument renvoy� apr�s le \fi
               #2% <- ceci reste avant le \fi
       \fi
}
a) \ncar{7}{*}\qquad
b) \ncar{13}{W}\qquad
c) \edef\foo{\ncar{5}X}\meaning\foo
****************** Fin code ******************


****************** Code 143 ******************
\def\ncar#1#2{%
 \ifnum#1>0
   #2% afficher le caract�re
   \expandafter\ncar\expandafter% le pont d'\expandafter lance \number et \numexpr
               {\number\numexpr#1-1\expandafter}% le dernier \expandafter mange "\else...\fi"
 \else
   \expandafter\gobone% si le test est faux, manger {#2} ci-dessous
 \fi{#2}%
}
a) \ncar{7}{*}\qquad
b) \ncar{13}{W}\qquad
c) \edef\foo{\ncar{5}X}\meaning\foo
****************** Fin code ******************


****************** Code 144 ******************
\catcode`\@11
\def\ncar#1#2{%
       \def\ncar@i##1{%
               \ifnum##1<#1 % si i < valeur maxi
               #2% afficher le caract�re
               \exparg\ncar@i{\number\numexpr##1+1\expandafter}% puis recommencer avec i+1
               \fi% \fi mang� par le \expandafter en fin de zone de \numexpr
       }%
       \ncar@i{0}% commence avec la valeur "compteur" 0
}
\catcode`\@12
a) \ncar{7}{*}\qquad
b) \ncar{13}{W}\qquad
c) \ncar{5}{X}
****************** Fin code ******************


****************** Code 145 ******************
\catcode`\@11 \newcount\compte@cnt
\def\compte#1{%
       \def\val@max{#1}\compte@cnt=0 % effectue les initialisations
       \compte@i% appelle la macro principale
}
\def\compte@i{%
       \ifnum\compte@cnt<\val@max% si compteur < valeur maxi
               \advance\compte@cnt1 % incr�menter le compteur
               \number\compte@cnt, % afficher le nombre, la virgule et l'espace
               \expandafter\compte@i %recommencer
       \fi
}
\catcode`\@12
a) \compte{9}\qquad
b) \compte{-4}\qquad
c) \compte{2}
****************** Fin code ******************


****************** Code 146 ******************
\catcode`\@11 \newcount\compte@cnt
\def\compte#1{\def\val@max{#1}\compte@cnt=0 \compte@i}
\def\compte@i{%
       \ifnum\compte@cnt<\val@max\relax
               \advance\compte@cnt1
               \number\compte@cnt
               \ifnum\compte@cnt<\val@max , \fi% afficher ", " si le maxi n'est pas atteint
               \expandafter\compte@i
       \fi
}
\catcode`\@12
a) \compte{9}\qquad
b)\compte{-4}\qquad
c) \compte{2}
****************** Fin code ******************


****************** Code 147 ******************
\catcode`\@11 \newcount\compte@cnt
\def\compte#1{%
 \ifnum#1>0 % ne faire quelque chose que si l'argument est positif
   \def\val@max{#1}\compte@cnt=1 % faire les initialisations
   \expandafter\compte@i% appeller la macro r�crusive
 \fi
}
\def\compte@i{%
 \number\compte@cnt\relax % afficher le nombre
 \ifnum\compte@cnt<\val@max\relax % si valeur maxi n'est pas atteinte
   , % afficher la virgule et l'espace
   \advance\compte@cnt1 % incr�menter le compteur
   \expandafter\compte@i % recommencer
 \fi
}
\catcode`\@12
a) \compte{9}\qquad
b) \compte{-4}\qquad
c) \compte{2}
****************** Fin code ******************


****************** Code 148 ******************
\catcode`\@11
\def\compte#1{%
       \ifnum#1>\z@% ne faire quelque chose que si #1 > 0
               \antefi\compte@i{1}{#1}%
       \fi
}

\def\compte@i#1#2{%
       #1% afficher le nombre
       \ifnum#1<#2 % si le maxi n'est pas atteint
               \expandafter\identity% ex�cuter...
       \else
               \expandafter\gobone% sinon, manger...
       \fi% le code entre accolades ci-dessous
               {, % afficher la virgule et l'espace
               \exparg\compte@i{\number\numexpr#1+1}{#2}% appel r�cursif
               }%
}
\catcode`\@12
a) \compte{9}\qquad
b) \compte{-4}\qquad
c) \edef\foo{\compte{2}}\meaning\foo
****************** Fin code ******************


****************** Code 149 ******************
\catcode`\@11
\def\compte#1{%
       \ifnum#1>\z@% ne faire quelque chose que si #1 > 0
               \antefi\compte@i{1}{#1}%
       \fi
}

\def\compte@i#1#2{%
 #1% afficher le nombre
 \ifnum#1<#2 % si le maxi n'est pas atteint
   \antefi% d�place le \fi ici
   , % affiche la virgule et l'espace
   \exparg\compte@i{\number\numexpr#1+1}{#2}% appel r�cursif
 \fi
}
\catcode`\@12
a) \compte{9}\qquad
b) \compte{-4}\qquad
c) \edef\foo{\compte{2}}\meaning\foo
****************** Fin code ******************


****************** Code 150 ******************
\catcode`\@11
\def\for#1=#2to#3\do#4{% #1=\<macro>   #2=n1   #3=n2   #4=<code>
       \def#1{#2}% initialise la \<macro> � l'entier n1
       \def\val@max{#3}% stocke n2
       \def\loop@code{#4}% stocke le <code>
       \for@i#1% appelle la macro r�cursive et passe la \<macro> en argument
}
\def\for@i#1{%
       \unless\ifnum#1>\val@max\relax% tant que la \<macro> est <= n2
               \loop@code% effectue le code pr�c�demment sauvegard�
               \edef#1{\number\numexpr#1+1}% incr�menter la \<macro>
               \expandafter\for@i\expandafter#1% et recommencer apr�s avoir mang� le \fi
       \fi
}
\catcode`\@=12
\for\ii=1to5\do{Maintenant \string\ii\ vaut : \ii.\endgraf}\medbreak
"\for\ii=1to0\do{A}"\medbreak% boucle parcourue 0 fois
"\for\ii=1to1\do{A}"\medbreak% boucle parcourue 1 fois
\for\ii = 0 to 10 \do {[\ii]}.
****************** Fin code ******************


****************** Code 151 ******************
\catcode`\@11
\long\def\for#1=#2to#3\do#4{%
       \def\for@i{%
               \unless\ifnum#1>\val@max\relax% tant que la \<macro> <= n2
                       #4% code � ex�cuter
                       \edef#1{\number\numexpr#1+1}% incr�menter \<macro>
                       \expandafter\for@i% et recommencer apr�s avoir mang� le \fi
               \fi
       }%
       \edef#1{\number\numexpr#2\relax}% initialise la variable � n1
       \edef\val@max{\number\numexpr#3\relax}% stocke n2
       \for@i% appelle la sous-macro r�cursive
}
\catcode`\@=12
\for\ii = 1 to 5 \do {Maintenant \string\ii\ vaut : \ii.\par}\medbreak
"\for\ii=1to0\do{A}"\medbreak% boucle parcourue 0 fois
"\for\ii=1to1\do{A}"\medbreak% boucle parcourue 1 fois
\for\ii = 0 to 10 \do {[\ii]}.
****************** Fin code ******************


****************** Code 152 ******************
\catcode`\@11
\def\for#1=#2to#3\do#4#{%
       \edef\for@increment{\number\numexpr0#4}% lit et normalise l'argument optionnel
       \ifnum\for@increment=\z@% s'il est nul,
               \edef\for@increment{% le red�finir :
                       \ifnum\numexpr#3\relax<\numexpr#2\relax
                               -% ajoute un signe - si #3<#2
                       \fi
                       1% devant "1"
               }% \for@increment vaut donc 1 ou -1
       \fi
       \ifnum\numexpr\for@increment*(#3-#2)\relax<\z@% si l'argument est incompatible
               \expandafter\firstoftwo% ex�cuter le 1er argument qui suit
       \else
               \expandafter\secondoftwo% sinon le second
       \fi
               {Incr�ment incompatible !\gobone %\gobone mangera le <code> qui � lire
               }%
               {\edef#1{\number\numexpr#2\relax}% initialise la \<macro>
               \edef\cmp@sgn{\ifnum\for@increment<\z@<\else>\fi}% stocke "<" ou ">" pour plus tard
               \expandafter\for@i\expandafter#1\expandafter% appelle la macro r�cursive
                       {\number\numexpr#3\relax}% et lui lui passe la \<macro> (#1) et n2 (#3)
               }%
}

% #1 = \<macro>   #2 = n2
\long\def\for@i#1#2#3{% l'argument #3 (le <code>) est lu � ce moment-l�
       \def\for@ii{%
               \unless\ifnum#1\cmp@sgn#2\relax% tant que la \<macro> n'a pas d�pass� n2
                       #3% ex�cute le <code>
                       \edef#1{\number\numexpr#1+\for@increment}% incr�mente la \<macro>
                       \expandafter\for@ii% recommence apr�s avoir mang� le \fi
               \fi
       }%
       \for@ii% appelle la sous-macro r�cursive
}%
\catcode`\@=12
a) \for\ii = -4 to 7 \do{(\ii)}\par
b) \for\jj = 20 to -50\do-10 {(\jj)}\par
c) \for\xx = 8 to 185\do 20 {[\xx]}\par
d) \for\yy = 0 to 10\do -2{(\yy)}\par
e) "\for\ii = 1 to 0 \do1{XX}"\par
f) "\for\ii = 1 to 1 \do{A}"\par% boucle parcourue 1 fois
g) \for\ii=1to4\do{\for\jj=0to2\do{(\ii,\jj)}\par}% imbrication de boucles
****************** Fin code ******************


****************** Code 153 ******************
\catcode`\@11
\def\for#1=#2to#3\do#4#{%
       \edef\for@increment{\number\numexpr0#4}% lit et normalise l'argument optionnel
       \ifnum\for@increment=\z@% s'il est nul,
               \edef\for@increment{% le red�finir � -1 (si #3<#2) et 1 sinon
                       \ifnum\numexpr#3-#2\relax<\z@ -1\else 1\fi
               }% \for@increment vaut donc 1 ou -1
       \fi
       \ifnum\numexpr\for@increment*(#3-#2)\relax<\z@
               \expandafter\gobone% si argument optionnel incompatible, manger le {<code>}
       \else
               \edef#1{\number\numexpr#2}% initialise la \<macro>
               \edef\macro@args{% d�finit et d�veloppe les arguments � passer � \for@i
                       %#1=nom de la macro r�cursive :
                       \expandafter\noexpand\csname for@ii@\string#1\endcsname
                       \ifnum\for@increment<\z@ <\else >\fi% #2=signe de comparaison
                       {\for@increment}% #3=incr�ment
                       \noexpand#1% #4=\<macro>
                       {\number\numexpr#3\relax}% #5=entier n2
               }%
               \antefi% externalise la ligne ci-dessous de la port�e du test
               \expandafter\for@i\macro@args% appelle \for@i avec les arguments d�finis ci-dessus
       \fi
}

% #1=nom de la macro r�cursive de type "\for@ii@\<macro>"
% #2=signe de comparaison  % #3=incr�ment
% #4=\<macro>  % #5=entier n2  % #6=<code> � ex�cuter
\long\def\for@i#1#2#3#4#5#6{%
       \def#1{% d�finit la sous macro r�cursive
               \unless\ifnum#4#2#5\relax% tant que la \<macro> variable n'a pas d�pass� n2
                       \afterfi{% rendre la r�cursivit� terminale
                               #6% ex�cute le code
                               \edef#4{\number\numexpr#4+#3\relax}% incr�mente la \<macro>
                               #1% recommence
                       }%
               \fi
       }%
       #1% appelle la sous-macro r�cursive
}%
\catcode`\@=12
\for\ii=1to4\do{\for\jj=0to2\do{(\ii,\jj)}\par}\medbreak

\for\carA= `\A to `\E \do{\for\carB= `w to `z \do{\char\carA\char\carB}\quad}
****************** Fin code ******************


****************** Code 154 ******************
\catcode`\@11
\long\def\for@i#1#2#3#4#5#6{%
       \def\exitfor{\def#1{}}%
       \def#1{% d�finit la sous macro r�cursive
               \unless\ifnum#4#2#5\relax% tant que la variable n'a pas d�pass� l'entier max
                       \afterfi{% rendre la r�cursivit� terminale
                               #6% ex�cute le code
                               \edef#4{\number\numexpr#4+#3\relax}% incr�mente la variable #1
                               #1% recommence
                       }%
               \fi
       }%
       #1% appelle la sous-macro r�cursive
}%
\catcode`\@=12
\for\ii= 1 to 9 \do{\string\ii{} vaut \ii.\ifnum\ii=5 \exitfor\fi\par}
****************** Fin code ******************


****************** Code 155 ******************
\def\exitfor#1{% #1=\<macro> correspondant � la boucle de laquelle on veut sortir
       \defname{for@ii@\string#1}{}
}

\def\ifexitfor#1{% envoie vrai si on est pr�matur�ment sorti de la boucle de \<macro> #1
       % si la macro r�cursive est �gale � la macro "\empty"
       \expandafter\ifx\csname for@ii@\string#1\endcsname\empty
               \expandafter\firstoftwo% c'est qu'on est sortir pr�matur�ment, renvoyer "vrai"
       \else
               \expandafter\secondoftwo% sinon, renvoyer "faux"
       \fi
}

% on ne sort QUE de la boucle int�rieure quand \ii=3 donc
% les boucles sont normalement ex�cut�es pour \ii=4 et \ii=5
a. \for\ii=1 to 5\do1{%
    \for\jj=1 to 3\do1{(\ii,\jj) \ifnum\ii=3 \exitfor\jj\fi}%
    \qquad
  }

% on sort de la boucle ext�rieure lorsque \ii=3 donc la boucle
% int�rieure est faite enti�rement m�me lorsque \ii=3
b. \for\ii=1 to 5\do1{%
    \for\jj=1 to 3\do1{(\ii,\jj) \ifnum\ii=3 \exitfor\ii\fi}%
    \qquad
  }

% on sort de la boucle int�rieure lorsque \ii=3
% et aussi de la boucle ext�rieure � l'aide de \ifexitfor
c. \for\ii=1 to 5\do1{%
    \for\jj=1 to 3\do1{(\ii,\jj) \ifnum\ii=3 \exitfor\jj\fi}%
    \ifexitfor\jj{\exitfor\ii}{}% si on est sorti de \jj, sortir aussi de \ii
    \qquad
  }
****************** Fin code ******************


****************** Code 156 ******************
\def\foo{a}\ifx a\foo vrai\else faux\fi
****************** Fin code ******************


****************** Code 157 ******************
1) \meaning9\par% un caract�re de catcode 12
2) \meaning a\par% une lettre
3) \def\foo{a}\meaning\foo\par% une macro
4) \long\def\foo{a}\meaning\foo\par% une macro d�clar�e \long
5) \meaning\sdlkfj\par% une macro ind�finie
6) \edef\foo{\string a}\meaning\foo\par%\foo contient un "a" de catcode 12
7) \def\foo{a}\meaning\foo\par%\foo contient un "a" de catcode 11
****************** Fin code ******************


****************** Code 158 ******************
a) \ifx abvrai\else faux\fi\quad% a est n'est pas �gal � b
b) \ifx++vrai\else faux\fi\quad% le caract�re "+" est �gal � "+"
c) \ifx\relax\par vrai\else faux\fi\quad% \relax n'est pas la m�me primitive que \par
d) \ifx\par\par vrai\else faux\fi\quad% \par et \par sont les m�mes primitives
e) \ifx\sdfk\qlms vrai\else faux\fi\quad% 2 macros non d�finies sont �gales
f) \def\foo{abcd}\def\bar{abc}% \foo et \bar ont des textes de remplacement diff�rents
  \ifx\foo\bar vrai\else faux\fi\quad
g) \def\foo{abcd}\def\bar{abcd }% \foo et \bar ont des textes de remplacement diff�rents
  \ifx\foo\bar vrai\else faux\fi\quad
h) \def\foo{abcd}\def\bar{abcd}
  \ifx\foo\bar vrai\else faux\fi\quad% \foo et \bar ont les m�mes textes de remplacement
i) \long\def\foo{a}\def\bar{a}
  \ifx\foo\bar vrai\else faux\fi\quad% \foo est \long, \bar ne l'est pas
j) \edef\foo{\string a}% \foo contient un "a" de catcode 12
  \def\bar{a}% \bar contient un "a" de catcode 11
  \ifx\foo\bar vrai\else faux\fi
****************** Fin code ******************


****************** Code 159 ******************
\def\cmpmacro#1#2{%
       \begingroup
       \edef\tempa{\detokenize\expandafter{#1}}\edef\tempb{\detokenize\expandafter{#2}}%
       \ifx\tempa\tempb% si �galit�
               \endgroup\expandafter\firstoftwo% ferme le groupe et lit 1er argument
       \else
               \endgroup\expandafter\secondoftwo% sinon, ferme le groupe et lit le 2e argument
       \fi
}
a) \edef\foo{\string a}\def\bar{a}
  \cmpmacro\foo\bar{vrai}{faux}\qquad
b) \edef\foo{\detokenize{$i^2=-1$\relax}}\def\bar{$i^2=-1$\relax}
  \cmpmacro\foo\bar{vrai}{faux}
****************** Fin code ******************


****************** Code 160 ******************
a) \let\rien\relax      \ifx\rien\relax vrai\else faux\fi\qquad
b) \let\AA=a            \ifx a\AA vrai\else faux\fi\qquad
c) \let\foo=_\let\bar=_ \ifx\foo\bar vrai\else faux\fi
****************** Fin code ******************


****************** Code 161 ******************
\def\quark{\quark}% d�finit un quark
1) \def\test{\quark} \ifx\quark\test vrai\else faux\fi
\qquad
2) \let\test=\quark  \ifx\quark\test vrai\else faux\fi
****************** Fin code ******************


****************** Code 162 ******************
\def\ifempty#1{%
       \def\tempa{#1}% stocke l'argument #1 dans \tempa
       \ifx\tempa\empty% si \tempa = \empty
               \expandafter\firstoftwo% 1er argument
       \else
               \expandafter\secondoftwo% sinon, second
       \fi
}
a) \ifempty{abc}{vide}{pas vide}\qquad
b) \ifempty{}{vide}{pas vide}\qquad
c) \ifempty{ }{vide}{pas vide}\qquad
d) \ifempty{\empty}{vide}{pas vide}
****************** Fin code ******************


****************** Code 163 ******************
\def\empty{}
\long\def\ifempty#1{%
 \ifx_#1_\expandafter\firstoftwo
 \else\expandafter\secondoftwo
 \fi}
a) \ifempty{abc}{vide}{pas vide}\qquad
b) \ifempty{}{vide}{pas vide}\qquad
c) \ifempty{ }{vide}{pas vide}\qquad
d) \ifempty{\empty}{vide}{pas vide}\qquad
e) \edef\foo{\ifempty{abc}{vide}{pas vide}}\meaning\foo
****************** Fin code ******************


****************** Code 164 ******************
\long\def\ifempty#1{%
 \ifx W#1W\expandafter\firstoftwo
 \else    \expandafter\secondoftwo
 \fi}
1) \ifempty{foobar}{vide}{pas vide}\qquad
2) \ifempty{}{vide}{pas vide}\qquad
2) \ifempty{\empty}{vide}{pas vide}\qquad
4) \ifempty{Wagons}{vide}{pas vide}
****************** Fin code ******************


****************** Code 165 ******************
\long\def\ifempty#1{%
       \expandafter\ifx\expandafter\relax\detokenize{#1}\relax
               \expandafter\firstoftwo
       \else
               \expandafter\secondoftwo
       \fi
}
a) \ifempty{abc}{vide}{pas vide}\qquad
b) \ifempty{}{vide}{pas vide}\qquad
c) \ifempty{ }{vide}{pas vide}\qquad
d) \ifempty{\relax}{vide}{pas vide}\qquad
e) \edef\foo{\ifempty{abc}{vide}{pas vide}}\meaning\foo
****************** Fin code ******************


****************** Code 166 ******************
\catcode`\@11
\def\reverse#1{%
       \ifempty{#1}
               {}% s'il n'y a rien � inverse, ne rien faire
               {\reverse@i#1\@nil\@nil}% initialisation des r�servoirs et appeler \reverse@i
}
\def\reverse@i#1#2\@nil#3\@nil{% #1 est le 1er caract�re du r�servoir A
       \ifempty{#2}% si ce qui reste apr�s ce 1er caract�re est vide
               {#1#3}% renvoyer #1#3 qui est le r�sultat final
               {\reverse@i#2\@nil#1#3\@nil}% sinon, recommencer en d�pla�ant #1
                                           % en 1re position du r�servoir B
}
\catcode`\@12
a) \reverse{foobar}\qquad
b) \edef\foo{\reverse{Bonjour}}\meaning\foo\qquad
c) \reverse{Bonjour le monde}\qquad
d) \reverse{Bonjour{ }le{ }monde}
****************** Fin code ******************


****************** Code 167 ******************
\catcode`\@11
\def\ifin#1#2{%
       \def\ifin@i##1#2##2\@nil{% d�finit la macro auxiliaire
               \ifempty{##2}% si ce qu'il y a derri�re le motif est vide
                       \secondoftwo% aller � "faux"
                       \firstoftwo% sinon � "vrai"
       }%
       \ifin@i#1#2\@nil% appel de la macro auxiliaire
}
\catcode`\@12
a) \ifin{abc\relax1}{bc}{vrai}{faux}\qquad
b) \ifin{abc \relax1}{c\relax}{vrai}{faux}\qquad
c) \ifin{abc \relax1}{ }{vrai}{faux}\qquad
d) \ifin{abc \relax1}{}{vrai}{faux}\qquad
e) \ifin{}{a}{vrai}{faux}
****************** Fin code ******************


****************** Code 168 ******************
\catcode`\@11
\def\ifstart#1#2{%
       \def\ifstart@i##1#2##2\@nil{\ifempty{##1}}%
       \ifstart@i#1#2\@nil
}
\catcode`\@12
a) \ifstart{abc}{bc}{vrai}{faux}\qquad
b) \ifstart{abc}{ab}{vrai}{faux}\qquad
c) \ifstart{ abc}{ }{vrai}{faux}\qquad
d) \ifstart{abc}{}{vrai}{faux}\qquad
e) \ifstart{}{a}{vrai}{faux}
****************** Fin code ******************


****************** Code 169 ******************
\catcode`\@11
\def\ifstart#1#2{%
       \def\ifstart@i##1#2##2\@nil{\ifempty{##1}}%
       \ifempty{#2}% si motif vide
               \firstoftwo% ex�cuter code "vrai"
               {\ifstart@i#1\relax#2\@nil}% sinon, aller � la macro auxiliaire
}
\catcode`\@12
a) \ifstart{abc}{bc}{vrai}{faux}\qquad
b) \ifstart{abc}{ab}{vrai}{faux}\qquad
c) \ifstart{ abc}{ }{vrai}{faux}\qquad
d) \ifstart{abc}{}{vrai}{faux}\qquad
e) \ifstart{}{a}{vrai}{faux}
****************** Fin code ******************


****************** Code 170 ******************
\catcode`\@11
\def\ifend#1#2{%
       \def\ifend@i##1#2##2\@nil{% ##2 = ce qui reste apr�s le motif
               \ifempty{##2}% si ##2 est vide
                       \firstoftwo% ex�cuter l'argument "vrai"
                       {\ifin{##2}{#2}% sinon, si ##2 contient le <motif>
                               {\ifend@i##2\@nil}% appeler \ifend@i avec ce qui reste
                               \secondoftwo% sinon, ex�cuter l'argument "faux"
                       }%
       }%
       \ifend@i#2#1\@nil% appelle la macro r�cursive
}
\catcode`\@12
1) \ifend{abc de}{de}{vrai}{faux}\qquad
2) \ifend{abd de }{de}{vrai}{faux}\qquad
3) \ifend{abc de }{ }{vrai}{faux}\qquad
4) \ifend{}{a}{vrai}{faux}\qquad
5) \ifend{abc de}{}{vrai}{faux}
****************** Fin code ******************


****************** Code 171 ******************
\catcode`\@11
\def\ifend#1#2{%
       \def\ifend@i##1#2##2\@nil{% ##2 = ce qui reste apr�s le motif
               \ifempty{##2}% si ##2 est vide
                       \firstoftwo% ex�cuter l'argument "vrai"
                       {\ifin{##2}{#2}% sinon, si ##2 contient le <motif>
                               {\ifend@i##2\@nil}% appeler \ifend@i avec ce qui reste
                               \secondoftwo% sinon, ex�cuter l'argument "faux"
                       }%
       }%
       \ifempty{#2}% si le motif est vide
               \firstoftwo% ex�cuter "vrai"
               {\ifend@i#2\relax#1\@nil}% sinon, appelle la macro r�cursive
}
\catcode`\@12
1) \ifend{abc de}{de}{vrai}{faux}\qquad
2) \ifend{abd de }{de}{vrai}{faux}\qquad
3) \ifend{abc de }{ }{vrai}{faux}\qquad
4) \ifend{}{a}{vrai}{faux}\qquad
5) \ifend{abc de}{}{vrai}{faux}
****************** Fin code ******************


****************** Code 172 ******************
\catcode`\@11
\def\substin#1#2#3{%
       \def\substin@i##1{%
               \ifempty{##1}% si le <code> est vide
                       \relax% ne rien faire -> fin du processus
                       {\ifin{##1}{#2}% sinon, si le <code> contient <motif1>
                               {\substin@ii##1\@nil}% appeler la macro � argument d�limit�s
                               {##1}% sinon, afficher le <code>
                       }%
       }%
       \def\substin@ii##1#2##2\@nil{%
               ##1#3% afficher ##1 et #3 (qui est <motif2>)
               \substin@i{##2}% et recommencer avec ce qui reste
       }%
       \substin@i{#1}%
}
\catcode`\@12
a) \substin{abracadabra}{a}{A}\qquad
b) \substin{abracadabra}{x}{W}\qquad
c) \substin{abracadabra}{br}{}\qquad
d) \substin{1\relax3}\relax{222}\qquad
****************** Fin code ******************


****************** Code 173 ******************
\catcode`\@11
\def\substtocs#1#2#3#4{%
       \def\substtocs@i##1{%
               \ifempty{##1}% si le <code> est vide
                       \relax% ne rien faire -> fin du processus
                       {\ifin{##1}{#3}% sinon, si le <code> contient <motif1>
                               {\substtocs@ii##1\@nil}% appeler la macro � argument d�limit�s
                               {\addtomacro#1{##1}}% sinon, ajouter le <code>
                       }%
       }%
       \def\substtocs@ii##1#3##2\@nil{%
               \addtomacro#1{##1#4}% ajouter ##1#4
               \substtocs@i{##2}% et recommencer avec ce qui reste
       }%
       \let#1=\empty% initialise la macro � vide
       \substtocs@i{#2}%
}
\catcode`\@12
\substtocs\foo{abracadabra}{a}{A}\meaning\foo\par
\substtocs\foo{abracadabra}{x}{W}\meaning\foo\par
\substtocs\foo{abracadabra}{br}{}\meaning\foo\par
\substtocs\foo{1\relax3}\relax{222}\meaning\foo\par
\substtocs\foo{\ifnum1=2 test vrai\fi}{2}{1}\meaning\foo
****************** Fin code ******************


****************** Code 174 ******************
\def\majuscule#1{\uppercase{#1}}
\def\majmot#1{\substin{\majuscule#1}{ }{ \majuscule}}
\majmot{un petit texte}\par
\majmot{Un grand texte sans importance}
****************** Fin code ******************


****************** Code 175 ******************
\def\majuscule#1{\uppercase{#1}}
\def\majmot#1{%
       \begingroup
               \substtocs\temp{\majuscule#1}{ }{ \majuscule}%
               \temp% ex�cute la macro temporaire
       \endgroup
}
\majmot{un petit texte}\par
\majmot{Un grand texte Sans importance}
****************** Fin code ******************


****************** Code 176 ******************
\catcode`\@11
\newcount\cnt@occ
\def\cnttimes#1#2{%
       \def\cnttimes@i##1{%
               \ifempty{##1}% si le <code> est vide
                       {\number\cnt@occ}% afficher le nombre d'occurrences
                       {\ifin{##1}{#2}% sinon, si le <code> contient <motif1>
                               {\cnttimes@ii##1\@nil}% appeler la macro � argument d�limit�s
                               {\number\cnt@occ}% sinon, afficher le nombre d'occurrences
                       }%
       }%
       \def\cnttimes@ii##1#2##2\@nil{%
               \advance\cnt@occ1
               \cnttimes@i{##2}% et recommencer avec ce qui reste
       }%
       \cnt@occ=0 % initialise le compteur
       \cnttimes@i{#1}%
}
\catcode`\@12
a) \cnttimes{abracadabra}{a}\qquad
b) \cnttimes{abracadabra}{ra}\qquad
c) \cnttimes{abracadabra}{w}\qquad
d) \cnttimes{abc def ghijk l }{ }\qquad
e) \cnttimes{\ifnum1=2 vrai\else faux\fi}{\ifnum}
****************** Fin code ******************


****************** Code 177 ******************
\catcode`\@11
\long\def\cnttimestocs#1#2#3{% #3=macro recevant le r�sultat
       \long\def\cnttimestocs@i##1\@nil##2#2##3\@nil{%
               % ##1=nb d'occurrences rencontr�es jusqu'alors
               % ##2 et ##3=ce qui est avant/apr�s le <motif>
               \ifin{##3}{#2}% si le <motif> est dans ce qui reste
                       {\expandafter\cnttimestocs@i% appeler la macro r�cursive
                               \number\numexpr##1+1\relax\@nil% avec une occurrence de plus
                               ##3\@nil% et ce qui reste
                       }%
                       {\edef#3{\number\numexpr##1+1\relax}}% sinon, stocker 1 occurrence de plus dans #3
       }%
       \ifin{#1}{#2}% si le <motif> est dans le <code>
               {\cnttimestocs@i 0\@nil#1\@nil}% appeler la macro r�cursive avec 0 occurrence
               {\def#3{0}}% sinon, mettre 0 dans #3
}
\catcode`\@12
a) \cnttimestocs{abracadabra}{a}\foo \meaning\foo\qquad
b) \cnttimestocs{abracadabra}{ra}\foo \meaning\foo\qquad
c) \cnttimestocs{abracadabra}{w}\foo \meaning\foo\qquad
d) \cnttimestocs{abc def ghijk l }{ }\foo \meaning\foo\qquad
e) \cnttimestocs{\ifnum1=2 vrai\else faux\fi}{\ifnum}\foo \meaning\foo
****************** Fin code ******************


****************** Code 178 ******************
\catcode`\@11
\def\multisubst#1#2{%
       \def\subst@code{#1}% stocke le <code>
       \multisubst@i#2\@nil% appelle la macro r�cursive avec la liste de motifs
}

\def\multisubst@i#1#2#3\@nil{% #1 et #2=paire de motifs  #3=motifs restants
       \expandafter\substtocs\expandafter\subst@code\expandafter% 1-d�veloppe
               {\subst@code}{#1}{#2}% le <code> et effectue la substitution en cours
       \ifempty{#3}% si la liste des motifs est vide
               \subst@code% ex�cuter le <code> obtenu
               {\multisubst@i#3\@nil}% recommencer avec les motifs qui restent
}
\catcode`\@12
1) \multisubst{abracadabra}{aA rR}\par
2) \multisubst{Ce texte devenu \`a peine reconnaissable montre que le
  r\'esultat contient des sonorit\'es catalanes, corses ou grecques
  assez inattendues.}{a{AA} ya uy ou io ei {AA}e}
****************** Fin code ******************


****************** Code 179 ******************
\catcode`\@11
\def\quark{\quark}

\def\multisubst#1#2{% #1 = <code>   #2 = <liste des paires>
       \def\subst@code{#1}% stocke le <code>
       \multisubst@i#2\quark\quark% appelle la macro r�cursive avec
                                  % 2 arguments sp�ciaux en fin de liste
}

\def\multisubst@i#1#2{% #1#2 = paire de motifs en cours
       \def\arg@a{#1}% stocke le <motif1> dans une macro
       \ifx\arg@a\quark% si le motif sp�cial est atteint
               \expandafter\subst@code% ex�cuter le code obtenu
       \else
               \expandafter\substtocs\expandafter\subst@code\expandafter% 1-d�veloppe
                       {\subst@code}{#1}{#2}% le <code> et effectue la substitution en cours
               \expandafter\multisubst@i% puis lis la paire de motifs suivants
       \fi
}
\catcode`\@12
\multisubst{abracadabra}{aA rR}\par
\multisubst{Ce texte devenu \`a peine reconnaissable montre que le r\'esultat contient des
 sonorit\'es catalanes, corses ou grecques assez inattendues.}{a{AA} ya uy ou io ei {AA}e}
****************** Fin code ******************


****************** Code 180 ******************
\iftrue foobar\else ceci n'est jamais lu par \TeX\fi\par
\iffalse ceci n'est jamais lu par \TeX\else foobar\fi
****************** Fin code ******************


****************** Code 181 ******************
\newif\ifhomme
\def\debutlettre{Ch\ifhomme er Monsieur\else �re Madame\fi}%

\hommetrue
\debutlettre
\medbreak

\hommefalse
\debutlettre
****************** Fin code ******************


****************** Code 182 ******************
\catcode`\*=13 \catcode`\+=13 % "*" et "+" sont actifs
1) \def*{xyz}\def+{abc}% d�finit les caract�res actifs
  \ifcat *+vrai\else faux\fi\qquad
2) \ifcat \noexpand *\noexpand +vrai\else faux\fi\qquad
3) \def\foo{foobar}%
  \ifcat \noexpand\foo\relax vrai\else faux\fi\qquad% \foo et \relax sont vus �gaux
4) \ifcat = vrai\else faux\fi\qquad% "=" et " " n'ont pas le m�me catcode
5) \ifcat _^vrai\else faux\fi\qquad% "_" et "^" n'ont pas le m�me catcode
6) \let\foo=&
  \ifcat &\foo vrai\else faux\fi% "&" et \foo (let-�gal � "&") sont vus �gaux
****************** Fin code ******************


****************** Code 183 ******************
\catcode`\@11
\def\ifcs#1{%
       \ifcat\noexpand#1\relax\expandafter\firstoftwo
       \else                  \expandafter\secondoftwo
       \fi
}
\catcode`\@12
1) \def\foo{bar}\ifcs\foo{vrai}{faux}\qquad
2) \ifcs\def{vrai}{faux}\qquad
3) \ifcs A{vrai}{faux}\qquad
\catcode`\*=13
4) \let*=W \ifcs*{vrai}{faux}\qquad
5) \let*=\relax \ifcs*{vrai}{faux}\qquad
6) \let\foo=A \ifcs\foo{vrai}{faux}\qquad
7) \ifcs\bgroup{vrai}{faux}
****************** Fin code ******************


****************** Code 184 ******************
1) \def\foo{xxy}\def\bar{aab}
  \if\foo\bar vrai\else faux\fi\qquad
2) \if aA vrai\else faux\fi\qquad% "a" et "A" n'ont pas les m�mes charcode
3) \if\relax\noexpand\foo vrai\else faux\fi\qquad% \relax et \foo ont un charcode=256
4) \let\foo=&\if\foo &vrai\else faux\fi\qquad% \foo est vue comme "&"
5) \if\string~\noexpand~vrai\else faux\fi
****************** Fin code ******************


****************** Code 185 ******************
\catcode`\@11
\def\ifcs#1{%
       \begingroup
               \escapechar=`\@ % prend "@" comme caract�re d'�chappement
               \if% les premiers caract�res de
                       \expandafter\firstto@nil\string#1a\@nil% "#1a"
                       \expandafter\firstto@nil\string\relax\@nil% et "\relax" sont-ils �gaux ?
                       \endgroup\expandafter\firstoftwo% si oui, fermer le groupe et renvoyer "vrai"
               \else% sinon, fermer le groupe et renvoyer "faux"
                       \endgroup\expandafter\secondoftwo
               \fi
}
\catcode`\@12
1) \def\foo{bar}\ifcs\foo{vrai}{faux}\qquad
2) \ifcs\def{vrai}{faux}\qquad
3) \ifcs A{vrai}{faux}\qquad
\catcode`\*=13
4) \let*=W \ifcs*{vrai}{faux}\qquad
5) \let*=\relax \ifcs*{vrai}{faux}\qquad
6) \let\foo=A \ifcs\foo{vrai}{faux}\qquad
7) \ifcs\bgroup{vrai}{faux}
****************** Fin code ******************


****************** Code 186 ******************
\edef\specialrelax{\ifnum1=1\fi}
\meaning\specialrelax
****************** Fin code ******************


****************** Code 187 ******************
\edef\specialrelax{\ifnum1=1\fi}% texte de remplacement = \relax sp�cial
\edef\normalrelax{\relax}% texte de remplacement = \relax normal
\meaning\specialrelax\par
\meaning\normalrelax\par
Les 2 \string\relax{} sont \ifx\specialrelax\normalrelax identiques\else diff�rents\fi.
****************** Fin code ******************


****************** Code 188 ******************
\edef\specialrelax{\ifnum1=1\fi}
\expandafter\def\specialrelax{foobar}% red�finition un \relax sp�cial
****************** Fin code ******************


****************** Code 189 ******************
\catcode`\@11
\def\ifnumcase#1{%
       \begingroup
       \def\elseif{\elseif}\def\endif{\endif}% d�finir deux "quarks" locaux
       \def\nombre@{#1}% stocker le nombre � comparer dans \nombre@
       \ifnumcase@i% appeller la macro r�cursive
}

\def\ifnumcase@i#1{%
       \def\nxt@arg{#1}% stocker l'argument suivant
       \ifx\nxt@arg\elseif% si c'est \elseif
               \def\next@todo{\endgroup\idto@endif}% fermer le groupe et aller � \idto@endif
       \else
               \ifx\nxt@arg\endif% si c'est \endif
                       \let\next@todo\endgroup% fermer le groupe
               \else
                       \ifnum\nombre@=\nxt@arg% s'il y a �galit�
                               \def\next@todo{\endgroup\firstto@endif}% fermer le groupe puis \firstto@endif
                       \else% sinon
                               \let\next@todo=\ifnumcase@ii% aller � \ifnumcase@ii
                       \fi
               \fi
       \fi
       \next@todo% ex�cuter l'action d�cid�e ci-dessus
}

\def\ifnumcase@ii#1{\ifnumcase@i}
\def\idto@endif#1\endif{#1}
\def\firstto@endif#1#2\endif{#1}
\catcode`\@12
\def\swaptwo#1#2{#2#1}
\def\testenombre#1{%
       \ifnumcase{#1}
               {1}{C'est "un" et je prends le premier argument: \firstoftwo}
               {3}{J'ai vu un "trois" et je mange les deux arguments : \gobtwo}
               {15}{L'argument est "15" et je prends le second argument : \secondoftwo}
       \elseif
               ni 1, ni 3, ni 5 et j'inverse les deux arguments : \swaptwo
       \endif
}
\testenombre{3}{foo}{bar}\par
\testenombre{16}{foo}{bar}\par
\testenombre{15}{foo}{bar}\par
\testenombre{1}{foo}{bar}
****************** Fin code ******************


****************** Code 190 ******************
\catcode`\@11
\def\endif{\endif}\def\elseif{\elseif}% d�finit les quarks

\def\ifnumcase#1#2{% #1=<nombre>   #2=prochain argument
       \ifx\elseif#2% si #2 est \elseif
       \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               \idto@endif% aller � \idto@endif, sinon :
               {\ifx\endif#2% si #2 est \endif
               \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                       {}% ne rien faire. Sinon #2 est une <valeur i>:
                       {\ifnum#1=#2 % s'il y a �galit� entre <nombre> et <valeur i>
                       \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                               \firstto@endif% aller � \firstto@endif
                               {\ifnumcase@i{#1}}% sinon aller � \ifnumcase@i
                       }%
               }%
}

\def\ifnumcase@i#1#2{% #1=<nombre>  #2=<code i> � suivre qui est mang�
       \ifnumcase{#1}% retourner � \ifnumcase en transmettant #1
}

\def\idto@endif#1\endif{#1}
\def\firstto@endif#1#2\endif{#1}
\catcode`\@12
\def\swaptwo#1#2{#2#1}
\def\testenombre#1{%
       \ifnumcase{#1}
               {1}{C'est "un" et je prends le premier argument: \firstoftwo}
               {3}{J'ai vu un "trois" et je mange les deux arguments : \gobtwo}
               {15}{L'argument est "15" et je prends le second argument : \secondoftwo}
       \elseif
               ni 1, ni 3, ni 5 et j'inverse les deux arguments : \swaptwo
       \endif
}
\testenombre{3}{foo}{bar}\par
\testenombre{16}{foo}{bar}\par
\testenombre{15}{foo}{bar}\par
\edef\macro{\testenombre{1}{foo}{bar}}\meaning\macro
****************** Fin code ******************


****************** Code 191 ******************
\catcode`\@11
\def\endif{\endif}\def\elseif{\elseif}%
\def\ifxcase#1#2{% #1=<token>   #2=prochain argument
       \ifx\elseif#2% si #2 est \elseif
       \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               \idto@endif% aller � \idto@endif, sinon :
               {\ifx\endif#2% si #2 est \endif
               \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                       {}% ne rien faire. Sinon #2 est un <token i>:
                       {\ifx#1#2% s'il y a �galit� entre <token> et <token i>
                       \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                               \firstto@endif% aller � \firstto@endif
                               {\ifxcase@i{#1}}% sinon aller � \ifnumcase@i
                       }%
               }%
}
\def\ifxcase@i#1#2{% #1=<token>  #2=<code i> � suivre (qui est mang�)
       \ifxcase{#1}% retourner � \ifxcase en transmettant #1
}
\def\idto@endif#1\endif{#1}
\def\firstto@endif#1#2\endif{#1}
\catcode`\@12
\def\testtoken#1{%
       \ifxcase{#1}
               a{Le token est "a"}
               +{J'ai vu un "+"}
               \relax{L'argument est "\string\relax"}
       \elseif
               Tous les tests sont n�gatifs%
       \endif
}
1) \testtoken a\par
2) \let\foo=a\testtoken\foo\par
3) \testtoken+\par
4) \testtoken\relax\par
5) \edef\foo{\testtoken\relax}\meaning\foo\par
6) \edef\foo{\testtoken W}\meaning\foo
****************** Fin code ******************


****************** Code 192 ******************
\newcount\xx % d�finit un compteur utilis� dans la boucle
\def\compte#1{%
       \xx=0 % initialise le compteur
       \loop% d�but de la boucle
               \advance\xx1 % incr�mente le compteur
               \ifnum\xx<#1 % s'il est inf�rieur � la borne
                 \number\xx , % affiche le nombre et la virgule
       \repeat% et recommence
       \ifnum#1>0 \number\xx\relax\fi% si le nombre #1 est >0, afficher le dernier nombre
       }
a) \compte{1}.\qquad b) \compte{-3}.\qquad c) \compte{7}.
****************** Fin code ******************


****************** Code 193 ******************
\catcode`\@11
\newcount\cnt@repeat % d�finit le compteur de \xrepeat

\def\xloop{%
       \def\xiterate{}% initialiser \xiterate � vide
       \cnt@repeat\z@% initialiser le compteur de \xrepeat
       \xloop@i% aller � la macro r�cursive
}

\long\def\xloop@i#1\xrepeat{%
       \addtomacro\xiterate{#1}% ajoute ce qui est avant le premier \xrepeat
       \exparg\cnttimestocs{\xiterate}\xloop\cnt@loop
       % combien de \xloop dans \xiterate
       \ifnum\cnt@loop=\cnt@repeat\relax
               \expandafter\firstoftwo\else\expandafter\secondoftwo
       \fi
               {% autant que de \xrepeat -> \detokenize pour afficher
               "\detokenize\expandafter{\xiterate}"%
               }
               {\addtomacro\xiterate\xrepeat% sinon, ajouter ce \xrepeat
               \advance\cnt@repeat by 1% incr�menter le compteutr de \xrepeat
               \xloop@i% et chercher le prochain \xrepeat
               }%
}
\let\xrepeat\fi
\catcode`\@12
\xloop a\xloop b\xloop 12\xrepeat c\xrepeat \xloop X\xrepeat\xrepeat
****************** Fin code ******************


****************** Code 194 ******************
\catcode`\@11
\newcount\cnt@repeat
\newcount\cnt@nested
\cnt@nested=0 % compteur d'imbrications
\def\xloop{%
       \global\advance\cnt@nested by 1 % augmente le compteur d'imbrications
       \expandafter\def\csname xiterate@\number\cnt@nested\endcsname{}%
       \cnt@repeat\z@% initialise le compteur de \xrepeat � 0
       \xloop@i% aller � la macro \xloop@i
}
\long\def\xloop@i#1\xrepeat{%
       \expandafter\addtomacro\csname xiterate@\number\cnt@nested\endcsname{#1}%
       \expandafter\expandafter\expandafter\cnttimestocs\expandafter\expandafter\expandafter
               {\csname xiterate@\number\cnt@nested\endcsname}\xloop\cnt@loop
       \ifnum\cnt@loop=\cnt@repeat\relax
               \expandafter\firstoftwo\else\expandafter\secondoftwo
       \fi
               {\expandafter\eaddtomacro\csname xiterate@\number\cnt@nested\expandafter\endcsname
                       {\expandafter\expandafter\csname xiterate@\number\cnt@nested\endcsname\fi}%
               %\expandafter\show\csname xiterate@\number\cnt@nested\endcsname
               \csname xiterate@\number\cnt@nested\endcsname
               \letname{xiterate@\number\cnt@nested}\relax
               \global\advance\cnt@nested by -1
               }
               {\expandafter\addtomacro\csname xiterate@\number\cnt@nested\endcsname\xrepeat
               \advance\cnt@repeat by 1
               \xloop@i
               }%
}%
\let\xrepeat\fi
\catcode`\@12

\newcount\cntxx \cntxx=1 % compteur des lignes
\newcount\cntyy
\xloop
       \cntyy=1 % compteur des colonnes
       \xloop
               (\number\cntxx,\number\cntyy)% affiche "(ligne,colonne)"
               \ifnum\cntyy<5 % tant que colonne<5
               \advance\cntyy1 % incr�mente colonne
               , % <- affiche ", "
       \xrepeat% et recommence
       \ifnum\cntxx<3 % tant que ligne<3
       \advance\cntxx1 % incr�mente ligne
       \par % va � la ligne
\xrepeat% et recommence
****************** Fin code ******************


****************** Code 195 ******************
\catcode`\@11
\def\end@foreach{\end@foreach}% d�finit un quark
\long\def\doforeach#1\in#2#3{%
       \def\loop@code{#3}% assigne le <code> � \loop@code
       % appel � \doforeach@i : mettre la macro #1 en premier, puis la liste de valeurs #2
       \doforeach@i#1#2,\end@foreach,% ajouter � la fin ",\end@foreach,"
       % une fois les boucles finies, neutraliser les macros d�j� d�finies
       \let#1\relax \let\loop@code\relax
}

\long\def\doforeach@i#1#2,{% #1=\<macro>  #2=valeur courante
       \def#1{#2}% stocke la valeur en cours dans la \<macro>
       \unless\ifx\end@foreach#1% si \end@foreach n'est pas atteint
               \antefi% am�ne le \fi ici
               \loop@code% ex�cute le code
               \doforeach@i#1% et recommencer
       \fi
}
\catcode`@12
\doforeach\x\in{a,bcd,{efg},hi}{\meaning\x.\par}
****************** Fin code ******************


****************** Code 196 ******************
\catcode`\@11
\def\end@foreach{\end@foreach}
\def\defseplist#1{%
       \long\def\doforeach##1\in##2##3{%
               \def\loop@code{##3}% assigne le <code> � \loop@code
               \doforeach@i##1##2#1\end@foreach#1% ajouter ",\end@foreach," et aller � \doforeach@i
               % apr�s �tre sorti des boucles, neutraliser les macros d�j� d�finies
               \let\loop@code\relax \let##1\relax
       }%
       \long\def\doforeach@i##1##2#1{%
               \def##1{##2}% stocke la valeur en cours dans la \<macro>
               \unless\ifx\end@foreach##1% si la fin n'est pas atteinte
                       \antefi% am�ne le \fi ici
                       \loop@code% ex�cute le code
                       \doforeach@i##1% et recommencer
               \fi
       }%
}
\defseplist{,}% d�finit les macros avec le s�parateur par d�faut
\catcode`@12

\doforeach\x\in{a,bcd,efg}{Argument courant : "\x".\par}\medbreak

\defseplist{--}% s�parateur "--"
\doforeach\nn\in{4,19--0,5--8,575}{Nombre lu : "\nn"\par}
****************** Fin code ******************


****************** Code 197 ******************
\catcode`\@11
\newcount\cnt@nest \cnt@nest=0 % d�finit et initialise le compteur d'imbrication
\def\end@foreach{\end@foreach}

\def\defseplist#1{%
       \long\def\doforeach##1\in##2##3{%
               \global\advance\cnt@nest1 % entr�e de boucle : incr�menter le compteur d'imbrication
               \defname{loop@code@\number\cnt@nest}{##3}% assigne le <code> � \loop@code@<n>
               \doforeach@i##1##2#1\end@foreach#1% ajouter ",\end@foreach," et aller � \doforeach@i
               % une fois fini :
               \let##1\empty% dans ce cas, neutraliser les macros d�j� d�finies
               \letname{loop@code@\number\cnt@nest}\empty%
               \global\advance\cnt@nest-1 %sortie de boucle : d�cr�menter le compteur d'imbrication
       }%
       \long\def\doforeach@i##1##2#1{%
               \def##1{##2}% stocke la valeur en cours dans la \<macro>
               \unless\ifx\end@foreach##1% tant que la fin n'est pas atteinte
                       \antefi% am�ne le \fi ici
                       \csname loop@code@\number\cnt@nest\endcsname% ex�cute le code
                       \doforeach@i##1% et recommencer
               \fi
       }%
}
\catcode`@12
\defseplist{,}

\doforeach\xxx\in{1,2,3}{%
       Ligne \xxx{} : \doforeach\yyy\in{a,b,c,d,e}{(\xxx,\yyy)}.\par
}
****************** Fin code ******************


****************** Code 198 ******************
\catcode`\@11
\newcount\cnt@nest \cnt@nest=0 % d�finit et initialise le compteur d'imbrication
\def\end@foreach{\end@foreach}
\long\def\save@macro#1{% sauvegarde la macro #1
       \ifdefined#1% si la macro #1 est d�j� d�finie...
               \letname{saved@var@\number\cnt@nest}#1% ...la sauvegarder
       \fi
}
\long\def\restore@macro#1{% restaure la macro #1
% le \csname donne \relax si la sauvegarde n'a pas �t� faite
       \expandafter\let\expandafter#1\csname saved@var@\number\cnt@nest\endcsname
}
\def\defseplist#1{%
       \long\def\doforeach##1\in##2##3{%
               \global\advance\cnt@nest1 % entr�e de boucle : incr�menter le compteur d'imbrication
               \save@macro##1% sauvegarde la macro ##1
               \defname{loop@code@\number\cnt@nest}{##3}% assigne le <code> � \loop@code@<n>
               \doforeach@i##1##2#1\end@foreach#1% ajouter ",\end@foreach," et aller � \doforeach@i
               % une fois fini, neutraliser la macro contenant le <code>
               \letname{loop@code@\number\cnt@nest}\empty
               \restore@macro##1% restaurer la \<macro>
               \global\advance\cnt@nest-1 % et d�cr�menter le compteur d'imbrication
       }%
       \long\def\doforeach@i##1##2#1{%
               \def##1{##2}% stocke la valeur en cours dans la \<macro>
               \unless\ifx\end@foreach##1% si la fin n'est pas atteinte
                       \antefi% am�ne le \fi ici
                       \csname loop@code@\number\cnt@nest\endcsname% ex�cute le code
                       \doforeach@i##1% et recommencer
               \fi%
       }%
}
\catcode`@12
\defseplist{,}
\doforeach\par\in{a,b,c,y,z}{$\par_i$}

\meaning\par% \par doit �tre redevenu une primitive

\doforeach\xxx\in{1,2,3}{%
       Ligne \xxx{} : \doforeach\yyy\in{a,b,c,d,e}{(\xxx,\yyy)}.\par
}
****************** Fin code ******************


****************** Code 199 ******************
\let\foo=\djfhdsldv% \foo est rendue \let-�gale � une macro ind�finie
a) \meaning\foo\par
% puis \djfhdsldv est rendue \let-�gale � \foo (ou \foo est construit avec \csname)
\expandafter\let\expandafter\djfhdsldv\csname foo\endcsname
b) \meaning\djfhdsldv
****************** Fin code ******************


****************** Code 200 ******************
\catcode`\@11
\newcount\cnt@nest \cnt@nest=0 % d�finit et initialise le compteur d'imbrication
\def\end@foreach{\end@foreach}
\long\def\save@macro#1#2{\letname{saved@var@\number\cnt@nest#1}#2}
\long\def\save@macro@i#1/#2{\save@macro{a}#1\save@macro{b}#2}
\long\def\restore@macro#1#2{%
       \expandafter\let\expandafter#2\csname saved@var@\number\cnt@nest#1\endcsname
}
\long\def\restore@macro@i#1/#2{\restore@macro{a}#1\restore@macro{b}#2}
\def\defseplist#1{%
       \long\def\doforeach##1\in##2##3{%
               \global\advance\cnt@nest1 % entr�e de boucle : incr�menter le compteur d'imbrication
               \global\let\allow@recurse\identity% permet l'appel r�cursif plus bas
               \ifin{##1}{/}% si ##1 contient "/"
                       {\save@macro@i##1% sauvegarde les macros
                       \doforeach@ii% appeler la macro r�cursive avec les arguments
                               {##3}% 1) code � ex�cuter
                               ##1%   2) variables sous la forme \<macro1>/\<macro2>
                               ##2#1\end@foreach/\end@foreach#1% puis la liste ##2 suivie de
                                                               % ",\end@foreach/\end@foreach,"
                       \restore@macro@i##1% une fois sorti de toutes les boucles, restaurer les macros
                       }% si ##1 ne contient pas "/"
                       {\save@macro{}##1% sauvegarde la macro
                       \doforeach@i% appeler la macro r�cursive
                               {##3}% mettre en premier le <code>
                               ##1% puis la variable ##1 en 2e position
                               ##2#1\end@foreach#1% enfin la liste ##2 suivie de ",\end@foreach,"
                       \restore@macro{}##1% une fois sorti de toutes les boucles, restaurer la macro
                       }%
               \global\advance\cnt@nest-1 % d�cr�mente le compteur d'imbrications
       }%
       % ##1 = code � ex�cuter, ##2= variable, ##3=valeur courante
       \long\def\doforeach@i##1##2##3#1{%
               \ifx\end@foreach##3% si la fin est atteinte
               \expandafter\gobone\else\expandafter\identity\fi% manger sinon ex�cuter:
                       {\def##2{##3}% fait l'assignation � la variable
                       ##1% le code puis
                       \allow@recurse{\doforeach@i{##1}##2}% recommencer
                       }%
       }%
       % ##1 = code � ex�cuter, ##2/##3= variables, ##4/##5=valeurs courantes
       \long\def\doforeach@ii##1##2/##3##4/##5#1{%
               \ifx\end@foreach##4% si la fin est atteinte
               \expandafter\gobone\else\expandafter\identity\fi% manger sinon ex�cuter:
                       {\def##2{##4}\def##3{##5}% fait l'assignation des deux variables
                       ##1% le code puis
                       \allow@recurse{\doforeach@ii{##1}##2/##3}% recommencer
                       }%
       }%
       % macro qui, si elle remplace \allow@recurse, annule l'appel r�cursif
       \long\def\forbid@recurse##1\end@foreach#1{}% tout manger jusqu'� "\end@foreach,"
}
\def\doforeachexit{\global\let\allow@recurse\forbid@recurse}
\catcode`\@12
\defseplist{,}
\doforeach\par\in{a,b,c,y,z}{$\par_i$}\medskip

\doforeach\sujet/\terminaison\in{Je/e,Tu/es,Il/e,Nous/ons,Vous/ez,Ils/ent}
       {\sujet\ programm\terminaison{} en \TeX\par}\medskip

Les voyelles lues sont :
\doforeach\ii\in{a,e,i,o,u,y}{\ii\if o\ii\doforeachexit\fi}.\medskip

\doforeach\xx\in{a,b,c,d,e,f}
       {\doforeach\ii\in{1,2,3,4}{\xx\ii{} \ifnum\ii=3 \doforeachexit\fi}\par}
****************** Fin code ******************


****************** Code 201 ******************
\newdimen\dimA \newdimen\dimB% alloue deux registres de dimension
a) \dimA=59.5pt
  \the\dimA\qquad% doit afficher 59.5pt
b) \dimA=1.5cm
  \the\dimA\qquad% convertit � l'affichage 1.5cm en pt
c) \dimB=7pt % assigne 7pt � \dimB
  \dimA\dimB% rend \dimA �gal � dimB
  \the\dimA\qquad
d) \dimA=6\dimB% rend \dimA �gal � 6 fois \dimB
  \the\dimA
****************** Fin code ******************


****************** Code 202 ******************
\newdimen\foo
\foo=25pt % assigne 25pt au registre \foo
\divide\foo 4 % le multiplie par 4
\advance\foo1.72pt % lui ajoute 1.72pt
\multiply\foo3 % le multiplie par 3
\the\foo% affiche la dimension obtenue
****************** Fin code ******************


****************** Code 203 ******************
\begingroup% ouvrir un groupe
       \edef\temp{\endgroup\def\noexpand\removept##1.##2\string p\string t}%
\temp{#1\ifnum#2>0 .#2\fi}% et le fermer avant de d�finir \removept
\newdimen\foo
a) \foo=15pt \expandafter\removept\the\foo\qquad
b) \foo=3.14pt \expandafter\removept\the\foo
****************** Fin code ******************


****************** Code 204 ******************
\def\dimtodec{\expandafter\removept\the}
\newdimen\foo
a) \foo=15pt \dimtodec\foo \qquad
b) \foo=3.14pt \dimtodec\foo
****************** Fin code ******************


****************** Code 205 ******************
a) \the\dimexpr 1cm + 0.5cm\relax \qquad
b) \the\dimexpr 1pt + 1pt\relax \qquad
c) \the\dimexpr 1pt + 2pt * 3\relax\qquad
d) \the\dimexpr (1pt + 2pt) * 3\relax\qquad
e) \the\dimexpr (1.2pt + 0.8pt) * 5\relax\qquad
f) \newdimen\foo \foo=15pt
  \the\dimexpr\foo-(\foo + 1pt) / 4\relax
****************** Fin code ******************


****************** Code 206 ******************
\the\dimexpr0,7pt + 0.4pt\relax
****************** Fin code ******************


****************** Code 207 ******************
a) \newdimen\foodim \foodim=1cm \number\foodim\relax\qquad
b) \number\dimexpr 0.7pt + 0.4pt\relax\qquad
c) \number\dimexpr 1.1pt\relax
****************** Fin code ******************


****************** Code 208 ******************
\catcode`\@11
\def\FOR#1=#2to#3\do#4#{%
       \ifempty{#4}
               {\let\FOR@increment\z@}
               {\edef\FOR@increment{\the\dimexpr#4pt\relax}}% lit et normalise l'argument optionnel
       \ifdim\FOR@increment=\z@% s'il est nul,
               \edef\FOR@increment{% le red�finir � -1pt (si #3<#2) et 1pt sinon
                       \ifdim\dimexpr#3pt-#2pt\relax<\z@ -1\else 1\fi pt
               }% \FOR@increment vaut donc 1 ou -1
       \fi
       \ifdim\dimtodec\dimexpr#3pt-#2pt\relax\dimexpr\FOR@increment\relax<\z@
               \expandafter\gobone% si argument optionnel incompatible, manger le {<code>}
       \else
               \edef#1{\dimtodec\dimexpr#2pt\relax}% initialise la \<macro>
               \edef\macro@args{% d�finit et d�veloppe les arguments � passer � \FOR@i
                       %#1=nom de la macro r�cursive :
                       \expandafter\noexpand\csname FOR@ii@\string#1\endcsname
                       \ifdim\FOR@increment<\z@ <\else >\fi% #2=signe de comparaison
                       {\FOR@increment}% #3=incr�ment
                       \noexpand#1% #4=\<macro>
                       {\the\dimexpr#3pt\relax}% #5=dimension n2
               }%
               \antefi% externalise la ligne ci-dessous de la port�e du test
               \expandafter\FOR@i\macro@args% appelle \FOR@i avec les arguments d�finis ci-dessus
       \fi
}

% #1=nom de la macro r�cursive de type "\FOR@ii@\<macro>"
% #2=signe de comparaison  % #3=incr�ment
% #4=\<macro>  % #5=dimension n2  % #6=<code> � ex�cuter
\long\def\FOR@i#1#2#3#4#5#6{%
       \def#1{% d�finit la sous macro r�cursive
               \unless\ifdim#4pt#2#5\relax% tant que la \<macro> variable n'a pas d�pass� n2
                       \afterfi{% rendre la r�cursivit� terminale
                               #6% ex�cute le code
                               \edef#4{\dimtodec\dimexpr#4pt+#3\relax}% incr�mente la \<macro>
                               #1% recommence
                       }%
               \fi
       }%
       #1% appelle la sous-macro r�cursive
}%
\def\exitFOR#1{% #1=\<macro> correspondant � la boucle de laquelle on veut sortir
       \defname{FOR@ii@\string#1}{}%
}

\def\ifexitFOR#1{% envoie vrai si on est pr�matur�ment sorti de la boucle de \<macro> #1
       % si la macro r�cursive est \empty
       \expandafter\ifx\csname FOR@ii@\string#1\endcsname\empty
               \expandafter\firstoftwo% c'est qu'on est sortir pr�matur�ment, renvoyer "vrai"
       \else
               \expandafter\secondoftwo% sinon, renvoyer "faux"
       \fi
}
\catcode`\@=12
a) \FOR\xx=1.5 to -5\do-1{"\xx" }\par

b) \FOR\ii=1 to 2.742\do.25{"\ii" }\par

c) \FOR\ii=0 to 1\do0.1{"\ii" \ifdim\ii pt>0.5pt \exitFOR\ii\fi}
****************** Fin code ******************


****************** Code 209 ******************
\newdimen\foo
\foo=15.2pt \foo=1.5\foo \the\foo% vaut 15.2*1.5
****************** Fin code ******************


****************** Code 210 ******************
\catcode`\@11
\newdimen\dim@a
\def\decmul#1#2{%
       \dim@a=#2pt    % range la dimension #2pt dans le registre de dimension
       \dim@a=#1\dim@a% multiplier le registre par le d�cimal #1
       \dimtodec\dim@a% convertir la dimension en d�cimal
}
\catcode`\@12
a) \decmul{15.2}{1.5}\qquad
b) \decmul{48.2}{.375}
****************** Fin code ******************


****************** Code 211 ******************
\def\decmul#1#2{\dimtodec\dimexpr#1\dimexpr#2pt\relax\relax}

a) \decmul{15.2}{1.5}\qquad
b) \edef\foo{\decmul{48.2}{.375}}\meaning\foo
****************** Fin code ******************


****************** Code 212 ******************
\def\decdiv#1#2{% divise le d�cimal #1 par le d�cimal #2
       \dimtodec
       \dimexpr
               \numexpr
                       \dimexpr #1pt \relax * 65536 / \dimexpr #2pt \relax
               \relax
               sp
       \relax
}

1) \decdiv{4.5}{0.075}\qquad% doit donner 60
2) \decdiv{8}{0.1}\qquad% doit donner 80
3) \decdiv{3.14}{1.6}\qquad% doit donner 1.9625
4) \decdiv{687.59829}{5.29871}\qquad% doit donner 129.76706
4) \edef\foo{\decdiv{0.37}{2.5}}\foo% doit donner 0.148
****************** Fin code ******************


****************** Code 213 ******************
\def\convertunit#1#2{%
       \dimtodec
       \dimexpr
               \numexpr
                       \dimexpr #1 \relax * 65536 / \dimexpr 1#2 \relax
               \relax
               sp
       \relax
}

a) \convertunit{15cm}{mm}\qquad
b) \convertunit{9,14in}{cm}\qquad
c) \convertunit{100000sp}{mm}\qquad
d) \convertunit{160.5pt}{cm}\qquad
e) \edef\foo{\convertunit{2,5cm}{cc}}\meaning\foo
****************** Fin code ******************


****************** Code 214 ******************
\the\glueexpr 5pt plus 2pt minus 1.5pt + 7pt plus0.5pt minus 3pt\relax \par
\the\glueexpr 25pt plus2fil + 35pt plus 0.1fill\relax
****************** Fin code ******************


****************** Code 215 ******************
foo% les caract�res font entrer TeX en mode horizontal
\kern0.5cm % espace ins�r�e en mode horizontal
bar\par% \par fait passer en mode vertical
\kern0.5cm % espace ins�r�e en mode vertical
boo
****************** Fin code ******************


****************** Code 216 ******************
Une premi�re ligne\par
\nointerlineskip% n'ins�re pas de ressort d'interligne ici
Un second paragraphe constitu� de plusieurs lignes.
Un second paragraphe constitu� de plusieurs lignes.
Un second paragraphe constitu� de plusieurs lignes.
\par% le ressort d'interligne sera ins�r� ici
Une derni�re ligne
****************** Fin code ******************


****************** Code 217 ******************
\begingroup
\offinterlineskip
La macro \litterate-\offinterlineskip-, en modifiant de fa�on appropri�e les trois
primitives \litterate-\baselineskip-, \litterate-\lineskip- et
\litterate-\lineskiplimit-, rend les boites cons�cutives jointives.

On peut constater dans ces deux paragraphes o� \litterate-\offinterlineskip- a �t�
appel�e, que les lignes sont plac�es verticalement au plus pr�s les unes des autres ce
qui rend la lecture tr�s p�nible et d�montre que le ressort d'interligne est une
n�cessit� typographique !\par
\endgroup
D�sactiver le ressort d'interligne ne se justifie que lorsque l'on doit composer
des boites contenant autre chose que du texte, sauf � vouloir des effets
typographiques sp�ciaux.
****************** Fin code ******************


****************** Code 218 ******************
\baselineskip=12pt
d�but \vtop{\hbox{ligne du haut ligne du haut ligne du haut}
\hbox{ligne du bas ligne du bas ligne du bas}
}
\par
Et la suite du texte suite du texte suite du texte
****************** Fin code ******************


****************** Code 219 ******************
\baselineskip=12pt
d�but \vtop{\hbox{ligne du haut ligne du haut ligne du haut}
\hbox{ligne du bas ligne du bas ligne du bas}
\xdef\sprevdepth{\the\prevdepth}% sauvegarde la valeur de \prevdepth
}
\par\prevdepth=\sprevdepth\relax% ment sur la boite pr�c�dente
Et la suite du texte suite du texte suite du texte
****************** Fin code ******************


****************** Code 220 ******************
\def\dummytext{Voici un texte qui ne rev�t aucune importance
       et dont le seul but est de meubler artificiellement un paragraphe. }
\begingroup% � l'int�rieur d'un groupe,
       \leftskip=0pt plus 0.5\hsize\relax
       \rightskip=\leftskip\relax % modifier les ressort d'extr�mit�s
       \spaceskip=0.3em plus 0.05em\relax% dimension de l'espace intermot
       \parfillskip=0pt \relax% annuler le ressort de fin de paragraphe
       \dummytext\dummytext\dummytext% corps du paragraphe
       \par% compose la paragraphe courant
       Juste une phrase%
       \par% compose la paragraphe courant
\endgroup% avant de sortir du groupe
****************** Fin code ******************


****************** Code 221 ******************
\def\narrowtext{%
       \par
       \begingroup
               \advance\leftskip 0.1\hsize
               \advance\rightskip 0.1\hsize
}
\def\endnarrowtext{\par\endgroup}
\def\dummytext{Ceci est un texte sans
importance destin� � meubler un paragraphe. }

\dummytext\dummytext\dummytext
\narrowtext
       \dummytext\dummytext\dummytext
\narrowtext
               \dummytext\dummytext\dummytext
\endnarrowtext
       \dummytext\dummytext\dummytext
\endnarrowtext
****************** Fin code ******************


****************** Code 222 ******************
a) \hfill Composition au fer � droite\par
b) Composition au fer � gauche\hfill\kern0pt\par
c) \hfill Centrage\hfill\kern0pt\par
d) Des \hfill mots\hfill r�guli�rement\hfill espac�s
****************** Fin code ******************


****************** Code 223 ******************
a% le caract�re "a" fait passer en mode horizontal
\hbox{b}c\hbox{d}% les \hbox sont ajout�es en mode horizontal
\medbreak
..� comparer avec...
\medbreak
a \par% \par fait passer en mode vertical
\hbox{b}% \hbox est ajout�e � la liste verticale
c% "c" fait passer en mode horizontal
\hbox{d}% la \hbox est ajout�e en mode horizontal
****************** Fin code ******************


****************** Code 224 ******************
Ligne de base : .........%
\vbox{\hbox{ligne du haut}\hbox{ligne du milieu}\hbox{ligne du bas}}%
........%
\vtop{\hbox{ligne du haut}\hbox{ligne du milieu}\hbox{ligne du bas}}.........
****************** Fin code ******************


****************** Code 225 ******************
\def\dummytext{Bla, bla, bla, un texte sans importance. }
Ligne de base.........%
\vbox{\hsize=4cm \dummytext\dummytext}%
........%
\vtop{\hsize=4cm \dummytext\dummytext}.........
****************** Fin code ******************


****************** Code 226 ******************
\newbox\foobox
a) \setbox\foobox=\hbox{foobar}% registre non vide
  Le registre est \ifvoid\foobox vide\else non vide\fi\par
b) \setbox\foobox=\hbox{foobar}
  "\box\foobox" et le registre est \ifvoid\foobox vide\else non vide\fi\par
c) \setbox\foobox=\hbox{foobar}
  "\copy\foobox" et le registre est \ifvoid\foobox vide\else non vide\fi\par
d) \setbox\foobox=\hbox{}
  Le registre est \ifvoid\foobox vide\else non vide\fi
****************** Fin code ******************


****************** Code 227 ******************
\newbox\foobox
\setbox\foobox=\hbox{Programmer est facile.}
<<\copy\foobox>>
mesure \the\wd\foobox\ de long, \the\dp\foobox\ de profondeur et \the\ht\foobox\ de haut.
\medbreak

\setbox\foobox=\vbox{\hbox{Programmer}\hbox{est}\hbox{facile.}}
<<\copy\foobox>>
mesure \the\wd\foobox\ de long, \the\dp\foobox\ de profondeur et \the\ht\foobox\ de haut.
\medbreak

\setbox\foobox=\vtop{\hbox{Programmer}\hbox{est}\hbox{facile.}}
<<\copy\foobox>>
mesure \the\wd\foobox\ de long, \the\dp\foobox\ de profondeur et \the\ht\foobox\ de haut.
****************** Fin code ******************


****************** Code 228 ******************
\def\vdim#1{\dimexpr\ht#1+\dp#1\relax}
a) \setbox\foobox=\vbox{\hbox{Programmer}\hbox{est}\hbox{facile.}}
  Verticalit� de la \litterate-\vbox- = \the\vdim\foobox\par
b) \setbox\foobox=\vtop{\hbox{Programmer}\hbox{est}\hbox{facile.}}
  Verticalit� de la \litterate-\vtop- = \the\vdim\foobox
****************** Fin code ******************


****************** Code 229 ******************
\def\countallchar#1{%
       Il y a %
       \setbox0=\hbox{\tt#1}% met #1 dans la boite
       \edef\arglength{\number\wd0 }% stocke la largeur de la boite en sp
       \setbox0=\hbox{\tt A}% met "A" dans la boite
       \edef\charlength{\number\wd0 }% stocke la largeur d'un caract�re
       $\number\arglength/\charlength % affiche la division
       =\number\numexpr\arglength/\charlength\relax$ % affiche le quotient
       caract�res%
}
\countallchar{abcd efgh}\par
\countallchar{A5 xW5 64 a1}\par
\countallchar{affligeant}
****************** Fin code ******************


****************** Code 230 ******************
\catcode`@11
\def\countchar#1#2{%
               \setbox\z@\hbox{\tt#2}% met #2 dans boite 0
               \edef\len@a{\number\wd\z@}% mesure la boite
               \setbox\z@\hbox{\tt\substin{#2}{#1}{}}% recommencer sans "#1"
               \edef\len@b{\number\wd\z@}% mesure la boite
               \setbox\z@\hbox{\tt A}% met "A" dans la boite
               \edef\charlength{\number\wd\z@}% stocke la largeur du caract�re
               \number\numexpr(\len@a-\len@b)/\charlength% et affiche le quotient
}
\catcode`@12
a) \countchar{a}{abracadabra}\qquad
b) \countchar{b}{zigzag}\qquad
c) \countchar{ }{a bc de f ghi j k }
****************** Fin code ******************


****************** Code 231 ******************
Programmer \raise1ex\hbox{en} \lower1ex\hbox{\TeX} \lower2ex\hbox{est} facile.
****************** Fin code ******************


****************** Code 232 ******************
\def\cbox#1{%
       \setbox0\vbox{#1}% met le contenu dans une \vbox
       \lower\dimexpr(\ht0-\dp0)/2\relax\box0 % l'abaisse
}

.....\cbox{\hbox{$x^2$}}......\cbox{\hbox{foo}\hbox{et bar}}......%
\cbox{\hbox{Programmer}\hbox{en \TeX}\hbox{est facile}}.......
****************** Fin code ******************


****************** Code 233 ******************
.....\cbox{\hbox{foo}\hbox{et bar}}......$\vcenter{\hbox{foo}\hbox{et bar}}$......
****************** Fin code ******************


****************** Code 234 ******************
\def\htmath{\begingroup
       \setbox0=\hbox{$\vcenter{}$}\the\ht0
\endgroup
}
L'axe math�matique se trouve � \htmath{} de la ligne de base.
****************** Fin code ******************


****************** Code 235 ******************
1) \hbox{foobar}\par
2) \hbox spread 5pt{foo\hfil bar}\par
3) \hbox spread10pt{foo\hfil bar}
****************** Fin code ******************


****************** Code 236 ******************
foobar|\rlap{/////}123456\qquad foobar|\llap{/////}123456
****************** Fin code ******************


****************** Code 237 ******************
\def\clap#1{\hbox to0pt{\hss#1\hss}}
a) avant la macro|\clap{SURIMPRESSION}apr�s la macro\medbreak
b) avant la macro|\raise2.5ex\clap{Au-dessus}\lower2.5ex\clap{Au-dessous}%
  apr�s la macro\medbreak
c) avant la macro|\raise2.5ex\llap{Au-dessus avant}\lower2.5ex\rlap{Au-dessous apr�s}%
  apr�s la macro
****************** Fin code ******************


****************** Code 238 ******************
\setbox0=\hbox{\tt//////////}
\wd0=0pt % fait croire � TeX que la larguer de la boite est nulle
Voici \copy0 du texte partiellement barr�...
****************** Fin code ******************


****************** Code 239 ******************
\def\printdim{largeur=\the\wd0 \qquad hauteur=\the\ht0 \qquad profondeur = \the\dp0 }
\setbox0=\hbox{Programmer en \TeX{} est facile}
a) \printdim\par
b) \wd0=0pt \ht0=0pt \dp0=0pt% rend toutes le dimensions nulles
  \printdim\par
c) \setbox0=\hbox{\unhbox0 }% reprend les dimensions d'origine
  \printdim
****************** Fin code ******************


****************** Code 240 ******************
\setbox0=\hbox{}% le registre 0 contient une boite vide
Le registre \ifvoid0 est vide\else n'est pas vide\fi
****************** Fin code ******************


****************** Code 241 ******************
\catcode`\@11
\def\ifzerodimbox#1{% #1=registre de boite
% revoie vrai si le registre est vide ou contient une boite de dimensions nulles
       \csname% former la macro "\firstoftwo" ou "\secondoftwo"
       \ifvoid#1first%% si le registre est vide "first"
       \else% sinon
               \ifdim\wd#1=\z@% si la largeur
                       \ifdim\ht#1=\z@% la hauteur
                               \ifdim\dp#1=\z@ first% et la profondeur=0pt, "first"
                               \else second% dans les autres cas "second"
                               \fi
                       \else second%
                       \fi
               \else second%
               \fi
       \fi
       oftwo% compl�ter avec "oftwo"
       \endcsname
}
\catcode`\@12
a) \setbox0=\hbox{}\ifzerodimbox0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par
b) \box0 % affiche la boite vide, le registre est maintenant "void"
  \ifzerodimbox0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par
c) \setbox0=\hbox{x}\ifzerodimbox0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par
d) \wd0=0pt \ht0=0pt \dp0=0pt % rend toutes les dimensions nulles
  \ifzerodimbox0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par
e) \setbox0=\vbox{}\ifzerodimbox0{vrai}{faux} (et \ifvoid0 void\else non void\fi)
****************** Fin code ******************


****************** Code 242 ******************
\def\ifvoidorempty#1{% teste si le registre #1 est vide ou contient une boite vide
       \ifvoid#1\relax
               \expandafter\firstoftwo
       \else
               \begingroup% dans un groupe
                       \setbox0=% affecter � la boite 0
                               \ifhbox#1\hbox\bgroup\unhcopy% un boite horizontale
                               \else    \vbox\bgroup\unvcopy% ou verticale
                               \fi% dans laquelle on compose
                               #1\relax% #1 en dimensions naturelles
                               \expandafter\egroup% sauter la fin de la boite
                               \expandafter% et le \endgroup
               \endgroup
               \ifnum\lastnodetype=-1 % et tester si le dernier noeud est vide
                       \expandafter\expandafter\expandafter\firstoftwo
               \else
                       \expandafter\expandafter\expandafter\secondoftwo
               \fi
       \fi
}
a) \setbox0=\hbox{}\ifvoidorempty0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par
b) \box0 % affiche la boite vide, le registre est maintenant "void"
  \ifvoidorempty0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par
c) \setbox0=\hbox{x}\ifvoidorempty0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par
d) \wd0=0pt \ht0=0pt \dp0=0pt % rend toutes les dimensions nulles
  \ifvoidorempty0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par
e) \setbox0=\vbox{}\ifvoidorempty0{vrai}{faux} (et \ifvoid0 void\else non void\fi)
****************** Fin code ******************


****************** Code 243 ******************
\newdimen\hmaxsize
\def\cvtop#1{%
       \hmaxsize=-\maxdimen% initialise � la plus petite longueur
       \doforeach\htext\in{#1}% pour chaque �l�ment :
               {\setbox0=\hbox{\htext}% stocker l'�l�ment "\htext" dans une \hbox
               \ifdim\wd0 >\hmaxsize% si sa longueur est sup�rieure � \hmaxsize
                       \hmaxsize=\wd0 % mettre � jour \hmaxsize
               \fi
               }%
       \vtop{% dans une \vtop...
               \doforeach\htext\in{#1}% pour chaque �l�ment :
                       {\hbox to\hmaxsize{\hss\htext\hss}% le centrer dans une \hbox de longueur \hmaxsize
                       }%
       }%
}

texte avant...\cvtop{Ligne du haut,Tr�s grande ligne du milieu,Ligne du bas pour finir}%
..texte apr�s
****************** Fin code ******************


****************** Code 244 ******************
\newdimen\hmaxsize
\def\cvtop#1{%
       \hmaxsize=-\maxdimen% initialise � la plus petite longueur
       \doforeach\htext\in{#1}% pour chaque �l�ment :
               {\setbox0=\hbox{\htext}% stocker l'�l�ment "\htext" dans une \hbox
               \ifdim\wd0 >\hmaxsize% si sa longueur est sup�rieure � \hmaxsize
                       \hmaxsize=\wd0 % mettre � jour \hmaxsize
               \fi
               }%
       \vtop{% dans une \vtop...
               \hsize\hmaxsize % longueur de la \vtop = \maxhsize
               \parindent=0pt % pas d'indentation
               \leftskip=0pt plus1fil minus0pt \rightskip=\leftskip% ressorts de centrage
               \doforeach\htext\in{#1}% pour chaque �l�ment :
                       {\htext\par}% le composer et finir le paragraphe
       }%
}

texte avant...\cvtop{Ligne du haut,Tr�s grande ligne du milieu,Ligne du bas pour finir}%
..texte apr�s
****************** Fin code ******************


****************** Code 245 ******************
\halign{X#**\ignorespaces&#&\hfil #\cr % pr�ambule
foo            &foo bar&123 456\cr % premi�re ligne
deuxi�me ligne &1      &12\cr % deuxi�me ligne
a              &\TeX   &1 2 3 4 5 6\cr % troisi�me ligne
\crcr}
****************** Fin code ******************


****************** Code 246 ******************
\def\cvtop#1{%
       \vtop{% \vtop assure que l'on est en mode vertical
               \substtocs\temp{#1}{,}{\cr}% dans \temp, remplacer les "," par "\cr"
               \halign{%
                       \hfil##\hfil\cr% pr�ambule : centrer le contenu
                       \temp\crcr}% mettre \temp dans l'alignement
       }% \temp est d�truite en sortant de la boite
}

texte avant...\cvtop{Ligne du haut,Tr�s grande ligne du milieu,Ligne du bas pour finir}%
..texte apr�s
****************** Fin code ******************


****************** Code 247 ******************
\def\calcmaxdim#1#2{%
       \setbox0=\vtop{% \vtop assure que l'on est en mode vertical (interne)
               \substtocs\temp{#2}{,}{\cr}% dans \temp, remplacer les "," par "\cr"
               \halign{##\hfil\cr% pr�ambule : composer au fer � gauche
                       \temp\crcr}% mettre \temp dans l'alignement
       }% \temp est d�truite en sortant de la boite
       \edef#1{\the\wd0 }%
}
a) La plus grande longueur vaut
  \calcmaxdim\foo{Ligne du haut,Tr�s grande ligne du milieu,Ligne du bas pour finir}\foo

b) V�rification : \setbox0=\hbox{Tr�s grande ligne du milieu}\the\wd0
****************** Fin code ******************


****************** Code 248 ******************
a) .......\vbox{\hrule\hbox{foo}\hbox{ligne du bas}\hrule}.......\medbreak
b) .......\vrule\vtop{\hbox{foo}\hbox{ligne du bas}}\vrule.......
****************** Fin code ******************


****************** Code 249 ******************
Une r�glure de 1.5cm :\hrule width1.5cm
foo\vrule width 2pt height .5cm depth .2cm bar
****************** Fin code ******************


****************** Code 250 ******************
\def\showdim#1{%
       \vrule width 0.4pt height 1ex  depth 0pt % trait vertical gauche
       \vrule width #1    height0.4pt depth 0pt % r�glure horizontale de longueur #1
       \vrule width 0.4pt height 1ex  depth 0pt % trait vertical droit
       \relax% stoppe la lecture de la pr�c�dente dimension
}

a) une longueur de 1 cm : \showdim{1cm}\par
b) une longueur de 137,4 pt : \showdim{137,4pt}\par
c) une longueur de 2 mm : \showdim{2mm}
****************** Fin code ******************


****************** Code 251 ******************

\frboxsep=5pt \frboxrule=1pt
\leavevmode
..%
\vbox{%
       \hrule height\frboxrule% r�glure sup�rieure
       \kern\frboxsep% espace verticale haute
       \hbox{\kern\frboxsep Programmation\kern\frboxsep}% contenu + espaces horizontales
       \kern\frboxsep% espace verticale basse
       \hrule height\frboxrule% r�glure inf�rieure
       }%
..
****************** Fin code ******************


****************** Code 252 ******************

\frboxsep=5pt \frboxrule=0.6pt
\def\FRbox#1{% /!\ ne change pas le mode H ou V en cours
       \hbox{% mettre � la suite horizontalement les 3 choses suivantes :
               \vrule width\frboxrule% 1) r�glure gauche
               \vbox{%                 2) un empilement vertical comprenant
                       \hrule height\frboxrule% a) r�glure sup�rieure
                       \kern\frboxsep%          b) espace verticale haute
                       \hbox{%                  c) contenu + espaces en mode H
                               \kern\frboxsep#1\kern\frboxsep
                       }%
                       \kern\frboxsep%          d) espace verticale basse
                       \hrule height\frboxrule% e)r�glure inf�rieure
                       }%
               \vrule width\frboxrule% 3) r�glure droite
       }%
}
Ligne de base : ...\FRbox{Programmation}...%
\frboxrule=2pt \FRbox{Programmation}...%
\frboxsep=0pt \FRbox{Programmation}...%
\frboxrule0.4pt \FRbox{Programmation}...
****************** Fin code ******************


****************** Code 253 ******************
Persuadez-vous que :
\vtop{
       \vbox{
               \hbox{Programmer}
               \hbox{en}
               \hbox{\TeX}
               \hbox{est}% <- ligne de base de la \vtop
       }
       \hbox{\it tout sauf}
       \hbox{facile.}
}
****************** Fin code ******************


****************** Code 254 ******************
%\newdimen\frboxrule \newdimen\frboxsep
\frboxrule=0.4pt \frboxsep=2pt
\def\frbox#1{% ne pas changer le mode H ou V en cours
       \hbox{% enferme dans une \hbox
               \vrule width\frboxrule% r�glure gauche
               \vtop{%
                       \vbox{% 1er �l�ment de la \vtop
                               \hrule height\frboxrule% r�glure sup�rieure
                               \kern\frboxsep% espace haut
                               \hbox{%
                                       \kern\frboxsep% espace gauche
                                       #1% contenu
                                       \kern\frboxsep% espace droite
                                       }%
                       }% puis autres �l�ments de la \vtop, sous la ligne de base
                       \kern\frboxsep% espace bas
                       \hrule height\frboxrule% r�glure inf�rieure
               }%
               \vrule width\frboxrule% r�glure droite
       }%
}
Ligne de base : ......\frbox{Programmation}......%
\frboxrule=2pt \frbox{Programmation}......%
\frboxsep=0pt \frbox{Programmation}......%
\frboxrule0.4pt \frbox{Programmation}......
****************** Fin code ******************


****************** Code 255 ******************
\def\centretitre#1{%
       \medbreak% passe en mode v puis saute une espace verticale
       \noindent% pas d'indentation et passe en mode horizontal
       \frbox{% encadre
               \vbox{% une boite verticale
                       \hsize=\dimexpr\hsize-2\frboxrule-2\frboxsep\relax
                       \parindent=0pt % pas d'indentation
                       \leftskip=0pt plus1fil \rightskip=\leftskip% ressorts de centrage
                       \parfillskip=0pt % annule le ressort de fin de paragraphe
                       #1% ins�re le titre
                       \endgraf% et le compose
                       }%
       }%
       \medbreak% passe en mode v puis saute une espace verticale
       \ignorespaces% mange les espaces situ�s apr�s la macro \centretitre
}
\frboxrule=0.8pt \frboxsep=5pt
Voici un
\centretitre{Titre}
puis un
\centretitre{Texte tr�s long pour composer un titre qui va prendre plusieurs
lignes et pour s'assurer que la composition s'effectue correctement}
****************** Fin code ******************


****************** Code 256 ******************
Une r�glure en hauteur : \vrule width 1cm height 10.4pt depth -10pt
****************** Fin code ******************


****************** Code 257 ******************
Une r�glure en dessous: \vrule width 1cm depth 2.4pt height -2pt
****************** Fin code ******************


****************** Code 258 ******************
\def\souligne#1{%
       \setbox0=\hbox{#1}% stocke le contenu dans le registre no 0
       \setbox0=\hbox{% puis, dans une \hbox, construit une r�glure
               \vrule width\wd0 % de la longueur du contenu
                       depth\dimexpr\dp0 + 1.4pt\relax % dp = profondeur texte + 1.4pt
                       height\dimexpr-\dp0 - 1pt\relax % ht = -profondeux texte - 1pt
       }%
       \wd0=0pt \dp0=0pt \ht0=0pt % annule toutes les dimensions
       \leavevmode \box0 % affiche la r�glure
       #1% puis le contenu
}
Voici \souligne{du texte normal}.\par
Voici \souligne{du texte profond}.
****************** Fin code ******************


****************** Code 259 ******************
\def\Souligne#1{%
       \setbox0=\hbox{#1}%
       \setbox0=\hbox{\vrule width\wd0 depth1.4pt height-1pt }%
       \wd0=0pt \dp0=0pt \ht0=0pt
       \leavevmode \box0 #1%
}
Voici \Souligne{du texte normal}.\par
Voici \Souligne{du texte profond}.
****************** Fin code ******************


****************** Code 260 ******************
\def\Souligne#1{%
       \setbox0=\hbox{#1}%
       \lower 1pt % abaisser � 1pt sous la ligne de base
               \rlap{% une \hbox en surimpression vers la droite
                       \vrule width\wd0 height0pt depth0.4pt % contenant le soulignement
               }%
       #1% puis afficher le <texte>
}
Voici \Souligne{du texte normal}.\par
Voici \Souligne{du texte profond}.
****************** Fin code ******************


****************** Code 261 ******************
\newdimen\stackwd \stackwd=3em % dimension horizontale interne des cadres
\catcode`@11
\def\stackbox#1{%
       \par% termine le paragraphe en cours
       \noindent
       \stackbox@i#1\\\quark\\% ajoute "\\\quark\\" � la fin et appelle \stackbox@i
       \par
}

\def\stackbox@i#1\\{% #1=ligne courante
       \def\temp@{#1}% stocke la ligne courante
       \unless\ifx\quark\temp@% si ce n'est pas la fin
               \hfill % ressort infini de centrage (et fait passer en mode horizontal)
               \noindent
               \doforeach\current@item\in{#1}% pour chaque �l�ment dans la ligne courante...
                       {\frbox{% ...encadrer
                               \hbox to\stackwd{% une \hbox de largeur \stackwd
                                       \hss% ressort de centrage
                                       \current@item% l'�l�ment courant
                                       \hss% ressort de centrage
                                       }
                               }% fin de la \frbox
                       }% fin \doforeach
               \hfill% ressort infini de centrage
               \null% assure que le dernier ressort est pris en compte
               \par% finir le paragraphe
               \nobreak% interdire une coupure de page
               \nointerlineskip% ne pas ins�rer le ressort d'interligne
               \expandafter\stackbox@i% et recommencer
       \fi
}
\catcode`@12

\frboxrule=0.5pt \frboxsep=3pt
\stackbox{a,bc,,d\\e,foobar,g\\123,456,$\alpha$,$x+y$,}
****************** Fin code ******************


****************** Code 262 ******************
a\vrule width0.2pt height15pt depth0pt \quad
a\vrule width0.2pt height0pt depth5pt \quad
a\vrule width0.2pt height10pt depth10pt \quad
a\vrule width1cm height0.2pt depth0pt
****************** Fin code ******************


****************** Code 263 ******************
\frboxsep0pt %encadrement au plus proche
\leavevmode
\frbox{a\vrule width0pt height15pt depth0pt }\quad
\frbox{a\vrule width0pt height0pt depth5pt }\quad
\frbox{a\vrule width0pt height10pt depth10pt }\quad
\frbox{a\vrule width1cm height0pt depth0pt }
****************** Fin code ******************


****************** Code 264 ******************
\def\rectangle#1#2{%
       \begingroup% dans un groupe
               \frboxsep = 0pt % encadrer au plus proche
               \frboxrule= 0.4pt % en traits assez fins
               \frbox{%
                       \vrule width#1 height0pt depth0pt %strut horizontal
                       \vrule width0pt height#2 depth0pt %strut vertical
               }%
       \endgroup% fermer le groupe
}
Carr� de 0.5 cm : \rectangle{0.5cm}{0.5cm}\smallskip

Rectangle de 2.5cm par 3pt : \rectangle{2.5cm}{3pt}
****************** Fin code ******************


****************** Code 265 ******************
\newdimen\stackwd \stackwd=3em
\catcode`\@11
\def\stackbox#1{%
       \par% termine le paragraphe en cours
       \begingroup% dans un groupe semi-simple
               \parindent=0pt% pas d'indentation
               \parskip=0pt% annuler le \parskip
               \setbox0\hbox{�gjp}% boite pour le strut
               \edef\stack@strut{\vrule width\z@ height\the\ht0 depth\the\dp0 }% d�finit le strut
               \stackbox@i#1\\\quark\\% ajoute "\\\quark\\" � la fin et appelle \stackbox@i
               \unkern% annule la derni�re compensation verticale
               \par
       \endgroup
}
\def\stackbox@i#1\\{% #1=ligne courante
       \def\temp@{#1}% stocke la ligne courante
       \unless\ifx\quark\temp@% si ce n'est pas la fin
               \hfill % ressort infini de centrage (passe en mode horizontal)
               \doforeach\current@item\in{#1}% pour chaque �l�ment dans la ligne courante...
                       {\frbox{% ...encadrer
                               \hbox to\stackwd{% une \hbox de largeur \stackwd contenant
                                       \hss%         1) ressort de centrage
                                       \stack@strut% 2) strut de dimension verticale
                                       \current@item%3) l'�lement courant
                                       \hss}%        4)ressort de centrage
                               }% fin de la \fbox
                       \kern-\frboxrule% revenir en arri�re pour superposer les r�glures verticales
                       }% fin de \doforeach
               \unkern% annuler la derni�re compensation horizontale
               \hfill% ressort infini de centrage
               \null% fait prendre en compte le dernier ressort
               \par% termine le paragraphe
               \nobreak% interdit une coupure de page
               \nointerlineskip% sinon, ne pas ajouter le ressort d'interligne
               \kern-\frboxrule% superposer les r�glures horizontales
               \expandafter\stackbox@i% et recommencer
       \fi
}
\frboxrule=0.5pt
\frboxsep=3pt
\stackbox{a,bc,,d\\e,foobar,g\\123,456,$\alpha$,$x+y$,}
****************** Fin code ******************


****************** Code 266 ******************
\catcode`\@11
\def\lineboxed#1{%
       \par% termine le paragraphe en cours
       \begingroup% dans un groupe semi-simple
               \parindent=0pt% pas d'indentation
               \parskip=0pt% annuler le \parskip
               \setbox0\hbox{�gjp}% boite pour le strut
               \edef\stack@strut{\vrule width\z@ height\the\ht0 depth\the\dp0 }% d�finit le strut
               \lineboxed@i#1\\\quark\\% ajoute "\\\quark\\" � la fin et appelle la macro r�cursive
               \unkern% annule la derni�re compensation verticale
               \par
       \endgroup
}
\def\lineboxed@i#1\\{% #1=ligne courante
       \def\temp@{#1}% stocke la ligne courante
       \unless\ifx\quark\temp@% si ce n'est pas la fin
               \cnttimestocs{#1,}{,}\nb@args% re�oit le nombre d'arguments dans la ligne courante
               \edef\dim@box{\the\dimexpr(\hsize-\frboxrule*(\nb@args+1)-
                             \frboxsep*2*\nb@args)/\nb@args}%
               \hbox{%
                       \doforeach\current@item\in{#1}% pour chaque �l�ment dans la ligne courante...
                               {\frbox{% ...encadrer
                                       \hbox to\dim@box{% une \hbox de largeur \dim@box contenant
                                               \hss%         1) ressort de centrage
                                               \stack@strut% 2) strut de dimension verticale
                                               \current@item%3) l'�lement courant
                                               \hss}%        4)ressort de centrage
                                       }% fin de la \fbox
                               \kern-\frboxrule% revenir en arri�re pour superposer les r�glures verticales
                               }% fin de \doforeach
                       \unkern% annuler la derni�re compensation horizontale
               }%
               \par% termine le paragraphe
               \nobreak% interdit une coupure de page
               \nointerlineskip% sinon, ne pas ajouter le ressort d'interligne
               \kern-\frboxrule% superposer les r�glures horizontales
               \expandafter\lineboxed@i% et recommencer
       \fi
}
\catcode`\@12
\lineboxed{a,bc,,d\\e,foobar,g\\123,456,$\alpha$,$x+y$,}\medbreak

\frboxrule=1.5pt
\frboxsep=3pt
\lineboxed{,,,,,,,\\,,\\,,,,,,}
****************** Fin code ******************


****************** Code 267 ******************
\xunit=0.5cm \yunit=0.5cm \mainrule=0.8pt \subrule=0.2pt
\def\vlap#1{\vbox to0pt{\vss#1\vss}}
\catcode`@11
\def\grid#1#2#3#4{%
       \vbox{% empiler les �l�ments verticalement
               \offinterlineskip% pas de ressort d'interligne
               \edef\total@wd{\the\dimexpr\xunit*#1\relax}% largeur totale ds r�glures
               \for\ii = 1 to #3 \do1% pour chaque carreau vertical (\ii=variable muette)
                       {\vlap{\hrule width\total@wd height\mainrule}% tracer la r�glure horizontale
                       \kern\yunit% ins�rer l'espace vertical
                       }%
               \vlap{\hrule width\total@wd height\mainrule}% derni�re r�glure horizontale
       }%
}
\catcode`@12
\setbox0\hbox{\grid{4}{}{3}{}}% range la quadrillage dans le registre no 0
Essai \copy0{} qui a pour
largeur=\convertunit{\wd0}{cm} cm et pour hauteur=\convertunit{\ht0}{cm} cm
****************** Fin code ******************


****************** Code 268 ******************
D�but\vbox to0pt{\hbox{sous}\hbox{la ligne de base}\vss}suite
****************** Fin code ******************


****************** Code 269 ******************
\xunit=0.5cm \yunit=0.5cm \mainrule=0.8pt \subrule=0.2pt
\def\vlap#1{\vbox to0pt{\vss#1\vss}}
\catcode`@11
\def\grid#1#2#3#4{%
       \vbox{% empiler les �l�ments verticalement
               \offinterlineskip% pas de ressort d'interligne
               \edef\total@wd{\the\dimexpr\xunit*#1\relax}% largeur totale de la boite
               \edef\sub@unit{\the\dimexpr\yunit/#4\relax}% hauteur verticale de la subdivision
               \for\ii = 1 to #3 \do% pour chaque unit� verticale en partant du haut, tracer :
                       {\vlap{\hrule width\total@wd height\mainrule}% la r�glure horizontale principale
                       % et dessous, les r�glures horizontales secondaires :
                       \vbox to\z@{% dans une \vbox de hauteur nulle,
                               \for\jj = 2 to #4 \do 1% ins�rer #4-1 fois sous la position courante :
                                       {\kern\sub@unit % l'espace verticale
                                       \vlap{\hrule width\total@wd height\subrule}% et la r�glure secondaire
                                       }%
                               \vss% ressort qui se comprime pour satisfaire la hauteur nulle
                       }%
                       \kern\yunit% ins�rer l'espace vertical entre r�glures principales
                       }%
               \vlap{\hrule width\total@wd height\mainrule}% derni�re r�glure principale du bas
       }%
}
\catcode`@12
\setbox0=\hbox{\grid{4}{}{3}{5}}
Essai \copy0{} qui a pour
largeur=\convertunit{\wd0}{cm} cm et pour hauteur=\convertunit{\ht0}{cm} cm
****************** Fin code ******************


****************** Code 270 ******************
\mainrule=0.8pt \subrule=0.2pt
\def\vlap#1{\vbox to0pt{\vss#1\vss}}
\catcode`@11
\def\grid#1#2#3#4{%
       \vbox{% empiler les �l�ments verticalement
               \offinterlineskip% pas de ressort d'interligne
               % #################### Trac� des r�glures verticales ####################
               \vbox to\z@{% dans une \vbox de hauteur nulle
                       \edef\total@ht{\the\dimexpr\yunit*#3\relax}% hauteur totale
                       \edef\sub@unit{\the\dimexpr\xunit/#2\relax}% espace entre 2 subdivisions
                       \rlap{% mettre � droite de la position sans bouger
                               \for\ii = 1 to #1 \do 1% pour chaque unit� horizontale
                                       {\clap{\vrule width\dimexpr\mainrule height\total@ht}% r�glure principale
                                       \rlap{% mettre � droite de la position sans bouger
                                               \for\jj = 2 to #2 \do 1% ins�rer #2-1 fois
                                                       {\kern\sub@unit % l'espace horizontal
                                                       \clap{\vrule width\subrule height\total@ht}% et la r�glure verticale
                                                       }%
                                       }%
                                       \kern\xunit % ins�rer l'espace entre r�glures horizontales
                                       }%
                               \clap{\vrule width\mainrule height\total@ht}% derni�re r�glure principale
                       }%
                       \vss% compense la hauteur=0pt de la \vbox
               }%
               % #################### Trac� des r�glures horizontales ####################
               \edef\total@wd{\the\dimexpr\xunit*#1\relax}% largeur totale de la boite
               \edef\sub@unit{\the\dimexpr\yunit/#4\relax}% espace entre 2 subdivisions
               \for\ii = 1 to #3 \do 1% pour chaque carreau vertical en partant du haut :
                       {\vlap{\hrule width\total@wd height\mainrule}% r�glure horizontale principale
                       % et dessous, les r�glures secondaires :
                       \vbox to\z@{% dans une \vbox de hauteur nulle,
                               \for\jj = 2 to #4 \do 1% ins�rer #4-1 fois sous la position courante :
                                       {\kern\sub@unit % l'espace vertical
                                       \vlap{\hrule width\total@wd height\subrule}% et la r�glure secondaire
                                       }%
                               \vss% ressort qui se comprime pour satisfaire la hauteur nulle
                       }%
                       \kern\yunit% ins�rer l'espace vertical entre r�glures principales
                       }%
               \vlap{\hrule width\total@wd height\mainrule}% derni�re r�glure horizontale
       }%
}
\catcode`@12
Grille 1 : \xunit=1cm \yunit=1cm \grid{5}{10}{2}{10}\smallskip

Grille 2 : \xunit=0.5cm \yunit=0.5cm \grid{7}{1}{3}{1}\smallskip

Grille 3 : \xunit=1.5cm \yunit=0.5cm \grid{4}{3}{3}{2}
****************** Fin code ******************


****************** Code 271 ******************
\vrule\hbox to10cm{\leaders\hbox to1.5cm{\hss A\hss}\hfill}\vrule
****************** Fin code ******************


****************** Code 272 ******************
\frboxsep=-\frboxrule \def~{\leavevmode\raise.75ex\hbox{\vrule height.2pt width1em}}
~\hbox to10cm{\leaders\hbox{\frbox{\hbox to1.5cm{\hss A\hss}}}\hfill}~

~\hbox to10cm{\cleaders\hbox{\frbox{\hbox to1.5cm{\hss A\hss}}}\hfill}~

~\hbox to10cm{\xleaders\hbox{\frbox{\hbox to1.5cm{\hss A\hss}}}\hfill}~
****************** Fin code ******************


****************** Code 273 ******************
a) \leavevmode\hbox to10cm{\leaders\hrule\hfill}\smallskip

b) \hbox to10cm{\leaders\hbox{\vrule height0.2pt width2.5mm \kern1.5mm}\hfill}

c) \vrule width0.2pt height1ex depth0pt % premi�re r�glure verticale
    \hbox to10cm{% puis r�p�tition de "_|"
    \leaders\hbox{\vrule width2em height0.2pt \vrule width0.2pt height1ex}\hfill}

d) \hbox to10cm{\leaders\hbox{%
               \vrule height.2pt width.5em% 1/2 palier bas
               \vrule height5pt width0.2pt% mont�e au palier haut
               \vrule height5pt depth-4.8pt width1em% palier haut
               \vrule height5pt width0.2pt% descente au palier bas
               \vrule height.2pt width.5em% 1/2 palier bas
               }\hfill}
****************** Fin code ******************


****************** Code 274 ******************
\mainrule=0.8pt \subrule=0.2pt
\def\carreau#1#2{% #1=nb subdiv H  #2=nb subdiv V
       \vbox to\yunit{% dans un \vbox de hauteur \yunit
               \offinterlineskip% pas de ressort d'interligne
               \vlap{\hrule height\mainrule width\xunit}% r�glure principale du haut
               \leaders% r�p�ter (ici ce sera donc #2-1 fois)
                       \vbox to\dimexpr\yunit/#2\relax% une \vbox de hauteur \yunit/#2
                               {\vss% ressort qui va s'�tirer � \yunit/#2
                               \vlap{\hrule height\subrule width\xunit}% r�glure de subdiv de dim 0pt
                               }\vfill
               \kern\dimexpr\yunit/#2\relax% derni�re espace verticale
               \vlap{\hrule height\mainrule width\xunit}% r�glure principale du bas
       }%
}
\yunit=1cm
\leavevmode \carreau{}{4} puis \carreau{}{10}
****************** Fin code ******************


****************** Code 275 ******************
\mainrule=0.8pt \subrule=0.2pt
\def\carreau#1#2{% #1=nb subdiv H  #2=nb subdiv V
       % ######## r�glures horizontales ########
       \rlap{% mettre � droite de la position sans bouger
               \vbox to\yunit{% dans un \vbox de hauteur \yunit
                       \offinterlineskip% pas de ressort d'interligne
                       \vlap{\hrule height\mainrule width\xunit}% r�glure principale du haut
                       \leaders% r�p�ter (ici ce sera #2-1 fois)
                               \vbox to\dimexpr\yunit/#2\relax% une \vbox de hauteur \yunit/#2
                                       {\vss% ressort qui va s'�tirer � \yunit/#2
                                       \vlap{\hrule height\subrule width\xunit}% r�glure de subdiv de dim 0pt
                                       }\vfill% ressort de \leaders
                       \kern\dimexpr\yunit/#2\relax% derniere espace verticale
                       \vlap{\hrule height\mainrule width\xunit}% r�glure principale du bas
               }%
       }%
       % ######## r�glures verticales ########
       \hbox to\xunit{% dans une \hbox de longueur \xunit
               \clap{\vrule height\yunit width\mainrule}% r�glure principale de gauche
               \leaders% r�p�ter (ici ce sera #1-1 fois)
                       \hbox to\dimexpr\xunit/#1\relax
                               {\hss% ressort qui va s'�tirer � \xunit/#1
                               \clap{\vrule height\yunit width\subrule}% r�glure H de dimension 0
                               }\hfill% ressort de \leaders
                       \kern\dimexpr\xunit/#1\relax% derni�re espace H
                       \clap{\vrule height\yunit width\mainrule}% r�glure principale de droite
       }%
}
\yunit=1cm \xunit=2cm
\leavevmode \carreau{3}{4} puis \carreau{8}{10}
****************** Fin code ******************


****************** Code 276 ******************
\mainrule=0.8pt \subrule=0.2pt
\def\grid#1#2#3#4{%
       \vbox to#3\yunit{% dans une boite verticale de hauteur #3*\yunit
               \leaders% r�p�ter verticalement
                       \hbox to#1\xunit{% une boite de longueur #1*\xunit
                               \leaders% dans laquelle se r�p�te horizontalement
                                       \hbox{\carreau{#2}{#4}}% le carreau de largeur \xunit
                               \hfill}%
               \vfill
       }%
}
Grille 1 : \xunit=1cm \yunit=1cm \grid{5}{10}{2}{10}\smallskip

Grille 2 : \xunit=0.5cm \yunit=0.5cm \grid{7}{1}{3}{1}\smallskip

Grille 3 : \xunit=1.5cm \yunit=0.5cm \grid{4}{3}{3}{2}
****************** Fin code ******************


****************** Code 277 ******************
\outer\def\foo{Bonjour}
\def\bar{\foo}
****************** Fin code ******************


****************** Code 278 ******************
\outer\def\foo{Bonjour}
\expandafter\def\expandafter\bar\expandafter{\noexpand\foo}
\meaning\bar

\edef\baz{\noexpand\foo}
\meaning\baz
****************** Fin code ******************


****************** Code 279 ******************
\catcode`\@11
\long\def\filedef#1#2{%
       \begingroup
               \let\input\@@input% <- utilisateurs de latex uniquement
               \everyeof{\eof@nil\noexpand}% ins�re "\eof@nil\noexpand" � la fin du fichier
               \expandafter\filedef@i\expandafter#1% d�veloppe \input #2
                       \expandafter\relax\input #2
}
\long\def\filedef@i#1#2\eof@nil{%
       \endgroup
       \expandafter\def\expandafter#1\expandafter{\gobone#2}% mange le \relax
}
\catcode`\@12
\filedef\foo{test.txt}
\meaning\foo
****************** Fin code ******************


****************** Code 280 ******************
% canal de lecture employ� dans tout ce chapitre
\def\iffileexists#1#2{% #1=canal de lecture  #2=nom du fichier
       \openin#1=#2
       \ifeof#1% le fichier n'existe pas
               \closein#1
               \expandafter\secondoftwo% renvoyer faux
       \else
               \closein#1
               \expandafter\firstoftwo% sinon renvoyer vrai
       \fi
}
a) \iffileexists\rtest{test.txt}{vrai}{faux}\qquad
b) \iffileexists\rtest{foobar.txt}{vrai}{faux}
****************** Fin code ******************


****************** Code 281 ******************
\openin\rtest =filetest.txt
\read\rtest to \foo% lit la premi�re ligne
1) Signification : \meaning\foo.\par% signification de ce qui a �t� lu
1) Ex�cution : \foo\par
\read\rtest to \foo% lit la deuxi�me ligne
2) Signification : \meaning\foo.\par
2) Ex�cution : \foo\par
\read\rtest to \foo% lit la derni�re ligne
3) Signification : \meaning\foo.\par
3) Ex�cution : \foo
\closein\rtest
****************** Fin code ******************


****************** Code 282 ******************
\openin\rtest =filetest.txt
\readline\rtest to \foo% lit la premi�re ligne
1) Signification : \meaning\foo.\par% signification de ce qui a �t� lu
1) Ex�cution : \foo\par
\readline\rtest to \foo% lit la deuxi�me ligne
2) Signification : \meaning\foo.\par
2) Ex�cution : \foo\par
\readline\rtest to \foo% lit la derni�re ligne
3) Signification : \meaning\foo.\par
3) Ex�cution : \foo
\closein\rtest
****************** Fin code ******************


****************** Code 283 ******************
Valeur de \string\endlinechar = \number\endlinechar\par
Caract�re correspondant : << \char\endlinechar{} >>
****************** Fin code ******************


****************** Code 284 ******************
\openin\rtest =filetest.txt
Ligne 1 : {\endlinechar=-1 \global\read\rtest to \foo}% lit la premi�re ligne
\meaning\foo.\par% donne ce qui a �t� lu
Ligne 2 : {\endlinechar=-1 \global\read\rtest to \foo}% lit la deuxi�me ligne
\meaning\foo.\par
Ligne 3 : {\endlinechar=-1 \global\read\rtest to \foo}% lit la derni�re ligne
\meaning\foo.
\closein\rtest
****************** Fin code ******************


****************** Code 285 ******************
\def\xread#1to#2{%
       \ifcs{#2}% si #2 est une s�quence de contr�le
               {\edef\restoreendlinechar{\endlinechar=\the\endlinechar}%
               \endlinechar=-1 % supprime le caract�re mis en fin de ligne
               \read#1to#2% lit la ligne et l'assigne � la macro #2
               \restoreendlinechar\relax% restaure le \endlinechar
               }% si #2 n'est pas une s�quence de contr�le,
               {\xread#1to}% ignorer #2, et recommencer
}

\openin\rtest =filetest.txt
Ligne 1 : \xread\rtest to \foo% lit la premi�re ligne
\meaning\foo.\par% donne ce qui a �t� lu
Ligne 2 : \xread\rtest to \foo% lit la deuxi�me ligne
\meaning\foo.\par
Ligne 3 : \xread\rtest to \foo% lit la derni�re ligne
\meaning\foo.
\closein\rtest
****************** Fin code ******************


****************** Code 286 ******************
\def\xread{% doit �tre suivie de "<nombre> to \<macro>"
       \edef\restoreendlinechar{\endlinechar=\the\endlinechar}%
       \endlinechar=-1 % neutralise \endlinechar
       \afterassignment\restoreendlinechar% apr�s l'assignation, restaurer \endlinechar
       \read% attend <nombre> to \<macro> pour effectuer l'assignation
}
\catcode`\@12

\openin\rtest =filetest.txt
Ligne 1 : \xread\rtest to \foo% lit la premi�re ligne
\meaning\foo.\par% donne ce qui a �t� lu
Ligne 2 : \xread\rtest to \foo% lit la deuxi�me ligne
\meaning\foo.\par
Ligne 3 : \xread\rtest to \foo% lit la derni�re ligne
\meaning\foo.
\closein\rtest
****************** Fin code ******************


****************** Code 287 ******************
\def\macroname{% se d�veloppe en le nom de la macro qui suit sans
              % le caract�re d'�chappement
       \ifnum\escapechar>-1 % si le caract�re d'�chappement est positif
               \ifnum\escapechar<256 % et inf�rieur � 256, d�velopper les 2 "\fi"
                       \expandafter\expandafter\expandafter\expandafter% et le "\string", puis
                       \expandafter\expandafter\expandafter\gobone% manger le "\" avec \gobone
               \fi
       \fi
       \string% doit �tre suivi d'une macro
}
\catcode`\@11
\newcount\field@cnt
\def\searchitem#1#2#3#4{% #1= canal  #2=nom fichier #3=r�f�rence  #4=macro � d�finir
       \let#4\gobone% pour l'instant, #4=\gobone
       \openin#1=#2\relax
       \unless\ifeof#1% si le fichier existe
               \lowercase{\def\sought@firstfield{#3}}% stocke le 1er champ � chercher
               \edef\macro@name{\macroname#4}% nom de la macro sans "\"
               \xread#1 to \current@line% lire la premi�re ligne
               \field@cnt=0 % initialiser le compteur de champs
               % ################ sauvegarde du nom des champs ################
               \expsecond{\doforeach\current@field\in}\current@line% pour chaque champ
                       {\advance\field@cnt1 % incr�menter le compteur de champs
                       \lowercase\expandafter{% e texte de remplacement de \current@field en minuscule
                               \expandafter\def\expandafter\current@field\expandafter{\current@field}%
                       }%
                       % sauvegarder chaque champ de la 1re ligne (qui sont les intitul�s) dans une macro
                       \letname{fieldname\number\field@cnt}=\current@field
                       }%
               \edef\field@num{\number\field@cnt}% nombre de champs
               % ################ lecture des lignes de donn�es ################
               \loop% tant que...
                       \unless\ifeof#1\relax% ...la fin du fichier n'est pas atteinte
                               \xread#1 to \current@line% lire une ligne
                               \unless\ifx\current@line\empty% si elle n'est pas vide
                                       % examniner les champs qu'elle contient (aller � \test@field)
                                       \expsecond{\expandafter\test@field\current@line\@nil}\macro@name%
                               \fi
               \repeat
       \fi
       \closein#1\relax
}

\def\test@field#1,#2\@nil#3{% #1=champ no 1 #2=autres champs #3=nom de la macro sans "\"
       \def\current@firstfield{#1}% stocke le premier champ de la ligne en cours
       \ifx\current@firstfield\sought@firstfield% s'il est �gal � celui cherch�
               \defname{#3.\csname fieldname1\endcsname}{#1}% d�finir la macros \<#3."champ 1">
               \field@cnt=1 % initialiser le compteur de champ
               \doforeach\current@field\in{#2}% puis, pour i>2, d�finir les macros \<#3."champ i">
                       {\advance\field@cnt1 % incr�menter le compteur de champ
                       \letname{#3.\csname fieldname\number\field@cnt\endcsname}=\current@field
                       }%
               \defname{#3}##1{% et d�finir la macro \<#3>
                       \ifcsname#3.##1\endcsname% si la macro \<#3."argument"> existe d�j�
                               \csname#3.##1\expandafter\endcsname% l'ex�cuter apr�s avoir mang� le \fi
                       \fi
               }%
       \fi
}
\catcode`\@12

\searchitem\rtest{fournitures.txt}{4562u}\monarticle
r�f = \monarticle{ref},
d�nomination = \monarticle{item},
prix = \monarticle{prix},
fournisseur = \monarticle{fournisseur},
champ non existant = \monarticle{foobar}.

\searchitem\rtest{fournitures.txt}{truc}\essai% r�f�rence "truc" n'existe pas
r�f = \essai{ref},
d�nomination = \essai{item},
prix = \essai{prix},
fournisseur = \essai{fournisseur}.
****************** Fin code ******************


****************** Code 288 ******************
\def\macroname{% se d�veloppe en le nom de la macro qui suit sans
              % le caract�re d'�chappement
       \ifnum\escapechar>-1 % si le caract�re d'�chappement est positif
               \ifnum\escapechar<256 % et inf�rieur � 256, d�velopper les 2 "\fi"
                       \expandafter\expandafter\expandafter\expandafter% et le "\string", puis
                       \expandafter\expandafter\expandafter\gobone% manger le "\" avec \gobone
               \fi
       \fi
       \string% doit �tre suivi d'une macro
}
\catcode`\@11
\newcount\field@cnt
\newif\ifsearch@repeat
\def\assign@arg#1=#2\@nil{%
       \def\sought@fieldnumber{#1}% no du champ � chercher
       \def\sought@fielvalue{#2}% et sa valeur
}
\def\searchitem#1#2#3#4{% #1= canal  #2=nom fichier #3=champ cherch�  #4=macro � d�finir
       \let#4\gobone% pour l'instant, #4=\gobone
       \openin#1=#2\relax%
       \unless\ifeof#1% si le fichier existe
               \edef\macro@name{\macroname#4}% nom de la macro sans "\"
               \xread#1 to \current@line% lire et ignorer la premi�re ligne
               \ifin{#3}{=}% si #3 contient =
                       {\assign@arg#3\@nil}% trouver le no de champ et sa valeur
                       {\def\sought@fieldnumber{1}% sinon, no du champ = 1
                       \def\sought@fielvalue{#3}% et sa valeur = #3
                       }%
               % ################ lecture des lignes de donn�es ################
               \search@repeattrue% poursuite de la boucle loop : vraie
               \loop% tant que...
                       \ifeof#1\relax% ...la fin du fichier n'est pas atteinte
                               \search@repeatfalse% sortir de la boucle loop
                       \else
                               \xread#1 to \current@line% lire une ligne
                               \unless\ifx\current@line\empty% si elle n'est pas vide
                                       % examniner les champs qu'elle contient (aller � \test@field)
                                       \expsecond{\expandafter\test@field\current@line\@nil}\macro@name%
                               \fi
                       \fi
                       \ifsearch@repeat% ne poursuivre que si le bool�en en vrai
               \repeat
       \fi
       \closein#1\relax
}

\def\test@field#1\@nil#2{% #1=champs #2=nom de la macro sans "\"
       \field@cnt=0 % initialiser le compteur de champ
       \doforeach\current@field\in{#1}% parcourir les champs de la ligne en cours
               {\advance\field@cnt1 % incr�menter le compteur de champ
               \ifnum\field@cnt=\sought@fieldnumber\relax% si c'est le bon num�ro de champ
                       \ifx\current@field\sought@fielvalue% et si le champ correspond � celui cherch�
                               \search@repeatfalse% sortir de la boucle loop
                               \doforeachexit% sortir de la boucle \doforeach en cours
                       \fi
               \fi
               }%
       \unless\ifsearch@repeat% si la ligne a �t� trouv�e
               \field@cnt=0 % initialiser le compteur de champ
               \doforeach\current@field\in{#1}% parcourir � nouveau les champs de la ligne
                               {\advance\field@cnt1 % incr�menter le compteur de champ
                               \letname{#2.\number\field@cnt}=\current@field% faire l'assignation
                               }%
               \defname{#2}##1{% et d�finir la macro \<#2>
                       \ifcsname#2.##1\endcsname% si la macro \<#2."argument"> existe d�j�
                               \csname#2.##1\expandafter\endcsname% l'ex�cuter apr�s avoir mang� le \fi
                       \fi
               }%
       \fi
}
\catcode`\@12
a) \searchitem\rtest{basecourse.txt}{3=283}\foo
  "\foo1", "\foo2", "\foo3", "\foo4", "\foo5", "\foo6", "\foo7"

b) \searchitem\rtest{basecourse.txt}{Valet}\bar
  "\bar1", "\bar2", "\bar3", "\bar4", "\bar5", "\bar6", "\bar{abcd}"
****************** Fin code ******************


****************** Code 289 ******************
\def\showfilecontent#1#2{% #1=canal de lecture #2=nom de fichier
       \begingroup
               \tt% s�lectionner la fonte � chasse fixe
               \openin#1=#2\relax
               \ifeof#1% si la fin du fichier est d�j� atteinte, il n'existe pas et
                       Le fichier n'existe pas% afficher le message
               \else% le fichier existe
                       \def\do##1{\catcode`##1=12 }%
                       \dospecials% neutraliser tous les tokens sp�ciaux
                       \obeyspaces% rendre l'espace actif
                       \loop
                               \xread#1 to \currline% lire une ligne
                               \unless\ifeof#1% si la fin du fichier n'est pas atteinte
                               \leavevmode\par% aller � la ligne
                               \currline% afficher la ligne lue
                       \repeat% recommencer
               \fi
               \closein#1\relax
       \endgroup
}

Contenu du fichier : "\showfilecontent\rtest{readtest.txt}", affich� tel quel
****************** Fin code ******************


****************** Code 290 ******************
\def\showfilecontent#1#2{% #1=canal de lecture #2=nom de fichier
       \begingroup
               \tt% s�lectionner la fonte � chasse fixe
               \openin#1=#2\relax
               \ifeof#1% si la fin du fichier est d�j� atteinte, il n'existe pas et
                       Le fichier n'existe pas% afficher le message
               \else% le fichier existe
                       \def\do##1{\catcode`##1=12 }%
                       \dospecials% neutraliser tous les tokens sp�ciaux
                       \obeyspaces% rendre l'espace actif
                       \def\magicpar{\let\magicpar=\par}%
                       \loop
                               \xread#1 to \currline% lire une ligne
                               \unless\ifeof#1% si la fin du fichier n'est pas atteinte
                               \leavevmode\magicpar% former le paragraphe (sauf � la 1er it�ration)
                               \currline% afficher la ligne
                       \repeat% recommencer
               \fi
               \closein#1\relax
       \endgroup
}

Contenu du fichier : "\showfilecontent\rtest{readtest.txt}", affich� tel quel
****************** Fin code ******************


****************** Code 291 ******************
% sera le canal d'�criture dans tout ce chapitre
\immediate\openout\wtest=writetest.txt % lie \wtest au fichier
\immediate\write\wtest{Programmer en \noexpand\TeX{} est   facile.}% �crit une ligne
\immediate\write\wtest{Et utile...}% puis une autre
\immediate\closeout\wtest% d�fait la liaison
a) Contenu du fichier :\par
"\showfilecontent\rtest{writetest.txt}"% affiche le contenu du fichier
\medbreak
% 2e tentative :
b) Contenu du fichier :\par
\immediate\openout\wtest=writetest.txt % lie \wtest au fichier
\immediate\write\wtest{Essai d'�criture}% �crit une ligne
\immediate\closeout\wtest% d�fait la liaison
"\showfilecontent\rtest{writetest.txt}"% affiche le contenu du fichier
****************** Fin code ******************


****************** Code 292 ******************
\def\noexpwrite#1#2{% #1=num�ro de canal  #2=texte � �crire
       \write#1{\unexpanded{#2}}%
}
\immediate\openout\wtest=writetest.txt
\immediate\noexpwrite\wtest{Programmer en \TeX{} est   facile.}%
\immediate\noexpwrite\wtest{Et utile...}%
\immediate\closeout\wtest
Contenu du fichier :\par
\showfilecontent\rtest{writetest.txt}% affiche le contenu du fichier
****************** Fin code ******************


****************** Code 293 ******************
\catcode`\@11
\def\exactwrite#1{% #1=num�ro de canal
       \begingroup
               \def\canal@write{#1}% sauvegarde le num�ro de canal
               \for\xx=0 to 255\do{\catcode\xx=12 }% donne � tous les octets le catcode 12
               \exactwrite@i% aller lire le <car>
}

\def\exactwrite@i#1{% #1 est le <car> de catcode 12
       \def\exactwrite@ii##1#1{% ##1 est le <texte> � envoyer vers le fichier
               \exactwrite@iii##1\@nil% envoyer <texte> � \exactwrite@iii
       }%
       \exactwrite@ii% va lire tout ce qui se trouve jusqu'au prochain <car>
}

{\catcode`\^^M 12 \gdef\EOL@char{^^M}}% d�finit le caract�re <EOL> de catcode 12

\def\exactwrite@iii#1\@nil{% #1 = <texte> � �crire dans le fichier
       \expsecond{\ifin{#1}}\EOL@char% si #1 contient "retour charriot"
               {\write@line#1\@nil% �crire la premi�re ligne de #1
               }
               {\immediate\write\canal@write{#1}% sinon : derni�re ligne atteinte, l'�crire
               \endgroup% puis sortir du groupe
               }%
}

% les \expandafter provoquent le 1-d�veloppement de \EOL@char :
\expandafter\def\expandafter\write@line\expandafter#\expandafter1\EOL@char#2\@nil{%
       \immediate\write\canal@write{#1}% �crit la ligne (ce qui se trouve avant ^^M)
       \exactwrite@iii#2\@nil% recommencer avec ce qui se trouve apr�s "^^M"
}
\catcode`\@12

\immediate\openout\wtest=writetest.txt % lie le canal \wtest au fichier
\exactwrite\wtest|Programmer en \TeX{} est   facile !

Et tr�s utile.|
\immediate\closeout\wtest% et fermer le fichier

Le contenu du fichier "writetest.txt" est :\par
"\showfilecontent\rtest{writetest.txt}"
****************** Fin code ******************


****************** Code 294 ******************
\catcode`\@11
\newcount\exo@number% compteur pour le num�ro d'exercice

\def\exocalctotal#1\endtotal{\edef\total@points{\dimtodec\dimexpr#1}}

\def\initexo#1{%
       \def\exo@canal{#1}% sauvegarde le canal d'�criture
       \exo@number=0 % initialiser le compteur d'exo
       \iffileexists\exo@canal{\jobname.pts}% si le fichier .pts existe
               {\input \jobname.pts }% le lire et ex�cuter son contenu
               {\def\total@points{\char`\#\char`\#}}% sinon, d�finir un total alternatif
       \immediate\openout\exo@canal=\jobname.pts % ouvrir le fichier .pts
       \immediate\write\exo@canal{\noexpand\exocalctotal}% et commencer � y �crire dedans
}

\def\exo#1{% d�finti la macro qui affiche l'exercice
       \bigbreak% sauter une grande espace verticale
       \immediate\write\exo@canal{+#1}% �crire "+#1" dans le fichier .pts
       \advance\exo@number by 1 % incr�menter le num�ro de l'exercice
       \noindent\vrule height1ex width1ex depth0pt % trace le carr�
       \kern1ex% ins�rer une espace horizontale
       {\bf Exercice \number\exo@number}% afficher "Exercice <nombre>"
       \leaders\hbox to.5em{\hss.\hss}\hfill% afficher les pointill�s
       #1/\total@points%  puis #1/<total>
       \smallbreak% composer la ligne pr�c�dente et sauter une espace verticale
}

\def\stopexo{%
       \immediate\write\exo@canal{\relax\noexpand\endtotal}%
       \immediate\closeout\exo@canal
}
\catcode`\@12
\initexo\wtest

\hfill{\bf Interrogation �crite. Sujet : \TeX{}}\hfill\null
\par
\leavevmode\hfill\vrule height.4pt width 2cm depth0pt\hfill\null
\exo{3pt}
�laborer un test \litterate/\ifonebyte{<texte>}{<vrai>}{<faux>}/ qui teste, pour une
compilation avec un moteur 8 bits, si le \litterate/<texte>/ est cod� sur un seul
octet. Ce test pourrait �tre utilis� pour d�terminer si l'encodage d'un document
est � plusieurs octets (comme l'est UTF8) en prenant comme \litterate/<texte>/
les caract�res <<~�~>>, <<~�~>>, etc.

\exo{5,5pt}
Si \verb-#1- est un nombre entier, quel est le test fait par ce code ?
\smallbreak
\hfill
\litterate/\if\string l\expandafter\firstto@nil\romannumeral#1\relax\@nil/
\hfill\null

\exo{4,5pt}
On a vu que pour provoquer un $n$-d�veloppement, les \litterate/\expandafter/se pla�aient
en nombre �gal � $2^n-1$ devant chaque token pr�c�dant celui que l'on veut d�velopper.
Or, ce nombre est {\it impair\/}. Trouver un exemple ou un cas particulier o� il faut
placer un nombre {\it pair\/} d'\litterate/\expandafter/ devant un token (on pourra
envisager le cas de 2 \litterate/\expandafter/).
\stopexo
****************** Fin code ******************


****************** Code 295 ******************
\def\identite{Foo Bar}% Pr�nom Nom
\def\beforespace#1 #2\nil{#1}
\def\afterspace#1 #2\nil{#2}
\def\prenom{\beforespace\identite\nil}
\def\nom{\afterspace\identite\nil}
Mon pr�nom : \expandafter\expandafter\prenom

Mon nom : \expandafter\expandafter\nom
****************** Fin code ******************


****************** Code 296 ******************
\newlinechar`\^^J
\immediate\openout\wtest=test1.txt
\immediate\write\wtest{Une premi�re ligne^^JEt une seconde.}
\immediate\closeout\wtest
\showfilecontent\rtest{test1.txt}
****************** Fin code ******************


****************** Code 297 ******************
\newlinechar`\^^J
\immediate\openout\wtest=test2.txt
\immediate\write\wtest{Une premi�re ligne^^JEt une seconde.}
\immediate\write\wtest{Et la derni�re.}
\immediate\closeout\wtest

{\endlinechar`\X % ins�re "X" � chaque fin de ligne
\openin\rtest=test2.txt % les fins de lignes sont comment�es
\loop%                    pour �viter que \endlinechar
       \read\rtest to \foo%    ne soit ins�r� � chaque fin de
       \unless\ifeof\rtest%    ligne du code source
       \meaning\foo\par%       affiche le texte de remplacement de \foo
\repeat%
\closein\rtest}%
****************** Fin code ******************


****************** Code 298 ******************
\catcode`\@11
\def\exactwrite#1{% #1=num�ro de canal
       \begingroup
               \for\xx=0 to 255\do{\catcode\xx=12 }% donne � tous les octets le catcode 12
               \newlinechar=`\^^M % caract�re de fin de ligne = retour charriot
               \exactwrite@i{#1}% donne le <canal> d'�criture comme premier argument
}

\def\exactwrite@i#1#2{% #2 est le caract�re d�limiteur de catcode 12
       \def\exactwrite@ii##1#2{% ##1 est le <texte> � envoyer vers le fichier
               \immediate\write#1{##1}% �crire le <texte> dans le fichier
               \endgroup% puis, sortir du groupe
       }%
       \exactwrite@ii% traiter tout ce qui se trouve jusqu'au prochain #2
}
\catcode`\@12

\immediate\openout\wtest=writetest.txt % lie le canal \wtest au fichier
\exactwrite\wtest|Programmer en \TeX{} est   facile !

Et tr�s utile.|
\immediate\closeout\wtest% et fermer le fichier

Le contenu du fichier "writetest.txt" est :\par
"\showfilecontent\rtest{writetest.txt}"
****************** Fin code ******************


****************** Code 299 ******************
\newlinechar`\^^J
\message{^^JQuel est votre nom ? }
\xread-1 to \username
\message{Bonjour \username.^^J%
Depuis combien d'ann�es pratiquez-vous TeX ? }
\read-1 to \yeartex
\message{%
       \ifnum\yeartex<5 Cher \username, vous �tes encore un d�butant !
       \else\ifnum\yeartex<10 Bravo \username, vous �tes un TeXpert !
       \else\ifnum\yeartex<15 F�licitations \username, vous �tes un TeXgourou.
       \else Passez � autre chose, par exemple � Metafont et Metapost !
       \fi\fi\fi^^J}
****************** Fin code ******************


****************** Code 300 ******************
\catcode`\@11
\def\answer@plus{+}\def\answer@minus{-}\def\answer@equal{=}%
\def\nb@found#1{% macro appel�e lorsque le nombre (argument #1) est trouv�
       \message{^^JVotre nombre est #1.^^JMerci d'avoir jou� avec moi.^^J}%
}

\def\nbguess#1#2{%
       \message{Choisissez un nombre entre #1 et #2.^^J
       Tapez entr�e lorsque c'est fait.}%
       \read-1 to \tex@guess% attend que l'on tape sur "entr�e"
       \nbguess@i{#1}{#2}%
}

\def\nbguess@i#1#2{%
       \ifnum#1<#2  \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               % si #1<#2 (donc le nombre n'est pas trouv�),
               % mettre dans \tex@guess la troncature de la moyenne de #1 et #2
               {\edef\tex@guess{\number\truncdiv{\numexpr#1+#2\relax}2}%
               \message{Je propose \tex@guess.^^J% afficher sur le terminal
               Votre nombre est-il plus grand (+), plus petit (-) ou �gal (=) : }%
               \read -1 to \user@answer% lire la r�ponse de l'utilisateur
               \edef\user@answer{%
                       \expandafter\firstto@nil\user@answer\relax\@nil% ne garder que le 1er caract�re
               }%
               \ifxcase\user@answer% envisager les cas "+", "-" et "="
                       \answer@plus{\exparg\nbguess@i{\number\numexpr\tex@guess+1\relax}{#2}}%
                       \answer@minus{\expsecond{\nbguess@i{#1}}{\number\numexpr\tex@guess-1\relax}}%
                       \answer@equal{\nb@found\tex@guess}%
               \elseif% si la r�ponse ne commence pas par "+", "-" ou "="
                       \message{Je n'ai pas compris votre r�ponse}% afficher message erreur
                       \nbguess@i{#1}{#2}% et recommencer avec les m�mes nombres
               \endif
               }
               % si #1>=#2, le nombre est trouv�
               {\nb@found{#1}}%
}
\catcode`\@12

\nbguess{1}{100}
****************** Fin code ******************


****************** Code 301 ******************
\def\syracuse#1{%
       #1% affiche le nombre
       \ifnum#1>1 % si le nombre est >1
               , % afficher une virgule+espace
               \ifodd#1 % s'il est pair
                       \exparg\syracuse% appeler la macro \syracuse
                       {\number\numexpr3*#1+1% avec 3*n+1
                       \expandafter\expandafter\expandafter}% apr�s avoir rendu la macro terminale
               \else % s'il est pair
                       \expandafter\syracuse\expandafter% appeler la macro \syracuse
                       {\number\numexpr#1/2% avec n/2
                       \expandafter\expandafter\expandafter}% apr�s avoir rendu la macro terminale
               \fi
       \else% si le nombre est 1
               .% afficher un point
       \fi
}
a) \syracuse{20}\par
b) \syracuse{14}\par
c) \syracuse{99}\par
d) \edef\foo{\syracuse{15}}\meaning\foo
****************** Fin code ******************


****************** Code 302 ******************
\def\syracuse#1{%
       #1% afficher le nombre
       \ifnum#1>1 % si le nombre est >1
               , % afficher une virgule+espace
               \exparg\syracuse{% appeler la macro \syracuse
                       \number\numexpr% avec le nombre :
                               \ifodd#1 3*#1+1% 3n+1 si #1 est impair
                               \else #1/2%      n/2 sinon
                               \fi%
                       \expandafter}% avant de rendre la r�cursivit� terminale
       \else
       .% si #1=1, afficher un point
       \fi
}
a) \syracuse{20}\par
b) \syracuse{14}\par
c) \syracuse{99}\par
d) \edef\foo{\syracuse{15}}\meaning\foo
****************** Fin code ******************


****************** Code 303 ******************
\def\factorielle#1{%
       \ifnum#1=0 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {1}% "1" si #1=0}
               {#1*\exparg\factorielle{\number\numexpr#1-1}}%
}
a) \factorielle{0}\qquad
b) \factorielle{3}\qquad
c) \edef\foo{\factorielle{8}}\meaning\foo
****************** Fin code ******************


****************** Code 304 ******************
\catcode`\@11
\def\factorielle#1{%
       \number\numexpr\factorielle@i{#1}\relax% appelle \factorielle@i
       % en lan�ant le d�veloppement maximal
}
\def\factorielle@i#1{%
       \ifnum#1=0 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {1}% "1" si #1=
               {#1*\exparg\factorielle@i{\number\numexpr#1-1}}%
}
\catcode`\@12
a) \factorielle{0}\qquad
b) \factorielle{3}\qquad
c) \edef\foo{\factorielle{8}}\meaning\foo
****************** Fin code ******************


****************** Code 305 ******************
\catcode`\@11
\def\PGCD#1#2{%
       \ifnum#1<#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {\PGCD@i{#2}{#1}}% si #1<#2, mettre #2 (le  grand) dans le premier argument
               {\PGCD@i{#1}{#2}}%
}

\def\PGCD@i#1#2{% #1=a   #2=b avec a>b
       \exptwoargs\PGCD@ii% appeler la macro r�cursive avec
                       {\number\numexpr#1-#2*\truncdiv{#1}{#2}}% le reste de a/b
                       {#2}% et le divisieur b
}

\def\PGCD@ii#1#2{% #1=reste r   #2=diviseur b
       \ifnum#1=\z@\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {#2}% si le reste est nul, renvoyer b
               {\PGCD@i{#2}{#1}}% sinon, recommencer avec b et r
}
\catcode`\@12
a) \PGCD{120}{75}\qquad
b) \PGCD{64}{180}\qquad
c) \PGCD{145}{64}\qquad
d) \edef\foo{\PGCD{1612}{299}}\meaning\foo
****************** Fin code ******************


****************** Code 306 ******************
\catcode`\@11
\def\calcPGCD#1#2{%
       \ifhmode\par\fi% si en mode horizontal, former le paragraphe
       \ifnum#1<#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {\calcPGCD@i{#2}{#1}}% si #1<#2, mettre #2 (le  grand) dans le premier argument
               {\calcPGCD@i{#1}{#2}}%
}

\def\calcPGCD@i#1#2{% #1=a   #2=b avec a>b
       \edef\calcPGCD@quotient{\number\truncdiv{#1}{#2}}% stocke le quotient
       $#1=\calcPGCD@quotient\times#2% en mode maths, afficher "a=q*b" (� suivre)
       \exptwoargs\calcPGCD@ii% appeler la macro r�cursive avec
                       {\number\numexpr#1-#2*\calcPGCD@quotient}% le reste de a/b
                       {#2}% et le divisieur b
}

\def\calcPGCD@ii#1#2{% #1=reste r   #2=diviseur b
       +#1$\par% (suite du mode math) afficher "+r", fermer le mode math et \par
       \ifnum#1=\z@\expandafter\firstoftwo\else\expandafter\secondoftwo\fi%
               {}% si le reste est nul, ne rien faire
               {\calcPGCD@i{#2}{#1}}% sinon, recommencer avec b et r
}
\catcode`\@12
\calcPGCD{39}{15}\medbreak
\calcPGCD{1612}{299}
****************** Fin code ******************


****************** Code 307 ******************
\frboxsep=0pt % encadrer au plus proche
\leavevmode\frbox{$=$} n'est pas identique � \frbox{${}={}$}
****************** Fin code ******************


****************** Code 308 ******************
\catcode`\@11
\def\calcPGCD#1#2{%
       \vtop{% mettre l'alignement dans une \vtop
               \halign{% les "#" doivent �tre doubl�s puisqu'� l'int�rieur d'une macro
               $\hfil##$&${}=\hfil##$&${}\times##\hfil$&${}+##\hfil$% pr�ambule
               \cr% fin du pr�ambule et d�but de la premi�re cellule
               \ifnum#1<#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                       {\calcPGCD@i{#2}{#1}}% si #1<#2, mettre #2 (le  grand) dans le premier argument
                       {\calcPGCD@i{#1}{#2}}%
               \crcr% fin de l'alignement
               }%
       }%
}

\def\calcPGCD@i#1#2{% #1=a   #2=b avec a>b
       \xdef\calcPGCD@quotient{\number\truncdiv{#1}{#2}}% stocke le quotient
       #1 & \calcPGCD@quotient & #2 &% afficher "a=q*b" (� suivre)
       \exptwoargs\calcPGCD@ii% appeler la macro r�cursive avec
                       {\number\numexpr#1-#2*\calcPGCD@quotient}% le reste de a/b
                       {#2}% et le divisieur b
}

\def\calcPGCD@ii#1#2{% #1=reste r   #2=diviseur b
       #1% (suite de l'alignement) afficher "+r"
       \cr% et terminer la ligne en cours
       \ifnum#1=\z@\expandafter\firstoftwo\else\expandafter\secondoftwo\fi%
               {}% si le reste est nul, ne rien faire
               {\calcPGCD@i{#2}{#1}}% sinon, recommencer avec b et r
}
\catcode`\@12
a) \calcPGCD{39}{15}\medbreak
b) \calcPGCD{1612}{299}
****************** Fin code ******************


****************** Code 309 ******************
\catcode`\@11
\def\baseconv#1{%
       \unless\ifnum#1=\z@ % si #1 est diff�rent de 0
               \number\numexpr#1-2*\truncdiv{#1}2\relax% �crire le reste
               \exparg\baseconv{\number\truncdiv{#1}2\expandafter}% recommencer avec #1/2
       \fi% apr�s que le \fi ait �t� lu
}
\catcode`\@12
a) \baseconv{43}\qquad
b) \baseconv{32}\qquad
c) \edef\foo{\baseconv{159}}\meaning\foo
****************** Fin code ******************


****************** Code 310 ******************
\catcode`\@11
\def\baseconv#1{%
       \baseconv@i{}{#1}%
}

\def\baseconv@i#1#2{% #1=restes   #2=n
       \ifnum#2=\z@\expandafter\firstoftwo\else\expandafter\secondoftwo\fi% si n=0
               {#1}% si <n>=0, afficher tous les restes
               {% sinon, recommencer en
               \exptwoargs\baseconv@i% ajoutant le reste courant avant #1
                       {\number\numexpr#2-2*\truncdiv{#2}2\relax #1}
                       {\number\truncdiv{#2}2}% et en prenant n:=n/2
               }%
}

\catcode`\@12
a) \baseconv{43}\qquad
b) \baseconv{32}\qquad
c) \edef\foo{\baseconv{159}}\meaning\foo
****************** Fin code ******************


****************** Code 311 ******************
\catcode`\@11
\def\z@@{\expandafter\z@\expandafter}
\def\basedigit#1{%
       \ifcase#1
               \z@@ 0%
               \or\z@@ 1\or\z@@ 2\or\z@@ 3\or\z@@ 4\or\z@@ 5\or\z@@ 6\or\z@@ 7%
               \or\z@@ 8\or\z@@ 9\or\z@@ A\or\z@@ B\or\z@@ C\or\z@@ D\or\z@@ E%
               \or\z@@ F\or\z@@ G\or\z@@ H\or\z@@ I\or\z@@ J\or\z@@ K\or\z@@ L%
               \or\z@@ M\or\z@@ N\or\z@@ O\or\z@@ P\or\z@@ Q\or\z@@ R\or\z@@ S%
               \or\z@@ T\or\z@@ U\or\z@@ V\or\z@@ W\or\z@@ X\or\z@@ Y\or\z@@ Z%
       \fi
}
\long\def\>#1<{\detokenize{#1}}
a) \expandafter\>\romannumeral\basedigit{23}<\quad
b) \expandafter\>\romannumeral\basedigit{6}<
\catcode`@12
****************** Fin code ******************


****************** Code 312 ******************
\catcode`\@11
\def\baseconv#1#2{% #1=base  #2=nombre � convertir
       \ifnum#1<37 % base maxi = 36 (10 signes chiffres + 26 signes lettres)
               \antefi
               \baseconv@i{}{#2}{#1}%
       \fi
}
\def\baseconv@i#1#2#3{% #1=restes  #2=n  #3=base
       \ifnum#2=\z@ \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {#1}% si n=0, afficher tous les restes
               {% si non, transmettre en dernier argument
               \expsecond{\baseconv@ii{#1}{#2}{#3}}%
                       {\number\truncdiv{#2}{#3}}% le quotient
               }%
}
\def\baseconv@ii#1#2#3#4{% #1=restes  #2=n  #3=base  #4=q
       \exparg\baseconv@i% recommencer, en ajoutant le <chiffre> avant les restes
               {\romannumeral\basedigit{\number\numexpr#2-#4*#3\relax}#1}%
               {#4}% et en rempla�ant n par q
               {#3}%
}
\def\z@@{\expandafter\z@\expandafter}%
\def\basedigit#1{%
       \ifcase#1
               \z@@ 0%
               \or\z@@ 1\or\z@@ 2\or\z@@ 3\or\z@@ 4\or\z@@ 5\or\z@@ 6\or\z@@ 7%
               \or\z@@ 8\or\z@@ 9\or\z@@ A\or\z@@ B\or\z@@ C\or\z@@ D\or\z@@ E%
               \or\z@@ F\or\z@@ G\or\z@@ H\or\z@@ I\or\z@@ J\or\z@@ K\or\z@@ L%
               \or\z@@ M\or\z@@ N\or\z@@ O\or\z@@ P\or\z@@ Q\or\z@@ R\or\z@@ S%
               \or\z@@ T\or\z@@ U\or\z@@ V\or\z@@ W\or\z@@ X\or\z@@ Y\or\z@@ Z%
       \fi
}
\catcode`\@12
a) "\baseconv{20}{21587}"\qquad
b) "\baseconv{16}{32}"\qquad
c) \edef\foo{\baseconv{16}{159}}%
  "\meaning\foo"\qquad
d) "\baseconv{2}{43}"
****************** Fin code ******************


****************** Code 313 ******************
\catcode`\@11
\def\quark@list{\quark@list}% quark de fin de liste
\def\finditem#1{% #1 = \<macrolist>, la position est lue plus tard par \finditem@i
       \exparg\finditem@i{#1}% 1-d�veloppe la \<macrolist>
}
\def\finditem@i#1#2{% #1 = liste   #2=position cherch�e
       \finditem@ii{1}{#2}#1,\quark@list,% appelle la macro r�cursive
}
\def\finditem@ii#1#2#3,{% #1=position courante  #2=position cherch�e  #3=�l�ment courant
       \ifx\quark@list#3\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {}% si la fin de liste est atteinte, ne rien renvoyer
               {% sinon
               \ifnum#1=#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                       {% si la position est la bonne
                       \finditem@iii{#3}% renvoyer #3 et manger les �l�ments restants
                       }
                       {% si la position n'est pas la bonne, recommencer en incr�mentant #1
                       \exparg\finditem@ii{\number\numexpr#1+1}{#2}%
                       }%
               }%
}
\def\finditem@iii#1#2\quark@list,{% renvoyer #1 et manger le reste de la liste
       #1%
}
\catcode`\@12
\def\liste{a,bcd,{ef},g,hij,kl}
a) \edef\foo{\finditem\liste5}\meaning\foo\qquad
b) \edef\bar{\finditem\liste3}\meaning\bar
****************** Fin code ******************


****************** Code 314 ******************
\catcode`\@11
\def\quark@list{\quark@list}% quark de fin de liste
\def\finditem#1{% #1 = \<macro>, la position est lue plus tard par \finditem@i
       \exparg\finditem@i{#1}% 1-d�veloppe la \<macro>
}
\def\finditem@i#1#2{% #1 = liste   #2=position cherch�e
       \ifnum#2>\z@% ne faire quelque chose que si la position est >0
               \antefi
               \finditem@ii{1}{#2}\relax#1,\quark@list,% appelle la macro r�cursive
       \fi
}
\def\finditem@ii#1#2#3,{% #1=position courante  #2=position cherch�  #3=�l�ment courant
       \expandafter\ifx\expandafter\quark@list\gobone#3%
       \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {}% si la fin de liste est atteinte, ne rien renvoyer
               {% sinon
               \ifnum#1=#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                       {% si la position est la bonne
                       \finditem@iii{#3}% renvoyer #3 et manger les �l�ments restants
                       }
                       {% si la position n'est pas la bonne, recommencer en incr�mentant #1
                       \exparg\finditem@ii{\number\numexpr#1+1}{#2}\relax
                       }%
               }%
}
\def\finditem@iii#1#2\quark@list,{% renvoyer #1 et manger le reste de la liste
       \gobone#1%
}
\def\finditemtocs#1#2#3{% #1 = \<macro>  #2=position  #3=macro � d�finir
       \def\finditemtocs@iii##1##2\quark@list,{% renvoyer #1 et manger le reste de la liste
               \expandafter\def\expandafter#3\expandafter{\gobone##1}%
       }%
       \let#3=\empty
       \exparg\finditemtocs@i{#1}{#2}% 1-d�veloppe la \<macro>
}
\def\finditemtocs@i#1#2{% #1 = liste   #2=position cherch�e
       \ifnum#2>\z@% ne faire quelque chose que si la position est >0
               \antefi\finditemtocs@ii{1}{#2}\relax#1,\quark@list,% appelle la macro r�cursive
       \fi
}
\def\finditemtocs@ii#1#2#3,{%
% #1=position courante  #2=position cherch�  #3=\relax + �l�ment courant
       \expandafter\ifx\expandafter\quark@list\gobone#3%
       \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {}% si fin de liste ne rien faire. Sinon, si position bonne
               {\ifnum#1=#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                       {\finditemtocs@iii{#3}% renvoyer #3 et manger les �l�ments restants
                       }% si la position n'est pas la bonne, recommencer en incr�mentant #1
                       {\exparg\finditemtocs@ii{\number\numexpr#1+1}{#2}\relax%
                       }%
               }%
}
\catcode`\@12
\def\liste{a,bcd,{ef},g,hij,kl}
a) "\finditem\liste5"\qquad
b) \edef\bar{\finditem\liste3}\meaning\bar\qquad
c) \finditemtocs\liste{3}\foo\meaning\foo
****************** Fin code ******************


****************** Code 315 ******************
\catcode`\@11
\def\quark@list{\quark@list}% quark de fin de liste
\def\positem#1{% #1 = \<macrolist>, la position est lue plus tard par \positem@i
       \def\positem@endprocess{\pos@item}% hook : afficher la position
       \exparg\positem@i{#1}% 1-d�veloppe la \<macrolist>
}
\def\positem@i#1#2{% #1 = liste   #2=�l�ment cherch�
       \def\sought@item{#2}% d�finir l'�l�ment cherch�
       \positem@ii{1}\relax#1,\quark@list,% appelle la macro r�cursive
}
\def\positem@ii#1#2,{% #1=position courante  #2=\relax + �l�ment courant
       \expandafter\def\expandafter\current@item\expandafter{\gobone#2}%
       \ifx\current@item\quark@list\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {\def\pos@item{0}% si la fin de liste est atteinte, renvoyer 0
               \positem@endprocess% et aller au hook
               }% sinon
               {\ifx\current@item\sought@item\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                       {\def\pos@item{#1}% si la position est la bonne, d�finir la position
                       \positem@goblist% et manger les �l�ments restants
                       }% si la position n'est pas la bonne, recommencer en incr�mentant #1
                       {\exparg\positem@ii{\number\numexpr#1+1}\relax
                       }%
               }%
}
\def\positem@goblist#1\quark@list,{\positem@endprocess}% manger la liste et aller au hook

\def\positemtocs#1#2#3{% #1=\<macrolist>  #2=�l�ment � chercher  #3=macro � d�finir
       \def\positem@endprocess{\let#3=\pos@item}% hook : mettre le r�sultat dans #3
       \exparg\positem@i{#1}{#2}% 1-d�veloppe la \<macrolist>
}

\catcode`\@12
\def\liste{a,bcd,{ef},g,hij,,kl}
a) \positem\liste{g}\qquad
b) \positem\liste{ef}\qquad
c) \positem\liste{{ef}}\qquad
d) \positem\liste{}\medbreak

\def\liste{a,bcd,{ef},g,hij,,kl}
a) \positemtocs\liste{g}\foo\meaning\foo\qquad
b) \positemtocs\liste{ef}\foo\meaning\foo\qquad
c) \positemtocs\liste{{ef}}\foo\meaning\foo\qquad
d) \positemtocs\liste{}\foo\meaning\foo\qquad
****************** Fin code ******************


****************** Code 316 ******************
\catcode`\@11
\def\quark@list{\quark@list}% quark de fin de liste
\def\insitem#1#2#3{% #1 = macro   #2=position cherch�e   #3=�l�ment � ins�rer
       \let\item@list=\empty
       \ifnum#2<1 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               % si position < 1
               {\addtomacro\item@list{#3,}% ajouter l'�lement � ins�rer en premier
               \eaddtomacro\item@list#1% puis la liste enti�re
               }
               % si la position  > 1
               {% d�finir la macro r�cursive
               \def\insitem@i##1##2,{% ##1 = position courante  ##2=\relax + �l�ment courant
                       \expandafter\ifx\expandafter\quark@list\gobone##2%
                       \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                               {\addtomacro\item@list{#3}}% si fin de liste, ajouter l'�l�ment en dernier
                               {% sinon, si la position cherch�e est atteinte
                               \ifnum##1=#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                                       {\addtomacro\item@list{#3,}% ajouter l'�lement
                                       \add@remainlist##2,% et ##2 (en supprimant le \relax) et le reste
                                       }% si la position n'est pas atteinte
                                       {\eaddtomacro\item@list{\gobone##2,}% ajouter l'�l�ment
                                       \exparg\insitem@i{\number\numexpr##1+1}\relax% et recommencer
                                       }%
                               }%
                       }%
               % appel de la macro r�cursive
               \expandafter\insitem@i\expandafter1\expandafter\relax#1,\quark@list,%
               }%
       \let#1=\item@list% rendre #1 �gal au r�sultat
}

\def\add@remainlist#1,\quark@list,{%
       \eaddtomacro\item@list{\gobone#1}% ajouter #1 ainsi que les autres
}
\catcode`\@12
\def\liste{a,bra,{cA},da,brA}\insitem\liste3{XX}\meaning\liste\par
\def\liste{a,bra,{cA},da,brA}\insitem\liste0{XX}\meaning\liste\par
\def\liste{a,bra,{cA},da,brA}\insitem\liste9{XX}\meaning\liste
****************** Fin code ******************


****************** Code 317 ******************
\catcode`\@11
\def\quark@list{\quark@list}% quark de fin de liste
\def\delitem#1#2{% #1 = macro   #2=position cherch�e
       \ifnum#2>0 % ne faire quelque chose que si la position est >0
               \def\delitem@i##1##2,{% ##1 = position courante  ##2=\relax + �l�ment courant
                       \expandafter\ifx\expandafter\quark@list\gobone##2%
                       \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                               {}% si fin de liste, ne rien faire
                               {% sinon, si la position cherch�e est atteinte
                               \ifnum##1=#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                                       {\add@reaminingitems% et ##2 (en supprimant le \relax) et le reste
                                       }% si la position n'est pas la bonne
                                       {\eaddtomacro\item@list{\gobone##2,}% ajouter l'�l�ment
                                       \exparg\delitem@i{\number\numexpr##1+1}\relax% et recommencer
                                       }%
                               }%
                       }%
               \let\item@list=\empty% initialiser la macro tempporaire
               % appel de la macro r�cursive
               \expandafter\delitem@i\expandafter1\expandafter\relax#1,\quark@list,%
               \let#1=\item@list% rendre #1 �gal au r�sultat
       \fi
}

\def\add@reaminingitems#1\quark@list,{%
       \eaddtomacro\item@list{#1}% ajouter tout jusqu'au quark
}
\catcode`\@12
\for\xx=0 to 8 \do{%
\def\liste{a,bcd,{ef},g,hij,kl}
position \xx{} : \expandafter\delitem\expandafter\liste\xx\meaning\liste.\par
}
****************** Fin code ******************


****************** Code 318 ******************
\catcode`\@11
\def\moveitem#1#2#3{% #1 = liste, #2=position d�part, #3=position arriv�e
       \ifnum#2>0 % ne faire quemque chose que si #2>0
               \finditemtocs#1{#2}\temp@item% sauvegarder l'�l�ment
               \delitem#1{#2}% supprimer l'�l�ment
               \expsecond{\insitem#1{#3}}\temp@item% ins�rer l'�l�ment
       \fi
}
\catcode`\@12
% d�place "b" en 5e position
a) \def\liste{a,b,c,d,e,f} \moveitem\liste25 "\liste"\par
% d�place "d" en 1e position
b) \def\liste{a,b,c,d,e,f} \moveitem\liste41 "\liste"\par
% d�place "c" en 9e position
c) \def\liste{a,b,c,d,e,f} \moveitem\liste39 \liste"\par
% position d�part=0 -> sans effet
d) \def\liste{a,b,c,d,e,f} \moveitem\liste02 "\liste"
****************** Fin code ******************


****************** Code 319 ******************
\catcode`\@11
\def\runlist#1\with#2{% #1=liste #2=macro
       \def\runlist@i##1,{%
               \ifx\quark@list##1\relax\else% si la fin n'est pas atteinte
                       \addtomacro\collect@run{#2{##1}}% ajouter "\<macro>{<�l�ment>}""
                       \expandafter\runlist@i% et recommencer en lisant l'�l�ment suivant
               \fi
       }%
       \begingroup% fait la collecte dans un groupe
               \let\collect@run=\empty% initialiser la macro
               \expandafter\runlist@i#1,\quark@list,% appeler \runlist@i
       \expandafter\endgroup% ferme le groupe et d�truit \collect@run
       \collect@run% apr�s l'avoir d�velopp� !
}
\catcode`\@12
\newcount\foocnt
\foocnt=0 % compteur utilis� pour num�roter les �l�ments dans la macro \foo
\def\foo#1{% la macro qui va ex�cuter chaque �l�ment de la liste. #1 = l'�l�ment
       \advance\foocnt1 % incr�mente le compteur
       L'argument \number\foocnt\ est : {\bf #1}\par%
}
\def\liste{a,bra,ca,da,BRA}%
\runlist\liste\with\foo%
****************** Fin code ******************


****************** Code 320 ******************
\catcode`\@11
\def\ifspacefirst#1{%
       \expandafter\ifspacefirst@i\detokenize{#1W} \@nil% "W" se pr�munit d'un argument vide
}
\def\ifspacefirst@i#1 #2\@nil{\ifempty{#1}}% renvoyer vrai s'il n'y a rien avant " "
\catcode`\@12
a) \ifspacefirst{a bc d}{vrai}{faux}\qquad
b) \ifspacefirst{ a bc d}{vrai}{faux}\qquad
c) \ifspacefirst{ }{vrai}{faux}\qquad
d) \ifspacefirst{}{vrai}{faux}\qquad
e) \ifspacefirst{{ } }{vrai}{faux}\qquad
f) \ifspacefirst{ {x} }{vrai}{faux}
****************** Fin code ******************


****************** Code 321 ******************
\catcode`\@11
\expandafter\def\expandafter\gobspace\space{}

\def\removefirstspaces#1{%
       \ifspacefirst{#1}% si #1 commence par un espace
               {\exparg\removefirstspaces{\gobspace#1}}% recommencer sans le 1er espace
               {#1}% sinon, renvoyer l'argument
}
\catcode`\@12
a) "\removefirstspaces{12 {\bf3}4 567}"\qquad
b) "\removefirstspaces{ 12 {\bf3}4 567}"\qquad
c) \edef\foo{\space\space\space 12 34 567}
  "\exparg\removefirstspaces\foo"
****************** Fin code ******************


****************** Code 322 ******************
\catcode`\@11
\def\removefirstspaces{%
       \romannumeral% lance le d�veloppement maximal
       \removefirstspaces@i% et passe la main � la macro r�cursive
}

\def\removefirstspaces@i#1{%
       \ifspacefirst{#1}% si #1 commence par un espace
               {\exparg\removefirstspaces@i{\gobspace#1}}% recommencer sans le 1er espace
               {\z@#1}% sinon, renvoyer l'argument o� \z@ stoppe l'action de \romannumeral
}
\catcode`\@12
\long\def\>#1<{"\detokenize{#1}"}

a) \expandafter\expandafter\expandafter\>\removefirstspaces{12 {\bf3}4 567}<\qquad
b) \expandafter\expandafter\expandafter\>\removefirstspaces{ 12 {\bf3}4 567}<\qquad
c) "\removefirstspaces{ 12 {\bf3}4 }"
****************** Fin code ******************


****************** Code 323 ******************
\catcode`\@11
\edef\catcodezero@saved{\number\catcode0 }% stocke le catcode de ^^00
\catcode0=12 % le modifie � 12
\def\removelastspaces#1{%
       \romannumeral% lance le d�veloppement maximal
       \removelastspaces@i\relax#1^^00 ^^00\@nil% mettre un \relax au d�but
                                                % et passer la main � \removelastspaces@i
}
\def\removelastspaces@i#1 ^^00{% prendre ce qui est avant " W"
       \removelastspaces@ii#1^^00% ajouter "W"
}
\def\removelastspaces@ii#1^^00#2\@nil{% #1=ce qui est avant "W"  #2=reliquat
       \ifspacefirst{#2}% si le reliquat commence par un espace
               {\removelastspaces@i#1^^00 ^^00\@nil}% recommencer sans passer par \removelastspaces
               {\expandafter\z@\gobone#1}% sinon supprimer le \relax ajout� au d�but
                                         % et stopper l'action de \romannumeral avec \z@
}
\catcode0=\catcodezero@saved\relax% restaure le catcode de ^^00
\catcode`\@12
\long\def\>#1<{"\detokenize{#1}"}

a) \expandafter\expandafter\expandafter\>\removelastspaces{ 12 {\bf3}4 }<\qquad
b) \expandafter\expandafter\expandafter\>\removelastspaces{12 {\bf3}4}<\qquad
c) "\removelastspaces{ 12 {\bf3}4 }"
****************** Fin code ******************


****************** Code 324 ******************
\catcode`\@11
\def\removetrailspaces#1{%
       \romannumeral% lance le d�veloppement maximal
               \expandafter\expandafter\expandafter% le pont d'\expandafter
       \removelastspaces
               \expandafter\expandafter\expandafter% fait agir \removefirstspaces en premier
       {%
               \expandafter\expandafter\expandafter
       \z@% stoppe le d�veloppement initi� par \romannumeral
       \removefirstspaces{#1}%
       }%
}
\catcode`\@12
\long\def\>#1<{"\detokenize{#1}"}

a) \expandafter\expandafter\expandafter\>\removetrailspaces{ 12 {\bf3}4 }<\qquad
b) \expandafter\expandafter\expandafter\>\removetrailspaces{12 {\bf3}4}<\par
c) \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter
  \foo\expandafter\expandafter\expandafter{\removetrailspaces{ 12 {\bf3}4 }}%
  signification : \meaning\foo.\par
c) ex�cution : "\foo"\par
d) "\removetrailspaces{ 12 {\bf3}4 }"
****************** Fin code ******************


****************** Code 325 ******************
\catcode`\@11
\def\sanitizelist#1{% #1 = liste
       \let\item@list\empty% initialise le r�ceptacle de la liste assainie
       \def\sanitizelist@endprocess{% d�finit le hook de fin
               \expandafter\remove@lastcomma\item@list\@nil% supprimer derni�re virgule
               \let#1=\item@list% et assigner le r�sultat � #1
       }%
       \expandafter\sanitizelist@i\expandafter\relax#1,\quark@list,% aller � la macro r�cursive
}

\def\sanitizelist@i#1,{% #1="\relax" + �l�ment courant
       \expandafter\ifx\expandafter\quark@list\gobone#1%
       \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {\sanitizelist@endprocess% si fin de liste, hook de fin
               }% si la fin de la liste n'est pas atteinte :
               {\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter
                       \addtomacro% 1-d�velopper \gobone pour retirer \relax
               \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter
                       \item@list% puis 2-d�velopper \removetrailspaces
               \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter
                       {\expandafter\removetrailspaces\expandafter{\gobone#1},}% "#1"
               \sanitizelist@i\relax% et continuer avec l'�l�ment suivant
               }%
}

\catcode`\@12
\frboxsep=0pt % encadrer au plus proche
\def\foo#1{\frbox{\tt\strut#1} }% boite avec un strut et en fonte "tt" puis espace
\def\liste{ Programmer, en \TeX{} ,est   ,{\bf facile}, et utile }
a) \runlist\liste\with\foo% encadrer les items

b) \sanitizelist\liste% supprimer les espaces inutiles des items
  \runlist\liste\with\foo
****************** Fin code ******************


****************** Code 326 ******************
\catcode`\@11
\def\boxsentence#1{%
       \leavevmode% se mettre en mode horizontal
       \boxsentence@i#1\quark% transmet "#1+\quark" � boxsentence@i
}
\def\boxsentence@i#1{% #1= argument lu
       \def\current@arg{#1}% stocke l'argument dans une macro temporaire
       \unless\ifx\quark\current@arg% si la fin n'est  pas atteinte
               \frbox{#1}% encadrer cet argument
               \expandafter\boxsentence@i% lire l'argument suivant
       \fi
}
\catcode`@12
\frboxsep=1pt \frboxrule=0.2pt
\boxsentence{Programmer en \TeX\ est facile}
****************** Fin code ******************


****************** Code 327 ******************
\catcode`\@11
\edef\star@macro{\string *}% stocke une �toile de catcode 12
\def\expo#1{%
       \def\temp@arg{#1}% stocke l'argument lu
       \ifx\star@macro\temp@arg\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {% si l'argument est une �toile de catcode 12
               $^\dag$% affiche une dague
               }% sinon
               {$^\ddag$% affiche une double dague
               {#1}% puis r�-�crit l'argument {#1}
               }%
}
A\expo B\expo*C
****************** Fin code ******************


****************** Code 328 ******************
\def\boxsentence#1{%
       \readtok#1\quark% met le token d'arr�t \quark � la fin de #1
}
\def\readtok{\afterassignment\cmptok\let\nxttok= }
\def\cmptok{%
       \unless\ifx\nxttok\quark% si la fin n'est pas atteinte
               \frbox{\nxttok}%  encadrer le token lu
               \expandafter\readtok% puis aller lire le suivant
       \fi
}
\frboxsep=1pt \frboxrule=0.2pt
\leavevmode\boxsentence{Programmer en \TeX\ est facile}
****************** Fin code ******************


****************** Code 329 ******************
\def\permutstart{\afterassignment\cmptok\let\nxttok= }
\def\permutend{\permutend}%
\def\cmptok{%
       \unless\ifx\permutend\nxttok% tant que la fin n'est pas atteinte :
               \ifxcase\nxttok
               ae% si le token lu est "a", afficher un "e"
               ei io ou uy ya% etc pour les autres lettres
               \elseif
                       \nxttok% si ce n'est aucune voyelle, afficher le token
               \endif
               \expandafter\permutstart% aller lire le token suivant
       \fi
}
\permutstart Un "a" puis "e puis "i" ensuite, un "o", un "u" et "y".\permutend
****************** Fin code ******************


****************** Code 330 ******************
\def\boxsentence#1{\readtok#1\boxsentence}
\def\readtok{\afterassignment\cmptok\let\nxttok= }
\def\cmptok{%
       %\show\nxttok% � d�commenter pour d�bogage
       \unless\ifx\nxttok\boxsentence
               \frbox{\nxttok}%
               \expandafter\readtok
       \fi
}
\frboxsep=1pt \frboxrule=0.2pt
\leavevmode\boxsentence{Pro{gra}mmer en \TeX\ est facile}
****************** Fin code ******************


****************** Code 331 ******************
\catcode`\@11
\def\Litterate{%
       \begingroup% ouvrir un groupe
               \tt% et adopter une fonte � chasse fixe
               \afterassignment\Litterate@i% apr�s l'assignation, aller � \Litterate@i
               \expandafter\let\expandafter\lim@tok\expandafter=\string% \lim@tok = token d�limiteur
}
\def\Litterate@i{%
               \afterassignment\Litterate@ii%apr�s avoir lu le prochain token, aller � \Litterate@ii
               \expandafter\let\expandafter\nxttok\expandafter=\string% lit le token suivant
}
\def\Litterate@ii{%
       \ifx\nxttok\lim@tok% si le token suivant="token d�limiteur"
               \endgroup% fermer le groupe et finir
       \else
               \nxttok% sinon, afficher ce token
               \expandafter\Litterate@i% et lire le token suivant
       \fi
}
\catcode`\@12
\Litterate|Programmer     en \TeX {} est << facile >> !|
****************** Fin code ******************


****************** Code 332 ******************
\catcode`\@11
\def\Litterate{%
       \begingroup% ouvrir un groupe
               \tt% et adopter une fonte � chasse fixe
               \afterassignment\Litterate@i% apr�s l'assignation, aller � \Litterate@i
               \expandafter\let\expandafter\lim@tok\expandafter=\string% \lim@tok = token d�limiteur
}
\def\Litterate@i{%
       \afterassignment\Litterate@ii% apr�s avoir lu un token, aller � \Litterate@ii
               \expandafter\expandafter\expandafter% 1-d�velopper \string
       \let
               \expandafter\expandafter\expandafter% puis 1-d�velopper \space en " "
       \nxttok
               \expandafter\expandafter\expandafter
       =\expandafter\space\string% et lire le token obtenu
}
\def\Litterate@ii{%
       \ifx\nxttok\lim@tok% si le token suivant="token d�limiteur"
               \endgroup% fermer le groupe et finir
       \else
               \nxttok% sinon, afficher ce token
               \expandafter\Litterate@i% et lire le token suivant
       \fi
}
\catcode`\@12
\Litterate|Programmer     en \TeX {} est << facile >> : $~$^_#|
****************** Fin code ******************


****************** Code 333 ******************
\catcode`@11
\newskip\ltr@spc
\def\letterspace#1#2{%
       \ltr@spc=#1\relax % assigne le ressort
       \letterspace@i#2\letterspace@i% appelle la macro \letterspace@i
}
\def\letterspace@i{%
       \afterassignment\letterspace@ii
       \let\nxttok=
}
\def\letterspace@ii{%
       \ifx\nxttok\letterspace@i% si la fin est atteinte
               \unskip% supprimer le dernier ressort qui est de trop
       \else
               \nxttok% afficher le token
               \hskip\ltr@spc\relax% ins�re le ressort
               \expandafter\letterspace@i% va lire le token suivant
       \fi
}
\catcode`@12
Voici "\letterspace{0.3em}{des lettres espac�es}"
et voici "\letterspace{-0.075em}{de la compression}".
****************** Fin code ******************


****************** Code 334 ******************
\catcode`@11
\newcount\test@cnt
\def\ifinteger#1{%
       \ifstart{#1}{-}% si "-" est au d�but de #1
               {\exparg\ifinteger{\gobone#1}% l'enlever et recommencer
               }
               {\ifempty{#1}% sinon, si #1 est vide
                       \secondoftwo% lire l'argument <faux>
                       {\afterassignment\after@number% sinon, apr�s l'assignation, aller � \after@number
                       \test@cnt=0#1\relax% faire l'assignation
                                          %(\relax termine le nombre et n'est pas mang�)
                       }%
               }%
}
\def\after@number#1\relax{% #1 est ce qui reste apr�s l'assignation
       \ifempty{#1}% teste si #1 est vide et lit l'argument <vrai> ou <faux> qui suit
}

\catcode`@12
1) \ifinteger{5644}{oui}{non}\qquad
2) \ifinteger{-987}{oui}{non}\qquad
3) \ifinteger{6a87}{oui}{non}\qquad
4) \ifinteger{abcd}{oui}{non}\qquad
5) \ifinteger{-a}{oui}{non}\qquad
6) \ifinteger{-}{oui}{non}\qquad
7) \ifinteger{3.14}{oui}{non}
****************** Fin code ******************


****************** Code 335 ******************
\catcode`\@11
\def\teststar{%
       \futurelet\nxttok\teststar@i% % pioche le token suivant puis aller � \teststar@i
}
\def\teststar@i{%
       \ifx *\nxttok\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {% si le token suivant est une �toile
               \afterassignment\teststar@bf% apr�s avoir lu "*", aller � \teststar@bf
               \let\nxttok= % lire l'�toile
               }% si le token n'est pas une �toile
               {\teststar@it% aller � \teststar@it
               }%
}
\def\teststar@bf#1{{\bf#1}}% lit l'argument et le compose en gras dans un groupe
\def\teststar@it#1{{\it#1\/}}% lit l'argument et le compose en italique
\catcode`\@12
Un essai \teststar{r�ussi} et un essai \teststar*{�toil�} r�ussi aussi.
****************** Fin code ******************


****************** Code 336 ******************
\catcode`@11
\def\deftok#1#2{\let#1= #2\empty}% d�finit le token #1 (\empty au cas o� #2 est vide)
\deftok\sptoken{ }
\def\ifnexttok#1#2#3{% lit les 3 arguments : #1=token #2=code vrai #3=code faux
       \deftok\test@tok{#1}% stocke le token cherch�
       \def\true@code{#2}\def\false@code{#3}% et les codes � ex�cuter
       \ifnexttok@i% aller � la macro r�cursive
}
\def\ifnexttok@i{%
       \futurelet\nxttok\ifnexttok@ii% piocher le token d'apr�s et aller � \ifnexttok@ii
}
\def\ifnexttok@ii{%
       \ifx\nxttok\sptoken% si le prochain token est un espace
               \def\donext{%
                       \afterassignment\ifnexttok@i% recommencer apr�s
                       \let\nxttok= % apr�s avoir absorb� cet espace
               }%
       \else
               \ifx\nxttok\test@tok% si le prochain token est celui cherch�
                       \let\donext\true@code% ex�cuter le code vrai
               \else
                       \let\donext\false@code% sinon code faux
               \fi
       \fi
       \donext% faire l'action d�cid�e ci-dessus
}
\catcode`@12
\ifnexttok W{je vais lire un W : }{je ne vais pas lire un W : }W.\par
\ifnexttok W{je vais lire un W : }{je ne vais pas lire un W : }a.\par
\ifnexttok *{je vais lire une �toile : }{je ne vais pas lire une �toile : } *.\par
\ifnexttok *{je vais lire une �toile : }{je ne vais pas lire une �toile : }a.
****************** Fin code ******************


****************** Code 337 ******************
\catcode`@11
\newif\iftestspace \testspacefalse
\def\deftok#1#2{\let#1= #2}\deftok\sptoken{ }
\def\ifnexttok#1#2#3{% #1=token #2=code vrai #3=code faux
       \let\test@tok= #1% stocke le token � tester
       \def\true@code{#2}\def\false@code{#3}% et les codes � ex�cuter
       \iftestspace \def\ifnexttok@i{\futurelet\nxttok\ifnexttok@ii}%
       \else        \def\ifnexttok@i{\futurelet\nxttok\ifnexttok@iii}%
       \fi% apr�s avoir d�fini la macro r�cursive selon le bool�en,
       \ifnexttok@i% l'ex�cuter
}
\def\ifnexttok@ii{% macro "normale" qui ne teste pas les espaces
       \ifx\nxttok\test@tok \expandafter\true@code% ex�cuter le code vrai
       \else                \expandafter\false@code% sinon code faux
       \fi
}
\def\ifnexttok@iii{% macro qui ignore les espaces
       \ifx\nxttok\sptoken% si le prochain token est un espace
               \def\donext{%
                       \afterassignment\ifnexttok@i% lire le token d'apr�s
                       \let\nxttok= % apr�s avoir absorb� l'espace
               }%
       \else
               \let\donext\ifnexttok@ii% sinon, faire le test "normal"
       \fi
       \donext% faire l'action d�cid�e ci-dessus
}
\catcode`@12
\testspacefalse
\ifnexttok W{je vais lire un W : }{je ne vais pas lire un W : }W.\par
\ifnexttok W{je vais lire un W : }{je ne vais pas lire un W : } W.\medbreak
\testspacetrue
\ifnexttok W{je vais lire un W : }{je ne vais pas lire un W : }W.\par
\ifnexttok W{je vais lire un W : }{je ne vais pas lire un W : } W.
****************** Fin code ******************


****************** Code 338 ******************
\def\ifstarred#1{\ifnexttok*{\firstoftwo{#1}}}
\catcode`\@11
\def\teststar{\ifstarred{\teststar@bf}{\teststar@it}}
\def\teststar@bf#1{{\bf#1}}
\def\teststar@it#1{{\it#1\/}}
\catcode`\@12

Un essai \teststar{r�ussi} et un essai \teststar*{�toil�} r�ussi aussi.
****************** Fin code ******************


****************** Code 339 ******************
\catcode`\@11
\def\parsestop{\parsestop}% d�finit la macro-quark se trouvant en fin de code
\newtoks\code@toks% registre contenant le code lu
\def\parseadd{\addtotoks\code@toks}
\def\parse{%
       \code@toks={}% initialise \code@toks � vide
       \parse@i% et passe la main � \parse@i
}
\def\parse@i{\futurelet\nxttok\parse@ii}% lit le prochain token et va � \parse@ii
\def\parse@ii{%
       \ifxcase\nxttok
               \parsestop\parsestop@i% si la fin va �tre atteinte, aller � \parsestop@i
               \sptoken\read@space% si un espace va �tre lu, aller � \read@space
               \bgroup\read@bracearg% si une accolade ouvrante  aller � \read@bracearg
       \elseif
               \testtoken% dans les autres cas, aller � \testtoken
       \endif
}

\def\parsestop@i\parsestop{% la fin est atteinte : manger \parsestop
       \the\code@toks% afficher le registre de tokens
}
\expandafter\def\expandafter\read@space\space{% manger un espace dans le code
       \testtoken{ }% et aller � \testtoken
}
\def\read@bracearg#1{% l'argument entre accolades est lu
       \parseadd{{#1}}% puis ajout� (entre accolades) tel quel � \code@toks
       \parse@i% ensuite, lire le prochain token
}
\catcode`@12

{\bf Exemple 1 :}
\catcode`@11
\def\testtoken#1{% macro qui teste le token
       \ifxcase{#1}
               a{\parseadd{e}}% remplacer a par e
               e{\parseadd{i}}% e par i
               i{\parseadd{o}}% i par o
               o{\parseadd{u}}% o par u
               u{\parseadd{y}}% u par y
               y{\parseadd{a}}% y par a
       \elseif
               \parseadd{#1}% sinon, ajouter le token tel quel
       \endif
       \parse@i% aller lire le token suivant
}%
\catcode`@12
\parse
Ce texte devenu \`a peine reconnaissable montre que le r\'esultat contient des sonorit\'es
{\bf catalanes, corses ou grecques} assez inattendues.
\parsestop\medbreak

{\bf Exemple 2 :}
\leavevmode \frboxsep=1pt
\catcode`@11
\def\testtoken#1{%
       \ifxcase{#1}% si #1 est un espace
               { }{\parseadd{\hskip 0.75em }}% ajouter un espace
               \ {\parseadd{\hskip 0.75em }}
       \elseif
               \parseadd{\frbox{#1}}% sinon, l'encadrer
       \endif
       \parse@i}%
\catcode`@12
\parse Programmer en \TeX\ est facile\parsestop\medbreak

{\bf Exemple 3 :}
\catcode`@11
\def\testtoken#1{%
       \ifx a#1\parseadd{X}\else\parseadd{#1}\fi% remplace les "a" par des "X"
       \parse@i
}
\catcode`@12
\parse a\bgroup\bf braca\egroup dabra\parsestop
****************** Fin code ******************


****************** Code 340 ******************
\catcode`\@11
\def\ifbracefirst#1{%
       \ifnum\catcode\expandafter\expandafter\expandafter
               `\expandafter\firstto@nil\detokenize{#1W}\@nil=1 % tester si son catcode est 1
               \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
}
\catcode`\@12

a) \ifbracefirst{123 456}{vrai}{faux}\qquad
b) \ifbracefirst{\bgroup12\egroup3 456}{vrai}{faux}\qquad
c) \ifbracefirst{{12}3 456}{vrai}{faux}\qquad
d) \ifbracefirst{1{2}3 456}{vrai}{faux}\qquad
\begingroup
\catcode`[=1 \catcode`]=2 % les crochets deviennent des accolades
e) \ifbracefirst[[]123 456][vrai][faux]
\endgroup
****************** Fin code ******************


****************** Code 341 ******************
\catcode`\@11
\def\ifbracefirst#1{% teste si #1 commence par un token de catcode 1
       \ifspacefirst{#1}% si #1 commence par un espace
               {\secondoftwo}% renvoyer faux
               {\ifnum\catcode\expandafter\expandafter\expandafter
                       `\expandafter\firstto@nil\detokenize{#1W}\@nil=1 % tester si son catcode est 1
                       \expandafter\firstoftwo
               \else
                       \expandafter\secondoftwo
               \fi
               }%
}

\catcode`\@12
a) \ifbracefirst{}{vrai}{faux}\qquad b) \ifbracefirst{ }{vrai}{faux}\qquad
c) \ifbracefirst{ {}}{vrai}{faux}
****************** Fin code ******************


****************** Code 342 ******************
\catcode`\@11
\def\parsestop@i\parsestop{% la fin va �tre atteinte
       \detokenize\expandafter{\the\code@toks}% afficher le contenu du registre
}
\def\read@bracearg{%
       \read@bracearg@i\relax% ajoute un \relax avant de passer la main � \read@bracearg@i
}
\def\read@bracearg@i#1\parsestop{% #1 = tout jusqu'� \parsestop
       \exparg\ifbracefirst{\gobone#1}% retire le \relax et teste si #1 commence par "{"
               {\expandafter\read@bracearg@ii\gobone#1\parsestop}% si oui, aller � \readbrace@ii
               {\expandafter\testtoken\gobone#1\parsestop}% sinon, aller � \testtoken
}
\def\read@bracearg@ii#1{% lit l'argument entre accolades
       \parseadd{{#1}}% ajoute cet argument entre accolades
       \parse@i% aller lire le token suivant
}

\def\testtoken#1{%
       \parseadd{#1}% ajouter le token tel quel
       \parse@i% aller lire le token suivant
}
\catcode`\@12
\parse a\hbox\bgroup\bf braca\egroup {da}{}b{ra}\parsestop
****************** Fin code ******************


****************** Code 343 ******************
\catcode`\@11
\def\parsestop{\parsestop}% d�finit le quark se trouvant en fin de code
\newtoks\code@toks% alloue le registre contenant le code lu
\def\parseadd#1{\code@toks\expandafter{\the\code@toks#1}}
\newif\ifparse@group
\def\parse{%
       \code@toks{}% initialise le collecteur de tokens
       \ifstarred% teste si la macro est �toil�e
               {\parse@grouptrue\parse@i}% mettre le bool�en � vrai
               {\parse@groupfalse\parse@i}% sinon � faux
}
\def\parse@i{\futurelet\nxttok\parse@ii}% lit le prochain token
                                       % et va � \parse@ii
\def\parse@ii{%
       \ifxcase\nxttok
               \parsestop\parsestop@i% si la fin va �tre atteinte, aller � \parsestop@i
               \sptoken\read@space% si un espace va �tre lu, aller � \read@space
               \bgroup\read@bracearg% si une accolade ouvrante  aller � \read@bracearg
       \elseif
               \testtoken% dans les autres cas, aller � \testtoken
       \endif
}
\def\parsestop@i\parsestop{% la fin est atteinte
       \the\code@toks% afficher le registre de tokens
}
\expandafter\def\expandafter\read@space\space{% \read@space mange un espace dans le code
       \testtoken{ }% et va � \testtoken
}
\def\read@bracearg{%
       \read@bracearg@i\relax% ajoute un \relax avant de passer la main � \read@bracearg@i
}
\def\read@bracearg@i#1\parsestop{% l'argument tout jusqu'� \parsestop
       \expsecond\ifbracefirst{\gobone#1}% retire le \relax et teste si #1 commence par "{"
               {\expandafter\read@bracearg@ii\gobone#1\parsestop}% lire l'argument entre accolades
               {\expandafter\testtoken\gobone#1\parsestop}% sinon, tester le token
}
\def\read@bracearg@ii#1{% l'argument entre accolades est lu
       \ifparse@group\expandafter\firstoftwo\else\expandafter\secondoftwo\fi% si macro �toil�e
               {\begingroup% ouvre un groupe pour parser l'int�rieur de l'accolade
                       \def\parsestop@i\parsestop{% red�finir localement \parsestop@i pour
                               \expandafter\endgroup% ne fermer le groupe qu'apr�s avoir
                               \expandafter\parseadd% 1-d�velopp� � l'ext�rieur du groupe
                               \expandafter{\expandafter{\the\code@toks}}%
                               \parse@i% puis va lire le token suivant
                       }%
                       \parse*#1\parsestop% <- le \parsestop@i fermera le groupe semi-simple
               }
               {\parseadd{{#1}}% macro non �toil�e, on ajoute #1 tel quel entre accolades
               \parse@i% puis va lire le token suivant
               }%
}
\def\testtoken#1{% macro qui teste le token
       \ifxcase{#1}
               a{\parseadd{e}}
               e{\parseadd{i}}
               i{\parseadd{o}}
               o{\parseadd{u}}
               u{\parseadd{y}}
               y{\parseadd{a}}
       \elseif
               \parseadd{#1}%
       \endif
       \parse@i% aller lire le token suivant
}
\catcode`@12
\frboxsep=1pt
a) \parse
Ce texte devenu \`a peine reconnaissable montre que le r\'esultat contient des sonorit\'es
{\bf catalanes, \frbox{corses} ou grecques} assez inattendues.
\parsestop\medbreak

b) \parse*
Ce texte devenu \`a peine reconnaissable montre que le r\'esultat contient des sonorit\'es
{\bf catalanes, \frbox{corses} ou grecques} assez inattendues.
\parsestop
****************** Fin code ******************


****************** Code 344 ******************
\catcode`\@11
\def\parse{%
       \code@toks{}% initialise le collecteur de tokens
       \ifstarred
               {\parse@grouptrue
               \ifnexttok{ }% si un espace suit l'�toile
                       {\afterassignment\parse@i% aller � \parse@i
                       \let\nxttok= }% apr�s l'avoir mang�
                       {\parse@i}% sinon, aller � \parse@i
               }
               {\parse@groupfalse
               \parse@i
               }%
}
\def\testtoken#1{% macro qui teste le token
       \ifxcase{#1}
               a{\parseadd{e}}e{\parseadd{i}}i{\parseadd{o}}o{\parseadd{u}}
               u{\parseadd{y}}y{\parseadd{a}}
       \elseif
               \parseadd{#1}%
       \endif
       \parse@i% aller lire le token suivant
}
\catcode`@12
\frboxsep=1pt
a) \parse
Ce texte devenu \`a peine reconnaissable montre que le r\'esultat contient des sonorit\'es
{\bf catalanes, \frbox{corses} ou grecques} assez inattendues.
\parsestop\medbreak
b) \parse*
Ce texte devenu \`a peine reconnaissable montre que le r\'esultat contient des sonorit\'es
{\bf catalanes, \frbox{corses} ou grecques} assez inattendues.
\parsestop
****************** Fin code ******************


****************** Code 345 ******************
\catcode`\@11
\def\grab@first#1#2{%
       \ifx#1\empty\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {\let#2\empty% si #1 est vide, ne rien faire et assigner <vide> � #2
               }% si #1 n'est pas vide
               {\def\arg@b{#2}% stocke la macro #2 dans \arg@b
               \exparg\ifbracefirst#1% si le 1er token de #1 est "{"
                       {\expandafter\grab@arg#1\@nil#1% aller lire l'argument avec \grab@arg
                       }
                       {% sinon, d�velopper #1 avant de le regarder avec \futurelet :
                       \expandafter\futurelet\expandafter\nxttok\expandafter\test@nxttok#1\@nil#1%
                       % puis aller � \test@nxttok
                       }%
               }%
}
\def\test@nxttok{% si le premier token de l'arg #1 de \grab@first est
       \ifx\nxttok\sptoken% un espace
               \expandafter\grab@spc% aller le lire avec \grab@spc
       \else
               \expandafter\grab@tok% sinon, lire le token avec \grab@tok
       \fi
}
\def\grab@arg#1{% assigne l'argument de \grab@first (mis entre accolades)
       \expandafter\def\arg@b{{#1}}% � #2
       \assign@tonil\relax% puis, assigne le reste � #1 de \grab@first
}
\expandafter\def\expandafter\grab@spc\space{%
       \expandafter\def\arg@b{ }% assigne un espace � #2 de \grab@first
       \assign@tonil\relax% puis, assigne le reste � #1 de \grab@first
}
\def\grab@tok#1{%% assigne le premier token de l'arg #1 de \grab@first
       \expandafter\def\arg@b{#1}% � la macro #2 de \grab@first
       \assign@tonil\relax% puis, assigne le reste � #1 de \grab@first
}
% assigne tout ce qui reste � lire (moins le "\relax") � la macro
% #1 de \grab@first
\def\assign@tonil#1\@nil#2{\expsecond{\def#2}{\gobone#1}}
\tt
a) \def\foo{1 {2 3} 4}\grab@first\foo\bar
  "\meaning\bar"\qquad"\meaning\foo"

b) \def\foo{ 1 {2 3} 4}\grab@first\foo\bar
  "\meaning\bar"\qquad"\meaning\foo""

c) \def\foo{{1 2} 3 4}\grab@first\foo\bar
  "\meaning\bar"\qquad"\meaning\foo"
****************** Fin code ******************


****************** Code 346 ******************
\catcode`\@11
\def\ifstartwith#1#2{% #1=<texte>  #2=<motif>
       \ifempty{#2}
               \firstoftwo% si <motif> est vide, renvoyer vrai
               {\ifempty{#1}% si <code> est vide et <motif> non vide
                       \secondoftwo% renvoyer faux
                       {\def\startwith@code{#1}\def\startwith@pattern{#2}%
                       \ifstartwith@i% dans les autres cas, aller � \ifstartwith@i
                       }%
               }%
}
\def\ifstartwith@i{%
       \grab@first\startwith@code\first@code% extrait le premier "argument" de <texte>
       \grab@first\startwith@pattern\first@pattern% et celui de <motif>
       \ifx\first@code\first@pattern\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {% si les deux arguments �largis sont �gaux
               \exparg\ifempty\startwith@pattern
                       \firstoftwo% et que <motif> ne contient plus rien => vrai
                       {\exparg\ifempty\startwith@code
                               \secondoftwo% si <texte> ne contient plus rien => faux
                               \ifstartwith@i% sinon poursuivre les tests
                       }%
               }
               \secondoftwo% si les deux argument �largis sont diff�rents, renvoyer faux
}
\catcode`\@12

1) \ifstartwith{a b c}{a b}{oui}{non}\quad 2) \ifstartwith{a b}{a b c}{oui}{non}\quad
3) \ifstartwith{ 123 }{ }{oui}{non}\quad   4) \ifstartwith{ 123 }{1}{oui}{non}\quad
5) \ifstartwith{1{2} 3}{12}{oui}{non}\quad 6) \ifstartwith{1{2} 3}{1{2} }{oui}{non}\quad
7) \ifstartwith{{} {}}{ }{oui}{non}\quad   8) \ifstartwith{{} {}}{{} }{oui}{non}\quad
9) \ifstartwith{ {12} a}{ }{oui}{non}\quad10) \ifstartwith{ {12} a}{ {1}}{oui}{non}
****************** Fin code ******************


****************** Code 347 ******************
\catcode`\@11
\def\ifcontain#1#2{% #1 contient-il #2?
       \def\main@arg{#1}\def\pattern@arg{#2}% stocke le <code> et le <motif>
       \ifempty{#2}
               \firstoftwo% si #2 est vide => vrai
               {\ifempty{#1}
                       \secondoftwo% si #1 est vide et pas #2 => faux
                       \ifcontain@i% sinon, aller faire les tests
               }%
}
\def\ifcontain@i{%
       \exptwoargs\ifstartwith\main@arg\pattern@arg
               \firstoftwo% si motif est au d�but de code => vrai
               {\exparg\ifempty\main@arg
                       \secondoftwo% sinon, si code est vide => faux
                       {\grab@first\main@arg\aux@arg% autrement, manger le 1er "argument" de code
                       \ifcontain@i% et recommencer
                       }%
               }%
}
\catcode`\@12
1) \ifcontain{abc def}{c }{oui}{non}\quad  2) \ifcontain{abc def}{cd}{oui}{non}\quad
3) \ifcontain{12 34 5}{1 }{oui}{non}\quad  4) \ifcontain{12 34 5}{ }{oui}{non}\quad
5) \ifcontain{a{b c}d}{b c}{oui}{non}\quad 6) \ifcontain{a{b c}d}{{b c}}{oui}{non}\quad
7) \ifcontain{{} {}}{ }{oui}{non}\quad     8) \ifcontain{{} {}}{{}}{oui}{non}
****************** Fin code ******************


****************** Code 348 ******************
\catcode`@11
\newif\ifin@group
\def\ifcontain{%
       \ifstarred
               {\in@groupfalse\ifcontain@i\ifcontain@star}%
               {\ifcontain@i\ifcontain@nostar}}

\def\ifcontain@i#1#2#3{% #1 = macro � appeler selon �toile ou pas. #2 = code. #3 = motif
       \def\main@arg{#2}\def\pattern@arg{#3}%
       \ifempty{#3}
               \firstoftwo
               {\ifempty{#2}
                       \secondoftwo
                       #1% aller � \ifcontain@star ou \ifcontain@nostar
               }%
}
\def\ifcontain@nostar{%
       \exptwoargs\ifstartwith\main@arg\pattern@arg
               \firstoftwo% si motif est au d�but de code => vrai
               {\exparg\ifempty\main@arg
                       \secondoftwo% sinon, si code est vide => faux
                       {\grab@first\main@arg\aux@arg% autrement, manger le 1er "argument" de code
                       \ifcontain@nostar% et recommencer
                       }%
               }%
}
\def\ifcontain@star{%
       \expandafter\ifbracefirst\expandafter{\main@arg}% si code commence par "{"
               {\grab@first\main@arg\aux@arg% enlever {<argument>} de main@arg
               \begingroup% ouvrir un groupe
                       \in@grouptrue% mettre le bool�en � vrai
                       \expandafter\def\expandafter\main@arg\aux@arg% assigner "argument" � \main@arg
                       \ifcontain@star% et recommencer avec ce nouveau \main@arg
               }% si code ne commence pas par "{"
               {\exptwoargs\ifstartwith\main@arg\pattern@arg% si motif est au d�but de code
                       \return@true% renvoyer vrai
                       {\expandafter\ifempty\expandafter{\main@arg}% si code est vide
                               {\ifin@group% et que l'on est dans un groupe
                                       \endgroup \expandafter\ifcontain@star% en sortir et recommencer
                               \else% si on n'est pas dans un groupe, le code a �t� parcouru
                                       \expandafter\secondoftwo% sans trouver <motif> => renvoyer faux
                               \fi
                               }% si code n'est pas vide
                               {\grab@first\main@arg\startwith@code% manger le 1er "argument" de code
                               \ifcontain@star% et recommencer
                               }%
                       }%
               }%
}
\def\return@true{%
       \ifin@group% tant qu'on est dans un groupe
               \endgroup \expandafter\return@true% en sortir et recommencer
       \else
               \expandafter\firstoftwo% sinon, renvoyer vrai
       \fi
}
\catcode`@12
1) \ifcontain{ab {c d}ef}{c}{oui}{non}\quad 2) \ifcontain*{ab {c d}ef}{c}{oui}{non}
****************** Fin code ******************


****************** Code 349 ******************
\catcode`@11
\newtoks\subst@toks% registre de tokens pour stocker le <texte> modifi�
\def\substitute{%
       \def\substitute@end{\the\subst@toks}% macro ex�cut�e � la fin
       \ifstarred
               {\let\recurse@macro\substitute@star  \substitute@i}%
               {\let\recurse@macro\substitute@nostar\substitute@i}%
}
\def\substitute@i#1#2#3#4{% #1=macro � appeler selon �toile ou pas.
                         % #2=<texte> #3=<motif>  #4=<motif de substi>
       \def\code@arg{#2}\def\pattern@arg{#3}\def\subst@arg{#4}%
       \subst@toks={}% initialiser le collecteur � vide
       #1% aller � \substitute@star ou \substitute@nostar
}
\def\substitute@nostar{%
       \exptwoargs\ifstartwith\code@arg\pattern@arg% si le <texte> commence par <motif>
               {\eaddtotoks\subst@toks\subst@arg% ajouter <motif subst>
               \grab@first\code@arg\aux@code% manger le 1er "argument" de <texte>
               \substitute@nostar% et recommencer
               }
               {\expandafter\ifempty\expandafter{\code@arg}%
                       {\substitute@end% sinon, si <texte> est vide => afficher le registre de tokens
                       }
                       {\grab@first\code@arg\aux@arg% autrement, manger le 1er "argument" de <texte>
                       \eaddtotoks\subst@toks\aux@arg% et l'ajouter au registre de tokens
                       \substitute@nostar% et recommencer
                       }%
               }%
}
\def\substitute@star{%
       \expandafter\ifbracefirst\expandafter{\code@arg}% si <texte> commence par "{"
               {\grab@first\code@arg\aux@arg% enlever {<argument>} de \code@arg
               \begingroup% ouvrir un groupe
                       \def\substitute@end{% modifier localement la macro ex�cut�e � la fin
                               \expandafter\endgroup\expandafter% avant de fermer le groupe
                               \addtotoks\expandafter\subst@toks\expandafter% ajouter au registre hors du groupe
                                       {\expandafter{\the\subst@toks}}% ce qui est collect� localement, mis entre {}
                       \substitute@star% puis recommencer
                       }%
                       \subst@toks{}% initialiser � vide
                       \expandafter\def\expandafter\code@arg\aux@arg% % assigner "argument" au <texte>
                       \substitute@star% et recommencer avec ce nouveau \code@arg
               }% si code ne commence pas par "{"
               {\exptwoargs\ifstartwith\code@arg\pattern@arg% si <motif> est au d�but de <texte>
                       {\eaddtotoks\subst@toks\subst@arg% ajouter <motif subst>
                       \grab@first\code@arg\aux@code% manger le 1er "argument" de <texte>
                       \substitute@star% et recommencer
                       }
                       {\expandafter\ifempty\expandafter{\code@arg}% si <texte> est vide
                               {\substitute@end% aller � la macro de fin
                               }% si <texte> n'est pas vide
                               {\grab@first\code@arg\aux@code% manger le 1er "argument" de <texte>
                               \eaddtotoks\subst@toks\aux@code% et l'ajouter au registre
                               \substitute@star% et recommencer
                               }%
                       }%
               }%
}
\catcode`@12
1) \substitute{ab{\bf racada}bra}{a}{W}\qquad
2) \substitute*{ab{\bf racada}bra}{a}{W}\qquad
3) \substitute{12\frbox{\bf 34}56}{\bf}{\it}\qquad
4) \substitute*{12\frbox{\bf 34}56}{\bf}{\it}
****************** Fin code ******************


****************** Code 350 ******************
\catcode`@11
\newtoks\subst@toks% registre de tokens pour stocker le <texte> modifi�
\def\substitute{%
       \def\substitute@end{\the\subst@toks}% macro ex�cut�e � la fin
       \ifstarred
               {\let\recurse@macro\substitute@star  \substitute@i}%
               {\let\recurse@macro\substitute@nostar\substitute@i}%
}
\def\substitute@i#1#2#3{% #1=<texte> #2=<motif> #3=<motif de substi>
       \def\code@arg{#1}\def\pattern@arg{#2}\def\subst@arg{#3}%
       \subst@toks={}% initialiser � vide
       \recurse@macro% aller � \substitute@star ou \substitute@nostar
}
\def\substitute@nostar{%
       \exptwoargs\ifstartwith\code@arg\pattern@arg% si le <texte> commence par <motif>
               {\eaddtotoks\subst@toks\subst@arg% ajouter <motif subst>
               \grab@first\code@arg\aux@code% manger le 1er "argument" de <texte>
               \recurse@macro% et recommencer
               }
               {\expandafter\ifempty\expandafter{\code@arg}%
                       \substitute@end% sinon, si <texte> est vide => afficher le registre de tokens
                       {\grab@first\code@arg\aux@arg% autrement, manger le 1er "argument" de <texte>
                       \eaddtotoks\subst@toks\aux@arg% et l'ajouter au registre de tokens
                       \recurse@macro% et recommencer
                       }%
               }%
}
\def\substitute@star{%
       \expandafter\ifbracefirst\expandafter{\code@arg}% si <texte> commence par "{"
               {\grab@first\code@arg\aux@arg% enlever {<argument>} de \code@arg
               \begingroup% ouvrir un groupe
                       \def\substitute@end{% modifier localement la macro ex�cut�e � la fin
                               \expandafter\endgroup\expandafter% avant de fermer le groupe
                               \addtotoks\expandafter\subst@toks\expandafter% ajouter au registre hors du groupe
                                       {\expandafter{\the\subst@toks}}% ce qui est collect� localement, mis entre {}
                               \recurse@macro% puis recommencer
                       }%
                       \subst@toks{}% initialiser � vide
                       \expandafter\def\expandafter\code@arg\aux@arg% % assigner "argument" au <texte>
                       \recurse@macro% et recommencer avec ce nouveau \code@arg
               }% si <texte> ne commence pas par "{" :
               \substitute@nostar% ex�cuter macro non �toil�e pour une seule it�ration
}
\def\substitutetocs{%
       \ifstarred
               {\let\recurse@macro\substitute@star  \substitutetocs@i}%
               {\let\recurse@macro\substitute@nostar\substitutetocs@i}%
}
\def\substitutetocs@i#1#2#3#4{% #1=<texte> #2=<motif> #3=<motif de substi> #4=\<macro>
       \def\substitute@end{\edef#4{\the\subst@toks}}% macro ex�cut�e � la fin
       \substitute@i{#1}{#2}{#3}% continuer comme avec \substitute
}
\catcode`@12
\frboxsep=1pt
1) \substitute{ab{\bf racada}bra}{a}{W}\qquad
2) \substitute*{ab{\bf racada}bra}{a}{W}\qquad
3) \substitute{12\frbox{\bf 34}56}{\bf}{\it}\qquad
4) \substitute*{12\frbox{\bf 34}56}{\bf}{\it}
\medbreak

1) \substitutetocs{ab{\bf racada}bra}{a}{W}\foo       \meaning\foo\par
2) \substitutetocs*{ab{\bf racada}bra}{a}{W}\foo      \meaning\foo\par
3) \substitutetocs{12\frbox{\bf 34}56}{\bf}{\it}\foo  \meaning\foo\par
4) \substitutetocs*{12\frbox{\bf 34}56}{\bf}{\it}\foo \meaning\foo
****************** Fin code ******************


****************** Code 351 ******************
\catcode`@11
\def\vecteur{%
       \ifnexttok[% si la macro est suivie d'un crochet
               \vecteur@i% aller � la macro � arguments d�limit�s
               {\vecteur@i[1]}% sinon, ajouter l'argument optionnel par d�faut entre crochets
}
\def\vecteur@i[#1]#2{% #1=arg optionnel  #2=arg obligatoire
       $(x_{#1},\ldots,x_{#2})$
}
\catcode`@12
1) \vecteur{n}\qquad 2) \vecteur[0]{k}\qquad 3) \vecteur[i]j \qquad4) \vecteur[]n
****************** Fin code ******************


****************** Code 352 ******************
\catcode`@11
\def\forcemath#1{% compose #1 en mode math, quel que soit le mode en cours
       \ifmmode\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {#1}{$#1$}%
}
\def\vecteur{%
       \ifnexttok[% si la macro est suivie d'un crochet
               \vecteur@i% aller � la macro � arguments d�limit�s
               {\vecteur@i[1]}% sinon, ajouter l'argument optionnel par d�faut entre crochets
}
\def\vecteur@i[#1]{%
       \ifnexttok(% si une parenth�se vient ensuite
               {\vecteur@ii[#1]}% aller � la macro � argument d�limit�s
               {\vecteur@ii[#1](x)}% sinon, rajouter "x" comme argument optionnel
}
\def\vecteur@ii[#1](#2)#3{% #1 et #2=arg optionnel  #3=arg obligatoire
       \forcemath{({#2}_{#1},\ldots,{#2}_{#3})}%
}
\catcode`@12
1) \vecteur{n}\qquad 2) \vecteur[0]{k}\qquad
3) \vecteur[i](y)j \qquad4) \vecteur[](\alpha)n
****************** Fin code ******************


****************** Code 353 ******************
\catcode`@11
\def\vecteur{%
       \ifnexttok[% si la macro est suivie d'un crochet
               \vecteur@bracket% lire cet argument entre crochet
               {\ifnexttok(% sinon, si elle est suivie d'une parenth�se
                       \vecteur@paren % lire cet argument entre parenth�ses
                       {\vecteur@i[1](x)}% sinon, transmettre les arguments par d�faut
               }%
}
\def\vecteur@bracket[#1]{%
       \ifnexttok(% s'il y a une parenth�se apr�s
               {\vecteur@i[#1]}% lire la parenth�se
               {\vecteur@i[#1](x)}% sinon, donne "x" comme argument par d�faut
}
\def\vecteur@paren(#1){%
       \ifnexttok[% si le caract�re suivant est un crochet
               {\vecteur@ii(#1)}% lire l'argument entre crochets
               {\vecteur@ii(#1)[1]}% sinon, donner "1" comme argument par d�faut
}
\def\vecteur@i[#1](#2)#3{\forcemath{({#2}_{#1},\ldots,{#2}_{#3})}}
\def\vecteur@ii(#1)[#2]{\vecteur@i[#2](#1)}% met les arg optionnels dans l'ordre
\catcode`@12
1) \vecteur{n}\qquad 2) \vecteur[i](y){j}\qquad 3) \vecteur(y)[i]{j}\qquad
4) \vecteur[0]{k}\qquad 5) \vecteur(\alpha){n}
****************** Fin code ******************


****************** Code 354 ******************
\catcode`\@11
\def\foo#1{% #1 -> lit le premier argument obligatoire
       \ifnexttok[% si le token suivant est un crochet
               {\foo@i{#1}}% aller � \foo@i qui va lire cet argument
               {\foo@i{#1}[xxx]}% sinon, transmettre [xxx] � foo@i
}

\def\foo@i#1[#2]#3#4{% lit l'arg obligatoire + arg optionnel + 2 arg obligatoires
       \ifnexttok[
               {\foo@ii{#1}[#2]{#3}{#4}}%
               {\foo@ii{#1}[#2]{#3}{#4}[y]}%
}

\def\foo@ii#1[#2]#3#4[#5]#6{% lit tous les arguments
       1="#1" 2="#2" 3="#3" 4="#4" 5="#5" 6="#6"%
}

\catcode`\@12
1) \foo{arg1}{arg2}{arg3}{arg4}\par
2) \foo{arg1}[OPT\_A]{arg2}{arg3}{arg4}\par
3) \foo{arg1}{arg2}{arg3}[OPT\_B]{arg4}\par
4) \foo{arg1}[OPT\_A]{arg2}{arg3}[OPT\_B]{arg4}\medbreak
****************** Fin code ******************


****************** Code 355 ******************
\catcode`\@11
\newcount\macro@cnt% num�ro � mettre dans le nom des sous macros
\newcount\arg@cnt% compte le nombre d'arguments
\newtoks\param@text% texte de param�tre des macros sous forme "#x" et/ou "[#x]"
\newtoks\arg@text% arguments sous forme "{#x}" et/ou "[#x]"

\def\newmacro#1{%
       % \macro@name construit le <nom> de la macro et �ventuellement "@[<chiffre romain>]"
       \def\macro@name##1{\expandafter\gobone\string#1\ifnum##1>0 @[\romannumeral##1]\fi}%
       \macro@cnt=0 \arg@cnt=0 % initialise les compteurs
       \param@text{}\arg@text{}% vide les registres de texte de param�tre et d'argument
       \newmacro@i% va voir le prochain token
}

\def\newmacro@i{\futurelet\nxttok\newmacro@ii}% met le prochain token dans \nxttok...
% ...puis va � la macro :
\def\newmacro@ii{%
       \ifxcase\nxttok
               [\newmacro@optarg% si le prochain token est un crochet aller � \newmacro@optarg
               \bgroup% si c'est un accolade ouvrante
                       % le texte de param�tre est fini et il faut d�finir la macro
                       {\defname{\macro@name\macro@cnt\expandafter}%
                       \the\param@text}% <- le {<code>} est juste apr�s, il n'est pas encore lu
       \elseif% sinon, c'est donc un chiffre
                       \newmacro@arg% aller � \newmacro@arg
       \endif
}

\def\newmacro@optarg[#1]{% lit la valeur par d�faut de l'argument optionnel
       % D�finit la macro \<nom>@[<nbre>] qui lit tous les arguments (optionnels ou pas)
       % jusqu'alors d�finis � l'aide de \param@text. Puis, cette macro testera si le prochain
       % token est un crochet
       \expandafter\edef\csname\macro@name\macro@cnt\expandafter\endcsname\the\param@text{%
               \noexpand\ifnexttok[%
                       % si oui : la macro \<nom>@<nbr+1> le lira
                       {\expandafter\noexpand\csname\macro@name{\numexpr\macro@cnt+1}\expandafter\endcsname
                       \the\arg@text}%
                       % si non : transmettre � \<nom>@<nbr+1> l'argument optionnel par d�faut lu
                       {\expandafter\noexpand\csname\macro@name{\numexpr\macro@cnt+1}\expandafter\endcsname
                       \the\arg@text[\unexpanded{#1}]}%
       }%
       \advance\arg@cnt 1 % incr�menter le num�ro d'argument
       % pour ajouter "[#<x>]" � \param@text et � \arg@text
       \eaddtotoks\param@text{\expandafter[\expandafter##\number\arg@cnt]}%
       \eaddtotoks\arg@text  {\expandafter[\expandafter##\number\arg@cnt]}%
       \advance\macro@cnt 1 % incr�menter le num�ro de nom de macro
       \newmacro@i% va voir le token suivant
}

\def\newmacro@arg#1{% #1=nombre d'arguments obligatoires � ajouter
       % boucle qui ajoute "#<x>#<x+1>etc" dans \param@text
       % et "{#<x>}{#<x+1>}etc" dans \arg@text
       \ifnum#1>\z@ % tant qu'on n'a pas ajout� le nombre de #x n�cessaire
               \advance\arg@cnt 1 % incr�menter le num�ro d'argument
               % pour ajouter #x � \param@text et {#x} � \arg@text
               \eaddtotoks\param@text{\expandafter##\number\arg@cnt}%
               \eaddtotoks\arg@text  {\expandafter{\expandafter##\number\arg@cnt}}%
               \expandafter\newmacro@arg\expandafter{\number\numexpr#1-1\expandafter}% boucler
       \else% si les arguments sont tous ajout�s
               \expandafter\newmacro@i% lire le token suivant
       \fi
}
\catcode`\@12
\newmacro\foo 1[xxx]2[y]1{1="#1" 2="#2" 3="#3" 4="#4" 5="#5" 6="#6"}
a) \foo{arg1}{arg2}{arg3}{arg4}\par
b) \foo{arg1}[OPT\_A]{arg2}{arg3}{arg4}\par
c) \foo{arg1}{arg2}{arg3}[OPT\_B]{arg4}\par
d) \foo{arg1}[OPT\_A]{arg2}{arg3}[OPT\_B]{arg4}\medbreak

\meaning\foo\par
\expandafter\meaning\csname foo@[i]\endcsname\par
\expandafter\meaning\csname foo@[ii]\endcsname
****************** Fin code ******************


****************** Code 356 ******************
\newmacro\framebox[ULRD]1{% #1 = ULRD (Up, Down, Right, Left)
% ne pas changer le mode H ou V en cours
       \hbox{% enferme dans une \hbox
               \uppercase{\ifin{#1}L}{\vrule width\frboxrule}{}% r�glure gauche
               \vtop{%
                       \vbox{% 1er �l�ment de la \vtop
                               \uppercase{\ifin{#1}U}{% si la r�glure sup doit �tre trac�e
                                       \hrule height\frboxrule% r�glure sup�rieure
                                       \kern\frboxsep% espace haut
                                       }
                                       {}%
                               \hbox{%
                                       \uppercase{\ifin{#1}L}{\kern\frboxsep}{}% espace gauche
                                       #2% contenu
                                       \uppercase{\ifin{#1}R}{\kern\frboxsep}{}% espace droite
                                       }%
                       }% puis autres �l�ments de la \vtop, sous la ligne de base
                       \uppercase{\ifin{#1}D}{%
                               \kern\frboxsep% espace bas
                               \hrule height\frboxrule% r�glure inf�rieure
                               }%
                               {}%
               }%
               \uppercase{\ifin{#1}R}{\vrule width\frboxrule}{}% r�glure droite
       }%
}
\frboxsep=1pt
Boite \framebox{enti�re}, \framebox[ud]{Up down}, \framebox[LR]{Left Right},
\framebox[LU]{Left Up} et \framebox[rd]{Right Down}.
****************** Fin code ******************


****************** Code 357 ******************
\catcode`\@11
\newtoks\eargs@toks
\newtoks\eargs@temptoks
\def\eargs[#1]#2{% #1=liste des d�veloppements  #2=macro
       \eargs@toks{#2}% mettre la macro dans le collecteur de tokens
       \expandafter\eargs@i\detokenize{#1}\@nil% appeler \eargs@i avec
                                               % la liste des developpements
}

\def\eargs@i#1\@nil{% #1=liste des n-d�veloppements restant
       \ifempty{#1}% s'il n' y plus de n-d�veloppements
               {\the\eargs@toks}% ex�cuter la macro et ses arguments d�velopp�s
               {\eargs@ii#1\@nil}% sinon appeller la macro qui lit un argument
}

% #1=n-d�veloppement actuel  #2=liste des n-d�veloppements restants   #3=argument lu
\def\eargs@ii#1#2\@nil#3{%
       \if+#1% si #1="+", un \edef est demand� pour cet argument
               \edef\eargs@tempmacro{{#3}}% le stocker dans une macro temporaire
       \else% sinon
               \eargs@temptoks={#3}% stocker l'argument dans un registre temporaire
               \for\eargs@loop = 1 to #1\do 1 % faire #1 fois :
                       {\eargs@temptoks=% 1-d�velopper le 1er token du registre temporaire
                               \expandafter\expandafter\expandafter{\the\eargs@temptoks}%
                       }% puis le stocker dans la macro temporaire
               \edef\eargs@tempmacro{{\the\eargs@temptoks}}%
       \fi
       \eaddtotoks\eargs@toks\eargs@tempmacro% ajouter le contenu de la macro au collecteur
       \eargs@i#2\@nil% appeler \eargs@i avec les n-d�veloppements restants
}
\catcode`\@12
\def\foo#1#2#3#4#5{\detokenize{1="#1" 2="#2" 3="#3" 4="#4" 5="#5"}}
\def\aaa{\bbb}\def\bbb{\ccc}\def\ccc{Bonjour}

\eargs[0123+]\foo{\aaa\bbb}{\aaa\bbb}{\aaa\bbb}{\aaa\bbb}{\aaa\bbb}.
****************** Fin code ******************


****************** Code 358 ******************
\catcode`\@11
\def\detectmark#1{% #1 est le marqueur
       \begingroup
               \catcode`#1=13 % rendra #1 actif apr�s la macro
               \begingroup% pour les besoins du \lccode
                       \lccode`\~=`#1 % transforme "~" en " #1 actif"
                       \lowercase{\endgroup\def~##1~}{\markeffect{##1}}%
               \detectmark@i
}
\def\detectmark@i#1{%
               #1% ex�cute le code
       \endgroup% ferme le groupe, le marqueur perd son catcode actif
}
\catcode`\@12
a) \def\markeffect#1{{\bf #1}}% met en gras
\detectmark+{Un +argument+ o� les +marqueurs+ sont d�tect�s}
\medskip

b) \def\markeffect#1{% met dans une boite
       \begingroup
               \frboxsep=1pt % modifie l'espacement entre texte et encadrement
               \frbox{\strut#1}% encadre
       \endgroup
}
\detectmark|{Un |argument| o� les |marqueurs| sont d�tect�s}
\medskip

c) \def\markeffect#1{$\vcenter{\hbox{#1}\hbox{#1}}$}% superpose 2 fois
\detectmark`{Un `argument` o� les `marqueurs` sont d�tect�s}
****************** Fin code ******************


****************** Code 359 ******************
\catcode`\@11
\def\detectmark#1{%
       \begingroup
               \catcode`#1=13 % rendra #1 actif apr�s la macro
               \begingroup% pour les besoins du \lccode
                       \lccode`\~=`#1 % transforme "~" en " #1 actif"
                       \lowercase{\endgroup\def~##1~}{\markeffect{##1}}%%
               \detectmark@i
}
\def\detectmark@i#1{%
               #1% lit le code
       \endgroup% ferme le groupe, le marqueur perd son catcode actif
}
\catcode`\@12
\def\markeffect#1{{\bf #1}}% met en gras
\frbox{\detectmark+{Un +argument+ o� les +marqueurs+ sont d�tect�s}}
****************** Fin code ******************


****************** Code 360 ******************
\catcode`\@11
\newtoks\alter@toks% collecteur de tokens

\def\alter#1#2{% #1= d�limiteur  #2 = macro � alt�rer
       \let\alter@macro#2% sauvegarde la macro
       \edef\alter@restorecatcode{% restaurera le catcode de #1
               \catcode`\noexpand#1=\the\catcode`#1 }%
       \edef\alter@tmp{\let\noexpand\alter@markertoks= \string#1}%
       \alter@tmp% et sauvegarder le d�limiteur apr�s avoir mis son catcode � 12
       \edef\alter@tmp{\def\noexpand\alter@readlitterate@i\string#1####1\string#1}%
       % d�veloppe les \string#1 pour que les arguments d�limit�s aient
       % des d�limiteurs de catcode 12
       \alter@tmp{% <- comme si on �crivait "\def\alter@readlitterate@i#1##1#1"
               \endgroup% apr�s avoir lu ##1 (tokens rendus inoffensifs), fermer le groupe
               \addtotoks\alter@toks{{\tt##1}}% ajouter ces tokens
               \alter@i% et aller lire le prochain token
       }%
       \alter@toks{}% initialise le collecteur de tokens
       \afterassignment\alter@i% aller lire le premier token apr�s avoir
       \let\alter@tmptok= % mang� l'accolade ouvrante de l'<argument> qui suit
}

\def\alter@i{% lit le prochain token et va � \alter@ii
       \futurelet\alter@nxttok\alter@ii}%

\def\alter@ii{% teste le token qui doit �tre lu
       \ifxcase\alter@nxttok% si le token � lire est
               \egroup           \alter@stop% "}" : aller � \alterstop@i
               \sptoken          \alter@readspc% " " : aller � \alter@readspc
               \bgroup           \alter@readarg% "{" : aller � \alter@readarg
               \alter@markertoks \alter@readlitterate% "<delimiteur>" : aller � \alter@readlitterate
       \elseif
               \alter@readtok% dans les autres cas, aller � \alter@readtok
       \endif
}

\def\alter@readlitterate{% le prochain token est le d�limiteur
       \begingroup% ouvrir un groupe
       \for\alter@tmp=0to255\do{\catcode\alter@tmp=12 }%
       % mettre tous les catcodes � 12
       \defactive{ }{\ }% sauf l'espace rendu actif
       \doforeach\alter@tmp\in{<,>,-,`,{,},'}% pour chaque motif de ligature
                       {\unless\if\alter@tmp\alter@markertoks% s'il est diff�rent du d�limiteur
                               % le rendre actif pour �viter la ligature
                               \expandafter\alter@defligchar\alter@tmp
                       \fi
                       }%
       \alter@readlitterate@i% puis aller � \alter@readlitterate@i...
       % ...qui a �t� d�finie dans \alter
}

\def\alter@defligchar#1{% d�finit le caract�re pour ne pas provoquer de ligature
       \defactive#1{\string#1{}}%
}

\expandafter\def\expandafter\alter@readspc\space{% mange un espace dans le code
       \addtotoks\alter@toks{ }% ajoute l'espace
       \alter@i% puis lire le token suivant
}

\def\alter@readarg{% le token qui suit est "{"
       \begingroup% ouvrir un groupe
       \def\alter@stop@ii{% et modifier localement la macro appel�e � la toute fin,
       % apr�s que l'accolade fermante ait �t� mang�e (par \alterstop@i)
               \expandafter\endgroup% retarder la fermeture de groupe ouvert ci-dessus
               \expandafter\addtotoks\expandafter\alter@toks\expandafter
                       {\expandafter{\the\alter@toks}}%
               % pour ajouter hors du groupe ce qui a �t� collect� � l'int�rieur,
               % le tout mis entre accolades
               \alter@i% puis, lire le token suivant
       }%
       \alter@toks{}% au d�but du groupe, initialiser le collecteur
       \afterassignment\alter@i% aller lire le prochain token apr�s
       \let\alter@tmptok= % avoir mang� l'accolade ouvrante
}

\def\alter@readtok#1{% le prochain token ne demande pas une action sp�ciale
       \addtotoks\alter@toks{#1}% l'ajouter au collecteur
       \alter@i% et aller lire le token suivant
}

\def\alter@stop{% le token � lire est "}"
       \afterassignment\alter@stop@ii% aller � \alter@stop@ii apr�s
       \let\alter@tmptok= % avoir mang� l'accolade fermante
}

\def\alter@stop@ii{% donner � la \<macro> tout ce qui a �t� r�colt�
       \expandafter\alter@macro\expandafter{\the\alter@toks}%
       \alter@restorecatcode% puis restaure le catcode du d�limiteur
}
\catcode`@12

\frboxsep=1pt
\alter|\frbox{Texte normal - |#& }| - texte normal - |_^ ##| - texte normal}
\alter=\frbox{La macro =\alter= autorise du verbatim dans
des commandes imbriqu�es \frbox{comme ici =\alter=}.}
****************** Fin code ******************


****************** Code 361 ******************
\def\hello#1#2{Bonjour #1 et  #2 !}
\hello{foo}{bar}\par
\alter|\identity{\hello{macro |{{{\foo|}{macro |\bar}|}}
****************** Fin code ******************


****************** Code 362 ******************
\def\retokenize#1{%
       \immediate\openout\wtest=retokenize.tex % ouvre le fichier
       \immediate\write\wtest{\unexpanded{#1}}%  y �crit l'argument
       \immediate\closeout\wtest% ferme le fichier
       \input retokenize.tex % lit le fichier selon les catcodes en vigueur
       \unskip% mange l'espace pr�c�demment ajout� qui provient de la fin du fichier
}
\frboxsep=1pt
1) \frbox{Programmer en \catcode`\~=12 \TeX{} est~facile et~utile.}\par
2) \frbox{Programmer en \retokenize{\catcode`\~=12 \TeX{} est~facile} et~utile.}\par
3) \frbox{Programmer en \catcode`\~=12 \retokenize{\TeX{} est~facile} et~utile.}
****************** Fin code ******************


****************** Code 363 ******************
\frboxsep=1pt
1) \frbox{Programmer \retokenize{\litterate|en \TeX {} est |}facile et utile.}\par
2) \frbox{Programmer \retokenize{\litterate|en    \TeX{} est |}facile et utile.}
****************** Fin code ******************


****************** Code 364 ******************
\frboxsep=1pt
1) \frbox{Programmer en \catcode`\~=12 \TeX{} est~facile et~utile.}\par
2) \frbox{Programmer en \scantokens{\catcode`\~=12 \TeX{} est~facile} et~utile.}\par
3) \frbox{Programmer en \catcode`\~=12 \scantokens{\TeX{} est~facile} et~utile.}\par
4) \frbox{Programmer \scantokens{\litterate|en \TeX {} est facile|} et utile.}\par
5) \frbox{Programmer \scantokens{\litterate|en    \TeX{} est facile|} et utile.}
****************** Fin code ******************


****************** Code 365 ******************
\scantokens{a}b
****************** Fin code ******************


****************** Code 366 ******************
\begingroup\endlinechar=-1 \scantokens{a}b\endgroup
****************** Fin code ******************


****************** Code 367 ******************
\edef\foo{\scantokens{Bonjour le monde}}% produit une erreur
****************** Fin code ******************


****************** Code 368 ******************
\expandafter\def\expandafter\foo\expandafter
       {\scantokens{Bonjour le monde}}% produit une erreur
****************** Fin code ******************


****************** Code 369 ******************

Voici la macro \string\foo\ : \foo.
****************** Fin code ******************


****************** Code 370 ******************
\catcode`\@11
\def\scandef#1#2{% #1=\<macro>   #2=<texte>
       \begingroup
               \endlinechar=-1 % pas de caract�re de fin de ligne
               \everyeof{\@nil#1\noexpand}% ajoute "\@nil\<macro>\noexpand" avant la fin du fichier
               \expandafter\scandef@i\expandafter\relax\scantokens{#2}%
}
\def\scandef@i#1\@nil#2{% "\@nil#2" ont �t� ajout� par \everyeof
       \endgroup% ferme le groupe
       \expandafter\def\expandafter#2\expandafter{\gobone#1}% et d�finit la \<macro>
}
\catcode`@12
\def\foo{%
       Dans tout l'argument de \string\foo, <<~>> est actif
       sauf
       \catcode`\~12
       \scandef\bar{dans celui de \string\bar : <<~>>}%
       \catcode`~13
       \bar
}
\foo
****************** Fin code ******************


****************** Code 371 ******************
{%
\endlinechar=`\d% ins�re la lettre "d" � chaque fin de ligne
% le \noexpan(d) est incomplet
Voici la macro \string\foo\ : \foo.% fins de ligne...
}% ...comment�es pour �viter le "d"
****************** Fin code ******************


****************** Code 372 ******************
\catcode`\@11
\def\cprotect#1{% #1 est la \<macro>
       \def\cprotect@i##1{% ##1 est l'<argument>
               \endgroup% ferme le groupe pr�c�demment ouvert
               #1{\scantokens{##1\noexpand}}%
       }%
       \begingroup% rend tous les octets de catcode12
               \for\cprotect@temp=0to255\do{\catcode\cprotect@temp=12 }%
               \catcode`\{=1 \catcode`\}=2 % sauf "{" et "}"
               \cprotect@i% puis, lit l'argument
}
\catcode`@12
\frboxsep=1.5pt
1) \cprotect\frbox{foo \litterate-&#  #^   ^_%- bar}\par
2) \cprotect\frbox{\catcode`\~=12 a~b~c~d}\par
3) \cprotect\frbox{foo \litterate-\bar- \cprotect\frbox{\litterate-&#   #-} fin}
****************** Fin code ******************


****************** Code 373 ******************
\catcode`@11
\def\Cprotect#1{% #1 est la \<macro>
       \def\Cprotect@i##1{% ##1 est la liste des arguments
               \endgroup% ferme le groupe pr�c�demment ouvert
               \toks0={#1}% met la \<macro> dans le registre de tokens
               \Cprotect@ii##1\quark% \quark est mis � la fin des arguments
               \the\toks0 % ex�cute le registre
       }%
       \begingroup% rend tous les octets de catcode12
               \for\temp@arg= 0 to 255 \do{% changer � 12 tous les catcodes
                       \unless\ifnum\catcode\temp@arg=1 % sauf si catcode=1
                               \unless\ifnum\catcode\temp@arg=2 % ou 2
                                       \catcode\temp@arg=12
                               \fi
                       \fi}%
               \Cprotect@i% puis, lit l'argument
}
\def\Cprotect@ii#1{% #1 est l'argument courant (d�pouill� de ses accolades)
       \def\temp@arg{#1}% stocke l'argument pour le tester ci dessous :
       \unless\ifx\quark\temp@arg% si la fin n'est pas atteinte
               % ajouter "{\scantokens{#1\noexpand}}" au registre
               \addtotoks{\toks0}{{\scantokens{#1\noexpand}}}%
               \expandafter\Cprotect@ii% et recommencer
       \fi
}
\catcode`@12

\def\test#1#2{Bonjour #1 et #2}
\Cprotect\test{{argument 1 : \litterate-\foo-}{argument 2 : \litterate-\bar-}}
****************** Fin code ******************


****************** Code 374 ******************
\newdimen\pixelsize \newdimen\pixelsep
\def\pixel{\vrule height\pixelsize width\pixelsize depth0pt }
\def\vblankpixel{\vrule height\pixelsize width0pt depth0pt }
\def\blankpixel{\vblankpixel \vrule height0pt width\pixelsize depth0pt }
\def\gap{\kern\pixelsep}
\pixelsize=3pt \pixelsep=1pt
Essai :
\vbox{% aligne verticalement
       \offinterlineskip% annule le ressort d'interligne
       \lineskip=\pixelsep\relax% pour le mettre � \pixelsep
       \hbox{\pixel\gap\blankpixel\gap\blankpixel\gap\blankpixel\gap\pixel}% 1re ligne
       \hbox{\pixel\gap\pixel     \gap\blankpixel\gap\pixel     \gap\pixel}% 2e ligne
}
****************** Fin code ******************


****************** Code 375 ******************
\pixelsize=3pt \pixelsep=1pt
Essai :
\vtop{%
 \offinterlineskip \lineskip=\pixelsep\relax
 \vbox{%
   \hbox{\blankpixel\gap\pixel     \gap\pixel     \gap\pixel}%         ***
   \hbox{\pixel     \gap\blankpixel\gap\blankpixel\gap\pixel}%        *  *
   \hbox{\pixel     \gap\blankpixel\gap\blankpixel\gap\pixel}%        *  *
   \hbox{\pixel     \gap\blankpixel\gap\blankpixel\gap\pixel}%        *  *
   \hbox{\blankpixel\gap\pixel     \gap\pixel     \gap\pixel}%         ***
 }%                                                      ----ligne de base
 \hbox  {\blankpixel\gap\blankpixel\gap\blankpixel\gap\pixel}%           *
 \hbox  {\blankpixel\gap\pixel     \gap\pixel               }%         **
}
****************** Fin code ******************


****************** Code 376 ******************
\catcode`\@11
\begingroup% dans ce groupe :
\catcode`\ =12\relax% l'espace devient un "caract�re autre"
\catcode`\^^M=13\relax% le retour � la ligne est actif
\edef^^M{\string,}% et se d�veloppe en une virgule (de catcode 12)
\global\deftok\otherspc{ }% d�finit un espace de catcode 12
\xdef\letter@code{% macro contenant le dessin de la lettre "e"
**
*  *
***
*
***}%
\endgroup

\def\makecar@i#1{% #1 = dessin de la lettre avec les caract�res "," "*" et " "
       \doforeach\current@line\in{#1}% pour chaque ligne dans #1 :
               {\ifx\empty\current@line% si la ligne est vide
                       \addtomacro\pixabove{\hbox{\vblankpixel}}% ajouter une fausse ligne
               \else% sinon
                       \let\pix@line\empty% initialiser le code de la ligne � vide
                       \expandafter\makecar@ii\current@line\quark% et la construire
               \fi
               }%
}

\def\makecar@ii#1{% #1=caract�re de dessin de la ligne en cours
       \ifxcase#1% si le caract�re est
               *        {\addtomacro\pix@line\pixel}%
               \otherspc{\addtomacro\pix@line\blankpixel}%
       \endif
       \ifx#1\quark% si la fin est atteinte
               \addtomacro\pix@line\unkern% annuler le dernier espace interpixel
               \eaddtomacro\pixabove{% et encapsuler \pix@line dans une \hbox
               \expandafter\hbox\expandafter{\pix@line}}%
       \else% si la fin n'est pas atteinte, ajouter l'espace interpixel
               \addtomacro\pix@line\gap
               \expandafter\makecar@ii% recommencer avec le caract�re suivant
       \fi
}
\pixelsize=3pt \pixelsep=1pt
\let\pixabove\empty% initialisation de la macro finale � vide
\exparg\makecar@i\letter@code% appelle la macro qui construit \pixabove
La lettre
\vtop{% enferme le tout dans une \vtop :
       \offinterlineskip\lineskip=\pixelsep% ajuste l'espace interligne
       \vbox{\pixabove}% affiche le caract�re cr��
}.
****************** Fin code ******************


****************** Code 377 ******************
\catcode`\@11
\begingroup% dans ce groupe :
\catcode`\ =12\relax% l'espace devient un "caract�re autre"
\catcode`\^^M=13\relax% le retour � la ligne est actif
\edef^^M{\string,}% et se d�veloppe en une virgule (de catcode 12)
\global\deftok\otherspc{ }% d�finit un espace de catcode 12
\xdef\letter@code{% macro contenant le dessin de la lettre "g"
***
*  *
*  *
*  *
***_
  *
**}%
\endgroup

\def\makecar#1#2{% #1=nom recevant le code final  #2=macro contenant le dessin
       \let\pixabove\empty \let\pixbelow\empty \let\pix@line\empty% initialise � vide
       \exparg\ifin{#2}_% si le code contient _
               {\expandafter\makecar@iii#2\@nil}% aller � \makecar@iii
               {\exparg\makecar@i{#2}}% sinon, � \makecar@i
       \edef#1{% d�finit la macro #1 comme
               \vtop{% une \vtop contenant :
                       \unexpanded{\offinterlineskip\lineskip\pixelsep}% r�glage d'espace inter ligne
                       \vbox{\unexpanded\expandafter{\pixabove}}% \vbox des pixels au-dessus
                                                                % de la ligne de base
                       \unless\ifx\pixbelow\empty% s'il y a des pixels au-dessous de la baseline
                               \unexpanded\expandafter{\pixbelow}% les ajouter dans la \vtop
                       \fi
                       }%
               }%
}

\def\makecar@iii#1_,#2\@nil{%
       \makecar@i{#2}% construit la partie au-dessous de la baseline
       \let\pixbelow\pixabove% et affecte le code � \pixbelow
       \let\pixabove\empty \let\pix@line\empty% r�-initialise
       \makecar@i{#1}% construit la partie au-dessus de la baseline
}

\makecar\lettreg\letter@code
\catcode`\@12
\pixelsize=3pt \pixelsep=1pt

Essai : \lettreg
****************** Fin code ******************


****************** Code 378 ******************
\catcode`\@11
\begingroup
\expandafter\gdef\csname impact@" "\endcsname{% d�finit la lettre "espace"
       \hskip 4\pixelsize plus.5\pixelsize minus.5\pixelsize\relax}%
\catcode`\^^M=13\relax% le retour � la ligne est actif
\edef^^M{\string,}% et se d�veloppe en une virgule (de catcode 12)
\catcode`\ =12\relax% l'espace devient un "caract�re autre"
\gdef\impact@alphabet{
a/
***
  *
***
*  *
****,
b/
*
*
***
*  *
*  *
*  *
***,
% beaucoup de caract�res omis
9/
***
*   *
*   *
****
   *
   *
***,
0/
***
*   *
*   *
* * *
*   *
*   *
***,
error/
* * *
* *
* * *
* *
* * *
* *
* * *}% <- commenter la fin de ligne
\endgroup%
% On parcourt le texte de remplacement de \impact@alphabet
\edef\saved@crcatcode{\catcode13=\the\catcode13\relax}%
\catcode`\^^M=13\relax% le retour � la ligne est actif
\edef^^M{\string,}% et se d�veloppe en une virgule (de catcode 12)
\expsecond{\doforeach\letter@name/\letter@code\in}\impact@alphabet%
       {\edef\letter@name{\letter@name}% d�veloppe la lettre (^^M devient ",")
       \edef\letter@code{\letter@code}% d�veloppe le code (^^M devient ",")
       \exparg\ifstart\letter@name,% si la lettre commence par ","
               {\edef\letter@name{\expandafter\gobone\letter@name}}% la retirer
               {}%
       \exparg\ifstart\letter@code,% si le code commence par ","
               {\edef\letter@code{\expandafter\gobone\letter@code}}% la retirer
               {}%
       \expandafter\makecar\csname impact@"\letter@name"\endcsname\letter@code%
       }%
\saved@crcatcode% redonne le catcode de ^^M
% % d�finit l'espace
\pixelsize=3pt \pixelsep=1pt
% puis, on affiche ce qui a �t� d�fini :
a = \csname impact@"a"\endcsname\qquad b = \csname impact@"b"\endcsname\qquad
9 = \csname impact@"9"\endcsname \qquad 0 = \csname impact@"0"\endcsname\qquad
error = \csname impact@"error"\endcsname
****************** Fin code ******************


****************** Code 379 ******************
\catcode`\@11
\newskip\letter@skip% ressort mis entre chaque lettre
\def\impactend{\impactend}% d�finit le quark de fin

\newmacro\impact[0.2ex][0pt]{% d�finit la macro � arguments optionnels
       \leavevmode% passer en mode horizontal
       \begingroup% dans un groupe semi-simple :
               \pixelsize=#1\relax \pixelsep=#2\relax% d�finir ces deux dimensions
               \letter@skip=#1 plus.1\pixelsize minus.1\pixelsize\relax% d�finir espace inter-lettre
               \baselineskip=% d�finir la distance entre les lignes de base
                       \dimexpr12\pixelsize+7\pixelsep\relax% � 12\pixelsize+7\pixelsep
               \lineskiplimit=0pt % si lignes trop serr�es
               \lineskip=2\pixelsize\relax% les espacer de 2\pixelsize
               \impact@i% puis aller voir le prochain token
}

% va voir le prochain token puis va le tester � \impact@ii
\def\impact@i{\futurelet\nxtletter\impact@ii}

\def\impact@ii{%
               \ifx\nxtletter\impactend% si le token est \let �gal � \impactend
                       \let\donext\impact@endprocess% aller � al macro de fin
               \else
                       \ifx\nxtletter\sptoken% si c'est un espace
                               \let\donext\impact@spc% aller � \impact@spc
                       \else
                               \let\donext\impact@arg% sinon, aller � \impact@arg
                       \fi
               \fi
               \donext% faire l'action d�cid�e ci-dessus
}

% mange un espace (argument d�limit�) et affiche "\letter@<spc>"
\expandafter\def\expandafter\impact@spc\space{%
               \csname impact@" "\endcsname
               \impact@i% puis va voir le prochain token
}
%
% lit l'argument suivant
\def\impact@arg#1{%
               \csname impact@% affiche
                       \ifcsname impact@"#1"\endcsname
                               "#1"% le caract�re \impact@"#1" s'il est d�fini
                       \else
                               "error"% sinon \impact@"error"
                       \fi
               \endcsname
               \hskip\letter@skip% ins�rer le ressort inter-lettre
               \impact@i% puis, aller voir le prochain token
}
\def\impact@endprocess\impactend{% macro ex�cut� lorsqque le quark \impactend va �tre lu
               \unskip% annuler le dernier ressort
               \par% composer le paragraphe pour prendre en compte
                   % \baselineskip, \lineskip et \lineskiplimit
       \endgroup% et fermer le groupe
}
\catcode`\!=12 % rend le point d'exclamation "gentil"
\impact Programmer en {TEX} est facile et tr{e`}s utile !\impactend\par
\impact[2pt][0.5pt]Programmer en {TEX} est facile et tr{e`}s utile !\impactend
****************** Fin code ******************


****************** Code 380 ******************
\newdimen\maingraddim \maingraddim=4pt % hauteur des graduations principales
\newdimen\maingradwd \maingradwd=0.5pt % �paisseur des graduations principales
\def\maingradx#1{%
       \lower1.5ex\clap{$\scriptscriptstyle#1$}% afficher l'argument au dessous
       \clap{\vrule height\maingraddim width\maingradwd depth0pt }% et la r�glure
}
D�but\maingradx{1}suite\maingradx{2}conclusion\maingradx{3}fin.
****************** Fin code ******************


****************** Code 381 ******************
\maingraddim=4pt \maingradwd=0.5pt
\newdimen\axiswd \axiswd=0.5pt
\newmacro\xaxis[1cm]1[1]1[4]{%% #1= dist  #2=xmin  #3=inc  #4=xmax  #5=subdiv
       \hbox{% mettre le tout dans une \hbox
               \rlap{% en d�bordement � droite :
                       \FOR\xx = #2 to #4 \do #3{% pour chaque graduation principale
                               \maingradx{\xx}% tracer la graduation et �crire l'abscisse
                               \kern#1\relax% puis se d�placer vers la droite
                       }%
               }%
               \vrule% tracer l'axe des abscisses
                       height\axiswd% d'epaisseur \axiswd, de longueur #1*(#4-#2)/#3
                       width\dimexpr#1*\decdiv{\dimtodec\dimexpr#4pt-#2pt\relax}{#3}\relax
                       depth 0pt\relax % et de profondeur nulle
       }%
}
a) \xaxis{-2}{5}suite

b) \frboxsep=0pt\frbox{\xaxis[1.25cm]{-1}[0.25]{1}}suite
****************** Fin code ******************


****************** Code 382 ******************
\maingraddim=4pt \maingradwd=0.5pt \axiswd=0.5pt
\newdimen\subgraddim \subgraddim=2.5pt
\newdimen\subgradwd \subgradwd=0.2pt
% trace un trait de subdivision
\def\subgradx{\clap{\vrule height\subgraddim width\subgradwd depth0pt }}

\newmacro\xaxis[1cm]1[1]1[4]{% #1= dist  #2=xmin  #3=inc  #4=xmax  #5=subdiv
       \hbox{% tout mettre dans une \hbox
               \setbox0=\hbox{% stocke dans une \hbox les grad secondaires entre 2 unit�s
                       \edef\dimsubgrad{\the\dimexpr#1/#5\relax}% dimension entre 2 subdivisions
                       \for\xx=1 to #5-1 \do{% ins�rer #5-1 fois
                               \kern\dimsubgrad% une espace secondaire
                               \subgradx% une graduation secondaire
                               }%
               }%
               \rlap{% en d�bordement � droite :
                       \FOR\xx = #2 to #4 \do #3{% pour chaque graduation principale
                               \maingradx{\xx}% imprimer l'abscisse
                               \ifdim\xx pt<#4pt % et en d�bordement � droite,
                                       \rlap{\copy0 }% les r�glures secondaires, sauf pour la derni�re
                               \fi
                               \kern#1\relax% se d�placer vers la droite
                       }%
               }%
               \vrule% tracer l'axe des abscisses
                       height\axiswd% d'epaisseur \axiswd, de longueur #1*(#4-#2)/#3
                       width\dimexpr#1*\decdiv{\dimtodec\dimexpr#4pt-#2pt\relax}{#3}\relax
                       depth 0pt\relax % et de profondeur nulle
       }%
}
a) \xaxis{-2}{5}[2]

)b \xaxis[1.25cm]{-1}[0.25]{1}[5]
****************** Fin code ******************


****************** Code 383 ******************
\maingraddim=4pt \maingradwd=0.5pt \axiswd=0.5pt
\subgraddim=2.5pt \subgradwd=0.2pt
\def\maingrady#1{% affiche...
       \vlap{\llap{$\scriptscriptstyle#1$\kern2pt }}% l'ordonn�e...
       \vbox to0pt{\vss\hrule height\maingradwd width\maingraddim depth0pt }% et la r�glure
}

% affiche une subdiv
\def\subgrady{\vlap{\hrule height\subgradwd width\subgraddim depth0pt }}
\newmacro\yaxis[1cm]1[1]1[4]{%
% #1= dist  #2=ymin  #3=inc  #4=ymax  #5=subdiv
       \vbox{%
               \offinterlineskip% d�sactiver le ressort d'interligne
               \setbox0=\vbox{% stocke dans une \hbox les grad secondaires entre 2 unit�s
                       \edef\dimsubgrad{\the\dimexpr#1/#5\relax}% dimension entre 2 subdivisions
                       \for\xx=1 to #5-1 \do{% ins�rer #5-1 fois
                               \kern\dimsubgrad% une espace secondaire
                               \subgrady% une graduation secondaire
                               }%
               }%
               \edef\dimsubgrad{\the\dimexpr#1/#5\relax}% distance entre 2 subdivisions
               \vbox to 0pt{% en d�bordement vers le bas
                       \FOR\xx = #4to#2\do-#3{%
                               \maingrady{\xx}% imprimer l'abscisse
                               \ifdim\xx pt>#2pt % et en d�bordement � droite,
                                       \vbox to 0pt{\copy0 \vss}% les r�glures secondaires, sauf pour la derni�re
                               \fi
                               \kern#1\relax% se d�placer vers la droite
                       }%
                       \vss% assure le d�bordement vers le bas
               }%
               \clap{\vrule% tracer l'axe des ordonn�es
                       width\axiswd% d'�paisseur \axiwd, et de hauteur (#4-#2)/#3*#1
                       height\decdiv{\dimtodec\dimexpr(#4pt-#2pt)\relax}{#3}\dimexpr#1\relax
                       depth 0pt\relax % profondeur nulle
               }%
       }%
}

Essai : \yaxis{-2}{5}[2]\qquad \frboxsep=0pt \frbox{\yaxis[0.75cm]{-1}[0.5]{3}[5]}
****************** Fin code ******************


****************** Code 384 ******************
\newdimen\xunit \xunit=1cm
\newdimen\yunit \yunit=0.75cm
\maingraddim=4pt \maingradwd=0.5pt \axiswd=0.5pt
\subgraddim=2.5pt \subgradwd=0.2pt
\catcode`@11
\newmacro\graphzone1[1]1[4]1[1]1[4]{%
       \leavevmode% quitter le mode vertical
       \begingroup% travailler dans un groupe semi-simple
               \def\graphxmin{#1}\def\graphxmax{#3}% sauvegarder
               \def\graphymin{#5}\def\graphymax{#7}% les
               \def\xincrement{#2}\def\yincrement{#6}% arguments
               \setbox0\hbox{\yaxis[\yunit]{#5}[#6]{#7}[#8]}% axe "y" dans boite 0
               \setbox1\hbox{\xaxis[\xunit]{#1}[#2]{#3}[#4]}% axe "x" dans boite 1
               \edef\graphboxht{\the\ht0 }% \graphboxh est la hauteur de la zone
               \edef\graphboxwd{\the\wd1 }% \graphboxw est la largeur de la zone
               \rlap{% annuler la dimension horizontale, et...
                       \box1 % ...afficher l'axe (Ox) puis
                       % le trait vertical � l'extr�me droite de la zone
                       \clap{\vrule height\dimexpr\graphboxht+\axiswd\relax width\axiswd depth0pt }%
                       }%
               \rlap{\box0 }% afficher l'axe (Oy) en annulant sa dimension horizontale
               \raise\graphboxht% puis monter tout en haut de la zone
                       % pour tracer le trait horizontal en annulant sa longueur
                       \rlap{\kern-0.5\axiswd% et en rattrapant le centrage de l'axe des ordonn�es
                               \vrule height\axiswd width\dimexpr\graphboxwd+\axiswd}%
               \begingroup% pour lire l'argument "<code>" :
                       \catcode`\^^M=9\relax % ignorer les retours � la ligne
                       \graphzone@i% appeler \graphzone@i
}
\def\graphzone@i#1{% lire le <code>...
               \endgroup% et fermer le groupe pr�c�demment ouvert
               \setbox0\hbox{#1}% mettre les instructions graphique dans la boite 0
               \wd0=\dimexpr\graphboxwd+\axiswd\relax% forcer sa dim horizontale
               \ht0=\dimexpr\graphboxht+\axiswd\relax% et verticale
               % pour correspondre aux dimension de la zone graphique
               \box0 % l'afficher
       \endgroup% sortir du groupe initial
}
\catcode`@12
essai\graphzone{-1}[0.5]{1.5}[5]{-20}[10]{10}[2]{\relax}fin
****************** Fin code ******************


****************** Code 385 ******************
\def\putat#1#2#3{%
       \leavevmode\rlap{\kern#1\vbox to0pt{\vss\hbox{#3}\kern#2}}%
}
Essai\putat{0.5cm}{0.3cm}{A}\putat{-0.2cm}{-0.1cm}{B}\putat{0pt}{0.2cm}{C}suite
****************** Fin code ******************


****************** Code 386 ******************
\def\ifinside#1[#2,#3]{%
       \ifnum\sgn{\dimexpr#1pt-#2pt\relax}\sgn{\dimexpr#1pt-#3pt}1=1
               \expandafter\secondoftwo
       \else
               \expandafter\firstoftwo
       \fi
}
1) \ifinside3.5[0.5,4]{vrai}{faux}\qquad
2) \ifinside-0.2[-0.4,-0.3]{vrai}{faux}\qquad
3) \ifinside-0.999[-1,-0.5]{vrai}{faux}
****************** Fin code ******************


****************** Code 387 ******************
\def\fonction#1{\dimtodec\dimexpr
       \decmul{#1}{\decmul{#1}{#1}}pt% x^3
       -\decmul{#1}{#1}pt% -x^2
       -#1pt*3% -3x
       +2pt\relax}% +2
1) \fonction{-4}\qquad% doit afficher -66
2) \fonction{-1.7}\qquad %  doit afficher -0.703
3) \fonction{1}\qquad%  doit afficher -1
4) \fonction{1.35}%  doit afficher -1.412125
****************** Fin code ******************


****************** Code 388 ******************
\newmacro\cross[2pt][0.2pt]{%
       % #1=dimensions de traits depuis le centre de la croix
       % #2=�paisseur des traits
       \leavevmode
       \vlap{%
               \clap{%
                       \vrule height#2 depth0pt width#1 % 1/2 trait horizontal gauche
                       \vrule height#1 depth#1 width#2  % trait vertical
                       \vrule height#2 depth0pt width#1 % 1/2 trait horizontal droit
               }%
       }%
}
Une croix : \cross{}puis une autre\cross[8pt][0.8pt]
****************** Fin code ******************


****************** Code 389 ******************
\maingraddim=4pt \maingradwd=0.5pt \axiswd=0.5pt
\subgraddim=2.5pt \subgradwd=0.2pt
\xunit=1.25cm \yunit=0.75cm

\def\maingradx#1{%
       \lower1.5ex\clap{$\scriptscriptstyle#1$}% afficher l'argument au dessous
       \clap{\vrule height\maingraddim width\maingradwd depth0pt }% et la r�glure
}

\def\subgradx{\clap{\vrule height\subgraddim width\subgradwd depth0pt }}

\newmacro\xaxis[1cm]1[1]1[4]{%
       \hbox{% tout mettre dans une \hbox
               \setbox0=\hbox{% stocke dans une \hbox les grad secondaires entre 2 unit�s
                       \edef\dimsubgrad{\the\dimexpr#1/#5\relax}% dimension entre 2 subdivisions
                       \for\xx=1 to #5-1 \do{% ins�rer #5-1 fois
                               \kern\dimsubgrad% une espace secondaire
                               \subgradx% une graduation secondaire
                               }%
               }%
               \rlap{% en d�bordement � droite :
                       \FOR\xx = #2 to #4 \do #3{% pour chaque graduation principale
                               \maingradx{\xx}% imprimer l'abscisse
                               \ifdim\xx pt<#4pt % et en d�bordement � droite,
                                       \rlap{\copy0 }% les r�glures secondaires, sauf pour la derni�re
                               \fi
                               \kern#1\relax% se d�placer vers la droite
                       }%
               }%
               \vrule% tracer l'axe des abscisses
                       height\axiswd% d'epaisseur \axiswd, de longueur #1*(#4-#2)/#3
                       width\dimexpr#1*\decdiv{\dimtodec\dimexpr#4pt-#2pt\relax}{#3}\relax
                       depth 0pt\relax % et de profondeur nulle
       }%
}

\def\maingrady#1{% affiche...
       \vlap{\llap{$\scriptscriptstyle#1$\kern2pt }}% l'ordonn�e...
       \vbox to0pt{\vss\hrule height\maingradwd width\maingraddim depth0pt }% et la r�glure
}

% affiche une subdiv
\def\subgrady{\vlap{\hrule height\subgradwd width\subgraddim depth0pt }}
% #1= dim entre 2 grad principales #2=abscisse d�part #3=incr�ment
% #4=abscisse arriv�e #5=nb intervalles secondaires
\newmacro\yaxis[1cm]1[1]1[4]{%
       \vbox{%
               \offinterlineskip% d�sactiver le ressort d'interligne
               \setbox0=\vbox{% stocke dans une \hbox les grad secondaires entre 2 unit�s
                       \edef\dimsubgrad{\the\dimexpr#1/#5\relax}% dimension entre 2 subdivisions
                       \for\xx=1 to #5-1 \do{% ins�rer #5-1 fois
                               \kern\dimsubgrad% une espace secondaire
                               \subgrady% une graduation secondaire
                               }%
               }%
               \edef\dimsubgrad{\the\dimexpr#1/#5\relax}% distance entre 2 subdivisions
               \vbox to 0pt{% en d�bordement vers le bas
                       \FOR\xx = #4to#2\do-#3{%
                               \maingrady{\xx}% imprimer l'abscisse
                               \ifdim\xx pt>#2pt % et en d�bordement � droite,
                                       \vbox to 0pt{\copy0 \vss}% les r�glures secondaires, sauf pour la derni�re
                               \fi
                               \kern#1\relax% se d�placer vers la droite
                       }%
                       \vss% assure le d�bordement vers le bas
               }%
               \clap{\vrule% tracer l'axe des ordonn�es
                       width\axiswd% d'�paisseur \axiwd, et de hauteur (#4-#2)/#3*#1
                       height\decdiv{\dimtodec\dimexpr(#4pt-#2pt)\relax}{#3}\dimexpr#1\relax
                       depth 0pt\relax % profondeur nulle
               }%
       }%
}

\catcode`@11
\newmacro\graphzone1[1]1[4]1[1]1[4]{%
       \leavevmode% quitter le mode vertical
       \begingroup% travailler dans un groupe semi-simple
               \def\graphxmin{#1}\def\graphxmax{#3}% sauvegarder
               \def\graphymin{#5}\def\graphymax{#7}% les
               \def\xincrement{#2}\def\yincrement{#6}% arguments
               \setbox0\hbox{\yaxis[\yunit]{#5}[#6]{#7}[#8]}% axe "y" dans boite 0
               \setbox1\hbox{\xaxis[\xunit]{#1}[#2]{#3}[#4]}% axe "x" dans boite 1
               \edef\graphboxht{\the\ht0 }% \graphboxh est la hauteur de la zone
               \edef\graphboxwd{\the\wd1 }% \graphboxw est la largeur de la zone
               \rlap{% annuler la dimension horizontale, et...
                       \box1 % ...afficher l'axe (Ox) puis
                       % le trait vertical � l'extr�me droite de la zone
                       \clap{\vrule height\dimexpr\graphboxht+\axiswd\relax width\axiswd depth0pt }%
                       }%
               \rlap{\box0 }% afficher l'axe (Oy) en annulant sa dimension horizontale
               \raise\graphboxht% puis monter tout en haut de la zone
                       % pour tracer le trait horizontal en annulant sa longueur
                       \rlap{\kern-0.5\axiswd% et en rattrapant le centrage de l'axe des ordonn�es
                               \vrule height\axiswd width\dimexpr\graphboxwd+\axiswd}%
               \begingroup% pour lire l'argument "<code>" :
                       \catcode`\^^M=9\relax % ignorer les retours � la ligne
                       \graphzone@i% appeler \graphzone@i
}
\def\graphzone@i#1{% lire le <code>...
               \endgroup% et fermer le groupe pr�c�demment ouvert
               \xunit=\decdiv1\xincrement\xunit% divise les unit�s par l'incr�ment
               \yunit=\decdiv1\yincrement\yunit
               \setbox0\hbox{#1}% mettre les instructions graphique dans la boite 0
               \wd0=\dimexpr\graphboxwd+\axiswd\relax% forcer sa dim horizontale
               \ht0=\dimexpr\graphboxht+\axiswd\relax% et verticale
               % pour correspondre aux dimension de la zone graphique
               \box0 % l'afficher
       \endgroup% sortir du groupe initial
}

\def\putat#1#2#3{%
       \leavevmode\rlap{\kern#1\vbox to0pt{\vss\hbox{#3}\kern#2}}%
}

\newmacro\cross[2pt][0.2pt]{%
       \leavevmode
       \vlap{%
               \clap{%
                       \vrule height#2 depth0pt width#1 % 1/2 terait horizontal gauche
                       \vrule height#1 depth#1 width#2  % trait vertical
                       \vrule height#2 depth0pt width#1 % 1/2 trait horizontal droit
               }%
       }%
}

\def\plot(#1,#2){% place "\plotstuff" aux coordonn�es #1,#2
       \edef\x@plot{#1}\edef\y@plot{#2}% d�velopper au cas o�
       \ifinside\x@plot[\graphxmin,\graphxmax]% si #1 est dans les limites
               {\ifinside\y@plot[\graphymin,\graphymax]% et si #2 l'est aussi
                       {\putat% placer aux coordonn�es
                               {\dimexpr\x@plot\xunit-\graphxmin\xunit\relax}% X=(x-xmin)/xinc
                               {\dimexpr\y@plot\yunit-\graphymin\yunit\relax}% Y=(y-ymin)/yinc
                               \plotstuff% le contenu de \plotstuff
                       }%
                       \relax
               }
               \relax
}

\def\showxaxis{% affiche l'axe (Ox)
       \ifinside0[\graphymin,\graphymax]%
               {\putat\z@{-\graphymin\yunit}{\vlap{\vrule width\graphboxwd height\axiswd}}}%
               \relax
}

\def\showyaxis{% affiche l'axe (Oy)
       \ifinside0[\graphxmin,\graphxmax]%
               {\putat{-\graphxmin\xunit}\z@{\clap{\vrule width\axiswd height\graphboxht}}}%
               \relax
}

\def\showaxis{\showxaxis\showyaxis}% affiche les deux axes
\catcode`@12

%%%%%%%%%%%%%%% 1er exemple :
\xunit=1cm \yunit=0.5cm
\def\fonction#1{\dimtodec\dimexpr\decmul{#1}{\decmul{#1}{#1}}pt-%
       \decmul{#1}{#1}pt-#1pt*3+2pt\relax}
Exemple 1 :\qquad
\graphzone{-2}[0.5]{2.5}[5]{-5}{5}[2]{%
       \let\plotstuff\cross% d�finit ce qu'il faut afficher comme point
       \FOR\xx=-2 to 2.5 \do 0.1{%
               \plot(\xx,\fonction{\xx})% afficher les points de coordonn�es (x ; f(x))
       }%
       \putat{5pt}{\dimexpr\graphboxht-10pt\relax}% afficher
               {$f(x)=x^3-x^2-3x+2$}% la fonction trac�e
       \showaxis% et les axes
}\par\medskip
%%%%%%%%%%%%% 2e exemple
\xunit=0.7cm \yunit=\xunit
\def\foncx#1{\dimtodec\dimexpr\decmul{#1}{\decmul{#1}{#1}}pt-%
       \decmul{4}{\decmul{#1}{#1}}pt-#1pt+4pt}
\def\foncy#1{\dimtodec\dimexpr\decmul{#1}{#1}pt-#1pt*2-6pt}
Exemple 2 :\qquad
\graphzone{-12}[2]{12}[2]{-8}[2]{8}[2]{%
       \def\plotstuff{\cross[1.25pt]}
       \FOR\tt = -5 to 5 \do 0.1 {%
               \plot(\foncx\tt,\foncy\tt)%
       }%
       \putat{5pt}{\dimexpr\graphboxht-20pt\relax}% afficher la fonction param�trique trac�e
               {$\left\{\vcenter{\hbox{$x(t)=t^3-4t^2-t-4$}\hbox{$y(t)=t^2-2t-6$}}\right.$}%
       \showaxis
}
****************** Fin code ******************


****************** Code 390 ******************
\def\mandeltest#1#2{%
       \def\zx{0}\def\zy{0}% zn=0 + i*0
       \def\zxx{0}\def\zyy{0}% carr�s de \zx et \zy
       \def\mandelresult{1}% le point appartient � M a priori
       \for\ii=1to\maxiter\do1{%
               \advance\count255 by1
               \edef\zy{\dimtodec\dimexpr\decmul{\decmul2\zx}\zy pt+#2pt\relax}%
               \edef\zx{\dimtodec\dimexpr\zxx pt-\zyy pt+#1pt\relax}%%
               \edef\zxx{\decmul\zx\zx}%
               \edef\zyy{\decmul\zy\zy}%
               \ifdim\dimexpr\zxx pt+\zyy pt\relax>4pt
                       \def\mandelresult{0}%
                       \exitfor\ii
               \fi
       }%
}
\def\mandel#1#2{% #1=points par unit� #2=nombre maximal d'it�rations
       \graphzone{-2}[1]{1}[2]{-1}[1]{1}[2]{%
               \def\maxiter{#2}%
               \edef\plotstuff{\the\dimexpr\xunit/#1\relax}% taille d'un pixel
               \edef\plotstuff{\vrule height\plotstuff width\plotstuff}%
               \edef\increment{\decdiv{1}{#1}}% incr�ment
               \count255=0 % compteur des it�rations
               \FOR\xxx = -2 to 1 \do \increment{% pour chaque
                       \FOR\yyy = 0 to 1 \do \increment{% pixel du domaine
                               \mandeltest\xxx\yyy% tester s'il est dans M
                               \ifnum\mandelresult=1 % si oui,
                                       \plot(\xxx,\yyy)\plot(\xxx,-\yyy)% afficher les 2 points
                               \fi
                       }%
               }%
       \edef\plotstuff{$\scriptstyle\number\count255 $}% affiche la valeur du compteur
       \plot(-1.99,0.92)% aux coordonn�es (-1.99 ; 0.92)
       }%
}
\xunit=3cm \yunit=3cm \mandel{400}{500}
****************** Fin code ******************


****************** Code 391 ******************
\catcode`\@11
\protected\def\numsep{\kern0.2em }% \numsep est le s�parateur mis tous les 3 chiffres

\def\formatdecpart#1{% #1=s�rie de chiffres
       \ifempty{#1}% si la partie d�cimale est vide
               {}% ne rien afficher
               {{,}\formatdecpart@i 1.#1..}% sinon, afficher la virgule et mettre en forme
}

% #1=compteur de caract�res #2= chiffre courant
% #3= chiffres restants     #4 = chiffres d�j� trait�s
\def\formatdecpart@i#1.#2#3.#4.{%
       \ifempty{#3}% si #2 est le dernier chiffre
               {#4#2}% le mettre en derni�re position et tout afficher, sinon
               {\ifnum#1=3 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                       % si 3 chiffres sont atteint, rendre #1 �gal � 1 et
                       {\formatdecpart@i 1.#3.#4#2\numsep.}% mettre #2\numsep en dernier puis recommencer
                       % sinon, mettre #2 en derni�re position et recommencer
                       % tout en incr�mentant #1 de 1
                       {\expandafter\formatdecpart@i \number\numexpr#1+1.#3.#4#2.}%
               }%
}
a) \formatdecpart{1234567}\qquad
b) \formatdecpart{987125}\qquad
c) \formatdecpart{56}\qquad
d) \edef\foo{\formatdecpart{2014}}\meaning\foo
****************** Fin code ******************


****************** Code 392 ******************
\catcode`\@11
\protected\def\numsep{\kern0.2em }% \numsep est le s�parateur mis tous les 3 chiffres
\def\formatintpart#1{% #1=s�rie de chiffres
       \formatintpart@i 1.#1..% appelle la macro r�cursive
}

% #1=compteur de caract�res #2= chiffre courant
% #3= chiffres restants     #4 = chiffres d�j� trait�s
\def\formatintpart@i#1.#2#3.#4.{%
       \ifempty{#3}% si #2 est le dernier chiffre
               {#2#4}% le mettre en premi�re position et tout afficher, sinon
               {\ifnum#1=3 \expandafter\firstoftwo\else\expandafter\secondoftwo
               \fi% si 3 chiffres sont atteint, rendre #1 �gal � 1 et
                       {\formatintpart@i 1.#3.\numsep#2#4.}% mettre "\numsep#2" en premier et recommencer
                       % sinon, mettre #2 en premi�re position et recommencer
                       % tout en incr�mentant #1 de 1
                       {\expandafter\formatintpart@i \number\numexpr#1+1.#3.#2#4.}%
               }%
}
\catcode`\@12
a) \formatintpart{1234567}\qquad b) \formatintpart{987125}\qquad
c) \formatintpart{56}\qquad
d) \edef\foo{\formatintpart{2014}}\meaning\foo
****************** Fin code ******************


****************** Code 393 ******************
\catcode`\@11
\def\formatintpart#1{% #1=s�rie de chiffres
       \expandafter\formatintpart@i\expandafter1\expandafter.\romannumeral\reverse{#1\z@}..%
}

\catcode`\@12
a) \formatintpart{1234567}\qquad b) \formatintpart{987125}\qquad
c) \formatintpart{56}\qquad
d) \edef\foo{\formatintpart{2014}}\meaning\foo
****************** Fin code ******************


****************** Code 394 ******************
\catcode`\@11
\def\ifnodecpart#1{\if@nodecpart#1.\@nil}% teste si #1 est un entier
\def\if@nodecpart#1.#2\@nil{\ifempty{#2}}

\def\formatnum#1{%
       \ifnodecpart{#1}% s'il n'y a pas de partie d�cimale
               {\formatintpart{#1}}% formatter la partie enti�re
               {\formatnum@i#1\@nil}% sinon, formatter les deux parties
}

\def\formatnum@i#1.#2\@nil{%
       \formatintpart{#1}% formatte la partie enti�re
       \formatdecpart{#2}% et la partie d�cimale
}

\catcode`\@12
a) \formatnum{3.1415926}\qquad
b) \formatnum{1987654.12301}\qquad
c) \edef\foo{\formatnum{0987654.12300}}$\foo$
****************** Fin code ******************


****************** Code 395 ******************
\catcode`\@11
\def\removefirstzeros#1{%
       \removefirstzeros@i#1\quark% ajoute "\quark" en dernier
}
\def\removefirstzeros@i#1{% #1=chiffre courant
       \ifx\quark#1% fin atteinte donc nombre = 0
               \expandafter0% laisser un z�ro
       \else
               \ifx0#1% si le chiffre lu est un 0
                       \expandafter\expandafter\expandafter\removefirstzeros@i% recommencer
               \else% sinon remettre le chiffre #1 et tout afficher jusqu'� \removefirstzeros@i
                       \expandafter\expandafter\expandafter\removefirstzeros@ii
                       \expandafter\expandafter\expandafter#1%
               \fi
       \fi
}
\def\removefirstzeros@ii#1\quark{#1}
\catcode`\@12
a) \removefirstzeros{000325478}\qquad
b) \removefirstzeros{00000}\qquad
c) \edef\foo{\removefirstzeros{001000}}\meaning\foo\qquad
d) \long\def\>#1<{\detokenize{#1}}
  \expandafter\>\romannumeral\removefirstzeros{0123}<
****************** Fin code ******************


****************** Code 396 ******************
\long\def\>#1<{\detokenize{#1}}
\expandafter\>\romannumeral-`\@\removefirstzeros{000123}<
****************** Fin code ******************


****************** Code 397 ******************
\catcode`\@11
\def\removelastzeros#1{%
       \exparg\reverse% inverser apr�s
               {\romannumeral-`\.% tout d�velopper
                       \expandafter\removelastzeros@i% enlever les 0 de gauche apr�s
                       \romannumeral\reverse{#1\z@}\quark% avoir invers� #1
               }%
}
\def\removelastzeros@i#1{% enl�ve tous les 0 de gauche
       \unless\ifx\quark#1% si la fin n'est pas atteinte
               \ifx0#1% si le chiffre lu est un 0
                       \expandafter\expandafter\expandafter\removelastzeros@i% recommencer
               \else% sinon remettre le chiffre et tout afficher jusqu'� \removefirstzeros@i
                       \expandafter\expandafter\expandafter\removelastzeros@ii
                       \expandafter\expandafter\expandafter#1%
               \fi
       \fi
}
\def\removelastzeros@ii#1\quark{#1}
\catcode`\@12
a) \removelastzeros{0003254780}\qquad
b) \removelastzeros{00000}\qquad
c) \edef\foo{\removelastzeros{001000}}\foo\qquad
\long\def\>#1<{\detokenize{#1}}
d) \expandafter\>\romannumeral-`\.\removelastzeros{012300}<
****************** Fin code ******************


****************** Code 398 ******************
\catcode`\@11
\protected\def\numsep{\kern0.2em }% \numsep est le s�parateur mis tous les 3 chiffres

\def\formatdecpart#1{% #1=s�rie de chiffres
       \ifempty{#1}% si la partie d�cimale est vide
               {}% ne rien afficher
               {{,}\formatdecpart@i 1.#1..}% sinon, afficher la virgule et mettre en forme
}

% #1=compteur de caract�res #2= chiffre courant
% #3= chiffres restants     #4 = chiffres d�j� trait�s
\def\formatdecpart@i#1.#2#3.#4.{%
       \ifempty{#3}% si #2 est le dernier chiffre
               {#4#2}% le mettre en derni�re position et tout afficher, sinon
               {\ifnum#1=3 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                       % si 3 chiffres sont atteint, rendre #1 �gal � 1 et
                       {\formatdecpart@i 1.#3.#4#2\numsep.}% mettre #2\numsep en dernier puis recommencer
                       % sinon, mettre #2 en derni�re position et recommencer
                       % tout en incr�mentant #1 de 1
                       {\expandafter\formatdecpart@i \number\numexpr#1+1.#3.#4#2.}%
               }%
}

\def\formatintpart#1{% #1=s�rie de chiffres
       \expandafter\formatintpart@i\expandafter1\expandafter.%
       \romannumeral\reverse{#1\z@}..% appelle la macro r�cursive
}

% #1=compteur de caract�res #2= chiffre � d�placer
% #3= chiffres restants     #4 = chiffres d�j� trait�s
\def\formatintpart@i#1.#2#3.#4.{%
       \ifempty{#3}% si #2 est le dernier chiffre � traiter
               {#2#4}% le mettre en premi�re position et tout afficher, sinon
               {\ifnum#1=3 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                       % si 3 chiffres sont atteint, rendre #1 �gal � 1 et
                       {\formatintpart@i 1.#3.\numsep#2#4.}% mettre \numsep#2 en premier puis recommencer
                       % sinon, mettre #2 en derni�re position et recommencer
                       % tout en incr�mentant #1 de 1
                       {\expandafter\formatintpart@i\number\numexpr#1+1.#3.#2#4.}%
               }%
}
\def\removefirstzeros#1{%
       \removefirstzeros@i#1\quark% ajoute "\quark" en dernier
}
\def\removefirstzeros@i#1{% #1=chiffre courant
       \ifx\quark#1% fin atteinte donc nombre = 0
               \expandafter0% laisser un z�ro
       \else
               \ifx0#1% si le chiffre lu est un 0
                       \expandafter\expandafter\expandafter\removefirstzeros@i% recommencer
               \else% sinon remettre le chiffre #1 et tout afficher jusqu'� \removefirstzeros@i
                       \expandafter\expandafter\expandafter\removefirstzeros@ii
                       \expandafter\expandafter\expandafter#1%
               \fi
       \fi
}
\def\removefirstzeros@ii#1\quark{#1}

\def\removelastzeros#1{%
       \exparg\reverse% inverser apr�s
               {\romannumeral-`\.% tout d�velopper
                       \expandafter\removelastzeros@i% enlever les 0 de gauche apr�s
                       \romannumeral\reverse{#1\z@}\quark% avoir invers� #1
               }%
}
\def\removelastzeros@i#1{% enl�ve tous les 0 de gauche
       \unless\ifx\quark#1% si la fin n'est pas atteinte
               \ifx0#1% si le chiffre lu est un 0
                       \expandafter\expandafter\expandafter\removelastzeros@i% recommencer
               \else% sinon remettre le chiffre et tout afficher jusqu'� \removefirstzeros@i
                       \expandafter\expandafter\expandafter\removelastzeros@ii
                       \expandafter\expandafter\expandafter#1%
               \fi
       \fi
}
\def\removelastzeros@ii#1\quark{#1}

% renvoie vrai s'il n'y a pas de partie d�cimale
\def\if@nodecpart#1.#2\@nil{\ifempty{#2}}

\def\formatnum#1{\formatnum@i1!#1!}

% #1 = <s�rie de signes> suivie de "1"
% #2 = caract�re courant
% #3 = caract�res non trait�s
\def\formatnum@i#1!#2#3!{%
       \ifx+#2\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {\ifempty{#3}% si #2=+ et #3 est vide
                       {\number#1 }% afficher "+1" ou "-1" (il n'y avait que des signes)
                       {\formatnum@i#2#1!#3!}% sinon, mettre le signe #2 devant #1
               }
               {\ifx-#2\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                       {\ifempty{#3}% si #2=- et #3 est vide
                               {\number#1 }% afficher "+1" ou "-1" (il n'y avait que des signes)
                               {\formatnum@i#2#1!#3!}% sinon, mettre le signe #2 devant #1
                       }% #2 est le dernier caract�re qui n'est pas un signe + ou -
                       {\ifnum#1<0 -\fi% si "<signes>1" est <0 afficher un "-"
                       \formatnum@ii{#2#3}% formatter le nombre form� avec "#2#3""
                       }%
               }%
}

\def\formatnum@ii#1{%
       \if@comma{#1}% si #1 comporte une virgule
               {\formatnum@iii#1\@nil}% la remplacer par un "." et recommencer
               {\if@nodecpart#1.\@nil% puis si les chiffres restants sont un entier
                       {\formatintpart{#1}}% formatter l'entier
                       {\formatnum@iv#1\@nil}% sinon, formatter le nombre
               }%
}

\def\formatnum@iii#1,#2\@nil{\formatnum@ii{#1.#2}}

\def\formatnum@iv#1.#2\@nil{% formatte le nombre d�cimal #1.#2
       \exparg\formatintpart{\romannumeral-`\.\removefirstzeros{#1}}%
       \exparg\formatdecpart{\romannumeral-`\.\removelastzeros{#2}}%
}

\def\if@comma#1{\if@comma@i#1,\@nil}% teste la pr�sence d'un virgule dans #1
\def\if@comma@i#1,#2\@nil{\ifempty{#2}\secondoftwo\firstoftwo}
\catcode`\@12

a) \formatnum{3,141592653589793238462643383279502884197169399375105820974944592}\par
b) \formatnum{---+69874}\qquad
c) \formatnum{0032100,98000}\qquad
d) \formatnum{+++010.01100}\qquad
e) \formatnum{-+--+}\qquad
f) \formatnum{---00.0000}\qquad
g) \formatnum{+99,0000}\qquad
h) \formatnum{.123456}\par
i) \edef\foo{\formatnum{-+-+-010500,090900}}\meaning\foo
****************** Fin code ******************


****************** Code 399 ******************
\setbox0=\vbox{%
       \hbox{Premi�re ligne}
       \hbox{Deuxi�me ligne}
       \hbox{Avant-derni�re ligne}
       \hbox{Derni�re ligne}
}

\frboxsep=0pt % aucun espace entre le contenu et l'encadrement
Boite initiale de hauteur \the\ht0 {} : \frbox{\copy0 }
\splittopskip0pt % ne rajouter aucun espace au sommet de la boite restante
\setbox1=\vsplit0 to 22pt % couper la boite � 22pt de hauteur

Boite 1 de hauteur \the\ht1 {} : \frbox{\box1 }

Boite 0 de hauteur \the\ht0 {} : \frbox{\box0 }
****************** Fin code ******************


****************** Code 400 ******************
\setbox0=\vbox{%
       \hbox{Premi�re ligne}
       \hbox{Deuxi�me ligne}
       \hbox{Avant-derni�re ligne}
       \hbox{Derni�re ligne}
}

\edef\restorevbadness{\vbadness=\the\vbadness\relax}% restaurera le \vbadness
\vbadness=10000 % plus d'avertissement pour boite verticale
\frboxsep=0pt % aucun espace entre le contenu et l'encadrement
Boite initiale de hauteur \the\ht0 {} : \frbox{\copy0 }
\splittopskip0pt % ne rajouter aucun espace au sommet de la boite restante
\setbox1=\vsplit0 to 22pt % couper la boite � 22pt de hauteur
\setbox1=\vbox{\unvbox1 }% la boite 1 prend la hauteur naturelle
\restorevbadness\relax% restaure le \vbadness

Boite 1 de hauteur \the\ht1 {} : \frbox{\box1 }

Boite 0 de hauteur \the\ht0 {} : \frbox{\box0 }
****************** Fin code ******************


****************** Code 401 ******************
\catcode`@11
\newbox\remainbox
\newbox\partialbox
\newdimen\cut@ht

\def\breakpar{%
       \par\nointerlineskip% termine le paragraphe pr�c�dent
       \vskip\frboxsep\relax% et saute une petite espace verticale
       \begingroup
               \splittopskip\topskip% \topskip en haut des boites coup�es
               \topskip=0pt % neutraliser le \topskip
               % nbre de r�glures horizontales contribuant � l'encadrement restant (2 au d�but)
               \def\coeff@rule{2}%
               \setbox\remainbox=\vbox\bgroup% compose la boite apr�s avoir...
                       \advance\hsize by -2\dimexpr\frboxrule+\frboxsep\relax% ajust� sa largeur
}

\def\endbreakpar{%
               \egroup% fin de la composition de la boite
               \def\rule@arg{ULR}% prendre l\cut@htes r�glures d'encadrement haute, gauche et droite
               \splitbox% puis, aller � l'algorithme de coupure
       \endgroup% une fois fini, sortir du groupe semi-simple
}

\def\splitbox{%
       \ifvoid\remainbox% si la boite est vide, c'est la fin du processus
               \par\nointerlineskip% termine le paragraphe pr�c�dent
               \vskip\frboxsep\relax% et saute un petit espace vertical
       \else% sinon
               \expandafter\splitbox@i% aller � \splitbox@i
       \fi
}

\def\splitbox@i{%
       \hbox{}% composer un noeud en mode vertical
       \nointerlineskip% pas de ressort d'interligne
       % calculer la dimension verticale disponible dans la page pour le texte de la boite
       \cut@ht=\dimexpr\pagegoal-\pagetotal-(\frboxsep+\frboxrule)*\coeff@rule\relax
       % si dimension totale du texte > dimension disponible pour le texte
       \ifdim\dimexpr\ht\remainbox+\dp\remainbox>\cut@ht% si une coupure doit �tre faite
                       \advance\cut@ht\dimexpr%   augmenter Dv de l'espace verticale lib�r�e
                               +\frboxsep+\frboxrule% par la r�glure inf�rieure qui n'est pas sur cette page
                               \relax
               \edef\old@vbadness{\the\vbadness}% sauvegarder \badness
               \vbadness=10000 % d�sactive les avertissement lors de la coupure
               \def\coeff@rule{1}% ne prendre en compte que r�glure D + espace D
               \setbox\partialbox=\vsplit\remainbox to\cut@ht% coupe � la hauteur calcul�e
               % \partialbox retrouve sa hauteur naturelle
               \setbox\partialbox=\vbox{\unvbox\partialbox}%
               \vbadness=\old@vbadness\relax% restaure \vbadness
               \printpartialbox% imprime la boite partielle
               \vfill\eject% et compose la page en cours
       \else% si une coupure n'est pas n�cessaire :
               \setbox\remainbox\vbox{\unvbox\remainbox}% reprendre la hauteur naturelle
               \setbox\partialbox=\box\remainbox% \partialbox devient \remainbox
                                                % et cette derni�re devient vide
               \cut@ht=\dimexpr\ht\partialbox+\dp\partialbox\relax% hauteur � encadrer
               \edef\rule@arg{\rule@arg D}% ajouter "D" aux r�glures � tracer
               \printpartialbox% afficher la boite restante
       \fi
       \splitbox
}

\def\printpartialbox{% imprime \partialbox
       \expandafter\framebox\expandafter[\rule@arg]{%
               \vbox to\cut@ht{\unvbox\partialbox\vss}}%
       \def\rule@arg{LR}% ne mettre que les r�glures d et g
}

\def\dummytext#1{%
       \for\xx=1to#1\do% composer #1 fois la phrase suivante :
               {Ceci est un texte sans aucun int\'er\^et dont le seul but est de meubler
               la page artificiellement.
               }%
}

\catcode`@12
\dummytext{5}
\frboxsep=5pt

\breakpar
       \dummytext{70}
\endbreakpar

\dummytext{5}
****************** Fin code ******************


****************** Code 402 ******************
\setbox0=\vbox{%
       \hsize=5cm
       Ceci est un texte sans aucun int�r�t dont le seul but est de meubler
       la page de fa�on artificielle.
}

Boite 0 : \copy0 % affiche la boite totale
\medbreak

\edef\restorevfuzz{\vfuzz=\the\vfuzz\relax}% appel�e apr�s la coupure
\vfuzz=\maxdimen% annule les avertissements pour d�bordement
\splittopskip=0pt % ne rajouter aucun espace au sommet de la boite restante
\setbox1=\vsplit0 to 0pt % couper la boite � 0pt de hauteur
\restorevfuzz% restaurer \vfuzz
\setbox1=\vbox{\unvbox1}% redonner � la boite sa hauteur d'origine

Boites 1+0 : \vbox{%
       \offinterlineskip% annule le ressort d'interligne
       \box1 % affiche la premi�re ligne
       \box0 %affiche les lignes restantes
}
****************** Fin code ******************


****************** Code 403 ******************
\def\vdim#1{\dimexpr\ht#1+\dp#1\relax}% hauteur totale de la boite #1
\setbox0=\vbox{%
       \hsize=5cm Ceci est un texte sans aucun int�r�t dont le seul but est
       de meubler la page de fa�on artificielle.
}
\edef\htbefore{\the\vdim0}% hauteur de la boite 0

Boite 0 : \copy0 % affiche la boite totale
\medbreak

\edef\restoreparam{%
       \vfuzz=\the\vfuzz\relax% sauvegarde le \vfuzz
       \splittopskip=\the\splittopskip% et \splittopskip
}%
\vfuzz=\maxdimen% annule les avertissements pour d�bordement
\splittopskip=0pt % ne rajouter aucun espace au sommet de la boite restante
\setbox1=\vsplit0 to 0pt % couper la boite � 0pt de hauteur
\restoreparam
\setbox1=\vbox{\unvbox1}% redonner � la boite sa hauteur d'origine

\edef\intersplitspace{\the\dimexpr\htbefore-(\vdim0+\vdim1)\relax}%
Boites 1+0 : \vbox{%
       \offinterlineskip% annule le ressort d'interligne
       \box1 % affiche la premi�re ligne
       \vskip\intersplitspace\relax% ajoute le ressort perdu � la coupure
       \box0 % affiche les lignes restantes
}
****************** Fin code ******************


****************** Code 404 ******************
\setbox0=\vbox{%
       \hsize=5cm Ceci est un texte sans aucun int�r�t dont le seul but est
       de meubler la page de fa�on artificielle.
}

Boite 0 : \copy0 % affiche la boite totale
\medbreak

\edef\restoreparam{%
       \vfuzz=\the\vfuzz\relax% sauvegarde le \vfuzz
       \splittopskip=\the\splittopskip\relax% , le \splittopskip
       \savingvdiscards=\the\savingvdiscards\relax% et le \savingvdiscards
       }%
\vfuzz=\maxdimen% annule les avertissements pour d�bordement
\splittopskip=0pt % ne rajouter aucun espace au sommet de la boite restante
\savingvdiscards=1 % autorise la sauvagarde des �l�ments supprim�s
\setbox1=\vsplit0 to 0pt % couper la boite � 0pt de hauteur
\setbox1=\vbox{\unvbox1}% redonner � la boite sa hauteur d'origine
\restoreparam

Boites 1+0 : \vbox{%
       \offinterlineskip% annule le ressort d'interligne
       \box1 % affiche la premi�re ligne
       \splitdiscards% affiche les �l�ments ignor�s
       \box0 % affiche les lignes restantes
}
****************** Fin code ******************


****************** Code 405 ******************
\catcode`@11
\newbox\remainbox% boite contenant le texte total
\newbox\currentline% boite contenant le ligne en cours
\newcount\linecnt% compteur pour num�roter les lignes

\def\vdim#1{\dimexpr\ht#1+\dp#1\relax}% hauteur totale de la boite #1

\newmacro\leftline[0pt]{% d�finit ce qui se trouve � gauche de chaque ligne
       \def\wd@left{#1}%
       \def\stuff@left
}

\newmacro\rightline[0pt]{% d�finit ce qui se trouve � droite de chaque ligne
       \def\wd@right{#1}%
       \def\stuff@right
}

\let\formatline=\identity% par d�faut, afficher chaque ligne telle quelle

% Par d�faut :
\leftline[11pt]{$\scriptscriptstyle\number\linecnt$\kern3pt }% num�rotation � gauche
\rightline{}% rien � droite

\def\numlines{%
       \par\smallskip
       \begingroup% dans un groupe semi-simple
               \splittopskip=0pt % ne rajouter aucun espace au sommet de la boite restante
               \linecnt=0 % initialiser le compteur de lignes
               \savingvdiscards=1 % autorise la sauvagarde des �l�ments supprim�s
               \setbox\remainbox=\vbox\bgroup% compose la boite...
                       \advance\hsize by% diminuer la \hsize
                       -\dimexpr\wd@left+\wd@right\relax% de la largeur des contenus
}

\def\endnumlines{%
       \egroup
       \offinterlineskip
       \split@line
}

\def\split@line{%
       \ifvoid\remainbox% si la boite est vide
               \par% fin du processus
               \endgroup% fermer le groupe ouvert au d�but
       \else% sinon
               \advance\linecnt 1 % incr�mente le compteur de lignes
               \edef\htbefore{\the\vdim\remainbox}%
               \edef\restorevfuzz{\vfuzz=\the\vfuzz\relax}% sauvegarde le \vfuzz
               \vfuzz=\maxdimen% annule les avertissements pour d�bordement
               \setbox\currentline=\vsplit\remainbox to 0pt % couper la boite � 0pt de hauteur
               \restorevfuzz
               \setbox\currentline=\vbox{\unvbox\currentline}% redonner � la boite sa hauteur
               \edef\intersplitspace{% calcul de l'espace vertical perdu � la coupure
                       \the\dimexpr\htbefore-(\vdim\remainbox+\vdim\currentline)\relax
               }%
               \hbox{% en mode vertical et dans une hbox, afficher :
                       \hbox to\wd@left{\hss\stuff@left}%   1) ce qui est � gauche
                       \formatline{\box\currentline}%       2) la ligne courante
                       \hbox to\wd@right{\stuff@right\hss}% 3) ce qui est � droite
               }%
               \splitdiscards% affiche ce qui a �t� ignor� � la coupure
               \expandafter\split@line% recommencer
       \fi
}

\def\dummytext#1{%
       \for\xx=1to#1\do% composer #1 fois la phrase suivante :
               {Ceci est un texte sans aucun int�r�t dont le seul but est de meubler
               la page de fa�on artificielle. }%
}

\catcode`@12
\parindent=2em

ESSAI 1 :
\numlines
       \dummytext{2}\par% 2 phrases
       $$1+1=2$$\par% des maths
       \dummytext{1}\par% une phrase
       \hrulefill\par% un leaders
       \dummytext{2}% 2 phrases
       \hrule height2pt depth 2pt %une \hrule
       \vskip10pt % saute 10pt verticalement
       \dummytext{1}% une phrase
\endnumlines\medbreak

ESSAI 2 :
\leftline{}\rightline{}% rien � gauche et rien � droite
\frboxsep=-\frboxrule% encadrer vers "l'int�rieur"
\let\formatline\frbox% lignes encadr�es
\numlines
       \dummytext{4}
\endnumlines\medbreak

ESSAI 3 :
\let\formatline\identity
\leftline[7pt]{%
       \for\xx= 1 to 2 \do{% ins�rer 2 fois
               \setbox0=\hbox{% % mettre dans une \hbox une \vrule de "bonnes dimensions"
                       \vrule height\ht\currentline depth\dimexpr\dp\currentline+\intersplitspace
                              width0.5pt }%
               \dp0=\dp\currentline% r�ajuster la profondeur (c-�-d enlever \intersplitspace)
               \box0 % afficher le boite
               \kern2pt % et ins�rer un espace horizontal de 2pt apr�s chaque r�glure verticale
               }%
       \kern2pt % ajouter 2pt de plus entre les lignes et le texte
}

\rightline[10pt]{\kern5pt $\scriptscriptstyle\number\linecnt$}% num�roter � droite

\numlines
       \dummytext{2}

       $$a^2+b^2=c^2$$

       \dummytext{2}
\endnumlines
****************** Fin code ******************


****************** Code 406 ******************
% d�finition des ressorts "inter-lettre" et "inter-mot"
\newskip\interletterskip \interletterskip=0.25em plus0.05em minus0.05em
\newskip\interwordskip   \interwordskip=3\interletterskip\catcode`\@11
\catcode`@11
\def\spreadtxt@testtoken#1{% macro qui teste le token
       \ifcat\noexpand#1\sptoken% si le token est un espace
               \parseadd{%
                       \unskip% retirer le pr�c�dent ressort
                       \hskip\interwordskip}% et ajouter le ressort inter-mot
       \else
               \ifcat\noexpand#1a% si le token est une lettre
                       \parseadd{#1\hskip\interletterskip}% ajouter le ressort inter-lettre
               \else
                       \ifcat\noexpand#1.% si le token est "autre", comme le "."
                               \parseadd{#1\hskip\interletterskip}% ajouter le ressort inter-lettre
                       \else% sinon
                               \parseadd{#1}% ajouter le token lu
                       \fi
               \fi
       \fi
       \parse@i
}
\def\spreadtxt{%
       \ifstarred% si �toil�e
               {\spreadtxt@i{\parse*}}% appeler \parse*
               {\spreadtxt@i{\parse}}% sinon, appeler \parse
}
\def\spreadtxt@i#1#2{% #1= appel "\parse*" ou "\parse"   #2 = texte � espacer
       \begingroup% dans un groupe
               \let\testtoken=\spreadtxt@testtoken% modifier \testtoken
               #1#2\parsestop% et appeler \parse
       \endgroup
}
\catcode`@12

\spreadtxt{Comme on le voit sur cet exemple, une espace est ins�r�e apr�s
{\it chaque} caract�re de catcode 10, 11 ou 12.}
\medbreak

\spreadtxt*{Comme on le voit sur cet exemple, une espace est ins�r�e apr�s
{\it chaque} caract�re de catcode 10, 11 ou 12.}
****************** Fin code ******************


****************** Code 407 ******************
\newskip\interletterskip
\newskip\interwordskip
\catcode`\@11
\newtoks\spacetxt@toks%  le registre qui contient le texte final

\def\spacetxt{%
       \let\spacetxt@endprocess\spacetxt@endnormal
       % d�finit la macro appel�e en fin de processus -> a priori : fin normale
       \ifstarred% si la macro est �toil�e
               {\let\spacetxt@recurse\spacetxt@star% d�finir la macro r�cursive
               \spacetxt@i% et aller � \spacetxt@i
               }% sinon
               {\let\spacetxt@recurse\spacetxt@nostar% d�finir la macro r�cursive
               \spacetxt@i% et aller � \spacetxt@i
               }%
}

\newmacro\spacetxt@i[0.3em plus0.07em minus.07em][3\interletterskip]1{%
% arg optionnel #1 et #2 = ressorts inter-lettre et inter--mot
% #3 = texte � espacer
       \interletterskip=#1\relax
       \interwordskip=#2\relax
       \def\spacetxt@code{#3}% met le texte � espacer dans \spacetxt@code
       \spacetxt@toks{}% initialiser le registre contenant le texte final
       \spacetxt@recurse% aller � la macro r�cursive pr�c�demment d�finie
}

\newif\if@indivifound% bool�en qui sera vrai si un motif sp�cial est rencontr�

\def\rightofsc#1#2{%
       \exparg\ifin{#1}{#2}% si #1 contient le #2
               {\def\right@of##1#2##2\@nil{\def#1{##2}}%
               \expandafter\right@of#1\@nil% appelle la macro auxiliaire
               }%
               {\let#1=\empty}% sinon, #1 est vide
}

\def\spacetxt@nostar{%
       \exparg\ifempty{\spacetxt@code}% si texte restant est vide
               \spacetxt@endprocess% aller � la fin du processus
               {\@indivifoundfalse% sinon, a priori, les motifs non r�guliers ne sont pas trouv�s
               % pour chaque \indivi@tmp dans \indivilist
               \expsecond{\doforeach\indivi@tmp\in}{\indivilist}% pour chaque motif indivisible
                       {% si le code commence par le motif courant
                       \exptwoargs\ifstartwith\spacetxt@code\indivi@tmp
                               {% l'ajouter dans le registre ainsi que l'espace inter-lettre
                               \eaddtotoks\spacetxt@toks{\indivi@tmp\hskip\interletterskip}%
                               % et enlever le motif du texte restant � lire
                               \expsecond{\rightofsc\spacetxt@code}{\indivi@tmp}%
                               \@indivifoundtrue% marquer qu'un motif a �t� trouv�
                               \doforeachexit% et sortir pr�matur�ment de la boucle
                               }%
                               \relax% si le code ne commence pas le motif courant -> ne rien faire
                       }%
               \unless\if@indivifound% si aucun motif n'a �t� trouv�
                       \grab@first\spacetxt@code\spacetxt@temp% retirer le 1er caract�re du texte
                       \ifx\spacetxt@temp\space% si le 1er caract�re est un espace
                               \addtotoks\spacetxt@toks{%
                                       \unskip% annuler le pr�c�dent ressort
                                       \hskip\interwordskip}% ajouter l'espace inter-mot au registre de token
                       \else% si le 1er caract�re n'est pas un espace
                               % ajouter ce caract�re et l'espace inter-lettre au registre de token
                               \eaddtotoks\spacetxt@toks{\spacetxt@temp\hskip\interletterskip}%
                       \fi
               \fi
               \spacetxt@recurse% enfin, continuer le processus
               }%
}

\def\spacetxt@star{%
       \exparg\ifempty{\spacetxt@code}% si texte restant est vide
               \spacetxt@endprocess% aller � la fin du processus
               {% sinon, si texte commence par "{"
               \exparg\ifbracefirst{\spacetxt@code}%
                       {\grab@first\spacetxt@code\spacetxt@temp
                       % mettre {<argument} dans \spacetxt@temp
                       \begingroup% ouvrir un groupe
                       % mettre le contenu de l'argument dans \spacetxt@code
                       \expandafter\def\expandafter\spacetxt@code\spacetxt@temp
                       \let\spacetxt@endprocess\spacetxt@endingroup% changer le processus de fin
                       \spacetxt@toks{}% initialiser
                       \spacetxt@recurse% ex�cuter le processus avec ce nouveau texte
                       }% si le code ne commence pas par "{", aller � \spacetxt@nostar mais comme
                       \spacetxt@nostar% \spacetxt@recurse vaut \spacetxt@star, n'y faire qu'1 boucle
               }%
}

\def\spacetxt@endnormal{% fin de processus normal
       \the\spacetxt@toks% afficher le registre � token
       \unskip% et supprimer le dernier ressort
}

\def\spacetxt@endingroup{% fin du processus dans un groupe :
       \expandafter\endgroup\expandafter% avant de fermer le groupe
       \addtotoks\expandafter\spacetxt@toks\expandafter% ajouter au registre hors du groupe
               {\expandafter{\the\spacetxt@toks}}% ce qui est collect� localement mis entre {}
       \spacetxt@recurse% puis aller � la macro r�cursive
}

\catcode`\@12
\def\indivilist{�,�}% liste des motifs sp�ciaux
\spacetxt*{Comme on le voit sur cet exemple, une espace est ins�r�e apr�s
{\it chaque} caract�re.}
\medbreak

\def\indivilist{�,es,au,<<,>>}
\spacetxt[4pt plus.7pt minus.7pt][12pt plus2pt minus2pt]{Ici, les motifs <<es>> et <<au>>
restent indivisibles et la ligature des guillemets devient possible en d�clarant "<<" et
">>" comme motifs.}
****************** Fin code ******************


****************** Code 408 ******************
\catcode`\@11
\def\ttcode#1{% lit #1, le <d�limiteur> de d�but
       \def\ttcode@i##1#1{% ##1 = <texte> entre d�limiteurs
               \tt% passe en fonte � chasse fixe
               \setbox0=\hbox{ }%
               \edef\spc@wd{\the\wd0 }% longueur d'un espace
               \spacetxt
                       [.1pt plus0pt minus.1pt]% espace inter-lettre
                       [\glueexpr\wd0+.3pt plus.1pt minus.1pt\relax]% espace inter-mot
                       {##1}% le <texte> est compos� par \spacetxt
               \endgroup
       }%
       \begingroup
               \def\indivilist{<<,>>,{,,},--}% (rajouter �, �, �, etc. en codage UTF8)
               \def\do##1{\catcode`##1=12 }%
               \dospecials% rend inoffensifs tous les tokens sp�ciaux
               \letactive\ =\space % rend l'espace actif
               \ttcode@i% va lire le <texte> et le d�limiteur de fin
}
\catcode`\@12

\hfill\vrule\vbox{%
       \hsize=.75\hsize
       Avec \ttcode/\ttcode/, on peut ins�rer une adresse internet <<
       \ttcode-http://www.gutenberg.eu.org/Typographie- >> puis repasser en fonte normale
       puis \ttcode+m�me composer un court passage en fonte � chasse fixe -- m�me si les
       coupures de mots se font n'importe o� -- et aussi afficher tous les caract�res
       sp�ciaux <<{$^ _$#}&+>>, et finir en fonte normale\ldots
}\vrule\hfill\null
****************** Fin code ******************


****************** Code 409 ******************
\def\ttwide{0.7}% coefficient pour la largeur de composition
\def\ttindent{5}% nombre de caract�res d'indentation
\hfill\vrule
\vbox{%
       \ttfamily% en TeX, on �crirait "\tt"
       \setbox0\hbox{0}% \wd0 est donc la largeur d'un caract�re
       \parindent=\ttindent\wd0 % r�glage de l'indentation
       \hsize=\ttwide\hsize % compose sur 70% de la largeur
       Dans ce paragraphe, compos� en fonte � chasse fixe et o� les limites gauches
       et droites du texte ont �t� trac�es, on constate que les caract�res sont
       exactement les uns au-dessous d'une ligne � l'autre. Des d�bordements dans
       la marge deviennent alors in�vitables, car la largeur de composition (ici
       \the\hsize) n'est pas un multiple de la largeur d'un caract�re (\the\wd0 ),
       le quotient des deux valant environ
       \xdef\ttratio{\decdiv{\dimtodec\hsize}{\dimtodec\wd0 }}\ttratio.
}%
\vrule\hfill\null
****************** Fin code ******************


****************** Code 410 ******************
Fonte normale : \fontname\font\par
{\bf Fonte grasse : \fontname\font\par}
{\it Fonte italique : \fontname\font\par}
{\sc Fonte petites majuscules : \fontname\font}
****************** Fin code ******************


****************** Code 411 ******************
\font\gras=LinLibertineTB-tlf-t1 at 8pt
\font\ital= LinLibertineTI-tlf-t1 at 8pt
\font\itgras=LinLibertineTBI-tlf-t1 at 8pt
Du texte normal {\gras puis en gras, \ital en italique,
\itgras en italique gras} et retour � la normale.
****************** Fin code ******************


****************** Code 412 ******************
Code du caract�re de coupure = \number\hyphenchar\font\par
Caract�re de coupure : "\char\hyphenchar\font"
****************** Fin code ******************


****************** Code 413 ******************
\def\longtext{Voici une phrase �crite avec des mots insignifiants mais terriblement,
       �pouvantablement, horriblement et ind�niablement longs.}
% cr��r une macro restaurant le \hyphenchar
\edef\restorehyphenchar{\hyphenchar\font=\number\hyphenchar\font}%

%comportement normal, caract�re de coupure "-"
1) \vrule\vbox{\hsize=5cm \longtext}\vrule\hfill
% modification du caract�re de coupure "W"
2) \vrule\vbox{\hsize=5cm \hyphenchar\font=`W \longtext}\vrule
\medbreak
% interdiction des coupures de mots
3) \vrule\vbox{\hsize=5cm \hyphenchar\font=-1 \longtext}\vrule
\restorehyphenchar
****************** Fin code ******************


****************** Code 414 ******************
\def\longtext{Voici une phrase �crite avec des mots insignifiants mais terriblement,
       �pouvantablement, horriblement et ind�niablement longs.}

\edef\restorehyphenchar{\hyphenchar\font=\number\hyphenchar\font}%
\vrule\vbox{\hsize=5cm \hyphenchar\font=-1 \sloppy \longtext}\vrule
\restorehyphenchar
****************** Fin code ******************


****************** Code 415 ******************
a) \texttt{\number\hyphenchar\font}\qquad
b) {\ttfamily\number\hyphenchar\font}
****************** Fin code ******************


****************** Code 416 ******************
\leavevmode
\vbox{%
       \hsize=.4\hsize
       \Souligne{Police � chasse variable}%
       \vskip5pt
       espace inter-mot = \the\fontdimen2\font\par
       �trirement inter-mot = \the\fontdimen3\font\par
       compression inter-mot = \the\fontdimen4\font
}\hfill
\vbox{%
       \tt
       \hsize=.4\hsize
       \Souligne{Police � chasse fixe}%
       \vskip5pt
       espace inter-mot = \the\fontdimen2\font\par
       �trirement inter-mot = \the\fontdimen3\font\par
       compression inter-mot = \the\fontdimen4\font
}
****************** Fin code ******************


****************** Code 417 ******************
\def\ttwide{0.7}\def\ttindent{5}%
\hfill\vrule
\vbox{%
       \ttfamily
       \hyphenchar\font=`\- % change le caract�re de coupure de la fonte en cours
       \setbox0\hbox{0}\parindent=\ttindent\wd0
       \hsize=\ttwide\hsize % compose sur 70% de la largeur
       Dans ce paragraphe, compos� en fonte � chasse fixe et o� les limites gauche
       et droite du texte ont �t� trac�es, on constate que les caract�res sont
       exactement les uns au-dessous des autres d'une ligne � l'autre. Des d�bordements
       dans la marge deviennent in�vitables m�me si les coupures des mots sont
       � nouveau rendues possibles.%
}%
\vrule\hfill\null
****************** Fin code ******************


****************** Code 418 ******************
\frboxsep=0.5pt
\def\printallchars{%
       \leavevmode
       \for\xx=0 to255\do{%
               \vbox{% empiler verticalement
                       \offinterlineskip% en d�sactivant le ressort d'interligne
                       \setbox0\hbox{\frbox{\char\xx}}%
                       \copy0 % la boite contenant le caract�re encadr�
                       \kern1pt% saute 1pt vertical
                       \hbox to\wd0{\hss$\scriptscriptstyle\xx$\hss}% le num�ro
               }\hskip0.5em plus1pt minus1pt % saute 0.5em horizontalement
       }%
}
\tt
Nom de la fonte = \fontname\font\par
\printallchars
****************** Fin code ******************


****************** Code 419 ******************
\setbox0=\hbox{\tt\char23}
Largeur = \the\wd0 \qquad Hauteur = \the\ht0 \qquad Profondeur = \the\dp0
****************** Fin code ******************


****************** Code 420 ******************
{\tt\xdef\nfont{\the\font}}
Largeur = \the\fontcharwd\nfont23 \qquad Hauteur = \the\fontcharht\nfont23
\qquad Profondeur = \the\fontchardp\nfont23
****************** Fin code ******************


****************** Code 421 ******************
\newmacro\ttstart[5]{%
       \begingroup
       \tt
       \edef\restorefontsettings{% stocke les param�tres de fonte
               \hyphenchar\font=\the\hyphenchar\font\relax% le \hyphenchar
               \fontdimen2\font=\the\fontdimen2\font\relax% et les param�tres d'espacement
               \fontdimen3\font=\the\fontdimen3\font\relax
               \fontdimen4\font=\the\fontdimen4\font\relax
       }%
       \fontdimen3\font=0.30\fontdimen2\font% composante + = 30% de la dimension naturelle
       \fontdimen4\font=0.20\fontdimen2\font% composante - = 20% de la dimension naturelle
       \hyphenchar\font=`\- % on autorise la coupure des mots (au cas o� on utilise latex)
       \setbox0\hbox{0}% largeur d'un caract�re
       \parindent=#1\wd0 % indentation (en nombre de caract�res)
       \ignorespaces
}
\def\ttstop{%
       \restorefontsettings% restaure les param�tres de fonte
       \endgroup% et ferme le groupe
}
\hfill\vrule
\def\ttwide{0.70}%
\vbox{%
       \hsize=\ttwide\hsize % compose sur 70% de la largeur
       \ttstart[5]
       Dans ce paragraphe, compos� en fonte � chasse fixe et o� les limites gauche
       et droite du texte ont �t� trac�es, on constate que les caract�res ne sont pas
       exactement les uns au-dessous des autres entre les lignes du paragraphe.
       Puisque les espaces sont redevenus �tirables, les d�bordements dans la marge
       (m�me s'ils restent possibles), sont bien plus rares et ce d'autant plus que
       le nombre d'espaces dans une ligne est grand.%
       \ttstop
}%
\vrule\hfill\null
****************** Fin code ******************


****************** Code 422 ******************
\catcode`\@11
\newcount\brktt@cnt
\newdimen\brktt@interletter
\newif\ifline@start% bool�en vrai lorsqu'aucun caract�re n'est encore affich�
\newif\if@indivifound% bool�en qui sera vrai si un motif sp�cial est rencontr�

\def\insert@blankchar{%
       \ifstarred\insert@blankchar@ii\insert@blankchar@i
}

\def\insert@blankchar@i#1{% ins�re une espace de largeur #1 caract�res complets
       \ifnum\numexpr#1\relax>0
               \kern\numexpr#1\relax\dimexpr\ttchar@width+\brktt@interletter\relax
       \fi
}

\def\insert@blankchar@ii#1{% ins�re #1-1 caract�res complets + 1 largeur de caract�re
       \ifnum\numexpr#1\relax>0
               \insert@blankchar@i{#1-1}\kern\ttchar@width
       \fi
}

\def\restart@hbox#1{%
       \egroup% feerme la \hbox pr�c�dente
       \hbox\bgroup% ouvre la suivante
       \expsecond{\def\tt@remaintext}
               {\romannumeral\removefirstspaces@i{#1}}% initialiser le code � composer
       \let\previous@char\space% initialise le caract�re pr�c�dent
       \line@starttrue% aucun caract�re n'a encore �t� imprim�
       \brktt@cnt=0\relax% remettre le compteur � 0
}

\newmacro\breaktt[0.3em][\hsize]1{%
% arg optionnel #1 et #2 = ressorts inter-lettre et dimension horizontale texte
% #3 = texte � espacer
       \begingroup% ouvrir un groupe et le fermer � la toute fin
       \par% commencer un nouveau paragraphe -> passage en mode vertical
       \parindent=0pt% emp�che l'indentation
       \tt% passer en fonte � chasse fixe
       \setbox0 = \hbox{M}% la boite 0 contient un caract�re
       \edef\ttchar@width{\the\wd0 }% largeur de chaque caract�re en fonte \tt
       \edef\text@width{\the\dimexpr#2\relax}% largeur de composition
       % les 2 lignes suivantes rendent le compteur �gal � E((L-l)/(l+Delta))
       \brktt@cnt=\numexpr\dimexpr#2-\wd0 \relax\relax% largeur diminu�e du 1er caract�re
       \divide\brktt@cnt by \numexpr\dimexpr\wd0 + #1 \relax\relax
       % le nombre de caract�re par ligne est �gal � 1 de plus :
       \edef\maxchar@num{\number\numexpr\brktt@cnt+1\relax}%
       % calcul de la dimension inter-lettre
       \brktt@interletter=\dimexpr(\text@width-\ttchar@width*\maxchar@num)/\brktt@cnt\relax
       % stocke le texte apr�s avoir enlev� les �ventuels espaces extremes :
       \expsecond{\expsecond{\def\tt@remaintext}}{\removetrailspaces{#3}}%
       \unless\ifx\tt@remaintext\empty% si le texte � composer n'est pas vide
               \hbox\bgroup% d�marrer la boite horizontale contenant la premi�re ligne
               \insert@blankchar\ttindent% ins�rer une espace d'indentation
               \brktt@cnt=\ttindent\relax% tenir compte du nombre de caract�res indent�s
               \line@starttrue% il s'agit du d�but d'une ligne
               \expandafter\breaktt@i% aller � la macro r�cursive
       \fi
}

\def\breaktt@i{%
       \print@nchar\maxchar@num% afficher \maxchar@num caract�res
       \ifx\tt@remaintext\empty% si texte restant est vide
               \egroup% fermer la hbox
               \par% aller � la ligne
               \endgroup% fermer le groupe ouvert au d�but
       \else
               \unless\ifnum\brktt@cnt<\maxchar@num\relax% si la ligne est remplie
                       \exparg\restart@hbox{\tt@remaintext}% ferme la hbox et en r�-ouvre une
               \fi
               \expandafter\breaktt@i% enfin, continuer le processus
       \fi
}

\def\print@nchar#1{% affiche #1 caract�res pris dans \tt@remaintext
       \for\xxx= 1 to #1 \do 1{%
               \ifx\tt@remaintext\empty% si le code restant � composer est vide
                       \exitfor\xxx%sortir de la boucle pr�matur�ment
               \else
                       \@indivifoundfalse% sinon, a priori, les motifs de ligature ne sont pas trouv�s
                       % pour chaque \indivi@tmp dans la liste de ligatures
                       \expsecond{\doforeach\indivi@tmp\in}{\liglist}%
                               {% si le code commence par la ligature courante
                               \exptwoargs\ifstartwith\tt@remaintext\indivi@tmp
                                       {\let\previous@char\indivi@tmp% prendre le motif pour caract�re courant,
                                       \expsecond{\rightofsc\tt@remaintext}{\indivi@tmp}% l'enlever du texte restant
                                       \@indivifoundtrue% marquer qu'un motif a �t� trouv�
                                       \doforeachexit% et sortir pr�matur�ment de la boucle
                                       }%
                                       {}% si le code ne commence pas le motif courant -> ne rien faire
                               }%
                       \unless\if@indivifound% si aucun motif trouv�,
                               \grab@first\tt@remaintext\previous@char%  lire le premier caract�re
                       \fi
                       \advance\brktt@cnt by 1 % incr�menter le compteur de caract�res
                       \hbox to\ttchar@width{\hss\previous@char\hss}% afficher le caract�re lu
                       \line@startfalse% nous ne sommes plus au d�but d'une ligne
                       \ifnum\brktt@cnt<\maxchar@num\relax% si la ligne n'est pas encore remplie
                               \kern\brktt@interletter% ins�rer le ressort inter-lettre
                       \else
                               \exitfor\xxx% sinon, sortir de la boucle pr�matur�ment
                       \fi
               \fi
       }%
}
\catcode`\@12

\def\liglist{<<,>>}% liste des motifs de ligature
                  % ajouter �, �, etc si codage UTF8 + moteur 8 bits
\def\ttindent{3}% valeur de l'indentation'
\vrule\vbox{\breaktt[4pt][.7\hsize]{%
Dans ce paragraphe, compos� en fonte � chasse fixe et o� les limites gauche
et droite du texte ont �t� trac�es, on constate que les caract�res sont
exactement les uns au-dessous des autres d'une ligne � l'autre. Plus aucun
d�bordement n'a lieu, car une espace correctement calcul�e est ins�r�e entre
chaque caract�re. Les mots, en revanche, sont toujours coup�s <<sauvagement>>.%
}%
}\vrule\smallbreak

\vrule\vbox{\breaktt[1pt][6cm]{%
Dans ce paragraphe, compos� en fonte � chasse fixe et o� les limites gauche
et droite du texte ont �t� trac�es, on constate que les caract�res sont
exactement les uns au-dessous des autres d'une ligne � l'autre. Plus aucun
d�bordement n'a lieu, car une espace correctement calcul�e est ins�r�e entre
chaque caract�re. Les mots, en revanche, sont toujours coup�s <<sauvagement>>.%
}%
}\vrule
****************** Fin code ******************


****************** Code 423 ******************
\catcode`\@11
\newcount\brktt@cnt
\newdimen\brktt@interletter
\newif\ifline@start% bool�en vrai lorsqu'aucun caract�re n'est encore affich�
\newif\if@indivifound% bool�en qui sera vrai si un motif sp�cial est rencontr�

\newmacro\breakttA[0.3em][\hsize]1{%
% arg optionnel #1 et #2 = ressorts inter-lettre et dimension horizontale texte
% #3 = texte � espacer
       \begingroup% ouvrir un groupe et le fermer � la toute fin
       \par% commencer un nouveau paragraphe -> passage en mode vertical
       \parindent=0pt% emp�che l'indentation
       \tt% passer en fonte � chasse fixe
       \setbox0 = \hbox{M}% la boite 0 contient un caract�re
       \edef\ttchar@width{\the\wd0 }% largeur de chaque caract�re en fonte \tt
       \edef\text@width{\the\dimexpr#2\relax}% largeur de composition
       % les 2 lignes suivantes rendent le compteur �gal � E((L-l)/(l+Delta))
       \brktt@cnt=\numexpr\dimexpr#2-\wd0 \relax\relax% largeur diminu�e du 1er caract�re
       \divide\brktt@cnt by \numexpr\dimexpr\wd0 + #1 \relax\relax
       % le nombre de caract�res par ligne est �gal � 1 de plus :
       \edef\maxchar@num{\number\numexpr\brktt@cnt+1\relax}%
       % calcul de la dimension inter-lettre
       \brktt@interletter=\dimexpr(\text@width-\ttchar@width*\maxchar@num)/\brktt@cnt\relax
       % stocke le texte apr�s avoir enlev� les �ventuels espaces extremes :
       \expsecond{\expsecond{\def\tt@remaintext}}{\removetrailspaces{#3}}%
       \unless\ifx\tt@remaintext\empty% si le texte � composer n'est pas vide
               \hbox\bgroup% d�marrer la boite horizontale contenant la premi�re ligne
               \insert@blankchar\ttindent% ins�rer une espace d'indentation
               \brktt@cnt=\ttindent\relax% tenir compte du nombre de caract�res indent�s
               \line@starttrue% il s'agit du d�but d'une ligne
               \expandafter\breakttA@i% aller � la macro r�cursive
       \fi
}

\def\breakttA@i{%
       \edef\remaining@chars{% calculer le nombre de caract�res restant � placer sur la ligne
               \numexpr\maxchar@num-\brktt@cnt\relax}%
       \len@tonextword% \next@len contient le nombre de caract�res du prochain mot
       % si le mot + l'eventuel "-" qui le suit ne peut pas loger sur la ligne en cours
       \ifnum\numexpr\next@len+\extra@char\relax>\remaining@chars\relax
               \ifline@start% et si c'est le d�but d'une ligne
                       % avertir l'utilisateur
                       \message{Largeur de composition trop faible pour
                               \unexpanded\expandafter{\next@word}^^J}%
                       % et composer tout de m�me "� la sauvage" jusqu'� la fin de la ligne
                       \exparg\print@nchar{\number\numexpr\maxchar@num-\brktt@cnt}%
               \else% si la ligne en cours n'est pas au d�but
                       \insert@blankchar*{\maxchar@num-\brktt@cnt}% remplir la ligne d'espaces
               \fi
               \exparg\restart@hbox{\tt@remaintext}% commencer une nouvelle ligne
               \expandafter\breakttA@i% et poursuivre le processus
       % s'il y a assez de place pour accueillir ce qui est avant la prochaine coupure
       \else
               \print@nchar\next@len% afficher le mot
               \ifx\tt@remaintext\empty% si texte restant est vide
                       \insert@blankchar*{\maxchar@num-\brktt@cnt}% remplir la ligne
                       \egroup% fermer la hbox en cours
                       \par% aller � la ligne
                       \endgroup% fermer le groupe ouvert au d�but. Fin du processus
               \else% si le texte restant n'est pas vide
                       \ifnum\brktt@cnt<\maxchar@num\relax% si la ligne n'est pas remplie
                                       \print@nchar{1}% afficher le caract�re qui suit le mot (" " ou "-")
                       \else% si la ligne est remplie
                               \exparg\restart@hbox{\tt@remaintext}% ferme la hbox et en r�-ouvre une
                       \fi
                       \expandafter\expandafter\expandafter\breakttA@i% enfin, continuer le processus
               \fi
       \fi
}

\def\leftofsc#1#2{% dans la macro #1, garde ce qui est � gauche de #2
       \def\leftofsc@i##1#2##2\@nil{\def#1{##1}}%
       \expandafter\leftofsc@i#1#2\@nil
}

\def\len@tonextword{% stocke dans \next@len le nombre de caract�res avant
                   % le prochain point de coupure dans \tt@remaintext
       \let\next@word\tt@remaintext% copie \tt@remaintext dans la macro temporaire \next@word
       \leftofsc\next@word{ }% ne prend que ce qui est avant le prochain espace
       \exparg\ifin\next@word{-}% si le mot contient un tiret
               {\leftofsc\next@word{-}% prendre ce qui est � gauche de ce tiret
               \def\extra@char{1}% il y a un caract�re de plus � loger apr�s le mot
               }% sinon, le caract�re apr�s le mot est un espace
               {\def\extra@char{0}% qu'il ne faut pas compter
               }%
       \setbox0=\hbox{\next@word}% enfermer le mot dans une boite
       % et en calculer le nombre de caract�res = dim(boite)/dim(caract�re)
       \edef\next@len{\number\numexpr\dimexpr\wd0 \relax/\dimexpr\ttchar@width\relax\relax}%
}
\catcode`\@12

\def\liglist{<<,>>}% liste des motifs de ligature (mettre �, �, etc si codage UTF8)
\def\ttindent{3}

\vrule\vbox{\breakttA[3pt][8cm]{%
Dans ce paragraphe, compos� en fonte � chasse fixe et o� les limites gauche
et droite du texte ont �t� trac�es, on constate que les caract�res sont
exactement les uns au-dessous d'une ligne � l'autre. Plus aucun d�bordement
n'a lieu, car une espace correctement calcul�e est ins�r�e entre chaque
caract�re. Dor�navant, les mots ne sont plus coup�s <<~sauvagement~>>.
}}\vrule\medbreak

\leavevmode\vrule\vbox{\breakttA[1pt][5cm]{%
Dans ce paragraphe, compos� en fonte � chasse fixe et o� les limites gauche
et droite du texte ont �t� trac�es, on constate que les caract�res sont
exactement les uns au-dessous d'une ligne � l'autre. Plus aucun d�bordement
n'a lieu, car une espace correctement calcul�e est ins�r�e entre chaque
caract�re. Dor�navant, les mots ne sont plus coup�s <<~sauvagement~>>.
}}\vrule\qquad\def\ttindent{0}%
\vrule\vbox{\breakttA[0.6pt][2cm]{mot-compos� mot-cl� passe-droit au-dessus
l�-bas remonte-pente vingt-huit Notre-Dame-de-Lourdes Mont-Blanc
Saint-Jean-de-Luz}}\vrule
****************** Fin code ******************


****************** Code 424 ******************
\newmacro\zerocompose[]2{%
% #1=code � ex�cuter avant la composition
% #2=registre de boite recevant le r�sultat
% #3= texte � composer en largeur 0pt
       \setbox#2=\vbox{%
               #1% code a ex�cuter (changement de fonte par exemple)
               \hfuzz=\maxdimen% annule les avertissements pour d�bordement horizontaux
               \hbadness=10000 % annule les avertissements pour mauvaise boite horizontale
               \pretolerance=-1 % d�sactive la premi�re passe (celle sans coupures)
               \tolerance=10000 % passe avec coupures accept�e
               \hyphenpenalty=-10000 % favorise fortement les copures de mots
               \lefthyphenmin=2 \righthyphenmin=3 % longueur mini des fragments de d�but et fin
               \clubpenalty=0 % pas de p�nalit� suppl�mentaire apr�s la premi�re ligne
               \interlinepenalty=0 % pas de p�nalit� inter-ligne
               \widowpenalty=0 % pas de p�nalit� suppl�mentaire avant la derni�re ligne
               \exhyphenpenalty=0 % ne pas p�naliser une coupure explicite
               \leftskip=0pt \rightskip=0pt % d�sactive les �ventuels ressorts lat�raux
               \everypar={}% d�sactive l'�ventuel \everypar
               \parfillskip=0pt plus1fil % r�gle le \parfillskip par d�faut
               \hsize=0pt % largeur de composition = 0pt
               \edef\restorehyphenchar{\hyphenchar\font=\number\hyphenchar\font}%
               \hyphenchar\font=`\- % impose "-" comme caract�re de coupure
               \noindent % pas d'indentation + passage en mode horizontal
               \hskip0pt \relax% premier noeud horizontal pour permettre la coupure de la suite
               #3\par% compose #3
               \restorehyphenchar% restaure le caract�re de coupure
               }%
}
\zerocompose{0}{Programmation}%
\leavevmode\box0
\hskip 5cm
\zerocompose{0}{Composer en largeur nulle}%
\box0
****************** Fin code ******************


****************** Code 425 ******************
\def\dummytext{Ceci est un texte sans aucun int�r�t dont le seul but est de meubler
               la page de fa�on artificielle. }
\setbox0=\vtop{% d�finit la boite 0
       \hsize=8cm
       \dummytext\dummytext
}

a) Boite pleine : \copy0

b) \setbox0=\vtop{%
       \unvbox0 % boite pr�c�demment compos�e
       \global\setbox1=\lastbox% et capture la derni�re ligne dans la boite 1
       }%
       Derni�re ligne = |\hbox{\unhbox1 }|\par% redonne � box1 sa largeur naturelle
       Boite restante = \box0
****************** Fin code ******************


****************** Code 426 ******************
\def\dummytext{Ceci est un texte sans aucun int�r�t dont le seul but est de meubler
               la page de fa�on artificielle. }
\setbox0=\vtop{% d�finit la boite 0
       \hsize=8cm
       \dummytext\dummytext
}

\setbox0=\vtop{\unvbox0 \global\setbox1=\lastbox}
\setbox1=\hbox{\unhbox1 }
1) |\box1|

\setbox0=\vtop{\unvbox0 \global\setbox1=\lastbox}
\setbox1=\hbox{\unhbox1 }
2) |\box1|

\setbox0=\vtop{\unvbox0 \global\setbox1=\lastbox}
\setbox1=\hbox{\unhbox1 }
3) |\box1|
****************** Fin code ******************


****************** Code 427 ******************
\setbox0=\vbox{\hsize=2.5cm Programmer en TeX est facile}%
\showboxbreadth=5 \showboxdepth=3 \tracingonline=1
\showbox0
****************** Fin code ******************


****************** Code 428 ******************
\newbox\tempbox
\def\reversebox#1{% affiche le contenu de la boite verticale #1
       \setbox#1=\vbox{%
               \unvbox#1% composer la boite #1
               \unskip\unpenalty% retirer ce qui n'est pas capturable par \lastbox
               \global\setbox0=\lastbox% la boite 1 devient la derni�re ligne
       }%
       |\hbox{\unhbox0 }|\par% afficher la boite 1 dans sa largeur d'origine
       \ifvoidorempty{#1}% si le registre #1 contient une boite vide
               \relax% ne rien faire
               {\reversebox{#1}}% sinon, rencommencer
}
\def\dummytext{Ceci est un texte sans aucun int�r�t dont le seul but est de meubler
               la page de fa�on artificielle. }
\setbox\tempbox=\vbox{% d�finit la boite 0
       \hsize=8cm \dummytext\dummytext
}

\reversebox\tempbox
****************** Fin code ******************


****************** Code 429 ******************
% compose "Programmation" en largeur 0 dans la boite 0 :
\zerocompose{0}{Programmation}%
Boite initiale : \copy0 \par% compose la boite r�sultante
\vfuzz=\maxdimen% annule les avertissements pour d�bordements
\splittopskip=0pt % ne rajouter aucun espace au sommet de la boite restante
\setbox1 =\vsplit0 to 0pt % coupe la boite 0 � 0pt
{% dans un groupe (o� la boite 0 sert de brouillon)
       \setbox0 =\vbox{% affecter � la boite brouillon
               \unvbox1 % la boite 1 compos�e dans sa largeur naturelle
               \unskip\unpenalty% annule ce qui n'est pas une boite
               \global\setbox2 =\lastbox% affecte globalement la derni�re (et unique) ligne
                                        % � la boite 1
       }%
}% ferme le groupe
\setbox2=\hbox{\unhbox2}% rend � la boite 2 sa largeur naturelle
Premi�re ligne = "\box2 "% compose la boite 2
****************** Fin code ******************


****************** Code 430 ******************
\catcode`@11
\def\hyphlengths#1#2{%#2 = macro contenant les longueurs de coupures du mot #1
       \begingroup
               \zerocompose
                       [\tt% passer en fonte � chasse fixe
                       \setbox\z@\hbox{M}\xdef\ttwidth{\the\wd\z@}% mesurer la largeur des caract�res
                       ]\z@{#1}% compose en 0pt dans la boite 0
               \let#2 = \empty% initialise la macro #2
               \def\cumul@length{0}% le cumul des longueurs initialis� � 0
               \vfuzz=\maxdimen% annule les avertissements pour d�bordement
               \splittopskip=\z@ % ne rajouter aucun espace au sommet de la boite restante
               \loop
                       \setbox1=\vsplit\z@ to \z@% couper la boite � 0pt de hauteur
                       {\setbox\z@=\vbox{\unvbox1 \unskip\unpenalty\global\setbox1=\lastbox}}%
                       \setbox1=\hbox{\unhbox1 }%
                       \unless\ifvoid\z@% si la boite 0 n'est pas encore vide
                               \edef\cumul@length{% mettre � jour \cumul@length
                                       \number\numexpr
                                               \cumul@length
                                               +% ajouter le quotient "largeur syllabe/largeur d'1 caract�re"
                                               \wd1/\dimexpr\ttwidth\relax
                                               -1% et soustraire 1 (le caract�re "-")
                                               \relax
                               }%
                               % ajouter � #2 la virgule et le cumul actuel +1
                               \edef#2{% d�finir la macro #2 :
                                       #2% reprendre le contenu de #2
                                       \ifx#2\empty\else,\fi% ajouter "," si #2 non vide
                                       \number\numexpr\cumul@length+1\relax% et le cumul
                                       }%
               \repeat% et recommencer
               \expsecond{% avant de fermer le groupe
       \endgroup
       \def#2}{#2}% d�finit #2 hors du groupe
}
\catcode`\@12
a) \hyphlengths{programmation}\foo liste = "\foo"\par
b) \hyphlengths{typographie}\foo liste ="\foo"\par
c) \hyphlengths{j'entendrai}\foo liste ="\foo"\par
d) \hyphlengths{vite}\foo liste ="\foo"
****************** Fin code ******************


****************** Code 431 ******************
\catcode`\@11
\newcount\brktt@cnt
\newdimen\brktt@interletter
\newif\ifline@start% bool�en vrai lorsqu'aucun caract�re n'est encore affich�
\newif\if@indivifound% bool�en qui sera vrai si un motif sp�cial est rencontr�

\let\breakttB=\breakttA

\def\breakttA@i{%
       \edef\remaining@chars{% calculer le nombre de caract�res restant � placer sur la ligne
               \numexpr\maxchar@num-\brktt@cnt\relax}%
       \len@tonextword% calculer dans \next@len le nombre de caract�res avant le prochain mot
       \def\next@hyphlen{0}% initialiser la longueur de coupure possible du mot
       % si le mot + l'eventuel "-" qui le suit ne rentre pas sur ce qui reste de la ligne
       \ifnum\numexpr\next@len+\extra@char\relax>\remaining@chars\relax
               \hyphlengths\next@word\list@hyphlengths% b�tir la liste des longueurs de coupures
               \unless\ifx\list@hyphlengths\empty% si une coupure est possible
                       \expsecond{\doforeach\xx\in}{\list@hyphlengths}% les examiner toutes
                               {% si la coupure examin�e peut loger sur la ligne
                               \unless\ifnum\xx>\remaining@chars\relax%
                                       \let\next@hyphlen\xx% la stocker
                               \fi% pour que \next@hyphlen soit maximal
                               }%
               \fi
       \fi
       \ifnum\next@hyphlen>0 % si une coupure est n�cessaire et a �t� trouv�e
               \let\next@len\next@hyphlen% mettre � jour la longueur du mot � placer
       \fi
       % si le mot + l'eventuel "-" qui le suit ne peut pas loger sur la ligne en cours
       \ifnum\numexpr\next@len+\extra@char\relax>\remaining@chars\relax
               \ifline@start% si c'est le d�but d'une ligne
                       % avertir l'utilisateur
                       \message{Largeur de composition trop faible pour
                                \unexpanded\expandafter{\next@word}^^J}%
                       % et composer tout de m�me jusqu'� la fin de la ligne
                       \exparg\print@nchar{\number\numexpr\maxchar@num-\brktt@cnt}%
               \else% sinon
                       \insert@blankchar*{\maxchar@num-\brktt@cnt}% remplir la ligne
               \fi
               \exparg\restart@hbox{\tt@remaintext}% r�-ouvrir une boite
               \expandafter\breakttA@i% et poursuivre le processus
       % s'il y a la place pour accueillir ce qui est avant la prochaine coupure
       \else
               \ifnum\next@hyphlen>0 % si une coupure de mot doit �tre faite
                       \exparg\print@nchar{\number\numexpr\next@len-1}% afficher les lettres de la syllabe
                       \print@hyphchar% et le caract�re de coupure
                       \insert@blankchar*{\maxchar@num-\brktt@cnt}% remplir la ligne
                       \exparg\restart@hbox{\tt@remaintext}% r�-ouvrir une boite
                       \expandafter\expandafter\expandafter\breakttA@i% et continuer le processus
               \else% si pas de coupure dans le mot
                       \print@nchar\next@len% afficher le mot
                       \ifx\tt@remaintext\tt@emptytext% si texte restant est vide
                               \insert@blankchar*{\maxchar@num-\brktt@cnt}% remplir la ligne
                               \egroup% fermer la hbox
                               \par% aller � la ligne
                               \endgroup% fermer le groupe ouvert au d�but. Fin du processus
                       \else% si le texte restant n'est pas vide
                               \ifnum\brktt@cnt<\maxchar@num\relax% si la ligne n'est pas remplie
                                               \print@nchar{1}% afficher le caract�re qui suit le mot
                               \else% si la ligne est remplie
                                       \exparg\restart@hbox{\tt@remaintext}% ferme la hbox et en r�-ouvre une
                               \fi
                               \expandafter\expandafter\expandafter\breakttA@i% enfin, continuer le processus
                       \fi
               \fi
       \fi
}

\def\print@hyphchar{%
       \advance\brktt@cnt by 1 % augmenter le compteur de caract�res
       \hbox to\ttchar@width{\hss-\hss}% afficher "-"
       \ifnum\brktt@cnt<\maxchar@num\relax% si la ligne n'est pas encore remplie
               \kern\brktt@interletter\relax% ins�rer le ressort inter-lettre
       \fi
}

\catcode`\@12

\def\liglist{<<,>>}% liste des motifs de ligature (mettre �, �, etc si codage UTF8)
\def\ttindent{3}

\vrule\vbox{\breakttB[3pt][8cm]{%
Dans ce paragraphe, compos� en fonte � chasse fixe et o� les limites gauche
et droite du texte ont �t� trac�es, on constate que les caract�res sont
exactement les uns au-dessous d'une ligne � l'autre. Plus aucun d�bordement
n'a lieu, car une espace correctement calcul�e est ins�r�e entre chaque
caract�re. Dor�navant, les mots ne sont plus coup�s <<sauvagement>>.
}%
}\vrule

\vrule\vbox{\breakttB[1pt][5cm]{%
Dans ce paragraphe, compos� en fonte � chasse fixe et o� les limites gauche
et droite du texte ont �t� trac�es, on constate que les caract�res sont
exactement les uns au-dessous d'une ligne � l'autre. Plus aucun d�bordement
n'a lieu, car une espace correctement calcul�e est ins�r�e entre chaque
caract�re. Dor�navant, les mots ne sont plus coup�s <<sauvagement>>.
}%
}\vrule
****************** Fin code ******************


****************** Code 432 ******************
Voici un algorithme �l�mentaire :
\algorithm[\#]{Algorithme {\bf MinMax}}|
macro ~Min_Max~ (#1) % afficher la valeur max et min d'une liste de valeurs #1
       $V_{max}:=-\infty$ % $-\infty$ ou la plus petite valeur possible
       $V_{min}:=+\infty$ % $+\infty$ ou la plus grande valeur possible
       ~Pour~ chaque $x$ dans (#1)
               ~Si~ $x>V_{max}$
                       ~alors~ $V_{max}:=x$
               ~FinSi~
               ~Si~ $x<V_{min}$
                       ~alors~ $V_{min}:=x$
               ~FinSi~
       ~FinPour~
       Afficher "$V_{min}$ et $V_{max}$"
~FinMin_Max~|
Suite du texte...
****************** Fin code ******************


****************** Code 433 ******************
\def\algoindent{1cm}%
\begingroup
\parindent=0pt % pas d'indentation
\defactive\^^M{\leavevmode\par}% rend le retour charriot actif
\defactive\^^I{\hskip\algoindent\relax}% tabulation active
Pas d'indentation ici\ldots
       Voici une premi�re ligne
               une seconde plus indent�e
       retour � l'indentation normale
               \for\xx=1to10\do{un long texte }
       pour terminer, la derni�re ligne
\endgroup
****************** Fin code ******************


****************** Code 434 ******************
\def\algoindent{1cm}%
\begingroup
\leftskip=0pt \rightskip=0pt plus1fil \relax % initialise les ressorts lat�raux
\parindent=0pt % pas d'indentation
\defactive\^^M{\leavevmode\par\leftskip=0pt }% rend le retour charriot actif
\defactive\^^I{\advance\leftskip by \algoindent\relax}% tabulation active
Pas d'indentation ici\ldots
       Voici une premi�re ligne
               une seconde plus indent�e
       retour � l'indentation normale
               \for\xx=1to10\do{un long texte }
       pour terminer, la derni�re ligne
\endgroup
****************** Fin code ******************


****************** Code 435 ******************
% compteur de lignes pour l'algorithme
\def\algoindent{1cm}%
\begingroup
\algocnt=1 % initialise le compteur � 1
\leftskip=0pt \rightskip=0pt plus1fil\relax% initialise les ressorts � 0pt
\parindent=0pt % pas d'indentation
\everypar={\llap{$\scriptstyle\number\algocnt$\kern\dimexpr4pt+\leftskip\relax}}%

\defactive\^^M{\leavevmode\par\advance\algocnt by1 \leftskip=0pt }% retour charriot actif
\defactive\^^I{\advance\leftskip by \algoindent\relax}% tabulation active
Pas d'indentation ici\ldots
       Voici une premi�re ligne
               une seconde plus indent�e
       retour � l'indentation normale
               \for\xx=1to10\do{un long texte }
       pour terminer, la derni�re ligne
\endgroup
****************** Fin code ******************


****************** Code 436 ******************
\newif\ifnumalgo
\newcount\algocnt
\numalgotrue

\def\algoindent{2em}
\def\algorule{.4pt}% �paisseur des r�glures de d�but et de fin

\def\algohrulefill{% remplit avec une ligne horizontale
       \leavevmode
       \leaders\hrule height\algorule\hfill
       \kern0pt % rajoute un noeud au cas o� la commande est en fin de ligne
}

\newmacro\algorithm[\\,\#,\{,\}]2{%
       \medbreak
       \begingroup% ouvre un groupe (sera ferm� � la fin de l'algorithme)
               \algocnt=1 % initialise le compteur de lignes
               \leftskip=0pt \rightskip=0pt plus1fil\relax% initialise les ressorts lat�raux
               \parindent=0pt % pas d'indentation
               %%%%%%%%%%%% affichage du titre %%%%%%%
               \algohrulefill% remplir avec une ligne horizontale
               \ifempty{#2}% si #2 est vide
                       {}% ne rien ins�rer
                       {% sinon
                       \lower.5ex\hbox{ #2 }% ins�rer le titre abaiss� de 0.5ex
                       \algohrulefill% ins�rer une ligne horizontale
                       }%
               \par% aller � la ligne
               \nointerlineskip% ne pas ins�rer le ressort d'interligne
               \kern7pt % et sauter 7pt verticalement
               \nobreak% emp�cher une coupure de page
               %%%%%%%%%%%%%% fin du titre %%%%%%%%%%
               %
               %%%%%%%%%%%%%% rend les caract�res actifs %%%%%%%%%%%%%%
               \def~##1~{\begingroup\bf##1\endgroup}%
               \defactive:{% rend ":" actif
                       \futurelet\nxttok\algoassign% \nxttok = token suivant
               }%
               \def\algoassign{% suite du code de ":"
                       \ifx=\nxttok% si ":" est suivi de "="
                               \ifmmode% si mode math
                                       \leftarrow% afficher "\leftarrow"
                               \else% si mode texte
                                       ${}\leftarrow{}$% passer en mode math pour "\leftarrow"
                               \fi
                               \expandafter\gobone% manger le signe "="
                       \else% si ":" n'est pas suivi de "="'
                               \string:% afficher ":"
                       \fi
               }%
               \ifnumalgo% si la num�rotation est demand�e,
                       \everypar={% d�finir le \everypar
                               \llap{$\scriptstyle\number\algocnt$\kern\dimexpr4pt+\leftskip\relax}%
                       }%
               \fi
               \doforeach\currentchar\in{#1}{\catcode\expandafter`\currentchar=12 }%
               \def\algocr{% d�finit ce que fait ^^M
                       \color{black}% repasse en couleur noire
                       \rm% fonte droite
                       \leavevmode\par% termine le paragraphe
                       \advance\algocnt by1 % incr�mente le compteur de lignes
                       \leftskip=0pt % initialise le ressort gauche
               }
               \letactive\^^M=\algocr%
               \defactive\^^I{\advance\leftskip by \algoindent\relax}%
               \defactive\ {\hskip1.25\fontdimen2\font\relax}% espace = 25% de + que
                                                             % la largeur naturelle
               \defactive\%{\it\color{gray}\char`\%}% passe en italique et gris puis affiche "%"
               \defactive_{\ifmmode_\else\string_\fi}%
               \defactive#3{% rend le token #3 actif (il sera rencontr� � la fin de l'algorithme)
                       \everypar{}% neutralise le \everypar
                       \par% aller � la ligne
                       \nointerlineskip% ne pas ins�rer le ressort d'interligne
                       \kern7pt % et sauter 7pt verticalement
                       \nobreak% emp�cher une coupure de page
                       \algohrulefill% tracer la ligne de fin
       \endgroup% ferme le groupe ouvert au d�but de l'algorithme
       \smallbreak% saute un petit espace vertical
               }%
       %%%%%%%%%%%%%%%%% fin des caract�res actifs %%%%%%%%%%%%%%%%
       \sanitizealgo% va manger les espaces et les ^^M au d�but de l'algo
}

\def\sanitizealgo{\futurelet\nxttok\checkfirsttok}% r�cup�re le prochain token

\def\checkfirsttok{% teste le prochaun token
       \def\nextaction{% a priori, on consid�re que la suite est " " ou "^^M" donc
               \afterassignment\sanitizealgo% aller � \sanitizealgo
               \let\nexttok= % apr�s avoir mang� ce "^^M" ou cet espace
       }%
       \unless\ifx\nxttok\algocr% si le prochain token n'est pas un ^^M
               \unless\ifx\space\nxttok% et si le prochain token n'est pas un espace
                       \let\nextaction\relax% ne rien faire ensuite
               \fi
       \fi
       \nextaction% faire l'action d�cid�e ci-dessus
}

Voici un algorithme �l�mentaire
\algorithm[\#]{Algorithme {\bf MinMax}}|
macro ~Min_Max~ (#1) % afficher la valeur max et min d'une liste de valeurs #1
W$V_{max}:=-\infty$ % $-\infty$ ou la plus petite valeur possible
W$V_{min}:=+\infty$ % $+\infty$ ou la plus grande valeur possible
W~Pour~ chaque $x$ dans (#1)
WW~Si~ $x>V_{max}$
WWW~alors~ $V_{max}:=x$
WW~FinSi~
WW~Si~ $x<V_{min}$
WWW~alors~ $V_{min}:=x$
WW~FinSi~
W~FinPour~
WAfficher "$V_{min}$ et $V_{max}$"
~FinMin_Max~|
Suite du texte...
****************** Fin code ******************


****************** Code 437 ******************
a) \meaning a\par
b) \meaning {\par
c) \meaning _\par
d) \meaning\def\par % une primitive
e) \meaning\baselineskip\par% une primitive
f) \long\def\foo#1#2.#3{#1 puis #2 et #3 !}\meaning\foo
****************** Fin code ******************


****************** Code 438 ******************
\def\foo#1#2{%
       \def\argA{#1}\show\argA% d�bogage
       Bonjour #1 et #2}
\foo{{\bf X}}{Y}
****************** Fin code ******************


****************** Code 439 ******************
\def\foo#1#2{%
       \showtokens{#1}% d�bogage
       Bonjour #1 et #2}
\foo{{\bf X}}{Y}
****************** Fin code ******************


****************** Code 440 ******************
\newtoks\footoks
\footoks={foo bar}
\show\footoks
****************** Fin code ******************


****************** Code 441 ******************
\showthe\baselineskip% registre-primitive
\newtoks\footoks \footoks={foo bar} \showthe\footoks
\newcount\foocount \foocount=987 \showthe\foocount
\newdimen\foodimen \foodimen=3.14pt \showthe\foodimen
\newskip\fooskip \fooskip=10 pt plus 1pt minus 1fil \showthe\fooskip
\newbox\foobox \foobox\hbox{foo} \showthe\foobox
****************** Fin code ******************


****************** Code 442 ******************
\def\foo#1,#2\endfoo{Bonjour #1 et #2}
\tracingmacros=1
\foo moi,toi\endfoo
\tracingmacros=0
****************** Fin code ******************


****************** Code 443 ******************
\tracingcommands=2
Foo \hbox{et \ifnum2>1 bar\else toi\fi}\par
Suite
\tracingcommands=0
****************** Fin code ******************


****************** Code 444 ******************
\def\i{\advance\count255 1 }
\tracingrestores=1
\count255=2 {\i\i\i}
\tracingrestores=0
****************** Fin code ******************


****************** Code 445 ******************
\def\i{\advance\count255 1 } \def\gi{\global\i}
\tracingrestores=1
\count255=2 {\i\i\gi\i\gi\i}
\tracingrestores=0
****************** Fin code ******************


****************** Code 446 ******************
\catcode`@11
\def\ifnodecpart#1{\ifnodecpart@i#1.\@nil}
\def\ifnodecpart@i#1.#2\@nil{\ifempty{#2}}
\def\decadd#1#2{% #1 et #2=nombre � additionner
       \ifnodecpart{#1}% si #1 est un entier
               {\ifnodecpart{#2}% et #2 aussi, les additionner avec \numexpr
                       {\number\numexpr#1+#2\relax}%
                       {\decadd@i#1.0\@nil#2\@nil}% sinon, ajouter ".0" apr�s #1
               }
               {\ifnodecpart{#2}% si #1 a une partie enti�re mais pas #2
                       {\decadd@i#1\@nil#2.0\@nil}% ajouter ".0" � #2
                       {\decadd@i#1\@nil#2\@nil}% sinon, les 2 parties enti�res sont pr�sentes
               }%
}
\def\decadd@i#1.#2\@nil#3.#4\@nil{% affiche les parties enti�res et d�cimales re�ues
       $x_a=#1\quad y_a=#2\qquad x_b=#3\quad y_b=#4$
}
\catcode`@12
a) \decadd{5}{9.4}\par
b) \decadd{-3.198}{-6.02}\par
c) \decadd{0.123}{123}
****************** Fin code ******************


****************** Code 447 ******************
\def\addzeros#1#2/#3.#4#5/#6.#7/{%
       Arguments re�us : #1#2/#3.#4#5/#6.#7/\par% afficher ce que la macro re�oit
       \ifempty{#2}% si #1 est le dernier chiffre de y
               {\ifempty{#5}% et si #4 est le dernier chiffre de y2
                       {R�sultat final : \detokenize{{#3#1}{#6#4}{#70}}}% afficher le r�sultat final
                       {\addzeros0/#3#1.#5/#6#4.#70/}% sinon alimenter #1 avec un 0
               }
               {\ifempty{#5}% si #4 est le dernier chiffre de y2
                       {\addzeros#2/#3#1.0/#6#4.#70/}% alimenter #4 avec un 0
                       {\addzeros#2/#3#1.#5/#6#4.#70/}% #2 et #5 non vides
               }%
}
\addzeros457/.689714/.1/
****************** Fin code ******************


****************** Code 448 ******************
\catcode`\@11
\def\addzeros#1#2/#3.#4#5/#6.#7/{%
       \ifempty{#2}% si #1 est le dernier chiffre de y1
               {\ifempty{#5}% et si #4 est le dernier chiffre de y2
                       {{#3#1}{#6#4}{#70}}% redonner les 3 arguments
                       {\addzeros0/#3#1.#5/#6#4.#70/}% sinon alimenter #1 avec un 0
               }
               {\ifempty{#5}% si #4 est le dernier chiffre de y2
                       {\addzeros#2/#3#1.0/#6#4.#70/}% alimenter #4 avec un 0
                       {\addzeros#2/#3#1.#5/#6#4.#70/}% #2 et #5 non vides
               }%
}
\def\decadd#1#2{% #1 et #2=nombre � additionner
       \ifnodecpart{#1}
               {\ifnodecpart{#2}{\number\numexpr#1+#2\relax}{\decadd@i#1.0\@nil#2\@nil}}
               {\ifnodecpart{#2}{\decadd@i#1\@nil#2.0\@nil}{\decadd@i#1\@nil#2\@nil}}%
}
\def\decadd@i#1.#2\@nil#3.#4\@nil{%
       \expandafter\decadd@ii
                       \romannumeral-`\0\addzeros#2/.#4/.1/% se d�veloppe en 3 arguments
                       {#1}
                       {#3}%
}
\def\decadd@ii#1#2#3#4#5{%
% #1 et #2=parties d�cimales (m�mes longueurs);
% #3=seuil de retenue; #4 et #5=parties enti�res
       \exptwoargs{\decadd@iii{#3}}% envoyer le seuil de retenue tel quel
               % sommer les parties d�cimales sign�es
               {\number\numexpr\true@sgn{#4}#1+\true@sgn{#5}#2\relax}%
               % et les parties enti�res
               {\number\numexpr#4+#5\relax}%
}
\def\decadd@iii#1#2#3{%
       seuil de retenue = #1 \qquad nombre = "#3"."#2"%
}
\catcode`\@12
a) \decadd{6.7}{3.498}\par
b) \decadd{1.67}{-4.9}\par
c) \decadd{3.95}{2.0005}\par
d) \decadd{1.007}{2.008}\par
e) \decadd{-7.123}{3.523}
****************** Fin code ******************


****************** Code 449 ******************
\catcode`\@11
\def\format@dec#1#2{% #1=partie d�cimale #2=seuil de retenue
       \expandafter\gobone% le \gobone agira en dernier,
               \romannumeral-`\0% mais avant, tout d�velopper
               \expandafter\reverse\expandafter% et retarder le \reverse de fin
                       % pour d�velopper son argument qui
                       {\number% d�veloppe tout et �value avec \number
                               \expandafter\reverse\expandafter% l'inversion de
                               {\number\numexpr\abs{#1}+#2\relax}% |#1|+#2
                       }%
}
a) \format@dec{710}{100000}\par
b) \format@dec{6}{100}\par
c) \format@dec{-12300}{1000000}
\catcode`\@12
****************** Fin code ******************


****************** Code 450 ******************
\catcode`@11
\def\true@sgn#1{\ifnum#11<\z@-\fi}
\def\decadd#1#2{% #1 et #2=nombre � additionner
       \romannumeral-`\.% tout d�velopper jusqu'� l'affichage du nombre (\decadd@iv)
       \ifnodecpart{#1}% si #1 est un entier
               {\ifnodecpart{#2}% et #2 aussi, les additionner avec \numexpr
                       {\numexpr#1+#2\relax}%
                       {\decadd@i#1.0\@nil#2\@nil}% sinon, ajouter ".0" apr�s #1
               }
               {\ifnodecpart{#2}% si #1 a une partie enti�re mais pas #2
                       {\decadd@i#1\@nil#2.0\@nil}% ajouter ".0" � #2
                       {\decadd@i#1\@nil#2\@nil}% sinon, les 2 parties enti�res sont pr�sentes
               }%
}
\def\decadd@i#1.#2\@nil#3.#4\@nil{%
       \expandafter\decadd@ii
                       \romannumeral-`\0\addzeros#2/.#4/.10/% se d�veloppe en 3 arguments
                       {#1}
                       {#3}%
}
\def\decadd@ii#1#2#3#4#5{%
% #1 et #2=parties d�cimales (m�mes longueurs)
% #3=seuil de retenue; #4 et #5=parties enti�res
       \exptwoargs{\decadd@iii{#3}}% envoyer le seuil de retenue tel quel
               % sommer les parties d�cimales sign�es
               {\number\numexpr\true@sgn{#4}#1+\true@sgn{#5}#2\relax}%
               % et les parties enti�res
               {\number\numexpr#4+#5\relax}%
}
\def\decadd@iii#1#2#3{% #1=seuil de retenue #2=partie d�cimale #3= partie enti�re
       \ifnum\true@sgn{#2}\true@sgn{\ifnum#3=\z@#2\else#3\fi}1=-1 % si les signes sont
                                                                  % diff�rents
       \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
               {\exptwoargs\decadd@iv% transmettre les arguments modifi�s :
                       {\number\numexpr#3-\true@sgn{#3}1}% #3:=#3-sgn(#3)1
                       {\number\numexpr#2-\true@sgn{#2}#1}% #2:=#2-sgn(#2)10^n
                       {#1}%
               }% si les signes sont �gaux
               {\ifnum\abs{#2}<#1 % et si abs(y)<10^n
               \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                       {\decadd@iv{#3}{#2}{#1}% tranmettre les arguments tels quels
                       }
                       {\exptwoargs\decadd@iv% sinon
                               {\number\numexpr#3+\true@sgn{#3}1}% #3:=#3+sgn(#3)1
                               {\number\numexpr#2-\true@sgn{#2}#1}% #2:=#2-sgn(#2)10^n
                               {#1}%
                       }%
               }%
}
\def\decadd@iv#1#2#3{% affiche le d�cimal "#1.#2"
       % le d�veloppement maximal initi� par le \romannumeral de \decadd est actif
       \ifnum#1=\z@\ifnum#2<\z@% si #1=0 et #2<0
               \expandafter\expandafter\expandafter% transmettre le d�veloppement � \number
               -% puis afficher le signe "-"
       \fi\fi
       \number#1% affiche #1 qui est la somme des parties enti�res
       % poursuivre le d�veloppement initi� par \number
       \unless\ifnum#2=\z@% si la partie d�cimale est diff�rente de 0
               \antefi% se d�barrasser de \fi
               \expandafter.% afficher le "." d�cimal apr�s avoir
               \romannumeral-`\0\format@dec{#2}{#3}% correctement g�r� les 0 de #2
       \fi
}
\def\addzeros#1#2/#3.#4#5/#6.#7/{%
       \ifempty{#2}% si #1 est le dernier chiffre de y1
               {\ifempty{#5}% et si #4 est le dernier chiffre de y2
                       {{#3#1}{#6#4}{#7}}% redonner les 3 arguments
                       {\addzeros0/#3#1.#5/#6#4.#70/}% sinon alimenter #1 avec un 0
               }
               {\ifempty{#5}% si #4 est le dernier chiffre de y2
                       {\addzeros#2/#3#1.0/#6#4.#70/}% alimenter #4 avec un 0
                       {\addzeros#2/#3#1.#5/#6#4.#70/}% #2 et #5 non vides
               }%
}
\def\format@dec#1#2{% #1=partie d�cimale #2=seuil de retenue
       \expandafter\gobone% le \gobone agira en dernier,
               \romannumeral-`\0% mais avant, tout d�velopper
               \expandafter\reverse\expandafter% et retarder le \reverse de fin
                       % pour d�velopper son argument qui
                       {\number% d�veloppe tout et �value avec \number
                               \expandafter\reverse\expandafter% l'inversion de
                               {\number\numexpr\abs{#1}+#2\relax}% abs(#1)+#2
                       }%
}
\catcode`@12
a) $-3.78+1.6987=\decadd{-3.78}{1.6987}$\par
b) $3.56-3.06=\decadd{3.56}{-3.06}$\par
c) $4.125+13.49=\decadd{4.125}{13.49}$\par
d) $-0.99+1.005=\decadd{-0.99}{1.005}$\par
e) $16.6-19.879=\decadd{16.6}{-19.879}$\par
f) $5.789-0.698=\decadd{5.789}{-0.698}$\par
g) $0.123-0.123=\decadd{0.123}{-0.123}$\par
h) $3.14-16.4912=\decadd{3.14}{-16.4912}$\par
i) $0.1-0.98=\decadd{0.1}{-0.98}$\par
j) $2.43+7.57=\decadd{2.43}{7.57}$\par
h) \edef\foo{\decadd{1.23}{9.78}}\meaning\foo\par
j) \detokenize\expandafter\expandafter\expandafter{\decadd{3.14}{-8.544}}
****************** Fin code ******************


****************** Code 451 ******************
a) \pdfstrcmp{foo}{bar}\qquad
b) \pdfstrcmp{bar}{foo}\qquad
c) \def\foo{ABC}\pdfstrcmp{\foo}{ABC}\qquad
d) \edef\foo{\string_}\pdfstrcmp{1_2}{1\foo2}\qquad
e) \pdfstrcmp{\string\relax}{\relax}
****************** Fin code ******************


****************** Code 452 ******************
\edef\tempcompil{\number\pdfelapsedtime}%
Depuis le d�but de la compilation, il s'est �coul� \tempcompil{} secondes d'�chelle,
soit \convertunit{\tempcompil sp}{pt} secondes.
****************** Fin code ******************


****************** Code 453 ******************
%%%%%%%%%% definition de \loop...\repeat comme plain-TeX %%%%%%%%%%
\def\loop#1\repeat{\def\body{#1}\iterate}
\def\iterate{\body \let\next\iterate \else\let\next\relax\fi \next}
\let\repeat=\fi
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcount\testcnt
\pdfresettimer% remet le compteur � 0
       \testcnt=0
       \loop % Test no 1
               \ifnum\testcnt<100000 \advance\testcnt 1
       \repeat
Temps 1 = \convertunit{\pdfelapsedtime sp}{pt} s (boucle loop de \TeX)\par
%%%%%%%%%%%% definition de \loop...\repeat comme LaTeX %%%%%%%%%%%%
\def\loop#1\repeat{\def\iterate{#1\relax\expandafter\iterate\fi}%
 \iterate \let\iterate\relax}
\let\repeat\fi
\pdfresettimer% remet le compteur � 0
       \testcnt=0
       \loop % Test no 2
               \ifnum\testcnt<100000
               \advance\testcnt 1
       \repeat
Temps 2 = \convertunit{\pdfelapsedtime sp}{pt} s (boucle loop de \LaTeX)\par
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pdfresettimer% remet le compteur � 0
       \for\ii=1 to 100000\do{}% Test no 3
Temps 3 = \convertunit{\pdfelapsedtime sp}{pt} s (boucle for)
****************** Fin code ******************


****************** Code 454 ******************
%%%%%%%%%%%% definition de \loop...\repeat comme LaTeX %%%%%%%%%%%%
\def\loop#1\repeat{\def\iterate{#1\relax\expandafter\iterate\fi}%
 \iterate \let\iterate\relax}
\let\repeat\fi
\pdfresettimer% remet le compteur � 0
       \def\ii{0}%
       \loop % Test no 1
               \ifnum\ii<100000
               \edef\ii{\number\numexpr\ii+1\relax}%
       \repeat
Temps 1 = \convertunit{\pdfelapsedtime sp}{pt} s (boucle loop de \LaTeX)\par
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pdfresettimer% remet le compteur � 0
       \for\ii=1 to 100000\do{}% Test no 2
Temps 2 = \convertunit{\pdfelapsedtime sp}{pt} s (boucle for)
****************** Fin code ******************


****************** Code 455 ******************
\newcount\testcnt
\pdfresettimer
\testcnt=0
\for\ii=1 to 100000\do{\advance\testcnt1 }
Temps 1 : \convertunit{\pdfelapsedtime sp}{pt} s (incr�mentation compteur)

\pdfresettimer
\def\foo{0}%
\for\ii=1 to 100000\do{\edef\foo{\number\numexpr\foo+1\relax}}%
Temps 2 : \convertunit{\pdfelapsedtime sp}{pt} s (incr�mentation du texte de remplacement)
****************** Fin code ******************