% \iffalse meta-comment/*% \end{macrocode}*/ % % Copyright (C) 2021 by Sigitas Tolu\v{s}is % --------------------------------------------------------------------------- % 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 % %<*batchfile> \input docstrip.tex \keepsilent\askforoverwritefalse \preamble %% %% This is file `flushend.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% flushend.dtx (with options: `package') %% \endpreamble \generate{\file{flushend.sty}{\from{flushend.dtx}{package}}} % %\endbatchfile %<*internal> \generate{\file{flushend.ins}{\from{flushend.dtx}{batchfile}}} \endgroup % %<*driver> \ProvidesFile{flushend.dtx} % %<*package> %% Copyright (C) 1997-2021 by Sigitas Tolu\v{s}is %% UAB VTeX, Mokslininkų 2A, LT-08412 Vilnius, Lithuania %% -------------------------------------------------------------------------- %% 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. %% % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{flushend} %<*package> [2021/10/04 v4.0 Balancing columns in twocolumn mode] % % %<*driver> \documentclass{ltxdoc} \usepackage{flushend}[2021/10/04] \usepackage{geometry} \geometry{a4paper} \setlength\marginparwidth{5pc} \EnableCrossrefs \CodelineIndex %%\RecordChanges \OnlyDescription \begin{document} \DocInput{flushend.dtx} %%\PrintChanges %%\PrintIndex \end{document} % % \fi % % \CheckSum{2020} % % \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} % \changes{v3.4}{2020/10/14}{bugfix development and test} % \changes{v3.5}{2020/10/16}{bugfix version: modern with noautobase} % \changes{v4.0}{2021/10/04}{another rewrite with new balance algorithm and options} % % \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 leftcolumn footnotes (option checkfootnote) % and rightcolumn top floats (option checkfloat). % % To compare with the previous version the package is completely rewritten % with new balancing algorithm and new options, removed dependency on other packages. % % \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 % \leftline{\textbf{\textit{Available commands}}:} % % \begin{description} % % \item[\cs{flushend}] % This macro switches on column balancing on the last page. It is used % by default. % % \item[\cs{raggedend}] % This macro switches off column balancing on the last page. % % \item[\cs{flushcolsend}] % This macro switches on column balancing on the current page. % % \item[\cs{raggedcolsend}] % This macro switches off column balancing on the current page. % % \item[\cs{atColsBreak}\meta{tokens}] % Adds \meta{tokens} in place of the original column break (made without balancing). % % \medskip % \textit{Example}: |\atColsBreak{\vskip-2pt}| % % \item[\cs{atColsEnd}\meta{tokens}] % Adds \meta{tokens} at the end of right column. % % \item[\cs{showcolsendrule}] % It can be used just for debugging: adds rule to the bottom of columns. % % \end{description} % % \subsection{Package options} % % \begin{description} % % \item[\meta{|spread|}] % \texttt{[default]} It enables columns spreading trying to balance. % % \item[\meta{|nospread|}] % It disables columns spreading trying to balance. % % \item[\meta{|shrink|}] % \texttt{[default]} It enables columns shrinking trying to balance. % % \item[\meta{|noshrink|}] % It disables columns shrinking trying to balance. % % \medskip % \textit{Similiar options exist for single column separatly}: % % |lspread|, |nolspread|, |lshrink|, |nolshrink| -- for left column % % |rspread|, |norspread|, |rshrink|, |norshrink| -- for right column % % \item[\meta{|checkfootnote|}] % \texttt{[default]} Adds guess and checking for possible footnote on left column. % % \item[\meta{|nocheckfootnote|}] % Skips guess for possible footnote and ignores any existing one. % % \item[\meta{|checkfloat|}] % Adds guess for top float on right column. Any box with height bigger then 5|\topskip| % is considered as float. There are no user interface to change this limit except % internal macro definition: |\gdef\top@@floatbox@min@default{5\topskip}| % % As guess is too brutal, not accurate, and somehow dangerous in case for text misplacement % it is switched off by default. % % \item[\meta{|nocheckfloat|}] % \texttt{[default]} Skips guess for top float on right column. % % \item[\meta{|debug|}] % Adds rules to the bottom of columns (just for debugging) and leftcolumn break place. % Adds some additional log info. % % \item[\meta{|nodebug|}] % \texttt{[default]} Skips putting debuging lines and additional info. % % \end{description} % % \section{Implementation} % % Improved balancing (at least it is expected so) is based on using possible spread and shrink % in both columns checking constructed columns badness. % Hard coded limit for badness is |101|. Available only as internal macro: |\def\flushend@@column@badness{101}|. % |\pagediscards| material dimensions are used to restore original vertical skip at original columns break. % % \bigskip % \leftline{\textbf{\textit{Expected usecase}} \texttt{(with options [checkfootnote,checkfloat])}:} % % \begin{verbatim} % % -------------------------- -------------------------- % |xxxxxxxxxx ++++++++++| |xxxxxxxxxx ++++++++++| % |xxxxxxxxxx + +| |xxxxxxxxxx + +| % |xxxxxxxxxx + +| |xxxxxxxxxx + +| % |xxxxxxxxxx ++++++++++| |xxxxxxxxxx ++++++++++| % |xxxxxxxxxx figure | |xxxxxxxxxx figure | % | | | | % |section xxxxxxxxxx| |section yyyyyyyyyy| % | xxxxxxxxxx| -----> | yyyyyyyyyy| % |xxxxxxxxxx xxxxxxxxxx| |xxxxxxxxxx xxxxxxxxxx| % |xxxxxxxxxx xxxxxxxxxx| |xxxxxxxxxx xxxxxxxxxx| % |yyyyyyyyyy xxxxxxxxxx| | xxxxxxxxxx| % |yyyyyyyyyy | |--- xxxxxxxxxx| % | | |footnote xxxxxxxxxx| % |--- | | | % |footnote | | | % -------------------------- -------------------------- % % \end{verbatim} % \StopEventually{} % % \iffalse %<*package> % \fi % %/*% \begin{macrocode}*/ % \begin{macrocode} \newif\if@footnote@check \@footnote@checktrue \newif\if@right@column@spread \@right@column@spreadtrue \newif\if@right@column@shrink \@right@column@shrinktrue \newif\if@left@column@spread \@left@column@spreadtrue \newif\if@left@column@shrink \@left@column@shrinktrue \newif\if@balance@debug \@balance@debugfalse \DeclareOption{spread}{% \global\@left@column@spreadtrue \global\@right@column@spreadtrue } \DeclareOption{nospread}{% \global\@left@column@spreadfalse \global\@right@column@spreadfalse } \DeclareOption{lspread}{\global\@left@column@spreadtrue} \DeclareOption{nolspread}{\global\@left@column@spreadfalse} \DeclareOption{rspread}{\global\@right@column@spreadtrue} \DeclareOption{norspread}{\global\@right@column@spreadfalse} \DeclareOption{shrink}{% \global\@left@column@shrinktrue \global\@right@column@shrinktrue } \DeclareOption{noshrink}{% \global\@left@column@shrinkfalse \global\@right@column@shrinkfalse } \DeclareOption{lshrink}{\global\@left@column@shrinktrue} \DeclareOption{nolshrink}{\global\@left@column@shrinkfalse} \DeclareOption{rshrink}{\global\@right@column@shrinktrue} \DeclareOption{norshrink}{\global\@right@column@shrinkfalse} \DeclareOption{checkfootnote}{% \AtEndOfPackage{% \let\check@@footnoterule@@box\initial@check@@footnoterule@@box \@footnote@checktrue }% } \DeclareOption{nocheckfootnote}{% \AtEndOfPackage{% \let\check@@footnoterule@@box\@gobblethree \@footnote@checkfalse }% } \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 \newskip\flushend@@lastskip@a \newskip\flushend@@lastskip@b \newcount\flushend@@lastnode \newcount\var@@loop@iter \newdimen\var@@temp@spread \newdimen\var@@temp@a \newdimen\var@@temp@loop \newdimen\flushend@@page@rule \flushend@@page@rule\z@ \def\showcolsendrule{\global\flushend@@page@rule=.4\p@} \gdef\top@@floatbox@min@default{5\topskip} \let\top@@floatbox@min\maxdimen \def\flushend@@column@badness{101} \newbox\flushend@@varbox@lastpage \newbox\flushend@@varbox@a \newbox\flushend@@varbox@c \newbox\flushend@@tempbox@a \newbox\flushend@@tempbox@c \newbox\flushend@@floatbox \@ifundefined{@viper}{\newbox\@viper}{} \@ifundefined{hold@viper}{\newbox\hold@viper}{} \newtoks\atColsBreak \atColsBreak={} \newtoks\atColsEnd \atColsEnd={} \@ifundefined{fmt@box@adds}{\def\fmt@box@adds#1{#1}}{} \@ifundefined{fmt@vbox@adds}{\def\fmt@vbox@adds[#1]#2{#2}}{} \def\wlog@balance@debug#1{\if@balance@debug \wlog{#1}\fi} \def\log@box@info#1{(\the\ht#1+\the\dp#1)x\the\wd#1} \def\unskip@three@kern@penalty{% \unskip\unkern\unpenalty \unskip\unkern\unpenalty \unskip\unkern\unpenalty } \gdef\remove@empty@lastbox@at@balancing#1{% %% %% Removes lastbox without dimensions. %% Removes latest skip, kern, penalty. %% Cuts the lastbox's depth bigger then strutbox's depth. %% \var@@temp@a=\z@ \setbox\flushend@@tempbox@a\vbox{% \unvcopy#1% \unskip@three@kern@penalty \global\flushend@@lastnode=\lastnodetype }% \setbox#1\vbox{% \unvcopy\flushend@@tempbox@a \setbox\z@\lastbox \ifdim\dimexpr\ht\z@+\dp\z@+\wd\z@\relax>\z@ %% not empty lastbox - store depth of the lastbox \global\var@@temp@a=\dp\z@ \else %% empty lastbox \setbox\z@\box\flushend@@tempbox@a \expandafter\unskip@three@kern@penalty \fi }% \ifvoid\flushend@@tempbox@a\else %% not empty lastbox - restore original \setbox#1\box\flushend@@tempbox@a \fi \ifdim\var@@temp@a>\z@ %% cut the depth of the lastbox with the negative skip \ifdim\var@@temp@a>\dp\strutbox %% it is something more than single line depth \else \setbox#1\vbox{\unvbox#1\vskip-\var@@temp@a}% \fi \fi } \def\set@split@topskip@to#1{% \splittopskip=#1\relax \vfuzz=\maxdimen \vbadness=\maxdimen } \gdef\analyze@leftcolumn@box#1{% %% %% Try to find footnotes on the leftcolumn %% \set@split@topskip@to\z@ \flushend@@lastskip@b\ht#1% \advance\flushend@@lastskip@b\dp#1% \setbox\flushend@@varbox@a\vbox{% \unvbox#1% \global\flushend@@lastskip@a\lastskip \unskip\unkern\unpenalty \global\setbox\flushend@@tempbox@a\lastbox }% \advance\flushend@@lastskip@b -\ht\flushend@@varbox@a \advance\flushend@@lastskip@b -\ht\flushend@@tempbox@a \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 \check@@footnoterule@@box\flushend@@varbox@a\flushend@@lastskip@b \flushend@@tempbox@c \setbox\flushend@@varbox@a\vbox{\unvbox\flushend@@tempbox@c}% \else \global\@footnote@checkfalse \fi \else \check@@footnoterule@@box\flushend@@tempbox@a\flushend@@lastskip@b\flushend@@varbox@a \fi \if@footnote@check \ifdim\var@@temp@loop=\ht\flushend@@varbox@a\relax \global\advance\var@@loop@iter\@ne \fi \var@@temp@loop=\ht\flushend@@varbox@a\relax \ifnum\var@@loop@iter<3\relax %% next iteration \else %% loop limit, break loop \ht\flushend@@varbox@a=\z@ \fi \ifdim\ht\flushend@@varbox@a>\topskip \expandafter\analyze@leftcolumn@box\expandafter\flushend@@varbox@a \fi \fi } \def\get@@footnoterule@@box{% \set@split@topskip@to\z@ \setbox\flushend@@varbox@a\vbox{\strut \vskip\z@ \footnoterule \unskip@three@kern@penalty }% \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}% } \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@depth{\the\dp#3}% \xdef\main@box@skip{\the#2}% \wlog@balance@debug{^^J:footnoterule found: main@box }% \global\let\check@@footnoterule@@box\@gobblethree \global\@footnote@checkfalse \fi \fi \fi \fi } \let\initial@check@@footnoterule@@box\check@@footnoterule@@box \def\analyze@rightcolumn@box#1{% %% %% Looking for the top floats on the right column. %% %% Top box is considered as float if box's height %% is larger then \top@@floatbox@min. %% So, it is a dangerous feature to be used carefully. %% \bgroup \xdef\top@@floatbox@ht{\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@ \flushend@@lastskip@a\ht\flushend@@varbox@a \advance\flushend@@lastskip@a\dp\flushend@@varbox@a \ifdim\flushend@@lastskip@a>\z@ %% analyze non empty rightcolumn box \var@@temp@a=3\p@ \loop \setbox\flushend@@tempbox@c\vsplit\flushend@@varbox@a to\var@@temp@a \flushend@@lastskip@b\ht\flushend@@varbox@a \advance\flushend@@lastskip@b\dp\flushend@@varbox@a \ifvoid\flushend@@tempbox@c \advance\var@@temp@a by3\p@ \ifdim\var@@temp@a>\flushend@@lastskip@b %% reach column end, break loop \var@@temp@a=-1\p@ \fi \else \setbox\flushend@@tempbox@c\vbox{\unvbox\flushend@@tempbox@c}% \ifdim\ht\flushend@@tempbox@c>\top@@floatbox@min %% found float; set height; look for the next \setbox\flushend@@tempbox@a\vbox{\splitdiscards}% \ifvoid\flushend@@tempbox@a \else \advance\flushend@@lastskip@b \ht\flushend@@tempbox@a \advance\flushend@@lastskip@b \dp\flushend@@tempbox@a \fi \advance\flushend@@lastskip@b -\flushend@@lastskip@a \flushend@@lastskip@b=-\flushend@@lastskip@b \xdef\top@@floatbox@ht{\the\flushend@@lastskip@b}% \var@@temp@a=3\p@ \else %% break loop \var@@temp@a=-1\p@ \fi \fi \ifdim \var@@temp@a>\z@ \repeat \fi \egroup } \def\set@outputbox@with@footnote@and@float{% %% %% The main unit formatting balanced columns. %% %% \flushend@@tempbox@a - left column %% \flushend@@tempbox@c - left column with natural dimensions %% \flushend@@varbox@a - right column %% \flushend@@varbox@c - right column with natural dimensions %% \flushend@@floatbox - rightcolumn top float %% \@leftcolumn - void or leftcolumn footnote %% \@tempdimb\ht\flushend@@varbox@lastpage \ifdim\top@@floatbox@ht>\z@ \advance\@tempdimb \textfloatsep \advance\@tempdimb \top@@floatbox@ht \fi \ifdim\main@box@skip>\z@ \advance\@tempdimb \main@box@skip \advance\@tempdimb \ht\@leftcolumn \fi \@tempdimb=.5\@tempdimb \ifdim\@tempdimb>\@colht \@tempdimb=\@colht \fi \ifdim\main@box@skip>\z@ \advance\@tempdimb -\main@box@skip \advance\@tempdimb -\ht\@leftcolumn \fi \set@split@topskip@to\topskip \loop \xdef\saved@tempdimb{\the\@tempdimb}% \setbox\flushend@@varbox@a\copy\flushend@@varbox@lastpage \setbox\flushend@@tempbox@a\vsplit\flushend@@varbox@a to\@tempdimb \ifdim\main@box@skip>\z@ \setbox\flushend@@tempbox@c\vbox{% \unvbox\flushend@@tempbox@a \vskip\main@box@skip \vskip\z@ plus\p@ \unvcopy\@leftcolumn }% \else \setbox\flushend@@tempbox@c\vbox{\unvbox\flushend@@tempbox@a}% \fi \setbox\flushend@@tempbox@a\vbox to\@tempdimb{\unvcopy\flushend@@tempbox@c}% \xdef\var@@leftcolumn@badness{\the\badness}% \ifdim\top@@floatbox@ht>\z@ \setbox\flushend@@varbox@c\vbox{% \unvcopy\flushend@@floatbox \vskip\textfloatsep \vskip\z@ plus\p@ minus\p@ \unvbox\flushend@@varbox@a }% \else \setbox\flushend@@varbox@c\vbox{\unvbox\flushend@@varbox@a}% \fi \setbox\flushend@@varbox@a\vbox to\@tempdimb{\unvcopy\flushend@@varbox@c}% \xdef\var@@rightcolumn@badness{\the\badness}% \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{----- ^^JLeft: \the\ht\flushend@@tempbox@c +\the\dp\flushend@@tempbox@c\space / \var@@leftcolumn@badness ^^JRight: \the\ht\flushend@@varbox@c +\the\dp\flushend@@varbox@c\space / \var@@rightcolumn@badness ^^JSplit: \the\@tempdimb ^^JExtra height: \the\var@@temp@spread }% \ifdim\main@box@skip>\z@ \wlog@balance@debug{Footnote: \the\dimexpr\main@box@skip + \the\ht\@leftcolumn\relax}% \fi \ifdim\top@@floatbox@ht>\z@ \wlog@balance@debug{Float: \the\dimexpr\the\ht\flushend@@floatbox + \textfloatsep\relax}% \fi \ifnum\var@@leftcolumn@badness<\flushend@@column@badness \ifnum\var@@rightcolumn@badness<\flushend@@column@badness \ifdim\main@box@skip>\z@ \advance\@tempdimb -\main@box@skip \advance\@tempdimb -\ht\@leftcolumn \fi \var@@temp@spread=\z@ \fi \fi \ifdim\var@@temp@spread<\z@ \if@left@column@spread \if@right@column@shrink \ifdim\dimexpr\var@@temp@spread+\pageshrink>\z@ \var@@temp@a=\dimexpr\ht\flushend@@tempbox@c-0.5\var@@temp@spread\relax \else \var@@temp@a=-\dimexpr\var@@temp@spread+.5\pageshrink\relax \fi \setbox\flushend@@varbox@a\vbox to\var@@temp@a{\unvcopy\flushend@@tempbox@c}% \ifnum\badness<\flushend@@column@badness \@tempdimb=\var@@temp@a \ifdim\main@box@skip>\z@ \advance\@tempdimb -\main@box@skip \advance\@tempdimb -\ht\@leftcolumn \fi \var@@temp@spread=\z@ \fi \wlog{[leftcolumn badness]: \number\badness\space on \the\var@@temp@a}% \setbox\flushend@@varbox@a\vbox to\var@@temp@a{\unvcopy\flushend@@varbox@c}% \wlog{[rightcolumn badness]: \number\badness\space on \the\var@@temp@a}% \else \setbox\flushend@@varbox@a\vbox to\ht\flushend@@varbox@c{% \unvcopy\flushend@@tempbox@c }% \ifnum\badness<\flushend@@column@badness \@tempdimb=\ht\flushend@@varbox@c \ifdim\main@box@skip>\z@ \advance\@tempdimb -\main@box@skip \advance\@tempdimb -\ht\@leftcolumn \fi \var@@temp@spread=\z@ \fi \wlog{[leftcolumn badness]: \number\badness on \the\ht\flushend@@varbox@c}% \setbox\flushend@@varbox@a\vbox to\ht\flushend@@varbox@c{% \unvcopy\flushend@@varbox@c }% \wlog{[rightcolumn badness]: \number\badness on \the\ht\flushend@@varbox@c}% \fi \else \if@right@column@shrink \ifdim\dimexpr\var@@temp@spread+\pageshrink<\z@ \else \@tempdimb=\ht\flushend@@tempbox@c \ifdim\main@box@skip>\z@ \advance\@tempdimb -\main@box@skip \advance\@tempdimb -\ht\@leftcolumn \fi \var@@temp@spread=\z@ \fi \fi \fi \else \ifdim\var@@temp@spread>\z@ \ifdim\dimexpr\@tempdimb+\p@\relax>\@colht \@tempdimb=\@colht \ifdim\main@box@skip>\z@ \advance\@tempdimb -\main@box@skip \advance\@tempdimb -\ht\@leftcolumn \fi \var@@temp@spread=\z@ \fi \fi \fi \ifdim\var@@temp@spread<\z@ \advance\@tempdimb 1\p@ \repeat %% final construction of the lastpage \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 ^^JSplit: \saved@tempdimb ^^JOutput:\the\@tempdimb ^^JPageshrink: \the\pageshrink ^^JPagestretch: \the\pagestretch ^^J@colht:\the\@colht }% \setbox\flushend@@tempbox@c\vsplit\flushend@@varbox@lastpage to\saved@tempdimb \ifdim\main@box@skip>\z@ \@tempdimb=\dimexpr\@tempdimb+\main@box@skip+\ht\@leftcolumn\relax \setbox\@leftcolumn\vbox to\@tempdimb{% \flushend@@lastskip@a=\dimexpr \@tempdimb -\ht\flushend@@tempbox@c -\main@box@skip -\ht\@leftcolumn \relax \unvbox\flushend@@tempbox@c \vskip\main@box@skip \vskip\z@ plus\p@ \unvbox\@leftcolumn \prevdepth\z@ \hrule\@height\flushend@@page@rule width\textwidth \vskip-\flushend@@page@rule \ifdim\flushend@@lastskip@a>\z@ \if@left@column@spread \else \vss \fi \else \ifdim\flushend@@lastskip@a<\z@ \if@left@column@shrink \else \vss \fi \fi \fi }% \else \setbox\@leftcolumn\vbox to\@tempdimb{% \flushend@@lastskip@a=\dimexpr \@tempdimb-\ht\flushend@@tempbox@c \relax \var@@temp@spread=\dp\flushend@@tempbox@c \unvbox\flushend@@tempbox@c \ifdim\var@@temp@spread>\dp\strutbox \else \vskip-\var@@temp@spread \fi \prevdepth\z@ \hrule\@height\flushend@@page@rule width\textwidth \vskip-\flushend@@page@rule \ifdim\flushend@@lastskip@a>\z@ \if@left@column@spread \else \vss \fi \else \ifdim\flushend@@lastskip@a<\z@ \if@left@column@shrink \else \vss \fi \fi \fi }% \fi \wlog{FLUSHEND [output]: \the\@tempdimb ^^JFLUSHEND [leftcolumn badness]: \number\badness }% \global\ht\@leftcolumn=\the\@tempdima \ifdim\top@@floatbox@ht>\z@ \setbox\@outputbox\vbox to\@tempdimb{% \flushend@@lastskip@a=\dimexpr \@tempdimb -\ht\flushend@@floatbox -\textfloatsep -\ht\flushend@@varbox@lastpage \relax \unvbox\flushend@@floatbox \vskip\textfloatsep \vskip\z@ plus\p@ minus\p@ \unvbox\flushend@@varbox@lastpage \ifdim\flushend@@lastskip@a>\z@ \if@right@column@spread \else \vss \fi \else \ifdim\flushend@@lastskip@a<\z@ \if@right@column@shrink \else \vss \fi \fi \fi }% \else \setbox\@outputbox\vbox to\@tempdimb{% \flushend@@lastskip@a=\dimexpr \@tempdimb-\ht\flushend@@varbox@lastpage \relax \unvbox\flushend@@varbox@lastpage \ifdim\flushend@@lastskip@a>\z@ \if@right@column@spread \else \vss \fi \else \ifdim\flushend@@lastskip@a<\z@ \if@right@column@shrink \else \vss \fi \fi \fi }% \fi \wlog{FUSHEND [rightcolumn badness]: \number\badness}% \global\ht\@outputbox=\the\@tempdima } \newdimen\oldbreak@skip \def\combine@columns@for@balance{% %% %% Combines lastpage columns for balancing. %% \setbox\flushend@@tempbox@a\vbox{\pagediscards}% \oldbreak@skip=\ht\flushend@@tempbox@a \advance\oldbreak@skip by\dp\flushend@@tempbox@a \setbox\@outputbox\vbox{\strut \vskip\z@ \unvbox\@outputbox }% \set@split@topskip@to\z@ %% Removes topskip \setbox\flushend@@tempbox@c\vsplit\@outputbox to\p@ \ifdim\top@@floatbox@ht>\z@ %% removes top float from right column (if option enabled) \setbox\flushend@@floatbox\vsplit\@outputbox to\top@@floatbox@ht \setbox\flushend@@floatbox\vbox{\unvbox\flushend@@floatbox}% \fi \setbox\flushend@@varbox@lastpage\vbox{% \remove@empty@lastbox@at@balancing\flushend@@varbox@a \unvbox\flushend@@varbox@a \hrule\@height\flushend@@page@rule width\columnwidth \vskip-\flushend@@page@rule \hrule\@height\z@ width\columnwidth \penalty\z@ \ifdim\var@@temp@a>\z@ \ifdim\var@@temp@a>\dp\strutbox \else \vskip\var@@temp@a \fi \fi \vskip\oldbreak@skip \the\atColsBreak \remove@empty@lastbox@at@balancing\@outputbox \unvbox\@outputbox \the\atColsEnd }% } \def\last@outputdblcol{% %% %% Redefined \@outputdblcol with columns balancing. %% \if@firstcolumn \global \@firstcolumnfalse \global\setbox\@leftcolumn\copy\@outputbox \splitmaxdepth\maxdimen \vbadness\maxdimen \setbox\@outputbox\vbox{\unvbox\@outputbox\unskip}% \setbox\@outputbox\vsplit\@outputbox to\maxdimen \toks@\expandafter{\topmark}% \xdef\@firstcoltopmark{\the\toks@}% \toks@\expandafter{\splitfirstmark}% \xdef\@firstcolfirstmark{\the\toks@}% \ifx\@firstcolfirstmark\@empty \global\let\@setmarks\relax \else \gdef\@setmarks{% \let\firstmark\@firstcolfirstmark \let\topmark\@firstcoltopmark }% \fi \else \global \@firstcolumntrue \@tempdima\ht\@leftcolumn \advance\@tempdima by\dp\@leftcolumn \set@split@topskip@to\topskip \var@@temp@spread=\wd\@outputbox \xdef\top@@floatbox@ht{\z@}% \xdef\main@box@skip{\z@}% \ifdim\var@@temp@spread>\z@ %% rightcolumn non empty \setbox\flushend@@varbox@a\vbox{\unvcopy\@outputbox}% \ifdim\dimexpr\@colht-\ht\flushend@@varbox@a>\z@\relax \if@footnote@check \get@@footnoterule@@box \xdef\main@box@height{\the\ht\@leftcolumn}% \setbox\flushend@@varbox@a\vbox{\unvcopy\@leftcolumn}% \var@@loop@iter\z@ \var@@temp@loop\z@ \analyze@leftcolumn@box\flushend@@varbox@a \fi \ifdim\top@@floatbox@min<\maxdimen \setbox\flushend@@varbox@a\vbox{\unvcopy\@outputbox}% \var@@loop@iter\z@ \var@@temp@loop\z@ \analyze@rightcolumn@box\flushend@@varbox@a \fi \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 \combine@columns@for@balance \else \xdef\main@box@skip{\maxdimen}% \fi \else %% rightcolumn empty \setbox\flushend@@varbox@a\box\@leftcolumn \setbox\flushend@@varbox@lastpage\vbox{% \remove@empty@lastbox@at@balancing\flushend@@varbox@a \unvbox\flushend@@varbox@a \the\atColsEnd }% \fi \ifdim\main@box@skip<\maxdimen \set@outputbox@with@footnote@and@float \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 \csname @setmarks\endcsname \@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 } \def\initialize@flushend{% %% %% Activates flushend package functionality. %% \global\let\saved@orig@@outputdblcol\@outputdblcol \global\let\balanced@@outputdblcol\last@outputdblcol \edef\enddocument{% \unexpanded{\let\@outputdblcol\balanced@@outputdblcol}% \unexpanded\expandafter{\enddocument}% }% \g@addto@macro\footnoterule{\vskip\z@}% \savingvdiscards=\@ne } \def\flushcolsend{\global\let\@outputdblcol\last@outputdblcol} \def\raggedcolsend{\global\let\@outputdblcol\saved@orig@@outputdblcol} \def\flushend{\global\let\balanced@@outputdblcol\last@outputdblcol} \def\raggedend{\global\let\balanced@@outputdblcol\saved@orig@@outputdblcol} \if@balance@debug \showcolsendrule \fi \AtBeginDocument{\initialize@flushend} % \end{macrocode} % % \iffalse % % \fi % % \Finale