27

I would like to put some longer tabular data inside the multicols environment while maintaining its balancing abilities. I have tried supertabular with the trick to redefine \newpage as columnbreak. This isn't good though, because the columns aren't properly balanced. Finally I ended up using \halign:

\documentclass[11pt, a4paper]{article}
\usepackage[margin=3cm]{geometry}
\usepackage{supertabular}
\usepackage{multicol}

\def\shortlipsum{\par Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna. Donec vehicula augue eu neque.\par}

\newcounter{entryno}
\setcounter{entryno}{1}
\def\tabline{Test & \the\value{entryno} & Description\addtocounter{entryno}{1}\\}
\def\tablines{\tabline\tabline\tabline\tabline\tabline}
\def\mybreak{\hrule width \columnwidth height 0pt \columnbreak}

\begin{document}
\begin{multicols}{2}
\shortlipsum
\medskip

% % This doesn't balance the columns. Whole table ends up in the left column (it fits)
% \begingroup\let\newpage\mybreak
% \noindent\begin{supertabular*}{\columnwidth}{@{\indent}l l l}
% \tablines\tablines\tablines\tablines\tablines\tablines
% \end{supertabular*}
% \endgroup

\begingroup\let\\\cr
\noindent\halign{\indent#\quad&#\quad&#\hfil\cr
\tablines\tablines\tablines\tablines\tablines\tablines}
\endgroup

\medskip
\shortlipsum
\end{multicols}
\shortlipsum
\end{document}

result

I was wondering if I'm the only one using \halign to achieve this result. On the other hand supertabular leaves me with an undesired almost empty right column. How would you approach this problem?

lockstep
  • 250,273
Frg
  • 1,137

3 Answers3

36

If you don't want longtable to add headers and footers to the table at the same time that multicol is balancing where to make the break (which would require that frank and I cooperate:-) then multicol will balance the output from longtable if you first trick longtable into thinking that it isn't in multicol at all.

I added some rules, just to show that latex tabular features then work, which is harder to do with a bare \halign.

enter image description here

\documentclass[11pt, a4paper]{article}
\usepackage[margin=3cm]{geometry}
\usepackage{longtable}
\usepackage{multicol}

\newsavebox\ltmcbox

\def\shortlipsum{\par Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna. Donec vehicula augue eu neque.\par}

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


\begin{document}





\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
\end{document}
David Carlisle
  • 757,742
  • I would never suspect this to work! I may even overlook the runaway vrule at the second "Lorem". :) If longtable works then maybe longtabu will work as well. Still, it's good to see a familiar table environment and not have to dive into hrule texnicalities. :) – Frg Feb 27 '12 at 16:02
  • I mean "\halign". And as for the odd extra vrule, I don't get it in my pdf, so it must have been some dead pixels in the screenshot. – Frg Feb 27 '12 at 16:11
  • 1
    It really does work across multiple pages with both plain longtable and longtabu. Only things like \endhead, \endfoot, \endlastfoot don't appear at all. – Frg Feb 27 '12 at 16:33
  • 2
    the only thing LT could do with the head and foot commands is put either head or firsthead at the start and and either foot or lastfoot at the end, no chance of it doing anything at the break. So really no point in doing anything at all (as you can just put the lines in the table body) but it might be kinder to support that, as it makes it easier to move existing longtables into this useage, – David Carlisle Feb 27 '12 at 16:36
  • 7
    I kindly ask for Frank and you (or someone else from the LaTeX3 team) to spend some time together again to fix this for LaTeX3: I want true mini pages in multicolumn mode, i.e. columns with separate headers and footers. And of course balanced (or not, if I want). The last time I looked at this the best option for this was to use pdfpages. I'm quite sure that this has been possible with ConTeXt for years, though. – Martin Schröder Feb 27 '12 at 22:23
  • @Frg, @DavidCarlisle: I am getting oodles of ! Package longtable Error: longtable not in 1-column mode. errors when I use this trick. Is this expected? – wilx Feb 17 '14 at 17:46
  • @wilx no \makeatletter\col@number\@ne tells LT it is in one column mode. – David Carlisle Feb 17 '14 at 18:08
  • @DavidCarlisle: I have made it work but I am seeing some artifacts, like text being hidden/disappearing. I will try to prepare a MWE for a separate question later today. – wilx Feb 25 '14 at 16:16
  • This solution also works in Lyx: set the table as multi-page table (so that it uses longtable), place it inside a table float, and input the code given here at the beginning and the end of the table float (around the longtable, just like in the code snippet here). – gaborous Jun 13 '16 at 13:56
  • Is it possible to make it so the \endhead, \endfoot, and \endlastfoot can be respected, for those who don't need the columns balanced (using either twocolumn document setting or multicols* environment)? – Keith Davies Aug 19 '19 at 19:18
  • @KeithDavies anything's possible, but not for free like the answer here, Supporting two column is probably a matter of duplicating the existing one col code adapting for two col. Supporting multicol's balanced columns would probably need a complete redesign – David Carlisle Aug 19 '19 at 20:51
  • I can understand that. I have been able to get it to render the longtable in multicols environment and in twocolumn, but see only the single header (with the column names). This is as described, so I wasn't surprised. I realize and understand why the solution here doesn't present the other elements in (balanced) multicols... but I wonder if it's possible to make them appear if the columns don't need to balance. Sadly, I lack the depth of knowledge to quickly solve this one... – Keith Davies Aug 19 '19 at 23:57
  • How can one define an environment so this can be easily (re)used within a document (say, \begin{multicolstable}{2}{|l|l|l|}\tablines\tablines\tablines\tablines\tablines\tablines\end{multicolstable})? I tried using \newenvironment and environ’s \NewEnviron, but I get error messages. – Júda Ronén Apr 03 '22 at 13:06
