我的支架宏有什么问题?

我的支架宏有什么问题?

基于 egreg 对我的替代解决方案上一个问题我从中学到将字符变成宏的想法,现在我为 bra-kets 定义了一种不同的语法,事实上我更喜欢这种语法。我的宏几乎有效(尽管这里有一点货物崇拜编程,因为我\begingroup\lccode在我的宏中复制了他的解决方案中一些我不完全理解的部分 - 以...开头的两行 - 对它们进行了稍微的改动;我怀疑问题就在那里,因为我相信其余部分我已经充分理解了,这要感谢 egregs 对另一个问题的解释)。

这是我的宏定义:

\newcommand{\braket}[2][\middle]{\ensuremath{
\begingroup
\begingroup\lccode`~=`<
  \lowercase{\endgroup\def~}{#1\langle}
\begingroup\lccode`~=`|
  \lowercase{\endgroup\def~}{#1\pipedel}
\begingroup\lccode`~=`>
  \lowercase{\endgroup\def~}{#1\rangle}
\edef\pipedel{\delimiter\the\delcode`|}
\mathchardef\lt\mathcode`<
\mathchardef\pipechar\mathcode`|
\mathchardef\gt\mathcode`>
\mathcode`\<=\string"8000
\mathcode`\|=\string"8000
\mathcode`\>=\string"8000
\left.
#2
\right.
\endgroup
}}

以下用法均按预期工作:

\braket{<\psi|\psi>}
\braket{<\psi|A|\psi>}
\braket{<\psi|\frac{p^2}{2m}|\psi>}
\braket[\Big]{<\alpha|\beta>}
\braket{|a \gt 0>}
\braket[]{<\psi|\frac{p^2}{2m}|\phi>}

(最后一个只是禁用自动尺寸适应)。

然而,以下不是正常工作:

\braket{<0|1>}

它应该给出“〈0|1〉”但只给出“〈0〉”。

那么我的宏有什么问题?我该如何修复它?

答案1

问题是,当 TeX 找到活动管道时,它会将其扩展为

\delimiter 2532108

并且其后的数字将并入该代码中。

\mathchardef\lt\mathcode`<
\mathchardef\pipechar\mathcode`|
\mathchardef\gt\mathcode`>
\edef\pipedel{\delimiter\the\delcode`| }
\show\pipedel
\newcommand{\braket}[2][\middle]{
  \begingroup
  \begingroup\lccode`~=`<
    \lowercase{\endgroup\def~}{#1\langle}
  \begingroup\lccode`~=`|
    \lowercase{\endgroup\def~}{#1\pipedel\relax}
  \begingroup\lccode`~=`>
     \lowercase{\endgroup\def~}{#1\rangle}
  \mathcode`\<=\string"8000
  \mathcode`\|=\string"8000
  \mathcode`\>=\string"8000
  \mathopen{}\left.#2\right.\mathclose{}
  \endgroup
}

\relax将避免这个问题。另外有些部分在定义之外会更好,因此\ensuremath不建议使用。

注意\lowercase诀窍

当一个字符(类别代码 11 或 12)被分配了数学代码"8000并且在数学模式下被发现时,TeX 会将其视为活动的(即像宏一样),并且需要将其定义为活动字符。

一个很常用的技巧就是利用这一点~ 主动;当我们想赋予主动意义时<,有两种策略。第一种是

{\catcode`<=\active \gdef<{something}}

这有一些缺点:我们被迫提前执行它,而且全球的所以我们采用不同的策略:

\begingroup\lccode`~=`< \lowercase{\endgroup\def~}{something}

这是如何工作的?首先,我们打开一个组,并在该组中告诉 TeX 的小写对应项~<。然后我们执行\lowercase,这会将字符标记转换为小写字母(但控制序列保持不变),并将标记放回原处,就像它们从一开始就在那里一样。因此 TeX 认为

\endgroup\def<{something}

(但< 激活,因为\lowercase不会改变类别代码)。取消和\endgroup之间的对应关系,并执行定义。 稍后,我们说,魔法会发生(是预防~<\mathcode`<=\string"8000\string巴别塔这可能会成为"一个活跃的角色)。

相关内容