summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/pbalance/pbalance.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/pbalance/pbalance.dtx')
-rw-r--r--macros/latex/contrib/pbalance/pbalance.dtx559
1 files changed, 462 insertions, 97 deletions
diff --git a/macros/latex/contrib/pbalance/pbalance.dtx b/macros/latex/contrib/pbalance/pbalance.dtx
index b5712f00c6..a426a6366a 100644
--- a/macros/latex/contrib/pbalance/pbalance.dtx
+++ b/macros/latex/contrib/pbalance/pbalance.dtx
@@ -15,7 +15,7 @@
% \iffalse
%
%<package>\NeedsTeXFormat{LaTeX2e}[2015/01/01]
-%<package>\ProvidesPackage{pbalance}[2022/06/22 v1.3.0 Poor man's balance]
+%<package>\ProvidesPackage{pbalance}[2022/07/28 v1.4.0 Poor man's balance]
%
%<*driver>
@@ -70,6 +70,15 @@
% \changes{v1.2.0}{2022/06/20}{Compatibility with \texttt{lineno} pkg}
% \changes{v1.2.1}{2022/06/21}{Better error handling}
% \changes{v1.3.0}{2022/06/22}{Compatibility with \texttt{stfloats} pkg}
+% \changes{v1.4.0}{2022/07/28}{Fix bug when switching single/double cols}
+% \changes{v1.4.0}{2022/07/28}{Add alternatives and troubleshooting
+% sections to the docs}
+% \changes{v1.4.0}{2022/07/28}{Create \texttt{\textbackslash{}balancePageNum}
+% and \texttt{\textbackslash{}nopbalance}
+% commands}
+% \changes{v1.4.0}{2022/07/28}{Fix bug: detect float pages correctly}
+% \changes{v1.4.0}{2022/07/28}{Compatibility with memoir, footmisc, ftnright,
+% flafter, fnpos, midfloat, and cuted}
%
% \GetFileInfo{pbalance.sty}
%
@@ -132,31 +141,49 @@
% need one additional \LaTeX{} pass will likely demand three. If you load
% the package with the \verb|draft| option (or pass the \verb|draft|
% option to the document class), balancing is disabled, alleviating the
-% need for extra passes during document preparation.
-%
-% If the last page does not have floats, footnotes, or marginpars, the
-% package simply uses \verb|\balance|, from the \texttt{balance} package,
-% otherwise it uses its own algorithm. If that fails for some reason, you
-% may add the \verb|safe| option to the package, which makes the code
-% never use (or even load) the \texttt{balance} package. You may also use
+% need for extra passes during document preparation. You may also use
% \verb|\shrinkLastPage{some-measurement}| to manually define how much
% shorter the first column of the last page should be instead of letting
-% the package determine the amount. This, however, will not eliminate the
-% need for extra passes (the package needs to find out which \mbox{page is
-% the last).}\looseness=1
+% the package determine the amount and \verb|\balancePageNum{page-number}|
+% to force balancing a specific page (note that this is the \textit{physical}
+% page number). These options, however, will not eliminate the need
+% for extra passes. Finally, you may disable processing by calling
+% \verb|\nopbalance| (useful if a class preloaded the package, for example).
%
-% The package actually balances the last \emph{text} page; if the last
-% page is a float page, it is ignored. It also \emph{should} work if you
-% switch to single-column mode mid-document (with \verb|\onecolumn|); it
-% will then balance the last two-column text page. The same should happen
-% in a document that is mainly typeset in one column and you switch to
-% two-column layout (with \verb|\twocolumn|), but \emph{only} if the page
-% to be balanced does \emph{not} contain the \verb|\twocolumn| command.
+% \section{Troubleshooting and fine tuning}
+%
+% \texttt{pbalance} should never generate defective output or cause an
+% error; if it does, please try passing the \texttt{safe} option to the
+% package and submit a bug report with a MWE. Other than that, three
+% things may go wrong when using \texttt{pbalance}:
+%
+% \begin{enumerate}
+% \item The final result may be ``ugly'';
+% \item \texttt{pbalance} may give up and produce an unbalanced last page;
+% \item Some other package may prevent \texttt{pbalance} from working.
+% \end{enumerate}
+%
+% \subsection{The final result is ``ugly''}
+%
+% If you find the results unsatisfactory, there are two things you may try:
+%
+% \begin{itemize}
+% \item Change the layout: apply \verb|\looseness| to a paragraph, move
+% where floats are defined\footnote{Remember that, in two-column
+% mode, dblfloats should be defined before the place you expect
+% them to appear; see the docs for the \texttt{stfloats} package.}
+% or change their sizes, etc.;
+% \item Use \verb|\shrinkLastPage| and \verb|\balancePageNum| to manually
+% define the size of the left column and the page to balance.
+% \end{itemize}
+%
+% \subsection{\texttt{pbalance} gave up}
%
-% If there are many floats near the end of the document, the \LaTeX{}
-% float placement parameters (\verb|\topfraction|, \verb|topnumber|,
-% etc.) may interfere negatively with the algorithm. In some rare
-% cases\footnote{For example, imagine a document in which page 5 is
+% This should happen very rarely, but \texttt{pbalance} may sometimes
+% generate the warning ``\texttt{Could not balance, doing nothing}''
+% (the document is still generated correctly in this case), which means
+% the package algorithm failed to find a suitable solution to do its
+% thing\footnote{For example, imagine a document in which page 5 is
% a float page that happens to be the last one. We will balance page
% 4, which is the last text page. Balancing page 4 may move a float
% from the left to the right column, but this may in turn exceed the
@@ -166,10 +193,11 @@
% that just opened up in page 4. Depending on the size of this float,
% the text may no longer fit in page 4, making some text spill onto
% page 5. This means page 5 is now the last text page and should then
-% be balanced instead of page 4. Oops!}, this may force the package
-% to give up on balancing (the document is still generated correctly
-% in this case). To minimize the chances of this outcome, it is
-% probably a good idea to make the parameters a little more liberal
+% be balanced instead of page 4. Oops!\looseness=-1}. This problem is
+% amenable to the same mitigation strategies discussed in the previous
+% section. However, if there are many floats near the end of the document,
+% you should also consider making the \LaTeX{} float placement parameters
+% (\verb|\topfraction|, \verb|topnumber|, etc.) a little more liberal
% than the default, for example:\looseness=-1
%
% \begin{verbatim}
@@ -180,6 +208,64 @@
%\renewcommand{\floatpagefraction}{.75} % default .5, must be < \topfraction
% \end{verbatim}
%
+% \subsection{Patching failed due to another package}
+%^^A TODO: list all other packages in a comment
+%
+% If \texttt{pbalance} yields the warning ``\texttt{Patching failed, cannot
+% balance; try \mbox{loading} pbalance earlier or later}'', there is some
+% incompatibility with another package. Since \texttt{pbalance} modifies
+% the internal \LaTeX{} macros \verb|\@outputdblcol|, \verb|\@addtocurcol|,
+% \verb|\@makecol|, and \verb|\@addmarginpar|, there may be problems with
+% other packages that do the same; thankfully, not many packages do. For
+% some of them (such as \texttt{stfloats}), \texttt{pbalance} includes code
+% to circumvent any problems; for others, your best bet is to change the
+% order in which the packages are loaded (in general, \texttt{pbalance}
+% prefers to go last).\looseness=-1
+%
+% \subsection{Some details you normally do not need to consider}
+%
+% The package actually balances the last \emph{text} page; if the last
+% page is a float page, it is ignored. It also \emph{should} work if you
+% switch to single-column mode mid-document (with \verb|\onecolumn|); it
+% will then balance the last two-column text page. The same should happen
+% in a document that is mainly typeset in one column and you switch to
+% two-column layout (with \verb|\twocolumn|), but \emph{only} if the page
+% to be balanced does \emph{not} contain the \verb|\twocolumn| command
+% (i.e., there are at least two consecutive two-column text pages).
+%
+% If the last page does not have floats, footnotes, or marginpars, the
+% package simply uses \verb|\balance|, from the \texttt{balance} package,
+% otherwise it uses its own algorithm. If that fails for some reason, you
+% may add the \verb|safe| option to the package, which makes the code
+% never use (or even load) the \texttt{balance} package.
+%
+% \section{Other options}
+%
+% There are other approaches to balancing that may be better suited to your
+% needs. Beyond the already mentioned \texttt{balance} and \texttt{flushend}
+% packages, I am aware of:
+%
+% \begin{itemize}
+% \item The \texttt{multicol} package, which allows the user to freely
+% switch between one- and multi-column layouts. The only drawback
+% of the package is that it cannot handle ordinary floats, only
+% dblfloats (\verb|\begin{figure*}|, \verb|\begin{table*}|);
+% \item The \texttt{ltxgrid} package, which allows the user to freely
+% switch between one- and two-column layouts but, differently from
+% \texttt{multicol}, works even in the presence of floats. With it,
+% switching from two columns to one balances the previous output
+% (its main disadvantage is that it may have compatibility problems
+% with other packages);
+% \item The \texttt{revtex} class, for which \texttt{ltxgrid} was
+% developed;
+% \item The \verb|\IEEEtriggeratref{}| macro from the \texttt{IEEEtran}
+% class, which allows you to attach arbitrary code (such as
+% \verb|\newpage|) to a specific entry in a bibliography listing;
+% \looseness=-1
+% \item The code suggested at \url{https://tex.stackexchange.com/a/583228/},
+% similar to the \texttt{IEEEtran} approach.
+% \end{itemize}
+%
% \section{How does it work}
%
% This package works on two fronts:
@@ -359,6 +445,8 @@
% Let's give the user a chance to manually define what to do
\newcommand\shrinkLastPage[1]{\dimgdef\@PBslack{#1}}
+\newcommand\balancePageNum[1]{\gdef\@PBthepage{#1}}
+\newcommand\nopbalance{\toggletrue{@PBdraft}}
\newcommand\@PBStartBalancing{
\ifdefvoid{\@PBslack}
@@ -445,7 +533,7 @@
{}
{
\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch failed, won't balance}
+ \PackageWarningNoLine{pbalance}{Patch failed (@outputdblcol)}
}
\let\@PBbalanceSecondColumn\relax
@@ -522,7 +610,7 @@
{}
{
\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch failed, won't balance}
+ \PackageWarningNoLine{pbalance}{Patch failed (@makecol)}
}
% This only gets called if there is a marginpar, so that's easy
@@ -530,7 +618,7 @@
{}
{
\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch failed, won't balance}
+ \PackageWarningNoLine{pbalance}{Patch failed (@addmarginpar)}
}
% \end{macrocode}
@@ -575,14 +663,14 @@
{}
{
\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch failed, won't balance}
+ \PackageWarningNoLine{pbalance}{Patch failed (@addtocurcol)}
}
\apptocmd{\@addtocurcol}{\@PBcollectFloatHeights}
{}
{
\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch failed, won't balance}
+ \PackageWarningNoLine{pbalance}{Patch failed (@addtocurcol)}
}
% \end{macrocode}
@@ -595,7 +683,7 @@
% balance; if both columns are float columns, this page cannot be the
% final text page, i.e., we want to balance some other page.
\newtoggle{@PBtmpHasFloatcol}
-\newtoggle{@PBtmpIsFloatPage}
+\newtoggle{@PBtmpFloatcolBoth}
% It would be nice to modify @makecol to do something like
%
@@ -627,24 +715,26 @@
{}
{
\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch failed, won't balance}
+ \PackageWarningNoLine{pbalance}{Patch failed (@makecol)}
}
-\newtoggle{@PBpatchStillActive} % Let's make sure our patched code actually runs
+ % Let's make sure our patched code actually runs. We only switch this
+ % to true after we verify that the patches in @makecol and @outputdblcol
+ % are actually executed when the page is built (therefore, after the
+ % preamble has ended).
+\newtoggle{@PBpatchStillActive}
\newcommand\@PBcollectColumnInfo{
- \global\toggletrue{@PBpatchStillActive}
-
\iftoggle{@PBpatchFailed}
{}
{
\ifdefvoid{\@PBtmpColumnUsedHeight}
+ {} % the patch to @makecol is not active, so we do nothing here
{
- \global\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch disabled by another
- package, won't balance}
+ % the patch to @makecol is active and so is ours, we're good to go!
+ \global\toggletrue{@PBpatchStillActive}
+ \@PBreallyCollectColumnInfo
}
- {\@PBreallyCollectColumnInfo}
}
}
@@ -671,7 +761,7 @@
\@PBiffloatcol
{
\iftoggle{@PBtmpHasFloatcol}
- {\global\toggletrue{@PBtmpIsFloatPage}}
+ {\global\toggletrue{@PBtmpFloatcolBoth}}
{\global\toggletrue{@PBtmpHasFloatcol}}
}
{}
@@ -687,7 +777,7 @@
{}
{
\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch failed, won't balance}
+ \PackageWarningNoLine{pbalance}{Patch failed (@outputdblcol)}
}
% ... And the balance package version, but only if we actually loaded it
@@ -699,14 +789,14 @@
{}
{
\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch failed, won't balance}
+ \PackageWarningNoLine{pbalance}{Patch failed (@BAdblcol)}
}
% Revert \balance before next page if it exists (it might be a float page)
\patchcmd{\@BAdblcol}{\endgroup}{\endgroup\nobalance}
{}
{
\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch failed, won't balance}
+ \PackageWarningNoLine{pbalance}{Patch failed (@BAdblcol)}
}
}
}
@@ -721,7 +811,9 @@
% modifies the output routine as well, we will not break anything, which
% is why this package is mostly safe to use. Unfortunately, such other
% packages may prevent us from balancing. Here we try to play nice with
-% some of them.
+% some of them. These workarounds may result in the same patch being
+% applied and run more than once; that is not ideal (we are wasting time)
+% but it should not cause problems.
%
% \subsubsection{stfloats}
%
@@ -737,14 +829,14 @@
{}
{
\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch failed, won't balance}
+ \PackageWarningNoLine{pbalance}{Patch failed (stfloats/@addtocurcol)}
}
\apptocmd{\@addtocurcol}{\@PBcollectFloatHeights}
{}
{
\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch failed, won't balance}
+ \PackageWarningNoLine{pbalance}{Patch failed (stfloats/@addtocurcol)}
}
}
@@ -757,25 +849,262 @@
{}
{
\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch failed, won't balance}
+ \PackageWarningNoLine{pbalance}{Patch failed (stfloats/fn@makecol)}
}
\pretocmd{\org@makecol}{\@PBcollectPageInfo}
{}
{
\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch failed, won't balance}
+ \PackageWarningNoLine{pbalance}{Patch failed (stfloats/org@makecol)}
}
\apptocmd{\fn@makecol}{\@PBcollectColumnUsedHeight}
{}
{
\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch failed, won't balance}
+ \PackageWarningNoLine{pbalance}{Patch failed (stfloats/fn@makecol)}
}
\apptocmd{\org@makecol}{\@PBcollectColumnUsedHeight}
{}
{
\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch failed, won't balance}
+ \PackageWarningNoLine{pbalance}{Patch failed (stfloats/org@makecol)}
+ }
+ }
+
+% \end{macrocode}
+%
+% \subsubsection{memoir}
+%
+% \begin{macrocode}
+
+% memoir defines the macros \mem@makecol and \mem@makecolbf; the commands
+% \feetabovefloat and \feetbelowfloat then redefine \@makecol to call
+% either one and executes \feetabovefloat. What we do, then, is patch
+% these two macros. Since memoir is a class, we assume it is always
+% loaded before us. Note that this means that, by default, our patch
+% is applied twice: one to \@makecol (because we always patch it) and
+% one to \mem@makecol, which is called by \@makecol. Only if the user
+% executes \feetabovefloat or \feetbelowfloat again does the patch in
+% \@makecol disappears.
+
+\ifdefvoid{\mem@makecol}
+ {}
+ {
+ \pretocmd{\mem@makecol}{\@PBcollectPageInfo}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (memoir/mem@makecol)}
+ }
+ \apptocmd{\mem@makecol}{\@PBcollectColumnUsedHeight}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (memoir/mem@makecol)}
+ }
+ \pretocmd{\mem@makecolbf}{\@PBcollectPageInfo}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (memoir/mem@makecolbf)}
+ }
+ \apptocmd{\mem@makecolbf}{\@PBcollectColumnUsedHeight}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (memoir/mem@makecolbf)}
+ }
+ }
+
+% \end{macrocode}
+%
+% \subsubsection{footmisc}
+%
+% \begin{macrocode}
+
+% footmisc simply redefines @makecol. If the package is loaded before
+% us, everything works; we just need to apply the patches again if it
+% is loaded after us. Therefore, we use AtEndOfPackageFile without *.
+% Note that there are two active versions of this package (the newer
+% uses new features from the LaTeX kernel). While their inner workings
+% are different, our strategy here is the same. footmisc checks if
+% @makecol has been modified before and issues a warning is that is
+% true. We could prevent this from happening, but if some other package
+% modifies it too that could be misleading, so we leave the warning
+% alone.
+\AtEndOfPackageFile{footmisc}
+ {
+ \pretocmd{\@makecol}{\@PBcollectPageInfo}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (footmisc/@makecol)}
+ }
+ \apptocmd{\@makecol}{\@PBcollectColumnUsedHeight}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (footmisc/@makecol)}
+ }
+ }
+
+% \end{macrocode}
+%
+% \subsubsection{ftnright}
+%
+% \begin{macrocode}
+
+% ftnright simply redefines @makecol and @outputdblcol. If the package is
+% loaded before us, everything works; we just need to apply the patches
+% again if it is loaded after us. Therefore, we use AtEndOfPackageFile
+% without *.
+
+\AtEndOfPackageFile{ftnright}
+ {
+ \pretocmd{\@makecol}{\@PBcollectPageInfo}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (ftnright/@makecol)}
+ }
+ \apptocmd{\@makecol}{\@PBcollectColumnUsedHeight}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (ftnright/@makecol)}
+ }
+
+ \pretocmd{\@outputdblcol}{\@PBbalanceSecondColumn}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (ftnright/@outputdblcol)}
+ }
+
+ \pretocmd{\@outputdblcol}{\@PBcollectColumnInfo}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (ftnright/@outputdblcol)}
+ }
+ }
+
+% \end{macrocode}
+%
+% \subsubsection{dblfnote}
+%
+% \begin{macrocode}
+
+% dblfnote copies @makecol to dfn@latex@makecol and defines dfn@makecol.
+% It then alternates between the two with the \twocolumn and \onecolumn
+% commands (in two-column mode, the default LaTeX version of the command
+% is used). dblfnote does the copy at the end of the preamble, so we do
+% not need to patch anything else, but it does assume that the document
+% is one-column. This means it substitutes dfn@makecol even in a two-
+% column document, which is clearly a bug. We could try to work around
+% this with AtBeginDocument, but this might make us overwrite some other
+% modification, so let's do nothing.
+
+% \end{macrocode}
+%
+% \subsubsection{flafter}
+%
+% \begin{macrocode}
+
+% flafter is probably irrelevant in two-column mode: I believe the default
+% algorithm always places the float on the next column or page. Still,
+% flafter overwrites @addtocurcol, so let's deal with it to be on the
+% safe side. We only need to worry if flafter is loaded after us, so we
+% use AtEndOfPackageFile without "*".
+
+\AtEndOfPackageFile{flafter}
+ {
+
+ \pretocmd{\@addtocurcol}{\dimgdef{\@PBtmpHeightBefore}{\@textfloatsheight}}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (flafter/@addtocurcol)}
+ }
+
+ \apptocmd{\@addtocurcol}{\@PBcollectFloatHeights}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (flafter/@addtocurcol)}
+ }
+ }
+
+% \end{macrocode}
+%
+% \subsubsection{fnpos}
+%
+% \begin{macrocode}
+
+% fnpos redefines \@makecol, so we need to patch it again. With option
+% \makeFNbottom (the default), our modification to \@textbottom that
+% aligns footnotes on the right column is overwritten; the user can
+% solve this by calling \makeFNmid. We only need to worry if fnpos
+% is loaded after us, so we use AtEndOfPackageFile without "*".
+
+\AtEndOfPackageFile{fnpos}
+ {
+ \pretocmd{\@makecol}{\@PBcollectPageInfo}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (fnpos/@makecol)}
+ }
+ \apptocmd{\@makecol}{\@PBcollectColumnUsedHeight}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (fnpos/@makecol)}
+ }
+ }
+
+
+% \end{macrocode}
+%
+% \subsubsection{midfloat and cuted}
+%
+% \begin{macrocode}
+
+% These packages are similar in spirit, but use different implementations.
+% Both redefine \@outputdblcol, so we just need to patch that again if
+% the package is loaded after us.
+
+\AtEndOfPackageFile{cuted}
+ {
+ \pretocmd{\@outputdblcol}{\@PBbalanceSecondColumn}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (cuted/@outputdblcol)}
+ }
+
+ \pretocmd{\@outputdblcol}{\@PBcollectColumnInfo}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (cuted/@outputdblcol)}
+ }
+ }
+
+\AtEndOfPackageFile{midfloat}
+ {
+ \pretocmd{\@outputdblcol}{\@PBbalanceSecondColumn}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (midfloat/@outputdblcol)}
+ }
+
+ \pretocmd{\@outputdblcol}{\@PBcollectColumnInfo}
+ {}
+ {
+ \toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch failed (midfloat/@outputdblcol)}
}
}
@@ -789,58 +1118,86 @@
%
% \begin{macrocode}
+\ExplSyntaxOn
\AtBeginShipout{
\iftoggle{@PBpatchFailed}
{}
{
- \iftoggle{@PBpatchStillActive}
- {\@PBfinalizePageData}
- {
- \global\toggletrue{@PBpatchFailed}
- \PackageWarningNoLine{pbalance}{Patch disabled by another
- package, won't balance}
- }
+ % It only makes sense to consider pages that actually have two columns.
+ \if@twocolumn
+ \iftoggle{@PBpatchStillActive}
+ {\@PBfinalizePageData}
+ {
+ \global\toggletrue{@PBpatchFailed}
+ \PackageWarningNoLine{pbalance}{Patch~disabled~by~another~package}
+ }
+ \fi
+
+ % Reset before processing next page
+ \global\togglefalse{@PBtmpHasFloats}
+ \global\togglefalse{@PBtmpHasFloatcol}
+ \global\togglefalse{@PBtmpHasFootnotes}
+ \global\togglefalse{@PBtmpHasMarginpars}
+ \global\togglefalse{@PBtmpFloatcolBoth}
+
+ \seq_gclear_new:N \@PBtmpLeftFloatHeights
+ \seq_gclear_new:N \@PBtmpLeftFloatSpacesBelow
+
+ \gundef{\@PBtmpHeight}
+ \gundef{\@PBtmpLeftHeight}
+ \gundef{\@PBtmpLeftFloatsHeight}
+ \gundef{\@PBtmpUsedLeft}
+ \gundef{\@PBtmpRightHeight}
+ \gundef{\@PBtmpRightFloatsHeight}
+ \gundef{\@PBtmpUsedRight}
}
}
+\ExplSyntaxOff
-\ExplSyntaxOn
\newcommand\@PBfinalizePageData{
- % It only makes sense to consider pages that actually have two
- % columns. LaTeX3 does not do short-circuit evaluation, so we
- % cannot add this test to the ifboolexpr below.
- \if@twocolumn
- \ifboolexpr
- {
- % A float page is not the last text page, ignore
- togl {@PBtmpIsFloatPage}
- or
- % A page with a float column on the left and an empty
- % column on the right is not the last text page, ignore
- (
- togl {@PBtmpHasFloatcol}
- and
- test {\ifdimcomp{\@PBtmpUsedRight}{=}{\topskip}}
- )
- }
- {}
- {
- % This page is a candidate to be the last two-column text page
- \xdef\@PBlastPage{\the\value{abspage}}
- \@PBcopyPageData{tmp}{candidate}
- }
- \fi
-
- % Reset before processing next page
- \global\togglefalse{@PBtmpHasFloats}
- \global\togglefalse{@PBtmpHasFloatcol}
- \global\togglefalse{@PBtmpHasFootnotes}
- \global\togglefalse{@PBtmpHasMarginpars}
- \global\togglefalse{@PBtmpIsFloatPage}
-
- \seq_gclear_new:N \@PBtmpLeftFloatHeights
- \seq_gclear_new:N \@PBtmpLeftFloatSpacesBelow
+ % LaTeX3 does not do short-circuit evaluation,
+ % so we cannot use a single ifboolexpr here
+ \ifdefvoid{\@PBtmpUsedRight}
+ % This is probably a float page or the user disabled
+ % the package somehow and recompiled. Either way,
+ % this is not the last text page, ignore
+ {}
+ {
+ \ifboolexpr
+ {
+ % If both cols are float cols, this is not the last text page, ignore
+ togl {@PBtmpFloatcolBoth}
+ or
+ % A page with a float column on the left and an empty
+ % column on the right is not the last text page, ignore
+ (
+ togl {@PBtmpHasFloatcol}
+ and
+ test {\ifdimcomp{\@PBtmpUsedRight}{=}{\topskip}}
+ )
+ }
+ {}
+ {
+ \ifdefvoid{\@PBthepage}
+ {
+ % The user did not choose a page, so this page is
+ % a candidate to be the last two-column text page
+ \xdef\@PBlastPage{\the\value{abspage}}
+ \@PBcopyPageData{tmp}{candidate}
+ }
+ {
+ \ifnumcomp{\@PBthepage}{=}{\the\value{abspage}}
+ {
+ % This is the page the user indicated
+ % as the last two-column text page
+ \xdef\@PBlastPage{\the\value{abspage}}
+ \@PBcopyPageData{tmp}{candidate}
+ }
+ {}
+ }
+ }
+ }
}
-\ExplSyntaxOff
% \end{macrocode}
%
@@ -905,7 +1262,11 @@
{\PackageWarningNoLine{pbalance}{Could not balance, doing nothing}}
{
\iftoggle{@PBpatchFailed}
- {\PackageWarningNoLine{pbalance}{Patching failed, doing nothing}}
+ {
+ \PackageWarningNoLine{pbalance}{Patching failed, cannot balance;
+ try \MessageBreak loading
+ pbalance earlier or later}
+ }
{\PackageInfo{pbalance}{Draft mode, doing nothing}}
}
}
@@ -945,8 +1306,12 @@
% The document has changed, so we need to measure
% stuff again; clear aux file and start over.
{\@PBnotifyRerun}
- % Nothing changed, just write the same info down
- {\@PBsaveUnbalancedInfo\@PBsaveBalancedInfo}
+ {
+ % Nothing changed, just write the same info down
+ \@PBsaveUnbalancedInfo
+ \@PBsaveBalancedInfo
+ \PackageInfo{pbalance}{Done balancing page \@PBlastPage}
+ }
}
% Second pass, which means something did change: we have just
% balanced the columns for the first time.