加载 tocloft 使 \ifdefined\chapter 在文章类中为 TRUE

加载 tocloft 使 \ifdefined\chapter 在文章类中为 TRUE

我正在使用该类article,但发现tocloft包定义了\chapter,这会弄乱我的其他内容。这是怎么回事?\chapter加载 后我可以再次使“未定义”吗tocloft?这是一个 MWE:

\documentclass{article}
% loading tocloft will make \chapter defined
\usepackage{tocloft}

\begin{document}

\ifdefined\chapter
   chapter is defined in the current \texttt{article} document.

   \chapter{This is not a chapter, but will be typeset as plain text}
\else
   chapter is \emph{not} defined.
\fi

\end{document} 

答案1

一些包和宏会检查是否\chapter已定义以便采取某些操作;例如,将参考书目排版为章节(bookreport类)或部分(article类)。

\@ifundefined他们进行的测试基于

\@ifundefined{chapter}
  {\section*{\refname}}
  {\chapter*{\bibname}}

重要的是要知道,\@ifundefined当参数中给出的命令名称未定义或等效于时,将返回 true \relax。实际上,每当使用

\@ifundefined{foo}{<true>}{<false>}

如果之前没有定义过该命令,\foo那么它将等效于该命令。\relax

相反,\ifdefined当条件后的标记相当于时,条件也会返回 true \relax,这就是您观察到这种行为的原因:确实检查了是否tocloft存在。\chapter\@ifundefined

这样做的原因是历史原因:LaTeX 需要在发布时或对于时知道是否\foo定义。因此,宏将名称而不是令牌本身作为参数。它在内部使用具有之前概述的效果:如果未定义,则使用将使其等同于。\newenvironment{foo}\c@foo\newcounter{foo}\@ifundefined\csname...\endcsname\foo\csname foo\encsname\relax

只要你坚持\@ifundefined测试定义性,就不会有问题。

\ifdefined和基元\ifcsname是 e-TeX 扩展,因此在 LaTeX2e 发布时它们不可用。实际上没有其他可靠的方法来检查定义性;另一种策略是与未定义的标记进行比较(有\@undefined针对此情况的策略)。但是,\csname...\endcsname除非使用巧妙的技巧,否则问题仍然存在:

\def\@ifundefined#1{%
    \begingroup\expandafter\expandafter\expandafter\endgroup
    \expandafter\ifx\csname#1\endcsname\@undefined
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
    \fi}

因此,如果未定义,则\@ifundefined{foo}不会保留\foo等同于。但是,由于和,此测试无法完全扩展,因此开发人员决定保留原样。\relax\begingroup\endgroup\@ifundefined

这个技巧之所以有效,是因为\csname foo\endcsname在 TeX 扫描之前执行了,\endgroup所以\relax一旦 TeX 执行它,与的等价性就会消失;但条件\ifx已经扩展了。:)


请注意,从 2018 年起的 LaTeX 版本中,的定义已被修改,因此如果之前未定义,\@ifundefined它不再将测试的命令定义为。\relax

答案2

tocloft定义\chapter\relaxarticle如果您希望它未定义,请发出

\usepackage{tocloft}% http://ctan.org/pkg/tocloft
\let\chapter\undefined

这里\undefined只是一个未定义的控制序列。它也可能\anyundefinedmacro,只要它是不明确的。

\let将第二个控制序列的整个定义复制到第一个控制序列中,就像它当时定义的那样。由于\undefined不存在,\chapter所以将“不存在”。根据您的其他用法,您可能还必须删除其他\chapter相关定义。但是,如果没有更多信息,这应该就足够了。

在此处输入图片描述

\documentclass{article}
% loading tocloft will make \chapter defined
\usepackage{tocloft}% http://ctan.org/pkg/tocloft
\let\chapter\undefined
\begin{document}

\ifdefined\chapter
   chapter is defined in the current \texttt{article} document.

   \chapter{This is not a chapter, but will be typeset as plain text}
\else
   chapter is \emph{not} defined.
\fi

\end{document}

相关内容