和文の記号の名前を持つ制御記号(control symbol)、例えば \☃
に対して保護付のマクロを \DeclareRobustCommand
で定義したとする。
% upLaTeX文書, UTF-8 \documentclass[uplatex,dvipdfmx,a4paper]{jsarticle} \usepackage{scsnowman} % ☃のマフラーは赤色 \DeclareRobustCommand*{\☃}{\scsnowman[% hat,arms,buttons,snow,muffler=red,scale=1.3]} \begin{document} % 目次 \tableofcontents % 本文 \section{{\TeX}とは何か} アレ。 \section{\☃とは何か} 非アレ。 \end{document}
よく見ると、目次の☃の部分の出力がおかしい。☃の後に余分な欧文空白が入ってしまっている。それもそのはず、補助(.aux)ファイルを見ると、明らかに \☃
の後に空白文字が入っている。
\relax \@writefile{toc}{\contentsline {section}{\numberline {1}{\TeX }とは何か}{1}} \@writefile{toc}{\contentsline {section}{\numberline {2}\☃ とは何か}{1}}
TeX on LaTeX な人には周知の通り、\DeclareRobustComamnd
で \foo
を定義した場合は、内部で“foo␣”という名前の制御綴が使われる。\foo
が動く引数で用いられた場合、補助ファイルにはこの内部制御綴が \foo␣␣
という形で書き出されるので、再び字句解析されたときには \foo
に戻る、という仕組である。この仕組に従って、保護付の \☃
の定義では、補助ファイルに \☃␣␣
が書き出されるわけだが、☃
は英字扱いではないので、これは空白トークンが 1 つあると見なされてしまうのである。
というと、欧文の制御記号でも全く同じことになりそうな気がするが、そうではない。例えば、先の例で \☃
の変わりに \8
を使った場合は、補助ファイルは次のようになる。余計な空白文字は書き出されず、従って、組版結果にも余分な空きは現れない。
\relax \@writefile{toc}{\contentsline {section}{\numberline {1}{\TeX }とは何か}{1}} \@writefile{toc}{\contentsline {section}{\numberline {2}\8とは何か}{1}}
何故欧文の方は正常なのかというと、この場合は LaTeX が特別に対処しているからである。元の制御綴の意味を調べてみる。
\DeclareRobustCommand*{\☃}{NICE!} \typeout{(\string\☃=\meaning\☃)} \DeclareRobustCommand*{\8}{NICE!} \typeout{(\string\8=\meaning\8)} \stop
すると次のような結果になる。明らかに、欧文の方は普段(制御語の場合)と違う少し複雑な定義になっている。
(\☃=macro:->\protect \☃ ) (\8=macro:->\x@protect \8\protect \8 )
これに対して、和文の制御記号の場合はこの特別扱いから漏れている(制御語と同じ扱い)ことがわかる。LaTeX カーネルが和文の制御記号を制御記号と扱い損ねているのであろう。