
基於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)被指派了 mathcode"8000
並在數學模式下找到時,TeX 將其視為活動字元(即像巨集),並且需要將其定義為活動字元。
一個非常常用的技巧是利用~
是積極的;當我們想要賦予主動事物意義時<
,有兩種策略。第一個是
{\catcode`<=\active \gdef<{something}}
它有一些缺點:我們被迫提前執行它全球的。所以我們使用不同的策略:
\begingroup\lccode`~=`< \lowercase{\endgroup\def~}{something}
這是如何運作的?首先,我們打開一個組,並在組中告訴 TeX 的小寫字母~
是<
。然後我們這樣做\lowercase
,這會改變字元標記到它們的小寫對應部分(但保持控制序列不變)並將令牌放回原處,就像它們從一開始就在那裡一樣。所以 TeX 看到
\endgroup\def<{something}
(但<
是有效,因為\lowercase
不會更改類別代碼)。撤銷和\endgroup
之間的對應關係並執行定義。稍後,我們說,魔法將會發生(是預防措施)~
<
\mathcode`<=\string"8000
\string
通天塔這可能會成為"
一個活躍的角色)。