我想详细阐述一个命令,该命令可以以不同的方式打印简单微分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
这个网站上的一篇帖子,其中说 \end
Plain 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}
这比你的有两个优点:
- 它会自动处理
d
- 如果有指数,它会使用稍微小一点的退格键
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
。