12

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?

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

2 Answers 2

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

5
  • +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, 2014 at 13:51
  • @SándorKazi Yes, there should be. Still, an use example would be better, to clarify your aims.
    – egreg
    Jan 7, 2014 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, 2014 at 15:30
  • Will this also work for longtable?
    – Niranjan
    Sep 25, 2019 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, 2019 at 9:20
13
\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.

2
  • +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, 2014 at 13:49
  • 1
    @SándorKazi You can use the lengths within the table, latex will sort itself out on the next run. Jan 7, 2014 at 14:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .