マクロツイーター

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

LaTeX で \newfont したい話 (bxnewfont パッケージ)

本記事では「TFM が既に存在するフォントを LaTeX でまともに使う方法」について解説する。「TFM については知っているが、LaTeX のフォント管理機構(NFSS)については関わりあいたくない」という、チョットアレな人のための話。

新しいフォントを使う話

LaTeX において「新しいフォントが提供される」という場合、それは“そのフォントを使用するためのパッケージ”という形で提供されるのが通例である。例えば、次の Lobster Two フォントは、LobsterTwo というパッケージで提供される。

つまり、このフォントを使いたい場合は LobsterTwo パッケージを読みこんで、あとはそのパッケージの機能を仕様に従って((LobsterTwo パッケージの場合、\LobsterTwo 命令を実行するとフォントが Lobster Two に切り替わる。))利用すればいい。

\documentclass[a4paper]{article}
\usepackage{LobsterTwo}
\begin{document}
{\LobsterTwo Thanks TeX, and Good-bye!}
\end{document}

場合によっては、パッケージが提供されていなくて、代わりに「そのフォントを表す NFSS 情報」が示されることもある。例えば、CM Funny Italic フォント(本ブログ読者にはお馴染みの“アホなフォント”)は、「cmfr ファミリのイタリック体」である。

従って、“アホなフォント”を使いたい場合は、LaTeX のフォント指定命令を用いて所望のファミリとシェープを指定すればよいことになる。

\documentclass[a4paper]{article}
\usepackage{type1cm}
\begin{document}
{\fontfamily{cmfr}\itshape Thanks {\TeX}, and Good-bye!}
\end{document}

もちろん、あるフォントに対する NFSS のファミリ名が存在する、ということは、そのフォントに対する「LaTeX 用のサポート」が(パッケージでの提供ほど便利でないとしても)既に提供されていることを意味する。

\newfont が役に立ちそうな話

しかし、あるフォントについて、TFM は存在する(だから“TeX では使える”状況にある)が、NFSS の設定は提供されていない、という場合もある。例えば、「The TeXbook」で用いられているフォントの一つである CM Sans Serif Quotation Style は、一般的な TeX システムにおいて、cmssq8 という TFM 名で使えるようになっている。

つまり、plain TeX であれば、次のソースで上掲の出力を得ることができる。

% plain TeX 文書
\font\fcmssq=cmssq8 at 10pt % CM Sans Serif Quotation Style
{\fcmssq Thanks {\Tex}, and Good-bye!}
\bye

では、このフォントを LaTeX利用するにはどうすればよいだろうか。これがこの記事の本題である。

そもそも、NFSS の設定が提供されていない、ということはすなわち“LaTeX でサポートされていない”ということであり、そういう状況で LaTeX で使おうとすること自体に無理があるだろう。ところが実際は、LaTeX にはこのようなフォントを利用するための、\newfont という命令が存在する。使い方は TeX\font プリミティブとほとんど同じで、単に引数の書き方が“LaTeX 風”になっているだけである。

% LaTeX 文書
\documentclass[a4paper]{article}
% TeX の "\font\fcmssq=cmssq8 at 10pt" と同じ定義を行う
\newfont{\fcmssq}{cmssq8 at 10pt}% CM Sans Serif Quotation Style
\begin{document}
{\fcmssq Thanks {\TeX}, and Good-bye!}
\end{document}

この文書をコンパイルすると、cmssq8 を使った上掲の出力が無事に得られる。

というわけで、“TFM だけが存在するフォント”を LaTeX で使いたい場合は、\newfont 命令を利用すればよいのであった。めでたしめでたし……で終わればいいのだが、実際には話はそんなに簡単ではない。

\newfont が役に立たない話

\newfont 命令の何が問題なのかというと、それが“ほとんど TeX\font プリミティブそのもの”であることである。すなわち、「\newfont{\fcmssq}{cmssq8 at 10pt}」というコードが行う動作は「命令 \fcmssq が定義済であればエラーを出して、そうでなければ TeX の『\font\fcmssq=cmssq8 at 10pt』を実行する」という単純なものである。

※参考として、\newfont 命令の実装*1TeX 言語コードを示しておく。

\def\newfont#1#2{\@ifdefinable#1{\font#1=#2\relax}}

従って、\newfont 命令は NFSS を完全に無視した動作をする。なので、“LaTeX の普通のフォント命令”と併用するとワケノワカラナイことが起こってしまう。

