% Fichier PB.MAC %+----------------------------------------------------------------------------+ %| Macros pour un texte de problŠme : 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\pbcharge\undefined\let\next\relax\else\let\next\endinput\fi\next \def\pbcharge{PB 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 | %+----------------------------------------------------------------------------+ % \pnum : num‚ro de la partie 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 \newdimen\numindent \newcount\qqnum \newdimen\qqmarge \newcount\sqnum \newdimen\sqmarge \def\pnum{} \qqnum=0 \sqnum=96 % a = \char97 \numindent=5mm \let\@endgroup=\relax % pas encore d'exercice \let\@endmulticol=\relax % pas de multicolonnage %---------------------------------------------------------- Nouvelle partie \def\partie{\catcode13=12\relax\suitepartie} % accepte ^M comme d‚limiteur {\catcode13=12 \gdef\suitepartie#1#2^^M{% % #1 = num‚ro de partie, #2 = titre \catcode13=5 % restaure le code de ^M \xdef\pnum{#1}% % note le num‚ro de partie \vskip 0pt % termine le paragraphe (avant chgt marge) \@endmulticol % termine le multicolonnage en cours \@endgroup % ferme le groupe de la partie pr‚c‚dente \SV % petit espace vertical \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 \leftskip=0pt% % restaure la marge \qqmarge=0pt% % pas de marge pour les question% \centerline{\bf#2}\sv}} % titre centr‚ en gras %---------------------------------------------------------- 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\endpartie{% \vskip 0pt \@endmulticol \@endgroup} %+----------------------------------------------------------------------------+ %| R‚f‚rences | %+----------------------------------------------------------------------------+ %--------------------------------------------------------- enregistre un label \def\label#1{% \expandafter\ifx\csname p#1\endcsname\relax \expandafter\xdef\csname p#1\endcsname{\pnum}% \expandafter\xdef\csname qq#1\endcsname{\the\qqnum}% \expandafter\xdef\csname sq#1\endcsname{\char\the\sqnum}% \else \errmessage{label #1 deja defini (\csname p#1\endcsname -\csname qq#1\endcsname -\csname sq#1\endcsname)} \fi \ignorespaces} %------------------------------------------------------- ressort une r‚f‚rence \def\ref#1{{% \bf \expandafter\ifx\csname p#1\endcsname\relax #1 \errmessage{label #1 non defini} \else \expandafter\let\expandafter\pref\csname p#1\endcsname \expandafter\let\expandafter\qqref\csname qq#1\endcsname \expandafter\let\expandafter\sqref\csname sq#1\endcsname \edef\pcur{\pnum}% \edef\qqcur{\number\qqnum}% \edef\sqcur{\char\the\sqnum}% \let\t=\relax \let\p=\relax \ifx\pcur\pref\else\pref\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 Corrig\'e}% titre centr‚ \noexpand\sv % espace vertical }} %-------------------------------------------------- Enregistre une r‚ponse % r‚f‚rences de la derniŠre r‚ponse \newcount\qqnum@ \newcount\sqnum@ \def\pnum@{} % pour l'instant, rien \qqnum@=0 \sqnum@=96 \def\reponse{% \ifx\pnum\pnum@\else\answerwrite{\noexpand\partie{\pnum}{\pnum}}\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\let\pnum@=\pnum \global\qqnum@=\qqnum \global\sqnum@=\sqnum \answerwrite} %------------------------------------------------ Intercepte la fin du fichier \def\@pbbye{\pbbye} \let\pbbye=\bye \def\pbbye@{% \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=\pbbye@ % traite les r‚ponses \else \let\next=\@pbbye % chaŒne sur l'ancien bye \fi\next} %+----------------------------------------------------------------------------+ %| Termin‚ | %+----------------------------------------------------------------------------+ \catcode64=\active