例の \en の問題の解答。
e-TeX 拡張エンジン上の plain TeX または LaTeX において、以下の要件を満たすように制御綴
\enを定義せよ。
\enは (La)TeX の寸法指定における「単位」の位置に書くことができる。- そして、「現在の
0.5em」の長さを表す。すなわち、1\enと0.5emは常に同じ長さを表す。
もちろん、次のものは不正解である。
\newdimen\en \en=0.5em
何故なら、これだと「em 値の解釈(絶対値への変換)」が \en に代入する時に起こってしまって、その後変わらないからである。だから、この後(fontdef トークンが実行されて)現在フォントが変わると、そこではもはや \en は「現在の 0.5em」とは一致しなくなる。((とすると、「\font プリミティブにフックを入れて……」という方向を考えたくなるかも知れないので、補足条件を入れてこちらを排除しておいた。))といって、
\def\en{0.5em}という単純極まるマクロで定義すると、確かに \en はいつでも「現在の 0.5em」となるが、2\en は当然ながら \en の 2 倍ではなく 20.5em となるのでこれもダメである。
e-TeX 前提の出題であるが、必要な e-TeX の機能は、割と有名なアレである。すなわち、正解はコレ。
\def\en{\dimexpr 0.5em\relax}これだけでよい。
\def\en{\dimexpr 0.5em\relax}
\font\cmttX=cmtt10 \cmttX
\skip2=-\en plus 1.23\en minus \en
\showthe\skip2 %==> -5.24994pt plus 6.4574pt minus 5.24994pt.これでよい直接の理由は、\dimexpr の式は、その式の値に等しい「単位」として機能するからである。例えば、
\parindent=6\dimexpr3pt\relax %「\dimexpr3pt\relax」は「単位」となる
とすると、代入されるのは 18.0pt である。
なお、\relax は \dimexpr の式の終端を表すのに使われる(値が解釈される際に吸収されその場には残らない)。もし \en の定義に \relax がないと、\dimen0=10\en+1pt のような場合に「+1pt」が巻き込まれてしまう(本来はそのまま文字として出力されるべき)ので不完全である。
何故 \dimexpr は「単位」になるのか
これは要するに「そういう仕様」なのであって、理由を挙げるのは難しい。ただし、以下の性質を考えて合わせていけば納得し易いかも知れない:
- TeX では「数字で書いた値」と「そうでない値」(「内部値」という)では文法的な扱いが異なる。
例えば、\count@=\p@とすると\count@には 1pt の換算値である 65536 が代入される。これに対して、値を直接記述して\count@=1ptとすると\count@は 1 となり文字「pt」が出力される。明らかに挙動が違う。 - 「単位」の役割を担える寸法は「内部値」のものだけである。
つまり、「\p@」は単位になるが、「1pt」は単位にならない。((「pt」は純粋な単位で、それ自体は寸法ではない。)) \XXXexprの式はそれ自体は展開可能でなく、前に\theを付けて初めて「その式の値(の数字表記)」に展開される:例えば、\edef\foo{\numexpr6*7}とした場合、\fooは「\numexpr6*7」のままである。\edef\foo{\the\numexpr6*7}とした場合は、\fooは「42」になる。- つまりは、
\numexpr6*7自体は数字で書いた「42」とは同等ではない。そして、\theというのは、「内部値」を「数字で書いた値」に変換する(例えば\the\p@→1.0pt)プリミティブである。そう考えると、\XXXexprの式はそれ自体は「内部値」と解釈できる。 - 従って、
\dimexprの式は「内部値の寸法」なので「単位」として機能する。