From 855f5fb65b35423aa18e0e69a1e36aca098e93e3 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 29 Jul 2022 21:00:35 +0000 Subject: pbalance (28jul22) git-svn-id: svn://tug.org/texlive/trunk@64002 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/pbalance/pbalance.pdf | Bin 39562 -> 50436 bytes .../texmf-dist/source/latex/pbalance/pbalance.dtx | 559 +++++++++++++++++---- Master/texmf-dist/tex/latex/pbalance/pbalance.sty | 338 ++++++++++--- 3 files changed, 729 insertions(+), 168 deletions(-) diff --git a/Master/texmf-dist/doc/latex/pbalance/pbalance.pdf b/Master/texmf-dist/doc/latex/pbalance/pbalance.pdf index d8ddbb38f0d..499e31de975 100644 Binary files a/Master/texmf-dist/doc/latex/pbalance/pbalance.pdf and b/Master/texmf-dist/doc/latex/pbalance/pbalance.pdf differ diff --git a/Master/texmf-dist/source/latex/pbalance/pbalance.dtx b/Master/texmf-dist/source/latex/pbalance/pbalance.dtx index b5712f00c61..a426a6366a6 100644 --- a/Master/texmf-dist/source/latex/pbalance/pbalance.dtx +++ b/Master/texmf-dist/source/latex/pbalance/pbalance.dtx @@ -15,7 +15,7 @@ % \iffalse % %\NeedsTeXFormat{LaTeX2e}[2015/01/01] -%\ProvidesPackage{pbalance}[2022/06/22 v1.3.0 Poor man's balance] +%\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. diff --git a/Master/texmf-dist/tex/latex/pbalance/pbalance.sty b/Master/texmf-dist/tex/latex/pbalance/pbalance.sty index 6cab784cb9d..10719cbcaa4 100644 --- a/Master/texmf-dist/tex/latex/pbalance/pbalance.sty +++ b/Master/texmf-dist/tex/latex/pbalance/pbalance.sty @@ -18,7 +18,7 @@ %% The Current Maintainer of this work is Nelson Lago . %% \NeedsTeXFormat{LaTeX2e}[2015/01/01] -\ProvidesPackage{pbalance}[2022/06/22 v1.3.0 Poor man's balance] +\ProvidesPackage{pbalance}[2022/07/28 v1.4.0 Poor man's balance] \RequirePackage{etoolbox} \RequirePackage{expl3} @@ -87,6 +87,8 @@ } \newcommand\shrinkLastPage[1]{\dimgdef\@PBslack{#1}} +\newcommand\balancePageNum[1]{\gdef\@PBthepage{#1}} +\newcommand\nopbalance{\toggletrue{@PBdraft}} \newcommand\@PBStartBalancing{ \ifdefvoid{\@PBslack} @@ -167,7 +169,7 @@ {} { \toggletrue{@PBpatchFailed} - \PackageWarningNoLine{pbalance}{Patch failed, won't balance} + \PackageWarningNoLine{pbalance}{Patch failed (@outputdblcol)} } \let\@PBbalanceSecondColumn\relax @@ -221,14 +223,14 @@ {} { \toggletrue{@PBpatchFailed} - \PackageWarningNoLine{pbalance}{Patch failed, won't balance} + \PackageWarningNoLine{pbalance}{Patch failed (@makecol)} } \pretocmd{\@addmarginpar}{\global\toggletrue{@PBtmpHasMarginpars}} {} { \toggletrue{@PBpatchFailed} - \PackageWarningNoLine{pbalance}{Patch failed, won't balance} + \PackageWarningNoLine{pbalance}{Patch failed (@addmarginpar)} } @@ -268,19 +270,19 @@ {} { \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)} } \newtoggle{@PBtmpHasFloatcol} -\newtoggle{@PBtmpIsFloatPage} +\newtoggle{@PBtmpFloatcolBoth} \newcommand\@PBcollectColumnUsedHeight{ \setbox\@tempboxa=\vbox{\unvcopy\@outputbox\unskip\unskip} @@ -291,24 +293,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} } } @@ -335,7 +339,7 @@ \@PBiffloatcol { \iftoggle{@PBtmpHasFloatcol} - {\global\toggletrue{@PBtmpIsFloatPage}} + {\global\toggletrue{@PBtmpFloatcolBoth}} {\global\toggletrue{@PBtmpHasFloatcol}} } {} @@ -350,7 +354,7 @@ {} { \toggletrue{@PBpatchFailed} - \PackageWarningNoLine{pbalance}{Patch failed, won't balance} + \PackageWarningNoLine{pbalance}{Patch failed (@outputdblcol)} } \ifboolexpr{togl {@PBdraft} or togl {@PBnoBalancePackage}} @@ -361,14 +365,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)} } } } @@ -381,14 +385,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)} } } @@ -398,81 +402,265 @@ {} { \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)} + } + } + + + +\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)} + } + } + + +\AtEndOfPackageFile{footmisc} + { + \pretocmd{\@makecol}{\@PBcollectPageInfo} + {} + { + \toggletrue{@PBpatchFailed} + \PackageWarningNoLine{pbalance}{Patch failed (footmisc/@makecol)} + } + \apptocmd{\@makecol}{\@PBcollectColumnUsedHeight} + {} + { + \toggletrue{@PBpatchFailed} + \PackageWarningNoLine{pbalance}{Patch failed (footmisc/@makecol)} + } + } + + + +\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)} + } + } + + + + + +\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)} + } + } + + + +\AtEndOfPackageFile{fnpos} + { + \pretocmd{\@makecol}{\@PBcollectPageInfo} + {} + { + \toggletrue{@PBpatchFailed} + \PackageWarningNoLine{pbalance}{Patch failed (fnpos/@makecol)} + } + \apptocmd{\@makecol}{\@PBcollectColumnUsedHeight} + {} + { + \toggletrue{@PBpatchFailed} + \PackageWarningNoLine{pbalance}{Patch failed (fnpos/@makecol)} + } + } + + + +\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)} } } +\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 \AfterLastShipout{ @@ -495,7 +683,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}} } } @@ -535,8 +727,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. -- cgit v1.2.3