Acetaminophen’s diary

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

私と TeX Live と LuaTeX の近況レポート

これは TeX & LaTeX Advent Calendar 2018 の 9 日目の記事です。昨日は CareleSmith9 さんでした。明日は wtsnjp さんです。

おことわり

重点テーマにあまり関係しない記事です。TeX & LaTeX Advent Calendar 2016 の記事の続きのような感じですが,どうぞお付き合いください。

目次

日頃やっていること                      

TeXConf 2018 の懇親会の席でリクエストを受けたので,この辺の話を書いてみます。

私は 2017 年に TeX Live チームにも入りました。「TeX Live チーム」の定義が明確ではありませんが,ここでは以下のように定義することとし*1,私は一つ目に該当します。

以下のいずれかの条件を満たす開発者を「TeX Live チーム」とみなす。

さて,TeX Live チームの一員になって以降,私は以下のような活動をしています。すべて毎朝一回,お出かけ前に必ずやることです。毎日やっていれば,大体 15 分くらいで終わります(溜め込んでしまうとむしろ訳が分からなくなり,余計に時間がかかってしまいます)。

  1. TeX Live の subversion をチェックする。具体的には,ブラウザから Log of /trunk を訪問し,その日の変更内容を見る。
  2. W32TeX の [ChangeLog] をチェックする(ほぼ常に TeX Live と同期しているので軽く眺める程度)。
  3. 購読している TeX Live 関連のメーリスの配信を読む。具体的に特に重視するのは以下:
  4. GitHub にログインして https://github.com/ を訪れ,All activity を見る。TeX Live チームの一員であると同時に,2015 年から日本語 TeX 開発コミュニティの一員でもあるという立場上,特に注意して見るのは以下:
    • texjporg, TeX-Live 以下の全てのリポジトリ(当然)。
    • latex2e: LaTeX2e の開発元。
      → ここ,ちゃんと見ないと例えば「LaTeX が変わると pLaTeX が動かなくなる」という問題(例えばこんなの)が起こるので,極めて重要です。
    • latex3: LaTeX3 (expl3) の開発元。
      → expl3 という新しい言語は,それを使うだけで pdfLaTeX / XeLaTeX / LuaLaTeX / pLaTeX / upLaTeX の違いを考えずに済む「クロス・エンジンなコード」が保証されることを理念に掲げています。しかし,それをマクロで実現するためには「全てのエンジンに必要な機能が揃っている」ことが必須です。そこで例えば「足りない機能を e-pTeX と XeTeX に追加したい」という提案が出ることがあり*3,その動向からは目が離せません。
    • graphics-def: graphicx パッケージのドライバオプション(\usepackage[dvipdfmx]{graphicx} とか)の開発元。
      2017 年のバウンディングボックスの仕様変更をいち早く事前につかめたのも,ここを watch しているからです。

あとは,暇を見つけて(毎日ではない)TwitterTeX Live 関連,W32TeX 関連のツイートが流れていないか探す。ここは,どういうワードで検索フィルターをかけるかがノウハウになってきます…。

そして,何か気になる変更があったら覚えておいて,帰宅後に $ git pull なり $ svn update なりして取ってきます。特に,TeX Live subversion の Build/ 配下に気になる変更があったら,ビルド*4して試してみます。だいたい,週に1回か2回はビルドを走らせます。その結果,特に問題なさそうならそのままですが,もし何か日本で関心がありそうな変化があれば(この判断も経験がものを言います),TeX Forum あるいは GitHub の関連する場所で周知を図ります。

 

最近の LuaTeX の動向                      

今年の Advent Calendar の重点テーマが「とにかくLua(La)TeXしよう」なので,ここから無理やり LuaTeX っぽい話に移ります。とはいっても,LuaTeX を使う話ではなく,ここまでの流れと続く「LuaTeX を使えるようにする側」の話をします。

さて,TeX Live 2018 がインストールされている環境では

$ luatex hoge.tex
This is LuaTeX, Version 1.07.0 (TeX Live 2018)

と表示されます。現在の TeX Live subversion にある最新版をビルドしてみると

$ luatex hoge.tex
This is LuaTeX, Version 1.09.0 (TeX Live 2019/dev)

と出てきます。そして,LuaTeX の roadmap によると

Version 1.10
This will be the TeXLive 2019 release. (後略)

というわけで,TeX Live 2019 では LuaTeX 1.10.0 になると思われます。数字だけみると大したことはない違いに見えますが,これが結構大きな影響かもしれない,という話をします。

Lua 5.2 → 5.3 に完全移行                      

今年 4 月の記事にも書いていた予定では

  • LuaTeX 1.07 以降は Lua 5.3 ベースでビルドできる
  • TeX Live 2018 では従来の Lua 5.2 ベースの LuaTeX が標準だが、luatex53(LuaTeX として)と texlua53(Lua インタプリタとして)も一緒に配布する
  • TeX Live 2019 では標準が Lua 5.3 ベースになる

でしたが,これは着実に遂行されています。LuaTeX のソース (experimental) は今日現在,LuaTeX 1.09.1 になっていて,これは既に Lua 5.2 ライブラリが削除され,Lua 5.3 に一本化されています。私は Lua に詳しくはありませんが,Lua 5.3 のマニュアルにも 8. Incompatibilities with the Previous Version として Lua 5.2 → Lua 5.3 での非互換な変更が列挙されています。TeX Live にあるパッケージは対応が間に合うのだろうか…?

画像取込ライブラリの poppler → pplib への移行                      

LuaTeX の roadmap に以下のような記述があります。

Image handling
(略) Inclusion of PDF has been optimized in 0.50. In 1.10 we expect to have replaced the dependency on Poppler for embedding external PDF images by a dedicated small lightweight PDF access library that will also replace the now somewhat inconsistent epdf interface. This is part of the onguing effort to make LuaTeX as independent if other code as possible (the long term stable TeX narrative).

PDF を画像として取り込む(\includegraphics のような)機能を実現するためには,PDF を読み取る能力が欠かせません。その機能を,TeX Live 2018 までの LuaTeX は poppler という外部ライブラリに任せていました。ところが,LuaTeX 1.08.0 以降は poppler を捨て,pplib という小さなライブラリに移管しています。

この「poppler を捨てる」という流れは,TeX Live 界隈の最近の風潮になりつつあります。あまり詳しくない(けれども複数の有識者から話を聞いた)私の理解では,以下の要因が挙げられます。

  1. poppler が安定しない
    • poppler 自体はかなり強力な機能を持っている。(実際,InkscapeTeXworks などのツールも PDF レンダリングに poppler を採用している。)
    • ところが,その機能の多くは外部公開用 API として「仕様化」されているわけではなく,他のソフトウェアが使うことを意図していない
    • 外部公開用 API としては poppler-glib があるが,これはもちろん仕様として安定しているが,機能が足りないので,結局,内部向け API を使わざるを得ない。
    • すると当然ながら,内部用 API には poppler のバージョンアップごとに破壊的変更が入るので,それを使っていたソフトウェアが壊れる。
    • 勿論,安定な poppler-glib に API を追加してほしいという pull request を出している方もいるわけですが,なかなかマージされなかったり…。
  2. 比較的新しいコンパイラ (C++14) が必要
    • TeX Live 特有の事情として,新旧によらず「幅広いプラットフォームをサポートする」ことを目指している(Master/bin/ を見ると,2018 年現在 17 プラットフォーム)。「古いプラットフォームをいつまでサポートし,いつ排除すべきか」という議論でも,新しい言語により得られるメリットとデメリットが天秤にかけられる。
    • ちなみに TeX Live のコンパイルC++11 が必須となったのは TeX Live 2017 以降(dvisvgm version 2.x を皮切りに,ICU や Poppler などのライブラリが C++11 で書かれている)。
    • そんな中,poppler 0.69.0 からは C++14 が必要である。まだまだ C++14 対応コンパイラが利用可能な環境が多くないらしい状況を鑑みると,あと 2, 3 年は先の話になる?

実際に LuaTeX の場合も,poppler を捨てて pplib に乗り換えたことで C++ コンパイラが不要となり,純粋に C コンパイラだけでビルドできるようになったそうです。なお,TeX Live 2019 では恐らく poppler 依存のプログラムは XeTeX だけになると思います。

そもそも,LuaTeX の開発で LuaLaTeX は考慮されていない                      

この記事を読んでいて,LuaTeX を使ったことがある人のほとんどは,LuaLaTeX で

  • \usepackage{luatexja}
  • \documentclass{ltjsarticle}
  • \documentclass[lualatex]{jlreq}

のいずれかで,直接的あるいは間接的に LuaTeX-ja の成果物を使っていることでしょう。当然ながら,これらは LuaLaTeX で動いています

ところが,LuaTeX の開発目標は LuaLaTeX とは関係ないところにあり,その大きな部分を占めるのは Hans Hagen 氏が開発している ConTeXt です。実際に,forum:2513 の例のように「新しい ConTeXt + 新しい LuaTeX だと問題ないが,古い LuaTeX との組ではエラーが出て動かない(しかもTeX Live 2018 の物も古い部類に入る!)」というほど,LuaTeX と ConTeXt が密接に結びついているのです*5

ConTeXt は LaTeX や plain TeX と双璧をなす(?)マクロの枠組みで,文法が全く異なる(\starttext で始めて \stoptext で終わる等)だけでなく,開発コンセプトも LaTeX とは異なります。What are the differences between ConTeXt and LaTeX? には Hans 氏の考え方が色濃く出ています。また,歴史的背景としても,LaTeX は長年の多くの人による成果物を守るため,よほどのバグは直しつつもなるべく安定志向で維持開発されていますが,ConTeXt はまだその段階に至っていません。

その ConTeXt を動かす LuaTeX の設計思想にも,Hans 氏の考え方が大いに取り入れられていると感じます。例えば,LuaTeX は KnuthTeX を一から再実装していて,LuaTeX と TeX で生じる任意の違いは仕様 (feature) であり,TeX に合わせる気はないと言います。(Hans 氏がそのような発言をしていた気がするのですが,どこで読んだかは忘れました…。)また,先の「新しい ConTeXt + 古い LuaTeX だとエラーが出て動かない」の例は,ConTeXt のために LuaTeX の挙動が変えられたことを示唆します。何が変わったのか詳細はわかりませんが,ConTeXt のために LuaTeX が変わるようだと,いつか LuaLaTeX にも影響が出る可能性がないとはいえません*6

