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 \bgroup
and \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
\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}
\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!
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
\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}
\usepackage[showframe]{geometry}
? It does the same but without breaking your code.