仄暗いリガチャーの底から

これは TeX & LaTeX Advent Calendar 2019 の記事ではありません

アブストラクト: 英文、独文においては合字 (リガチャー) を意図的に抑止する場合があるよ。\LaTeX でやる方法はいくつかあるけど、LuaLaTeX で selnolig パッケージを使うのが一番良さそうだよ。

はじめに

(La)TeX 関係の本を読めばたいてい最初の方に、(La)TeX の特徴として、カーニングや合字 (リガチャー) の話が出てくる訳ですが、それを読んだ私は何の疑いも持たず「あぁ (La)TeX に任せておけば、万事良きにはからってくれるのだな」と思い込んでいました (*1)

(*1) 今、美文書本 (初版) [1] を確認したら、「ただしoffline(ffl 合字) はoffline(ff 合字+l) のほうがいいのでしょうが,これは手動で指定しなければなりません。」との記述がありました。完全に読み飛ばしておりました。(ただ、ざっと見た感じ「手動で指定」する方法が書かれていないように見える…)

[1]: 奥村晴彦: LaTeX美文書作成入門. 技術評論社. 1991.

が、ごく最近、別件で l2kurz (\LaTeX2ε-Kurzbeschreibung [2]) を読んでいたところ、

Mit Rücksicht auf die Lesbarkeit des Textes sollten diese Ligaturen und Unterschneidungen (kerning) unterdrückt werden, wenn die betreffenden Buchstabenkombinationen nach Vorsilben oder bei zusammengesetzten Wörtern zwischenden Wortteilen auftreten. Dazu dient der Befehl \/.

Nicht Auflage (Au-fl-age) sondern Auf\/lage (Auf-lage)

Mit dem Paket babel steht zusätzlich der Befehl "| zur Verfügung, der gleichzeitig eine Trennhilfe darstellt.

Auf"|lage (Auf-lage)

なる文章が目に留まりました。

[2] Daniel, M. et al.: LaTeX2ε-Kurzbeschreibung (Version 3.0c8). 2018.
https://dante-ev.github.io/l2kurz/, https://www.ctan.org/tex-archive/info/lshort/german/

ざっくり意訳すると、

読み易さのために、前つづりや合成語の境ではリガチャーやカーニングは抑止されるべきである。その為には \/ が使える。

Auflage (Au-fl-age) ではなく Auf\/lage (Auf-lage)

babel パッケージでは "| も利用可能 (訳注: ngerman が必要) で、これを使うと、同時にこの位置にハイフネーションも指定される。

といった感じです。ちなみに、英語版 [3] では、

These so-called ligatures can be prohibited by inserting an \mbox{} between the two letters in question. This might be necessary with words built from two words.

Not shelfful but shelf\mbox{}ful

と、[2] とは異なる方法が書かれています。

[3] Tobias Oetiker et al.: The Not So Short Introduction to \LaTeX
Version 6.2, 2018.  https://www.ctan.org/tex-archive/info/lshort/english/lshort.pdf

「まぁ、言っていることは分かるけれども、ホントにそこまでやるのか?」と気になってしまったので、自分なりに少し調べてみました。

本記事内では、原則 ff, fi, fl のみに着目します。

極力ソースを提示しつつ客観的に記述するように努めましたが、なにぶん素人ゆえ、内容に間違い、勘違い等が含まれている可能性があります。その場合は、コメント等でご指摘いただけると有り難いです。

フォントを見てみる

さて、ひとまず、いくつかのフォントの中身を見てみてみましょう。なお、以下のフォントの選択については「なんとなく」以上の理由は特にありません。

実際のフォントの U+FB00–U+FB02 (ff, fi, fl の合字) を fontforge で見てみたところ、こんな感じになっていました。

ff, fi, fl のグリフがあるフォント

lmodern 等では期待通り、ff, fi, fl のグリフがあります。

Latin Modern

一部がもともとないフォント

Anonymous Pro や Bitter では fi, fl のグリフはありますが、ff はもともとありません。

Anonymous Pro
Bitter

ff, fi, fl のグリフがあるが、一部は普通に組むのと同等なフォント

XCharter-Roman では ff, fi, fl の全てのグリフがありますが、ff は f を 2 つ組むのと同等のようです。

XCharter-Roman

