定义过长导致测试失败

定义过长导致测试失败

我试图定义一个命令,使其在文本为斜体时表现不同,但我发现\newcommand\newcommand*(或者更确切地说,我认为是\long定义或的行为\ifx)之间存在差异,我不明白。基本上,我将命令定义\@itit。然后,我想使用检查文本是否为斜体。当使用或定义时,\ifx\f@shape\@it此测试有效,但当使用或定义时无效。\@it\def\newcommand*\@it\long\def\newcommand

下面的例子应该可以使一切清楚。

\documentclass{article}
\makeatletter
\def\@defit{it}
\long\def\@longdefit{it}
\newcommand{\@ncit}{it}
\newcommand*{\@ncsit}{it}
\newcommand{\itcheck}{%
    \ifx\f@shape\@defit
        The test from \textnormal{\textbackslash\texttt{def}} found the italic shape.
    \else
        The test from \textnormal{\textbackslash\texttt{def}} did not found the italic shape.
    \fi\par
    \ifx\f@shape\@longdefit
        The test from \textnormal{\textbackslash\texttt{long}\textbackslash\texttt{def}} found the italic shape.
    \else
        The test from \textnormal{\textbackslash\texttt{long}\textbackslash\texttt{def}} did not found the italic shape.
    \fi\par
    \ifx\f@shape\@ncit
        The test from \textnormal{\textbackslash\texttt{newcommand}} found the italic shape.
    \else
        The test from \textnormal{\textbackslash\texttt{newcommand}} did not found the italic shape.
    \fi\par
    \ifx\f@shape\@ncsit
        The test from \textbackslash\textnormal{\texttt{newcommand*}} found the italic shape.
    \else
        The test from \textbackslash\textnormal{\texttt{newcommand*}} did not found the italic shape.
    \fi%
}
\makeatother
\begin{document}
\itshape\itcheck
\end{document}

我原本期望所有测试都返回 true。但为什么事实并非如此?

答案1

使用更简单的纯 TeX:代码

\def\shortfoo{foo}
\long\def\longfoo{foo}

\ifx\shortfoo\longfoo\message{EQUAL}\else\message{DIFFERENT}\fi
\bye

将显示DIFFERENT在终端上。

\ifx两个宏在以下情况下被视为相等:

  1. 他们的参数文本相同;
  2. 它们的替换文本是相同的;
  3. 它们相对于\long和的地位\outer是一样的。

对于 e-TeX,还有另一种状态需要牢记:\protected

如果你确定你的宏可以扩展为字符标记,那么

\ifnum\pdfstrcmp{\shortfoo}{\longfoo}=0

将返回 true。该pdftex原语在 XeTeX 中被调用\strcmp,但在 LuaTeX 中缺失(该包pdftexcmds提供了 Lua 替代品)。您可以\usepackage{pdftexcmds}(或在纯 TeX 中)像在三个引擎中\input pdftexcmds.sty一样调用它。\pdf@strcmp

相关内容