4

Package such as longtable and supertabular or, better than the latter, xtab, aim at overcoming a "limitation" of the TeX engine: tabular material has to be entirely read in to find the column widths. For huge tables this may easily lead to memory problems.

Unfortunately, longtable is incompatible with the multicols environment while, as you discovered, supertabular (and xtab) don't maintain the same column width across pages. Using tabular is impossible, as its implementation locks the material into a box and inside \mathon and \mathoff items so it's unbreakable.

For a simple table where you can figure out the column width, you can use tabbing, which splits across pages and columns:

\begin{tabbing}
Test \quad\= 99\quad\=\kill
Test \> \hfil 1  \> Description ... \\
...
Test \> \hfil 30 \> Description ...
\end{tabbing}

For more complex tables I'm afraid that the lower level \halign can be, at the moment, the more flexible solution.

David Carlisle
  • 757,742
egreg
  • 1,121,712
  • I haven't tested that but couldn't you use the header line (with some invisible data) that supertabular inserts on each page to force certain column widths? That would force you to decide the column widths manually per column but it should then get them uniform (hopefully). – Frank Mittelbach Feb 27 '12 at 15:04
  • 1
    If one has to repeat data on the top (or bottom) of each column, the xtab solution is presently the only one. Probably forcing the header or footer to have the desired width can guarantee uniformity (but it defeats the principle that column width are computed from the data). – egreg Feb 27 '12 at 15:09
  • yes of course. it is kind of turning supertabular into a tabbing environment of sorts. but might be better than nothing and as you say longtable doesn't work as it deploys the outputroutine for its work – Frank Mittelbach Feb 27 '12 at 15:12
  • Something to be added to xor, of course. ;-) Also the \mathon and \mathoff items should be taken away from tabular when not necessary for "center alignment" so with some \lastbox trickery one could dismantle a tabular row by row. – egreg Feb 27 '12 at 15:16
  • I see a stripped version of tabular coming up. ;) – Frg Feb 27 '12 at 15:30
3

Here’s an environment definition that will allow you to set long tables in multi-column environments (with either the multicols environment or the traditional \twocolumn declarations). It’s also compatible with vanilla longtable but also packages like tabu (for features like growing/shrinking paragraph columns), ltxtable, etc.

Note that some longtable features, like headers and footers at page / column breaks, will be absent, but it mostly works.

\newsavebox\ltmcbox
\newenvironment{fakelongtable}
        {\setbox\ltmcbox\vbox\bgroup
        \csname @twocolumnfalse\endcsname
        \csname col@number\endcsname\csname @ne\endcsname}
        {\unskip\unpenalty\unpenalty\egroup\unvbox\ltmcbox}

Example usage:

\begin{fakelongtable}
    \begin{longtable}{|l|l|l|}
        \tablines\tablines\tablines\tablines\tablines\tablines
    \end{longtable}
\end{fakelongtable}
9999years
  • 433
  • 2
  • 12