[LaTeX2ε] NFSS2下で特定のフォントに対するTFM名を取得する

本稿では，LaTeX2εのNFSS2に基いて設定された，ある特定のフォントが用いているTFMの名前を取得する方法を提示する。動作はupLaTeXで確かめている。

## 動機
欧文をComputer Modern Type Writer等のタイプライタ体にした際に，和文で単純にゴシック体を用いると字体が大きく見えてしまう。これを解消する為に，TFM（および関連するVF・実フォント）はゴシック体を流用するが縮尺が小さいようなフォント形状を新たに作成することにした。

```latex
\DeclareKanjiFamily{\kanjiencodingdefault}{thb}{}% thb: 等幅
\DeclareRelationFont%
{\kanjiencodingdefault}{thb}{m}{}%
{\encodingdefault}{\ttdefault}{m}{}
\DeclareFontShape{\kanjiencodingdefault}{thb}{m}{n}%
{<->s*[0.8]upjisg-h}{}% 問題
```

上掲の様に設定すれば，下掲の様に宣言することによって，小さい和文ゴシック体と連動する標準タイプライタ体（この場合はComputer Modern Type Writer）が出力できる。

```latex
\userelfont
\fontencoding{\kanjiencodingdefault}%
\fontfamily{thb}%
\fontseries{m}%
\fontshape{\updefault}%
```
`\XXXdefault`等を駆使して，なるべく異なる処理系において命令を変更する手間を少なくするよう心掛けた。しかし，「`% 問題`」と註釈した行において，異なる処理系において命令を変更する手間が発生する。`upjisg-h`はupLaTeXにおける横組ゴシック体の標準TFMであり，縦組の場合や，pLaTeXやOTFパッケージを用いた場合は当然異なる名前を用いなければ，統一性が図れないばかりか異常終了する恐れもある。
`upjisg-h`というTFMを用いる目的は，（例えば「自分で設定した特殊なTFMを用いる」ことではなく）「現在の横組ゴシック体で用いられるTFM名と同じ名前を使う」ことであるから，自動的に取得したい。

## 方法と実装
TeXには`\fontname`という原始命令が存在し，あるフォント出力命令が用いているTFM名を取得できる。

```tex
\font\tmpfnt=cmss10 at 13pt
\fontname\tmpfnt% → ‘cmss10 at 13pt’
```

この命令は当然LaTeX上でも使えるが，使用上の問題がある。LaTeX2εのNFSS2が提供している機構では，plain TeX等とは異なり，利用者が`\font`という原始命令を用いることは（理想的には）無い。従って，「あるフォントに対するTFM名を取得したい」場合，その「あるフォント」というのは`\font`命令ではなくNFSS2が提供するより高度で抽象的な方法で指定したフォントを指すと考えてよい。すると，利用者は`\font`命令を直接扱うことができないから，`\fontname`原始命令に対してどういう名前の命令を指定すればよいか簡単には分からない。
具体的に言い直せば，上掲の例では利用者が`\tmpfnt`という名前の命令をあるフォントを出力する命令として宣言していることが明白であるから，`\fontname\tmpfnt`という形でTFM名を取得できたが，NFSS2では利用者が`\font`命令を直接弄れない・参照できない為に，`\fontname\???`の`\???`に置くべき命令の名前が把握できない，ということである。

しかし，LaTeXは，TeXが提供する原始命令をより高度で抽象的な方法で扱えるようにしているだけであるから，NFSS2においても結局は`\font`等の原始命令を用いている。よってNFSS2の仕組みそのものを流用して，`\font`命令の書式で宣言されたフォント出力命令の名前を取り出し，`\fontname`命令に指定すれば良い。LaTeX2ε中核には`\get@external@font`という外部フォント[^1]（つまりTFM名）を取得する内部命令が既に備わっているから，新規に作成する必要はない。本稿の目的は，この命令の定義を目的に沿うように変更するだけで達成できた。
具体的には，

*  寸法を表わす “at $n$pt” 等が表示されないように
*  `\external@font`に値を格納するだけでなく，その値を表示するように

した。

以下に実装例を示す。なお，不正なフォント指定に対する検証は行なっていない。

```latex
\newcommand*{\GetFontShapeTFM}[5][]{%
\begingroup
\if\relax\detokenize{#1}\relax\else%第1引数が空の場合はフォント寸法を指定しない。
\def\f@size{#1}\fi
\let\external@font\@empty
\edef\font@info{%
\expandafter\expandafter\expandafter\string\csname#2/#3/#4/#5\endcsname}%
\try@size@range
\ifx\external@font\@empty
\try@size@substitution
\fi
\mandatory@arg
\endgroup
}
```

### 使用法
```latex
\GetFontShapeTFM[〈寸法〉]{〈符号化方式〉}{〈族〉}{〈系列〉}{〈形状〉}
```

例

```latex
\GetFontShapeTFM{JY2}{gt}{m}{n}% → upjisg-h
\GetFontShapeTFM[18]{OT1}{cmr}{m}{n}% → cmr17
```

### 改善したい点
#### `\mandatory@arg`の不使用
`\mandatory@arg`にはTFM名のみが格納され，それと寸法の情報を合わせて`\external@font`に格納される訳だが，`\external@font`と異なり，`\mandatory@arg`は外部からの参照を全く想定していない雰囲気が感じられる名前である。`\external@font`の内容・挙動に関する仕様は固定的であり，変更する際には報知されると思われるが，その内部で用いられる`\mandatory@arg`の仕様は暗黙に変更される恐れがある。`\mandatory@arg`にTFM名を格納している処理に直接介入して，不安定な内部命令への依存を減らしたい。

## 参考
* [The LaTeX2ε Source](http://texdoc.net/texmf-dist/doc/latex/base/source2e.pdf) 2019-10-01 Patch level 3

[^1]: TFM名（とその寸法）のことを「外部フォント」と呼ぶのは “The TeX Book” に倣ったものと思われる。“The TeX Book” において，`\fontname`の説明に「“external file name” を表示する」旨の記述が見受けられる。