%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                                                                          %%
%%                        Codes donns dans le livre                        %%
%%                     Apprendre  programmer en TeX                      %%
%%                                                                          %%
%%                           Encodage ISO 8859-1                            %%
%%                                   _____                                  %%
%%                                                                          %%
%%                      2014-2020 Christian Tellechea                      %%
%%                                                                          %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Les codes et les macros comments donns dans ce fichier sont diffuss 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 mathmatique (espaces ignors)
1^{2^3}% 2 est en taille "\scriptstyle" et 3 en taille "\scriptscriptstyle"
$% fin du mode math

normal $1$, petit $\scriptstyle 2$, trs petit $\scriptscriptstyle 3$.
****************** Fin code ******************


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

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

Ligne 3\endlinechar13

\medbreak
c) "X" comme caractre de fin de ligne :
%%% "X" est insr  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 caractre de "a"
b) \number`\\ \quad % code de caractre de "\"
c) \number`\$ \quad % code de caractre de "$"
d) \number`\  \quad % code de caractre de l'espace
e) \number`\5 \quad % code de caractre de "5"
f) \number`\{ \quad % code de caractre de l'accolade ouvrante
g) \number`\}       % code de caractre de accolade fermante
****************** Fin code ******************


****************** Code 7 ******************
a) \number\catcode`\a \quad %code de catgorie de "a"
b) \number\catcode`\\ \quad % code de catgorie de "\"
c) \number\catcode`\$ \quad % code de catgorie de "$"
d) \number\catcode`\  \quad % code de catgorie de l'espace
e) \number\catcode`\5 \quad % code de catgorie de "5"
f) \number\catcode`\{ \quad % code de catgorie de l'accolade ouvrante
g) \number\catcode`\}       % code de catgorie 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 caractre affichable
$ s'affiche sans problme : $\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 dormais de catcode 5
Cette premire ligne sera tronque...

La deuxime aussi !

Et la dernire galement.
\catcode`\ =10 % l'espace reprend son catcode

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


****************** Code 11 ******************
\def\foo{Bonjour}% dfinit 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 dfinir 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 redfinie
\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}% redfinition
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 ******************
{% dbut 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 constitus 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 trs espacs\<\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,balanant 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,balanant 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 "copie" vers \bar
c) \def\baz{\foo}\meaning\baz\par
d) \catcode`\W=13 \def W{Wagons}% W est un caractre 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 conscutifs : \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 (caractre "autre")
l) \meaning ~\par% catcode 13 (caractre 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 caractre d'chappement
*def*foo{bar}
*LaTeX{} et la macro *string*foo : *foo.

L'ancien caractre d'chappement  "\" et \TeX.
*endgroup
****************** Fin code ******************


****************** Code 30 ******************
\def\foo{\bar}
\begingroup
a) \escapechar=-1  \meaning\foo\qquad% pas de caractre d'chappement
b) \escapechar=`\@ \meaning\foo\qquad% "@" est le caractre d'chappement
\endgroup
c) \meaning\foo% caractre d'chappement par dfaut
****************** 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}% dfinition
\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 aprs que la macro est termine)
****************** 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. Aprs s'tre
             bien amus\?{}, nous avons rang\?{} et il a fallu rentr\?{er}.}
Complter 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\?{}  got\?{er} chez Max. On s'est
             bien amus\?{} et ensuite, il a fallu rentr\?{er}.}
Complter 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 prcise 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}}% dfinit une commande \foo
\foo % la commande dfinie prcdemment
****************** 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}% dfinit le caractre 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 aprs 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 aprs 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 aprs 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 aprs 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 frontire 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 spciaux
		\defactive\^^M{\leavevmode\par}% dfinit le retour charriot
		\letactive#1\endgroup% dfinit #1 qui sera un \endgroup
		\tt% passe en fonte  chasse fixe
}
essai 1 : \litterate*\foo # #34{ } &_\ *
\medbreak
essai 2 : \litterate/une premire ligne  ,, >>

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


****************** Code 52 ******************
\def\litterate#1{% #1=lit le token frontire 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 spciaux
		\defactive\^^M{\leavevmode\par}% dfinit le retour charriot
		\defactive\ {\ }% l'espace est actif et devient "\ "
		\defactive<{\string<{}}\defactive>{\string>{}}% empche
		\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 premire      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}% dfinit 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}% dfinit 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}% dfinit 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}% dfinit 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}% dfinit 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 aprs #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}% dfinit 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
Rsultat : \firstto@nil\foo\@nil
\catcode`@=12
****************** Fin code ******************


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


****************** Code 68 ******************
\newtoks\testtoks \testtoks={Bonjour}
\catcode`@=11
Rsultat : \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}% dfinition rcursive
\foo% l'excution provoque un dpassement 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-dveloppement d'un \litterate-\noexpand- :
   \expandafter\meaning\noexpand\foo

b) excution d'un \litterate-\noexpand- : \noexpand\foo% identique  \relax

c) 1-dveloppement 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) excution : \foo\par
c) \edef\foo{\aa\noexpand{\aa\cc}}\meaning\foo\qquad d) excution : \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 protge !
\def\cc{ monde}

\edef\foo{\aa\bb\cc}
Signification de \string\foo~: \meaning\foo \par
Excution 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-dveloppe \bb
\meaning\foo
****************** Fin code ******************


****************** Code 90 ******************
\def\foo{Bonjour}% dfinition
\foo% excution
****************** 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
Excution : \bar
****************** Fin code ******************


****************** Code 93 ******************
\long\def\>#1<{\detokenize{#1}}
\expandafter\>% provoque le 1-dveloppement 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 % employe 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 dveloppement vide
d) "\romannumeral -2014 "\quad% ngatif donc dveloppement 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 dveloppement 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 dfinie : \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 dfinitions, 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% lve au carr (lmultiplie \foo par lui mme)
  \number\foo% enfin, afficher le rsultat
}
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) Excution : \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% rtablir 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 ngatif%
	\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 caractre est avant "a"
		#3% excuter "<code faux>"
	\else% sinon
		\ifnum`#1>`z% si le caractre est aprs "z"
			#3% excuter "<code faux>"
		\else% dans tous les autres cas
			#2% "#1" est une lettre : excuter "<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-dveloppe "\else...\fi"
	\else
		\ifnum`#1>`z
			\expandafter\expandafter\expandafter% 1-dveloppe "\else...\fi" puis "\fi"
			\secondoftwo
		\else
			\expandafter\expandafter\expandafter%1-dveloppe "\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 dveloppement 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 dveloppement 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% excuter l'action dcide 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 cre
			\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% rsultat -7 qui est affich 7
