Acetaminophen’s diary

化学に関すること,TeXに関すること,ゆきだるまに関すること。

TeX Live 2018 注目ポイントまとめ (1)

今年 2018 年も、TeX Live 最新版のリリースが近づいてきました。注目の変更点をまとめてみましょう。特にユーザに影響しそうな項目については、以下の目次に太字で示しています。

 

1. LaTeX の入力エンコーディング (inputenc) が UTF-8 既定に                            

最近は XeTeX や LuaTeX のように「既定で任意の Unicode 文字入力が可能なエンジン」がありますが、それ以外(“クラシックな TeX エンジン”)では ASCII 以外の文字がきちんと解釈されませんでした。pLaTeX / upLaTeX もそれに含まれ、「和文扱いされる文字」は勿論入力できますが、「欧文扱いされる文字」については ASCII の範囲内しか扱えませんでした。そして、欧文扱いされる Unicode 文字を入力したい場合は \usepackage[utf8]{inputenc} が必須でした。inputenc パッケージについてはこの記事が詳しいです。

長年の制約がついに 2018 年リリースの LaTeX2e 2018-04-01 で解消し、既定で UTF-8 入力が有効になりました。つまり、\usepackage[utf8]{inputenc} を明示的に書かなくても、生で UTF-8 の欧文文字を書くことができるようになります。

互換性が少し心配になるところだと思いますので、箇条書きで説明します。

  • 従来 \usepackage[utf8]{inputenc} していたソースはそのまま通ります*1。同様に、utf8 と少し違う文字集合を利用できる \usepackage[utf8x]{inputenc} も、エラーなく通ります。
  • ただし、従来の「ASCII 文字以外は解釈されず素通りする」という挙動を利用した「ソースファイルを UTF-8 以外のエンコーディングにして、そのエンコーディング特有の文字を書く」という使い方は封じられます。具体例としては、ZR さんのコメントにあるような「ファイルを Windows-1252 (winansi) で保存し、フォントのエンコーディングを LY1 にする」という使い方はサポートされません*2
  • 現時点では \input{tèst.tex} のように ASCII 以外の欧文文字を含むファイル名を読み込もうとすると失敗します。これは LaTeX team も承知の上で、後々対処される模様です。対処としては、例えばこの David さんのコメントにあるように、\detokenize を噛ませるとうまくいきます*3
  • 直感に反するかもしれませんが「日本語の LaTeX ソースを UTF-8 以外のエンコーディングで用意して、pLaTeXコンパイルする」という使い方は、従来通り可能です*4。例えば、今後も Shift_JIS でソースを保存して platex -kanji=sjis test.tex のようにコンパイルすることは可能です(Windows の場合は下記の自動推定機能により -kanji=sjis も不要)。これは、pTeX 系では和文文字と欧文文字が字句解析の時点で区別されるので、欧文の inputenc がどうなろうが関係ないからです。
  • この件に影響を受けてか、Windows 上の TeX Live 2018 で pTeX / e-pTeX / pLaTeX の日本語入力エンコーディングの既定値が Shift_JIS から UTF-8 に変わりました(他の Unix 系 OS との統一が図られました)。ただし従来と変わらず「文字コードの自動推定」という機能が存在するため、影響は無いはずです。 (→ forum:2396)