開発目標をどう持つかは自由なのでそれ自体は問題ではありませんが,「LaTeX 界隈での当たり前」が成り立たない LuaTeX (LuaLaTeX) が日本で受け入れられ,安定して使えるようになるのかどうかは,少なくとも私は見通せません。ただ,LuaTeX が「強い」のは確かなので,「安定」と比べてどちらを重視するかは個々人の判断に委ねられるところでしょう。

LuaTeX のフォーク版:LuaHBTeX                      

LuaTeX の公式版は主に Hans Hagen,Luigi Scarso,Taco Hoekwater らによって,ここまで述べてきたような独特の思想で開発されています。それとは別の方向性で,最近*7走っている LuaTeX のフォーク版プロジェクトが存在します。「LuaHBTeX」と名付けられたものがそれです。

これはエジプトの Khaled Hosny 氏が進めている「LuaTeX に HarfBuzz ライブラリを組み込む」という試みです。Khaled Hosny 氏といえば,XeLaTeX / LuaLaTeX で欠かせないといっても過言ではない fontspec パッケージに多大な貢献があり,ちょっと前までは XeTeX のメーリスでちょくちょく名前が出ていましたが,最近はどうやら LuaTeX でアラビア語を組むことに興味をお持ちのようです。

Arabic and color fonts in LuaTeX using HarfBuzz:
f:id:acetaminophen:20181209165000j:plain
Twitter より)

HarfBuzz は text-shaping engine と呼ばれるもので,「OpenType フォントに定義されている情報をもとに,ユーザが入力した Unicode コードポイントに対応するグリフを並べ,適切に配置する」という機能を提供するライブラリです。特に HarfBuzz には,アラビア語のような「隣り合う文字によって配置を変えて組む」という複雑な処理にも対応しているという強みがあり,これが現在の LuaTeX では弱いところとされています。同じく Unicode ベースの XeTeX は HarfBuzz を内蔵していて,そうしたアラビア語組版もこなすことができる*8ことと比べると,LuaTeX でも HarfBuzz を使いたくなるのも理解できます。

面白い試みなのですが,TeX Live チームからすると,この流れもまた難しいところです。LuaHBTeX は LuaTeX 本家のあずかり知らぬところで開発されていますから,方向性はよくわかっていません。

  • 先述のとおり LuaTeX は C++ 依存を外したのですが,HarfBuzz は C++11 を使っているので,結局ビルドに C++11 が必要になります。
  • LuaTeX に今後マージされるのかどうかは不明です*9

そういうわけで,動きは承知していながらも TeX Live チームとしては特に何もせず様子見です*10

追記(2019年4月):残念ながら LuaHBTeX は開発放棄されました。よくわかっていませんが,「バイナリに HarfBuzz を組み込む方式」ではなく,「LuaHarfBuzz なるライブラリを普通の LuaTeX から後で読み込む方式」になるのでしょうか。

 

まとめ                      

とりとめもなくなってしまいました…。でもリクエストは果たしました。

LuaTeX の怪しい動向を取り上げましたが,皆さんが使うのは自由ですし,それを TeX Live チームも最大限サポートしていくということは今後も変わりません。

*1:このように定義すれば,個別の「TeX に関連する何かを作って終了」するのではなく,それを「いかに TeX Live という枠組みに落とし込み,ユーザが使えるようにするか」という,よりマクロな「インフラ整備」とでもいうべき活動を指すことができると考えています。

*2:TeX-Live Organization (on GitHub) に所属している人数は,現在 18 名です(所属していることを非公開にしている人も含む)。しかし,実際には「GitHub アカウントで招待したので参加はしたが,活動実態がないメンバー」もいますので,ここではそれを TeX Live チームのメンバーとはみなしません。

*3:直近では \expanded というプリミティブが提案され,これは TeX Live 2019 の e-pTeX から利用可能となる予定です。

*4:簡単には,Build/source/ 以下にある「Build」というシェルスクリプトを走らせるだけです。

*5:実際に,LuaTeX の開発メーリス (dev-luatex) に修正をお願いするために LuaLaTeX の再現ソースを送ってみると返ってきたのは ConTeXt のソースでした。

*6:以前「LaTeX team の中の人が LuaTeX に要望を送ったけれども,結局通らなかった」という事象が確かあったような気がする…。ConTeXt とは対照的です。

*7:本当にごく最近の話で,おそらく初出は今年の 10 月 16 日のチャット (TeX, LaTeX and Friends - StackExchange) だと思われます。

*8:コマンドで xetex --version としてみると,使われている HarfBuzz のバージョンが表示されます。

*9:個人的には,マージされないのではないかと思っています。というのも,LuaTeX は OpenType フォントの扱いを,組み込みライブラリではなく全て Lua プログラムで書かれた fontloader によって実装しているためです。

*10:この本家 LuaTeX と LuaHBTeX をめぐる混沌が,TeXConf 2018 の懇親会の時に飲みながら Norbert さんと「勘弁してくれー」と言っていた話題です。

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

続きです。目次は前回の記事を参照してください。

 

7. dvipdfmx の仕様変更・機能強化       

