私のブレーキ マクロの何が問題なのでしょうか?

私のブレーキ マクロの何が問題なのでしょうか?

egregの代替ソリューションに基づいて前の質問文字をマクロにするというアイデアを学んだので、今では括弧の別の構文を定義しました。これは実際にはさらに気に入っています。私のマクロほとんど動作します (ただし、ここでは少しカーゴ カルト プログラミングが行われています。これは、私が完全に理解していなかった彼のソリューションの一部 (で始まる 2 行) を\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 ではその文字がアクティブであるかのように (つまり、マクロのように) 扱われ、アクティブ文字としての定義が必要になります。

非常によく使われるトリックは、~ 能動態に意味を持たせたい場合<、2つの戦略があります。1つ目は

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

これには欠点があります。事前に実行する必要があるため、グローバルそこで、別の戦略を採用します。

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

これはどのように動作するのでしょうか? まず、グループを開き、グループ内で の小文字の対応が~であることをTeXに伝えます<。次に を実行し\lowercase文字トークンを小文字に変換し(ただし制御シーケンスは変更しない)、トークンを最初からあったかのように戻します。そのため、TeXは

\endgroup\def<{something}

(しかし< アクティブで、\lowercaseカテゴリコードを変更しないため)。は と\endgroupの対応を解除し、定義が実行されます。 後ほど と言うと、魔法が起こります(は予防策です)。~<\mathcode`<=\string"8000\stringバベル"アクティブなキャラクターにできたかもしれない。

関連情報