Writing a table with equally spaced columns, based on the widest column
Well, I've been solving this problem before and I ended with quite a universal solution, see the example (you need to run the code twice to get the correct result):
\documentclass{article}
\usepackage{array}
\makeatletter
\newlength\eqcol@newlen
\newlength\eqcol@oldlen
\let\eqcol@bc\hfil
\let\eqcol@ec\hfil
\let\eqcol@br\hfil
\let\eqcol@el\hfil
\newcolumntype{e}[1]{%
>{\setbox0\hbox\bgroup}#1%
<{\egroup
\ifdim\wd0<\eqcol@newlen\else\global\eqcol@newlen\wd0\fi
\ifdim\wd0<\eqcol@oldlen\else\global\eqcol@oldlen\wd0\fi
\hbox to \eqcol@oldlen{%
\csname eqcol@b#1\endcsname
\box0 %
\csname eqcol@e#1\endcsname
}%
}%
}
\newcount\eqcol@count
\def\eqcolRead{%
\global\advance\eqcol@count1 %
\eqcol@oldlen5em\relax
\csname eqcol@def@\romannumeral\eqcol@count\endcsname
}
\def\eqcolWrite{%
\immediate\write\@auxout{%
\gdef\expandafter\noexpand\csname eqcol@def@\romannumeral\eqcol@count\endcsname
{\global\eqcol@oldlen\the\eqcol@newlen\relax}%
}%
\global\eqcol@newlen0pt\relax
}
\let\eqcol@old@tabular\tabular
\def\tabular{\eqcolRead\eqcol@old@tabular}
\let\eqcol@old@endtabular\endtabular
\def\endtabular{\eqcol@old@endtabular\eqcolWrite}
\makeatother
\begin{document}
\begin{tabular}{|el|er|}
\hline
111 & 22 \\\hline
33 & 4444444 \\\hline
\end{tabular}
\begin{tabular}{|ec|er|}
\hline
1 & 22 \\\hline
3 & 4 \\\hline
\end{tabular}
\begin{tabular}{|el|er|}
\hline
111 & 22 \\\hline
33 & 444444 \\\hline
\end{tabular}
\[
A =
\eqcolRead\begin{array}{*3{ec}}
1 & 10000 & 1 \\ 1 & 1 & 1
\end{array}\eqcolWrite
\]
\end{document}
The tabular
environment is tweaked by default, in other cases, you have to do it manually (see the array
example above).
This is inspired by tohecz, but uses a dedicated environment, which I believe is better.
In a equalizedtabular
one can use any column specifier, not just L
, C
or R
, but of course only these will be equalized. Two passes are necessary, since the .aux
file is used, and upon inclusion of an equalizedtabular
between two of them the first compilation will give wrong results; however, the next run of LaTeX will fix the lengths.
\documentclass{article}
\usepackage{array,collcell}
\newcolumntype{C}{>{\collectcell\docellC}c<{\endcollectcell}}
\newcolumntype{L}{>{\collectcell\docellL}c<{\endcollectcell}}
\newcolumntype{R}{>{\collectcell\docellR}c<{\endcollectcell}}
\makeatletter
\providecommand{\@nameedef}[1]{\expandafter\edef\csname#1\endcsname}
\newcommand{\docell}[2]{%
\sbox\equalizedtablebox{#2}%
\ifdim\wd\equalizedtablebox>\@nameuse{finallen\theequalizedtable}\relax
\global\@nameedef{finallen\theequalizedtable}{\the\wd\equalizedtablebox}%
\fi
\makebox[\@nameuse{startinglen\theequalizedtable}][#1]{#2}%
}
\newcommand{\docellC}[1]{\docell{c}{#1}}
\newcommand{\docellL}[1]{\docell{l}{#1}}
\newcommand{\docellR}[1]{\docell{r}{#1}}
\newcounter{equalizedtable}
\newsavebox\equalizedtablebox
\newenvironment{equalizedtabular}[2][c]
{%
\stepcounter{equalizedtable}%
\global\@namedef{finallen\theequalizedtable}{0pt}%
\@ifundefined{startinglen\theequalizedtable}
{\@namedef{startinglen\theequalizedtable}{5em}}{}
\tabular[#1]{#2}%
}
{%
\endtabular
\begingroup\edef\x{\endgroup
\write\@auxout{%
\global\noexpand\noexpand\noexpand\@namedef{startinglen\theequalizedtable}%
{\@nameuse{finallen\theequalizedtable}}%
}}\x
}
\makeatother
\begin{document}
\begin{equalizedtabular}{|L|C|}
\hline
111 & 22 \\\hline
33 & 4444444 \\\hline
\end{equalizedtabular}
\begin{equalizedtabular}{|R|C|}
\hline
111 & 22 \\\hline
33 & 4 \\\hline
\end{equalizedtabular}
\end{document}
I'd change the input syntax a bit:
\documentclass{article}
\makeatletter
\def\paulo#1{\count@#1\relax\leavevmode\setbox\z@\vbox\bgroup}
\def\endpaulo{\egroup\dimen@\wd\z@\global\setbox\@ne\null
\setbox\z@\vbox{\unvbox\z@\loop\unskip\unskip\setbox\z@\lastbox
\ifvoid\z@\else
\global\setbox\@ne\hbox{\hbox to\dimen@{\box\z@\hfil}\penalty\z@\unhbox\@ne}%
\repeat}%
\vbox{\hsize\count@\dimen@\noindent\unhbox\@ne}}
\def\cell#1{\hbox{\kern\tabcolsep\ignorespaces#1\unskip\kern\tabcolsep}}
\makeatother
\begin{document}
\begin{paulo}{2}
\cell{a}
\cell{b}
\cell{c}
\cell{Mary had a little lamb}
\end{paulo}
\end{document}