e) \absval{5-3*(-4)+10-50}% rsultat -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 diffrent de 0
		\uppercase\expandafter{\romannumeral\absval{#1}}% chiffres romains majuscules
		\raise 1ex \hbox{e\ifnum\absval{#1}=1 r\fi} sicle% affiche l'exposant puis "sicle"
		\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 dsormais un caractre 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 dlimits
}

\def\hdif@ii#1:#2:#3-#4:#5:#6\@nil{%
		%%%%%% calcul des nombres  afficher %%%%%%
		\edef\nb@hrs{\number\numexpr#1-#4\relax}% diffrence des heures
		\edef\nb@min{\number\numexpr#2-#5\relax}% diffrence des minutes
		\edef\nb@sec{\number\numexpr#3-#6\relax}% diffrence des secondes
		\ifnum\nb@sec<\z@ % si la diffrence 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 rsultat %%%%%%
		\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 dbut
}
\catcode`\:=\saved@catcode\relax% restaure le code de catgorie 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 caractre  afficher
    \ncar@i% appelle la macro rcursive
}
\def\ncar@i{%
  \ifnum\ii<\val@max% si la valeur maxi n'est pas atteinte
    \car@save% afficher le caractre
    \advance\ii 1 % incrmenter 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 caractre  afficher
    \ncar@i% appelle la macro rcursive
}
\def\ncar@i{%
  \ifnum\ii<\val@max% si la valeur maxi n'est pas atteinte
    \car@save% afficher le caractre
    \advance\ii 1 % incrmenter 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 aprs le "0"
    #2% affiche le caractre
    \exparg\ncar{\number\numexpr#1-1}{#2}% appel rcursif
  \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 excuter...
	\else      \expandafter\gobone% ...sinon manger
	\fi% ce qui est entre ces accolades :
		{#2% afficher le caractre
		\exparg\ncar{\number\numexpr#1-1}{#2}% appel rcursif
		}%
}
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 "dplac" ici
		#2% affiche le caractre
		\exparg\ncar{\number\numexpr#1-1}{#2}% appel rcursif
	\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 aprs 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 caractre
    \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 caractre
		\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 % incrmenter 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 rcrusive
  \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 % incrmenter 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% excuter...
	\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 rcursif
		}%
}
\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% dplace le \fi ici
    , % affiche la virgule et l'espace
    \exparg\compte@i{\number\numexpr#1+1}{#2}% appel rcursif
  \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 rcursive 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 prcdemment sauvegard
		\edef#1{\number\numexpr#1+1}% incrmenter la \<macro>
		\expandafter\for@i\expandafter#1% et recommencer aprs 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  excuter
			\edef#1{\number\numexpr#1+1}% incrmenter \<macro>
			\expandafter\for@i% et recommencer aprs 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 rcursive
}
\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 redfinir :
			\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% excuter le 1er argument qui suit
	\else
		\expandafter\secondoftwo% sinon le second
	\fi
		{Incrment 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 rcursive
			{\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 dpass n2
			#3% excute le <code>
			\edef#1{\number\numexpr#1+\for@increment}% incrmente la \<macro>
			\expandafter\for@ii% recommence aprs avoir mang le \fi
		\fi
	}%
	\for@ii% appelle la sous-macro rcursive
}%
\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 redfinir  -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{% dfinit et dveloppe les arguments  passer  \for@i
			%#1=nom de la macro rcursive :
			\expandafter\noexpand\csname for@ii@\string#1\endcsname
			\ifnum\for@increment<\z@ <\else >\fi% #2=signe de comparaison
			{\for@increment}% #3=incrment
			\noexpand#1% #4=\<macro>
			{\number\numexpr#3\relax}% #5=entier n2
		}%
		\antefi% externalise la ligne ci-dessous de la porte du test
		\expandafter\for@i\macro@args% appelle \for@i avec les arguments dfinis ci-dessus
	\fi
}

% #1=nom de la macro rcursive de type "\for@ii@\<macro>"
% #2=signe de comparaison  % #3=incrment
% #4=\<macro>  % #5=entier n2  % #6=<code>  excuter
\long\def\for@i#1#2#3#4#5#6{%
	\def#1{% dfinit la sous macro rcursive
		\unless\ifnum#4#2#5\relax% tant que la \<macro> variable n'a pas dpass n2
			\afterfi{% rendre la rcursivit terminale
				#6% excute le code
				\edef#4{\number\numexpr#4+#3\relax}% incrmente la \<macro>
				#1% recommence
			}%
		\fi
	}%
	#1% appelle la sous-macro rcursive
}%
\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{% dfinit la sous macro rcursive
		\unless\ifnum#4#2#5\relax% tant que la variable n'a pas dpass l'entier max
			\afterfi{% rendre la rcursivit terminale
				#6% excute le code
				\edef#4{\number\numexpr#4+#3\relax}% incrmente la variable #1
				#1% recommence
			}%
		\fi
	}%
	#1% appelle la sous-macro rcursive
}%
\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 prmaturment sorti de la boucle de \<macro> #1
	% si la macro rcursive est gale  la macro "\empty"
	\expandafter\ifx\csname for@ii@\string#1\endcsname\empty
		\expandafter\firstoftwo% c'est qu'on est sortir prmaturment, renvoyer "vrai"
	\else
		\expandafter\secondoftwo% sinon, renvoyer "faux"
	\fi
}

% on ne sort QUE de la boucle intrieure quand \ii=3 donc
% les boucles sont normalement excutes 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 extrieure lorsque \ii=3 donc la boucle
% intrieure est faite entirement mme 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 intrieure lorsque \ii=3
% et aussi de la boucle extrieure  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 caractre 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 dclare \long
5) \meaning\sdlkfj\par% une macro indfinie
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 caractre "+" est gal  "+"
c) \ifx\relax\par vrai\else faux\fi\quad% \relax n'est pas la mme primitive que \par
d) \ifx\par\par vrai\else faux\fi\quad% \par et \par sont les mmes primitives
e) \ifx\sdfk\qlms vrai\else faux\fi\quad% 2 macros non dfinies sont gales
f) \def\foo{abcd}\def\bar{abc}% \foo et \bar ont des textes de remplacement diffrents
   \ifx\foo\bar vrai\else faux\fi\quad
g) \def\foo{abcd}\def\bar{abcd }% \foo et \bar ont des textes de remplacement diffrents
   \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 mmes 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}% dfinit 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 rservoirs et appeler \reverse@i
}
\def\reverse@i#1#2\@nil#3\@nil{% #1 est le 1er caractre du rservoir A
	\ifempty{#2}% si ce qui reste aprs ce 1er caractre est vide
		{#1#3}% renvoyer #1#3 qui est le rsultat final
		{\reverse@i#2\@nil#1#3\@nil}% sinon, recommencer en dplaant #1
		                            % en 1re position du rservoir 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{% dfinit la macro auxiliaire
		\ifempty{##2}% si ce qu'il y a derrire 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% excuter 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 aprs le motif
		\ifempty{##2}% si ##2 est vide
			\firstoftwo% excuter 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, excuter l'argument "faux"
			}%
	}%
	\ifend@i#2#1\@nil% appelle la macro rcursive
}
\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 aprs le motif
		\ifempty{##2}% si ##2 est vide
			\firstoftwo% excuter 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, excuter l'argument "faux"
			}%
	}%
	\ifempty{#2}% si le motif est vide
		\firstoftwo% excuter "vrai"
		{\ifend@i#2\relax#1\@nil}% sinon, appelle la macro rcursive
}
\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 dlimits
				{##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 dlimits
				{\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% excute 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 dlimits
				{\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 rsultat
	\long\def\cnttimestocs@i##1\@nil##2#2##3\@nil{%
		% ##1=nb d'occurrences rencontres jusqu'alors
		% ##2 et ##3=ce qui est avant/aprs le <motif>
		\ifin{##3}{#2}% si le <motif> est dans ce qui reste
			{\expandafter\cnttimestocs@i% appeler la macro rcursive
				\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 rcursive 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 rcursive 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-dveloppe
		{\subst@code}{#1}{#2}% le <code> et effectue la substitution en cours
	\ifempty{#3}% si la liste des motifs est vide
		\subst@code% excuter 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 rcursive avec 
	                           % 2 arguments spciaux 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 spcial est atteint
		\expandafter\subst@code% excuter le code obtenu
	\else
		\expandafter\substtocs\expandafter\subst@code\expandafter% 1-dveloppe
			{\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}% dfinit les caractres 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 mme catcode
5) \ifcat _^vrai\else faux\fi\qquad% "_" et "^" n'ont pas le mme 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 mmes 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 caractre d'chappement
		\if% les premiers caractres 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 spcial
\edef\normalrelax{\relax}% texte de remplacement = \relax normal
\meaning\specialrelax\par
\meaning\normalrelax\par
Les 2 \string\relax{} sont \ifx\specialrelax\normalrelax identiques\else diffrents\fi.
****************** Fin code ******************


****************** Code 188 ******************
\edef\specialrelax{\ifnum1=1\fi}
\expandafter\def\specialrelax{foobar}% redfinition un \relax spcial
****************** Fin code ******************


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

\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% excuter l'action dcide 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}% dfinit 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 ngatifs%
	\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 % dfinit un compteur utilis dans la boucle
\def\compte#1{%
	\xx=0 % initialise le compteur
	\loop% dbut de la boucle
		\advance\xx1 % incrmente le compteur
		\ifnum\xx<#1 % s'il est infrieur  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 % dfinit le compteur de \xrepeat

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

\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% incrmenter 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 % incrmente colonne
		, % <- affiche ", "
	\xrepeat% et recommence
	\ifnum\cntxx<3 % tant que ligne<3
	\advance\cntxx1 % incrmente ligne
	\par % va  la ligne
\xrepeat% et recommence
****************** Fin code ******************


****************** Code 195 ******************
\catcode`\@11
\def\end@foreach{\end@foreach}% dfinit 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 dj dfinies
	\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% amne le \fi ici
		\loop@code% excute 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
		% aprs tre sorti des boucles, neutraliser les macros dj dfinies
		\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% amne le \fi ici
			\loop@code% excute le code
			\doforeach@i##1% et recommencer
		\fi
	}%
}
\defseplist{,}% dfinit les macros avec le sparateur par dfaut
\catcode`@12

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

\defseplist{--}% sparateur "--"
\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 % dfinit 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 % entre de boucle : incrmenter 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 dj dfinies
		\letname{loop@code@\number\cnt@nest}\empty%
		\global\advance\cnt@nest-1 %sortie de boucle : dcrmenter 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% amne le \fi ici
			\csname loop@code@\number\cnt@nest\endcsname% excute 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 % dfinit 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 dj dfinie...
		\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 % entre de boucle : incrmenter 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 dcrmenter 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% amne le \fi ici
			\csname loop@code@\number\cnt@nest\endcsname% excute 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 indfinie
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 % dfinit 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 % entre de boucle : incrmenter le compteur d'imbrication
		\global\let\allow@recurse\identity% permet l'appel rcursif plus bas
		\ifin{##1}{/}% si ##1 contient "/"
			{\save@macro@i##1% sauvegarde les macros
			\doforeach@ii% appeler la macro rcursive avec les arguments
				{##3}% 1) code  excuter
				##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 rcursive
				{##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 % dcrmente le compteur d'imbrications
	}%
	% ##1 = code  excuter, ##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 excuter:
			{\def##2{##3}% fait l'assignation  la variable
			##1% le code puis
			\allow@recurse{\doforeach@i{##1}##2}% recommencer
			}%
	}%
	% ##1 = code  excuter, ##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 excuter:
			{\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 rcursif
	\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 dfinir \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 redfinir  -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{% dfinit et dveloppe les arguments  passer  \FOR@i
			%#1=nom de la macro rcursive :
			\expandafter\noexpand\csname FOR@ii@\string#1\endcsname
			\ifdim\FOR@increment<\z@ <\else >\fi% #2=signe de comparaison
			{\FOR@increment}% #3=incrment
			\noexpand#1% #4=\<macro>
			{\the\dimexpr#3pt\relax}% #5=dimension n2
		}%
		\antefi% externalise la ligne ci-dessous de la porte du test
		\expandafter\FOR@i\macro@args% appelle \FOR@i avec les arguments dfinis ci-dessus
	\fi
}

% #1=nom de la macro rcursive de type "\FOR@ii@\<macro>"
% #2=signe de comparaison  % #3=incrment
% #4=\<macro>  % #5=dimension n2  % #6=<code>  excuter
\long\def\FOR@i#1#2#3#4#5#6{%
	\def#1{% dfinit la sous macro rcursive
		\unless\ifdim#4pt#2#5\relax% tant que la \<macro> variable n'a pas dpass n2
			\afterfi{% rendre la rcursivit terminale
				#6% excute le code
				\edef#4{\dimtodec\dimexpr#4pt+#3\relax}% incrmente la \<macro>
				#1% recommence
			}%
		\fi
	}%
	#1% appelle la sous-macro rcursive
}%
\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 prmaturment sorti de la boucle de \<macro> #1
	% si la macro rcursive est \empty
	\expandafter\ifx\csname FOR@ii@\string#1\endcsname\empty
		\expandafter\firstoftwo% c'est qu'on est sortir prmaturment, 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 dcimal #1
	\dimtodec\dim@a% convertir la dimension en dcimal
}
\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 dcimal #1 par le dcimal #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 caractres font entrer TeX en mode horizontal
\kern0.5cm % espace insre en mode horizontal
bar\par% \par fait passer en mode vertical
\kern0.5cm % espace insre en mode vertical
boo
****************** Fin code ******************


****************** Code 216 ******************
Une premire ligne\par
\nointerlineskip% n'insre 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 insr ici
Une dernire ligne
****************** Fin code ******************


****************** Code 217 ******************
\begingroup
\offinterlineskip
La macro \litterate-\offinterlineskip-, en modifiant de faon approprie les trois
primitives \litterate-\baselineskip-, \litterate-\lineskip- et
\litterate-\lineskiplimit-, rend les boites conscutives jointives.

On peut constater dans ces deux paragraphes o \litterate-\offinterlineskip- a t
appele, que les lignes sont places verticalement au plus prs les unes des autres ce
qui rend la lecture trs pnible et dmontre que le ressort d'interligne est une
ncessit typographique !\par
\endgroup
Dsactiver 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 spciaux.
****************** Fin code ******************


****************** Code 218 ******************
\baselineskip=12pt
dbut \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
dbut \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 prcdente
Et la suite du texte suite du texte suite du texte
****************** Fin code ******************


****************** Code 220 ******************
\def\dummytext{Voici un texte qui ne revt aucune importance
	et dont le seul but est de meubler artificiellement un paragraphe. }
\begingroup%  l'intrieur d'un groupe,
	\leftskip=0pt plus 0.5\hsize\relax
	\rightskip=\leftskip\relax % modifier les ressort d'extrmits
	\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 rgulirement\hfill espacs
****************** Fin code ******************


****************** Code 223 ******************
a% le caractre "a" fait passer en mode horizontal
\hbox{b}c\hbox{d}% les \hbox sont ajoutes en mode horizontal
\medbreak
... comparer avec...
\medbreak
a \par% \par fait passer en mode vertical
\hbox{b}% \hbox est ajoute  la liste verticale
c% "c" fait passer en mode horizontal
\hbox{d}% la \hbox est ajoute 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 caractre
	$\number\arglength/\charlength % affiche la division
	=\number\numexpr\arglength/\charlength\relax$ % affiche le quotient
	caractres%
}
\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 caractre
		\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 mathmatique 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}aprs la macro\medbreak
b) avant la macro|\raise2.5ex\clap{Au-dessus}\lower2.5ex\clap{Au-dessous}%
   aprs la macro\medbreak
c) avant la macro|\raise2.5ex\llap{Au-dessus avant}\lower2.5ex\rlap{Au-dessous aprs}%
   aprs 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% complter 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 lment :
		{\setbox0=\hbox{\htext}% stocker l'lment "\htext" dans une \hbox
		\ifdim\wd0 >\hmaxsize% si sa longueur est suprieure  \hmaxsize
			\hmaxsize=\wd0 % mettre  jour \hmaxsize
		\fi
		}%
	\vtop{% dans une \vtop...
		\doforeach\htext\in{#1}% pour chaque lment :
			{\hbox to\hmaxsize{\hss\htext\hss}% le centrer dans une \hbox de longueur \hmaxsize
			}%
	}%
}

texte avant...\cvtop{Ligne du haut,Trs grande ligne du milieu,Ligne du bas pour finir}%
...texte aprs
****************** Fin code ******************


****************** Code 244 ******************
\newdimen\hmaxsize
\def\cvtop#1{%
	\hmaxsize=-\maxdimen% initialise  la plus petite longueur
	\doforeach\htext\in{#1}% pour chaque lment :
		{\setbox0=\hbox{\htext}% stocker l'lment "\htext" dans une \hbox
		\ifdim\wd0 >\hmaxsize% si sa longueur est suprieure  \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 lment :
			{\htext\par}% le composer et finir le paragraphe
	}%
}

texte avant...\cvtop{Ligne du haut,Trs grande ligne du milieu,Ligne du bas pour finir}%
...texte aprs
****************** Fin code ******************


****************** Code 245 ******************
\halign{X#**\ignorespaces&#&\hfil #\cr % prambule
foo            &foo bar&123 456\cr % premire ligne
deuxime ligne &1      &12\cr % deuxime ligne
a              &\TeX   &1 2 3 4 5 6\cr % troisime 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% prambule : centrer le contenu
			\temp\crcr}% mettre \temp dans l'alignement
	}% \temp est dtruite en sortant de la boite
}

texte avant...\cvtop{Ligne du haut,Trs grande ligne du milieu,Ligne du bas pour finir}%
...texte aprs
****************** 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% prambule : composer au fer  gauche
			\temp\crcr}% mettre \temp dans l'alignement
	}% \temp est dtruite en sortant de la boite
	\edef#1{\the\wd0 }%
}
a) La plus grande longueur vaut
   \calcmaxdim\foo{Ligne du haut,Trs grande ligne du milieu,Ligne du bas pour finir}\foo

b) Vrification : \setbox0=\hbox{Trs 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 rglure 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 % rglure horizontale de longueur #1
	\vrule width 0.4pt height 1ex  depth 0pt % trait vertical droit
	\relax% stoppe la lecture de la prcdente 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% rglure suprieure
	\kern\frboxsep% espace verticale haute
	\hbox{\kern\frboxsep Programmation\kern\frboxsep}% contenu + espaces horizontales
	\kern\frboxsep% espace verticale basse
	\hrule height\frboxrule% rglure infrieure
	}%
...
****************** 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) rglure gauche
		\vbox{%                 2) un empilement vertical comprenant
			\hrule height\frboxrule% a) rglure suprieure
			\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)rglure infrieure
			}%
		\vrule width\frboxrule% 3) rglure 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% rglure gauche
		\vtop{%
			\vbox{% 1er lment de la \vtop
				\hrule height\frboxrule% rglure suprieure
				\kern\frboxsep% espace haut
				\hbox{%
					\kern\frboxsep% espace gauche
					#1% contenu
					\kern\frboxsep% espace droite
					}%
			}% puis autres lments de la \vtop, sous la ligne de base
			\kern\frboxsep% espace bas
			\hrule height\frboxrule% rglure infrieure
		}%
		\vrule width\frboxrule% rglure 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% insre le titre
			\endgraf% et le compose
			}%
	}%
	\medbreak% passe en mode v puis saute une espace verticale
	\ignorespaces% mange les espaces situs aprs la macro \centretitre
}
\frboxrule=0.8pt \frboxsep=5pt
Voici un
\centretitre{Titre}
puis un
\centretitre{Texte trs 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 rglure en hauteur : \vrule width 1cm height 10.4pt depth -10pt 
****************** Fin code ******************


****************** Code 257 ******************
Une rglure 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 rglure
		\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 rglure
	#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 lment dans la ligne courante...
			{\frbox{% ...encadrer
				\hbox to\stackwd{% une \hbox de largeur \stackwd
					\hss% ressort de centrage
					\current@item% l'lment 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 insrer 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 }% dfinit le strut
		\stackbox@i#1\\\quark\\% ajoute "\\\quark\\"  la fin et appelle \stackbox@i
		\unkern% annule la dernire 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 lment 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 arrire pour superposer les rglures verticales
			}% fin de \doforeach
		\unkern% annuler la dernire 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 rglures 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 }% dfinit le strut
		\lineboxed@i#1\\\quark\\% ajoute "\\\quark\\"  la fin et appelle la macro rcursive
		\unkern% annule la dernire 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% reoit 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 lment 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 arrire pour superposer les rglures verticales
				}% fin de \doforeach
			\unkern% annuler la dernire 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 rglures 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 lments verticalement
		\offinterlineskip% pas de ressort d'interligne
		\edef\total@wd{\the\dimexpr\xunit*#1\relax}% largeur totale ds rglures
		\for\ii = 1 to #3 \do1% pour chaque carreau vertical (\ii=variable muette)
			{\vlap{\hrule width\total@wd height\mainrule}% tracer la rglure horizontale
			\kern\yunit% insrer l'espace vertical
			}%
		\vlap{\hrule width\total@wd height\mainrule}% dernire rglure 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 ******************
Dbut\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 lments 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 rglure horizontale principale
			% et dessous, les rglures horizontales secondaires :
			\vbox to\z@{% dans une \vbox de hauteur nulle,
				\for\jj = 2 to #4 \do 1% insrer #4-1 fois sous la position courante :
					{\kern\sub@unit % l'espace verticale
					\vlap{\hrule width\total@wd height\subrule}% et la rglure secondaire
					}%
				\vss% ressort qui se comprime pour satisfaire la hauteur nulle
			}%
			\kern\yunit% insrer l'espace vertical entre rglures principales
			}%
		\vlap{\hrule width\total@wd height\mainrule}% dernire rglure 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 lments verticalement
		\offinterlineskip% pas de ressort d'interligne
		% #################### Trac des rglures 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}% rglure principale
					\rlap{% mettre  droite de la position sans bouger
						\for\jj = 2 to #2 \do 1% insrer #2-1 fois
							{\kern\sub@unit % l'espace horizontal
							\clap{\vrule width\subrule height\total@ht}% et la rglure verticale
							}%
					}%
					\kern\xunit % insrer l'espace entre rglures horizontales
					}%
				\clap{\vrule width\mainrule height\total@ht}% dernire rglure principale
			}%
			\vss% compense la hauteur=0pt de la \vbox
		}%
		% #################### Trac des rglures 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}% rglure horizontale principale
			% et dessous, les rglures secondaires :
			\vbox to\z@{% dans une \vbox de hauteur nulle,
				\for\jj = 2 to #4 \do 1% insrer #4-1 fois sous la position courante :
					{\kern\sub@unit % l'espace vertical
					\vlap{\hrule width\total@wd height\subrule}% et la rglure secondaire
					}%
				\vss% ressort qui se comprime pour satisfaire la hauteur nulle
			}%
			\kern\yunit% insrer l'espace vertical entre rglures principales
			}%
		\vlap{\hrule width\total@wd height\mainrule}% dernire rglure 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 % premire rglure verticale
     \hbox to10cm{% puis rptition 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% monte 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}% rglure principale du haut
		\leaders% rpter (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}% rglure de subdiv de dim 0pt
				}\vfill
		\kern\dimexpr\yunit/#2\relax% dernire espace verticale
		\vlap{\hrule height\mainrule width\xunit}% rglure 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
	% ######## rglures 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}% rglure principale du haut
			\leaders% rpter (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}% rglure de subdiv de dim 0pt
					}\vfill% ressort de \leaders
			\kern\dimexpr\yunit/#2\relax% derniere espace verticale
			\vlap{\hrule height\mainrule width\xunit}% rglure principale du bas
		}%
	}%
	% ######## rglures verticales ########
	\hbox to\xunit{% dans une \hbox de longueur \xunit
		\clap{\vrule height\yunit width\mainrule}% rglure principale de gauche
		\leaders% rpter (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}% rglure H de dimension 0
				}\hfill% ressort de \leaders
			\kern\dimexpr\xunit/#1\relax% dernire espace H
			\clap{\vrule height\yunit width\mainrule}% rglure 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% rpter verticalement
			\hbox to#1\xunit{% une boite de longueur #1*\xunit
				\leaders% dans laquelle se rpte 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}% insre "\eof@nil\noexpand"  la fin du fichier
		\expandafter\filedef@i\expandafter#1% dveloppe \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 premire ligne
1) Signification : \meaning\foo.\par% signification de ce qui a t lu
1) Excution : \foo\par
\read\rtest to \foo% lit la deuxime ligne
2) Signification : \meaning\foo.\par
2) Excution : \foo\par
\read\rtest to \foo% lit la dernire ligne
3) Signification : \meaning\foo.\par
3) Excution : \foo
\closein\rtest
****************** Fin code ******************


****************** Code 282 ******************
\openin\rtest =filetest.txt
\readline\rtest to \foo% lit la premire ligne
1) Signification : \meaning\foo.\par% signification de ce qui a t lu
1) Excution : \foo\par
\readline\rtest to \foo% lit la deuxime ligne
2) Signification : \meaning\foo.\par
2) Excution : \foo\par
\readline\rtest to \foo% lit la dernire ligne
3) Signification : \meaning\foo.\par
3) Excution : \foo
\closein\rtest
****************** Fin code ******************


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


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


****************** Code 285 ******************
\def\xread#1to#2{%
	\ifcs{#2}% si #2 est une squence de contrle
		{\edef\restoreendlinechar{\endlinechar=\the\endlinechar}%
		\endlinechar=-1 % supprime le caractre 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 squence de contrle,
		{\xread#1to}% ignorer #2, et recommencer
}

\openin\rtest =filetest.txt
Ligne 1 : \xread\rtest to \foo% lit la premire ligne
\meaning\foo.\par% donne ce qui a t lu
Ligne 2 : \xread\rtest to \foo% lit la deuxime ligne
\meaning\foo.\par
Ligne 3 : \xread\rtest to \foo% lit la dernire 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% aprs 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 premire ligne
\meaning\foo.\par% donne ce qui a t lu
Ligne 2 : \xread\rtest to \foo% lit la deuxime ligne
\meaning\foo.\par
Ligne 3 : \xread\rtest to \foo% lit la dernire ligne
\meaning\foo.
\closein\rtest
****************** Fin code ******************


****************** Code 287 ******************
\def\macroname{% se dveloppe en le nom de la macro qui suit sans 
               % le caractre d'chappement
	\ifnum\escapechar>-1 % si le caractre d'chappement est positif
		\ifnum\escapechar<256 % et infrieur  256, dvelopper 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=rfrence  #4=macro  dfinir
	\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 premire 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 % incrmenter 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 intituls) dans une macro
			\letname{fieldname\number\field@cnt}=\current@field
			}%
		\edef\field@num{\number\field@cnt}% nombre de champs
		% ################ lecture des lignes de donnes ################
		\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}% dfinir la macros \<#3."champ 1">
		\field@cnt=1 % initialiser le compteur de champ
		\doforeach\current@field\in{#2}% puis, pour i>2, dfinir les macros \<#3."champ i">
			{\advance\field@cnt1 % incrmenter le compteur de champ
			\letname{#3.\csname fieldname\number\field@cnt\endcsname}=\current@field
			}%
		\defname{#3}##1{% et dfinir la macro \<#3>
			\ifcsname#3.##1\endcsname% si la macro \<#3."argument"> existe dj
				\csname#3.##1\expandafter\endcsname% l'excuter aprs avoir mang le \fi
			\fi
		}%
	\fi
}
\catcode`\@12

\searchitem\rtest{fournitures.txt}{4562u}\monarticle
rf = \monarticle{ref},
dnomination = \monarticle{item},
prix = \monarticle{prix},
fournisseur = \monarticle{fournisseur},
champ non existant = \monarticle{foobar}.

\searchitem\rtest{fournitures.txt}{truc}\essai% rfrence "truc" n'existe pas
rf = \essai{ref},
dnomination = \essai{item},
prix = \essai{prix},
fournisseur = \essai{fournisseur}.
****************** Fin code ******************


****************** Code 288 ******************
\def\macroname{% se dveloppe en le nom de la macro qui suit sans 
               % le caractre d'chappement
	\ifnum\escapechar>-1 % si le caractre d'chappement est positif
		\ifnum\escapechar<256 % et infrieur  256, dvelopper 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  dfinir
	\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 premire 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 donnes ################
		\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 boolen 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 % incrmenter le compteur de champ
		\ifnum\field@cnt=\sought@fieldnumber\relax% si c'est le bon numro 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 trouve
		\field@cnt=0 % initialiser le compteur de champ
		\doforeach\current@field\in{#1}% parcourir  nouveau les champs de la ligne
				{\advance\field@cnt1 % incrmenter le compteur de champ
				\letname{#2.\number\field@cnt}=\current@field% faire l'assignation
				}%
		\defname{#2}##1{% et dfinir la macro \<#2>
			\ifcsname#2.##1\endcsname% si la macro \<#2."argument"> existe dj
				\csname#2.##1\expandafter\endcsname% l'excuter aprs 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% slectionner la fonte  chasse fixe
		\openin#1=#2\relax
		\ifeof#1% si la fin du fichier est dj 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 spciaux
			\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% slectionner la fonte  chasse fixe
		\openin#1=#2\relax
		\ifeof#1% si la fin du fichier est dj 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 spciaux
			\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 itration)
				\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% dfait 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% dfait la liaison
"\showfilecontent\rtest{writetest.txt}"% affiche le contenu du fichier
****************** Fin code ******************


****************** Code 292 ******************
\def\noexpwrite#1#2{% #1=numro 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=numro de canal
	\begingroup
		\def\canal@write{#1}% sauvegarde le numro 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}}% dfinit le caractre <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 premire ligne de #1
		}
		{\immediate\write\canal@write{#1}% sinon : dernire ligne atteinte, l'crire
		\endgroup% puis sortir du groupe
		}%
}

% les \expandafter provoquent le 1-dveloppement 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 aprs "^^M"
}
\catcode`\@12

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

Et trs 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 numro 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 excuter son contenu
		{\def\total@points{\char`\#\char`\#}}% sinon, dfinir 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{% dfinti 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 % incrmenter le numro de l'exercice
	\noindent\vrule height1ex width1ex depth0pt % trace le carr
	\kern1ex% insrer une espace horizontale
	{\bf Exercice \number\exo@number}% afficher "Exercice <nombre>"
	\leaders\hbox to.5em{\hss.\hss}\hfill% afficher les pointills
	#1/\total@points%  puis #1/<total>
	\smallbreak% composer la ligne prcdente 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 dterminer si l'encodage d'un document
est  plusieurs octets (comme l'est UTF8) en prenant comme \litterate/<texte>/
les caractres <<~~>>, <<~~>>, 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$-dveloppement, les \litterate/\expandafter/se plaaient
en nombre gal  $2^n-1$ devant chaque token prcdant celui que l'on veut dvelopper.
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}% Prnom Nom
\def\beforespace#1 #2\nil{#1}
\def\afterspace#1 #2\nil{#2}
\def\prenom{\beforespace\identite\nil}
\def\nom{\afterspace\identite\nil}
Mon prnom : \expandafter\expandafter\prenom

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


****************** Code 296 ******************
\newlinechar`\^^J 
\immediate\openout\wtest=test1.txt 
\immediate\write\wtest{Une premire 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 premire ligne^^JEt une seconde.}
\immediate\write\wtest{Et la dernire.}
\immediate\closeout\wtest 

{\endlinechar`\X % insre "X"  chaque fin de ligne
\openin\rtest=test2.txt % les fins de lignes sont commentes
\loop%                    pour viter que \endlinechar 
	\read\rtest to \foo%    ne soit insr  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=numro de canal
	\begingroup
		\for\xx=0 to 255\do{\catcode\xx=12 }% donne  tous les octets le catcode 12
		\newlinechar=`\^^M % caractre 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 caractre dlimiteur 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 trs 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'annes pratiquez-vous TeX ? }
\read-1 to \yeartex 
\message{%
	\ifnum\yeartex<5 Cher \username, vous tes encore un dbutant !
	\else\ifnum\yeartex<10 Bravo \username, vous tes un TeXpert !
	\else\ifnum\yeartex<15 Flicitations \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 appele 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 entre lorsque c'est fait.}%
	\read-1 to \tex@guess% attend que l'on tape sur "entre"
	\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 rponse de l'utilisateur
		\edef\user@answer{%
			\expandafter\firstto@nil\user@answer\relax\@nil% ne garder que le 1er caractre
		}%
		\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 rponse ne commence pas par "+", "-" ou "="
			\message{Je n'ai pas compris votre rponse}% afficher message erreur
			\nbguess@i{#1}{#2}% et recommencer avec les mmes 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}% aprs 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}% aprs 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 rcursivit 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 lanant le dveloppement 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 rcursive 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 rcursive 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 doubls puisqu' l'intrieur d'une macro
		$\hfil##$&${}=\hfil##$&${}\times##\hfil$&${}+##\hfil$% prambule
		\cr% fin du prambule et dbut de la premire 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 rcursive 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 diffrent 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% aprs 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 remplaant 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-dveloppe la \<macrolist>
}
\def\finditem@i#1#2{% #1 = liste   #2=position cherche
	\finditem@ii{1}{#2}#1,\quark@list,% appelle la macro rcursive
}
\def\finditem@ii#1#2#3,{% #1=position courante  #2=position cherche  #3=lment 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 lments restants
			}
			{% si la position n'est pas la bonne, recommencer en incrmentant #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-dveloppe la \<macro>
}
\def\finditem@i#1#2{% #1 = liste   #2=position cherche
	\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 rcursive
	\fi
}
\def\finditem@ii#1#2#3,{% #1=position courante  #2=position cherch  #3=lment 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 lments restants
			}
			{% si la position n'est pas la bonne, recommencer en incrmentant #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  dfinir
	\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-dveloppe la \<macro>
}
\def\finditemtocs@i#1#2{% #1 = liste   #2=position cherche
	\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 rcursive
	\fi
}
\def\finditemtocs@ii#1#2#3,{%
% #1=position courante  #2=position cherch  #3=\relax + lment 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 lments restants
			}% si la position n'est pas la bonne, recommencer en incrmentant #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-dveloppe la \<macrolist>
}
\def\positem@i#1#2{% #1 = liste   #2=lment cherch
	\def\sought@item{#2}% dfinir l'lment cherch
	\positem@ii{1}\relax#1,\quark@list,% appelle la macro rcursive
}
\def\positem@ii#1#2,{% #1=position courante  #2=\relax + lment 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, dfinir la position
			\positem@goblist% et manger les lments restants
			}% si la position n'est pas la bonne, recommencer en incrmentant #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=lment  chercher  #3=macro  dfinir
	\def\positem@endprocess{\let#3=\pos@item}% hook : mettre le rsultat dans #3
	\exparg\positem@i{#1}{#2}% 1-dveloppe 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 cherche   #3=lment  insrer
	\let\item@list=\empty
	\ifnum#2<1 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		% si position < 1
		{\addtomacro\item@list{#3,}% ajouter l'lement  insrer en premier
		\eaddtomacro\item@list#1% puis la liste entire
		}
		% si la position  > 1
		{% dfinir la macro rcursive
		\def\insitem@i##1##2,{% ##1 = position courante  ##2=\relax + lment courant
			\expandafter\ifx\expandafter\quark@list\gobone##2%
			\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
				{\addtomacro\item@list{#3}}% si fin de liste, ajouter l'lment en dernier
				{% sinon, si la position cherche 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'lment
					\exparg\insitem@i{\number\numexpr##1+1}\relax% et recommencer
					}%
				}%
			}%
		% appel de la macro rcursive
		\expandafter\insitem@i\expandafter1\expandafter\relax#1,\quark@list,%
		}%
	\let#1=\item@list% rendre #1 gal au rsultat
}

\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 cherche
	\ifnum#2>0 % ne faire quelque chose que si la position est >0
		\def\delitem@i##1##2,{% ##1 = position courante  ##2=\relax + lment 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 cherche 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'lment
					\exparg\delitem@i{\number\numexpr##1+1}\relax% et recommencer
					}%
				}%
			}%
		\let\item@list=\empty% initialiser la macro tempporaire
		% appel de la macro rcursive
		\expandafter\delitem@i\expandafter1\expandafter\relax#1,\quark@list,%
		\let#1=\item@list% rendre #1 gal au rsultat
	\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 dpart, #3=position arrive
	\ifnum#2>0 % ne faire quemque chose que si #2>0
		\finditemtocs#1{#2}\temp@item% sauvegarder l'lment
		\delitem#1{#2}% supprimer l'lment
		\expsecond{\insitem#1{#3}}\temp@item% insrer l'lment
	\fi
}
\catcode`\@12
% dplace "b" en 5e position
a) \def\liste{a,b,c,d,e,f} \moveitem\liste25 "\liste"\par
% dplace "d" en 1e position
b) \def\liste{a,b,c,d,e,f} \moveitem\liste41 "\liste"\par
% dplace "c" en 9e position
c) \def\liste{a,b,c,d,e,f} \moveitem\liste39 \liste"\par
% position dpart=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>{<lment>}""
			\expandafter\runlist@i% et recommencer en lisant l'lment 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 dtruit \collect@run
	\collect@run% aprs l'avoir dvelopp !
}
\catcode`\@12
\newcount\foocnt
\foocnt=0 % compteur utilis pour numroter les lments dans la macro \foo
\def\foo#1{% la macro qui va excuter chaque lment de la liste. #1 = l'lment
	\advance\foocnt1 % incrmente 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 prmunit 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 dveloppement maximal
	\removefirstspaces@i% et passe la main  la macro rcursive
}

\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 dveloppement maximal
	\removelastspaces@i\relax#1^^00 ^^00\@nil% mettre un \relax au dbut
	                                         % 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 dbut
		                          % 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 dveloppement maximal
		\expandafter\expandafter\expandafter% le pont d'\expandafter
	\removelastspaces
		\expandafter\expandafter\expandafter% fait agir \removefirstspaces en premier
	{%
		\expandafter\expandafter\expandafter
	\z@% stoppe le dveloppement 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) excution : "\foo"\par
d) "\removetrailspaces{ 12 {\bf3}4 }"
****************** Fin code ******************


****************** Code 325 ******************
\catcode`\@11
\def\sanitizelist#1{% #1 = liste
	\let\item@list\empty% initialise le rceptacle de la liste assainie
	\def\sanitizelist@endprocess{% dfinit le hook de fin
		\expandafter\remove@lastcomma\item@list\@nil% supprimer dernire virgule
		\let#1=\item@list% et assigner le rsultat  #1
	}%
	\expandafter\sanitizelist@i\expandafter\relax#1,\quark@list,% aller  la macro rcursive
}

