Help us understand the problem. What is going on with this article?

TeX Live 2019 + 原ノ味フォント + llmk の Docker コンテナを作る

Docker を使えば,普段使いの TeX Live 環境とは別に古い TeX 環境を保管しておいたり,あるいは逆に先端の開発中ブランチを試しに導入できたりと,色々便利です。

というわけで今回は,TeX Live 2019 + 原ノ味フォント + llmk でコンパイルできる Docker コンテナを作ってみました。

目標

とりあえず完成品を使うには

イメージの pull

完成したイメージは Docker Hub に doratex/texlive2019ja-haranoaji としてアップロードしてあるので,

$ docker pull doratex/texlive2019ja-haranoaji

とすれば pull できます。(TeX Live 2019 がフルに入っているのでサイズが大きいです🙇)

使い方

コンテナ内では /workdir が作業ディレクトリとなるので,それをカレントディレクトリと bind マウントして使うのを想定しています。

alias dockertl="docker run --rm \
  --mount type=bind,src=\"\$(pwd)\",dst=/workdir \
  --mount type=volume,src=ltcache,dst=/usr/local/texlive/2019/texmf-var/luatex-cache \
  doratex/texlive2019ja-haranoaji"

などとエイリアスを設定しておくと楽でしょう。(--mount type=volume,... の部分は,LuaTeX のフォントキャッシュを ltcache というボリューム(名前は任意です)に保存し永続化させるための設定です。詳細は後述。)このエイリアスが設定されている下で

$ dockertl

とすれば,デフォルトで llmk が起動し,カレントディレクトリの llmk.toml に基づきビルドしようとします。

$ dockertl llmk hoge.tex

のようにして特定のファイルをターゲットにすることもできます。従来の latexmk もインストールされているので

$ dockertl latexmk hoge.tex

も使えます。

またもちろん,llmk や latexmk のようなビルドシステムを用いずに,

$ dockertl lualatex fuga.tex
$ dockertl ptex2pdf -l piyo.tex

などと普通にコンパイルすることも可能です。pLaTeX + dvips + ps2pdf のワークフローを使う場合は,

$ dockertl /bin/bash -c 'platex hoge.tex && dvips hoge.dvi && ps2pdf hoge.ps'

とすれば OK です。

(u)pLaTeX + dvips/dvipdfmx においては,デフォルトで原ノ味フォントを埋め込む設定になっています。

テスト用サンプルコード

GitHub レポジトリにテスト用サンプルコード群を置いてあります。

  • (u)pLaTeX + dvips
  • (u)pLaTeX + dvipdfmx
  • LuaLaTeX
  • XeLaTeX

のそれぞれについて,原ノ味フォントが埋め込まれるサンプルコードとなっています。test_all.sh を起動すれば llmk による各テストファイルのビルドが走ります。また,docker-compose を用いるサンプルも入れてあります。

Dockerfile の作り方

以下,この Docker イメージのビルドに用いる Dockerfile の作り方を述べます。

参考文献

@yyu さんがLaTeXで年賀状を作る際に製作された Dockerfile を大いに参考にさせていただきました。

迷ったこと

Alpine ベースか Ubuntu ベースか?

イメージのサイズ削減のためには,Alpine ベースでいきたいところです。が,実際にやってみたところ,大半はうまくいったのですが,XeTeX に動的リンクされる fontconfig が(apk add fontconfig-dev してあっても)うまく呼び出せず,XeTeX を起動することができませんでした。

割り切って「XeTeX は諦めて Alpine ベースにする」という手も考えられます。実際にイメージを作って比較してみたところ,

  • Ubuntu ベース(XeTeX 使用可):3.63 GB
  • Alpine ベース(XeTeX 使用不可):3.52 GB

となりました。TeX Live の scheme-full の容量が圧倒的で,もはや Ubuntu と Alpine のサイズの違いは誤差みたいなものとなっていました。それなら XeTeX が使えた方がいいだろうと考え,今回は Ubuntu ベースでイメージ構築することにしました。

TeX Live は scheme-full でいくか scheme-basic + collection-langjapanese でいくか?

イメージのサイズ削減のためには scheme-basic + collection-langjapanese の方がよいでしょう。が,LuaLaTeX / XeLaTeX / (u)pLaTeX で一通りの組版をできるようにするためにどのパッケージを追加すべきかを考えるのが面倒だし,「モダンな TeX Live 環境が丸ごと整う」ことが目標なので,今回はサイズは気にせずに scheme-full でいっちゃうことにしました。(ただしサイズ削減のために option_docoption_src は外す。)

原ノ味フォントへの対応方法

LuaLaTeX

TeX Live 2019 の最新レポジトリでは,luatexja-preset パッケージが haranoaji プリセットに対応しているのでそのままで大丈夫です。

(u)pLaTeX, dvips, dvipdfmx

pxchfon パッケージ

TeX Live 2019 の最新レポジトリで haranoaji プリセットに対応済みです。

ptex-fontmaps

