[Tex/LaTex] Know the cell width with tabular* or include a paragraph box without specifying its width

tables

I wrote the following table using tabular* inside a \newenvironment. Worked fine but I prefer to have text wrapping on one column. The table uses "phantom" cells to achive what I want that is having one column which takes all available width that all other three (visible) columns leaves, i.e. three columns takes its minimum width depending on the text written into them, and the other column takes the remaining width. The total width is \linewidth, so that's why I did use tabular* instead of tabular. The MWE:

\documentclass{article}
\begin{document}
\begin{tabular*}{\linewidth {|c|l@{\extracolsep{\fill}}cc@{\extracolsep{0pt}}|r|r|}
minwidth& remaining width &&& minw & minw\\
x & x &&& x & x
\end{tabular*}
\end{document}

Now, what I want is text wrapping on the second visible column (the "big" one). Neither a parbox nor a p-like column can be used because of the dynamically-adjusted columns. I don't know how to read the column width of the second column to include a parbox with this width to allow text wrapping into lines.

It is possible to read a length in which tabular* stores the width of the current cell? or there is a way to include some paragraph box without specifying its length?

I can't use tabu because of [1]. Also may work tabularx but it requires some redefinition of the enddef when including it inside a new environment. Tabularx exhibited another issue which I don't remember now, but if what I need is not possible with tabular*, I'll try again with tabularx.

I did read [2]. Using '<' and '>' in column definition with lrbox doesn't solve my problem because the size of the box is restricted to the size of its contents, not the size of the resulting column.

Also I did try with zref-savepos to save the x-position of two columns to later take its difference and substracting \tabcolsep and \arrayrulewidth:

\documentclass{article}
\usepackage{zref-savepos}
\newlength{\auxleng}
\newsavebox{\auxbox}
\newenvironment{auxenviron}
{\begin{lrbox}{\auxbox}}{\end{lrbox}\usebox{\auxbox}\global\setlength{\auxleng}{\wd\auxbox}}
\begin{document}
\begin{tabular*}{\linewidth}{|c|l@{\extracolsep{\fill}}cc@{\extracolsep{0pt}}|r|r|}
minw & \zsaveposx{XX}remaining width &&& \zsaveposx{XXX} minw & minw\\
x & \setlength{\auxleng}{\zposx{XXX} sp}\addtolength{\auxleng}{-\zposx{XX} sp}\parbox{\auxleng}{asdf}&&& x & x
\end{tabular*}
\end{document}

…but every time the document is compiled, the second reference moves to the right because tabular* recalculates the position of the 2th column.

[1] Can't include a 'tabu' inside \newenvironment with cells in the postamble

[2] \parbox "textwidth" for the combined width of a subset of table cells

Best Answer

Package tabularx can help. Since you are using \newenvironment, you cannot use \begin{tabularx} and \end{tabularx}, because then \end{tabularx} is hidden. However, \tabularx and \endtabularx works:

\documentclass{article}
\usepackage{tabularx}

\newenvironment{mytab}{%
  \tabularx
}{%
  \endtabularx
}

\begin{document}
\noindent
\begin{mytab}{\linewidth}{|c|X|r|}
minwidth& remaining width minw & minw\\
x & x & x\\
\end{mytab}
\end{document}

Result

It is also possible to catch the contents of the environment via package environ (some restrictions for \verb stuff). Perhaps you can add your mysterious stuff at the end of the table more easily.

\documentclass{article}
\usepackage{tabularx}
\usepackage{environ}

\NewEnviron{mytab}{%
  \expandafter\mytabaction\expandafter{\BODY}%
}
\newcommand{\mytabaction}[1]{%
  \begin{tabularx}#1\end{tabularx}%
}

\begin{document}
\noindent
\begin{mytab}{\linewidth}{|c|X|r|}
minwidth& remaining width minw & minw\\
x & x & x\\
\end{mytab}
\end{document}
Related Question