
Basierend auf egregs alternativer Lösung für meinevorherige Frageaus dem ich die Idee gelernt habe, Zeichen in Makros umzuwandeln, habe ich jetzt eine andere Syntax für Bra-Kets definiert, die mir eigentlich noch besser gefällt. Mein Makrofastfunktioniert (obwohl hier ein bisschen Cargo-Kult-Programmierung am Werk ist, da ich einen Teil seiner Lösung, den ich nicht ganz verstanden habe – die beiden Zeilen, die mit beginnen \begingroup\lccode
– in mein Makro kopiert und leicht angepasst habe; ich vermute, dort liegt das Problem, da ich den Rest, dank egregs Erklärungen zu der anderen Frage, glaube, ausreichend zu verstehen).
Hier ist meine Makrodefinition:
\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
}}
Die folgenden Verwendungen funktionieren alle wie erwartet:
\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>}
(Letzteres deaktiviert einfach die automatische Größenanpassung).
Das Folgende gilt jedochnichtrichtig funktionieren:
\braket{<0|1>}
Es sollte "〈0|1〉" ergeben, ergibt aber nur "〈0〉".
Was ist also mit meinem Makro nicht in Ordnung und wie kann ich es beheben?
Antwort1
Das Problem ist, dass TeX, wenn es die aktive Pipe findet, diese erweitert auf
\delimiter 2532108
und eine darauf folgende Zahl wird in diesen Code integriert.
\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
}
Dadurch \relax
wird das Problem vermieden. Außerdem sind einige Teile außerhalb der Definition besser und \ensuremath
nicht empfehlenswert.
Hinweis zum \lowercase
Trick
Wenn einem Zeichen (mit dem Kategoriecode 11 oder 12) ein Mathecode zugewiesen wird "8000
und es im Mathematikmodus gefunden wird, wird es von TeX so behandelt, als wäre es aktiv (also wie ein Makro) und es ist eine Definition als aktives Zeichen erforderlich.
Ein sehr häufig verwendeter Trick besteht darin, dies auszunutzen~
Istaktiv; wenn wir dem Aktiv eine Bedeutung geben wollen <
, gibt es zwei Strategien. Die erste ist
{\catcode`<=\active \gdef<{something}}
was einen Nachteil hat: wir sind gezwungen, es im Voraus auszuführen, und es istweltweit. Deshalb verwenden wir eine andere Strategie:
\begingroup\lccode`~=`< \lowercase{\endgroup\def~}{something}
Wie funktioniert das? Zuerst öffnen wir eine Gruppe und teilen TeX darin mit, dass das kleingeschriebene Gegenstück von ~
ist <
. Dann führen wir aus \lowercase
, was zu transformiertZeichentokenin ihr Kleinbuchstaben-Gegenstück (unter Beibehaltung der Steuersequenzen) und fügt die Tokens wieder ein, als wären sie von Anfang an da gewesen. TeX sieht also
\endgroup\def<{something}
(Aber<
Istaktiv, da \lowercase
sich die Kategoriecodes nicht ändern). Das \endgroup
macht die Korrespondenz zwischen ~
und rückgängig <
und die Definition wird durchgeführt. Wenn wir später sagen \mathcode`<=\string"8000
, wird die Magie geschehen ( \string
ist eine Vorsichtsmaßnahme gegenbabelwas zu einem aktiven Charakter hätte werden können "
).