考虑一下(愚蠢的)MWE:
\documentclass[]{article}
\usepackage{array, ragged2e}
% in a package
\newcolumntype{R}[1]{>{\raggedright\arraybackslash\hspace{0pt}}p{#1\linewidth}<{}}
% here
\newcolumntype{R}[1]{>{\RaggedRight\arraybackslash\hspace{0pt}}p{#1\linewidth}<{}}
\begin{document}
\begin{tabular}{R{0.3}c}
Test & test
\end{tabular}
\end{document}
显然,会有一个警告:
Package array Warning: Column R is already defined on input line 6.
现在,我明白了列类型是重新定义(我不清楚),但是 --- 是否可以\newcolumnstyle
以类似的方式扩展它xparse
?
我的意思是,拥有全套
\newcolumntype
:应该出错,说不要为了兼容性而改变当前行为\providecolumntype
(若存在则不重新定义)\renewcolumntype
(重新定义,如果存在则不发出警告)\definecolumntype
(始终重新定义,无警告)
我尝试深入研究array.sty
,但对我来说它太过 TeX 了……所以我想问问是否有人已经这样做过了…… ;-)。只要有一种等价的方法\providenewcolumn
就好了。
另一种选择是使用类似
\ifcolumndefined{R}{then}{else}%
或类似...
顺便说一句:我知道我可以用
\usepackage{silence}
\WarningFilter{array}{Column R}
答案1
如果您想检查某个列类型是否存在,可以使用array.sty
与以下相同的测试\newcolumntype
:
\newcommand\ifcolumndefined[1]{%
\edef\NC@char{\string#1}%
\@ifundefined{NC@find@\NC@char}%
{\@tempswafalse
\@tfor\next:=<>clrmbp@!|\do
{\if\expandafter\noexpand\next\NC@char \@tempswatrue \fi}%
\if@tempswa \expandafter\@firstoftwo
\else \expandafter\@secondoftwo
\fi}%
{\@firstoftwo}}
NC@find@#1
如果存在,或者#1
为原始列类型之一,则为真<>clrmbp@!|
。此测试不可扩展(您可能不需要它,但为了炫耀expl3
),这是一个可扩展的版本:
\ExplSyntaxOn
\prg_new_conditional:Npnn \rmano_if_column_defined:n #1 { p, T, F, TF }
{
\cs_if_exist:cTF { NC@find@ \token_to_str:N #1 }
{ \prg_return_true: }
{
\exp_args:No \rmano_if_primitive_column:NTF { \token_to_str:N #1 }
{ \prg_return_true: }
{ \prg_return_false: }
}
}
\prg_new_conditional:Npnn \rmano_if_primitive_column:N #1 { p, T, F, TF }
{
\tl_map_tokens:nn { <>clrmbp@!| }
{ \__rmano_if_primitive_column:NN #1 }
\prg_return_false:
}
\cs_new:Npn \__rmano_if_primitive_column:NN #1 #2
{
\token_if_eq_charcode:NNT #1 #2
{ \tl_map_break:n { \use_i:nn \prg_return_true: } }
}
\cs_set_eq:NN \ifcolumndefined \rmano_if_column_defined:nTF
\ExplSyntaxOff
(\ifcolumndefined
是 的副本\rmano_if_column_defined:nTF
,但您也可以复制其他变体(:nT
、:nF
)或 的副本\rmano_if_primitive_column:N(TF)
。)
这是一个完整的例子:
\documentclass{article}
\usepackage{array}
% \makeatletter
% \newcommand\ifcolumndefined[1]{%
% \edef\NC@char{\string#1}%
% \@ifundefined{NC@find@\NC@char}%
% {\@tempswafalse
% \@tfor\next:=<>clrmbp@!|\do
% {\if\expandafter\noexpand\next\NC@char \@tempswatrue \fi}%
% \if@tempswa \expandafter\@firstoftwo
% \else \expandafter\@secondoftwo
% \fi}%
% {\@firstoftwo}}
% \makeatother
\ExplSyntaxOn
\prg_new_conditional:Npnn \rmano_if_column_defined:n #1 { p, T, F, TF }
{
\cs_if_exist:cTF { NC@find@ \token_to_str:N #1 }
{ \prg_return_true: }
{
\exp_args:No \rmano_if_primitive_column:NTF { \token_to_str:N #1 }
{ \prg_return_true: }
{ \prg_return_false: }
}
}
\prg_new_conditional:Npnn \rmano_if_primitive_column:N #1 { p, T, F, TF }
{
\tl_map_tokens:nn { <>clrmbp@!| }
{ \__rmano_if_primitive_column:NN #1 }
\prg_return_false:
}
\cs_new:Npn \__rmano_if_primitive_column:NN #1 #2
{
\token_if_eq_charcode:NNT #1 #2
{ \tl_map_break:n { \use_i:nn \prg_return_true: } }
}
\cs_set_eq:NN \ifcolumndefined \rmano_if_column_defined:nTF
\ExplSyntaxOff
\begin{document}
\ifcolumndefined{W}{W exists}{W doesn't exist}
\ifcolumndefined{R}{R exists}{R doesn't exist}
\ifcolumndefined{c}{c exists}{c doesn't exist}
\edef\x{\ifcolumndefined{|}{| exists}{| doesn't exist}}
\texttt{\meaning\x}
\end{document}