2

I need to create some tables for a special college report. The data provided specifies the values column by column.

The user Andrew Swann pointed out, that there is a way to create TeX tables column by column which was completeley new to me, but would be a great benefit for my special purpose.

Unfortunately I neither understand those commands nor didn't find a good documentation for that. What I need is a table with borders around each single cell except for the first cell and the whole last row. Below is an example how it would look like using the regular syntax.

Could you please tell me how I can create such a table by building it columnwise?

Result of example code

\begin{tabular}{|l|l|l|}
    \cline{2-3}
    \multicolumn{1}{l|}{a} & b & c \\ \hline
    d & e & f \\ \hline
    g & h & i \\ \hline
    \multicolumn{1}{l}{j}  &
    \multicolumn{1}{l}{k}  &
    \multicolumn{1}{l}{l}  &
\end{tabular}
1

The macros \halign and \valign are documented in the TeXbook. More accurately \halign is described in detail there, and \valign is introduced briefly, saying that is analogous.

The \valign statement starts with a preamble than has the form

pre-row-1 # post-row-1& pre-row-2 # post-row-2& .... & ... # post-row-n\cr

the table material is for the given column is inserted in place of the #'s much as in macros. A short cut is that an extra & at the beginning or immediately after another &, means that the format material from that point up to the \cr is repeated for all subsequent rows. Thus a preamble

&pre-row # post-row\cr

produces an arbitrary number of rows with the same format.

In the table you add entries in the usual way; rows separated by &, column ending with \cr. A complete column format specification can be replaced by other material via \noalign{...}; so \noalign{\vrule} produces a vertical rule the whole way down the table. A single row is replaced by writing \omit<...> where <...> is the new material. The analogue of \multicolumn is \multispan, thus \multispan3<...> will spread <...> over three rows.

Here is your example:

Sample output

\documentclass{article}

\begin{document}

\valign{% Preamble
&\hrule\vskip 2pt plus 1fil\hbox{\strut\quad #\quad}\vfil\cr
%         First rule empty row one, span across rows 2 and 3, empty in row 4
\omit&\multispan2\leaders\vrule\vfil&\omit\cr
%         First column, first cell has non-standard format without rule
\omit \vskip 2.4pt plus 1fil\hbox{\strut\quad a\quad}\vfil&d&g&j\cr
%         Second vertical rule, span rows 1 to 3, empty row 4
\multispan3\leaders\vrule\vfil&\omit\cr
%         Second column, all cells are regular
b&e&h&k\cr
\multispan3\leaders\vrule\vfil&\omit\cr
c&f&i&l\cr
\multispan3\leaders\vrule\vfil&\omit\cr}

\end{document}

The preamble says each row starts with a horizontal rule, a vertical space of 2pt that can stretch followed by a horizontal box containing the material (padded with \quad space on each size and with a guaranteed minimum height and depth from \strut) followed by stretchable vertical space.

\leaders\vrule\vfil is what \vrulefill ought to be, but the command happens not to be defined, this is used in combination with \multispan to draw the vertical rules over the appropriate rows.

When we use \omit for the box containing a we have to provided the relevant parts of the formatting that we still need. The extra .4pt on the \vskip accounts for the thickness of the \hrule.

An alternative approach to the whole table would be to provide separate rows for the rules, but then this essentially doubles the number of &s we have to write.

0
1

stackengine package builds stacks vertically. I EDITED the answer to make sure it works with changes in \fboxsep and \fboxrule. Two examples shown below. A further EDIT allows for cell content to be of variable width. There are five parameters you can adjust, fboxrule, \fboxsep, \mystrutheight, \mystrutdepth, and \horzbuffer. The last of these is the horizontal gap added to the cell width.

EDITED to reflect name change of internal routine.

\documentclass{article}
\usepackage{stackengine}
\usepackage{readarray}
% YOU CONTROL THE NEXT FIVE LINES
\fboxsep=3pt
\fboxrule=.25pt
\def\mystrutheight{.7\baselineskip}
\def\mystrutdepth{.1\baselineskip}
\def\horzbuffer{2ex}
%
\def\mybox{}
\newcounter{index}
\newlength\cellwidth
\newlength\colwidth
\newcommand\myLongstack[1]{%
  \renewcommand\mybox[1]{##1}%
  \getargsC{#1}%
  \setlength\colwidth{0pt}%
  \setcounter{index}{0}%
  \whiledo{\value{index} < \narg}{%
    \stepcounter{index}%
    \setlength\cellwidth{\widthof{\csname arg\roman{index}\endcsname}}%
    \ifthenelse{\cellwidth > \colwidth}{%
      \setlength\colwidth{\the\cellwidth}}{}%
  }%
  \setlength\colwidth{\the\colwidth + \horzbuffer}%
  \xdef\myboxwidth{\the\colwidth}%
  \renewcommand\mybox[1]{\kern -\fboxrule\protect\framebox[\myboxwidth]{%
    \protect\rule[-\mystrutdepth]{0ex}{\mystrutheight}\smash{##1}}}%
  \Longstack{#1}%
}
\setstackgap{L}{\mystrutheight+2\fboxsep+\fboxrule}
\begin{document}
\myLongstack{a         \mybox{d} \mybox{g} j}%
\myLongstack{\mybox{b} \mybox{e} \mybox{h} k}%
\myLongstack{\mybox{c} \mybox{f} \mybox{i} l}
%
\fboxsep=4pt
\fboxrule=1pt
\def\mystrutheight{.7\baselineskip}
\def\mystrutdepth{.15\baselineskip}
\myLongstack{a         \mybox{d} \mybox{g} j}%
\myLongstack{\mybox{b} \mybox{eeeee} \mybox{h} k}%
\myLongstack{\mybox{c} \mybox{f} \mybox{i} l}
\end{document}

enter image description here

4
  • Your solution provides an easy way to achieve the example pattern, but unfortunately the boxes don't 'grow' like columns do. If I e.g. change 'e' to 'eeeeee', is there any way to modify the solution (only) the second column grows to hold the new content without line breaks? – muffel Aug 13 '13 at 14:12
  • @muffel Will you know which is the widest element in a column, or could it be anywhere in each column? – Steven B. Segletes Aug 13 '13 at 15:19
  • Could be anywhere. The content is dynamically generated, and I do not have any influence on the content itself or its order. – muffel Aug 13 '13 at 15:52
  • 1
    @muffel Revised to do as you ask. – Steven B. Segletes Aug 13 '13 at 16:10

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.