0

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
   \advance #1 by \splittopskip \advance #1 by-\topskip
}
\def\begmulti #1 {\par\bgroup\penalty0 \def\Ncols{#1}
   \setbox6=\vbox\bgroup\penalty0
   %% \hsize := Sirka sloupce = (\hsize+\colsep) / n - \colsep
   \advance\hsize by\colsep
   \divide\hsize by\Ncols  \advance\hsize by-\colsep
   \mullines=0
   \def\par{\ifhmode\endgraf\global\advance\mullines by\prevgraf\fi}%
}
\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}
   \else \dimen1=\pagegoal \advance\dimen1 by-\pagetotal \fi
   \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
   \vbadness=20000 \setbox1=\hbox{}\tmpnum=0
   \loop \ifnum\Ncols>\tmpnum
      \advance\tmpnum by1
      \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
   \global\advance\mullines by-\dimen0
   \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
   \ifx\balancecolumns\flushcolumns \advance\dimen0 by-.5\vsize \fi
   \dimen1=\vsize \corrsize{\dimen1}\dimen2=\dimen1
   \advance\dimen2 by-\Ncols\baselineskip
   %% 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
   \vbadness=20000
   \def\tmp{%
      \setbox1=\hbox{}\tmpnum=0
      \loop \ifnum\Ncols>\tmpnum
         \advance\tmpnum by1
         \setbox1=\hbox{\unhbox1
              \ifvoid6 \hbox to\wd6{\hss}\else \vsplit6 to\dimen0 \fi\hss}
      \repeat
   \ifvoid6 \else
      \advance \dimen0 by.2\baselineskip
      \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}

enter image description here

1

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}
   \else \dimen1=\pagegoal \advance\dimen1 by-\pagetotal \fi
   \advance\dimen1 by-\baselineskip % <<< this line is added
   \ifdim \dimen1<2\baselineskip
   ...
2
  • Thanks it works, could you explain what that line does ? Apr 14 '20 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.
    – wipet
    Apr 14 '20 at 16:20

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.