Was ist mit meinem Brackett-Makro los?

Was ist mit meinem Brackett-Makro los?

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 \relaxwird das Problem vermieden. Außerdem sind einige Teile außerhalb der Definition besser und \ensuremathnicht empfehlenswert.

Hinweis zum \lowercaseTrick

Wenn einem Zeichen (mit dem Kategoriecode 11 oder 12) ein Mathecode zugewiesen wird "8000und 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 \lowercasesich die Kategoriecodes nicht ändern). Das \endgroupmacht 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 ( \stringist eine Vorsichtsmaßnahme gegenbabelwas zu einem aktiven Charakter hätte werden können ").

verwandte Informationen