% BICOLONN.TEX : Macros de mise en page sur 2 colonnes
% M.Quercia 08/07/94

\newbox\partialpage                  % d�but de la page en monocolonne
\newtoks\oldoutput                   % sauvegarde routine de sortie
\newdimen\oldhsize                   % sauvegarde \hsize
\newdimen\oldvsize                   % sauvegarde \vsize
\newskip\oldleftskip                 % sauvegarde marge gauche
\newskip\oldrightskip                % sauvegarde marge gauche

            %+---------------------------------------------+
            %|  code � intercaler entre les deux colonnes  |
            %+---------------------------------------------+

\def\doublesep{\hskip2.5mm\vrule\hskip2.5mm}

                  %+----------------------------------+
                  %|  D�marre le mode double colonne  |
                  %+----------------------------------+

\def\begindoublecolonnes{%
  \begingroup                           % gr. referm� � la fin du double colonnage
  %
  \oldoutput=\output                    % sauvegarde les param�tres mono colonne
  \oldhsize=\hsize
  \oldvsize=\vsize
  \oldleftskip=\leftskip
  \oldrightskip=\rightskip
  %
  \setbox\partialpage=\hbox{\doublesep}%% mesure l'espace intercolonne
  \advance\hsize by -\wd\partialpage    % calcule la largeur utile des colonnes
  \advance\hsize by -\leftskip
  \advance\hsize by -\rightskip
  \divide\hsize by 2
  %
  \output={\doubledebut}%               % fait sortir ce qui est d�j� compos�
  \eject                                % dans \partialpage
  %
  \multiply\vsize by 2                  % majore la hauteur � viser
  \advance\vsize by 5mm
  \pagegoal=\vsize
  \leftskip=0pt                         % r�initialise les marges
  \rightskip=0pt
  \output={\doublemilieu}}              % nouvelle routine de sortie

%
%  R�cup�re le texte mono colonne dans \partialpage
%
\def\doubledebut{%
  \global\setbox\partialpage=\vbox{\unvbox255\bigskip}}

%
% Sort une page en double colonne
%
\def\doublemilieu{%
  \setbox255=\vbox{\unvbox255}%  % �limine le \vfil de bas de page
  \doublecoupe                   % coupe en deux colonnes
  \doubleeject                   % les fait sortir
  \unvbox255                     % renvoie � TeX le suppl�ment non sorti
  \penalty\outputpenalty}        % restaure la p�nalit� de d�but de liste

                  %+---------------------------------+
                  %|  Arr�te le mode double colonne  |
                  %+---------------------------------+

\def\enddoublecolonnes{%
  \output={\doublefin}%                 % r�cup�re la fin des colonnes et
  \eject                                % la coupe en deux
  \endgroup}                            % restaure les r�glages mono colonne

%
% R�cup�re la fin des colonnes et la coupe en deux
%
\def\doublefin{%
  \setbox255=\vbox{\unvbox255}%         % �limine le \vfil de bas de page
  \loop
     \doublecoupe                       % coupe en deux colonnes
  \ifdim\ht255>0pt                      % si une page est compl�te,
     \doubleeject                       % la sort
  \repeat                               % coupe en deux ce qui reste
  \unvbox\partialpage\bigskip}          % repasse � TeX tout ce qui n'est pas sorti


                    %+-----------------------------+
                    %|  Coupe une colonne en deux  |
                    %+-----------------------------+

\def\doublecoupe{%
  %
  \splittopskip=\topskip               % r�glage des ciseaux
  \splitmaxdepth=\maxdepth
  %
  \dimen0=\oldvsize                    % calcule la hauteur o� couper
  \advance\dimen0 by -\ht\partialpage
  %
  \ifdim\dimen0>0.5\ht255              % est-ce qu'on a assez de mat�riel ?
         \doubleequilibre              % non : constitue des petites colonnes
  \else  \setbox0=\vsplit255 to\dimen0 % oui : alors on coupe
         \setbox1=\vsplit255 to\dimen0
  \fi
  \wd0=\hsize                          % rectifie les largeurs des colonnes
  \wd1=\hsize
  %
  \setbox\partialpage=\vbox{%          % assemble le haut et les deux colonnes
    \offinterlineskip                  % ajustement exact
    \unvbox\partialpage                % voici le haut
    \hbox{%
      \hskip\oldleftskip               % la marge gauche
      \box0                            % la colonne gauche
      \doublesep                       % l'espace intercolonne
      \box1                            % la colonne droite
      \hskip\oldrightskip              % la marge droite
      \hss                             % compense les erreurs de largeur
      }}}



%
% Cas o� il n'y a pas assez de mat�riel pour constituer une page :
% Ici, il faut couper au milieu en t�chant d'avoir des colonnes de m�me hauteur
%
\def\doubleequilibre{%
  \vbadness=10000                      % ignore les laideurs �ventuelles
  \dimen0=0.5\ht255                    % vise le milieu exact
  \loop
    \setbox1=\vbox{\unvcopy255}%       % on prend la boite,
    \setbox0=\vsplit1 to \dimen0       % et on la coupe
  \ifdim\ht1<\ht0                      % si b.droite est trop petite,
    \advance\dimen0 -1pt               % remonte les ciseaux
  \repeat                              % et recommence
  %
  %   Maintenant, b.droite est l�g�rement plus haute que b.gauche
  %
  \loop
  \ifdim\ht1>\ht0
    \advance\dimen0 1pt                % rabaisse les ciseaux
    \setbox1=\vbox{\unvcopy255}%       % et recoupe
    \setbox0=\vsplit1 to \dimen0
  \repeat
  %
  %  Maintenant, b.droite est l�g�rement inf�rieure ou �gale � b.gauche
  %  (et on ne peut pas faire mieux que �a, avec une r�solution de 1pt
  %   sur la position des ciseaux)
  %
  \setbox1=\vbox to \ht0{\unvbox1\vss}%  % ajuste la hauteur de b.droite
  \setbox255=\vbox to 0pt{}}             % vide la boite initiale


               %+---------------------------------------+
               %|  Fait sortir les pages en bi colonne  |
               %+---------------------------------------+

\def\doubleeject{%
  \bgroup
     \setbox255=\vbox{\unvbox\partialpage}%  % met la page dans b255
     \hsize=\oldhsize                        % restaure les r�glages monocolonne
     \vsize=\oldvsize
     \the\oldoutput                          % routine de sortie mono colonne
  \egroup
  \setbox\partialpage=\vbox to 0pt{}}        % vide la page sortie