仕様変更 2 件は,組版結果にも関わる大きな変更です。

7.1 バウンディングボックスのデフォルトが常に /CropBox へ       

昨年の TeX Live 2017 の解説記事で,「3. dvipdfmx の画像取り込みの挙動変更」として

従来の dvipdfmx のバウンディングボックス選択律「/CropBox → /ArtBox → /TrimBox → /BleedBox → /MediaBox の順に明示されている最初のものを選択する」が 2017 年 6 月に LaTeX team によって破棄され,「常に /CropBox を使う」という仕様に統一された

ことを述べました。この時点では「graphicx パッケージの dvipdfmx オプション (dvipdfmx.def)」の挙動が変わったのですが,TeX Live 2017 の時点では「dvipdfmx 本体」はまだ従来の挙動のままでした。どういうことかというと

TeX Live 2017 では「extractbb hoge.pdf で得られる .xbb に抽出されるバウンティングボックス」と,「graphicx パッケージが思うバウンディングボックス」が違う可能性がある

という状態です。TeX Live 2018 では,dvipdfmx 本体の改修も反映されますので,extractbb hoge.pdf でも常に /CropBox が返るようになりました。

7.2 回転された PDF (/Rotate) のサポート       

昨年の記事に【TeX Live 2018 に向けて】として書いていた部分です。

PDF の見た目を回転するために,PDF の内部に /Rotate という回転命令が仕込まれる場合があります。ほとんどの PDF ビューアはこの /Rotate 命令に従い,ページは回転して表示します。ところが,TeX Live 2017 までの dvipdfmx や XeTeX は /Rotate を無視し,ビューアの見た目と違う「回転前の向きのまま」で取り込むという挙動でした。これが TeX Live 2018 ではついに,dvipdfmx や XeTeX でも「/Rotate で回転されたページは回転して取り込む」という挙動に変更されました (r44963, r44964)。

以上 7.1・7.2 の結果を踏まえると,TeX Live 2018 では「PDF のページがビューアの見た目のまま(向き・バウンディングボックス共に)\includegraphics できる」ということになります。一方,過去のドキュメントをコンパイルすると結果が違ってびっくりすることもあるかもしれませんので,注意が必要です。

7.3 OpenType サポート機能の強化・修正       

dvipdfmx の OpenType サポート機能が TeX Live 2017 で追加されたことは,昨年の記事で述べました。ここで【TeX Live 2018 に向けて】として触れた修正内容が反映されますので,「一つのフォントには複数の OpenType Layout タグが付けられない」という制約がなくなります。

7.4 挿入可能な画像数上限の撤廃       

2015 年頃 (r37953) から 2017 年までの一時期,おそらく実装上の都合で「dvipdfmx で扱える挿入画像数の上限は 5000 枚まで」という制約がありましたが,撤廃されました (r45126)。

7.5 XeTeX で見 (U+898B) を処理すると ⾒(U+2F92) に化ける等の修正       

一見 dvipdfmx とは関係ないように見えますが,これは「XeTeX が組版した結果が xdvipdfmx(= dvipdfmx の独自拡張版)を通して PDF 化される過程」で起きている問題なので,dvipdfmx の問題です。

ここでは前者の質問を基に説明します。これは,「見」という見た目の字形が,Unicode文字集合の中に重複して登録されていることが一因でした(画像は Code Chart から。PDF 直リンク → U2F00.pdf, U4E00.pdf)。

  • CJK UNIFIED IDEOGRAPH - U+898B(「見る」を意味する単独の漢字)

    f:id:acetaminophen:20190413175254p:plain

  • KANGXI RADICAL SEE - U+2F92(漢字の一部,康熙部首としての⾒)

    f:id:acetaminophen:20190413175227p:plain     f:id:acetaminophen:20190413175241p:plain

意味は異なるので,Unicode に 2 回登場するのはおかしくありません。ただし,この字形を表示するフォントの方は,多くの場合は「見」という全く同じ見た目の字体を2つも収録せず,Unicode のコードポイント U+898B も U+2F92 も単一の「見」グリフを割り当てる多対一対応でいわば“節約”しています。

この“節約”で問題になるのが,「フォントの収録文字のうち何番目が,Unicode のどのコードポイントに対応するか」の対応づけです。これは ToUnicode CMap というもので,PDF からのコピペなどに必須のテキスト情報を定義するために欠かせません。(x)dvipdfmx は,フォントのxx番目の文字を使うという指示を受け取り,その文字を埋め込むのですが,その「見」が元々どちらの意味だったかという情報はもらえません。そこで,(x)dvipdfmx はフォントから逆算して ToUnicode CMap を作りますが,「多対一」の逆算は「一対多」ですから,必然的にどちらかを選ぶことになります。その選択の結果,たまたま「見」を単独の漢字 (U+898B) ではなく康熙部首 (U+2F92) を選んでしまっていた…というのがこの「部首問題」です。(x)dvipdfmx に限らず,他のソフトウェアや Web ブラウザでも似たような「部首問題」が起きることがあるそうです。

実用的な書類で部首が出てくることはあまりなく,漢字としての利用がほとんどでしょう。そこで,今回の例のような一対多の対応を考慮し,部首よりも単独の漢字の Unicode コードポイントを優先し,ToUnicode CMap に使うような対策がとられました(逆に言えば,部首のつもりで書いたものは漢字になってしまう,という制約があります)。

 

