这是来自安德鲁·霍华德 (Andrew Howard) 提出的问题。经过一番讨论,很明显colortbl
存在一些与 相关的名称问题\newcolumntype
。讨论的结果离题太远,似乎可能会提出一个新的、更普遍的问题。
假设我们想定义新列而不使用\newcolumntype
,这有限制,因为名称只能是一个字符。tabular
环境可以接受更复杂的输入。例如,在不定义 的情况下,\newcolumntype
我们可以这样做
\documentclass[10pt]{article}
\usepackage[table,dvipsnames]{xcolor}
\usepackage{array}
\usepackage{colortbl}
\begin{document}
\begin{tabular}{|>{\columncolor{blue!10}}c|>{\columncolor{red!10}}c|}
Something & Something else\\
\end{tabular}
\end{document}
这不是特别可重复使用。我们不能做的是
\newcommand{\colone}{>{\columncolor{blue!10}}c}
\newcommand{\coltwo}{>{\columncolor{red!10}}c}
\begin{tabular}{|\colone|\coltwo|}
Something & Something else\\
\end{tabular}
该array
软件包提供了\newcolumntype
解决这个问题的方法,但只允许使用单个字符的名称,这不是很令人满意。
我如何才能强制 LaTeX 扩展\colone
并\coltwo
在 tabular 获取它们之前?定义一个新的环境就可以了。一般来说,如何使用以特定顺序强制扩展new environment
?
答案1
值得一提的是,大多数方法\newcolumntype
实际上并不要求列名称为单个字符,而只是要求它是一个标记。例如,这是可行的
\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}
但它实际上并没有得到支持,并且\showcols
在这种用法下会失败,尽管这个问题大概可以被修复,但坚持使用单个字母可能更简单,即使在避免了特殊字符之后,8 位 TeX 中也有超过 200 个特殊字符,这应该是足够的列类型了。:-)
答案2
贾斯汀想法的改进:
\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}
它相对于通常的tabular
环境有很多限制:例如,像 这样的操作>{\raggedright}p{3cm}
将不起作用(这正是array
的参数中不扩展标记的原因tabular
)。必须\protect
在每个此类标记前面放置 。
总的来说,我认为它不是特别有用。手头的问题可以通过以下方法解决:
\newcolumntype{Z}[1]{>{\columncolor{#1}}c}
和
\begin{tabular}{Z{blue!10}Z{red!10}}
回想一下,执行的定义\newcolumntype
是局部的,因此在table
环境内部给出的定义将在它之后消失。
答案3
下面的定义tabularex
适用于一列,并且可以推广到以 分隔的任意数量的列|
。它不适用于任何环境,但适用于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}
\expandafter
关键元素是在标记赋值中使用: \toks0=\expandafter{#1}
。由于colone
不带参数,因此这只进行一级扩展。我从 TeXBook 中学到了这一技巧 - 练习 20.15 的答案向您展示了如何编写一个只扩展另一个一级的宏,\asts
附录 D(“肮脏的技巧”)开头对宏的讨论展示了如何\expandafter
与标记赋值一起使用。