Re: アンダーバーを含む文字列を引数にとるマクロ

名前: しっぽ愛好家
日時: 2003-03-07 12:56:50
IPアドレス: 211.4.36.*

>>17386 >\def\setemail#1{% > \begingroup > \@sanitize > \@setemail#1} >\def\@setemail#1{% > \gdef\@email{#1} > \endgroup} >この場合、どうしてうまくいかないのかおわかりでしょうか? 要は,``カテゴリーコードの設定'' と ``マクロの引数の読み取り'' の 順序の問題です. まず,\@sanitize はいくつかの文字のカテゴリーコードを変更する マクロであることに注意が必要です. 実際,\@sanitize は(ファイル latex.ltx において)次のように 定義されています. \def\@sanitize{\@makeother\ \@makeother\\\@makeother\$\@makeother\&% \@makeother\#\@makeother\^\@makeother\_\@makeother\%\@makeother\~} \def\@makeother#1{\catcode`#1=12\relax} %%% 例えば,\@sanitize の中にある \@makeother\_ という部分は, %%% \catcode`\_=12\relax に展開されますが,これは文字 _ のカテゴリーコードを %%% 12(その他の文字)に変更します.なお,文字 _ のカテゴリーコードの %%% デフォルトの値は 8(下つき文字)です. 次に,個々の文字のカテゴリーコードは,その文字が最初に(ファイルから) 読み取られたとき(*)に決まり,その後は(原則として)変更されない, ということにも注意してください. %%% (*) 個々のトークンが TeX に認識された時点で ``読み取られた'' と %%% いうことにします. 例えば,17377 で用意した修正版の定義 \def\setemail{% \begingroup \@sanitize \@setemail} \def\@setemail#1{% %%% #1 は \@setmail を展開するときにはじめて読み取られます. \gdef\@email{#1}% \endgroup} では,\@sanitize でいくつかの文字のカテゴリーコードを変更してから, \setemail の引数(として与えられた文字列)を読み込むことにしています. そのため,例えば \setemail の引数(*)の中の文字 _ は ``カテゴリーコード 12 の _''(以下,``変な _'' といいます)になり, \@email を使用するときにも変な _ のままになっています. (\showemail において \@email を使用するときには,\@sanitize はもはや 適用されていないにもかかわらず,文字 _ は(タイプライタ体を 用いている場合)そのまま出力されます.) %%% (*) ユーザインタフェイスの面では \setemail の引数ですが, %%% 実際には \setemail の引数にはしていない,という見方ができます. 一方,冒頭に引用した定義では,\setemail の引数を \@sanitize を 適用する前に読み取っています.したがって,\setemail の引数の中の文字 _ は 通常の _ のままで読み取られ,そのまま \@setemail の引数として用いられます. (\catcode の設定は,``これから読み取る'' 文字に対してしか 適用されないことに注意してください.) したがって,\@email の定義・使用の際にも通常の _ のままになり, 意図しない挙動を示すわけです. [蛇足] 細かい点ですが, \def\setemail#1{% \begingroup \@sanitize \@setemail#1}%%% (*) の (*) のところは \@setemail{#1}} とするおつもりだったのでしょうか. %%% このようにしたとしても,文字 _ の取り扱いが意図どおりではない, %%% ということには変わりはないのですが…

この書き込みへの返事:

お名前
題名 
メッセージ(タグは <a href="...">...</a> だけ使えます)