\def\sanitizelist@i#1,{% #1="\relax" + lment 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-dvelopper \gobone pour retirer \relax
		\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter
			\item@list% puis 2-dvelopper \removetrailspaces
		\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter
			{\expandafter\removetrailspaces\expandafter{\gobone#1},}% "#1"
		\sanitizelist@i\relax% et continuer avec l'lment 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'arrt \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%  dcommenter pour dbogage
	\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% aprs l'assignation, aller  \Litterate@i
		\expandafter\let\expandafter\lim@tok\expandafter=\string% \lim@tok = token dlimiteur
}
\def\Litterate@i{%
		\afterassignment\Litterate@ii%aprs 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 dlimiteur"
		\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% aprs l'assignation, aller  \Litterate@i
		\expandafter\let\expandafter\lim@tok\expandafter=\string% \lim@tok = token dlimiteur
}
\def\Litterate@i{%
	\afterassignment\Litterate@ii% aprs avoir lu un token, aller  \Litterate@ii
		\expandafter\expandafter\expandafter% 1-dvelopper \string
	\let
		\expandafter\expandafter\expandafter% puis 1-dvelopper \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 dlimiteur"
		\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% insre le ressort
		\expandafter\letterspace@i% va lire le token suivant
	\fi
}
\catcode`@12
Voici "\letterspace{0.3em}{des lettres espaces}"
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 dbut 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, aprs 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 aprs 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% aprs 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{russi} et un essai \teststar*{toil} russi aussi.
****************** Fin code ******************


****************** Code 336 ******************
\catcode`@11
\def\deftok#1#2{\let#1= #2\empty}% dfinit 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  excuter
	\ifnexttok@i% aller  la macro rcursive
}
\def\ifnexttok@i{%
	\futurelet\nxttok\ifnexttok@ii% piocher le token d'aprs et aller  \ifnexttok@ii
}
\def\ifnexttok@ii{%
	\ifx\nxttok\sptoken% si le prochain token est un espace
		\def\donext{%
			\afterassignment\ifnexttok@i% recommencer aprs
			\let\nxttok= % aprs avoir absorb cet espace
		}%
	\else
		\ifx\nxttok\test@tok% si le prochain token est celui cherch
			\let\donext\true@code% excuter le code vrai
		\else
			\let\donext\false@code% sinon code faux
		\fi
	\fi
	\donext% faire l'action dcide 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  excuter
	\iftestspace \def\ifnexttok@i{\futurelet\nxttok\ifnexttok@ii}%
	\else        \def\ifnexttok@i{\futurelet\nxttok\ifnexttok@iii}%
	\fi% aprs avoir dfini la macro rcursive selon le boolen,
	\ifnexttok@i% l'excuter
}
\def\ifnexttok@ii{% macro "normale" qui ne teste pas les espaces
	\ifx\nxttok\test@tok \expandafter\true@code% excuter 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'aprs
			\let\nxttok= % aprs avoir absorb l'espace
		}%
	\else
		\let\donext\ifnexttok@ii% sinon, faire le test "normal"
	\fi
	\donext% faire l'action dcide 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{russi} et un essai \teststar*{toil} russi aussi.