例えば、先の cmssq8 を使った例で、テキストの一部の文字を大きく(\hyge サイズ)するにはどうすればよいか。

普通に考えると次のように書きたくなるだろう。

\documentclass[a4paper]{article}
\newfont{\fcmssq}{cmssq8 at 10pt}% CM Sans Serif Quotation Style
\begin{document}
{\fcmssq Thanks {\TeX}, and {\huge Good-bye!}}
\end{document}

しかしこれでは、\huge を適用した部分が既定のフォント(CM Roman)に戻ってしまい失敗する。

要するに \newfont で定義した \fcmssq と NFSS の命令 \huge は併用できないのである。結局、「大きい cmssq8」が使いたいのであれば、それを改めて \newfont で定義するしかない。

\documentclass[a4paper]{article}
\newfont{\fcmssq}{cmssq8 at 10pt}
\newfont{\fcmssqbig}{cmssq8 at 20.74pt}% \huge 相当のサイズ
\begin{document}
{\fcmssq Thanks {\TeX}, and {\fcmssqbig Good-bye!}}
\end{document}

\newfont についてはもっと厄介な欠点が存在する。LaTeX の一部の機能は“NFSS がちゃんと働く”ことを前提としている。だから \newfont はそのような機能とも併用できない。例えば、LaTeX のロゴ(\LaTeX)を出そうとすると、次のような奇妙な結果になってしまう。

\documentclass[a4paper]{article}
\newfont{\fcmssqbig}{cmssq8 at 20.74pt}
\begin{document}
% \LaTeX がアレになる!
{\fcmssqbig Never do {\TeX}, but do {\LaTeX}.}
\end{document}

※このような「\newfont の問題」については、UK TeX FAQ の次の記事で詳しく述べられているので、併せて読んでほしい。

\newfont はどうしてアレなのか

実は、\newfont は現在の LaTeX(2e)の“正式な”命令ではなくて、“LaTeX 2.09 時代の遺産”の一種である。そういう意味では、例の“二文字フォント命令”(\bf など)と似たような存在である。((ただし“二文字フォント命令”とは異なり、\newfont は LaTeX2e のカーネルで定義されていて、文書クラスの種類に依らずいつでも使うことができる。 ))

LaTeX 2.09 では文書中のフォントは次のようにして選択していた。

  • \rm\it\bf\sf 等の一群の命令により書体を選択する。((ここで \rm は「CM Roman」、\it は「CM Text Italic」、\bf は「CM Bold Extended Roman」、等のように各命令は特定の書体を表していた。これに対して LaTeX2e の NFSS の命令群は、「\bfseries は太字のシリーズ」「\itshape はイタリックのシェープ」のようにフォントの“特定の属性”を表して、その組み合わせで特定の書体を選択する仕組になっている。また NFSS においては「\rmfamily は既定では『CM Roman』のファミリであるがこれを『Times』のファミリに変更する」のような設定が可能である。))
  • \normalsize\large\small\scriptsize 等の一群の命令によりサイズを選択する。

しかし、これらの“LaTeX 2.09 のフォント命令”の枠組は拡張性を全く持っておらず、例えば「『CM Funny Italic』に対する書体命令を新たに作る」とか「\large\Large の間の大きさのサイズ命令を新たに作る」といった拡張は一切できなかったのである。しかしそれでは「LaTeX(2.09)の範囲では“予め決められたフォント”しか使えない」という残念な事態になってしまう。それを回避する苦肉の策として用意されたのが、「TeX\font プリミティブの薄いラッパーである \newfont 命令」だったのである。((従って、LaTeX 2.09 においても、\newfont で定義した命令と\large 等のサイズ命令は併用が不可能であった。))

これに対して、現在の LaTeX の NFSS では、設定(\DeclareFontFamily 命令)によって新しい書体ファミリを追加することが可能であり、またフォントサイズは最初から自由に選択できる(\fontsize 命令を使う)ようになっている。従って、\newfont のような“中途半端な LaTeX 命令”は不要である。恐らく、現在の LaTeX において \newfont 命令 は単に互換性のために残された obsolete な命令なのだろう。((実際、Lamport 本には \newfont 命令は全く載っていない。))

それでもやっぱり \newfont したい話

