# Is it possible to make an underfull tabulary spread out?

With this MWE

\documentclass{article}
\usepackage{tabulary}

\begin{document}

\hrule

\begin{center}
\begin{tabulary}{\textwidth}{|L|L|L|}
foo&bar&baz
\end{tabulary}
\end{center}

\hrule

\end{document}


I get a table which is narrower than the page:

But I'd like the table to be spread out to \textwidth like tabularx would do. Is this possible?

Or is there an alternative approach?

• tabulary won't make a column wider than needed. It first typesets the table as if it were lll and then sets the widths only for columns that need to be set as paragraphs. Dec 15 '12 at 11:33
• @egreg Thanks for the explanation of the behaviour. I still think it's counterintuitive because I see tabulary as a more intelligent tabularx and tabularx does spread out. Dec 15 '12 at 14:08
• They have different purposes; try foo&bar&\lipsum[1] to see what happens. Dec 15 '12 at 14:12
• As soon as the table is overfull the result is as expected. I was looking at the underfull case. Dec 15 '12 at 14:22
• I think it does with negative coefficients: \begin{tabu}to\linewidth{X[-1,l]|X[-1,l]|X[-1,l]} (not sure, though) Dec 15 '12 at 15:36

tabu seems to do what you want given one specifies negative coefficients to the X columns. Quoting the manual:

negativ width coefficients can be given to X columns:

ex. X[-2.5]X[1] or X[-2.5]X or X[-5]X[2]

In this case, the first X column will be at most two and a half wider than the second one, and if the natural width of the first X column is finally less than 2.5 × (the width of the second column) then it will be narrowed down to this natural width.

tabu forgets to put a \strut in its cells, though, a fact one probably should keep in mind.

\documentclass{article}
\usepackage{tabu}
\usepackage{lipsum}
\begin{document}
\hrule
\begin{center}
\begin{tabu}to\linewidth{|X[-1,l]|X[-1,l]|X[-1,l]|}
foo&bar&baz
\end{tabu}
\end{center}
\hrule
\begin{center}
\begin{tabu}to\linewidth{|X[-1,l]|X[-1,l]|X[-1,l]|}
foo&bar&\lipsum[2]
\end{tabu}
\end{center}
\hrule
\begin{center}
\begin{tabu}to\linewidth{|X[-1,l]|X[-1,l]|X[-1,l]|}
foo foo foo foo foo foo foo &bar&baz
\end{tabu}
\end{center}
\hrule
\end{document}


The patch in the other answer probably ought to have worked but it turns out the division algorithm used isn't really that accurate in the case that it is scaling up, and as Stephen noticed if you simply let it scale, rounding errors make the table wider than the line and you get overfull box warnings. This is basically the same but corrects the division result before scaling up the table.

\documentclass{article}
\usepackage[debugshow]{tabulary}

\makeatletter

\def\foo#1\def\TY@ratio#2#3!!{
\def\TY@checkmin{#1%
\@tempdima\TY@ratio\TY@tablewidth
\ifdim\@tempdima>\TY@linewidth
\Gscale@div\@tempb\@tempdima\TY@tablewidth
\@tempdimb\TY@ratio\p@
\edef\TY@ratio{\strip@pt\@tempdimb}%
\fi
#3}}
\expandafter\foo\TY@checkmin!!

\makeatother

\begin{document}

\hrule

\begin{center}
\begin{tabulary}{\textwidth}{|L|L|L|}
foo&bar&baz
\end{tabulary}
\end{center}

\hrule

\end{document}


Ok, I now made the following patch:

\usepackage{etoolbox}
\makeatletter
\patchcmd\TY@checkmin
{\def\TY@ratio{1}}
{%
\@tempdima\dimexpr\p@*\TY@linewidth/\TY@tablewidth\relax
\edef\TY@ratio{\strip@pt\@tempdima}%
}{}{}
\let\TY@@checkmin\TY@checkmin
\makeatother


which seems to do what I want:

Still, the calculation doesn't seem to be as exact as it could be and I'd like to know whether there is a more suitable solution.

Furthermore, I'm more or less undoing an explicit special case from the package code, so I assume it was there for a reason ;-)

## Edit

Note that tabulary still behaves differently from tabularx in this case. See for instance

\begin{center}
\begin{tabulary}{\textwidth}{|L|L|L|}
foo foo foo foo foo foo foo &bar&baz
\end{tabulary}
\end{center}


So even when "spreading", the column width is still proportional to the amount of material in the column, which seems to be a good thing to me.

• And where does it differ from \begin{tabularx}{\textwidth}{|*{3}{>{\raggedright\arraybackslash}X|}}? Dec 15 '12 at 14:17
• It is different in the case that the table is overfull. Dec 15 '12 at 14:19
• Never assume reason, especially when shown signs of unreasonable behaviour. Dec 16 '12 at 0:29
• @DavidCarlisle I'd still like to know which behaviour (when there is "too little" material in the table) you prefer, and why. Dec 16 '12 at 0:39
• As you commented in chat, the current behaviour seems a little unintuitive as you specify a table width and get a smaller one. It's all a long time ago but I suspect the reason was that TY began life as a request from someone doing automated publishing from SGML and wanted a table macro that just "did the right thing"™ In that scenario the width argument was never consciously used (was always \textwidth) and the package set the table to natural with and only kicked in if it was too wide. But for human authoring you could decide to use tabular if you don't want the forced width.... Dec 16 '12 at 0:48