我试图定义一个命令,使其在文本为斜体时表现不同,但我发现\newcommand
和\newcommand*
(或者更确切地说,我认为是\long
定义或的行为\ifx
)之间存在差异,我不明白。基本上,我将命令定义\@it
为it
。然后,我想使用检查文本是否为斜体。当使用或定义时,\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
两个宏在以下情况下被视为相等:
- 他们的参数文本相同;
- 它们的替换文本是相同的;
- 它们相对于
\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