# Measure the column width of a table

Is there a way to determine the width of the first column in a tabular enviroment?

I've thought about using a savebox but that would only give me the size of the text (and in one cell only), not the actual column width.

Or should I use longtable (or another package) to do that?

• Might be an idea to tell us what you are trying to do. Then we can figure out a good solution. – daleif Jan 7 '14 at 10:44
• yes, tell us a higher level picture. maybe you don't even need the size of the column. – Apiwat Chantawibul Jan 7 '14 at 12:02

This has some limitations on the tabular: you can't have \multicolumn in the last row, nor optional arguments to \\ (this one may be lifted off).

\documentclass{article}
\usepackage{environ}

\makeatletter
\NewEnviron{mtabular}[3][c]{%
\begingroup
\renewcommand{\multicolumn}[3]{\multispan{##1}##3}%
\let\\\cr
\setbox\tw@=\vbox{%
\ialign{&##\unskip\hfil\cr\BODY\crcr}%
\get@widths{#3}%
}%
\endgroup
\begin{tabular}[#1]{#2}\BODY\end{tabular}}

\def\get@widths#1{%
\def\@temp{\else\@latex@warning{No such column}\fi}
\setbox\z@=\lastbox
\get@next@width
\xdef#1##1{%
\noexpand\ifcase##1\relax\unexpanded\expandafter{\@temp}%
}%
}
\def\get@next@width{%
\setbox\z@=\hbox{\unhbox\z@\unskip\global\setbox\@ne=\lastbox}%
\ifvoid\@ne
\else
\edef\@temp{\noexpand\or\the\wd\@ne\unexpanded\expandafter{\@temp}}%
\expandafter\get@next@width
\fi
}
\makeatother

\begin{document}

\begin{mtabular}{lcr}{\foo}
abc & def & ghi \\
ABC & \multicolumn{2}{c}{aaa} \\
1 & 12 & 123
\end{mtabular}

The width of the first column was \foo{1}

The width of the second column was \foo{2}

The width of the third column was \foo{3}

\end{document}


It works by first typesetting the table in a “reduced” form, then taking off its last row and dismantling it bit by bit. The last argument to mtabular is a macro name that can later be used with a numeric argument for getting the relative column width.

• +1 and accepted, thanks. But shouldn't there be % at the end of the line before \endgroup. I think this might cause some unwanted spacing. – masu Jan 7 '14 at 13:51
• @SándorKazi Yes, there should be. Still, an use example would be better, to clarify your aims. – egreg Jan 7 '14 at 13:52
• I was just curious if it was possible. Here's what made me curious: tex.stackexchange.com/q/152784/36821 I've constructed an answer for this question based on your solution for this one. – masu Jan 7 '14 at 15:30
• Will this also work for longtable? – Niranjan Sep 25 '19 at 2:28
• @Niranjan No: longtable doesn't build all the table in one swoop and uses multiple runs of LaTeX to stabilize the column widths. – egreg Sep 25 '19 at 9:20
\documentclass{article}
\usepackage{array}

\makeatletter
\protected\def\z#1{\pdfsavepos\write\@auxout{\gdef\string\tpos#1{\the\pdflastxpos}}}%
\def\foo#1#2{\ifcsname tpos#1\endcsname\the\dimexpr\csname tpos#2\endcsname sp -\dimexpr\csname tpos#1\endcsname sp\relax\fi}
\makeatother

\begin{document}

\begin{tabular}{!{\z{a}}l!{\z{b}}c!{\z{c}}r!{\z{d}}}
abc & def & ghi \\
ABC & \multicolumn{2}{c}{aaa} \\
1 & 12 & 123
\end{tabular}

The width of the first column was \foo{a}{b}

The width of the second column was \foo{b}{c}

The width of the third column was \foo{c}{d}

\end{document}


Slightly different result than egreg, as the code takes a different view of whether tabcolsep padding is included or not.

• +1, great, but egreg's answer is a little more generic (You have to actually print to table to use this, so it can't effect the the actual table. Or am I mistaken?) – masu Jan 7 '14 at 13:49
• @SándorKazi You can use the lengths within the table, latex will sort itself out on the next run. – David Carlisle Jan 7 '14 at 14:03