summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/sttools/flushend.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/sttools/flushend.dtx
Initial commit
Diffstat (limited to 'macros/latex/contrib/sttools/flushend.dtx')
-rw-r--r--macros/latex/contrib/sttools/flushend.dtx1265
1 files changed, 1265 insertions, 0 deletions
diff --git a/macros/latex/contrib/sttools/flushend.dtx b/macros/latex/contrib/sttools/flushend.dtx
new file mode 100644
index 0000000000..2634f02e80
--- /dev/null
+++ b/macros/latex/contrib/sttools/flushend.dtx
@@ -0,0 +1,1265 @@
+% \iffalse meta-comment/*% \end{macrocode}*/
+%
+% Copyright (C) 2017 by Sigitas Tolu\v{s}is <sigitas@vtex.lt>
+% ---------------------------------------------------------------------------
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is Sigitas Tolu\v{s}is.
+%
+% This work consists of the files flushend.dtx and flushend.ins
+% and the derived filebase flushend.sty.
+%
+% \fi
+%
+% \iffalse
+%<*internal>
+\begingroup
+%</internal>
+%<*batchfile>
+\input docstrip.tex
+\keepsilent\askforoverwritefalse
+\nopreamble\nopostamble
+\generate{\file{flushend.sty}{\from{flushend.dtx}{package}}}
+%</batchfile>
+%<batchfile>\endbatchfile
+%<*internal>
+\generate{\file{flushend.ins}{\from{flushend.dtx}{batchfile}}}
+\endgroup
+%</internal>
+%<*driver>
+\ProvidesFile{flushend.dtx}
+%</driver>
+%<*package>
+%% Copyright (C) 1997-2017 by Sigitas Tolu\v{s}is <sigitas@vtex.lt>
+%% VTeX Ltd., Mokslinink\k{u} 2a, Vilnius, Lithuania
+%% http://www.vtex.lt/tex/download/macros/
+%% --------------------------------------------------------------------------
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%% PURPOSE: Balanced columns on last page in twocolumn mode.
+%%
+%</package>
+%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<package>\ProvidesPackage{flushend}
+%<*package>
+ [2017/03/27 v3.3 Balancing columns in twocolumn mode]
+%</package>
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{flushend}[2016/06/21]
+\EnableCrossrefs
+\CodelineIndex
+%%\RecordChanges
+%\OnlyDescription
+\begin{document}
+ \DocInput{flushend.dtx}
+ %%\PrintChanges
+ %%\PrintIndex
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{1855}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+%
+% \changes{v0.1}{1997/05/16}{first version}
+% \changes{v0.2}{1997/09/09}{support for compatibility with cuted.sty}
+% \changes{v1.0}{1997/10/01}{\string\vipersep changed to \string\stripsep for compatibility with cuted.sty}
+% \changes{v1.1}{2012/05/29}{Converted to DTX file}
+% \changes{v2.0}{2014/03/03}{rewritten with new balance algorithm}
+% \changes{v2.1}{2014/03/18}{Switched debug option off}
+% \changes{v2.2}{2014/04/24}{bugfix version: removing empty box at the right column end}
+% \changes{v3.0}{2015/04/08}{bugfix version and extra options:
+% ancient/modern,
+% spread/nospread,
+% removelastbox/keeplastbox}
+% \changes{v3.1}{2015/04/14}{set debug option off by default; keeplastbox modified;}
+% \changes{v3.2}{2016/06/21}{bugfix compatibility with luatexja}
+% \changes{v3.3}{2017/03/27}{bugfix for get@@footnoterule@@box; options for some checks on/off}
+%
+% \DoNotIndex{\newcommand,\newenvironment}
+%
+% \providecommand*{\url}{\texttt}
+% \GetFileInfo{flushend.dtx}
+% \title{The \textsf{flushend} package}
+% \author{Sigitas Tolu\v{s}is \\ \url{sigitas@vtex.lt}}
+% \date{\fileversion~from \filedate}
+%
+% \maketitle
+%
+% \section{Introduction}
+%
+% The package is used to balance columns on any page in twocolumn
+% mode. By default it is switched on at the end of document. It is
+% expected to work with footnotes, top floats and column break
+% before one line section title.
+%
+% \section{Usage}
+%
+% Just load the package to balance the last page: that's all.
+% To balance some page in middle of document use command
+% \cs{flushcolsend} at that page.
+%
+% \medskip
+% \DescribeMacro{\flushend}
+%
+% This macro switches on column balancing on the last page. It is used
+% by default.
+%
+% \medskip
+% \DescribeMacro{\raggedend}
+%
+% This macro switches off column balancing on the last page.
+%
+% \medskip
+% \DescribeMacro{\flushcolsend}
+%
+% This macro switches on column balancing on the current page.
+%
+% \medskip
+% \DescribeMacro{\raggedcolsend}
+%
+% This macro switches off column balancing on the current page.
+%
+% \medskip
+% \DescribeMacro{\atColsBreak}
+% \marg{tokens}
+%
+% Adds \meta{tokens} in place of the original column break (made without balancing).
+%
+% \medskip
+% \textit{Example}: |\atColsBreak{\vskip-2pt}|
+%
+% \medskip
+% \DescribeMacro{\atColsEnd}
+% \marg{tokens}
+%
+% Adds \meta{tokens} at the end of right column.
+%
+% \medskip
+% \textit{Example}: |\atColsEnd{\vfil}|.
+%
+% \medskip
+% \DescribeMacro{\showcolsendrule}
+%
+% It can be used just for debugging: adds rule to the bottom of columns.
+%
+% \subsection{Package options}
+%
+% \medskip
+% \DescribeMacro{ancient}
+% It is used to switch on old version of balancing algorithm.
+% This version is not so accurate or "clever" but quite safe.
+%
+% \medskip
+% \DescribeMacro{modern}
+% [default] It is used to switch on new version of balancing algorithm.
+% This version has some heuristic guesses for footnotes, floats
+% and section like head skip. So it is more dangerous in the case
+% for text misplace or disappear.
+%
+% \medskip
+% \DescribeMacro{autobase}
+% [default] It is used to guess |\baselineskip| value on original columns
+% break. On failure just use |\atColsBreak{...}|.
+%
+% \medskip
+% \DescribeMacro{noautobase}
+% It is used to switch off the previous option behaviour.
+%
+% \medskip
+% \DescribeMacro{spread}
+% [default] It adds extra glue to the rightcolumn trying to balance.
+%
+% \medskip
+% \DescribeMacro{nospread}
+% It skips adding extra glue to the last column.
+%
+% \medskip
+% \DescribeMacro{removelastbox}
+% [default] It tries to remove an empty box (some more material) from the last column bottom.
+%
+% \medskip
+% \DescribeMacro{keeplastbox}
+% It skips removing anything from the last column. As example it is usefull and can be used
+% then document ends by reference item and last line of text should be with indend.
+%
+% \medskip
+% \DescribeMacro{checkfootnote}
+% [default] Adds guess for footnote on left column then modern balancing algorithm is in use.
+%
+% \medskip
+% \DescribeMacro{nocheckfootnote}
+% Skips guess for footnote then modern balansing algorithm is in use.
+%
+% \medskip
+% \DescribeMacro{checkfloat}
+% [default] Adds guess for top float on right column then modern balancing algorithm is in use.
+%
+% \medskip
+% \DescribeMacro{nocheckfloat}
+% Skips guess for top float on right column then modern balancing algorithm is in use.
+%
+% \medskip
+% \DescribeMacro{debug}
+% Adds rules to the bottom of columns (just for debugging) and leftcolumn break place.
+% Adds some additional log info.
+%
+% \medskip
+% \DescribeMacro{nodebug}
+% [default] Skips putting debuging lines.
+%
+% \StopEventually{}
+%
+% \section{Implementation}
+%
+% \iffalse
+%<*package>
+% \fi
+%
+%/*% \begin{macrocode}*/
+% \begin{macrocode}
+\newif\if@auto@baselineskip \@auto@baselineskiptrue
+\newif\if@ancient@balance@version \@ancient@balance@versionfalse
+\newif\if@right@column@spread \@right@column@spreadtrue
+\newif\if@remove@lastbox@at@balancing \@remove@lastbox@at@balancingtrue
+\newif\if@balance@debug \@balance@debugfalse
+\DeclareOption{autobase}{\global\@auto@baselineskiptrue}
+\DeclareOption{noautobase}{\global\@auto@baselineskipfalse}
+\DeclareOption{ancient}{\global\@ancient@balance@versiontrue}
+\DeclareOption{modern}{\global\@ancient@balance@versionfalse}
+\DeclareOption{spread}{\global\@right@column@spreadtrue}
+\DeclareOption{nospread}{\global\@right@column@spreadfalse}
+\DeclareOption{removelastbox}{\global\@remove@lastbox@at@balancingtrue}
+\DeclareOption{keeplastbox}{\global\@remove@lastbox@at@balancingfalse}
+\DeclareOption{checkfootnote}{%
+ \AtEndOfPackage{%
+ \let\check@@footnoterule@@box\initial@check@@footnoterule@@box
+ }%
+ }
+\DeclareOption{nocheckfootnote}{%
+ \AtEndOfPackage{%
+ \let\check@@footnoterule@@box\@gobblethree
+ }%
+ }
+\DeclareOption{checkfloat}{%
+ \AtEndOfPackage{%
+ \let\top@@floatbox@min\top@@floatbox@min@default
+ }%
+ }
+\DeclareOption{nocheckfloat}{%
+ \AtEndOfPackage{%
+ \let\top@@floatbox@min\maxdimen
+ }%
+ }
+\DeclareOption{debug}{\global\@balance@debugtrue}
+\DeclareOption{nodebug}{\global\@balance@debugfalse}
+\ProcessOptions
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newskip\flushend@@lastskip@a
+\newskip\flushend@@lastskip@b
+\newskip\flushend@@lastskip@c
+\newcount\flushend@@penalty@a
+\newdimen\flushend@@lastkern@a
+\newdimen\var@@temp@spread
+\newdimen\var@@temp@a
+\def\top@@skip@@limit{.7\topskip}
+\newdimen\flushend@@page@rule \flushend@@page@rule\z@
+\def\showcolsendrule{\global\flushend@@page@rule=.4\p@}
+% \end{macrocode}
+%
+% \begin{macro}{\top@@floatbox@min}\marg{float size}
+% This value is used to catch possible float on right column top.
+% \begin{macrocode}
+\gdef\top@@floatbox@min@default{4\topskip}
+\let\top@@floatbox@min\top@@floatbox@min@default
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\newbox\flushend@@varbox@a
+\newbox\flushend@@varbox@c
+\newbox\flushend@@tempbox@a
+\newbox\flushend@@tempbox@c
+\@ifundefined{@viper}{\newbox\@viper}{}
+\@ifundefined{hold@viper}{\newbox\hold@viper}{}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\newtoks\atColsBreak \atColsBreak={}
+\newtoks\atColsEnd \atColsEnd={}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@ifundefined{fmt@box@adds}{\def\fmt@box@adds#1{#1}}{}
+\@ifundefined{fmt@vbox@adds}{\def\fmt@vbox@adds[#1]#2{#2}}{}
+% \end{macrocode}
+%
+% \begin{macro}{\remove@lastbox@at@balancing}
+% It is used to remove empty box at the right column end.
+% \begin{macrocode}
+\def\unskip@three@kern@penalty{%
+ \unskip\unkern\unpenalty
+ \unskip\unkern\unpenalty
+ \unskip\unkern\unpenalty
+ }
+\gdef\remove@lastbox@at@balancing{%
+ \unskip@three@kern@penalty
+ \if@remove@lastbox@at@balancing
+ \else
+ \expandafter\null
+ \fi
+ \bgroup
+ \setbox\z@\lastbox
+ \ifdim\wd\z@>\z@
+ \box\z@
+ \else
+ \aftergroup\unskip@three@kern@penalty
+ \fi
+ \egroup
+ }
+\def\set@split@topskip@to#1{%
+ \splittopskip#1\relax \vfuzz\maxdimen \vbadness\maxdimen
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% Macros used in debug mode.
+%
+% \begin{macrocode}
+\def\show@@box#1{%
+ \bgroup
+ \showboxbreadth=20000\showboxdepth=20000%
+ \showbox#1\relax
+ \egroup
+ }
+\def\wlog@balance@debug#1{\if@balance@debug \wlog{#1}\fi}
+\def\log@box@info#1{<box\the#1>(\the\ht#1+\the\dp#1)x\the\wd#1}
+\let\show@@box@next\@gobble
+% \end{macrocode}
+%
+% To get more or less proper result we need to know about footnotes at
+% the left column end, top floats at the right column top, skips and
+% so on. This part of the package is responsible for such analysis.
+%
+% \begin{macrocode}
+\gdef\analyze@lastbox@box#1{%
+ \setbox\flushend@@varbox@a\vbox{%
+ \unvbox#1%
+ \global\flushend@@lastskip@a\lastskip
+ \unskip
+ \global\var@@temp@a\lastkern
+ \unkern
+ \global\flushend@@penalty@a\lastpenalty
+ \unpenalty
+ \ifdim\lastskip>\z@
+ \global\flushend@@lastskip@a\lastskip
+ \fi
+ \unskip
+ \ifdim\lastkern>\z@
+ \global\var@@temp@a\lastkern
+ \fi
+ \unkern
+ \ifnum\lastpenalty>\z@
+ \global\flushend@@penalty@a\lastpenalty
+ \fi
+ \unpenalty
+ \global\setbox\flushend@@tempbox@a\lastbox
+ }%
+ \wlog@balance@debug{^^J::analyze@lastbox@box::\log@box@info{#1}%
+ ^^J ::unvbox: \log@box@info{\flushend@@varbox@a}%
+ ^^J::lastbox: \log@box@info{\flushend@@tempbox@a}%
+ ^^J::lastskip: \the\flushend@@lastskip@a;
+ lastkern: \the\var@@temp@a;
+ lastpenalty: \the\flushend@@penalty@a
+ }%
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\analyze@leftcolumn@box}\marg{box}
+%
+% Fills:
+% \begin{itemize}
+% \item baselineskip skip from the last boxes to |\flushend@@lastskip@c|
+% \item leftcolumn height without the footnote to |\main@box@height|
+% \item footnote skip to |\main@box@skip|
+% \end{itemize}
+%
+% \begin{macrocode}
+\gdef\analyze@leftcolumn@box#1{%
+ \set@split@topskip@to\z@
+ \flushend@@lastskip@b\ht#1%
+ \wlog@balance@debug{^^Jmainbox: \log@box@info{#1}}%
+ \setbox\flushend@@varbox@a\vbox{%
+ \unvbox#1%
+ \global\flushend@@lastskip@a\lastskip
+ \unskip
+ \global\flushend@@lastkern@a\lastkern
+ \unkern
+ \global\flushend@@penalty@a\lastpenalty
+ \unpenalty
+ \global\setbox\flushend@@tempbox@a\lastbox
+ }%
+ \advance\flushend@@lastskip@b -\ht\flushend@@varbox@a
+ \advance\flushend@@lastskip@b -\ht\flushend@@tempbox@a
+ \wlog@balance@debug{.-box: \log@box@info{\flushend@@varbox@a}%
+ ^^J.-lastbox: \log@box@info{\flushend@@tempbox@a}%
+ ^^J.-lastskip: \the\flushend@@lastskip@a;
+ lastkern: \the\flushend@@lastkern@a;
+ lastpenalty: \the\flushend@@penalty@a
+ ^^J.-diff: \the\flushend@@lastskip@b
+ }%
+ \check@@footnoterule@@box\flushend@@tempbox@a\flushend@@lastskip@b\flushend@@varbox@a
+ \check@@baselineskip@@skip
+ \flushend@@lastskip@a
+ \flushend@@lastskip@b
+ \flushend@@lastskip@c
+ \ifx\check@@footnoterule@@box\check@@baselineskip@@skip
+ \else
+ \ifvoid\flushend@@tempbox@a
+ \ifdim\ht\flushend@@varbox@a>\topskip
+ \flushend@@lastskip@b\ht\flushend@@varbox@a
+ \var@@temp@a\ht\flushend@@varbox@a
+ \loop
+ \setbox\flushend@@tempbox@c\vsplit\flushend@@varbox@a to\var@@temp@a
+ \ifvoid\flushend@@varbox@a
+ \setbox\flushend@@varbox@a\vbox{\unvbox\flushend@@tempbox@c}%
+ \advance \var@@temp@a -3\p@
+ \else
+ \var@@temp@a=-1\p@
+ \fi
+ \ifdim \var@@temp@a>\z@
+ \repeat
+ \setbox\flushend@@varbox@a\vbox{\unvbox\flushend@@varbox@a}%
+ \setbox\flushend@@tempbox@c\vbox{\unvbox\flushend@@tempbox@c}%
+ \advance\flushend@@lastskip@b -\ht\flushend@@varbox@a
+ \advance\flushend@@lastskip@b -\ht\flushend@@tempbox@c
+ \wlog@balance@debug{..--box: \log@box@info{\flushend@@tempbox@c}%
+ ^^J..--lastbox: \log@box@info{\flushend@@varbox@a}%
+ ^^J..--diff: \the\flushend@@lastskip@b
+ }%
+ \check@@footnoterule@@box\flushend@@varbox@a\flushend@@lastskip@b
+ \flushend@@tempbox@c
+ \check@@baselineskip@@skip\flushend@@lastskip@a\flushend@@lastskip@b
+ \flushend@@lastskip@c
+ \ifx\check@@footnoterule@@box\check@@baselineskip@@skip
+ \else
+ \ifdim\ht\flushend@@varbox@a>.5\topskip
+ \analyze@lastbox@box\flushend@@varbox@a
+ \fi
+ \setbox\flushend@@varbox@a\vbox{\unvbox\flushend@@tempbox@c}%
+ \fi
+ \else
+ \wlog@balance@debug{lastbox: \log@box@info{\flushend@@varbox@a}}%
+ \fi
+ \fi
+ \ifdim\ht\flushend@@varbox@a>\topskip
+ \expandafter\analyze@leftcolumn@box\expandafter\flushend@@varbox@a
+ \fi
+ \fi
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\get@@footnoterule@@box}
+%
+% Gets dimensions of the box made by |footnoterule| and writes to:
+% |\footnoterule@@box@@ht|, |\footnoterule@@box@@dp|, |\footnoterule@@box@@wd|.
+%
+% \begin{macrocode}
+\def\get@@footnoterule@@box{%
+ \set@split@topskip@to\z@
+ \setbox\flushend@@varbox@a\vbox{\strut
+ \vskip\z@
+ \footnoterule
+ \unskip\unkern\unpenalty
+ \unskip\unkern\unpenalty
+ }%
+ \setbox\flushend@@tempbox@c\vsplit\flushend@@varbox@a to\p@
+ \xdef\footnoterule@@box@@ht{\the\ht\flushend@@varbox@a}%
+ \xdef\footnoterule@@box@@dp{\the\dp\flushend@@varbox@a}%
+ \xdef\footnoterule@@box@@wd{\the\wd\flushend@@varbox@a}%
+ \wlog@balance@debug{:footnoterule: \log@box@info{\flushend@@varbox@a}}%
+ \setbox\flushend@@tempbox@c\vbox{\unvbox\flushend@@varbox@a}%
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\check@@footnoterule@@box}\marg{box1}\marg{skip}\marg{box2}
+%
+% Checks if \marg{box1} dimensions equals to |footnoterule| box dimensions.
+% If so and if \marg{skip} is not |\topskip| we guess it is footnote.
+% In that case we define |leftcolumn| height without |footnote| as
+% \marg{box2} height and save it as |\main@box@height|. Skip from text to
+% footnote define as |\main@box@skip|.
+%
+% \begin{macrocode}
+\long\def\@gobblethree#1#2#3{}
+\def\check@@footnoterule@@box#1#2#3{%
+ \ifdim\ht#1=\footnoterule@@box@@ht
+ \ifdim\dp#1=\footnoterule@@box@@dp
+ \ifdim\wd#1=\footnoterule@@box@@wd
+ \ifdim#2=\topskip
+ \else
+ \xdef\main@box@height{\the\ht#3}%
+ \xdef\main@box@skip{\the#2}%
+ \wlog@balance@debug{^^J:footnoterule found:
+ main@box <ht=\main@box@height,
+ skip=\main@box@skip>
+ }%
+ \global\let\check@@footnoterule@@box\@gobblethree
+ \global\let\check@@baselineskip@@skip\reset@check@@baselineskip@@skip
+ \fi
+ \fi
+ \fi
+ \fi
+ }
+\let\initial@check@@footnoterule@@box\check@@footnoterule@@box
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\check@@baselineskip@@skip}\marg{dimension1}\marg{dimension2}\marg{var}
+%
+% If both dimensions: \marg{dimension1} and \marg{dimension2} are positive we
+% define by \marg{var} value of \marg{dimension1} as last skip between text lines
+% and deactivate |\check@@baselineskip@@skip| itself.
+%
+% \begin{macrocode}
+\def\check@@baselineskip@@skip#1#2#3{%
+ \ifdim#1>\z@
+ \ifdim#2>\z@
+ \global#3=\the#1%
+ \global\let\check@@baselineskip@@skip\@gobblethree
+ \fi
+ \fi
+ }
+\let\initial@check@@baselineskip@@skip\check@@baselineskip@@skip
+% \end{macrocode}
+%
+% In the case we found footnote it is necessary to look for the last skip
+% between text lines again. For that we use
+% |\reset@check@@baselineskip@@skip|. It activates |\check@@baselineskip@@skip|.
+%
+% \begin{macrocode}
+\def\reset@check@@baselineskip@@skip#1#2#3{%
+ \global#3=\z@
+ \global\let\check@@baselineskip@@skip\initial@check@@baselineskip@@skip
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\analyze@rightcolumn@box}\marg{box}
+%
+% Some guess of possible float or section title at the top of right column.\break
+% Fills:
+% \begin{itemize}
+% \item float height to |\top@@floatbox@ht|
+% \item float skip to |\top@@floatbox@skip|
+% \item head skip to |\top@@section@skip|
+% \end{itemize}
+%
+% \begin{macrocode}
+\def\analyze@rightcolumn@box#1{%
+ \bgroup
+ \xdef\top@@floatbox@ht{\z@}%
+ \xdef\top@@floatbox@skip{\z@}%
+ \xdef\top@@section@skip{\z@}%
+ \set@split@topskip@to\z@
+ \setbox\flushend@@varbox@a\vbox{\strut
+ \vskip\z@
+ \unvcopy#1%
+ }%
+ \setbox\flushend@@tempbox@c\vsplit\flushend@@varbox@a to\p@
+ \wlog@balance@debug{^^J(R)mainbox: \log@box@info{#1}}%
+ \flushend@@lastskip@a\ht\flushend@@varbox@a
+ \advance\flushend@@lastskip@a\dp\flushend@@varbox@a
+ \ifdim\flushend@@lastskip@a>\z@
+ \analyze@nonempty@rightcolumn@box
+ \fi
+ \egroup
+ }
+\def\analyze@nonempty@rightcolumn@box{%
+ \bgroup
+ \var@@temp@a3\p@
+ \loop
+ \flushend@@lastskip@b\ht\flushend@@varbox@a
+ \advance\flushend@@lastskip@b\dp\flushend@@varbox@a
+ \setbox\flushend@@tempbox@c\vsplit\flushend@@varbox@a to\var@@temp@a
+ \ifvoid\flushend@@tempbox@c
+ \advance \var@@temp@a 3\p@
+ \ifdim\var@@temp@a>\flushend@@lastskip@b
+ \var@@temp@a=-1\p@
+ \fi
+ \else
+ \setbox\flushend@@tempbox@c\vbox{\unvbox\flushend@@tempbox@c}%
+ \ifdim\ht\flushend@@tempbox@c>\top@@floatbox@min
+ \advance\flushend@@lastskip@b -\ht\flushend@@tempbox@c
+ \advance\flushend@@lastskip@b -\dp\flushend@@tempbox@c
+ \advance\flushend@@lastskip@b -\ht\flushend@@varbox@a
+ \advance\flushend@@lastskip@b -\dp\flushend@@varbox@a
+ \xdef\top@@floatbox@skip{\the\flushend@@lastskip@b}%
+ \flushend@@lastskip@b\flushend@@lastskip@a
+ \advance\flushend@@lastskip@b -\ht\flushend@@varbox@a
+ \advance\flushend@@lastskip@b -\top@@floatbox@skip
+ \xdef\top@@floatbox@ht{\the\flushend@@lastskip@b}%
+ \var@@temp@a=3\p@
+ \else
+ \advance\flushend@@lastskip@b -\ht\flushend@@tempbox@c
+ \advance\flushend@@lastskip@b -\dp\flushend@@tempbox@c
+ \advance\flushend@@lastskip@b -\ht\flushend@@varbox@a
+ \advance\flushend@@lastskip@b -\dp\flushend@@varbox@a
+ \ifdim\ht\flushend@@tempbox@c>\topskip
+ \else
+ \xdef\top@@section@skip{\the\flushend@@lastskip@b}%
+ \fi
+ \var@@temp@a=-1\p@
+ \fi
+ \fi
+ \ifdim \var@@temp@a>\z@
+ \repeat
+ \ifvoid\flushend@@tempbox@c
+ \else
+ \ifdim\top@@section@skip>\z@
+ \else
+ \ifdim\ht\flushend@@tempbox@c>\z@
+ \setbox\flushend@@varbox@a\vbox{\unvbox\flushend@@tempbox@c}%
+ \fi
+ \flushend@@lastskip@b\ht\flushend@@varbox@a
+ \var@@temp@a=3\p@
+ \loop
+ \setbox\flushend@@tempbox@c\vsplit\flushend@@varbox@a to\var@@temp@a
+ \ifvoid\flushend@@tempbox@c
+ \advance \var@@temp@a 3\p@
+ \ifdim\var@@temp@a>\flushend@@lastskip@b
+ \var@@temp@a=-1\p@
+ \fi
+ \else
+ \ifdim\ht\flushend@@tempbox@c<\z@
+ \else
+ \var@@temp@a=-1\p@
+ \fi
+ \fi
+ \ifdim \var@@temp@a>\z@
+ \repeat
+ \loop
+ \setbox\flushend@@varbox@a\vbox{%
+ \unvbox\flushend@@tempbox@c
+ \unskip\unkern\unpenalty
+ \unskip\unkern\unpenalty
+ \unskip\unkern\unpenalty
+ \setbox\flushend@@tempbox@c\lastbox
+ }%
+ \flushend@@lastskip@b\ht\flushend@@varbox@a
+ \setbox\flushend@@varbox@a\vbox{%
+ \unvbox\flushend@@varbox@a
+ \unskip\unkern\unpenalty
+ \unskip\unkern\unpenalty
+ \unskip\unkern\unpenalty
+ }%
+ \advance\flushend@@lastskip@b -\ht\flushend@@varbox@a
+ \ifdim\flushend@@lastskip@b>\topskip
+ \xdef\top@@section@skip{\the\flushend@@lastskip@b}%
+ \fi
+ \ifdim\ht\flushend@@varbox@a>2\topskip
+ \setbox\flushend@@tempbox@c\vbox{\unvbox\flushend@@varbox@a}%
+ \repeat
+ \fi
+ \fi
+ \egroup
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\combine@columns@for@balance}
+%
+% Collects both columns to one box removing left column footnotes
+% and right column top float and adding right skip in between them.
+%
+% \begin{macrocode}
+\def\combine@columns@for@balance{%
+ \setbox\@outputbox\vbox{\strut
+ \vskip\z@
+ \unvbox\@outputbox
+ }%
+ \set@split@topskip@to\z@
+ \setbox\flushend@@tempbox@c\vsplit\@outputbox to\p@
+ \if@auto@baselineskip
+ %% Trying guess baselineskip value on column break
+ \ifdim\top@@floatbox@skip>\z@
+ \setbox\flushend@@tempbox@c\vsplit\@outputbox to\top@@floatbox@ht
+ \setbox\flushend@@tempbox@c\vbox{\unvbox\flushend@@tempbox@c}%
+ \fi
+ \setbox\@tempboxa\vbox{%
+ \unvbox\flushend@@varbox@a
+ \unskip\unkern\unpenalty
+ \vskip\flushend@@lastskip@c
+ \the\atColsBreak
+ \hrule\@height\flushend@@page@rule width\columnwidth
+ \ifdim\top@@section@skip>\top@@skip@@limit
+ \vskip\top@@section@skip
+ \fi
+ \unvbox\@outputbox
+ \remove@lastbox@at@balancing
+ \the\atColsEnd
+ }%
+ \ifdim\top@@floatbox@skip>\z@
+ \setbox\@outputbox\vbox{\unvbox\flushend@@tempbox@c}%
+ \fi
+ \else
+ %% Ignore baselineskip value on column break
+ \setbox\@tempboxa\vbox{%
+ \unvbox\@leftcolumn
+ \setbox\z@\lastbox
+ \unskip\unkern\unpenalty
+ \the\atColsBreak
+ \hrule\@height\flushend@@page@rule width\columnwidth
+ \unvbox\@outputbox
+ \remove@lastbox@at@balancing
+ \the\atColsEnd
+ }%
+ \fi
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\set@outputbox@with@footnote}
+%
+% Calculates break position and formats balanced columns in the |\@outputbox|
+% with footnotes.
+%
+% \begin{macrocode}
+\def\set@outputbox@with@footnote{%
+ %% footnote in left column
+ \@tempdimb\ht\@tempboxa
+ \ifdim\top@@floatbox@skip>\z@
+ \advance\@tempdimb \top@@floatbox@skip
+ \advance\@tempdimb \top@@floatbox@ht
+ \fi
+ \advance\@tempdimb \main@box@skip
+ \advance\@tempdimb \ht\@leftcolumn
+ \@tempdimb .5\@tempdimb
+ \advance\@tempdimb -\main@box@skip
+ \advance\@tempdimb -\ht\@leftcolumn
+ \set@split@topskip@to\topskip
+ \loop
+ \setbox\flushend@@varbox@a\copy\@tempboxa
+ \setbox\flushend@@tempbox@a\vsplit\flushend@@varbox@a to\@tempdimb
+ \setbox\flushend@@tempbox@c\vbox{\unvcopy\flushend@@tempbox@a}%
+ \ifdim\top@@floatbox@skip>\z@
+ \setbox\flushend@@varbox@c\vbox{%
+ \unvcopy\@outputbox
+ \vskip\top@@floatbox@skip
+ \unvbox\flushend@@varbox@a
+ }%
+ \else
+ \setbox\flushend@@varbox@c\vbox{\unvbox\flushend@@varbox@a}%
+ \fi
+ \var@@temp@spread=\ht\flushend@@tempbox@c
+ \advance\var@@temp@spread by\dp\flushend@@tempbox@c
+ \advance\var@@temp@spread \main@box@skip
+ \advance\var@@temp@spread \ht\@leftcolumn
+ \advance\var@@temp@spread by-\ht\flushend@@varbox@c
+ \advance\var@@temp@spread by-\dp\flushend@@varbox@c
+ \wlog@balance@debug{Left x: \the\ht\flushend@@tempbox@a
+ +\the\dp\flushend@@tempbox@a=\the\ht\flushend@@varbox@a
+ +\the\dp\flushend@@varbox@a::\the\@tempdimb
+ ^^JLeft 0: \the\ht\flushend@@tempbox@c
+ +\the\dp\flushend@@tempbox@c::\the\@tempdimb
+ ^^JRight x: \the\ht\flushend@@varbox@c
+ +\the\dp\flushend@@varbox@c=\the\ht\flushend@@varbox@a
+ +\the\dp\flushend@@varbox@a::\the\@tempdimb
+ ^^JExtra height:\the\var@@temp@spread\space when \the\@tempdimb
+ }%
+ \ifdim\var@@temp@spread<\z@
+ \advance\@tempdimb 1\p@
+ \repeat
+ \flushend@@lastskip@a\the\ht\flushend@@tempbox@c
+ \advance\flushend@@lastskip@a \main@box@skip
+ \advance\flushend@@lastskip@a \ht\@leftcolumn
+ \flushend@@lastskip@b\the\@tempdimb
+ \setbox\flushend@@tempbox@a\vsplit\@tempboxa to\@tempdimb
+ \setbox\@leftcolumn\vbox to\@tempdima{%
+ \vbox to \flushend@@lastskip@a{%
+ \unvbox\flushend@@tempbox@a
+ \vskip\main@box@skip
+ \unvbox\@leftcolumn
+ \vss
+ }%
+ \hrule\@height\flushend@@page@rule width\textwidth
+ \vss
+ }%
+ \global\ht\@leftcolumn=\the\@tempdima
+ \wlog{- LAST -%
+ ^^JExtra skip:\the\var@@temp@spread
+ ^^JLeft:\the\ht\@leftcolumn/\the\dp\@leftcolumn
+ ^^JRight:\the\ht\@tempboxa/\the\dp\@tempboxa
+ ^^JOutput:\the\@tempdimb
+ }%
+ \ifdim\top@@floatbox@skip>\z@
+ \setbox\@outputbox\vbox to\@tempdima{%
+ \if@right@column@spread
+ \vbox spread\var@@temp@spread{%
+ \unvbox\@outputbox
+ \vskip\top@@floatbox@skip
+ \unvbox\@tempboxa
+ }%
+ \else
+ \vbox spread\var@@temp@spread{%
+ \unvbox\@outputbox
+ \vskip\top@@floatbox@skip
+ \unvbox\@tempboxa
+ \vss
+ }%
+ \fi
+ \vss
+ }%
+ \else
+ \setbox\@outputbox\vbox to\@tempdima{%
+ \if@right@column@spread
+ \vbox spread\var@@temp@spread{%
+ \unvbox\@tempboxa
+ }%
+ \else
+ \vbox spread\var@@temp@spread{%
+ \unvbox\@tempboxa
+ \vss
+ }%
+ \fi
+ \vss
+ }%
+ \fi
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\set@outputbox@without@footnote}
+%
+% Calculates break position and formats balanced columns in the |\@outputbox|
+% without footnotes.
+%
+% \begin{macrocode}
+\def\set@outputbox@without@footnote{%
+ %% no footnote in left column
+ \@tempdimb \ht\@tempboxa
+ \ifdim\top@@floatbox@skip>\z@
+ \advance\@tempdimb \top@@floatbox@skip
+ \advance\@tempdimb \top@@floatbox@ht
+ \fi
+ \@tempdimb .5\@tempdimb
+ \set@split@topskip@to\topskip
+ \loop
+ \setbox\flushend@@varbox@a\copy\@tempboxa
+ \setbox\flushend@@tempbox@a\vsplit\flushend@@varbox@a to\@tempdimb
+ \setbox\flushend@@tempbox@c\vbox{\unvcopy\flushend@@tempbox@a}%
+ \ifdim\top@@floatbox@skip>\z@
+ \setbox\flushend@@varbox@c\vbox{%
+ \unvcopy\@outputbox
+ \vskip\top@@floatbox@skip
+ \unvbox\flushend@@varbox@a
+ }%
+ \else
+ \setbox\flushend@@varbox@c\vbox{\unvbox\flushend@@varbox@a}%
+ \fi
+ \var@@temp@spread=\ht\flushend@@tempbox@c
+ \advance\var@@temp@spread by\dp\flushend@@tempbox@c
+ \advance\var@@temp@spread by-\ht\flushend@@varbox@c
+ \advance\var@@temp@spread by-\dp\flushend@@varbox@c
+ \wlog@balance@debug{Left x: \the\ht\flushend@@tempbox@a
+ +\the\dp\flushend@@tempbox@a=\the\ht\flushend@@varbox@a
+ +\the\dp\flushend@@varbox@a::\the\@tempdimb
+ ^^JLeft 0: \the\ht\flushend@@tempbox@c
+ +\the\dp\flushend@@tempbox@c::\the\@tempdimb
+ ^^JRight x: \the\ht\flushend@@varbox@c
+ +\the\dp\flushend@@varbox@c=\the\ht\flushend@@varbox@a
+ +\the\dp\flushend@@varbox@a::\the\@tempdimb
+ ^^JExtra height:\the\var@@temp@spread\space when \the\@tempdimb
+ }%
+ \ifdim\var@@temp@spread<\z@ \advance\@tempdimb 1\p@ \repeat
+ \wlog{- LAST -%
+ ^^JExtra skip:\the\var@@temp@spread
+ ^^JLeft:\the\ht\flushend@@tempbox@c/\the\dp\flushend@@tempbox@c
+ ^^JRight:\the\ht\flushend@@varbox@c/\the\dp\flushend@@varbox@c
+ ^^JOutput:\the\@tempdimb
+ }%
+ \setbox\flushend@@tempbox@c\vsplit\@tempboxa to\@tempdimb
+ \setbox\flushend@@varbox@c\vbox{\unvbox\flushend@@tempbox@c}%
+ \setbox\@leftcolumn\vbox to\@tempdima{%
+ \vbox to\@tempdimb{\unvbox\flushend@@varbox@c\vss}%
+ \hrule\@height\flushend@@page@rule width\textwidth
+ \vss
+ }%
+ \global\ht\@leftcolumn=\the\@tempdima
+ \ifdim\top@@floatbox@skip>\z@
+ \setbox\@outputbox\vbox to\@tempdima{%
+ \if@right@column@spread
+ \vbox spread\var@@temp@spread{%
+ \unvbox\@outputbox
+ \vskip\top@@floatbox@skip
+ \unvbox\@tempboxa
+ }%
+ \else
+ \vbox spread\var@@temp@spread{%
+ \unvbox\@outputbox
+ \vskip\top@@floatbox@skip
+ \unvbox\@tempboxa
+ \vss
+ }%
+ \fi
+ \vss
+ }%
+ \else
+ \setbox\@outputbox\vbox to\@tempdima{%
+ \if@right@column@spread
+ \vbox spread\var@@temp@spread{%
+ \unvbox\@tempboxa
+ }%
+ \else
+ \vbox spread\var@@temp@spread{%
+ \unvbox\@tempboxa
+ \vss
+ }%
+ \fi
+ \vss
+ }%
+ \fi
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\last@outputdblcol@modern}
+%
+% Columns balancing of the twocolumn mode page (modern algorithm).
+% It is maybe not so safe for text moving or missing at all
+% as it uses some heuristic technique to find footnotes, last skip between lines
+% at left column and floats or section like heads at right column top
+% for replacing them (except heads of course) to other places in text.
+%
+% \begin{macrocode}
+\def\last@outputdblcol@modern{%
+ \if@firstcolumn
+ \global \@firstcolumnfalse
+ \global \setbox\@leftcolumn \box\@outputbox
+ \else
+ \global \@firstcolumntrue
+ \@tempdima\ht\@leftcolumn
+ \set@split@topskip@to\topskip
+ \var@@temp@spread=\wd\@outputbox
+ \get@@footnoterule@@box
+ \xdef\main@box@height{\the\ht\@leftcolumn}%
+ \xdef\main@box@skip{\z@}%
+ \global\flushend@@lastskip@c\z@
+ \setbox\flushend@@varbox@a\vbox{\unvcopy\@leftcolumn}%
+ \analyze@leftcolumn@box\flushend@@varbox@a
+ \setbox\flushend@@varbox@a\vbox{\unvcopy\@outputbox}%
+ \analyze@rightcolumn@box\flushend@@varbox@a
+ \ifdim\main@box@skip>\z@
+ %% footnote in left column
+ \set@split@topskip@to\z@
+ \setbox\flushend@@varbox@a\vsplit\@leftcolumn to\main@box@height
+ \else
+ %% no footnote in left column
+ \setbox\flushend@@varbox@a\box\@leftcolumn
+ \fi
+ \ifdim\var@@temp@spread>\z@
+ %% rightcolumn non empty
+ \combine@columns@for@balance
+ \else
+ %% rightcolumn empty
+ \setbox\@tempboxa\vbox{%
+ \unvbox\flushend@@varbox@a
+ \remove@lastbox@at@balancing
+ \the\atColsEnd
+ }%
+ \fi
+ \ifdim\main@box@skip>\z@
+ %% footnote in left column
+ \set@outputbox@with@footnote
+ \else
+ %% no footnote in left column
+ \set@outputbox@without@footnote
+ \fi
+ \setbox\@outputbox \vbox {%
+ \hb@xt@\textwidth {%
+ \hb@xt@\columnwidth {%
+ \fmt@box@adds{\box\@leftcolumn}\hss}%
+ \hfil
+ \vrule \@width\columnseprule
+ \hfil
+ \hb@xt@\columnwidth {%
+ \fmt@box@adds{\box\@outputbox}\hss}%
+ }%
+ }%
+ \global\let\@outputdblcol\saved@orig@@outputdblcol
+ \global\atColsEnd{}%
+ \ifvoid\hold@viper
+ \else
+ \setbox\@outputbox\vbox{\box\hold@viper\box\@outputbox}%
+ \fi
+ \@combinedblfloats
+ \@outputpage
+ \begingroup
+ \@dblfloatplacement
+ \@startdblcolumn
+ \@whilesw\if@fcolmade\fi
+ {\@outputpage\@startdblcolumn}%
+ \ifvoid\@viper
+ \else
+ \global\setbox\@viper\vbox{%
+ \vskip-\stripsep
+ \unvbox\@viper
+ }%
+ \csname @viperoutput\endcsname
+ \fi
+ \endgroup
+ \fi
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\last@outputdblcol@old}
+%
+% Columns balancing of the twocolumn mode page (ancient algorithm).
+% It is maybe not so good in some cases but maybe more safe for text
+% moving or missing at all.
+%
+% \begin{macrocode}
+\def\last@outputdblcol@ancient{%
+ \if@firstcolumn
+ \global\@firstcolumnfalse
+ \global\setbox\@leftcolumn\box\@outputbox
+ \else
+ \global\@firstcolumntrue
+ \@tempdima\ht\@leftcolumn
+ \set@split@topskip@to\topskip
+ \if@auto@baselineskip
+ \setbox\@tempboxa\vbox{%
+ \unvcopy\@leftcolumn
+ \global\flushend@@lastskip@c\lastskip
+ \global\flushend@@lastskip@b\lastskip
+ \loop
+ \global\flushend@@lastskip@a\flushend@@lastskip@b
+ \unskip\unpenalty
+ \global\flushend@@lastskip@b\lastskip
+ \global\advance\flushend@@lastskip@c by\lastskip
+ \ifdim\flushend@@lastskip@b=-\flushend@@lastskip@a
+ \global\advance\flushend@@lastskip@c by-\lastskip
+ \else
+ \repeat
+ \ifdim\flushend@@lastskip@b=-\flushend@@lastskip@a
+ \ifdim\flushend@@lastskip@b=\z@
+ \setbox\flushend@@varbox@a\lastbox
+ \global\advance\flushend@@lastskip@c by\ht\flushend@@varbox@a
+ \global\advance\flushend@@lastskip@c by\lastskip
+ \unskip\unpenalty
+ \setbox\flushend@@varbox@a\lastbox
+ \global\advance\flushend@@lastskip@c by\dp\flushend@@varbox@a
+ \else
+ \global\flushend@@lastskip@c\lastskip
+ \global\advance\flushend@@lastskip@c by\topskip
+ \fi
+ \fi
+ \global\advance\flushend@@lastskip@c by-\topskip
+ }%
+ \setbox\@tempboxa\vbox{%
+ \unvbox\@leftcolumn
+ \unskip\unpenalty
+ \vskip\flushend@@lastskip@c
+ \hrule\@height\flushend@@page@rule width\columnwidth
+ \the\atColsBreak
+ \unvbox\@outputbox
+ \remove@lastbox@at@balancing
+ \the\atColsEnd
+ }%
+ \else
+ \setbox\@tempboxa\vbox{%
+ \unvbox\@leftcolumn
+ \setbox\z@\lastbox
+ \unskip
+ \hrule\@height\flushend@@page@rule width\columnwidth
+ \the\atColsBreak
+ \unvbox\@outputbox
+ \remove@lastbox@at@balancing
+ \the\atColsEnd
+ }%
+ \fi
+ \@tempdimb .5\ht\@tempboxa
+ \loop
+ \setbox\flushend@@tempbox@a\copy\@tempboxa
+ \setbox\flushend@@tempbox@c\vbox to\@tempdimb{%
+ \vsplit\flushend@@tempbox@a to\@tempdimb
+ \vss
+ \vsplit\flushend@@tempbox@a to\@tempdimb
+ }%
+ \wlog{Extra height:\the\ht\flushend@@tempbox@a\space when \the\@tempdimb}%
+ \ifvoid\flushend@@tempbox@a
+ \else
+ \advance\@tempdimb 1\p@
+ \repeat
+ \loop
+ \setbox\flushend@@tempbox@a\copy\@tempboxa
+ \setbox\flushend@@tempbox@c\vbox to\@tempdimb{%
+ \vsplit\flushend@@tempbox@a to\@tempdimb
+ \vss
+ }%
+ \wlog{(2)Left:\the\ht\flushend@@tempbox@c\space
+ Right:\the\ht\flushend@@tempbox@a\space
+ Output:\the\@tempdimb
+ }%
+ \ifdim\ht\flushend@@tempbox@c<\ht\flushend@@tempbox@a
+ \@tempdimb=\the\ht\flushend@@tempbox@a
+ \repeat
+ \wlog{- LAST -^^JExtra skip: \the\z@
+ ^^JLeft:\the\ht\flushend@@tempbox@c
+ ^^JRight:\the\ht\flushend@@tempbox@a
+ ^^JOutput:\the\@tempdimb
+ }%
+ \setbox\flushend@@tempbox@c\vbox to\@tempdimb{%
+ \vsplit\@tempboxa to\@tempdimb
+ \vss
+ }%
+ \setbox\@leftcolumn\vbox to\@tempdima{%
+ \fmt@vbox@adds[\columnwidth]{%
+ \vbox to\@tempdimb{%
+ \unvbox
+ \flushend@@tempbox@c
+ }%
+ }%
+ \hrule\@height\flushend@@page@rule
+ \vss
+ }%
+ \setbox\@outputbox\vbox to\@tempdima{%
+ \fmt@vbox@adds[\columnwidth]{%
+ \vbox to\@tempdimb{%
+ \unvbox\@tempboxa
+ \vskip\z@
+ }%
+ }%
+ \hrule\@height\flushend@@page@rule
+ \vss
+ }%
+ \setbox\@outputbox\vbox{%
+ \hb@xt@\textwidth{%
+ \hb@xt@\columnwidth{\box\@leftcolumn\hss}%
+ \hfil
+ \vrule \@width\columnseprule
+ \hfil
+ \hb@xt@\columnwidth{\box\@outputbox\hss}%
+ }%
+ }%
+ \global\let\@outputdblcol\saved@orig@@outputdblcol
+ \global\atColsEnd{}%
+ \ifvoid\hold@viper
+ \else
+ \setbox\@outputbox\vbox{\box\hold@viper\box\@outputbox}%
+ \fi
+ \@combinedblfloats
+ \@outputpage
+ \begingroup
+ \@dblfloatplacement
+ \@startdblcolumn
+ \@whilesw\if@fcolmade\fi
+ {\@outputpage\@startdblcolumn}%
+ \ifvoid\@viper
+ \else
+ \global\setbox\@viper\vbox{%
+ \vskip-\stripsep
+ \unvbox\@viper
+ }%
+ \csname @viperoutput\endcsname
+ \fi
+ \endgroup
+ \fi
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% Adds default balancing of the last page at the end of document.
+%
+% \begin{macrocode}
+\usepackage{etoolbox}
+\AtBeginDocument{%
+ \global\let\saved@orig@@outputdblcol\@outputdblcol
+ \if@ancient@balance@version
+ \global\let\last@outputdblcol\last@outputdblcol@ancient
+ \else
+ \global\let\last@outputdblcol\last@outputdblcol@modern
+ \fi
+ \global\let\balanced@@outputdblcol\last@outputdblcol
+ \preto\enddocument{\let\@outputdblcol\balanced@@outputdblcol}%
+ \appto\footnoterule{\vskip\z@}%
+ }
+% \end{macrocode}
+%
+% User interface commands for the balancing pages.
+%
+% \cs{flushcolsend} is used to switch on column balancing on the current page.
+%
+% \begin{macrocode}
+\def\flushcolsend{\global\let\@outputdblcol\last@outputdblcol}
+% \end{macrocode}
+%
+% \cs{raggedcolsend} is used to switch off column balancing on the current page.
+%
+% \begin{macrocode}
+\def\raggedcolsend{\global\let\@outputdblcol\saved@orig@@outputdblcol}
+% \end{macrocode}
+%
+% \cs{flushend} is used to switch on column balancing on the last page.
+% It is used by default.
+%
+% \begin{macrocode}
+\def\flushend{\global\let\balanced@@outputdblcol\last@outputdblcol}
+% \end{macrocode}
+%
+% \cs{raggedend} is used to switch off column balancing on the last page.
+%
+% \begin{macrocode}
+\def\raggedend{\global\let\balanced@@outputdblcol\saved@orig@@outputdblcol}
+% \end{macrocode}
+%
+% In the case to see some debug information |debug| option is used and it is
+% possible to see how package calculates dimensions of balanced columns by
+% additional rules on balanced page and some log records in log file.
+%
+% \begin{macrocode}
+\if@balance@debug
+ \showcolsendrule
+\fi
+% \end{macrocode}
+%
+% \iffalse
+%</package>
+% \fi
+%
+% \Finale