TeX Gyre Heros では ff, fi, fl の全てのグリフがありますが、fi, fl は それぞれ f + i, f + l と組むのと同等のようです。

TeX Gyre Heros

実際に重ねてみると、こんな感じです。

実際の印刷例を見てみる

気になり始めたのでなるべく気を付けて見ていたのですが、いろいろなパターンがあるようです。以下にいくつか実例を挙げます (ドイツ語の文献のみ)。

きちんと使い分けてる例

Faust (Goethe, Reclam XL–Text und Kontext, 2014)

verfluchte の fl は合字になっていますが、unbegreiflich では f+l になっています。後者において f と l はわずかに接しています。ff は f を二つと同等であるように見えます。

Moderne Rechenanlagen (Bauer et al., B. G. Teubner, 1965)

Flipflop は合字で、Auflösung は非合字で組まれています。この本では f と l が完全に離れています。

全て合字と思われる例

QualityLand [dunkel Edition, Version 2.4] (Kling, ullstein, 2019)

二つ目は Begriff、三つめは Aufforderung。後者の ff は非合字で組まれるべきところですが、ここでは合字になっています。

おまけで ft と ffl も。

全て非合字と思われる例

Anorganische Chemie [8. Auflage] (Riedel et al., Walter de Gruyter, 2011)

三つ目は Hypofluolit、四つ目は Auflösung (写真の大きさが違うのは申し訳ないです)。いずれの fl も全く同じものになっているようです。

こちらは ff の比較。一つ目は Kohlenwasserstoffe (再掲)、二つ目は Auffüllung。

Organische Chemie [5., aktualisierte Auflage] (Bruice, Pearson Studium, 2011)

こちらでも beeinflussen の fl と Auflösung の fl が全く同じものになっているようです。

LaTeX での合字抑止

文書全体で合字無しで組む方法

microtype による方法 (pdfLaTeX, LuaLaTeX 共通)

microtype + \Disableligature とするのが一番楽な方法でしょう。ただしデフォルトだと n-Dash や m-Dash 等まで対象になってしまうので、[f] オプションで f-合字のみを対象にすると良いです。

\usepackage{microtype}
\DisableLigatures[f]{encoding = *, family = *}

fontspec による方法 (LuaLaTeX)

LuaLaTeX では fontspec で Ligatures 機能を off にする方法も使えます [4]。各 Ligature については [5] が分かりやすいと思います。

\usepackage{fontspec}
\defaultfontfeatures{Ligatures={NoCommon, NoRequired, NoContextual, NoHistoric, NoDiscretionary}}
\setmainfont{Latin Modern Roman}

[4] Removing ligatures when using fontspec https://tex.stackexchange.com/questions/103238/removing-ligatures-when-using-fontspec
[5] Ligatures: the font-variant-ligatures property https://www.w3.org/TR/css-fonts-3/#propdef-font-variant-ligatures

手動での合字抑止

pdfLaTeX の場合

すでに述べたように、手動での合字抑止の方法として、l2kurz では \/ 及び babel の "| (ただし ngerman オプションが必要)、英語版では \mbox{} を使用する方法が挙げられています。また、Stack Exchange などでは {} を使う方法が挙げられていることもあります。また元祖 \TeXbook では、{shelf}fulshelf{\kern0pt}ful も挙げられています。

なお、Wikibooks (de) [6] では、

Die automatischen Ligaturen sollte man besser mit "| verhindern als mit \/, wie meistens empfohlen wird. Dies ist allerdings nur mit Babel möglich. Bei \/ wird zwar auch die Ligatur verhindert, aber der Abstand der Buchstaben wird meist zu groß.

Eine weitere Möglichkeit ist folgende:

\textit{auf{}fällig}

意訳:

合字の抑止には "| を使うべきである。確かに \/ でも抑止できるが、たいてい、文字の間隔が広くなりすぎる。 {} を使う方法もある。

[6] LaTeX-Kompendium: Ligaturen, https://de.wikibooks.org/wiki/LaTeX-Kompendium:_Ligaturen

としています。

ところで、上記文献では \mbox{}"| での違いに言及していませんが、実際には "|texmf-dist/tex/generic/babel-german/ngermanb.ldf の中で、