****************** Fin code ******************


****************** Code 339 ******************
\catcode`\@11
\def\parsestop{\parsestop}% dfinit 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}% dfinit 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 toile
		{\parse@grouptrue\parse@i}% mettre le boolen  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 toile
		{\begingroup% ouvre un groupe pour parser l'intrieur de l'accolade
			\def\parsestop@i\parsestop{% redfinir localement \parsestop@i pour
				\expandafter\endgroup% ne fermer le groupe qu'aprs avoir
				\expandafter\parseadd% 1-dvelopp  l'extrieur 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 toile, 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= }% aprs 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, dvelopper #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 diffrents, 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 dbut 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 dbut 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 boolen  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 dbut 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 excute  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 excute  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 dbut 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 excute  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 excute  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% excuter macro non toile pour une seule itration
}
\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 excute  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 dlimits
		{\vecteur@i[1]}% sinon, ajouter l'argument optionnel par dfaut 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 dlimits
		{\vecteur@i[1]}% sinon, ajouter l'argument optionnel par dfaut entre crochets
}
\def\vecteur@i[#1]{%
	\ifnexttok(% si une parenthse vient ensuite
		{\vecteur@ii[#1]}% aller  la macro  argument dlimits
		{\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 parenthse
			\vecteur@paren % lire cet argument entre parenthses
			{\vecteur@i[1](x)}% sinon, transmettre les arguments par dfaut
		}%
}
\def\vecteur@bracket[#1]{%
	\ifnexttok(% s'il y a une parenthse aprs
		{\vecteur@i[#1]}% lire la parenthse
		{\vecteur@i[#1](x)}% sinon, donne "x" comme argument par dfaut
}
\def\vecteur@paren(#1){%
	\ifnexttok[% si le caractre suivant est un crochet
		{\vecteur@ii(#1)}% lire l'argument entre crochets
		{\vecteur@ii(#1)[1]}% sinon, donner "1" comme argument par dfaut
}
\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% numro  mettre dans le nom des sous macros
\newcount\arg@cnt% compte le nombre d'arguments
\newtoks\param@text% texte de paramtre 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 paramtre 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 paramtre est fini et il faut dfinir la macro
			{\defname{\macro@name\macro@cnt\expandafter}%
			\the\param@text}% <- le {<code>} est juste aprs, 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 dfaut de l'argument optionnel
	% Dfinit la macro \<nom>@[<nbre>] qui lit tous les arguments (optionnels ou pas)
	% jusqu'alors dfinis  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 dfaut lu
			{\expandafter\noexpand\csname\macro@name{\numexpr\macro@cnt+1}\expandafter\endcsname
			\the\arg@text[\unexpanded{#1}]}%
	}%
	\advance\arg@cnt 1 % incrmenter le numro 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 % incrmenter le numro 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 ncessaire
		\advance\arg@cnt 1 % incrmenter le numro 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 ajouts
		\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}{}% rglure gauche
		\vtop{%
			\vbox{% 1er lment de la \vtop
				\uppercase{\ifin{#1}U}{% si la rglure sup doit tre trace
					\hrule height\frboxrule% rglure suprieure
					\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 lments de la \vtop, sous la ligne de base
			\uppercase{\ifin{#1}D}{%
				\kern\frboxsep% espace bas
				\hrule height\frboxrule% rglure infrieure
				}%
				{}%
		}%
		\uppercase{\ifin{#1}R}{\vrule width\frboxrule}{}% rglure droite
	}%
}
\frboxsep=1pt 
Boite \framebox{entire}, \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 dveloppements  #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-dveloppements restant
	\ifempty{#1}% s'il n' y plus de n-dveloppements
		{\the\eargs@toks}% excuter la macro et ses arguments dvelopps
		{\eargs@ii#1\@nil}% sinon appeller la macro qui lit un argument
}

% #1=n-dveloppement actuel  #2=liste des n-dveloppements 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-dvelopper 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-dveloppements 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 aprs 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% excute 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 dtects}
\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 dtects}
\medskip

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


****************** Code 359 ******************
\catcode`\@11
\def\detectmark#1{%
	\begingroup
		\catcode`#1=13 % rendra #1 actif aprs 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 dtects}}
****************** Fin code ******************


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

\def\alter#1#2{% #1= dlimiteur  #2 = macro  altrer
	\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 dlimiteur aprs avoir mis son catcode  12
	\edef\alter@tmp{\def\noexpand\alter@readlitterate@i\string#1####1\string#1}%
	% dveloppe les \string#1 pour que les arguments dlimits aient
	% des dlimiteurs de catcode 12
	\alter@tmp{% <- comme si on crivait "\def\alter@readlitterate@i#1##1#1"
		\endgroup% aprs 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 aprs 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 dlimiteur
	\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 diffrent du dlimiteur
				% le rendre actif pour viter la ligature
				\expandafter\alter@defligchar\alter@tmp
			\fi
			}%
	\alter@readlitterate@i% puis aller  \alter@readlitterate@i...
	% ...qui a t dfinie dans \alter
}

\def\alter@defligchar#1{% dfinit le caractre 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 appele  la toute fin,
	% aprs que l'accolade fermante ait t mange (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'intrieur,
		% le tout mis entre accolades
		\alter@i% puis, lire le token suivant
	}%
	\alter@toks{}% au dbut du groupe, initialiser le collecteur
	\afterassignment\alter@i% aller lire le prochain token aprs
	\let\alter@tmptok= % avoir mang l'accolade ouvrante
}

\def\alter@readtok#1{% le prochain token ne demande pas une action spciale
	\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 aprs
	\let\alter@tmptok= % avoir mang l'accolade fermante
}

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

\frboxsep=1pt 
\alter|\frbox{Texte normal - |#& }| - texte normal - |_^ ##| - texte normal}
\alter=\frbox{La macro =\alter= autorise du verbatim dans
des commandes imbriques \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 prcdemment 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 caractre 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 dfinit 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% insre la lettre "d"  chaque fin de ligne
% le \noexpan(d) est incomplet
Voici la macro \string\foo\ : \foo.% fins de ligne...
}% ...commentes 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 prcdemment 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 prcdemment ouvert
		\toks0={#1}% met la \<macro> dans le registre de tokens
		\Cprotect@ii##1\quark% \quark est mis  la fin des arguments
		\the\toks0 % excute 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 (dpouill 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 "caractre autre"
\catcode`\^^M=13\relax% le retour  la ligne est actif
\edef^^M{\string,}% et se dveloppe en une virgule (de catcode 12)
\global\deftok\otherspc{ }% dfinit 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 caractres "," "*" 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=caractre de dessin de la ligne en cours
	\ifxcase#1% si le caractre 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 caractre 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 caractre cr
}.
****************** Fin code ******************


