# Define a table one column at a time instead of one row at a time

Is there a way to define a table like so?

\begin{tabular}{|c|c|}
column 1, row 1 \\
column 1, row 2 \\
column 1, row 3 \\
column 1, row 4 \\
column 1, row 5 \\ &&
column 2, row 1 \\
column 2, row 2 \\
column 2, row 3 \\
column 2, row 4 \\
column 2, row 5 \\
\end{tabular}


I'm flexible as to how it's done, I would just like to be able to define a whole column at a time (as each column's entries are highly inter-related, and not as much from row to row).

-
The tabular environment uses the plainTeX \halign primitive internally which needs the row-by-row format. This can't be changed. One funny idea would be to turn every cell 90degrees and then the whole table 90degr backwards, making effectively rows to columns and vice versa. However, then the cell alignment (c, l, r, ..) would not work as usual of course. –  Martin Scharrer Jul 3 '11 at 21:39
@Martin, Nate: \halign's counterpart is \valign which switches cols to rows, there's some rather nice examples of its use here in this site. –  morbusg Jul 4 '11 at 4:37
@morbusg: I know \valign but you can't just say {\let\halign\valign\begin{tabular}{..} .., can you? –  Martin Scharrer Jul 4 '11 at 5:15
@Martin: oh, right, I didn't think quite that far. Merely, your description rang a bell. :-) –  morbusg Jul 4 '11 at 7:14
I tried the three proposed methods. All of them work. Great examples. But, with the second method, the spaces betwen words are compressed. I added a title and text between the tables and observed that there aren't enough vertical space between tables and paragraphs. Probably an incorrect apreciation of mine, but the visual appearance is of a table too close to the text. Also, with the second method, the paragraphs does not wraps at the margin. –  djnavas Jul 6 '11 at 22:48

use two tabulars ...

\documentclass{article}

\begin{document}
\begin{tabular}[t]{|c}
column 1, row 1 \\
column 1, row 2 \\
column 1, row 3 \\
column 1, row 4 \\
column 1, row 5 \\
\end{tabular}%
\begin{tabular}[t]{|c|}
column 2, row 1 \\
column 2, row 2 \\
column 2, row 3 \\
column 2, row 4 \\
column 2, row 5 \\
\end{tabular}

\end{document}

-
Shame on me for not thinking of the obvious thing ;^). Obviously, these are two separate tables, so is there any way to set equal rubber column widths, like with tabularx's X? Or is the only option to set explicit widths with p{}? –  Nate Jul 3 '11 at 22:48
Actually, while I'm at it - is there a way to balance the number of rows across tables? Not all of my columns have the same number of rows, but (obviously) the \hlines at the bottom all need to line up. –  Nate Jul 3 '11 at 23:13
@Nate: then use [b] instead of [t] to align the tabulars at the bottom. –  Herbert Jul 4 '11 at 6:59
Ah, I guess I wasn't specific enough - I meant that I wanted both the top and the bottom to line up. I.e., some way to say "make these two tables the same height". For now it's not that big of a deal... I just put in filler. –  Nate Jul 4 '11 at 18:38

The code below defines a vtab environment which reads its body (thanks to the environ package) and splits it into columns, and cells (using some LaTeX3 code), then puts it back together in rows rather than columns, and places its two arguments before and after the result. It is used as

\begin{vtab}{\begin{tabular}{cccc}}{\end{tabular}}
a\\b\\c\\d&
e\\f&
g\\h\\i&
j\\k\\l\\m\\n\\o
\end{vtab}


There are some comments in the code below, don't hesitate to ask. Earlier, I forgot the \ExplSyntaxOff line, which restores the normal TeX behaviour (spaces not ignored).