\declare@shorthand{ngerman}{"|}{%
\textormath{\penalty\@M\discretionary{-}{}{\kern.03em}%
            \bbl@allowhyphens}{}}

と定義されているので、{}\mbox{}"| では結果が異なります。つまり、
{}, \mbox{}: ボックス間に隙間無し
"|: ボックス間に 0.03em の隙間
\/: イタリック補正 (フォント/文字に依存?)
となります。次の図を見ると分かりやすいでしょう (それぞれ左から合字、\mbox{}"|\/)。

試しにそれぞれで組んでみました。

PDF 版は以下です:

私自身の趣味でいえば、fl は \/ で、それ以外は "| くらいが好みでしょうか。

やっかいなのは、立体と斜体でかなり印象が変わるということです。Latin Modern の斜体で試してみるとこんな感じです。いずれも \/ では間隔が広すぎて不恰好であるように思います。

ハイフネーションの問題

困ったことに、\mbox{}\/ もしくは {\kern0pt} を使う場合には注意が必要です。

Auflage は Auf-la-ge とハイフネーションされるべき語ですが、\mbox{} 等では la と ge の間も含めて一切ハイフネーションが起こらなくなります。Auf\mbox{}\-la\-geAuf\/\-la\-ge などとすれば「正しく」組むことができます。ただ、Auflage くらいならまだ良いのですが、Aufforderungssatz (Auf-for-de-rungs-satz) 等の場合だとさらに面倒です。まとめると以下のような感じです:

  • 正しくハイフネーションされる
    • Auflage, Auf{}lage, {Auf}lage, Auf"|lage
  • (全ての) ハイフネーションが捨てられる
    • Auf\mbox{}lage, Auf\/lage, Auf{\kern0pt}lage
  • これらで正しくハイフネーションさせるには、
    • Auf\mbox{}\-la\-ge, Auf\/\-la\-ge, Auf{\kern0pt}\-la\-ge

(補足) LuaLaTeX で \mbox{} を使用した場合は、\mbox{} を入れた部分のハイフネーションは落ちるがそれ以外のハイフネーションは維持、となるようです。

LuaLaTeX の場合

いろいろ試してみた結果、

  • LuaLaTeX では {} は完全に無視される (らしい)
  • 立体では \/ が効かない?
    (イタリック補正の扱いが pdfLaTeX と LuaLaTeX で異なる? もしくはフォントの違い (OTF か否か?) に起因?)

となりました。少なくとも LuaLaTeX で \/ による合字抑止は避けた方がよさそうな気がします。

自動合字抑止 (LuaLaTeX のみ)

ようやく本題。LuaLaTeX では selnolig (Selective suppression of typographic ligatures) というパッケージがあるので、これを使うのが良いでしょう。fontspec が必要です。

英文、独文においては、それぞれ \usepackage[english]{selnolig} もしくは \usepackage[ngerman]{selnolig} を指定します。それ以外は特になにもする必要はありません。ハイフネーションも元のまま維持されます。デフォルトのルールで不十分な場合は、\nolig コマンドや \keeplig コマンドでルールを追加できます。一部だけ合字を使用/抑止したい場合はそれぞれ \uselig コマンド、\breaklig コマンドが使えます (但し、\breaklig コマンドは selnolig がやっていることと等価ではありません)。

ちなみに selnolig では文字間に隙間が入りません。これを "| と同じ 0.03em にできないかと調べてみたのですが、現状では難しそうです。

(ここから、にわか知識による推測)
segnolig.lua のなかでは、ルールにマッチしたら WHATSIT node をつっこむ、ということをやっています。kerning を設定しようとすると、もう少し複雑なことをする必要がありそうです。(直前に DISC node があれば、その中に replace field を追加して… とか?)
なお node については LuaTeX Reference 参照。

おまけ: 本稿を書く際に利用したパッケージ (一部)

  • showhyphens: hyphenation の位置を表示。LuaLaTeX 専用。
  • nodetree: ノード木をログに出力。こちらも LuaLaTeX 専用。
  • transparent: 文字の透過。pdfLaTeX + LuaLaTeX。

おわりに

かなりの長文になってしまいました (ただし本題部分はごくわずか…)。「役に立った!」という方はほとんどいないと思いますが、せめて「役にはたたないけど、面白かった」と思っていただければ幸いです。