****************** Code 377 ******************
\catcode`\@11
\begingroup% dans ce groupe :
\catcode`\ =12\relax% l'espace devient un "caractre autre"
\catcode`\^^M=13\relax% le retour  la ligne est actif
\edef^^M{\string,}% et se dveloppe en une virgule (de catcode 12)
\global\deftok\otherspc{ }% dfinit 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{% dfinit la macro #1 comme
		\vtop{% une \vtop contenant :
			\unexpanded{\offinterlineskip\lineskip\pixelsep}% rglage 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{% dfinit 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 dveloppe en une virgule (de catcode 12)
\catcode`\ =12\relax% l'espace devient un "caractre autre"
\gdef\impact@alphabet{
a/
***
   *
 ***
*  *
****,
b/
*
*
***
*  *
*  *
*  *
***,
% beaucoup de caractres 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 dveloppe en une virgule (de catcode 12)
\expsecond{\doforeach\letter@name/\letter@code\in}\impact@alphabet%
	{\edef\letter@name{\letter@name}% dveloppe la lettre (^^M devient ",")
	\edef\letter@code{\letter@code}% dveloppe 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
% % dfinit l'espace
\pixelsize=3pt \pixelsep=1pt 
% puis, on affiche ce qui a t dfini :
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}% dfinit le quark de fin

\newmacro\impact[0.2ex][0pt]{% dfinit la macro  arguments optionnels
	\leavevmode% passer en mode horizontal
	\begingroup% dans un groupe semi-simple :
		\pixelsize=#1\relax \pixelsep=#2\relax% dfinir ces deux dimensions
		\letter@skip=#1 plus.1\pixelsize minus.1\pixelsize\relax% dfinir espace inter-lettre
		\baselineskip=% dfinir la distance entre les lignes de base
			\dimexpr12\pixelsize+7\pixelsep\relax%  12\pixelsize+7\pixelsep
		\lineskiplimit=0pt % si lignes trop serres
		\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 dcide ci-dessus
}

% mange un espace (argument dlimit) 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 caractre \impact@"#1" s'il est dfini
			\else
				"error"% sinon \impact@"error"
			\fi
		\endcsname
		\hskip\letter@skip% insrer le ressort inter-lettre
		\impact@i% puis, aller voir le prochain token
}
\def\impact@endprocess\impactend{% macro excut 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 rglure
}
Dbut\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 dbordement  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 dplacer 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 units
			\edef\dimsubgrad{\the\dimexpr#1/#5\relax}% dimension entre 2 subdivisions
			\for\xx=1 to #5-1 \do{% insrer #5-1 fois
				\kern\dimsubgrad% une espace secondaire
				\subgradx% une graduation secondaire
				}%
		}%
		\rlap{% en dbordement  droite :
			\FOR\xx = #2 to #4 \do #3{% pour chaque graduation principale
				\maingradx{\xx}% imprimer l'abscisse
				\ifdim\xx pt<#4pt % et en dbordement  droite,
					\rlap{\copy0 }% les rglures secondaires, sauf pour la dernire
				\fi
				\kern#1\relax% se dplacer 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'ordonne...
	\vbox to0pt{\vss\hrule height\maingradwd width\maingraddim depth0pt }% et la rglure
}