\RequirePackage{expl3}
\RequirePackage{environ}
\ExplSyntaxOn
% \NewEnviron defines |\begin{vtab}| to grab until |\end{vtab}|
% and store the result in |\BODY|. Then two steps.
% (1) Split |\BODY| into cells, storing them in a property list.
% (2) Read the property list in a different order, building the
% body of the tabular as we go.
% (3) Typesetting the tabular.
%
\NewEnviron { vtab } [2]
{
\TV_build:
\tl_put_left:Nn \l_TV_result_tl { #1 }
\tl_put_right:Nn \l_TV_result_tl { #2 }
\tl_use:N \l_TV_result_tl
}

% We need some variables.
\int_new:N \l_TV_col_int
\int_new:N \l_TV_row_int
\int_new:N \l_TV_max_row_int
\prop_new:N \l_TV_cells_prop
\tl_new:N \l_TV_result_tl
\tl_new:N \l_TV_row_tl
\tl_new:N \l_TV_cell_tl

% Generic function to split a list with items delimited by a given token
% (in our application, either & or \\) and apply the third argument to
% each item that was found: this third argument will receive the item as
% |#1|. Used as |\TV_map_inline:nnn {\\} {a\\b\\c} {do #1}|.
%
% It is slightly tricky to get nesting to work (see e.g., explanations
% for |\clist_map_inline:nn| in |l3clist.dtx|).
%
\int_new:N \g_TV_map_inline_int
\cs_new_protected:Npn \TV_map_inline:nnn #1 #2 #3
{
\tl_if_empty:nF {#2}
{
\cs_gset_eq:cN
{TV_map_inline_\int_use:N \g_TV_map_inline_int :w}
\TV_map_inline_aux:w
\int_gincr:N \g_TV_map_inline_int
%
\cs_gset:Npn \TV_map_inline_aux:w ##1 #1
{
\quark_if_recursion_tail_stop:n {##1}
#3
\TV_map_inline_aux:w
}
\TV_map_inline_aux:w #2 #1 \q_recursion_tail #1 \q_recursion_stop
%
\int_decr:N \g_TV_map_inline_int
\cs_gset_eq:Nc
\TV_map_inline_aux:w
{TV_map_inline_\int_use:N \g_TV_map_inline_int :w}
}
}

% We split into columns first |&|, then rows |\\|. While doing this,
% we keep track of the index of the row and column, and what the
% highest row number is (this will be the number of rows in the
% resulting tabular). The cell's content is stored as the property
% "row,column" in |\l_TV_cells_prop|.
%
{
\int_zero:N \l_TV_col_int
\int_zero:N \l_TV_max_row_int
\TV_map_inline:nnn {&} {#1}
{
\int_incr:N \l_TV_col_int
\int_zero:N \l_TV_row_int
\TV_map_inline:nnn {\\} {##1}
{
\int_incr:N \l_TV_row_int
\exp_args:NNx \prop_put:Nnn \l_TV_cells_prop
{ \int_use:N \l_TV_row_int , \int_use:N \l_TV_col_int }
{ ####1 }
}
\int_compare:nT { \l_TV_row_int > \l_TV_max_row_int }
{ \int_set_eq:NN \l_TV_max_row_int \l_TV_row_int }
}
}

% To build, loop for |##1| from 1 to the number of rows,
% and for |####1| from 1 to the number of columns, and extract
% the relevant cell, then place it in the relevant row.
% The funny |\use_none:n| business removes the first |&| from
% each row as it is added to the result.
\cs_new:Npn \TV_build:
{
\tl_clear:N \l_TV_result_tl
\prg_stepwise_inline:nnnn {1} {1} { \l_TV_max_row_int }
{
\tl_clear:N \l_TV_row_tl
\prg_stepwise_inline:nnnn {1} {1} { \l_TV_col_int }
{
\prop_pop:NnNF \l_TV_cells_prop { ##1 , ####1 } \l_TV_cell_tl
{ \tl_clear:N \l_TV_cell_tl }
\tl_put_right:Nx \l_TV_row_tl { & \exp_not:V \l_TV_cell_tl }
}
\exp_args:NNf \tl_put_right:Nn \l_TV_result_tl
{ \exp_after:wN \use_none:n \l_TV_row_tl \\ }
}
}
\ExplSyntaxOff % [EDIT: added that line]
\documentclass{article}
\begin{document}
\begin{vtab}{\begin{tabular}{cccc}}{\end{tabular}}
a\\b\\c\\d&
e\\f&
g\\h\\i&
j\\k\\l\\m\\n\\o
\end{vtab}
\end{document}

-

Here is a plain-tex version using \valign, adapted from TH.'s awesome answer.

\valign{&\hbox spread1em{\strut#\hfil}\cr
column 1, row 1 & column 1, row 2 & column 1, row 3 & column 1, row 4 \cr
column 2, row 1 & column 2, row 2 & column 2, row 3 & column 2, row 4 \cr}
\bye

-
Do you think that this could be used as a basis for a tabular-like environment? (I tried, but failed) –  Bruno Le Floch Jul 5 '11 at 22:53
@morbusg - Now, how do you include borders as nice as the ones in tabular? I couldn't get it to do \hlines at all. –  Nate Jul 6 '11 at 13:15
@Bruno: I'm sorry to say I haven't yet got that far that I'd understand anything about LaTeX (I am still learning the primitives and plain-format). I did take a look at \def\tabular in latex.ltx, but I didn't really understand anything I saw. (lots and lots of @'s :-)) –  morbusg Jul 6 '11 at 13:51
@Nate: by borders do you mean rules around the whole construct? If so, you can just stuff the \valign inside a \fbox. (\fbox{\valign{...}}) –  morbusg Jul 6 '11 at 13:56
@morbusg: I understand. Tabulars in LaTeX are quite complicated. I'll ask "GL" (author of the tabu package, vary talkative on comp.text.tex) if he plans to do anything like that. –  Bruno Le Floch Jul 6 '11 at 14:23