# How to use commands in table specs, and still support array package?

For a package, I want to write code that creates tables, where the exact type of table is configurable (tabular, longtable, tabularx, ... [Update: David rightly remarked that formats like tabularx would be harder to use in a configurable way, as they need more parameters]), and where the number of columns is determined by the program (so table specs like l|l are computed; details do not matter here). The following simple code works with LaTeX tables:

\def\mytablespec{l|l}
\def\mytabletype{tabular}
\begin{\mytabletype}{\mytablespec}
1 & 2 \\\hline
3 & 4 \\
\end{\mytabletype}


However, if the package array is loaded, the code fails with the error

Package array Error:  Illegal pream-token (\mytablespec): c' used.


The problem is that array does not expand table specs. One can force this as follows:

\def\mytablespec{l|l}
\expandafter\tabular\expandafter{\mytablespec}
1 & 2 \\\hline
3 & 4 \\
\endtabular


This code works with or without the array package. However, this code no longer uses a command to define the table type. I did not manage to combine \expandafter with \begin{\mytabletype}...\end{\mytabletype}. The following, however, seems to work:

\expandafter\csname\expandafter\mytabletype\expandafter\endcsname\expandafter{\mytablespec}
1 & 2 \\\hline
3 & 4 \\
\csname end\mytabletype\endcsname


[Update: David pointed out that the following simpler version also works:

\csname\mytabletype\expandafter\endcsname\expandafter{\mytablespec}
1 & 2 \\\hline
3 & 4 \\
\csname end\mytabletype\endcsname


]

Besides being quite ugly, this assumes that environments like tabular and longtable always provide two corresponding commands, such as \tabular and \endtabular. This seems to be the case for many packages, but I could not find out if there is a general reason why this should be the case.

Is this the right way to solve this problem? Is there a cleaner/easier solution? In general, the behaviour of tables changes quite a bit if array is loaded (it also modifies table width computation in incompatible ways); is there maybe a more general approach to make packages robust against such things?

-

You have more \expandafter than needed

\csname\mytabletype\expandafter\csname\expandafter{\mytablespec}


would work for the \mytabletype tabular case, although I'm not sure how your actual code copes with the different argument structure, in particular tabular{*,x,y} taking a width argument that tabular* and longtable don't take.

The best way to not have to worry about the other changes that array makes is just to add \RequirePackage{array}. The array package has been part of the core LaTeX distribution since 2e came out in 1993, The only reason it's not part of the format is to avoid affecting tables written for LaTeX 2.09, but that shouldn't affect documents using a new package under construction.

-
Thanks; I did not know that one can expand "out of" csname. However, \csname\mytabletype\expandafter\csname{\mytablespec} does not work for me. It works if I insert another \expandafter before { though. You are right about the other tabular types; I am mainly trying to make longtable optional. In this sense, I probably do not need to worry whether other table environments provide corresponding \end... commands. – mak Mar 24 '13 at 13:32
@mak Thanks I corrected my answer. (It was trying to expand { which is not expandable). – David Carlisle Mar 24 '13 at 16:49
it's best to ask new questions as new questions rather than comments on old ones (as you see formatting in comments is poor and most people won't see the question You should not be using \def just use \newcolumntype` macros defined via that do get expanded – David Carlisle Oct 15 '14 at 22:13