%% fichier 'listing.tex' % cinquième etape de construction de la macro "listing"~: % la routine de sortie est modifiee (09/09/96), on reecrit totalement % le \input, on stocke dans des \vbox, et on donne le choix du % type de listing pour les coupures de page. % En plus, on reorganise tout ca, de facon a permettre une % macro \partiallisting. \catcode`\@ = 11 % ===== numerotation des lignes \newif \ifwithlinen@ % avec numerotation des lignes~? \withlinen@true % oui par defaut \def \withlineno{% % selection de l'option de numerotation \withlinen@true} % par des macros "visibles" \def \withoutlineno{% \withlinen@false} \def \n@mline{% % affichage du no de ligne \indent \llap{\sevenrm \the\lineno~: \hskip .5em}} \newcount \lineno % no de la ligne courante \newcount \listingno % no de version de la macro (0 = coupure n'importe ou, % 1 = coupure sur ligne vide) \newcount \beginlineno % no de la premiere ligne a afficher \newcount \endlineno % no de la derniere ligne a afficher \def \listingpath{% % le chemin d'acces, vide par defaut } % ===== affectation des caracteres actifs {\obeylines \global \def \temoin{^^M}} % la ligne suivante pose probleme : elle rajoute un caractere dans le % .dvi (?). A noter que c'est pourtant la solution proposee dans le % Lachand-Robert... %%{\obeyspaces\global\let =\ }% % solution de Knuth : voir le fichier info.tex, ligne 41 % ===== la boite pour encadrer le listing ligne par ligne \newbox \encadrbox \def \initencadrbox{% \setbox \encadrbox =\hbox to \hsize{% \vrule height 9pt depth 3pt \hfil \vrule height 9pt depth 3pt} \ht \encadrbox = 0pt \dp \encadrbox = 0pt \wd \encadrbox = 0pt} \newbox \box@ % le titre du listing \newtoks \listingtoks \newread \currentfile % ===== passe en mode verbatim \def \verb@tim{% \def \do##1{% % on prepare le verbatim \catcode`##1=12 }% \def°{% % pas tres propre ca, il s'agit \char23} % d'un truc provisoire pour le "degre" \dospecials \obeyspaces \def \par{% \leavevmode \endgraf}% \obeylines \eightpoint \tt} % style de fonte \def \writelistingline#1{% % #1 contient la ligne a traiter \ifnum \lineno < \beginlineno % qu'on affiche seulement si \else % le no de ligne courante \ifnum \lineno > \endlineno % est dans l'intervalle convenable \else #1 \fi \fi} % ===== traitement d'une ligne du fichier \def \traite@ne{% \ifx \temoin \next % si le 1er caractere est RET \writelistingline{\next} % c'est que la ligne est vide => on l'affiche \ifeof \currentfile % si le fichier n'est pas fini \else % alors on sauvegarde le no de ligne \global \edef \rest@renum{\lineno \the \lineno} \vss \egroup % puis on ferme la boite \mark{\the \listingtoks} \immediate \wlog{*************** \the \listingtoks ******** } \vbox\bgroup % on en ouvre une nouvelle \rest@renum % et on restaure le no de ligne \verb@tim \fi \else % la ligne n'est pas vide \writelistingline{\next} % et on l'affiche telle que \fi} % ===== lecture d'une ligne du fichier \def \read@ne{% % lit la ligne suivante et la \read \currentfile to \next % stocke dans \next \global \advance \lineno by 1 \ifnum \listingno = 1 % suivant le no de version \traite@ne % on fait un traitement adequat \else \writelistingline{\next} % ou on affiche tel que \fi \ifeof \currentfile % si c'est fini, \closein \currentfile % on ferme le fichier \let \next \relax % et on arrete, \else % sinon \let \next \read@ne % on recommence \fi \next} \def \listing#1#2#3{% #1 = version number #2 = file name, #3 = title \partiallisting{#1}{#2}{#3}{0}{10000}} % rque~: 10 000 en attendant mieux . . . \def \partiallisting#1#2#3#4#5{% #1 = version number #2 = file name, #3 = title \bigbreak % #4 = no de la 1ere ligne, #5 = no de la derniere ligne \vskip 2\baselineskip \penalty -200 \vskip -2\baselineskip \listingno = #1 \beginlineno = #4 \endlineno = #5 \immediate \wlog{Beginning listing of \listingpath #2} \initencadrbox \begingroup % DEBUT \offinterlineskip \listingtoks = {\tensl #3} \everypar = {% \hskip -\parindent \copy \encadrbox \strut \ifwithlinen@ \n@mline \else \indent \fi} \parskip = 0pt \lineno = 0 \ifwithlinen@ \parindent = 30pt \else \parindent = 20pt \fi \mark{\the\listingtoks} \ifnum \listingno = 1 % si version 1, on met dans des \vbox \vbox \fi \bgroup % debut du groupe listing \setbox\box@ = \hbox{\tensl #3} % recupere le titre pour en calculer la profondeur \line{% % la 1ere ligne du cadre \vrule height 0.4pt depth \dp\box@ \hrulefill \quad \the \listingtoks \quad \hrulefill \vrule height 0.4pt depth \dp\box@} \hbox to \hsize{% % la ligne vide qui suit \vrule height 9pt depth 3pt \hfil \vrule height 9pt depth 3pt} \verb@tim \openin \currentfile = \listingpath #2 % ici on change le \input \read@ne % et c'est \read@ne qui va lire le fichier \endgraf \nobreak \hbox to \hsize{% % la ligne vide finale \vrule height 9pt depth 0pt \hfil \vrule height 9pt depth 0pt} \hrule % la \hrule de fin de listing \egroup % fin du groupe listing \endgroup % FIN \mark{} % on restaure la marque \immediate \wlog{End listing of #2} \bigbreak}% % puis on modifie la routine de sortie \output = {% \expandafter \listingchek \botmark \end} % c'est une astuce pour lire % la \botmark en argument \def \listingchek#1\end{% \def \next{#1} % % #1 contient la \botmark \ifx \next \empty % % vide => pas de coupure \else % % sinon \setbox255 = \vbox to \vsize{% % on rajoute la ligne \unvbox255 % correspondante a la page \nointerlineskip % deja composee \line{\copy \encadrbox \hfil \strut} \nointerlineskip \hbox to \hsize{% \vsize = 0pt \dotfill}} % \advance \dimen0 by -\prevdepth % % \kern \dimen0 % \line{% \vrule height 0pt depth 2.5pt \dotfill \quad \sl \next % et la ligne (suite) a la \hskip 1em (suite)\quad \dotfill % page suivante \vrule height 0pt depth 2.5pt} \line{\copy \encadrbox \strut \hfill} % avec une ligne vide \fi \plainoutput} % final~: on appelle la routine % % habituelle \catcode`\@ = 12 \endinput