2

environment to balance a table in a multicol

I'd like an environment that balances a table in a multicol environment.

By this I mean I'd like to have potentially long tabular-like data that automatically breaks to another column of a roughly equal number of rows.

like so, automatically breaking after row 3, for a 2 column tabular, into a 2 column multicol (artist's rendition)

lipsum lipsum lipsum lipsum lipsum
row1 col2        row4 col2
row2 col2        row5 col2
row3 col2

lipsum lipsum lipsum lipsum lipsum

Additionally, I was looking to use xparse and a multicol to do this, in order to pass the number of columns to use through the custom environment down to multicols.

Additionally, I was looking to use the book class and showframe package.

I've tried two solutions:

solution A, long table

This answer produces the correct output but not when I wrap it in an environment:

Balancing long table inside multicol in LaTeX

I've tried two fixes:

solution A, fix 1: replace the \vbox{ and } with \bgroupand \egroup

Attempt no. 1 results in misaligned columns, and these errors:

  • Undefined control sequence. \begin{myenvironment}
  • Package longtable Error: longtable not in 1-column mode.
  • Undefined control sequence. \end{myenvironment}
  • misaligned columns
  • @numberne appears in the columns

solution 1, attempt 1

\documentclass[]{book}
\usepackage{showframe}
\usepackage[]{geometry}
\usepackage{longtable}
\usepackage{multicol}
\usepackage{xparse}

\newsavebox\ltmcbox

\def\shortlipsum{\par Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis.\par}

\newcounter{entryno} \setcounter{entryno}{1} \def\tabline{Test & \the\value{entryno} & Description\addtocounter{entryno}{1}\} \def\tablines{\tabline\tabline\tabline\tabline\tabline}

\NewDocumentEnvironment{myenvironment}{O{2}} { \begin{multicols}{#1} \setbox\ltmcbox\vbox\bgroup \makeatletter\col@number@ne \begin{longtable}{|l|l|l|} } { \makeatletter\col@number@ne \end{longtable} \unskip \unpenalty \unpenalty \egroup\unvbox\ltmcbox \end{multicols} }

\begin{document}

This works great! \shortlipsum \begin{multicols}{2} \shortlipsum \medskip \setbox\ltmcbox\vbox{ \makeatletter\col@number@ne \begin{longtable}{|l|l|l|} \tablines\tablines\tablines\tablines\tablines\tablines \end{longtable} \unskip \unpenalty \unpenalty } \unvbox\ltmcbox \medskip \shortlipsum \end{multicols}

\shortlipsum \par

This does not work! \begin{myenvironment} \tablines\tablines\tablines\tablines\tablines\tablines \end{myenvironment} \shortlipsum

\end{document}

solution A, fix 2: replace the \vbox{ and } with \begingroup and \endgroup

Attempt no. 2 results in a loss of output past the first \shortlipsum and:

  • Missing { inserted. \begin{myenvironment}
  • Undefined control sequence. \begin{myenvironment}
  • Package longtable Error: longtable not in 1-column mode.
  • Undefined control sequence. \end{myenvironment}
  • Missing } inserted. \end{myenvironment}

enter image description here

\documentclass[]{book}
\usepackage{showframe}
\usepackage[]{geometry}
\usepackage{longtable}
\usepackage{multicol}
\usepackage{xparse}

\newsavebox\ltmcbox

\def\shortlipsum{\par Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis.\par}

\newcounter{entryno} \setcounter{entryno}{1} \def\tabline{Test & \the\value{entryno} & Description\addtocounter{entryno}{1}\} \def\tablines{\tabline\tabline\tabline\tabline\tabline}

\NewDocumentEnvironment{myenvironment}{O{2}} { \begin{multicols}{#1} \setbox\ltmcbox\vbox\begingroup \makeatletter\col@number@ne \begin{longtable}{|l|l|l|} } { \makeatletter\col@number@ne \end{longtable} \unskip \unpenalty \unpenalty \endgroup\unvbox\ltmcbox \end{multicols} }

\begin{document}

This works great! \shortlipsum \begin{multicols}{2} \shortlipsum \medskip \setbox\ltmcbox\vbox{ \makeatletter\col@number@ne \begin{longtable}{|l|l|l|} \tablines\tablines\tablines\tablines\tablines\tablines \end{longtable} \unskip \unpenalty \unpenalty } \unvbox\ltmcbox \medskip \shortlipsum \end{multicols}

\shortlipsum \par

This does not work! \begin{myenvironment} \tablines\tablines\tablines\tablines\tablines\tablines \end{myenvironment} \shortlipsum

\end{document}

solution B, pseudo-nested longtable w/ savebox

This answer also produces what I want, but I couldn't get it to align with the text.

balanced longtables, multicol and page breaks

I've tried:

solution B, fix 1: wrap the commands in an env and remove the table, and that works great!

enter image description here

However...

That works great until I add the showframe package and I get:

  • Missing } inserted. \begin{myenvironment}3
  • Extra }, or forgotten \endgroup{myenvironment}
  • added space under the longtable

enter image description here

\documentclass[]{book}
%\usepackage{showframe}
\usepackage{longtable}
\usepackage{multicol}
\usepackage{lipsum}
\usepackage{capt-of}
\usepackage{xparse}

\def\shortlipsum{\par Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis.\par}

\newcounter{entryno} \setcounter{entryno}{1} \def\tabline{Test & \the\value{entryno} & Description\addtocounter{entryno}{1}\} \def\tablines{\tabline\tabline\tabline\tabline\tabline}

\makeatletter \newsavebox\ltmcbox \newsavebox\xxbox \newenvironment{multicolslongtable}[1]{ \setbox\ltmcbox\vbox\bgroup \col@number@ne \begin{longtable}{#1} } { \end{longtable} \unskip \unpenalty \unpenalty\egroup \unvbox\ltmcbox } \makeatother

\NewDocumentEnvironment{myenvironment}{O{2}} { \savebox\xxbox\bgroup \begin{minipage}{\textwidth} \begin{multicols}{#1} \begin{multicolslongtable}{| l | l | l |} } { \end{multicolslongtable} \end{multicols} \end{minipage} \egroup \begin{multicols}{#1} \usebox\xxbox \end{multicols} }

\begin{document}

\shortlipsum

\begin{myenvironment}[2] \tablines\tablines\tablines\tablines\tablines\tablines \end{myenvironment}

\shortlipsum

\end{document}

1 Answers1

0

The fix was to use the showframe option from geometry package instead of the showframe package.

Thank you AboAmmar!

The code below shows an environment that balances tabular data using a longtable in a multicol (with showframe), by combining the following answers, xparse, and minor refactoring:

enter image description here

% environment to balance a table in a multicol

\documentclass[]{book} \usepackage[showframe]{geometry} \usepackage{longtable} \usepackage{multicol} \usepackage{lipsum} \usepackage{xparse}

% helpers for the test \def\shortlipsum{\par Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis.\par} \newcounter{entryno} \setcounter{entryno}{1} \def\tabline{Test & \the\value{entryno} & Description\addtocounter{entryno}{1}\} \def\tablines{\tabline\tabline\tabline\tabline\tabline\tabline\tabline\tabline\tabline}

% box for a multi column long table % SEE https://tex.stackexchange.com/questions/161827/balanced-longtables-multicol-and-page-breaks \makeatletter \newsavebox\ltmcbox \newsavebox\xxbox \newenvironment{multicolslongtable}[1]{ \setbox\ltmcbox\vbox\bgroup \col@number@ne \begin{longtable}{#1} } { \end{longtable} \unskip \unpenalty \unpenalty\egroup \unvbox\ltmcbox } \makeatother

% environment to accept table input and produce multicol \NewDocumentEnvironment{myenvironment}{O{2}} { \savebox\xxbox\bgroup \begin{minipage}{\textwidth} \begin{multicols}{#1} \begin{multicolslongtable}{| l | l | l |} } { \end{multicolslongtable} \end{multicols} \end{minipage} \egroup \begin{multicols}{#1} \centering \usebox\xxbox \end{multicols} }

% patch multicols to allow for one column % SEE https://tex.stackexchange.com/questions/233866/one-column-multicol-environment \let\multicolmulticols\multicols \let\endmulticolmulticols\endmulticols \RenewDocumentEnvironment{multicols}{mO{}} {% \ifnum#1=1 #2% \else % More than 1 column \multicolmulticols{#1}[#2] \fi } {% \ifnum#1=1 \else % More than 1 column \endmulticolmulticols \fi }

\begin{document}

\section{one column} \shortlipsum \begin{myenvironment}[1] \tablines \end{myenvironment} \shortlipsum

\section{two column} \shortlipsum \begin{myenvironment} \tablines \end{myenvironment} \shortlipsum

\section{three column} \shortlipsum \begin{myenvironment}[3] \tablines \end{myenvironment} \shortlipsum

\end{document}

  • Your document example can't be compiled, it throw the same error as you reported in question. BTW, showframe doesn't interact with page content. Cause of your error is something else. – Zarko Aug 29 '21 at 07:59