8. macOS 向けサポートファイルの分離・TLContrib 収録       

TeX Live は「利用や改変,商用再配布にライセンスの問題がなく(=フリー),かつフリーでない何かを動作に必要としない」ものだけを採用するという方針をとっています。そこで,様々な事情で TeX Live には入れないが,ライセンスの問題がなく,利用や再配布が自由なパッケージを代わりに収録して,TeX Live を補完しようというディストリビューションが存在します。TLContrib です(参考:forum:2366)。

以下のパッケージ群がこれに該当するので,TeX Live から分離されて TLContrib に収録されました。

  • ptex-fontmaps-macos (kanji-config-updmap):hiragino-elcapitan や hiragino-highsierra などの「macOS 専用のヒラギノフォント」を使うためのファイルを収録。
  • cjk-gs-integrate-macos:「macOS 専用フォント(ヒラギノを含む)」の設定用データベースを収録。
  • japanese-otf-nonfree:「ヒラギノフォントの和文プロポーショナル組」に使う TFM/VF を収録。

従って,TeX Live 2017 では単独で可能だった sudo kanji-config-updmap-sys hiragino-elcapitan が使えなくなります。TLContrib に収録されている ptex-fontmaps-macos をインストールすると,この命令が利用可能になります。方法の詳細は forum:2366 で既に告知してある通りです。

このように手作業で TLContrib をインストールするのが嫌だという場合は,GUI でこれが可能なツールが munepi さんにより公開されています。

 

9. kanji-config-updmap と cjk-gs-integrate の機能強化       

すぐ上に書いたフォントの設定に使われるツールですが,macOS 向けのファイルが分離された一方で,機能強化も入りました。

9.1 kanji-config-updmap で --ja と --sc などの同時設定が可能に       

2017 年に,それまでは jfontmaps という名前でインストールされていた「日本語用マップファイルと設定用スクリプト (kanji-config-updmap) のセット」が ptex-fontmaps に改名されて再出発しました。下記表題にもあるとおり,upLaTeX + dvipdfmx で中国語や韓国語の文書を作る場合の埋込フォントを切り替える仕組みが,このとき確立されました。

この時点ではまだ一度に多言語のファミリ名を指定することができず,例えば

  • まず kanji-config-updmap-sys hiragino-pron を実行して「日本語をヒラギノ」に変えてから
  • 次に kanji-config-updmap-sys --sc fandol を実行して「中国語を Fandol」に変える

というように複数回に分けて実行する必要がありました。新しいバージョン 20180306.0 ではこの制約がなくなり,例えば kanji-config-updmap-sys --ja hiragino-pron --sc fandol --tc adobe --ko unfonts のように,CJK 言語の設定を一度に変えられ,速度的に効率化できます。

9.2 cjk-gs-integrate の --fontdef-add で複数ファイル指定が可能に       

cjk-gs-integrate は「Ghostscript で CJK フォントを使うためのセットアップと,(--link-texmf オプションをつけた場合は)TEXMFLOCAL に dvipdfmx で CJK フォントを使うためのリンク作成を自動で行うスクリプト」です。新機能を使えば,“自分用のデータベース”を用意して cjk-gs-integrate に使わせることができます。

既に触れた cjk-gs-integrate-macos はこの新機能を活用し,「macOS 専用のデータベース」を用意することで実現されています。

 

10. ファイルサーチ機能 (kpathsea) の大文字・小文字の取り扱い       

これもユーザに影響する変更だと思います。

TeX Live は,多くの人が作成した成果物の集合体なので,大量のファイルを分類してディレクトリ構造 (TeX Directory Structure; TDS) に組み込んでいます。LaTeX を使う場合も,例えば \documentclass{article} と書けば article.cls というファイルが探され,\usepackage{scsnowman} と書けば scsnowman.sty というファイルが探されます。このようなサーチ機能の根幹を担っているのが Kpathsea ライブラリです。

さて,ファイル名にはアルファベットの大文字や小文字が使われますが,「大文字と小文字のファイル名を同じとみなすかどうか」は OS によって異なります(大文字と小文字を区別しないことを case-insensitive といい,区別することを case-sensitive といいます)。例えば,Windowscase-insensitive で,Linux などの Unix OS はほとんどが case-sensitive です。また,macOS の場合は case-insensitivecase-sensitive かを選ぶことができます(既定は case-insensitive)。

このような状況では,例えば foo.JPG というファイルが存在するとき

  • ある OS では \includegraphics{foo.jpg} で foo.JPG を見つけられたのに
  • 同じ .tex ソースを別の OS に持って行くと foo.JPG を探し出せなくてエラー

というようなトラブルが頻発していました(ということのようです)。そこで,Kpathsea version 6.3.0 で

  • 最初に呼ばれたファイル名 (foo.jpg) を探す。
  • もし見つからなければ,大文字と小文字が違うだけのファイルを探す。

というフォールバック機能が新設されました。

TeX Live 2018 ではこの機能がデフォルトで ON になっていますので,二段階のファイル検索が行われます。この機能を OFF にしたい場合は texmf.cnf という設定ファイルに定義されている環境変数 texmf_casefold_search の値を 1 から 0 にする必要があります。