TeX Live 2019 の最新レポジトリで haranoaji プリセットに対応済みです。

cjk-gs-integrate

TeX Live 2019 の最新レポジトリで原ノ味フォントがデータベースに登録済みです。

XeLaTeX

TeX Live 2019 の最新レポジトリで haranoaji プリセットに対応済みです。

Dockerfile でやること

Dockerfile によるイメージのビルドにおいては,大まかに次のことを行います。

  1. TeX Live 2019 の最新版をネットワークインストール。
  2. 原ノ味フォントを GitHub レポジトリから取得して TEXMFLOCAL 内にインストール。 (→ TeX Live に収録されたので不要になりました。)
  3. 原ノ味フォントに対応した最新版 ptex-fontmaps を GitHub レポジトリから取得して TEXMFDIST 内に配置。 (→ TeX Live に反映されたので不要になりました。)
  4. 原ノ味フォントに対応した最新版 cjk-gs-integrate を GitHub レポジトリから取得して TEXMFDIST 内に配置。 (→ TeX Live に反映されたので不要になりました。)
  5. 原ノ味フォントに対応した最新版の zxjafont を GitHub レポジトリから取得して TEXMFDIST 内に配置。 (→ TeX Live に反映されたので不要になりました。)
  6. mktexlsr して原ノ味フォントを TeX システムに認識させる。
  7. cjk-gs-integrate を走らせて Ghostscript の原ノ味フォント対応。
  8. kanji-config-updmap-sys で (u)pLaTeX の既定の和文フォントを原ノ味フォントにする。
  9. 最新版の llmk を GitHub レポジトリから取得して /usr/local/bin に配置。

課題の解決

XeTeX に TEXMF ツリー内のフォントを認識させる(現在では必須ではない)

(ここは原ノ味フォントを別途インストールしていた時代の記述で,現在では必須ではなくなりました。)

Linux の場合,XeTeX は fontconfig を利用してフォントを見つけていますが,上記手順では原ノ味フォントをTEXMFLOCAL 内に配置しましたので,fontconfig がそれを見つけられません。そこで,次のような内容を記載した XML ファイルを /etc/fonts/local.conf として保存しておきます。こうすることで TEXMFDISTTEXMFLOCAL 内のフォントを XeTeX が見つけられるようになります。

local.conf
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
  <dir>/usr/local/texlive/texmf-dist/fonts/opentype</dir>
  <dir>/usr/local/texlive/texmf-dist/fonts/truetype</dir>
  <dir>/usr/local/texlive/texmf-local/fonts/opentype</dir>
  <dir>/usr/local/texlive/texmf-local/fonts/truetype</dir>
</fontconfig>

その上で fc-cache -r することで fontconfig のキャッシュを更新しておきます。

参考: fontspec が呼び出すフォント検索エンジン

エンジン Windows Mac Linux/UNIX
XeTeX fontconfig AAT fontconfig
LuaTeX luaotfload luaotfload luaotfload

Mac 上の TeXLive の luaotfload で「クレー」などのフォントを使えるようにする - ルギア君の戯言より。

LuaTeX の初回フォントキャッシュ作成が遅い問題

LuaTeX の使用においては,フォントを初使用したときのコンパイルが遅いという点が問題となります。

luaotfload-tool -u -f しておくことで,TEXMFLOCAL/texmf-var/luatex-cache/generic[-dev]/names 内のフォントのデータベースは事前に作成しておくできます。ただし,それとは別に,フォントの初使用時に TEXMFLOCAL/texmf-var/luat
ex-cache/generic[-dev]/fonts/otl
にフォントキャッシュが作成されるため,各フォントの初回使用時のコンパイルが遅くなります。2回目からは速くなりますが,Docker イメージからのコンテナ生成ではこれが問題になります。イメージから毎回使い捨てのコンテナを生成して使う場合,毎回が「初回起動」になるため,起動のたびに毎回フォントキャッシュ作成が入って無用に時間がかかってしまいます。

これを防ぐ方法の一案としては,次のようにして「Docker イメージ作成時に全てのフォントを1回ずつ使って全フォントのキャッシュを作成しておく」方法があります。

for x in $(luaotfload-tool --list=* --fields=fullpath); do \
  /bin/echo "\\relax\\input luaotfload.sty \\font\\x[$x]\\bye" | luatex > /dev/null; \
done 

しかし,このようにしてキャッシュを事前に全作成をすると,Docker イメージのサイズが 1GB 以上も増えてしまいます。そこで,キャッシュが保存されるコンテナ内のディレクトリ TEXMFLOCAL/texmf-var/luatex-cache を,Docker コンテナ起動時に名前付きボリュームとしてマウントし,ホスト内に保存することで永続化させましょう。先ほどのエイリアスにはその設定を仕込んであります。

完成品

こうしてできあがった Dockerfile がこちらです。

イメージのビルド

$ docker build --no-cache=true -t doratex/texlive2019ja-haranoaji .
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした