# Multiple column problem at page break using OPmac macros

I'm using the OPmac macros for mutiple columns in a tcolorbox as suggestested in: Multicolumns inside tcolorbox breakable box

It worked really nice so far, but I came upon a problem. Whenever I want to switch from a normal text to a two column text (that doesn't fit on one page) the remaining space on the page isn't used. Instead the two column text begins at the next page. If the text also is too large for this page it makes a normal page break. This problem also occurs outside of the tcolorbox. Is there a way that the columns begin right after the normal text and break at the end of the page?

\documentclass[11pt, oneside, a4paper]{report}

\usepackage{lipsum}

\newdimen\colsep \colsep=2em

\newcount\mullines
\newcount\tmpnum
\def\corrsize #1{%% #1 := #1 + \splittopskip - \topskip
}
\def\begmulti #1 {\par\bgroup\penalty0 \def\Ncols{#1}
\setbox6=\vbox\bgroup\penalty0
%% \hsize := Sirka sloupce = (\hsize+\colsep) / n - \colsep
\mullines=0
}
\def\endmulti{\vskip-\prevdepth\vfil
\expandafter\egroup\expandafter\baselineskip\the\baselineskip\relax
\dimen0=.8\maxdimen \tmpnum=\dimen0 \divide\tmpnum by\baselineskip
\splittopskip=\baselineskip
\setbox1=\vsplit6 to0pt
%% \dimen1 := the free space on the page
\vsize=.95\vsize
\ifdim\pagegoal=\maxdimen \dimen1=\vsize \corrsize{\dimen1}
\ifdim \dimen1<2\baselineskip
\vfil\break \dimen1=\vsize \corrsize{\dimen1} \fi
\ifnum\mullines<\tmpnum \dimen0=\ht6 \else \dimen0=.8\maxdimen \fi
\divide\dimen0 by\Ncols \relax
%% split the material to more pages?
\ifdim \dimen0>\dimen1 \splitpart
\else \balancecolumns \fi  % only balancing
\egroup
}
\def\makecolumns{\bgroup % full page, destination height: \dimen1
\loop \ifnum\Ncols>\tmpnum
\setbox1=\hbox{\unhbox1 \vsplit6 to\dimen1 \hss}
\repeat
\hbox{}\nobreak\vskip-\splittopskip \nointerlineskip
\null\nobreak\medskip\hbox to\hsize{\unhbox1\unskip}
\dimen0=\dimen1 \divide\dimen0 by\baselineskip \multiply\dimen0 by\Ncols
\egroup
}
\def\splitpart{%
\makecolumns % full page
\vskip 0pt plus 1fil minus\baselineskip \break
\ifnum\mullines<\tmpnum \dimen0=\ht6 \else \dimen0=.8\maxdimen \fi
\divide\dimen0 by\Ncols \relax
\dimen1=\vsize \corrsize{\dimen1}\dimen2=\dimen1
%% split the material to more pages?
\ifvoid6 \else
\ifdim \dimen0>\dimen2 \expandafter\expandafter\expandafter \splitpart
\else \balancecolumns % last balancing
\fi \fi
}
\def\balancecolumns{\bgroup \setbox7=\copy6 % destination height: \dimen0
\ifdim\dimen0>\baselineskip \else \dimen0=\baselineskip \fi
\def\tmp{%
\setbox1=\hbox{}\tmpnum=0
\loop \ifnum\Ncols>\tmpnum
\setbox1=\hbox{\unhbox1
\ifvoid6 \hbox to\wd6{\hss}\else \vsplit6 to\dimen0 \fi\hss}
\repeat
\ifvoid6 \else
\setbox6=\copy7
\expandafter \tmp \fi}\tmp
\hbox{}\nobreak\vskip-\splittopskip \nointerlineskip
\null\nobreak\medskip\hbox to\hsize{\unhbox1\unskip}%
\egroup
}

\begin{document}

\chapter{Example}

\lipsum[1-9]

\begmulti 2
\lipsum[1-4]
\endmulti

\end{document}


Note that the \begmulti and \endmulti works without problems in plain TeX. I don't know exactly why LaTeX does not work in this case but I will not to study it in deep because LaTeX is not my priority. A patch (maybe it will work in more cases:) can exist:

Try to add \advance\dimen1 by-\baselineskip after line 29 of your code, i.e.:

   \ifdim\pagegoal=\maxdimen \dimen1=\vsize \corrsize{\dimen1}
\ifdim \dimen1<2\baselineskip
...

• Thanks it works, could you explain what that line does ? Apr 14, 2020 at 16:01
• @GrueneSosse The macro calculates the amount of free space at the current page using primitive registers \pagegoal and \pagetotal. The result is stored to \dimen1. This calculation is processed correctly in plain TeX, but \dimen1 is too large in LaTeX. I don't know why. The \dimen1 is used for next processing: for creating the n columns of \dimen1 height. If they are created then they are put below previous text. But in LaTeX, there is no space for such putting and the columns are put to next page. If we scale down \dimen1` then the next columns fit to the same page. Apr 14, 2020 at 16:20