この機能の詳細は,texdoc kpathsea で読める PDF ファイルの 5.4 Casefolding Search の節を参照してください。

 

11. dviselect や dviconcat 等のツールの pTeX / upTeX 対応       

日本の pTeX / upTeX は組版結果を DVI というファイルに出力します。TeX Live には沢山の DVI ウェアが収録されているのですが,(u)pTeX の DVI はオリジナルの TeX の DVI と比べて拡張されていて,その DVI を処理できるツールは少々限られています。TeX Live 2017 時点で (u)pTeX の DVI をサポートしていたのは,代表的な dvipdfmx,dvips と dvisvgm くらいでした。

ところが,他にも「時々使える便利ツール」が TeX Live には存在します。dviselect は,時々日本でも話題に上がっています。例えば,dvipdfmx で処理できない「10 万ページある DVI」を一旦 2 つの DVI にぶった切って別々に PDF に変換したい場合,この「ぶった切り」に使えます。

TeX Live 2017 までの dviselect は,pTeX の縦組を使った DVI を受け付けてくれませんでしたが,TeX Live 2018 では問題なく扱えるようになります。他にも dviconcat, dvitodvi, dvibook, dvidvi というツールが,TeX Live 2018 を以って pTeX 対応になります(これらの改修には,1992 年まで籠谷氏によって書かれていた「SeeTeX の日本語対応化パッチ」が大いに寄与しました)。

 

12. pdfTeX の「deterministic な出力」の改良       

以前の記事に【TeX Live 2018 に向けて】と書いていた話です。一般に,あるソースファイル test.tex を複数回コンパイルすると,その都度 DVI に埋め込まれる「処理日付の情報」や PDF の「フォント埋込オブジェクト番号」などが時間的・乱数的に変化します。しかし,「ある .tex ソースを何度処理しても完全にバイナリ一致する PDF を作りたい」という要望(主にテスト目的)があることから,TeX Live 2016 辺りから determinisitic (reproducible) な出力がサポートされるようになりました。

ところが,pdfTeX などで「ソースファイルを置くディレクトリの名前によって出力がバイナリ一致しない」という現象が報告されました。

これでは,最悪のケースでは OS ごと・ユーザごとに不一致な PDF が生成してしまい不便でした。TeX Live 2018 ではこの問題が解消します(必然的に,TeX Live 2017 と TeX Live 2018 では同じ環境変数を設定していても「違うバイナリ」が出てくるわけですが,しょうがないです)。

 

13. LuaTeX の Lua がバージョン 5.3 へ向け準備態勢へ       

LuaTeX には現在,Lua 5.2 が組み込まれています。しかし,TeX Live 2019 を目処に,Lua をバージョン 5.3 へ上げることを計画しているようです。具体的には

  • LuaTeX 1.07 以降は Lua 5.3 ベースでビルドできる
  • TeX Live 2018 では従来の Lua 5.2 ベースの LuaTeX が標準だが,luatex53(LuaTeX として)と texlua53(Lua インタプリタとして)も一緒に配布する
  • TeX Live 2019 では標準が Lua 5.3 ベースになる

ということのようです。

Lua 5.2 と Lua 5.3 では言語仕様が異なる(整数型の導入,math.pow の廃止などとのこと)ため,各種パッケージの改修が必要になると予想されます。移行期間とも言える TeX Live 2018 の間に,luatex53 バイナリを動かして,自分の手元にあるパッケージが確かめておくと慌てずに済むかもしれません。

 

14. その他の修正       

他にも幾つかありますが,細かいので箇条書きにとどめます。

 

駆け足ではありますが,多くの修正が入っていることがわかります。パッケージなどにもいろいろな修正・新機能が追加されているケースがありますので,それらもお時間のある時に texdoc を使って読んでみると面白いでしょう。

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 ソースを抽出します。

TeX Live 2017 注目ポイントまとめ

これは TeX & LaTeX Advent Calendar 2017 の 10 日目の記事です。昨日は hak7a3 さんでした。明日は isaribi_saitoh さんです。

2017 年も残りわずかとなりました。TeX Live 2017 がリリースされてから早くも半年が経ったことになります。遅くなりましたが、ここで

TeX Live 2016 やそれ以前から TeX Live 2017 へ移行する場合のメリット・注意点

をまとめてみます。TeX Live のメンテナのお一人であるノルベルトさんの記事もありますが、遅ればせながらここで紹介させていただきます。

ここで詳細な説明をすると長くなってしまうので、この記事ではあくまで変更点を俯瞰するにとどめ、それぞれの詳しい説明への導線を可能な限りで張ることにします。

一般の LaTeX ユーザ☃が使う上で注意が必要なのは

もう少し進んだ使い方(欧文フォントの TFM/VF の追加など)をするユーザの方は

新しいコトをもっともっとしてみたいユーザにとっては

に注目です。TeXnician の方々🍣は

をどうぞ。

宣伝:昨年と一昨年も似たような記事を書いていますので、よろしければどうぞ。

 

☃ ☃ ☃ ☃ ☃ ☃ ☃ ☃ ☃ ☃ ☃ ☃ ☃ ☃ ☃ ☃ ☃ ☃ ☃ ☃

