3

This problem occurs when small paragraphs of a multicol environment are placed at the end of the page. I've produced the following MWE but the problem is sometimes more visible on longer documents:

\documentclass[letterpaper]{article}
\usepackage{multicol}\usepackage{biblatex}\usepackage{lipsum}
\usepackage{filecontents}

\begin{filecontents}{\jobname.bib}
@Thesis{biblioEntry,
Title                    = {Sed interdum libero ut metus. Pellentesque placerat. Nam rutrum augue a leo. Morbi sed elit sit amet ante lobortis sollicitudin. Sed interdum libero ut metus. Pellentesque placerat. Nam rutrum augue a leo Sed interdum libero Sed interdum libero Sed interdum libero},
Author                   = {Sed interdum libero},
Location                 = {Sed interdum libero},
Year                     = {1999},
}
\end{filecontents}

\addbibresource{\jobname.bib}

\begin{document} 
\section{Section}
\lipsum[1-3]
\fullcite{biblioEntry}
\section{Section}
\begin{multicols}{2}
Sed interdum libero ut metus. Pellentesque placerat. Nam rutrum augue a leo. Morbi sed elit sit amet ante lobortis sollicitudin. Praesent blandit blandit mauris. Praesent lectus tellus, aliquet aliquam, luctus a, egestas a, turpis.  Mauris lacinia lorem sit amet ipsum.

Sed interdum libero ut metus. Pellentesque placerat. Nam rutrum augue a leo. Morbi sed elit sit amet ante lobortis sollicitudin. Praesent blandit blandit mauris. Praesent lectus tellus, aliquet aliquam, luctus a, egestas a, turpis.  Mauris lacinia lorem sit amet ipsum.

\lipsum[1]

\end{multicols}
\end{document}  

screenshot showing unbalanced columns at the end of a page

The same problem occurs in the actual multicols documentation:

multicols documentation, end of p. 6

As a workaround, I'm using \setlength{\parskip}{0pt} in the multicol environment. It works, but I'd like to know if there is a better solution.

4
  • 1
    the space is added by a stretchable \parskip. within multcols, set \parskip=0pt \relax and that should make all columns end at the same point. (all bets are off if the text includes math displays. this works only with solid text.) Dec 4, 2017 at 18:10
  • You could as well use \addtolength{\baselineskip}{\fill} inside the multicols. If the unused space isn't that large, that might give good results (in your case imho it doesn't).
    – Skillmon
    Dec 4, 2017 at 18:21
  • Thx, both suggestions are working. Is there some advantage to use them rather than \setlength{\parskip}{0pt}?
    – omisson
    Dec 4, 2017 at 18:28
  • 1
    \setlength{\parskip}{0pt} does exactly the same as \parskip=0pt\relax. The difference between my suggestion and the setting of parskip to be non-stretchable is, that with mine you possibly get more space between the single rows, but the whole thing is bottom-justified while the other approach doesn't really justify anything compared to other pages.
    – Skillmon
    Dec 4, 2017 at 18:49

2 Answers 2

3

This problem arises (as others have already said) because the are only 75pts left on the page and so when multicol cuts the columns it will split off columns of that size. However, with a default \baselineskip of 12pt and 10 points of \topskip 6 lines of text are worth 70pt, so in columns that have no stretch there will be a 5pt gap at the bottom and in the column with just the \parskip there will be an ugly gap between the paragraphs as all of these 5 points end up there.

A general fix may need a little bit more finesse but try this and see how far it gets you in general:

\usepackage{multicol}
\usepackage{etoolbox}

\makeatletter
\patchcmd\multi@column@out
{\process@cols}
{%
  \typeout{Requested vsize = \the\dimen@ }%
   \advance\dimen@ -\topskip
   \divide\dimen@ \baselineskip
   \multiply\dimen@ \baselineskip
   \advance\dimen@ \topskip
   \typeout{Reducing vsize to integral number of lines = \the\dimen@ }%
   \process@cols}
{\typeout{Success!}}{\ERROR}
\makeatother  

