为什么 \@ifstar 在标题中不起作用?

为什么 \@ifstar 在标题中不起作用?

由于某种原因,下面的最小示例无法编译:

\documentclass{article}

\makeatletter
\newcommand{\testMe}{%
    test
    \@ifstar{1}{2}%
}
\makeatother

\begin{document}
\testMe
\testMe*
\begin{figure}
  bla bla bla
  \caption{\testMe*}
\end{figure}
\end{document}

但是,如果你取消注释该行,或者在标题中\@ifstar不使用它,它就会起作用。为什么?\testMe

答案1

以这种方式定义的命令很脆弱,因此您需要\protect\testMe移动参数,例如标题文本。

让我们看看为什么。 的参数\caption需要经过多次修改,特别是将其写入文件.aux以便可能包含在图形(或表格)列表中。

当 TeX 执行\write操作时,它会“完全”扩展命令,除非指示不要这样做(这是 的目的\protect)。在\write操作的扩展过程中,\@ifstar\@ifnextchar\@ifstar在 上定义)会中断,因为它们需要为临时宏分配一个值才能工作,而在扩展期间这是不可能的。

因此,您有三种可能性:

  1. \protect\testMe在移动争论中使用

  2. 用于\DeclareRobustCommand定义\testMe(与 语法相同\newcommand

  3. 使用xparse

最后一种可能性需要注释。如果你这样做

\usepackage{xparse}
\NewDocumentCommand{\testMe}{s}
 {test \IfBooleanTF{#1}{1}{2}}

您获得的内容与您的基本相同\testMe,但在移动参数中发现时会自动受到保护。

相关内容