%
% double columns work (hard)
%\check
\edef\catcodeat{\the\catcode`\@}\catcode`\@=11
\newbox\p@artialpage\newbox\r@emainder
\newbox\b@oxzero\newbox\b@oxone\newbox\b@oxtwo\newbox\b@oxthree
\newdimen\c@oldimen
\newdimen\i@nterskip
%
\newdimen\p@ageheight
\newdimen\p@agewidth
\newdimen\p@agework
\newdimen\v@dblesize
%
% pour que \pagetotal et \pagegoal soient initialises... (very dirty trick)
\def\v@oidbox{\hrule height 0pt width 0pt}
\def\b@ottomskip{\vskip 0pt plus 10pt}
\def\dble@safety{0.1}
%
\def\compute@left{\p@agework=\p@ageheight
 \ifvoid\footins\relax\else
   \advance\p@agework by -\ht\footins
   \advance\p@agework by -\skip\footins
 \fi 
 \ifvoid\topins\relax\else
   \advance\p@agework by -\ht\topins
   \advance\p@agework by -\skip\topins
 \fi}%
%
%\check
\def\out@sofar{{\def\pagecontents{\ifvoid\topins\else\unvbox\topins\fi
   \p@agesofar
   \ifvoid\footins\else % footnote info is present
     \vskip\skip\footins
     \footnoterule
     \unvbox\footins
   \fi}\hsize=\p@agewidth\vsize=\p@ageheight
   \givenoutput}}
%\check
%
\def\out@partial{{\def\pagecontents{\ifvoid\topins\else\unvbox\topins\fi
   \unvbox\p@artialpage
   \ifvoid\footins\else % footnote info is present
     \vskip\skip\footins
     \footnoterule
     \unvbox\footins
   \fi}\hsize=\p@agewidth\vsize=\p@ageheight
   \givenoutput}}
%
\def\safe@eject{\vsize=\p@ageheight\pagegoal=4\p@ageheight\eject
  \removelastskip}
%\check
%
\def\begindoublecolumns{\p@ageheight=\vsize\p@agewidth=\hsize
\edef\givenoutput{\the\output}%
\edef\restoretopskip{\noexpand
   \topskip=\the\topskip\noexpand\splittopskip=\the\splittopskip}%
\topskip=\baselineskip\splittopskip=\topskip
\edef\restorebaselineskip{\noexpand\baselineskip=\the\baselineskip
   \noexpand\normallineskip=\the\normallineskip}%
%
% securite : compute available height in \p@agework
 \compute@left
 \advance\p@agework by -2\baselineskip
% if there is a risk, then output 
 \ifdim\pagetotal > \p@agework
   \message{Begindoublecolumns: Pagetotal=\the\pagetotal\ >
   P@agework=\the\p@agework}\relax
   {\splittopskip=\topskip\splitmaxdepth=\maxdepth
   \output{\global\setbox\b@oxone=\vbox{\unvbox255}}\safe@eject
   \global\setbox\p@artialpage=\vsplit\b@oxone to \p@agework}\out@partial
   \unvbox\b@oxone
 \fi
%
 \begingroup\multiply\hyphenpenalty by 2\relax
   \widowpenalty 60\relax
   \clubpenalty 30\relax
   \brokenpenalty 50\relax
   \linepenalty 50\relax
   \output={\global\setbox\p@artialpage=\vbox{\unvbox255}}\relax
   \baselineskip=0pt \normallineskip=0pt    
%   \hrule width 5cm
   \boxmaxdepth=0pt\maxdepth=0pt\relax
   \topskip=0pt\splittopskip=0pt\safe@eject
   \restorebaselineskip
% compute available vertical place in half width into \p@agework   
   \compute@left \advance\p@agework by \p@ageheight % 2\p@ageheight-[inserts]
   \v@oidbox
% compute used vertical place in half width into \c@oldimen    
   \global\c@oldimen=2\ht\p@artialpage
   \global\advance\c@oldimen by -\dble@safety\ht\p@artialpage
   \global\advance\c@oldimen by -\dble@safety\ht\p@artialpage
   \global\advance\c@oldimen by \dble@safety\p@agework
   \v@dblesize=\p@agework
   \advance\v@dblesize by -\c@oldimen
   \ifdim\v@dblesize < \baselineskip
     \message{ P@agework=\the\p@agework, C@oldimen=\the\c@oldimen,
       V@dblesize=\the\v@dblesize}
%     \showthe\v@dblesize
   \fi  
%   
   \output={\doublecolumnout}\hsize=0.49\p@agewidth\vsize=2\p@ageheight
 }% end of \begindoublecolumns
% 
%\check
\def\enddoublecolumns{\removelastskip
 \compute@left\advance\p@agework by \p@ageheight
 \advance\v@dblesize by -2\baselineskip
 \ifdim\pagetotal > \v@dblesize
   \output{\global\setbox\r@emainder=\vbox{\unvbox255}}\safe@eject
   \splittopskip=\topskip\boxmaxdepth=\maxdepth
   \global\setbox255=\vsplit\r@emainder to \v@dblesize
   \doublecolumnout
   \unvbox\r@emainder
 \fi   
 \output={\balancecolumns}\safe@eject
 \endgroup %\leftrule
 \vsize=\p@ageheight
 \v@oidbox
 \pagegoal=2\p@ageheight\penalty 10000\p@agesofar
 \vsize=\p@ageheight
 \v@oidbox\pagegoal=\p@ageheight\par\penalty -2000}%
%
\def\doublecolumnout{\splittopskip=\topskip\splitmaxdepth=\maxdepth
 \vsize=\p@ageheight
 \compute@left
 \advance\p@agework by -\ht\p@artialpage
 \global\c@oldimen=2\p@agework
 \global\setbox\b@oxzero=\vsplit255 to \c@oldimen
 \balanceb@oxzero
 \out@sofar
 \vsize=2\p@ageheight\pagegoal=\vsize
 \unvbox255\restoretopskip
 \vsize=2\p@ageheight\pagegoal=\vsize
 \penalty\outputpenalty
}%
%
\def\p@agesofar{\unvbox\p@artialpage\penalty 10000\relax
 \wd\b@oxzero=\hsize \wd\b@oxtwo=\hsize
 \hbox to \p@agewidth{\vtop{\unvbox\b@oxzero}\hfil\vtop{\unvbox\b@oxtwo}}}
%\check
%
\def\balanceb@oxzero{\global\c@oldimen=\ht\b@oxzero
 \global\advance\c@oldimen by \topskip
 \global\advance\c@oldimen by -\baselineskip
 \global\divide\c@oldimen by 2\relax
 \splittopskip=\topskip\splitmaxdepth=\maxdepth
%
{\vbadness=10000\loop
\global\setbox\b@oxthree=\copy\b@oxzero
\global\setbox\b@oxtwo=\vsplit\b@oxthree to \c@oldimen
\global\setbox\b@oxone=\vbox{\unvbox\b@oxtwo}%
\p@agework=\ht\b@oxthree
\advance\p@agework by -\ht\b@oxone
\ifdim\p@agework > \baselineskip
 \global\advance\c@oldimen by 0.2\p@agework
% \message{ C@oldimen +1:\the\c@oldimen, \the\p@agework}
\repeat}\relax
%
{\vbadness=10000\loop
\global\setbox\b@oxthree=\copy\b@oxzero
\global\setbox\b@oxtwo=\vsplit\b@oxthree to \c@oldimen
\global\setbox\b@oxone=\vbox{\unvbox\b@oxtwo}%
\p@agework=\ht\b@oxthree
\advance\p@agework by -\ht\b@oxone
\ifdim\p@agework < -\baselineskip
 \global\advance\c@oldimen by 0.2\p@agework
% \message{ C@oldimen -1:\the\c@oldimen, \the\p@agework}
\repeat}\relax
%
\p@agework=\ht\b@oxthree
\advance\p@agework by -\ht\b@oxone
\ifdim\p@agework > \baselineskip
  \message{SPLIT: p.\the\count0, P@gework: \the\p@agework}\relax
  \i@nterskip=\baselineskip
  \global\setbox\b@oxtwo=\hbox{\rm W}\advance\i@nterskip by -\ht\b@oxtwo
  \global\setbox\b@oxtwo=\vsplit\b@oxthree to 0.5\p@agework
\else
  \i@nterskip=\topskip
\fi
\global\setbox\b@oxzero=\vbox to \c@oldimen{\unvbox\b@oxone
 \vskip\i@nterskip \unvbox\b@oxtwo\b@ottomskip}%
\global\setbox\b@oxtwo=\vbox to \c@oldimen{\unvbox\b@oxthree\b@ottomskip}%
}%
%
\def\balancecolumns{\global\setbox\b@oxzero=\vbox{\unvbox255}\balanceb@oxzero
}%
%\check
%
\def\leftrule{\removelastskip\par\kern -5pt\hbox{\vrule width 0.49\hsize height 0.4pt
\vrule height 6pt}\medskip}
\def\rightrule{\medskip\rightline{\vrule depth 5.6pt height 0.4pt width 0.4pt
\vrule width 0.49\hsize height 0.4pt depth 0pt}\kern -5pt\par}
\catcode`\@=\catcodeat
%