そういうわけで、現在の LaTeX\newfont を使うのはマチガイで、“正しい方法”は NFSS のパッケージレベル命令を用いて適切な設定を行うことである。ところが、実はこの設定がかなり厄介な代物なのである。実際に「cmssq8 を(現在の)LaTeX で使えるようにする」手順を解説した記事があるのでそれを眺めてみてほしい。

これを初めて見た人は恐らく「これは厄介だ」と思っただろう。実際、設定の記述そのものは複雑ではないのであるが、適切な設定コードを作り出すには、NFSS についての確実な知識が必要になるのである。

NFSS のヤヤコシイ話は勘弁してほしい、でも \newfont を使ってワケノワカラナイことが起こるのも嫌だ。そういう人が欲しいのは、“LaTeX でちゃんと動く \newfont”なのだろう。

bxnewfont で \newfontx する話

というわけで、作ってみた。

bxnewfont パッケージを読みこむと、\newfontx という命令が使えるようになる。この命令は、基本的には \newfont と同様の書式と機能をもつが、NFSS の機能を利用する。((つまり、\newfontx で定義される命令は、\usefont 命令での書体選択と \fontsize 命令でのサイズ選択を組み合わせたマクロになる。))従って、\huge 等の“LaTeX の普通のフォント命令”との併用が可能になっている。

\documentclass[a4paper]{article}
\usepackage{bxnewfont}
\newfontx{\fcmssq}{cmssq8 at 10pt}% x 付きにするだけ!
\begin{document}
{\fcmssq Thanks {\TeX}, and {\huge Good-bye!}}
\end{document}

もちろん LaTeX のロゴも正常に出力できる。

\documentclass[a4paper]{article}
\usepackage{bxnewfont}
\newfontx{\fcmssq}{cmssq8 at 10pt}
\begin{document}
{\fcmssq {\LaTeX}! \Large {\LaTeX}!! \huge {\LaTeX}!!!}
\end{document}

\newfontx 命令は、敢えて仕様を \newfont と合わせてあるので、これにより定義したフォント命令を実行すると必ず書体とサイズの両方を設定する。特に、\newfontx での定義時にサイズを指定しない場合は(\newfont および \font の仕様と同じで)その TFM のデザインサイズを指定したと見なされることに注意してほしい。

\documentclass[a4paper]{article}
\usepackage{bxnewfont}
\newfontx{\fcmssqA}{cmssq8 at 15pt}
% cmssq8 のデザインサイズは 8pt であるため,
% この指定は "cmssq8 at 8pt" と等価になる.
\newfontx{\fcmssqB}{cmssq8}
\begin{document}
{\TeX}              % 10pt
{\fcmssqA {\TeX}}   % 15pt
{\TeX}              % 10pt
{\fcmssqB {\TeX}}   % 8pt
\end{document}

bxnewfont で \newfontx* する話

\newfontx の「書体とサイズを同時に指定する」という仕様は、確かに元の \newfont には忠実であるが、明らかに不合理である。現在の LaTeX においてフォントサイズを自由に設定するのは極めて容易なことであるから、新たに定義するフォント命令は書体だけを変更するようにした方が適切であろう。そこで、そのような動作をする「\newfontx*-形」を用意した。

  • \newfontx*{\命令}{<TFM名>} :[一般命令] 新しいフォント命令 \命令 を(未定義ならば)定義する。その命令は、「現在の書体を指定の TFM のものに変更するが、フォントサイズは変更しない」という動作を行う。((\newfont の第 2 引数には“at 15pt”のようなサイズ指定を付けるができるが、\newfont* の第 2 引数は単純に TFM 名だけを指定する。))

\newfontx* 命令の使用例を示す。

\documentclass[a4paper]{article}
\usepackage{bxnewfont}
% 書体を CM Sans Serif Quotation Style にするだけの命令
\newfontx*{\fcmssq}{cmssq8}
\begin{document}
{\TeX}              % 10pt
{\fcmssq {\TeX}}    % 10pt
{\footnotesize % サイズ指定
{\TeX}              % 8pt
{\fcmssq {\TeX}}    % 8pt
}%
{\fontsize{15}{0}\selectfont % サイズ指定
{\fcmssq {\TeX}}    % 15pt
}%
\end{document}

bxnewfont パッケージを使うのであれば、従来の \font\newfont および \newfontx はなるべく使わずに \newfontx* だけを使うようにするのが望ましいと思われる。

*1:LaTeX [2016/03/31+3] の場合、latex.ltx の 3810 行目にある。