This should solve the problem, although I wonder if there need to be a different action if the gap is close to a whole baseline. So need to think about it a bit more.

Anyway, with the above I get:

enter image description here

which I think is what you are looking for.

Note

As pointed out in a comment, this results in the whole page being short which is true (by 5pt) and thus doesn't align with a facing page. However, this is only because \raggedbottom is used (which is the default in the article class). Thus any alignment is only by chance anyway. So if one wants the above but with aligned pages (and not just aligned by chance sometimes) then the right thing to do is to use \flushbottom in the preamble.

I could have forced such pages to be always bottom aligned which may or may not be better even with \raggedbottom in force but that's not done in the above patch.

4
  • I want to like this answer, but it doesn't really justify the columns compared to other pages which I think is a drawback. The results on that one page however are a lot better than with my answer, as mine gives inconsistent \baselineskips compared to the rest of the page.
    – Skillmon
    Dec 5, 2017 at 19:52
  • 1
    @Skillmon like it anyway :-). article class uses \raggedbottom by default so of course if a page is shorter (as that is now the case) the excess white space goes to the bottom. Thus, if you want bottom alignment correct way is to use \flushbottom as well (or a class like report that applies this automatically. I will updat my answer to include this. (as to fiddling with baselineskip, that is nearly always a bad idea if you have more than one page - it usually ends up be quite noticable) Dec 5, 2017 at 20:23
  • I'd not recommend to add stretchability to \baselineskip in general. Just within the multicols where it'd be needed. I did however not note the fact that \raggedbottom is used by article when I was writing that comment :)
    – Skillmon
    Dec 5, 2017 at 20:40
  • Thx a lot, It works perfectly on my MWE, I will test it on longer documents.
    – omisson
    Dec 5, 2017 at 22:36
3

The space is added because (La)TeX tries to justify the column to the bottom of the page (insert \usepackage{showframe} in the preamble to see this). In order to do this, all stretchable spaces are stretched as much as possible/necessary to fulfil that goal. In your example the only stretchable length is \parskip and it only occurs in the right column. The result is an unjustifiable left column and a justified right one.

If you want to disable this stretch you can use \setlength{\parskip}{0pt} as you're already doing. This results in unjustified columns which happen to end at the same height (as there are only multiples of \baselineskip possible in vertical space occupied).

Another approach could be to add stretch to every \baselineskip. Note however that \fill has a higher "priority" than the stretch of \parskip so \parskip wouldn't be stretched. This might look ugly if the \baselineskips are stretched a lot. You can use this approach with

\addtolength{\baselineskip}{\fill}

Another possibility would be to create a new skip register (which is what \newlength does after checking whether the name is unused) and setting that to a customized stretch value:

\newlength\mybaselinestretch
\mybaselinestretch=0pt plus 0.02pt\relax
\addtolength{\baselineskip}{\mybaselinestretch}

This way you can limit the amount \baselineskip should be stretched and \parskip gets stretched, too. Note that if there is no other stretch available \baselineskip would get stretched as much as necessary, even if that would result in more space then specified, as long as the length after plus is longer than 0pt.

Note:

Just to prevent misconceptions: I do not recommend to add stretchability to \baselineskip globally but only where it could be absolutely necessary to achieve justification. In general I think the answer provided by Frank Mittelbach is more reasonable and can be used more carefree than mine.

2
  • Thx for your explanation and the showframe tip. The problem is that the \baselinskip change still apply to the next pages and the text will take more space.
    – omisson
    Dec 5, 2017 at 22:39
  • @omisson it can change everything in the same group. That's why I said I wouldn't apply it globally. You could group stuff more. But overall that is the reason why I prefer Frank Mittelbachs answer, too.
    – Skillmon
    Dec 6, 2017 at 0:05

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.