%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                                                                          %%
%%                        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 ******************