10

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
12

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.

enter image description here

| improve this answer | |
  • +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
11
\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}

enter image description here

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

| improve this answer | |
  • +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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.