colortbl: new environments and how to apply \expandafter
For what it's worth, most of \newcolumntype
doesn't actually require that the column name to be a single character, just that it be a single token. So this works, for example
\newcolumntype{\fooa}[1]{>{\color{#1}}c}
\newcolumntype{\foob}{|l|}
\begin{tabular}{\fooa{red}\fooa{blue}\foob}
a b c & a b c & a b c \\
1&2&3
\end{tabular}
It's not really supported though, and \showcols
fails in this usage, although that could presumably be fixed, but it's probably simpler to stick to single letters, even after avoiding special characters there are over 200 of them in an 8-bit TeX, which ought to be enough column types. :-)
The definition of tabularex
below works for one column, and it could be generalized to any number of columns separated by |
. Its not in general for any environment but it works for tabular
:
\documentclass[10pt]{article}
\usepackage[table,dvipsnames]{xcolor}
\usepackage{array}
\usepackage{colortbl}
\def\tabularex#1{\toks0=\expandafter{#1}%%
\edef\go{\toks2={\noexpand\begin{tabular}{\the\toks0}}}%%
\go\the\toks2}
\begin{document}
\newcommand{\colone}{>{\columncolor{blue!10}}c}
\newcommand{\coltwo}{>{\columncolor{red!10}}c}
\tabularex{\colone}
Something \\
\end{tabular}
\end{document}
The key element is the use of \expandafter
in the token assignment: \toks0=\expandafter{#1}
. Because colone
takes no arguments, this only does one level of expansion. I learned this trick from the TeXBook - the answer to Exercise 20.15 shows you how write a macro that expands another only one level, and the discussion of the \asts
macro at the beginning of Appendix D ("Dirty Tricks") shows how to use \expandafter
with a token assignment.
An improvement of Justin's idea:
\documentclass[10pt]{article}
\usepackage[table,dvipsnames]{xcolor}
\usepackage{array}
\usepackage{colortbl}
\newenvironment{tabularex}[2][c]
{\begingroup\edef\x{\endgroup\noexpand\tabular[#1]{#2}}\x}
{\endtabular}
\newcommand{\newcolumntypeex}[2]{\newcommand#1{\unexpanded{#2}}}
\newcolumntypeex{\colone}{>{\columncolor{blue!10}}c}
\newcolumntypeex{\coltwo}{>{\columncolor{red!10}}c}
\begin{document}
\begin{tabularex}{\colone\coltwo}
Something & else\\
\end{tabularex}
\end{document}
It has many limitations with respect to the usual tabular
environment: for example, something like >{\raggedright}p{3cm}
won't work (which is precisely the reason why array
doesn't expand the tokens in the argument of tabular
). One has to put \protect
in front of every token of this kind.
All considered, I don't think it's particularly useful. The problem at hand may be solved by
\newcolumntype{Z}[1]{>{\columncolor{#1}}c}
and
\begin{tabular}{Z{blue!10}Z{red!10}}
Recall that the definitions performed by \newcolumntype
are local, so one given inside a table
environment will disappear after it.