% Fichier EXOS.MAC %+----------------------------------------------------------------------------+ %| Macros pour une feuille d'exercices : Michel Quercia 09/09/94 | %+----------------------------------------------------------------------------+ %------------------------------------------------------------------ S‚curit‚ % Le code qui suit permet de ne charger les macros que la premiŠre fois % en cas d'appels multiples : \ifx\exoscharge\undefined\let\next\relax\else\let\next\endinput\fi\next \def\exoscharge{Exos charg‚} \input carnot.mac %--------------------------------------------------------------------------- % autorise @ dans les noms \catcode64=11 %+----------------------------------------------------------------------------+ %| Mise en page | %+----------------------------------------------------------------------------+ \edef\indent{\hskip\the\parindent} \parindent=0pt \newtoks\footname % nom … afficher en bas de page \footname={\jobname.tex} \footline={% \footlinefont % fonte ind‚pendante de \gros, \Gros, \petit \hfil % justification … droite \the\footname\ \ifnum\pageno=1 \date\else page \folio\fi % nom et date ou page \ifodd\pageno\footoddskip\else\footevenskip\fi % corrige la justification } \def\footoddskip {\ifnum\the\mag=707 \hfill\fi} \def\footevenskip {\ifnum\the\mag=707 \else \hfill\fi} \def\impairagauche {\def\footoddskip {\hfill}} \def\impairaucentre {\def\footoddskip {\hfil}} \def\impairadroite {\def\footoddskip {}} \def\pairagauche {\def\footevenskip {\hfill}} \def\pairaucentre {\def\footevenskip {\hfil}} \def\pairadroite {\def\footevenskip {}} %+----------------------------------------------------------------------------+ %| Num‚rotation automatique | %+----------------------------------------------------------------------------+ % \exnum : num‚ro de l'exercice en cours % \qqnum : num‚ro de la question en cours % \sqnum : num‚ro de la sous-question en cours % \numindent = indentation pour num‚ros % \qqmarge = marge nø de question % \sqmarge = marge nø de sous-question \newcount\exnum \newdimen\numindent \newcount\qqnum \newdimen\qqmarge \newcount\sqnum \newdimen\sqmarge \exnum=0 \qqnum=0 \sqnum=96 % a = \char97 \numindent=5mm \let\@endgroup=\relax % pas encore d'exercice \let\@filbreak=\filbreak % pas de titre … coller \let\@endmulticol=\relax % pas de multicolonnage %---------------------------------------------------------- Nouvel exercice \def\ex{\catcode13=12\relax\suiteex} % accepte ^M comme d‚limiteur {\catcode13=12 \gdef\suiteex#1^^M{% % #1 = titre ‚ventuel \catcode13=5 % restaure le code de ^M \global\advance\exnum by 1 % avance le nø d'exercice \EX{\the\exnum}{#1}}} % annonce l'exercice \def\EX#1#2{% \vskip 0pt % termine le paragraphe (avant chgt marge) \@endmulticol % termine le multicolonnage en cours \@endgroup % ferme le groupe de l'exercice pr‚c‚dent \@filbreak\sv % petit espace vertical \global\exnum=#1% % note le num‚ro d'exercice \global\qqnum=0 % init le nø de question \global\sqnum=96 % init le nø de sous-question \begingroup % isole l'exercice dans un groupe \let\@endgroup=\endgroup % pr‚pare la fin du groupe \advance\leftskip by \numindent % d‚cale la marge \qqmarge=\leftskip % mesure la marge des questions \hskip-\numindent % ‚crit dans la marge {\bf Exercice #1. \sl#2}\par} %---------------------------------------------------------- Nouvelle question \def\qq{% \global\advance\qqnum by 1 % avance le nø de question \QQ{\the\qqnum}} % annonce la question \def\QQ#1{% \vskip 0pt % changer de ligne \leftskip=\qqmarge % remet la marge en place \global\qqnum=#1% % note le num‚ro de question \global\sqnum=96 % init le nø de sous-question \marge{\hbox to\numindent{\hss\bf#1) }}% % ‚crit le nø de question \sqmarge=\leftskip % mesure la marge sous-questions \def\sqpar{\def\sqpar{\vskip 0pt}}% % chgt de ligne diff‚r‚ \ignorespaces } %------------------------------------------------------ Nouvelle sous-question \def \sq{% \global\advance\sqnum by 1 % avance le nø de sous-question \SQ{\the\sqnum}} % annonce la sous-question \def\SQ#1{% \sqpar % changer de ligne \leftskip=\sqmarge % remet la marge en place \global\sqnum=#1% % note le num‚ro de sous-question \marge{\hbox to\numindent{\hss\bf\char#1) }}% ‚crit le nø de sous-question } %-------------------------------------------------------------- Multicolonnage \newcount\@nbcol \def\multicolonne#1{% \@endmulticol % termine le multicolonnage pr‚c‚dent \@nbcol=#1\relax % note le nb de colonnes \ifnum\@nbcol<2 \let\next=\relax % v‚rifie qu'il y a au \else \let\next=\suitemulticol % moins 2 colonnes \fi\next} \def\suitemulticol{% \setbox0=\vbox\bgroup % met en boite tout ce qui suit \advance\hsize by -\leftskip % d‚compte les marges \advance\hsize by -\rightskip \divide\hsize by \@nbcol % largeur d'une colonne \leftskip =\numindent % espace intercolonne \rightskip=0pt % plus de marge droite \let\@endmulticol=\endmulticolonne % pr‚pare la fin } \def\endmulticolonne{% % ici, tout le texte est dans \box0 \vskip 0pt % nouvelle ligne \egroup % referme la boite \dimen0=\ht0 % hauteur totale \divide \dimen0 by \@nbcol % hauteur d'une colonne \loop \multicoupe % d‚coupe en \@nbcol colonnes \ifdim\ht1>0pt % il reste qqch ? \advance\dimen0 by 1pt % alors agrandit les colonnes \repeat \par\nointerlineskip\vskip 2pt % termine la ligne pr‚c‚dente \hskip-\numindent\unhbox2\vskip 0pt % place l'ensemble sans la 1Šre marge } \def\multicoupe{% % d‚coupe \box0 en \@nbcol morceaux \splittopskip=0pt plus 10pt minus 2pt % ressort de d‚coupe \vbadness=10000 % ignore les laideurs ‚ventuelles \setbox1=\vbox{\vskip\splittopskip\unvcopy0}%% l'ajoute dans le 1Šre colonne \setbox2=\hbox{% \loop \setbox3=\vsplit1 to \dimen0 \vtop{\unvbox3}% \advance\@nbcol by -1 \ifnum\@nbcol>0 \repeat}} %------------------------------------------------------- Mat‚riel hors groupe \def\xe{% \vskip 0pt \@endmulticol \@endgroup \filbreak \def\@filbreak{\let\@filbreak=\filbreak}} %+----------------------------------------------------------------------------+ %| R‚f‚rences | %+----------------------------------------------------------------------------+ %--------------------------------------------------------- enregistre un label \def\label#1{% \expandafter\ifx\csname ex#1\endcsname\relax \expandafter\xdef\csname ex#1\endcsname{\the\exnum}% \expandafter\xdef\csname qq#1\endcsname{\the\qqnum}% \expandafter\xdef\csname sq#1\endcsname{\char\the\sqnum}% \else \errmessage{label #1 deja defini (\csname ex#1\endcsname -\csname qq#1\endcsname -\csname sq#1\endcsname)} \fi \ignorespaces} %------------------------------------------------------- ressort une r‚f‚rence \def\ref#1{{% \bf \expandafter\ifx\csname ex#1\endcsname\relax #1 \errmessage{label #1 non defini} \else \expandafter\let\expandafter\exref\csname ex#1\endcsname \expandafter\let\expandafter\qqref\csname qq#1\endcsname \expandafter\let\expandafter\sqref\csname sq#1\endcsname \edef\excur{\number\exnum}% \edef\qqcur{\number\qqnum}% \edef\sqcur{\char\the\sqnum}% \let\t=\relax \let\p=\relax \ifx\excur\exref\else\exref\def\qqcur{0}\def\sqcur{\char 96}\let\t=-\fi \ifx\qqcur\qqref\else\t\qqref\def\sqcur{\char 96}\let\p=)\fi \ifx\sqcur\sqref\else\sqref\let\p=)\fi \p \fi}} %+----------------------------------------------------------------------------+ %| Gestion du fichier r‚ponses | %+----------------------------------------------------------------------------+ \newwrite\@answer \newif\ifanswer\answerfalse % \ifanswer=true s'il y a au moins une r‚ponse \newlinechar=13 % ^M = nouvelle ligne %------------------------------------------- Ecriture dans le fichier answer \def\answerwrite{% \ifanswer\else\openanswer\fi % ouvre le fichier solution \bgroup \inactivespeciaux % d‚sactive les caractŠres sp‚ciaux \catcode 13=12 % y compris ^M \catcode 123=1 % mais pas { \catcode 125=2 % ni } \@answerwrite} % continue avec un argument sans codes sp‚ciaux \def\@answerwrite#1{\immediate\write\@answer{#1}\egroup} % ‚crit ce qui suit \def\openanswer{% % ouvre le fichier solution \immediate\openout\@answer=\jobname.ans \global\answertrue % d‚clare le fichier ouvert \answerwrite{% \noexpand\centerline{\noexpand\bf Solutions}% titre centr‚ \noexpand\sv % espace vertical }} %-------------------------------------------------- Enregistre une r‚ponse \newcount\exnum@ % r‚f‚rences de la derniŠre r‚ponse \newcount\qqnum@ \newcount\sqnum@ \exnum@=0 % pour l'instant, rien \qqnum@=0 \sqnum@=96 \def\reponse{% \ifnum\exnum=\exnum@\else\answerwrite{\noexpand\EX{\the\exnum}{}}\global\qqnum@=0\global\sqnum@=96 \fi \ifnum\qqnum=\qqnum@\else\answerwrite{\noexpand\QQ{\the\qqnum}}\global\sqnum@=96 \fi \ifnum\sqnum=\sqnum@\else\answerwrite{\noexpand\SQ{\the\sqnum}}\fi \global\exnum@=\exnum \global\qqnum@=\qqnum \global\sqnum@=\sqnum \answerwrite} %------------------------------------------------ Intercepte la fin du fichier \def\@exobye{\exobye} \let\exobye=\bye \def\exobye@{% \vfill\supereject % sort la derniŠre page \answerwrite{\noexpand\csname bye\endcsname} % fin des r‚ponses \immediate\closeout\@answer % referme le fichier \let\reponse\undefined % d‚sactive les macros \let\answerwrite\undefined % de r‚ponse \global\answerfalse % et cette branche de \bye \input\jobname.ans\relax % compose les r‚ponses } \outer\def\bye{% \vskip 0pt\@endmulticol\@endgroup % referme le dernier groupe \ifanswer \let\next=\exobye@ % traite les r‚ponses \else \let\next=\@exobye % chaŒne sur l'ancien bye \fi\next} %+----------------------------------------------------------------------------+ %| Termin‚ | %+----------------------------------------------------------------------------+ \catcode64=\active