% 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% dsactiver le ressort d'interligne
		\setbox0=\vbox{% stocke dans une \hbox les grad secondaires entre 2 units
			\edef\dimsubgrad{\the\dimexpr#1/#5\relax}% dimension entre 2 subdivisions
			\for\xx=1 to #5-1 \do{% insrer #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 dbordement vers le bas
			\FOR\xx = #4to#2\do-#3{%
				\maingrady{\xx}% imprimer l'abscisse
				\ifdim\xx pt>#2pt % et en dbordement  droite,
					\vbox to 0pt{\copy0 \vss}% les rglures secondaires, sauf pour la dernire
				\fi
				\kern#1\relax% se dplacer vers la droite
			}%
			\vss% assure le dbordement vers le bas
		}%
		\clap{\vrule% tracer l'axe des ordonnes
			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'extrme 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 ordonnes
				\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 prcdemment 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 rglure
}

\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 units
			\edef\dimsubgrad{\the\dimexpr#1/#5\relax}% dimension entre 2 subdivisions
			\for\xx=1 to #5-1 \do{% insrer #5-1 fois
				\kern\dimsubgrad% une espace secondaire
				\subgradx% une graduation secondaire
				}%
		}%
		\rlap{% en dbordement  droite :
			\FOR\xx = #2 to #4 \do #3{% pour chaque graduation principale
				\maingradx{\xx}% imprimer l'abscisse
				\ifdim\xx pt<#4pt % et en dbordement  droite,
					\rlap{\copy0 }% les rglures secondaires, sauf pour la dernire
				\fi
				\kern#1\relax% se dplacer 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'ordonne...
	\vbox to0pt{\vss\hrule height\maingradwd width\maingraddim depth0pt }% et la rglure
}

