rolfn/xltabular

Using more than 37 multicolumn causes width calculations to break.

Closed this issue · 8 comments

The example code below generate overfull boxes (which in the real world example causes terrible layout of course since
the cell widths become tiny, which is the cause for the overfull problem.)

The problem disappears if I:
Drop the [margin=3cm] or the whole geometry package.
or
Drop one of the tlxmulticolumn lines. So instead of 38, there are 37.

The tlxmulticolumn is based on the information I read here:
https://tex.stackexchange.com/questions/236155/tabularx-and-multicolumn
I hope my tlxmulticolumn is not the cause of the problem, but I am not skilled enough to understand fhtis.

Many thanks for a great package!

\documentclass[10pt,a4paper]{article}
\usepackage{xltabular}
\usepackage[margin=3cm]{geometry}

\overfullrule=10pt

\newcommand{\tlxmulticolumn}[3]
    {\multicolumn{#1}
                 {>{\hsize=\dimexpr#1\hsize+#1\tabcolsep+\arrayrulewidth\relax}#2}
                 {#3}}

\begin{document}
\begin{xltabular}{\linewidth}[l]{lll}
a&b&c\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
a&\tlxmulticolumn{2}{X}{$xxx$}\\
\end{xltabular}
\end{document}

If I change the line specifier from lll to lXX which makes more sense considering that the multicolumn is X, then you get the same error. Which can be fixed by removing the geometry package or deleteing some more tlxmulticolm lines.

rolfn commented

First of all: this is not an xltabular-specific problem. With tabularx it also occurs. Otherwise: I suspect that your definition of \tlxmulticolumn is incorrect. Try these instead:

\newcommand*{\tlxmulticolumn}[3]{\multicolumn{#1}%
  {>{\hsize=\dimexpr#1\hsize+\tabcolsep*(#1+1)\relax}#2}{#3}}

Or, if arrayrulewidth matters:

\newcommand*{\tlxmulticolumn}[3]{\multicolumn{#1}%
  {>{\hsize=\dimexpr#1\hsize+\tabcolsep*(#1+1)+\arrayrulewidth(#1-1)\relax}#2}{#3}}

I am not completely sure this is correct. You should experiment a little. In addition, you should write \noindent in front of the table to remove the paragraph indentation.

...Rolf

rolfn commented

Another addition: The distances in tables are as follows (example 3 columns).

| t [---h---] t | t [---h---] t | t [---h---] t |

With:

| = \arrayrulewidth (if available)
t = \tabcolsep
h = \hsize 

...Rolf

Many thanks! I have now done some more testing. The tlxmulticolumn macro is not the cause of the problem.
However, the macro does not do what one expects when covering all three columns since the macro only
works for covering the XX columns. I have lXX and the width of the l cannot be calculated by the macro as is.

Have a made a workaround for the 3col span with 0.95\textwidth. This gives the right colspanning. (well close enough.)
However the problem that the rendering breaks down when more than a certain number of lines have been added to the table, is still there. As you say, this exists in tabularx, but the problem occurs more often when doing xltabular since you usually have many more lines in an xltabular. :-)

Here is my current example code. The first table is short and always works. The second table renders broken.
But if you remove the last \foo then it will render fine. You can trigger the render bug earlier if you shrink the margins,
ie widen the linewidth.

\documentclass[10pt,a4paper]{article}
\usepackage{parskip}
\usepackage{xltabular}

\overfullrule=10pt

\newcolumntype{R}{>{\raggedright\arraybackslash}X}

\newcommand*{\spantwo}[1]{\multicolumn{2}{>{\hsize=\dimexpr 2\hsize+2\tabcolsep\relax\raggedright\arraybackslash}X|}{#1}}
\newcommand*{\spanthree}[1]{\multicolumn{3}{|>{\hsize=0.95\textwidth\relax\raggedright\arraybackslash}X|}{#1}}

\begin{document}
\raggedright

\newcommand{\foo}{a & $x>0 \land x>0 \land x>0 \land x>0 \land x>0 \land x>0$ & A comment comment comment. \\ \hline
b & \spantwo{$x>0 \land x>0 \land x>0 \land x>0 \land x>0 \land x>0 \land x>0 \land x>0 \land x>0 \land x>0 \land x>0 \land x>0 \land x>0 \land x>0 \land x>0 \land x>0 \land x>0$} \\ \hline
\spanthree{A comment comment comment comment comment comment comment comment comment comment comment comment.} \\ \hline
}

\begin{xltabular}{\linewidth}{|l|R|R|} \hline
  \foo
  \foo
  \foo
\end{xltabular}

\begin{xltabular}{\linewidth}{|l|R|R|} \hline
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo
  \foo % Remove this line and table magically works again.                                                                                                                                                                           
\end{xltabular}

\end{document}

I do not know how the X width calculation is done for columns where you have changed the hsize?
Is it a rounding error for the X calculation that gets added for each multicolumn line and eventually
trips over?

rolfn commented

Sorry, but I don't have enough time to dig deep into the problem. A hint: Perhaps the dimension register \TX@col@width will help (see xtabular documentation). For more convenient handling without \makeatletter.

\expandafter\let\expandafter\TXcolWidth\csname TX@col@width\endcsname

I hope this helps.

Thanks for the help! I have create a bug here: latex3/latex2e#630