[Tex/LaTex] tables with column width that depends on the width of table entries

spacingtables

  1. Is there an easy way to specify that a table should have columns of a width such that the beginning of a each new column is of a user-specified and column-independent distance to the end of the longest entry of the preceding column?

  2. Is there a way to specify that all columns in a table should be of equal width, namely the width of the longest table entry plus some epsilon (that may or may not be user-specified)?

Best Answer

@1: You can make use of the @{} notation to insert spaces between columns. Setting up a tabular with columns defined as {l@{\hspace{1cm}}l} would insert 1 cm of space between the two left-aligned columns, which, due to their nature, have the width of their respective longest entry each.

@2: There's an easy solution for the case "may not be user-specified"* using the tabu package. A tabu allows to specify the table width and accordingly adjusts the width of columns of type X. The column width does indeed _not_ depend on the lenght of the longest entry, but if the table width (.7\textwidth in the example) is of a sufficient amount, the epsilon, as you call it, will be 1/nth of the space necessary to stretch the width of n columns to the specified width of the table. Hence, as long as you ensure that the table width is sufficient (e.g. by using the default of `\textwidth, which you'd usually not want to exceed anyway), you get the desired result. The drawback is that the table doesn't get _less_ wide than specified.

Remarks

  • Line breaking in X columns can be prevented e.g. by inserting the text into an \mbox.
  • The code shown below also contains the intercolumn space specification proposed in (1), which you may set as desired. In the example, \hspace is used purely for demonstration purposes; in case of 0 cm, @{} could simply be used. Since 0 cm of intercolumn space are specified, the distance between two columns is entirely due to their width (to be observed by replacing \hspace with a vertical line @{}|@{} in the column definitions).
  • With tabu, you could moreover specify that rather than all columns being equal in width, e.g. the first should be twice as wide as the others. This can be achieved by accordingly setting the optional parameter in the column definition, e.g. to X[2] for the first column.

Example

enter image description here

Code

\documentclass{article}
\usepackage{tabu}
\usepackage{booktabs}

\begin{document}    
    \begin{tabu} to .7\textwidth {  X[1]@{\hspace{0cm}}
                                    X[1]@{\hspace{0cm}}
                                    X[1]}
        a & b & c\\\toprule
        123
            & some long text
            & 123\\\bottomrule
    \end{tabu}      
\end{document}

Notes

*Your case "epsilon is user-specified" requires the table width to be not specified but dynamically determined. Currently I don't see an easy way of setting up equal-width columns in a table of variable width, but probably someone else will (cf. Addendum).

**A similar result can be achieved with tabularx. tabu however has a more convenient user interface.

***You can specify the column widths to be maximum values by adding a minus as prefix. Column widths specified this way however are no longer synchronously adjusted, and as far as I know, you cannot specify a maximum width for the complete table.


Addendum

I should add that the comment given in the first footnote was based on my implicit, but maybe false assumption that you would not know the length of the longest entry when setting up the table. Should this not be a requirement, then the solution is straightforward: You just need to measure the length of a box containing the longest entry and then define the columns based on this length.

In the code given below, a command \setwidth is called with a text and a dimension as parameters. It sets \width, which then is used as width of each column. Except the text of the entry, the two table definitions shown in the example are identical.

enter image description here

\documentclass{article}
\usepackage{calc}
\usepackage{booktabs}
\usepackage{lipsum} 

\newlength\width

%measure length of a given text (#1) and add some space (#2)
\newcommand{\setwidth}[2]{%
    \settowidth{\width}{#1}
    \setlength{\width}{\width+#2}%
}

\begin{document}

\setwidth{short entry}{10pt}    

\lipsum[75]

\begin{table}[ht]
    \begin{tabular}{p{\width}p{\width}p{\width}}
    a & b & c\\\toprule
    1 & short entry & 3\\\bottomrule
    \end{tabular}
\end{table}

\lipsum[75] 

\setwidth{considerably longer cell entry}{10pt} %which will make the table overly wide

\begin{table}[ht]
    \begin{tabular}{p{\width}p{\width}p{\width}}
    a & b & c\\\toprule
    1 & considerably longer cell entry & 3\\\bottomrule
    \end{tabular}
\end{table}

\lipsum[75] 

\end{document}
Related Question