以下代码可以正确编译并生成 pdf:
\documentclass{article}
\usepackage{amsmath}
\DeclareMathOperator{\zero}{\overline{0}}
\begin{document}
Writing $V_\alpha$ does not give problems.
\end{document}
但是,以下代码确实存在问题:
\documentclass{article}
\usepackage{amsmath}
\DeclareMathOperator{\zero}{\overline{0}}
\begin{document}
Writing $V_\zero$ gives problems.
\end{document}
这是为什么?有没有什么办法可以让它\zero
像这样工作\alpha
?
答案1
在里面电子书,第 128 页,其中写道:请注意 ^ 和 _ 仅适用于下一个单个字符。
因此, 的V_\alpha
作品可能应该被视为例外。请注意 的标准定义\alpha
是\mathchar"010B
。
使用在原始 TeX 中定义的宏\def
,它不起作用(至少,它并不总是起作用),因为使用\def\zero{}
,您无法写入V_\zero
。
还要注意的是,TeX 不会将 后面的内容^
视为_
宏的参数。字符^
和_
非常特殊(就像 或 一样特殊)。 的 catcode是 7, 的 catcode是 8(而例如 的 catcode是 1,{
等等)。这意味着您不应该期望和具有宏的行为(即使是 catcode 为 13 的字符,其行为也像宏一样)。#
^
_
{
^
{
许多人可能会建议写作V_{\alpha}
(因为他们建议写作\frac{1}{2}
而不是\frac12
- 这有效......)。
答案2
尽管说 TeX 将后面的内容^
或_
参数视为宏是“几乎正确的”,但它实际上跳过了关于它们的一个基本事实。
这就是你的 出现问题的地方V_\zero
。
宏参数的根本区别在于,当你有一个宏接受一个参数(准确地说是一个无界参数)时,比如说\foo
,那么 TeX 会在其中寻找该参数无需做任何扩展:如果后面跟着一个开括号,那么直到匹配的闭括号为止的所有内容将被视为参数;否则下一个标记将被视为参数。
相反,看到^
或_
,TeX将要扩展标记以查看后面是否有左括号(可能是隐式的);在此过程中,\relax
空格标记将被忽略。一旦\relax
发现不可扩展的标记(或空格除外),这种扩展过程就会终止;如果它是左括号,则参数将被抓取到匹配的右括号(也可能是隐式的)。
因此你可以这样做
V_\bgroup 10\egroup
这将10
作为下标。请注意,如果\foo
是带参数的宏,\foo\bgroup 10\egroup
则将\bgroup
作为参数(可能产生不良副作用)。
您可以使用简单的纯 TeX 代码进行测试。
\def\foo#1{(#1)}
\def\x{\bgroup}
\def\void{}
\foo{10}
\foo\bgroup 10\egroup
$V_{10} = V_\bgroup 10\egroup=V_\x 10}$
$V_\void x$
\bye
使用\foo\bgroup 10\egroup
,令牌\bgroup
被视为参数,因此输入流将变为
(\bgroup)10\egroup
(第二行)。第三行显示所有这些(奇怪的)输入都会导致相同的结果。
第四行显示\void
已扩展;扩展为空,因此 TeX 继续寻找不可扩展的标记(使用宏扩展);它找到了x
,因此它将其作为下标。
为什么V_\alpha
有效?因为\alpha
是不可扩展的令牌。它是不是定义为
\def\alpha{\mathchar"010B }
但
\mathchardef\alpha="010B
即非常\alpha
不同。因此,当扫描到时,对不可扩展标记的查找结束。
如果你要求 LaTeX 显示你的\zero
实际上是如何定义的\show\zero
,你会看到
> \zero=macro:
->\protect \zero .
(最后一个命令的名称中有一个空格,但这并不重要)。上面解释的规则导致\zero
扩展为\protect\zero•
(项目符号表示名称中的空格)。由于\protect
相当于\relax
,因此在这种情况下,它会被忽略,因此 TeX 会扩展\zero•
。
如果你这样做,\ShowCommand\zero
你就会得到
> \zero=robust macro:
->\protect \zero .
> \zero =\long macro:
->\qopname \newmcodes@ o{\overline {0}}.
因此输入流中剩余的第一个标记是\qopname
。现在\ShowCommand\qopname
产生
> \qopname=robust macro:
->\protect \qopname .
> \qopname =\long macro:
#1#2#3->\mathop {#1\kern \z@ \operator@font #3}\csname n#2limits@\endcsname .
情况类似:\protect
被忽略并且\qopname•
被扩展;现在出现错误,因为\mathop
是不可扩展的,所以它被视为整个下标,但这样做是非法的
V_\mathop
原因很容易理解。
结论:可以这样V_\alpha
写V_1
类的,但不确定时请避免省略括号。更好的方法是总是括号下标和上标。