数式の開始・終了時にPERIWOを書きたい

やりたいこと

$2+3=5$と書いたら、出力が$PERIWO2+3=5PERIWO$になるようにすることが目標です。

obeylines

ソースコード中で改行したら出力の方でも改行するようにするコマンド\obeylines(および有志の方がそれを改良した\xobeylines)を参考にします。
これは改行文字のカテゴリーコードを変えてアクティブ文字にし、\defを使って改行文字に対して通常の制御綴のように定義する、という方法によって実現しています。

※先にこっちを見た方が理解がしやすいかもしれません。shukutoiya.hateblo.jp

ネックとなるポイント

数式開始時点と終了時点で違うことをやっているので、$を単純に定義するだけでは実装できません。なので違う文字を挟んで解決することにします。

実装1

{
\catcode`\$=\active
\catcode`\@=3
\gdef\dolltope{\catcode`\$=\active \def ${\ifmmode \mathcal{PERIWO}@\else @\mathcal{PERIWO}\fi}}
}

入力:

\dolltope
$2+3=5$

$f(x)=\begin{cases} 1 & \text{$x$は有理数} \\ 0 & \text{$x$は無理数}\end{cases}$

出力:

(最初の{は、カテゴリーコードの変更を局所的にするためです。)
@に(通常の)$と同じ機能を与えていることがポイントです。
数式モード中に$を読み込んだ時には\mathcal{PERIWO}@を、そうでないときは@\mathcal{PERIWO}を返すように設定することによって実装しています。

実装2

@を挟むのはやはり行儀が悪い(いまさら何をという感じもしますが)ので、$のままで解決したいです。

{
\catcode`\$=\active
\gdef\dolltoper{\catcode`\$=\active 
\def ${\ifmmode \mathcal{PERIWO}\bgroup \catcode`\$=3 $\egroup \else \bgroup \catcode`\$=3 $\egroup\mathcal{PERIWO}\fi}}
}

入力:

\dolltoper
$2+3=5$

$f(x)=\begin{cases} 1 & \text{$x$は有理数} \\ 0 & \text{$x$は無理数}\end{cases}$

出力:エラー

! TeX capacity exceeded, sorry [input stack size=10000].
$...ode `\$=3 $\egroup \else \bgroup \catcode `\$=
                                                  3 $\egroup \mathcal {PERIW...

無限ループに入っているのだと思いますが、何が起こっているかはよくわかりません。解析の際にカテゴリーコードの変更がどこで反映されるかあたりが謎なんでしょうか。

実装3

一方、これは成功します。

{
\gdef\periwodollar{$}
\catcode`\$=\active
\gdef\dolltoperi{\catcode`\$=\active \def ${\ifmmode \mathcal{PERIWO}\periwodollar \else \periwodollar\mathcal{PERIWO}\fi}}
}

入力:

\dolltoperi
$2+3=5$

$f(x)=\begin{cases} 1 & \text{$x$は有理数} \\ 0 & \text{$x$は無理数}\end{cases}$

出力:

\periwodollarは「カテゴリーコード3の$」と定義されている、つまり\defは中身のカテゴリーコードを確定させる、と現時点では考えていますが、この認識が正しいかどうかはよくわかりません。

次の目標

よく考えてみると\def\hoge{fuga}の }をどうやって認識しているかはそんなに自明な話ではない(\edefならまだしも、\defはその時点では完全展開しないので)ということに気づきました。\defまわりの構文解析は闇が深そうです。

ぺりをだねぇ