\empty 和 \@empty 之间有什么区别?

\empty 和 \@empty 之间有什么区别?

我想详细阐述一个命令,该命令可以以不同的方式打印简单微分dx和多维微分d^3x。为此,我发明了\dif一个带有一个可选参数的命令。它定义如下:

\newcommand{\dif}[1][]{%
    \def\@tmp@a{#1}%
    \ifx\@tmp@a\@empty
        [b1]\mathrm{d}
    \else
        [b2]\mathrm{d}^{#1}{} \!
    \fi
}

这里添加了 [b1] 和 [b2] 以进行调试。分支 [b1] 用于在不带任何参数的情况下调用命令的情况,例如\dif{x}。第二个分支 [b2] 应该用于例如\dif[3]{x}使用命令打印 的情况d^3x。如上所示的定义似乎工作正常。但是,如果用第一个分支\@empty替换,则始终会被忽略。\empty

该命令\empty的解释如下TeXBook,所以最初我尝试用这个代码,只是偶尔回想起\@empty这个网站上的一篇帖子,其中说 \endPlain TeX 的命令\@@end在 LaTeX 中被重新定义为。

\empty有人可以解释一下 LaTeX 中和 之间的区别吗\@empty,或许,可以为我的问题提出更好的解决方案?

答案1

\@empty和宏分别\empty在 LaTeX 格式的源文件的latex.ltx第 122 行和第 441 行中定义:

\def\@empty{}

\let\empty\@empty

所以两者实际上是相同的。我也想知道为什么同一个东西有两个名字。我猜 LaTeX 开发人员想要一个更安全的宏,以便由用户或其他包重新定义。

您的代码实际上应该同时使用\@empty\empty。在前面放置一个\show\@empty\show\empty\ifx调试问题。也许某个地方重新定义了一个。在这种情况下,您可以\tracingall\tracingassigns=1\relax \tracingonline=0\relax在文档前言的最前面放置一个,然后在日志文件中搜索重新定义。

答案2

\@empty无论是使用还是使用 ,我都会得到相同的输出\empty。我建议你使用另一种定义:

\newcommand{\dif}[1][]{\mathop{}\!\mathrm{d}
  \if\relax\detokenize{#1}\relax
  \else
    ^{#1}\mkern-1.5mu
  \fi}

这比你的有两个优点:

  1. 它会自动处理d
  2. 如果有指数,它会使用稍微小一点的退格键d

当然,我更喜欢斜体d,但那是另一回事。:)

答案3

为了测试命令的参数是否为空,我建议使用包\@ifmtarg提供的开关ifmtarg。因此:

\documentclass{article}

\usepackage{ifmtarg}

\makeatletter

\newcommand*{\dif}[1][]{%
  \@ifmtarg{#1}{[b1]\mathrm{d}}{[b2]\mathrm{d}^{#1}{} \!}%
}

\makeatother

...

\@ifmtarg开关既不依赖于\empty也不依赖于\@empty

相关内容