なお、(u)pLaTeX 側では、新しい LaTeX における \DeclareFontEncoding の定義変更に追随しています。 (→ texjporg/platex#68)

 

2. pLaTeX などの更新                            

番外:texjporg 管理の成果物のパッケージ再構成                            

日本語 TeX 開発コミュニティ (Japanese TeX Development Community) が始動して 3 年目に入ります。GitHub で管理を始めたさまざまなプロジェクトを、「メンテナンスのしやすさ」という観点から再構成し、CTAN にアップロードし直しました(参考:texjporg/tex-jp-build#51)。

  • (1) pLaTeX
    • フォーマット作成時の .ltx ファイルの読込順序を変えた。目的は後述 upLaTeX (2) のため。
    • ascmac.sty は (4) へ移動。
    • nidanfloat.sty は (5) へ移動。
  • (2) upLaTeX
  • (3) ptex-fonts
    • ascmac 用フォントを (4) へ移動。
    • morisawa 用フォントを (7) へ移動。
  • (4) ascmac ← pLaTeX (1) と ptex-fonts (3) から新規作成。
    • コミュニティ版であれば pLaTeX/upLaTeX 専用でなく pdfLaTeX などでも動く。
    • ascmac だけ更新したい場合に都合が良い。
  • (5) nidanfloat ← pLaTeX (1) から新規作成。
    • 元々 pdfLaTeX などでも動くため。
    • nidanfloat だけ更新したい場合に都合が良い。
  • (6) jsclasses
    • morisawa.sty は (7) へ移動。
  • (7) morisawa ← jsclasses (6) と ptex-fonts (3) から新規作成。
    • TeX Live に入っていた morisawa.map は上流がなかったので取り込み。
  • (8) ptex-fontmaps
    • hiragino-{elcapitan,highsierra} など macOS 専用は ptex-fontmaps-macos に分離;後述
  • (9) cjk-gs-integrate
    • macOS 専用のデータベースを cjk-gs-integrate-macos に分離;後述
  • (10) ptex-base
    • 古いアスキーのドキュメント類 (jtex.pdf, jtexdoc.pdf, ptexdoc.pdf, ptexskip.pdf) は obsolete 扱い。既に現在の pTeX と合わない部分もあるため,歴史的な資料ということにする。
    • 最新の pTeX のマニュアルは別途 ptex-manual として鋭意作成中。

2.1 JFM グルーを消す \removejfmglue 命令の追加                            

pTeX には \inhibitglue というプリミティブが存在します。

\inhibitglue: 和文フォントのメトリック情報から、自動的に挿入されるグルーの挿入を禁止します。このプリミティブを挿入した箇所にのみ有効です。

もう少し詳細に書くと

  • JFM(和文メトリック)には、「括弧類などの文字(例えば )はあたかも半角幅であるかのように扱い、空白に見える部分(例だと右半分)は半角幅のグルーとして扱う」という定義がある。
  • pTeX はこれを解釈し、組版時に自動的にこのグルーを挿入する。
  • ただし、\inhibitglue という命令を発行した箇所では、この自動挿入を抑制する。

というわけです。例えば 」あ では間に半角アキが挿入されますが、」\inhibitglue あ とするとくっつきます。

ところが、例えば 」\relax\inhibitglue あ のように書いても の間には半角分のアキが入ってしまいます。なぜかというと、」\relax の時点でグルー挿入が起こり、その後で \inhibitglue で抑制しようと思っても「時既に遅し」だからです。あくまで inhibit = 抑制であって、削除ではないのです。

では、「既に挿入されてしまった JFM グルーを削除する」ことはできないのか、という疑問が起こります。これは従来の pTeX では不可能でしたが、2018 年 2 月 26 日の e-pTeX の更新で \lastnodesubtype という新しいプリミティブが追加されたことにより、マクロで実装可能になりました。

この新しい \removejfmglue は、次に挙げる表組のマクロ改善に寄与しています。

2.2 表 (tabular) の JFM グルー対策の改良                            

コミュニティ版 pLaTeX では、表(tabular 環境)のセル内が括弧類で始まる場合・終わる場合を考慮し、JFM グルーを消したいという要望を反映した修正を 2017 年に導入しました(参考:texjporg/platex#43)。ところが、この影響で「LaTeXpLaTeX組版結果が違う」という事例が発生してしまいました。

細かい事例ではありますが、対処しようにも従来の pTeX では不可能…というところを、\removejfmglue マクロを活用することで解消することができました。

2.3 新規約:和文クラスファイルで「和文スケール値」規定へ                            

和文クラスファイルをデザインするとき、和文文字と欧文文字のサイズバランスを考える必要があります。そして、多くのクラスファイルは、和文文字のメトリックをスケールすることで欧文とバランスを取るという方法が採られています。

例えば \documentclass[10pt]{…} のように 10pt が指定されたとき、全角幅 1zw はどんなサイズにするのが良いでしょうか? これはクラスファイルの設計者に委ねられるので、例えば (u)jarticle 系は 0.962216 倍、jsclasses 系は 0.924690 倍という設計になっています。

世の中には、フォントを変更する・多書体化するパッケージが存在します(例えば OTF パッケージ)。ここで「フォントは変えるけど、クラスファイルが意図するスケール値を極力踏襲したい」と考えると…。クラスファイル毎の設計値を知る必要がありますが、アドホックに「jarticle というクラスでは 0.962216 倍、jsarticle というクラスでは 0.924690 倍、…」のように一つ一つ登録する必要が出てきます。実際、新たなクラスファイルについてはその都度スケール値を調べないと、クラスファイルのデザインと合わなくなってしまうのです。

それでは不便なので、新たに pLaTeX / upLaTeX 系列では規約を策定しよう、という方向で進めています*5。なお、この方向性は LuaTeX-ja にも踏襲されています。

  • 和文クラスファイルは、和文スケール値(1zw ÷ 要求サイズ)を \Cjascale という名前のマクロで定義する。
  • フォント関係のパッケージは、必要なら \Cjascale を参照する。

この新規約に従って実装されているクラスファイルであれば、例えば OTF パッケージ(2018-02-01 v1.7b 以降)はそのクラスファイルの和文スケール値を踏襲してくれます。2018 年 4 月 7 日現在、以下がその規約に従っています。

  • クラスファイル
    • pLaTeX 付属の標準クラス (jarticle, jbook, jreport, tarticle, tbook, treport)
    • upLaTeX 付属の標準クラス (ujarticle, ujbook, ujreport, utarticle, utbook, utreport)
    • jsclasses (jsarticle, jsbook, jsreport, jspf, kiyou)
    • BXjscls (bxjsarticle, bxjsbook, bxjsreport, bxjsslide)
    • LuaTeX-ja 付属のクラス (ltjsarticle, ltjsbook, ltjsreport, ltjspf, ltjskiyou)
  • パッケージ
    • OTF パッケージ (otf)
    • ZR さん作の各種パッケージ (BXbase, BXcjkjatype, PXchfon, PXgtfont, ZXjafont, ZXjatype, ZXotf)

この記事を書いている時点では、JLReq クラス (jlreq.cls) は従っていません。現時点では \Cjascale を解釈するパッケージが(ほぼ OTF パッケージのみと)限られること、またその OTF パッケージのメトリックが日本語組版処理の要件と必ずしも合致していないことが理由と思われます。

2.4 ascmac パッケージを縦組でも pict2e と互換に                            

LaTeX の picture 環境系の命令は、TeX 本来の機能「線や文字を置くだけ」で描ける精一杯の描画をします。しかし、それだけでは描ける線の方向や円の大きさに制限があるため、pict2e パッケージが開発されました。これは「描画はドライバ(DVI → PS/PDF に変換するツール)に任せる前提で、picture 系の命令を \special を駆使したものに再定義し、綺麗な描画をする」というものです。通常の横組の範囲では、この pict2e パッケージはうまく機能し、LaTeX 標準のインターフェースはそのままに、幅広い描画が可能になります。しかし、pLaTeX や upLaTeX の縦組では一般に pict2e の結果が崩壊しますpTeX が思っている縦組の字送り・行送り方向と \special で描かれる線の方向が 90 度ずれてしまうためです。

ascmac パッケージは screen 環境などで「角の丸」を描画します。そのために使われる \oval も pict2e による再定義を受けるため、縦組で pict2e を読み込んだだけで screen 環境の「角の丸」が変な方向を向きます。…が、ascmac にとって必要なのは \oval だけなので、案外簡単に対処できます。

というわけで対処した新しいバージョンが、TeX Live 2018 からは利用可能です。

2.5 morisawa パッケージの \textmg 命令を robust に                            

pLaTeX の \textmc(明朝体にする)や \textgt(ゴシック体にする)は robust な命令として定義されています。長年 morisawa パッケージの \textmg(丸ゴシック体にする)はなぜか robust でなく展開されるという挙動でしたが、今回の更新で robust にしました。

 

3. pTeX の修正・e-pTeX の修正と新機能                            

この点については、北川さんによる詳しいまとめがあります。

上記では (e-)pTeX エンジンの挙動に注目してまとめられているので、私の記事では目次の引用とともに「pLaTeX / upLaTeX ユーザに影響しそうなポイント」まで落とし込んだ補足を付けておきます。

pTeX
  1. 組方向変更が可能な条件を厳格化
    • 「ボックスが空でない時は組方向変更できない」を徹底しつつ、「ボックスが空かどうか」の判定は少し緩んでいます。この厳格化で、例えば過去にあった「biblatex が縦組でエラー (forum:1508)」のような「かなり“微妙な”問題」は起きなくなります。
  2. \hbox{・} の処理
    • 例えば okumacro の \kenten 命令の実装には、\hbox{・} が使われています。今回の pTeX の修正に伴い、従来の実装のままでは圏点がずれる(参考:forum:2272)という問題が起きました。現在の okumacro は texjporg/jsclasses#60 を経て修正されています。
  3. 和文のコントロールシンボル
  4. エラーメッセージのヘルプ
  5. \ptexversion プリミティブなどの追加
  6. disp_node の処理
    • forum:2388 のような現象が起きなくなります。ただし
      \documentclass{tarticle}
      \begin{document}
      \noindent 「こんにちは!」
      
      と元気に挨拶した。
      \end{document}
      
      のようなソースの組版結果が変わります(TL2017 では最初の が二分下がり、TL2018 では天付き)。
  7. 禁則用ペナルティや \inhibitxspcode でデフォルト値を設定した場合
    • 北川さんの記事にも書かれていますが、texjporg/tex-jp-build#57 のバグが TeX Live 2018 の初版の (e)(u)ptex に混入してしまいました。この状況では「既に禁則ペナルティや \inhibitxspcode が設定されている文字に対して、デフォルト値を設定してキャンセルしようとする」行為は避ける必要があったのですが、TeX Live 2018 でバグが多発したため、例年にはなく異例の「バイナリのリビルド」が行われました。このとき r47477 の修正が反映されましたので、5月下旬以降に tlmgr でアップデートした場合は解消しています
e-pTeX
  1. \epTeXversion プリミティブの追加
  2. \epTeXinputencoding プリミティブの動作修正
  3. \pdfprimitive, \ifpdfprimitive の動作修正
    • pdfTeX / XeTeX の同様の問題も修正されました。
  4. ! File ended ... エラーの修正
    • pdfTeX / XeTeX の同様の問題も修正されました。
  5. \lastnodesubtype プリミティブの追加
    • これが pLaTeX の \removejfmglue に寄与します。
JFM の改善・拡張
  1. 0x10000 以上の文字コードをサポート
    • この新仕様の JFM をサポートすべく、各種 DVI ドライバも改修が入っています。具体的には、dvips, dvipdfmx, dvisvgm, dvipos, (u)pdvitype が対応完了しています。(u)pmpost, dviout, (p)xdvi は未対応となっています。
  2. glue/kern テーブルの制限緩和
    • ここで「JFM グルー・カーンの指定(glue/kern テーブルのエントリ数)も 32510 個まで」に制限緩和されたことが、upLaTeX で OTF パッケージの \propshape を使う場合(※ japanese-otf-uptex-nonfree のインストールが必要)に効いてきます。実際、ヒラギノプロポーショナル用の JFM は 256 個が上限では足りず、たくさんの glue/kern エントリが定義されています。
なお「検討中の事項:\inhibitglue の有効範囲」は TeX Live 2018 には適用されませんでした。今後も要検討となります。

 

4. upTeX の仕様変更:和文扱い・欧文扱いする文字範囲の変更                            

従来の upTeX 1.22 では、ASCII 以外のすべての Unicode 文字(U+0080 以上)を和文扱い*6していました。おそらく、pTeX が ASCII 以外の「JIS X 0208 で扱える文字全て」を和文扱いしていることに合わせたのでしょう。

upTeX 1.23 では、(非英語)欧文との親和性向上のため、デフォルトでラテン文字をなるべく欧文扱いするよう変更されました。

この影響で、例えば \kcatcode`À=15 (À: U+C0) のような書き方はうまくいかなくなります(この文字は今回「デフォルトで欧文扱い」に変更された内に含まれるので)。pxcjkcat パッケージを使っている場合は(pxcjkcat も対応完了しているため)問題ありません。

 

5. makejvf の大規模拡張                            

makejvf とは、pTeX組版に使う JFM メトリックから、実際のフォントへの“橋渡し”を担う Virtual Font (VF) を作成するためのツールです。従来の makejvf ではできなかった機能が追加され、使い方次第で VF のカスタマイズが可能になりました。(TeX におけるフォントの扱いに詳しい方向けの難しめの内容を含みますが、極力簡単な記述を心がけます。)

5.1 Enhanced mode の追加                            

JFM では約物を半角幅のように扱い(その不足分を伸縮可能な JFM グルーで補い)ますが、実際の和文フォントでは約物も固定全角幅でデザインされています。この齟齬を解消するため、VF は「JFM グルーの分だけ文字を左にシフトする」という処理を担います。

この「シフト量」は、一般的な日本語フォントのデザインを前提として、makejvf のソース中にハードコードされていました。これでは日本語用 JFM に対してはうまくいきますが、例えば繁体中国語フォント(句読点類が仮装ボディの左下でなく、中央にデザインされているケースが殆ど)では失敗し、アンバランスになります。

このようにハードコードされたシフト量を使うのではなく、JFM に即した VF を作ることができればいいのに…という希望を叶えるのが、Enhanced mode です。-e オプションをつけて起動すると Enhanced mode に入ります。

-e           Enhanced mode; the horizontal shift amount is determined
             from the glue/kern table of <TFMfile> input

この Enhanced mode は、JFM に格納された glue/kern テーブルをうまく読み出し、その文字ごとに「pTeX が左に挿入してくるグルー量の分だけ、実際のフォントでは文字を左にシフトする」としてやれば良いという発想に基づきます。

例えば uptex-fonts に収録されている uptch〜 という繁体中国語用 VF はこの -e を利用して作成されています。

5.2 カスタマイズ用 Configuration file の読込機能                            

それでも少し特殊な JFM を作ると、シフト量が期待通りにならない場合がありえます。そこで使えるのが設定ファイルを読み込む -t オプションです。

-t  Use <CNFfile> as a configuration file

この設定ファイルでは「シフト量 (MOVE) の他にも「文字の置換」(REPLACE) と「VF に含める文字集合」(CHARSET) も指定可能です。使い方は以下の GitHub の議論中に日本語で書かれているのと、texdoc makejvf で表示されるマニュアル(英語)を参照してください。

既に、2018-02-11 にリリースされた uptex-fonts ではこの設定ファイルを利用し、upTeX / upLaTeX 用のデフォルト日本語 JFM(upjis 系)で Adobe-Japan1-6 の全文字を出力できるようにしてあります。ZR さんの「アレなデフォルト」の「その4:upLaTeXでBMP外の字を使うとアレ」が解消したのも、この makejvf の新機能あってのものです。

5.3 makejvf のその他の修正                            

細かい修正も入りました。(texjporg/tex-jp-build#16, texjporg/tex-jp-build#17)

 

6. KnuthTeX / PLtoTF と TeX Live 版のそれらとの差異解消                            

ちょっと驚きの発見が相次ぎました。少しだけ嚙み砕いた表現にすると、「TeX Live に 20 年以上収録されている TeX は、実は作者 Knuth が作った TeX とは動作が違った」といった事件が発生したのです。それを修正した結果、TeX Live 2017 以前と比べると TeX の字句解析の挙動まで変わってきます(といっても、かなり特殊なケースですが)。

6.1 TeX で行末のタブ文字が消えなくなります                            

KnuthTeX は、Pascal WEB というプログラミング言語で書かれていて、Pascal コンパイラコンパイルします*7。しかし、Pascal コンパイラを持っている人は少ないので、TeX Live では WEB から C 言語に変換し、C コンパイラコンパイルしています。このような TeX の実装をよく「Web2C 版の TeX」と呼びます。

TeX Live の TeX は「Web2C 版」なのですが、元の Pascal WEB から C に変換してコンパイルするために、入出力部分を書き直すことになります。その際に、「行末にタブ文字があった場合」の処理方法がまずく、Knuth が作った TeX と Web2C 版の TeX の間に違いがあることが 2017 年に見出されました。

これがついに修正され、TeX Live 2018 に反映されています。なお、この修正により、昨年の TeX & LaTeX Advent Calendar 2017 の 20 日目の記事

にある記述

行の最後のコマが空欄の場合は,Tabと改行の間に{}(ブレースの組)を入れてTabと改行を仕切ってください。そうしないと,TeXの字句解析器の段階で改行が食われてしまい,うまくいきません。

の問題が自動的に解消します。

6.2 PLtoTF が不正な TFM を作らなくなります                            

TFM を作成するツールである PLtoTF が「TeXBad metric (TFM) file. と怒られる不正な TFM」を作ってしまうという問題です(発見者は私)。

TFM には、全体のファイルサイズの上限が存在します。TeX Live 2017 までの PLtoTF には、TFM 生成時にサイズ上限を超えてもエラーを出さずにオーバーフローしてしまうという挙動がありました。その結果、大きすぎて読み込めない TFM ができてしまい、TeX や TFtoPL(逆変換ツール)に怒られてしまうわけです。このオーバーフローは、Pascal WEB ソースの PLtoTF にある整数値のレンジ 0〜32767 を C で書き直すときに、(signed) int のレンジ -32768〜32767 に拡張されてしまうことが原因でした。

この問題は日本語の JFM を作る (u)pPLtoTF も引き継いてしまっており、特に (u)pTFtoPL はこの不正な JFM を食わせるとメモリ不足のエラー(場合によっては落ちる)ケースがありました。TeX Live 2018 ではこうした問題に対処しています。

 

まだまだ続きます

*1:従来は「\usepackage[utf8]{inputenc} した時点で utf8.def というファイルが読まれる」という仕組みでした。新しい LaTeX では最初から utf8.def が読込済の状態になっていて、敢えて二回目は読まれないように対処されています。newunicodechar パッケージも 2018-04-08 付けで LaTeX の新仕様をサポートしています。

*2:これと同じ理由で、ZR さんのブログにある例のように「Shift_JIS の半角カタカナを直接書く」という使い方はサポートされません。これらの使い方は“バッドノウハウ”にすぎず、正統な使い方ではありません。

*3:なお、2018-04-08 時点でリリースされていた LaTeX2e 2018-04-01 patch level 1 には「ターミナルから pdflatex tèst.tex と打っただけでもエラーになる (issue 32)」という問題が存在したので、patch level 2 で修正されています。このエラーの理由は「ファイル名のつもりの引数も、実は TeX 言語コードの一部である」という TeX のアレな仕様に由来します。参考:ZR さんのブログ

*4:上述の「半角カタカナの“バッドノウハウ”」は除く。

*5:現時点では、pLaTeX の「公式マニュアル」と呼べるものが存在しないので、「規約化しました」と宣言するには不十分な状態になっています。今後、ドキュメントを整備しながら、これを規約として成立させられるよう善処する予定です。

*6:upTeX の仕様によると、厳密な表現は「CJK 扱い(漢字、仮名、その他記号、ハングルのうちのいずれか)」とすべきですが、簡単のため和文と呼ぶことにします。

*7:WEB とは「文芸的プログラミング」で、ソースコード本体とその解説文書を一緒に書くという、Knuth が提案した手法です。TeXソースコード tex.web は実際に Pascal WEB で書かれています。tex.web をコンパイルして TeX のバイナリを生成するためには、tangle というプログラムで Pascal WEB から素の Pascal ソースを抽出し、Pascal コンパイラコンパイルします。また、解説文書を処理するためには、weave というプログラムで TeX ソースを抽出します。