% affiche une subdiv
\def\subgrady{\vlap{\hrule height\subgradwd width\subgraddim depth0pt }}
% #1= dim entre 2 grad principales #2=abscisse dpart #3=incrment
% #4=abscisse arrive #5=nb intervalles secondaires
\newmacro\yaxis[1cm]1[1]1[4]{%
	\vbox{%
		\offinterlineskip% dsactiver le ressort d'interligne
		\setbox0=\vbox{% stocke dans une \hbox les grad secondaires entre 2 units
			\edef\dimsubgrad{\the\dimexpr#1/#5\relax}% dimension entre 2 subdivisions
			\for\xx=1 to #5-1 \do{% insrer #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 dbordement vers le bas
			\FOR\xx = #4to#2\do-#3{%
				\maingrady{\xx}% imprimer l'abscisse
				\ifdim\xx pt>#2pt % et en dbordement  droite,
					\vbox to 0pt{\copy0 \vss}% les rglures secondaires, sauf pour la dernire
				\fi
				\kern#1\relax% se dplacer vers la droite
			}%
			\vss% assure le dbordement vers le bas
		}%
		\clap{\vrule% tracer l'axe des ordonnes
			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'extrme 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 ordonnes
				\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 prcdemment ouvert
		\xunit=\decdiv1\xincrement\xunit% divise les units par l'incrment
		\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 coordonnes #1,#2
	\edef\x@plot{#1}\edef\y@plot{#2}% dvelopper 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 coordonnes
				{\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% dfinit ce qu'il faut afficher comme point
	\FOR\xx=-2 to 2.5 \do 0.1{%
		\plot(\xx,\fonction{\xx})% afficher les points de coordonnes (x ; f(x))
	}%
	\putat{5pt}{\dimexpr\graphboxht-10pt\relax}% afficher
		{$f(x)=x^3-x^2-3x+2$}% la fonction trace
	\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 paramtrique trace
		{$\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}% carrs 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'itrations
	\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}}% incrment
		\count255=0 % compteur des itrations
		\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 coordonnes (-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 sparateur mis tous les 3 chiffres

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

% #1=compteur de caractres #2= chiffre courant
% #3= chiffres restants     #4 = chiffres dj traits
\def\formatdecpart@i#1.#2#3.#4.{%
	\ifempty{#3}% si #2 est le dernier chiffre
		{#4#2}% le mettre en dernire 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 dernire position et recommencer
			% tout en incrmentant #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 sparateur mis tous les 3 chiffres
\def\formatintpart#1{% #1=srie de chiffres
	\formatintpart@i 1.#1..% appelle la macro rcursive
}

% #1=compteur de caractres #2= chiffre courant
% #3= chiffres restants     #4 = chiffres dj traits
\def\formatintpart@i#1.#2#3.#4.{%
	\ifempty{#3}% si #2 est le dernier chiffre
		{#2#4}% le mettre en premire 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 premire position et recommencer
			% tout en incrmentant #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=srie 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 dcimale
		{\formatintpart{#1}}% formatter la partie entire
		{\formatnum@i#1\@nil}% sinon, formatter les deux parties
}

\def\formatnum@i#1.#2\@nil{%
	\formatintpart{#1}% formatte la partie entire
	\formatdecpart{#2}% et la partie dcimale
}

\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 zro
	\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 aprs
		{\romannumeral-`\.% tout dvelopper
			\expandafter\removelastzeros@i% enlever les 0 de gauche aprs
			\romannumeral\reverse{#1\z@}\quark% avoir invers #1
		}%
}
\def\removelastzeros@i#1{% enlve 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 sparateur mis tous les 3 chiffres

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

% #1=compteur de caractres #2= chiffre courant
% #3= chiffres restants     #4 = chiffres dj traits
\def\formatdecpart@i#1.#2#3.#4.{%
	\ifempty{#3}% si #2 est le dernier chiffre
		{#4#2}% le mettre en dernire 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 dernire position et recommencer
			% tout en incrmentant #1 de 1
			{\expandafter\formatdecpart@i \number\numexpr#1+1.#3.#4#2.}%
		}%
}

\def\formatintpart#1{% #1=srie de chiffres
	\expandafter\formatintpart@i\expandafter1\expandafter.%
	\romannumeral\reverse{#1\z@}..% appelle la macro rcursive
}

% #1=compteur de caractres #2= chiffre  dplacer
% #3= chiffres restants     #4 = chiffres dj traits
\def\formatintpart@i#1.#2#3.#4.{%
	\ifempty{#3}% si #2 est le dernier chiffre  traiter
		{#2#4}% le mettre en premire 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 dernire position et recommencer
			% tout en incrmentant #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 zro
	\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 aprs
		{\romannumeral-`\.% tout dvelopper
			\expandafter\removelastzeros@i% enlever les 0 de gauche aprs
			\romannumeral\reverse{#1\z@}\quark% avoir invers #1
		}%
}
\def\removelastzeros@i#1{% enlve 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 dcimale
\def\if@nodecpart#1.#2\@nil{\ifempty{#2}}

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

% #1 = <srie de signes> suivie de "1"
% #2 = caractre courant
% #3 = caractres non traits
\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 caractre 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 dcimal #1.#2
	\exparg\formatintpart{\romannumeral-`\.\removefirstzeros{#1}}%
	\exparg\formatdecpart{\romannumeral-`\.\removelastzeros{#2}}%
}

\def\if@comma#1{\if@comma@i#1,\@nil}% teste la prsence 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{Premire ligne}
	\hbox{Deuxime ligne}
	\hbox{Avant-dernire ligne}
	\hbox{Dernire 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{Premire ligne}
	\hbox{Deuxime ligne}
	\hbox{Avant-dernire ligne}
	\hbox{Dernire 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 prcdent
	\vskip\frboxsep\relax% et saute une petite espace verticale
	\begingroup
		\splittopskip\topskip% \topskip en haut des boites coupes
		\topskip=0pt % neutraliser le \topskip
		% nbre de rglures horizontales contribuant  l'encadrement restant (2 au dbut)
		\def\coeff@rule{2}%
		\setbox\remainbox=\vbox\bgroup% compose la boite aprs 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 rglures 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 prcdent
		\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 libre
				+\frboxsep+\frboxrule% par la rglure infrieure qui n'est pas sur cette page
				\relax
		\edef\old@vbadness{\the\vbadness}% sauvegarder \badness
		\vbadness=10000 % dsactive les avertissement lors de la coupure
		\def\coeff@rule{1}% ne prendre en compte que rglure D + espace D
		\setbox\partialbox=\vsplit\remainbox to\cut@ht% coupe  la hauteur calcule
		% \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 ncessaire :
		\setbox\remainbox\vbox{\unvbox\remainbox}% reprendre la hauteur naturelle
		\setbox\partialbox=\box\remainbox% \partialbox devient \remainbox
		                                 % et cette dernire devient vide
		\cut@ht=\dimexpr\ht\partialbox+\dp\partialbox\relax% hauteur  encadrer
		\edef\rule@arg{\rule@arg D}% ajouter "D" aux rglures  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 rglures 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 intrt dont le seul but est de meubler
	la page de faon artificielle.
}

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

\edef\restorevfuzz{\vfuzz=\the\vfuzz\relax}% appele aprs la coupure
\vfuzz=\maxdimen% annule les avertissements pour dbordement
\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 premire 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 intrt dont le seul but est
	de meubler la page de faon 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 dbordement
\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 premire 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 intrt dont le seul but est
	de meubler la page de faon 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 dbordement
\splittopskip=0pt % ne rajouter aucun espace au sommet de la boite restante
\savingvdiscards=1 % autorise la sauvagarde des lments supprims
\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 premire ligne
	\splitdiscards% affiche les lments ignors
	\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 numroter les lignes

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

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

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

\let\formatline=\identity% par dfaut, afficher chaque ligne telle quelle

% Par dfaut :
\leftline[11pt]{$\scriptscriptstyle\number\linecnt$\kern3pt }% numrotation  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 lments supprims
		\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 dbut
	\else% sinon
		\advance\linecnt 1 % incrmente le compteur de lignes
		\edef\htbefore{\the\vdim\remainbox}%
		\edef\restorevfuzz{\vfuzz=\the\vfuzz\relax}% sauvegarde le \vfuzz
		\vfuzz=\maxdimen% annule les avertissements pour dbordement
		\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 intrt dont le seul but est de meubler
		la page de faon 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'intrieur"
\let\formatline\frbox% lignes encadres
\numlines
	\dummytext{4}
\endnumlines\medbreak

ESSAI 3 :
\let\formatline\identity
\leftline[7pt]{%
	\for\xx= 1 to 2 \do{% insrer 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% rajuster la profondeur (c--d enlever \intersplitspace)
		\box0 % afficher le boite
		\kern2pt % et insrer un espace horizontal de 2pt aprs chaque rglure verticale
		}%
	\kern2pt % ajouter 2pt de plus entre les lignes et le texte
}

\rightline[10pt]{\kern5pt $\scriptscriptstyle\number\linecnt$}% numroter  droite

\numlines
	\dummytext{2}

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

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


****************** Code 406 ******************
% dfinition 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 prcdent 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 toile
		{\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 insre aprs
{\it chaque} caractre de catcode 10, 11 ou 12.}
\medbreak

\spreadtxt*{Comme on le voit sur cet exemple, une espace est insre aprs
{\it chaque} caractre 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
	% dfinit la macro appele en fin de processus -> a priori : fin normale
	\ifstarred% si la macro est toile
		{\let\spacetxt@recurse\spacetxt@star% dfinir la macro rcursive
		\spacetxt@i% et aller  \spacetxt@i
		}% sinon
		{\let\spacetxt@recurse\spacetxt@nostar% dfinir la macro rcursive
		\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 rcursive prcdemment dfinie
}

\newif\if@indivifound% boolen qui sera vrai si un motif spcial 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 rguliers ne sont pas trouvs
		% 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 prmaturment 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 caractre du texte
			\ifx\spacetxt@temp\space% si le 1er caractre est un espace
				\addtotoks\spacetxt@toks{%
					\unskip% annuler le prcdent ressort
					\hskip\interwordskip}% ajouter l'espace inter-mot au registre de token
			\else% si le 1er caractre n'est pas un espace
				% ajouter ce caractre 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% excuter 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 rcursive
}

\catcode`\@12
\def\indivilist{,}% liste des motifs spciaux
\spacetxt*{Comme on le voit sur cet exemple, une espace est insre aprs
{\it chaque} caractre.}
\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 dclarant "<<" et
">>" comme motifs.}
****************** Fin code ******************


****************** Code 408 ******************
\catcode`\@11
\def\ttcode#1{% lit #1, le <dlimiteur> de dbut
	\def\ttcode@i##1#1{% ##1 = <texte> entre dlimiteurs
		\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 spciaux
		\letactive\ =\space % rend l'espace actif
		\ttcode@i% va lire le <texte> et le dlimiteur de fin
}
\catcode`\@12

\hfill\vrule\vbox{%
	\hsize=.75\hsize
	Avec \ttcode/\ttcode/, on peut insrer une adresse internet <<
	\ttcode-http://www.gutenberg.eu.org/Typographie- >> puis repasser en fonte normale
	puis \ttcode+mme composer un court passage en fonte  chasse fixe -- mme si les
	coupures de mots se font n'importe o -- et aussi afficher tous les caractres
	spciaux <<{$^ _$#}&+>>, 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 caractres d'indentation
\hfill\vrule
\vbox{%
	\ttfamily% en TeX, on crirait "\tt"
	\setbox0\hbox{0}% \wd0 est donc la largeur d'un caractre
	\parindent=\ttindent\wd0 % rglage 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 traces, on constate que les caractres sont
	exactement les uns au-dessous d'une ligne  l'autre. Des dbordements dans
	la marge deviennent alors invitables, car la largeur de composition (ici
	\the\hsize) n'est pas un multiple de la largeur d'un caractre (\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 caractre de coupure = \number\hyphenchar\font\par
Caractre de coupure : "\char\hyphenchar\font"
****************** Fin code ******************


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

%comportement normal, caractre de coupure "-"
1) \vrule\vbox{\hsize=5cm \longtext}\vrule\hfill
% modification du caractre 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 indniablement 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 caractre 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 traces, on constate que les caractres sont
	exactement les uns au-dessous des autres d'une ligne  l'autre. Des dbordements
	dans la marge deviennent invitables mme 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 dsactivant le ressort d'interligne
			\setbox0\hbox{\frbox{\char\xx}}%
			\copy0 % la boite contenant le caractre encadr
			\kern1pt% saute 1pt vertical
			\hbox to\wd0{\hss$\scriptscriptstyle\xx$\hss}% le numro
		}\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 paramtres de fonte
		\hyphenchar\font=\the\hyphenchar\font\relax% le \hyphenchar
		\fontdimen2\font=\the\fontdimen2\font\relax% et les paramtres 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 caractre
	\parindent=#1\wd0 % indentation (en nombre de caractres)
	\ignorespaces
}
\def\ttstop{%
	\restorefontsettings% restaure les paramtres 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 traces, on constate que les caractres ne sont pas
	exactement les uns au-dessous des autres entre les lignes du paragraphe.
	Puisque les espaces sont redevenus tirables, les dbordements dans la marge
	(mme 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% boolen vrai lorsqu'aucun caractre n'est encore affich
\newif\if@indivifound% boolen qui sera vrai si un motif spcial est rencontr

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

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

\def\insert@blankchar@ii#1{% insre #1-1 caractres complets + 1 largeur de caractre
	\ifnum\numexpr#1\relax>0
		\insert@blankchar@i{#1-1}\kern\ttchar@width
	\fi
}

\def\restart@hbox#1{%
	\egroup% feerme la \hbox prcdente
	\hbox\bgroup% ouvre la suivante
	\expsecond{\def\tt@remaintext}
		{\romannumeral\removefirstspaces@i{#1}}% initialiser le code  composer
	\let\previous@char\space% initialise le caractre prcdent
	\line@starttrue% aucun caractre 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% empche l'indentation
	\tt% passer en fonte  chasse fixe
	\setbox0 = \hbox{M}% la boite 0 contient un caractre
	\edef\ttchar@width{\the\wd0 }% largeur de chaque caractre 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 diminue du 1er caractre
	\divide\brktt@cnt by \numexpr\dimexpr\wd0 + #1 \relax\relax
	% le nombre de caractre 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 aprs 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% dmarrer la boite horizontale contenant la premire ligne
		\insert@blankchar\ttindent% insrer une espace d'indentation
		\brktt@cnt=\ttindent\relax% tenir compte du nombre de caractres indents
		\line@starttrue% il s'agit du dbut d'une ligne
		\expandafter\breaktt@i% aller  la macro rcursive
	\fi
}

\def\breaktt@i{%
	\print@nchar\maxchar@num% afficher \maxchar@num caractres
	\ifx\tt@remaintext\empty% si texte restant est vide
		\egroup% fermer la hbox
		\par% aller  la ligne
		\endgroup% fermer le groupe ouvert au dbut
	\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 caractres 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 prmaturment
		\else
			\@indivifoundfalse% sinon, a priori, les motifs de ligature ne sont pas trouvs
			% 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 caractre courant,
					\expsecond{\rightofsc\tt@remaintext}{\indivi@tmp}% l'enlever du texte restant
					\@indivifoundtrue% marquer qu'un motif a t trouv
					\doforeachexit% et sortir prmaturment 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 caractre
			\fi
			\advance\brktt@cnt by 1 % incrmenter le compteur de caractres
			\hbox to\ttchar@width{\hss\previous@char\hss}% afficher le caractre lu
			\line@startfalse% nous ne sommes plus au dbut d'une ligne
			\ifnum\brktt@cnt<\maxchar@num\relax% si la ligne n'est pas encore remplie
				\kern\brktt@interletter% insrer le ressort inter-lettre
			\else
				\exitfor\xxx% sinon, sortir de la boucle prmaturment
			\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 traces, on constate que les caractres sont
exactement les uns au-dessous des autres d'une ligne  l'autre. Plus aucun
dbordement n'a lieu, car une espace correctement calcule est insre entre
chaque caractre. Les mots, en revanche, sont toujours coups <<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 traces, on constate que les caractres sont
exactement les uns au-dessous des autres d'une ligne  l'autre. Plus aucun
dbordement n'a lieu, car une espace correctement calcule est insre entre
chaque caractre. Les mots, en revanche, sont toujours coups <<sauvagement>>.%
}%
}\vrule
****************** Fin code ******************


****************** Code 423 ******************
\catcode`\@11
\newcount\brktt@cnt
\newdimen\brktt@interletter
\newif\ifline@start% boolen vrai lorsqu'aucun caractre n'est encore affich
\newif\if@indivifound% boolen qui sera vrai si un motif spcial 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% empche l'indentation
	\tt% passer en fonte  chasse fixe
	\setbox0 = \hbox{M}% la boite 0 contient un caractre
	\edef\ttchar@width{\the\wd0 }% largeur de chaque caractre 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 diminue du 1er caractre
	\divide\brktt@cnt by \numexpr\dimexpr\wd0 + #1 \relax\relax
	% le nombre de caractres 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 aprs 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% dmarrer la boite horizontale contenant la premire ligne
		\insert@blankchar\ttindent% insrer une espace d'indentation
		\brktt@cnt=\ttindent\relax% tenir compte du nombre de caractres indents
		\line@starttrue% il s'agit du dbut d'une ligne
		\expandafter\breakttA@i% aller  la macro rcursive
	\fi
}

\def\breakttA@i{%
	\edef\remaining@chars{% calculer le nombre de caractres restant  placer sur la ligne
		\numexpr\maxchar@num-\brktt@cnt\relax}%
	\len@tonextword% \next@len contient le nombre de caractres 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 dbut d'une ligne
			% avertir l'utilisateur
			\message{Largeur de composition trop faible pour
				\unexpanded\expandafter{\next@word}^^J}%
			% et composer tout de mme " 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 dbut
			\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 dbut. 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 caractre 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 caractres 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 caractre de plus  loger aprs le mot
		}% sinon, le caractre aprs 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 caractres = dim(boite)/dim(caractre)
	\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 traces, on constate que les caractres sont
exactement les uns au-dessous d'une ligne  l'autre. Plus aucun dbordement
n'a lieu, car une espace correctement calcule est insre entre chaque
caractre. Dornavant, les mots ne sont plus coups <<~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 traces, on constate que les caractres sont
exactement les uns au-dessous d'une ligne  l'autre. Plus aucun dbordement
n'a lieu, car une espace correctement calcule est insre entre chaque
caractre. Dornavant, les mots ne sont plus coups <<~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  excuter avant la composition
% #2=registre de boite recevant le rsultat
% #3= texte  composer en largeur 0pt
	\setbox#2=\vbox{%
		#1% code a excuter (changement de fonte par exemple)
		\hfuzz=\maxdimen% annule les avertissements pour dbordement horizontaux
		\hbadness=10000 % annule les avertissements pour mauvaise boite horizontale
		\pretolerance=-1 % dsactive la premire passe (celle sans coupures)
		\tolerance=10000 % passe avec coupures accepte
		\hyphenpenalty=-10000 % favorise fortement les copures de mots
		\lefthyphenmin=2 \righthyphenmin=3 % longueur mini des fragments de dbut et fin
		\clubpenalty=0 % pas de pnalit supplmentaire aprs la premire ligne
		\interlinepenalty=0 % pas de pnalit inter-ligne
		\widowpenalty=0 % pas de pnalit supplmentaire avant la dernire ligne
		\exhyphenpenalty=0 % ne pas pnaliser une coupure explicite
		\leftskip=0pt \rightskip=0pt % dsactive les ventuels ressorts latraux
		\everypar={}% dsactive l'ventuel \everypar
		\parfillskip=0pt plus1fil % rgle le \parfillskip par dfaut
		\hsize=0pt % largeur de composition = 0pt
		\edef\restorehyphenchar{\hyphenchar\font=\number\hyphenchar\font}%
		\hyphenchar\font=`\- % impose "-" comme caractre 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 caractre 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 intrt dont le seul but est de meubler
		la page de faon artificielle. }
\setbox0=\vtop{% dfinit la boite 0
	\hsize=8cm 
	\dummytext\dummytext
}

a) Boite pleine : \copy0 

b) \setbox0=\vtop{%
	\unvbox0 % boite prcdemment compose
	\global\setbox1=\lastbox% et capture la dernire ligne dans la boite 1
	}%
	Dernire ligne = |\hbox{\unhbox1 }|\par% redonne  box1 sa largeur naturelle
	Boite restante = \box0
****************** Fin code ******************


****************** Code 426 ******************
\def\dummytext{Ceci est un texte sans aucun intrt dont le seul but est de meubler
		la page de faon artificielle. }
\setbox0=\vtop{% dfinit 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 dernire 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 intrt dont le seul but est de meubler
		la page de faon artificielle. }
\setbox\tempbox=\vbox{% dfinit 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 rsultante
\vfuzz=\maxdimen% annule les avertissements pour dbordements
\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 compose dans sa largeur naturelle
		\unskip\unpenalty% annule ce qui n'est pas une boite
		\global\setbox2 =\lastbox% affecte globalement la dernire (et unique) ligne
		                         %  la boite 1
	}%
}% ferme le groupe
\setbox2=\hbox{\unhbox2}% rend  la boite 2 sa largeur naturelle
Premire 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 caractres
			]\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 dbordement
		\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 caractre"
						\wd1/\dimexpr\ttwidth\relax
						-1% et soustraire 1 (le caractre "-")
						\relax
				}%
				% ajouter  #2 la virgule et le cumul actuel +1
				\edef#2{% dfinir 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}% dfinit #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% boolen vrai lorsqu'aucun caractre n'est encore affich
\newif\if@indivifound% boolen qui sera vrai si un motif spcial est rencontr

\let\breakttB=\breakttA

\def\breakttA@i{%
	\edef\remaining@chars{% calculer le nombre de caractres restant  placer sur la ligne
		\numexpr\maxchar@num-\brktt@cnt\relax}%
	\len@tonextword% calculer dans \next@len le nombre de caractres 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% btir 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 examine 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 ncessaire et a t trouve
		\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 dbut d'une ligne
			% avertir l'utilisateur
			\message{Largeur de composition trop faible pour
				 \unexpanded\expandafter{\next@word}^^J}%
			% et composer tout de mme 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 caractre 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 dbut. 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 caractre 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 caractres
	\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% insrer 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 traces, on constate que les caractres sont
exactement les uns au-dessous d'une ligne  l'autre. Plus aucun dbordement
n'a lieu, car une espace correctement calcule est insre entre chaque
caractre. Dornavant, les mots ne sont plus coups <<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 traces, on constate que les caractres sont
exactement les uns au-dessous d'une ligne  l'autre. Plus aucun dbordement
n'a lieu, car une espace correctement calcule est insre entre chaque
caractre. Dornavant, les mots ne sont plus coups <<sauvagement>>.
}%
}\vrule
****************** Fin code ******************


****************** Code 432 ******************
Voici un algorithme lmentaire :
\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 premire ligne
		une seconde plus indente
	retour  l'indentation normale
		\for\xx=1to10\do{un long texte }
	pour terminer, la dernire ligne
\endgroup
****************** Fin code ******************


****************** Code 434 ******************
\def\algoindent{1cm}%
\begingroup
\leftskip=0pt \rightskip=0pt plus1fil \relax % initialise les ressorts latraux
\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 premire ligne
		une seconde plus indente
	retour  l'indentation normale
		\for\xx=1to10\do{un long texte }
	pour terminer, la dernire 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 premire ligne
		une seconde plus indente
	retour  l'indentation normale
		\for\xx=1to10\do{un long texte }
	pour terminer, la dernire ligne
\endgroup
****************** Fin code ******************


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

\def\algoindent{2em}
\def\algorule{.4pt}% paisseur des rglures de dbut 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 latraux
		\parindent=0pt % pas d'indentation
		%%%%%%%%%%%% affichage du titre %%%%%%%
		\algohrulefill% remplir avec une ligne horizontale
		\ifempty{#2}% si #2 est vide
			{}% ne rien insrer
			{% sinon
			\lower.5ex\hbox{ #2 }% insrer le titre abaiss de 0.5ex
			\algohrulefill% insrer une ligne horizontale
			}%
		\par% aller  la ligne
		\nointerlineskip% ne pas insrer le ressort d'interligne
		\kern7pt % et sauter 7pt verticalement
		\nobreak% empcher une coupure de page
		%%%%%%%%%%%%%% fin du titre %%%%%%%%%%
		%
		%%%%%%%%%%%%%% rend les caractres 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 numrotation est demande,
			\everypar={% dfinir le \everypar
				\llap{$\scriptstyle\number\algocnt$\kern\dimexpr4pt+\leftskip\relax}%
			}%
		\fi
		\doforeach\currentchar\in{#1}{\catcode\expandafter`\currentchar=12 }%
		\def\algocr{% dfinit ce que fait ^^M
			\color{black}% repasse en couleur noire
			\rm% fonte droite
			\leavevmode\par% termine le paragraphe
			\advance\algocnt by1 % incrmente 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 insrer le ressort d'interligne
			\kern7pt % et sauter 7pt verticalement
			\nobreak% empcher une coupure de page
			\algohrulefill% tracer la ligne de fin
	\endgroup% ferme le groupe ouvert au dbut de l'algorithme
	\smallbreak% saute un petit espace vertical
		}%
	%%%%%%%%%%%%%%%%% fin des caractres actifs %%%%%%%%%%%%%%%%
	\sanitizealgo% va manger les espaces et les ^^M au dbut de l'algo
}

\def\sanitizealgo{\futurelet\nxttok\checkfirsttok}% rcupre le prochain token

\def\checkfirsttok{% teste le prochaun token
	\def\nextaction{% a priori, on considre que la suite est " " ou "^^M" donc
		\afterassignment\sanitizealgo% aller  \sanitizealgo
		\let\nexttok= % aprs 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 dcide ci-dessus
}

Voici un algorithme lmentaire
\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% dbogage
	Bonjour #1 et #2}
\foo{{\bf X}}{Y}
****************** Fin code ******************


****************** Code 439 ******************
\def\foo#1#2{%
	\showtokens{#1}% dbogage
	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" aprs #1
		}
		{\ifnodecpart{#2}% si #1 a une partie entire mais pas #2
			{\decadd@i#1\@nil#2.0\@nil}% ajouter ".0"  #2
			{\decadd@i#1\@nil#2\@nil}% sinon, les 2 parties entires sont prsentes
		}%
}
\def\decadd@i#1.#2\@nil#3.#4\@nil{% affiche les parties entires et dcimales reues
	$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 reus : #1#2/#3.#4#5/#6.#7/\par% afficher ce que la macro reoit
	\ifempty{#2}% si #1 est le dernier chiffre de y
		{\ifempty{#5}% et si #4 est le dernier chiffre de y2
			{Rsultat final : \detokenize{{#3#1}{#6#4}{#70}}}% afficher le rsultat 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 dveloppe en 3 arguments
			{#1}
			{#3}%
}
\def\decadd@ii#1#2#3#4#5{%
% #1 et #2=parties dcimales (mmes longueurs);
% #3=seuil de retenue; #4 et #5=parties entires
	\exptwoargs{\decadd@iii{#3}}% envoyer le seuil de retenue tel quel
		% sommer les parties dcimales signes
		{\number\numexpr\true@sgn{#4}#1+\true@sgn{#5}#2\relax}%
		% et les parties entires
		{\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 dcimale #2=seuil de retenue
	\expandafter\gobone% le \gobone agira en dernier,
		\romannumeral-`\0% mais avant, tout dvelopper
		\expandafter\reverse\expandafter% et retarder le \reverse de fin
			% pour dvelopper son argument qui
			{\number% dveloppe 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 dvelopper 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" aprs #1
		}
		{\ifnodecpart{#2}% si #1 a une partie entire mais pas #2
			{\decadd@i#1\@nil#2.0\@nil}% ajouter ".0"  #2
			{\decadd@i#1\@nil#2\@nil}% sinon, les 2 parties entires sont prsentes
		}%
}
\def\decadd@i#1.#2\@nil#3.#4\@nil{%
	\expandafter\decadd@ii
			\romannumeral-`\0\addzeros#2/.#4/.10/% se dveloppe en 3 arguments
			{#1}
			{#3}%
}
\def\decadd@ii#1#2#3#4#5{%
% #1 et #2=parties dcimales (mmes longueurs)
% #3=seuil de retenue; #4 et #5=parties entires
	\exptwoargs{\decadd@iii{#3}}% envoyer le seuil de retenue tel quel
		% sommer les parties dcimales signes
		{\number\numexpr\true@sgn{#4}#1+\true@sgn{#5}#2\relax}%
		% et les parties entires
		{\number\numexpr#4+#5\relax}%
}
\def\decadd@iii#1#2#3{% #1=seuil de retenue #2=partie dcimale #3= partie entire
	\ifnum\true@sgn{#2}\true@sgn{\ifnum#3=\z@#2\else#3\fi}1=-1 % si les signes sont
	                                                           % diffrents
	\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{\exptwoargs\decadd@iv% transmettre les arguments modifis :
			{\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 dcimal "#1.#2"
	% le dveloppement 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 dveloppement  \number
		-% puis afficher le signe "-"
	\fi\fi
	\number#1% affiche #1 qui est la somme des parties entires
	% poursuivre le dveloppement initi par \number
	\unless\ifnum#2=\z@% si la partie dcimale est diffrente de 0
		\antefi% se dbarrasser de \fi
		\expandafter.% afficher le "." dcimal aprs avoir
		\romannumeral-`\0\format@dec{#2}{#3}% correctement gr 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 dcimale #2=seuil de retenue
	\expandafter\gobone% le \gobone agira en dernier,
		\romannumeral-`\0% mais avant, tout dvelopper
		\expandafter\reverse\expandafter% et retarder le \reverse de fin
			% pour dvelopper son argument qui
			{\number% dveloppe 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 dbut 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 (incrmentation 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 (incrmentation du texte de remplacement)
****************** Fin code ******************