続きを読む

コミュニティ版 pLaTeX / upLaTeX 2017/05/05 版の解説 (2)

前回の続きです。

 

3. LaTeX2e 2017-04-15 対応

本家 LaTeX2e が更新されたので、それへの対応です。

3-1. \verbverbatim 環境の修正

「入力したまま」を表示する \verbverbatim 環境に対して、本家 LaTeX カーネル側で修正が入りました。修正内容とは「verbatim な範囲では“絶対に”ハイフネーション行分割が起きないようにする」というものです。

あれ? と思った方、鋭いです。従来も、verbatim な範囲ではハイフネーションが起きないように設計されているはずでした(要するに、たとえページをはみ出してもどこまでも「入力したまま」の内容が横にのびていく)。が、そこには条件があったのです。その条件とは、ざっくり言えば「verbatim に使われるフォントがタイプライタ体のときには」というものでした。

これでは「任意のフォントで verbatim したい」という場合に困ってしまいます(おそらくフォント選択の自由度が高い XeLaTeX や LuaLaTeX では、問題が顕著になると思います)。そこで新しい LaTeX では、verbatim な範囲ではどんなフォントを使っていてもハイフネーションが抑制されるようになっています。

補足:日付表記の変更に関して

なお、platex や uplatex の起動時のバナーを見て気づいた方がいらっしゃるかもしれませんが

LaTeX2e <2017/01/01>

という表示から

LaTeX2e <2017-04-15>

という表示に変わりました。年/月/日 (YYYY/MM/DD) から 年-月-日 (YYYY-MM-DD) に変わったことで、ISO 8601 に準拠したことになります。

従来の YYYY/MM/DD 方式では、地域によって YYYY/DD/MM だったり DD/MM/YYYY だったりとバラバラでした。たとえば 2017/05/04 と書かれていた場合、これが 2017 年 5 月 4 日なのか 2017 年 4 月 5 日なのかわからない…ということが多々ありました。LaTeX2e の日付はこれまで常に YYYY/MM/DD の順になっていましたが、ときどきパッケージ開発者が間違って YYYY/DD/MM と書いてしまうことがあって混乱を起こしていました。

ISO 8601 に規定されたハイフン方式は、地域差なく必ず YYYY-MM-DD を表します。長い歴史のある LaTeX team が日付表記を曖昧さのない方式に切り替えたことは英断だと思います。また、起動時のバナーにそれが現れていますので、アピールの意味合いも大きいと思われます。

pLaTeX の日付はまだ 2017/05/05 のように YYYY/MM/DD のフォーマットを維持していますが*1、近い将来、コミュニティ版 pLaTeX / upLaTeX も、LaTeX team に追随してこれを YYYY-MM-DD に切り替える予定です。

 

4. nidanfloat パッケージのバグ修正

図や表が大きすぎて、二段組の片カラムに入りきれず両カラムにまたがる場合があります。LaTeX は標準では、こうした段抜きフロートをページの top([t] オプション)か、別ページ ([p] オプション)にしか配置することができません。これを bottom([b] オプション)対応にするのが、nidanfloat パッケージです*2

このパッケージには古くからバグがあり、qa:44116qa:51706 で指摘されてきました。「右カラムの処理中に段抜きフロートが出現すると、カラムの高さの計算を間違って本文とフロートが重なる」というバグです。

\documentclass[twocolumn]{article}
\usepackage{nidanfloat}
\usepackage{lipsum}
\begin{document}
\lipsum[1-5]
\begin{table*}[b]
\begin{tabular}{cccccccc}
\hline
AAAAAA & BBBBBB & CCCCCC & DDDDDD & EEEEEE & FFFFFF & GGGGGG & HHHHHH \\
\hline
a & 1.00 & 1.00 & 1.00 & 1.00 & 1.00 & 1.00 & 1.00 \\ 
a & 2.00 & 2.00 & 2.00 & 2.00 & 2.00 & 2.00 & 2.00 \\ 
a & 3.00 & 3.00 & 3.00 & 3.00 & 3.00 & 3.00 & 3.00 \\ 
a & 4.00 & 4.00 & 4.00 & 4.00 & 4.00 & 4.00 & 4.00 \\ 
\hline
\end{tabular}
\end{table*}
\lipsum[1-3]
\end{document}

f:id:acetaminophen:20160311140406p:plain

今回のリリースで、ついにこのバグを修正することが出来ました! 実に 10 年以上の懸案が解消したことになります。

f:id:acetaminophen:20170604115113p:plain

 

5. 目次の中で \ref の直後の半角スペースが消えるバグの修正

ラベル \label の番号や出現したページ番号を取得する「相互参照」機能の \ref\pageref ですが、pLaTeX / upLaTeX ではたとえばセクション \section のタイトルに使うと、目次に出したときに後ろの空白が喰われて消滅するバグがありました。

\documentclass{article}
\begin{document}
\tableofcontents
\section{Question}\label{q1}
\section{Another Question}\label{q2}
\section{Answer for the question in \ref{q1} and \ref{q2}}
\end{document}

f:id:acetaminophen:20170604120409p:plain

新しいバージョンでは修正し、正常に半角スペースが残るようになりました。

