如何正确地重新定义表内的&?

如何正确地重新定义表内的&?

请帮我重新定义表格内的命令。当我尝试执行此操作时,出现错误:

! 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,而不是tabletable是浮动环境,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 也会导致大麻烦,因为环境往往会先查看,可能在执行任何操作之前先收集其整个正文,因此字符会冻结在错误的类别中。

>{}对于您所展示的示例,使用表格模板参数中的声明更有意义。

相关内容