Retour

Source de encadre.tex

Fichier TeX
%% fichier 'encadre.tex'
% Macros pour encadrement avec gestion des coupures de pages
% ==========================================================
%
% \beginframe ... \endframe{style}      
%
% ===================================================
% ===================================================
\catcode`\@=11
%
\newdimen\framelroffset \framelroffset=.5cm
\newdimen\frametboffset \frametboffset=.5cm
%
\newbox\fr@mebox
\newif\ifcont@
%
% debut d'un encadrement
% ======================
\def\beginframe{%
 \setbox\fr@mebox\vbox\bgroup
}%
%
% fin d'un encadrement
% ====================
\def\endframe#1{% #1 = le style
 \egroup % ferme la boite
 \ifcase#1 % configuration en fonction du style choisi
  %style 0: simple trait de coté
  \def\upperpart@##1{}%
  \let\middlepart@\simpletraitmiddle
  \def\bottompart@##1{}%
  \dimen5=0pt \dimen6=0pt
 \or
  %style 1: semi encadrement simple
  \def\upperpart@##1{}%
  \let\middlepart@\simpletraitmiddle
  \let\bottompart@\semiencadrementsimplebottom
  \dimen5=0pt \dimen6=\frametboffset
 \or
  %style 2: semi encadrement double
  \let\upperpart@=\semiencadrementdoubleupper
  \let\middlepart@=\semiencadrementdoublemiddle
  \let\bottompart@=\semiencadrementdoublebottom
  \dimen5=.4pt \dimen6=\frametboffset
 \or
  %style 3: semi encadrement double double
  \let\upperpart@=\semiencadrementdoubleupper
  \let\middlepart@=\semiencadrementdoublemiddle
  \let\bottompart@=\semiencadrementdoubledoublebottom
  \dimen5=.4pt \dimen6=\frametboffset
 \or
  %style 4: encadrement simple
  \let\upperpart@\encadreupper
  \let\middlepart@\encadremiddle
  \let\bottompart@\encadrebottom
  \dimen5=\frametboffset \dimen6=\frametboffset
 \else % par défaut on ne fait rien
  \def\upperpart@##1{}%
  \def\bottompart@##1{}%
  \def\middlepart@##1{\unvbox##1}%
  \dimen5=0pt \dimen6=0pt
 \fi
 \frameit@ % encadre \fr@mebox
}%
%
% ==============================================
% ==============================================
% chope la hauteur totale d'une boite 
\def\getheight@#1#2{% #1 = numéro de la boite, #2 = numéro du registre \dimen
 \dimen#2=\ht#1
 \advance\dimen#2 by\dp#1
}%
%
% algo qui découpe du mieux qu'il peut la boite en entrée
\def\cutit@{% \dimen1 = max, \fr@mebox=boite à découper
 \getheight@\fr@mebox0
 \ifdim\dimen0<\dimen1 \dimen1=\dimen0 \fi 
 \dimen0=2mm % pas 
 \dimen4=\dimen1 % valeur de départ
 {\vbadness10000 % évite les messages pendant les découpes
 \loop
  \global\setbox0=\copy\fr@mebox
  \global\setbox1=\vsplit0 to \dimen4
  \global\setbox1=\vbox{\unvbox1}% laisse le matos prendre sa taille réelle
  % on continue tant que la première partie est > max, ou que la deuxième est nulle
  % et qu'on peut encore essayer de découper plus petit
  \cont@false  
  \getheight@13
  \ifdim\dimen3 >\dimen1 \cont@true\fi
  \ifvoid0 \cont@true\fi
  \ifdim\dimen4<\dimen0 \cont@false\fi
 \ifcont@
  \advance\dimen4 by -\dimen0
 \repeat}%
 %\setbox1\vbox{\line{\vrule height\ht1 depth 0pt\dotfill\vrule depth\dp1 height 0pt}\vfill}%
 \setbox\fr@mebox\box0 % \fr@mebox = bas, haut = \box1
}%
%
\def\getpageheight@#1{%
 \ifdim\pagegoal=\maxdimen\line{}\fi % pour que TeX calcule \pagegoal !
 \dimen#1=\pagegoal
 \advance\dimen#1 by -\pagedepth
 \advance\dimen#1 by -\topskip
}%
%
% "encadre" la boite \fr@mebox en utilisant \upperpart@, \middlepart@ et \bottompart@
% la hauteur de la partie haute est \dimen5
% la hauteur de la partie basse est \dimen6
\def\frameit@{% 
 %
 \bgroup
 \ifhmode\par\fi% passe en mode vertical
 \dimen9=\wd\fr@mebox
 % calcule la place qu'il reste sur la page
 \getpageheight@1
 \advance\dimen1 by -\pagetotal
 %\advance\dimen1 by \pageshrink
 \ifdim\dimen1<\dimen5 % assez de place pour la première partie ? 
  \eject
  \getpageheight@1
 \fi
 \advance\dimen1 by -\dimen5 % pour pouvoir placer la partie haute
 % 
 \def\middle{% middle pour la première fois, milieu de page
  % teste si la 1ere partie trouvée rentre dans la page
  \getheight@10
  \ifdim\dimen0>\dimen1 % non
   \setbox\fr@mebox=\vbox{\unvbox1\unvbox\fr@mebox}% remet la première partie avec le reste
   \eject
   \getpageheight@1
   \advance\dimen1 by -\dimen5
  \else % oui
   \nointerlineskip
   \upperpart@9 % le dessus
   \middlesecond % la première partie
   \let\middle\middlesecond % change de "routine de sortie"
  \fi
 }% 
 \def\middlesecond{% middle pour le reste (pleine page)
  \ifcont@ % est-ce le dernier bout ?
   \setbox1\vbox to \dimen1{\unvbox1\hrule height 0pt depth 0pt}%
   \nointerlineskip
   \middlepart@1
   \eject
   \getpageheight@1
  \else
   \nointerlineskip
   \middlepart@1
  \fi
 }%
 %
 % découpe jusqu'à ce qu'il ne reste plus rien
 \dimen9=\wd\fr@mebox
 \dimen8=\dimen9
 \loop
  \getheight@\fr@mebox0 
  \advance\dimen0 by \dimen6 
  \ifdim\dimen0>\dimen1 % teste si tout rentre
   \cutit@ % première partie dans \box1, le reste dans \fr@mebox
  \else % oui
   \setbox1\box\fr@mebox 
  \fi
  \ifvoid\fr@mebox\cont@false\else\cont@true\fi % test de sortie du \loop
  \middle % la routine de sortie :-)
 \ifcont@
 \repeat
 %
 \nointerlineskip
 \bottompart@8 % place le bas, et basta!
 \egroup
}%
%
%----------- le style encadrement simple
\def\encadreupper#1{% #1 = numero de \dimen donnant la largeur de la boite
 \advance\dimen#1 by 2\framelroffset % largeur du filet
 \centerline{\vrule depth \dimen5\hbox to\dimen#1{\hrulefill}\vrule}%
}%
%
\def\encadremiddle#1{% #1 = numéro de boite
 \centerline{\vrule\kern\framelroffset\box#1\kern\framelroffset\vrule}%
}%
%
\def\encadrebottom#1{% #1 = numero de \dimen donnant la largeur de la boite
 \advance\dimen#1 by 2\framelroffset % largeur du filet
 \centerline{\vrule height\dimen6\hbox to\dimen#1{\hrulefill}\vrule}%
}%
%----------- le style simple trait de coté 
\def\simpletraitmiddle#1{% #1 = numéro de boite
 \rightline{\hbox to\framelroffset{\vrule height\ht#1 depth\dp#1\hfil}\box#1}%
}%
% ----------- le style semi encadrement simple
\def\semiencadrementsimplebottom#1{% #1 = numéro de \dimen
 \rightline{\hbox to\framelroffset{\vrule height\dimen6\hrulefill}\hbox to.5\dimen#1{\hrulefill}\kern.5\dimen#1}%
}%
%------------ le style semi encadrement double
\def\semiencadrementdoubleupper#1{% #1 = \dimen de la largeur
 \rightline{\hbox to\framelroffset{\hbox to .2\framelroffset{\hrulefill}\hfil}\kern\dimen#1}%
}%
\def\semiencadrementdoublemiddle#1{% #1 = numero de boite
\rightline{\hbox to\framelroffset{\hbox to .2\framelroffset{\vrule height\ht#1 depth \dp#1\hfil\vrule}\hfil}\box#1}%
}%
\def\semiencadrementdoublebottom#1{% #1 = dimen de la largeur
\rightline{\hbox to \framelroffset{\hbox to .2\framelroffset{\vrule height\dimen6\hrulefill\vrule}\hrulefill}\hbox to.5\dimen#1{\hrulefill}\kern.5\dimen#1}%
}%
%------------ le style semi encadrement double double
% un bordel immonde...
\def\semiencadrementdoubledoublebottom#1{% #1 = dimen de la largeur
 \rightline{%
  \vbox{%
   \hbox to .2\framelroffset{\vrule height.8\dimen6\hfil\vrule}%
   \nointerlineskip
   \hbox to .2\framelroffset{\vrule height.2\dimen6\hrulefill}% 
  }%
  \advance\dimen#1 by .8\framelroffset
  \hbox to \dimen#1{\hss
   \advance\dimen#1 by .8\framelroffset
   \vbox to.2\dimen6{\hrule width .5\dimen#1\vfil\hrule}%
   \vrule
   \kern .5\dimen#1\kern-0.8\framelroffset}%
}}%
%
\catcode`\@=12