f:id:acetaminophen:20170604120425p:plain

補足:一部には \section のような「動く引数」*3では \protect を前置すべきでは? という話がありました。しかし、LaTeX2e の source2e.pdf を見ると「\ref\pageref を robust にした」と書かれています。pLaTeX ではこれが意図せず壊れていたわけですから、LaTeX と合わせるためには robust な実装にしないといけないわけです。

 

6. 出力ルーチンの高さ補正量の誤り修正

これは説明が難しいのですが…大雑把に説明します。従来の pLaTeX で以下の縦組文書を処理した場合、脚注ありのページとなしのページで版面がまるごとずれていました

\documentclass{article}
\documentclass{tarticle}
\begin{document}
脚注がないpage\clearpage
脚注があるpage\par テスト\footnote{あいうpage}\clearpage
\noindent\vrule width\textwidth height\textheight
\end{document}

実際にオーバーレイしてみるとこんな感じでした。

f:id:acetaminophen:20170604122742p:plain

これは、pLaTeX / upLaTeX カーネルの出力ルーチン内で、高さ補正量が正しくなかったためでした。新しい pLaTeX では次のように綺麗に重なります。

f:id:acetaminophen:20170604122801p:plain

 

7. \linebreak を行頭禁則文字直前でも有効化

これは、pTeX 系特有の処理の代表である「禁則処理」が絡む話です。

pTeX のデフォルトでは、行頭禁則文字すなわち「。」や「、」や「!」等の直前では絶対に行分割が起きないような設定がされています。問題となるのは、このpTeX が定義した禁則文字」と「LaTeX が提供する明示的な強制改行命令 \\ または \linebreak」が連続したときの挙動です。

従来の pLaTeX は「pTeX の行頭禁則文字の直前でも \\ という強制改行命令は効く」という対処が施されていました。ところがどういうわけか、\linebreak に対してはそうなっていませんでした。同じ LaTeX レベルの命令なのに、一方は強制改行して一方は改行しない…というのは不自然なので、新しい pLaTeX では「pTeX の行頭禁則文字の直前でも \linebreak という強制改行命令も効く」という仕様にしました。

もっと詳しくpTeX の禁則処理は、ペナルティという概念を流用することで実現されています。現在の pTeX は「通常の TeX のペナルティ (\penalty) の直後に行頭禁則ペナルティ (\prebreakpenalty) が連続する場合、その場で 2 つのペナルティ値を合算する」という挙動を示します。LaTeX\\\(no)linebreak はともに「通常の TeX のペナルティを発行する命令」なので、直後に行頭禁則ペナルティが続くとそこで合算が起き、結果的に強制改行が無効化されてしまいます。pLaTeX ではこれらの命令を改修し、「通常の TeX のペナルティを発行した後に“見えない壁”を置く」ことで、あたかも連続していないかのように pTeX に見せかけて合算を抑制するようにした、と説明できます。

 

8. その他

ほかにもいくつかありますが、些細なバグ修正なので挙げるだけにとどめます。

  • \textundescore を縦組の数式内テキストで使ったときの位置が変だったのを修正
  • plext パッケージの \Kanji{数字} のあとにも数字が続く場合、その数字まで漢数字に変わってしまうもバグを修正
  • plext パッケージによって拡張された \parbox 命令と \pbox 命令(LaTeX\makebox みたいなもの)を robust にした。さらに、\pbox が calc パッケージ(簡単な式による寸法指定が可能に)でエラーにならないように修正

 

未完の最重要案件:plext パッケージ

実は、現在 2017/05/05 の pLaTeX に付属している plext パッケージは未完成な部分が残っています。それは、tabular 環境や \parbox 命令の「組方向オプション」拡張機能を使った場合の位置の問題です。これは現在 pLaTeX レポジトリの issue 24 で議論している最中です。

なぜこれが問題かというと、plext パッケージは 2001 年からその構造はほとんど変わっていません。それにもかかわらず、pTeX のほうは何度も修正を経ています。その結果「plext は変わっていないのに、plext を使った pLaTeX 文書の処理結果が年々変化してしまった」という事情があります。これでは困るので、「最新の pTeX の挙動に即して、plext の仕様を確定させよう」というのが目標です。詳細は GitHub の議論を参照してください。

*1:これはごく一部の LaTeX パッケージが「スラッシュで区切られた日付」を想定して書かれているためです。たとえば stfloats.sty というパッケージは、2016/06/28 v3.2 まで YYYY/MM/DD 書式しか想定していませんでした。このままでは LaTeX2e 2017-04-15 が出た途端に stfloats.sty が全く動かなくなる…という懸念を作者に報告し、対処済みの 2017/03/27 v3.3 をリリースしていただいた、という経緯があります。このようなケースが他にもあるかもしれないので、pLaTeX / upLaTeX はもう少し慎重に様子を見ようとしています。

*2:これと同じような機能を提供するものに dblfloatfix パッケージなどというものがありますが、nidanfloat のほうがフロートを元のページに配置しやすい傾向にあり、dblfloatfix のほうが次のページに送りやすい傾向にあります。

*3:ざっくりいうと、外部ファイル .aux や .toc などに一度書き出されて再度読みこまれるという処理を通るもの。