マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

もっともっと数式フォントできない話(1)

例の「チョット数式フォントしてみる話」の途中で、「数式フォントの個数の上限」についてチョット触れた。次の制限のことである。

数式フォントは 16 個しか登録できない。

つい最近、某フォーラムでもこの制限に関する議論があったところである。

ところで、この「16 個」という制限は、実際はもう少し話が複雑である。例の一連の記事で数式フォントの設定の基礎を習得したところなので、もう少し精密な説明をしてみようと思う。*1

TeX が数式フォントする話

LaTeX の数式フォントの上限は 16 個」であるそもそもの理由は「“TeX の数式フォント”の上限は 16 個」であることである。そこでまずは“TeX の数式フォント”について概説する。

TeX のフォントの話(復習)

まずは TeX のフォントの扱い方について復習しようj。LaTeX が NFSS というやや複雑なフォント管理の機構を備えているのに対し、TeX 自体のフォント管理は非常に単純なものである。すなわち、「CM Funny Italic の 20pt」というように具体的なシェープとサイズが決まったものが「TeX のフォント」であり、\font プリミティブを用いて「フォントを表すトークン(fontdef トークン)」を定義するのであった。

%"CM Funny Italic の 20pt"を \ahofont として定義
%※"CM Funny Italic" の TFM 名が cmfi10
\font\ahofont=cmfi10 at 20pt

つまり、TeX にとっては、同じシェープであってもサイズが異なるものは“全く異なるフォント”と扱われることに注意しておこう。

TeX の数式ファミリの話

ところがこの扱い方では数式を組むのには都合が悪い。数式中では添字として「同じシェープの小さいサイズ」のものを使う必要があるからである。

そこで、TeX の数式モードでは「同じシェープのサイズの異なる 3 種類のフォント(標準、添字用、二重添字用)」を一まとめにして扱っている。これを「数式ファミリ(math family)」と呼ぶ。TeX では 16 個の数式ファミリのレジスタを持っていて、これには 0〜15 の番号がついている。そして、数式中で“フォントを指定する”必要がある場合は、個々のフォント(fontdef トークン)ではなく「数式ファミリのレジスタ番号」により指定する、という方式を採っているのである。

ここから解るように、数式中の文字として使えるフォントは、数式ファミリのレジスタに設定したものに限られる。そしてこの制限こそが、「“TeX の数式フォント”の上限は 16 個」の意味するところなのである。

TeX で実際に数式ファミリする話

もう少し具体的な例として、plain TeX において「アホな数式」を出す話をする。

plain TeX の既定では、数式フォントのレジスタには次のようにフォントが割り当てられている。

ファミリ標準
\textfont
添字
\scriptfont
二重添字
\scriptscriptfont
備考
0cmr10cmr7cmr5“operators”/\rm
1cmmi10cmmi7cmmi5“letters”/\mit
2cmsy10cmsy7cmsy5“symbols”/\cal
3cmex10cmex10cmex10“largesymbols”
4cmti10\it
5cmsl10\sl
6cmbx10cmbx7cmbx5\bf
7cmtt10\tt
8〜15(未使用)

例えばこの中でファミリ 6 は「CM Bold Extended Roman」が入っている。数式中で \fam6 という命令を実行することで(数式英字が)当該のフォントに切り替わる。((ちなみに、ファミリ 4 のように添字のフォントが未割当の場合、${\fam4 a^2}$ のような添字を含む数式を出力しようとするとエラーになる。))

$a^2 + {\fam6 a^2}$

それでは、今は空いているファミリ 8 に“アホなフォント”(CM Funny Italic; TFM 名は cmfi10)のファミリを割り当ててみよう。まずは所望のサイズの cmfi10 の fontdef トークンを \font 命令で定義する。*2

% フォントの定義
\font\tenaho=cmfi10           % 標準(10pt)
\font\sevenaho=cmfi10 at 7pt  % 添字用(7pt)
\font\fiveaho=cmfi10 at 5pt   % 二重添字用(5pt)

次にこれらの fontdef トークンをファミリ 8 のレジスタに代入する。これには次のような代入文を用いる。

% 数式ファミリ8の設定
\textfont8=\tenaho            % 標準
\scriptfont8=\sevenaho        % 添字用
\scriptscriptfont8=\fiveaho   % 二重添字用

これらの準備を行った後に数式中で \fam8 を実行すると、無事にフォントが「CM Funny Italic」に切り替わる。

$N = {\fam8 3^{3^3} = 3^{27} < 3^{33}}$
% '=' や '<' はアホになっていないことに注意

ただし、先の出力を見て判るように、フォントが変わるのは“数式英字”に限られる。これは LaTeX で数式フォント命令を用いた場合と同じである。

チョット補足
  • 数式ファミリレジスタに現在割り当てられているフォントが何かを知りたい場合は、\fontname プリミティブを利用できる。例えば \fontname\textfont6 を展開すると、ファミリ 6 の標準のフォントの名前である「cmbx10」という \the-文字列になる。
  • 一つの数式の途中で数式ファミリへの割当内容を変更することはできない。*3これに対して、数式モードの外でレジスタの値を変更することで、異なる数式が異なるフォントのセットを使う、ということは可能である。(つまり“文書全体”では 16 個より多くのフォントを用いることができる。)例えば、先述の plain TeX の設定は、明らかに「本文のフォントサイズが 10pt である」ことを前提としている。もし文書の脚注をフォントサイズ 8pt で組んでいてその中でも数式を出力したい、という場合は、数式ファミリの設定を「フォントサイズが 8pt」に適したもの((例えば \textfont0 = cmr8、\scriptfont0 = cmr6、など。))に変更する必要がある。LaTeX においては、テキストのフォントサイズを変更した場合に数式ファミリレジスタの値を自動的に追随させて“適切なサイズの fontdef”に変えている。((実際には数式モードの開始時に(\everymath フックを利用して)この“追随”の作業を行っているようである。(先の脚注に書いたように、数式モードの開始時に変更すればその数式には変更が適用される。)))
  • 「数式ファミリ」について、Knuth 自身は単に「ファミリ(family)」という用語を用いている。しかしこれは NFSS の「フォントファミリ(font family)」という用語と紛らわしい。*4このため本記事では「数式ファミリ」という用語を採用した。
(つづけ)

*1:従って、「チョット数式フォントしてみる話」の一連の記事を読んでいることを前提とする。もちろん、“無慈悲な大前提”はここでも課される。

*2:10pt 用の cmfi10 だけがあって cmfi7 等はないので、cmfi10 を縮小して用いることになる。

*3:正確にいうと、数式の途中で数式ファミリレジスタへの代入はできるが、当該の数式モードを終了した時点でのレジスタの内容が数式全体に適用される。

*4:もちろん「数式ファミリ」は TeX 言語の概念であり LaTeX とは無関係である。ちなみに LaTeX では、用語の混乱を避ける為か、TeX の「(数式)ファミリ」のことを「数式グループ(math group)」という別の用語で呼んでいる。しかし「グループ(group)」も (La)TeX で別の意味がある用語なので、自分はあまり適切でないと思う。