本文中の「ぺ」をすべて「ぺりを」に変えたい

 

本文中の「ぺ」を全部「ぺりを」にしたくなることはありませんか?誰しも一度はあると思います. 今回はこれを実装しようと思います. 

 

\periwoと\endperiwoで挟まれた部分に対してそのような処理をしたいとします. 

 

方針1

\@tforを使う:一文字一文字が「ぺ」かどうかを判定すればよい. 入力する文字列が長すぎると困ったりするのかな, よくわからないけど今回は@tforの話をしたいわけではないので今後の課題ということで……

 

方針2

今回はこっちがメインです. \periwo の直後のトークンXが「ぺ」かどうかを判定し, そうならば「ぺりを\periwo」, 異なれば「X\periwo」を返す, という方針で書きたいとします. この方針そのままだと別の制御綴を挟むとヤバいですが, 今回はただの文字列に対して動くことを目標として, 一旦見逃すことにします. 

 

さて, 上の方針は次が可能であるためできそうです:

\def\testa#1{#1が先に来て\testb}

\def\testb#1{#1が後に来る}

 

入力:testa ぺり

出力:ぺが先に来てりが後に来る

 

\defはあくまで{}内の置き換えにすぎず, 中身の展開はしないことがポイントです. 

となると次のようにしたくなります. 

 

\def\periwo#1{%

  \def\karia{#1}%

  \def\PE{ぺ}%

  \ifx\karia\PE

    ぺりを\periwo

  \else

    #1\periwo

  \fi

}

\def\endperiwo#1{}

 

こうすると, 例えば

\periwo っぺの法則\endperiwo

は順に

・っ\periwo ぺの法則\endperiwo

・っぺりを\periwo の法則\endperiwo

・っぺりをの\periwo 法則\endperiwo

・っぺりをの法\periwo 則\endperiwo

・っぺりをの法則\periwo \endperiwo

・っぺりをの法則\endperiwo\periwo 

・っぺりをの法則

と展開されそうです. しかし, 実行してみると永久に出力が得られません. なぜか. 

 

それは, \ifx文中の\periwoが次の制御綴\elseや\fiを引数として読んでしまい無限ループに入るためです. そのため, この展開を制御するために例えば

 

\def\periwo#1{%

  \def\karia{#1}%

  \def\PE{ぺ}%

  \ifx\karia\PE

    \def\karib{ぺりを\periwo}%

  \else

    \def\karib{#1\periwo}%

  \fi

  \karib

}

とか

\def\periwo#1{%

  \def\karia{#1}%

  \def\PE{ぺ}%

  \ifx\karia\PE

    \def\karib{ぺりを}%

  \else

    \def\karib{#1}%

  \fi

  \karib\periwo

}

とか

\def\periwo#1{%

  \def\karia{#1}%

  \def\PE{ぺ}%

  \ifx\karia\PE

    ぺりを%

  \else

    #1%

  \fi

  \periwo

}

とかするなりの方法を取ることでうまく行きます. 

 

でもこれは人工的なのでもっと直接的に制御したいです. そこで次のことを考えました:\periwoより前に\elseや\fiをTeXが読めたら良いのでは?つまり, 

\def\periwo#1{%

  \def\karia{#1}%

  \def\PE{ぺ}%

  \ifx\karia\PE

    ぺりを\expandafter\periwo

  \else

    #1\expandafter\periwo

  \fi

}

とすれば動くのではないか?……

しかし, いざこれを実行してみるとバグります. これはいったい何が起きているのでしょうか. そもそも\elseや\fiを「展開する」とはどういうことなのでしょうか. それがわかったとして, もし\fiを先に展開してしまったら「\periwo」は読まれることになるのでしょうか. もっと言えば\expandafterは先に進んだ後に「戻る」ということをしていますがこれは何なのでしょうか. 

 

また根本的な部分で知識が抜けているのかもしれません. 現在のぺりをには理解しかねました……

 

ぺりをだねぇ

 

3/7追記:最後の例は\endperiwoの定義を\def\endperiwo#1#2{}にするだけで解決しました. \def\endperiwo#1{}だと, 最後の\endperiwoの引数が\expandafterになって\periwoが余るというオチで, ただの初歩的なミスでした……