7

In the layout I produce, the main text is typeset in two columns, and at the end of every section, the columns get balanced, and a decorative section break appears. Here's what it looks like in practice:

the correct way

I'm trying to get it so that the decorative part will always appear on the same page as the end of a section, but it's not working nicely. Here's a MWE:

\documentclass[letterpaper]{article}
\usepackage{multicol}
\usepackage{etoolbox}
\usepackage{fourier-orns}
\usepackage{adforn}
\usepackage{lipsum}

\def\endsecornament{\centerline{%
  \adfflowerright\hspace{-.04em}%
\raisebox{-2pt}{{\large\aldine}\hspace{-.04em}}%
 \adfflowerleft}}

\AfterEndEnvironment{multicols}{\endsecornament}

\begin{document}
\begin{multicols}{2}
  \lipsum[1-5]
\end{multicols}


\end{document}

which outputs

problematic one

Note how the ornament was placed on the next page.

I've already tried increasing \postmulticols, which seemed like it would make a page break if there isn't enough room for the ornament, but it didn't work.

If there's no way around this, b/c there's no room on the page, is it possible to automate an \enlargethispage command?

EDIT: I tried implementing an \enlargethispage approach, by using

\AfterEndEnvironment{multicols}{\enlargethispage{\totalheightof{\endsecornament}}%
\endsecornament}

Which should allow for the ornament to fit on the page. It cuts down the issue, but still sometimes in practice it ends up on another page.

  • Your problem is not really well-defined. The multicol workflow is to cut full pages until the end of the environment is reached, then balance what is on the last page. Now your code ends it exactly at a page boundary. So what should happen instead? How many lines should the first page run short and move over to the next? and how should that look (it isn't balancing that part normally), should it run short or spread things apart (wouldn't really work well in your example either) or ... ? What is the expected logic? – Frank Mittelbach Jul 17 '17 at 16:50
  • @Frank - Really, the preffered solution would be to enlarge the page to allow the ornament to fit, but only do so if we've hit the page boundary. This should work nicely, seeing as TeX has rather wide margins. I'm just not sure how I should go about this. – A Gold Man Jul 17 '17 at 18:26
  • Well it would and it wouldn't. \enlargethispage would not move the footerline with the result that you end up getting the ornament to close or even overprinting if you have such a line (as your example does. One could detect that the endo of the multicol is near the page boundary and issue an \enlargethispage but it is less easy to also move the footer – Frank Mittelbach Jul 18 '17 at 7:37
  • @FrankMittelbach could you post code to do that? I wouldn't be averse to just changing the footer to my ornament in that case. In general my footer is empty, so it's not a problem of getting overlapped. – A Gold Man Jul 18 '17 at 11:11
6

The problem is that multicols first adds the balanced columns and then a vertical skip of \multicolsep which generates a breakpoint after the columns. While this is normally what is wanted as this means the space vanishes in the page break if it is taken, it means that any code after ending the environment comes too late and thus can end up on the next page if the columns end at or very near the end of the page. Thereofore we disable

%\AfterEndEnvironment{multicols}{\endsecornament}

and proceed in a different way

To enlarge the page if this is the situation we need to hook into the multicols code to test for this before the skip is inserted.

%------ interface -----
\usepackage{etoolbox}
\patchcmd\endmulticols
    {{multicols}\endgroup}
    {{multicols}\endgroup\mcenlargepage}
    {\typeout{Success!}}
    {\typeout{Patch failed!}\ERROR}

The code added at this point could then test for the available space and do the right thing depending on the situation:

%----- code ------------
%
%  #1 = min space needed
%  #2 = material to be inserted before \vspace{\multicolsep}
%       but with \nointerlineskip (arguable)

\newdimen \mctempdim

\def\mcenlargepagecode#1#2{%
  \mctempdim \dimexpr \pagegoal-\pagetotal+\pageshrink \relax
  \ifdim  \mctempdim < \dimexpr #1\relax
    \PackageWarning{multicol}%
      {Space remaining on page:
        \the\mctempdim \space < \the\dimexpr #1\relax
        \MessageBreak
        Enlarging page by \the\dimexpr #1-\mctempdim\relax}%
    \enlargethispage{\dimexpr #1-\mctempdim\relax}%
  \fi
  \nointerlineskip   
  #2%
}

One could do the parametrisation setting up a number of registers but for now I used a simple way, i.e., you have to define \mcenlargepage to use \mcenlargepagecode above according to your needs:

%--- parametrization ----------

\setbox0\hbox{\endsecornament}

\def\mcenlargepage{\mcenlargepagecode{\ht0+\dp0+12pt}%
  {\vspace{12pt}%
   \endsecornament}}

And I guess that's it. For testing purposes I also increased the \textheight by 5pt and with that we get

enter image description here

and the warning:

Package multicol Warning: Space remaining on page: 5.0pt < 23.31198pt
(multicol)                Enlarging page by 18.31198pt on input line 70.

If we disable the patch we get

enter image description here

and if we end the multicols in the middle of the page we get

enter image description here

Thus, except for possibly some hidden snags this seems to do what is requested.

Addendum

The multicol package is free software distributed under LPPL. And so is this code of course. However, for historical reasons the multicol license has an extended "moral obligation clause" that asks for considering to pay a license fee of your own choosing if it is used for commercial applications such as producing a book to be sold.

The historical background of this rather curious moral obligation is described in the paper Reflections on the history of the LaTeX Project Public License (LPPL) - A software license for LaTeX and more which can be found on the LaTeX project site and in the TUGboat archives. That main part of the paper describes how the LaTeX Project License (LPPL) evolved and gives some history about the license "wars" that happened way back so I think it is worth a read in its own right.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.