请帮我重新定义表格内的命令。当我尝试执行此操作时,出现错误:
! Misplaced alignment tab character &.
可能是 catcodes 的问题,但我不知道如何解决。
\documentclass{article}
\usepackage{expl3,etoolbox}
\ExplSyntaxOn
\makeatletter
\cs_set_eq:NN \orig@& &
\AtBeginEnvironment{table}{
\cs_new_protected:npn{&}{\orig@&\message{amp command}}
}
%return original &
\AtEndEnvironment{table}{\cs_gset_protected:npn{&}{\orig@&}
\ExplSyntaxOff
\begin{document}
\begin{table}
test&new test\\
\end{table}
\end{document}
答案1
您的代码存在几个问题:
\cs_set_eq:NN \orig@& &
不起作用,因为&
不是信(catcode 11) 标记,但对齐制表符 (catcode 4) 标记,因此该行等于\orig@
(第一个) ,而TeX 认为&
第二个不在对齐 ( ) 上下文中,因此出现错误,这与您只是从表中使用时一样。 要使此行工作,您需要类似。但这也很难&
tabular
! Misplaced alignment tab character &
&
\cs_set_eq:cN { orig@& } &
使用\orig@&
之后。您想要的环境是
tabular
,而不是table
。table
是浮动环境,tabular
是用于对齐的环境。最好不要在对齐制表符后放置
\message
(或\iow_term:n
或任何不可扩展的内容),否则\multicolumn
将无法在表格中工作。表格单元格开头的标记必须可扩展,以便 TeX 可以找到可能的\omit
或\span
(请参阅唐纳德的评论)\cs_new_protected:npn
不存在:您需要\cs_new_protected:Npn
(首N
字母大写),但这也行不通,因为&
这不是有效的命令。您需要\char_set_catcode_active:N \&
先使用,但在同一段代码中处理 catcode-4、catcode-11 和 catcode-13 会很麻烦&
。这并非不可能,但也没有必要。
也就是说,更简单的方法是使用\char_set_active_eq:NN <char> <macro>
使活动字符<char>
等于<macro>
,然后<char>
使用使活动字符等于\char_set_catcode_active:N
。 在你的情况下<char>
是\&
。 另外,你不需要&
在环境结束时重置,因为这是由\begin
/形成的组完成的\end
。 这是代码:
\documentclass{article}
\usepackage{expl3,etoolbox}
\ExplSyntaxOn
% Define the desired behaviour of &
\cs_new_protected:Npn \kozlovskiy_tab_char:
{
\iow_term:n {amp~command}
\c_alignment_token % same as &
% Anything after this line must be expandable, or \multicolumn won't work
}
% Make active-& equal to the macro above, and make & active:
\AtBeginEnvironment{tabular}
{
\char_set_active_eq:NN \& \kozlovskiy_tab_char:
\char_set_catcode_active:N \&
}
\ExplSyntaxOff
\begin{document}
\begin{tabular}{ccc}
test&new test\\
test&\multicolumn{2}{r}{new test}\\
\end{tabular}
\end{document}
答案2
您不会,至少不会喜欢那样,因为&
这不是“命令”,而是“对齐制表符”,就像错误消息所说的那样。您可以通过声明来选择其他字符作为对齐字符,例如,
\catcode`\|=\catcode`\&
但这可能会破坏文档中 LaTeX 的其他部分。
你可以&
通过声明和定义,变成一个命令字符(“主动”),比如,
\let\aligamp=&
\catcode`\&=\catcode`\~
\def &{\aligamp\message{amp command}}
(我怀疑\protect
离子会干扰可扩展对齐字符的功能;两者\cs_new_protected:Npn
都会\DeclareRobustCommand
造成混乱。)
但同样,这可能会破坏文档中 LaTeX 的其他部分。动态更改 catcode 也会导致大麻烦,因为环境往往会先查看,可能在执行任何操作之前先收集其整个正文,因此字符会冻结在错误的类别中。
>{}
对于您所展示的示例,使用表格模板参数中的声明更有意义。