パッケージ・フォント管理

LaTeX 環境の維持で本当に効いてくるのは、tlmgr のオプション表を覚えることではなく 「ファイルをどこに置くか」 の判断です。TeX が使う探索パス TEXMF を印字すると、いくつかのツリーの前にだけ !! という印が付いています。これは「ディスクを走査するな、ls-R データベースだけを見よ」という指示で、この二文字があるかないかで 手で置いたファイルが即座に見つかるか、mktexlsr を叩くまで見つからないか が決まります。このページでは、tlmgr によるパッケージの追加と更新、ユーザツリー TEXMFHOME とシステムツリー TEXMFLOCAL の使い分け、CTAN から手で入れる手順、そしてフォントマップ(updmap)の管理までを、手元の TeX Live 2024 で実際に測った値とともに扱います。

パッケージを足す — tlmgr install の使い方

latex のパッケージを追加する 標準の手順は tlmgr install <名前> の一行で、依存パッケージも既定でついてきます。名前を一つずつ挙げるほか、collection-fontsrecommended のようにコレクション単位でまとめて入れることもできます。システム全体のツリーへ入れる構成なら 管理者権限が要ります(Unix 系は sudo tlmgr install …、Windows は管理者のシェル)。依存を引きたくないときは --no-depends、壊れたファイルを入れ替えたいときは --reinstall を付けます。

terminal
# Install a package; dependencies come along by default
tlmgr install siunitx
tlmgr install collection-fontsrecommended

# Skip dependencies, or overwrite a broken install
tlmgr install --no-depends siunitx
tlmgr install --reinstall siunitx

# A system-wide tree needs admin rights
sudo tlmgr install siunitx

実務でこれより大事なのは、エラーメッセージから名前へ渡る道筋 です。LaTeX Error: File siunitx.sty not found のようなエラーが出たとき、いきなり検索で拾った .sty を原稿フォルダへ置くのは最悪手です。まず ファイル名パッケージ名 を分けて考えます。ファイル名は siunitx.sty、パッケージ名は siunitx——たいてい一致しますが、tikz.stypgf パッケージに入っているように、しばしばずれます。tlmgr search --global --file は「そのファイルを収録しているパッケージ」を答えるので、ここが橋渡しになります。名前がうろ覚えなら tlmgr search --global <語>、素性を知りたければ tlmgr info <名前>(説明・ライセンス・サイズ・収録ファイルまで出ます)。

terminal
# From "File siunitx.sty not found" to an installed package
kpsewhich siunitx.sty                      # is it already here?
tlmgr search --global --file siunitx.sty   # which package ships it?
tlmgr install siunitx                      # install it properly

# Half-remembered name, or curious about a package
tlmgr search --global siunit
tlmgr info siunitx

見落としやすい挙動を一つ。tlmgr installtlmgr remove も、/usr/local/bin などシステムディレクトリのシンボリックリンクを張り直してはくれません。PATH を TeX Live の bin ディレクトリそのものに通しているなら関係ありませんが、tlmgr path add で実行ファイル・man・info のリンクを作る運用にしているなら、新しい実行ファイルを持つパッケージを入れたあとに自分で tlmgr path add を(削除後は tlmgr path remove を)走らせる必要があります。コマンドを打つのが苦手なら、TeX Live には Tcl/Tk 製の GUI tlshell が付属していて、検索・導入・削除・一括更新・リポジトリ切り替えを窓から行えます。裏で走ったコマンドのログも見えるので、tlmgr を覚える入口としても向いています。

更新は --self と --all をセットで

定番は tlmgr update --self --all の一行で、--selftlmgr 自身(インフラ)を、--all が残り全部を最新にします。この順序は好みの問題ではありません。tlmgr のマニュアルは --all について「tlmgr 自身を除く全パッケージを更新する。tlmgr 自身に更新があるときは、--force--self も指定しない限り エラーになる」と明記しています。つまり古い tlmgr は「まず自分を入れ替えさせろ」と言って止まるわけです。両方を渡せば、tlmgr は先に自分を入れ替え、成功したら新しい版で残りの更新を続けます。

terminal
# The standard move: infrastructure first, then everything else
tlmgr update --self --all

# See what would change before committing to it
tlmgr update --list

# Update one package only
tlmgr update siunitx

この更新で同時に起きることも把握しておきましょう。サーバ側でコレクションから外されたパッケージは 自動削除 され、コレクションに加わった新パッケージは 自動導入 されます(--list を付けると事前に一覧で確認できます)。取得先は リポジトリ の設定で決まり、既定では CTAN のミラー自動振り分けです。回線が遅い、あるいは特定ミラーに固定したいなら tlmgr option repository で恒久的に切り替え、その一回だけ別ミラーを使いたいなら --repository <url> を付けます。用紙サイズのような既定値も tlmgr が握っているので、A4 に揃えるなら tlmgr paper a4(プログラム別なら tlmgr dvips paper a4)です。現在の設定は tlmgr option show でまとめて見られます。

terminal
# Where tlmgr fetches from, and other stored defaults
tlmgr option repository ctan          # automatic CTAN mirror redirection
tlmgr option repository https://example.org/CTAN/systems/texlive/tlnet
tlmgr option show

# Use a different mirror for one run only
tlmgr install --repository https://example.org/CTAN/systems/texlive/tlnet siunitx

# Paper size defaults are stored here too
tlmgr paper a4
tlmgr dvips paper a4

TEXMFHOME と TEXMFLOCAL の違い

tlmgr が管理しないファイル——学会テンプレートのクラス、自作のスタイル、CTAN から手で落としたパッケージ——を置く場所は二つあり、TEXMFHOME が自分専用、TEXMFLOCAL がマシン全体 です。どちらも配布物のツリー(TEXMFDIST)より 先に 探索されるので、同名ファイルがあればこちらが勝ちます。実際の場所は環境で変わるので、思い込まずに印字してください。この Mac で kpsewhich -var-value=TEXMFHOME を叩くと /Users/wedd/Library/texmf が返ります——~/texmf ではありません。Linux では ~/texmf が既定なので、Linux 向けの手順をそのまま Mac でやると、置いたファイルが永久に見つからない という事故が起きます。TEXMFLOCAL はこの機械では /usr/local/texlive/texmf-local で、注目すべきは 年のディレクトリの外にある こと。だから来年の版に入れ替えても、ここに置いたものは生き残ります。

terminal
# Never guess these paths - print them
kpsewhich -var-value=TEXMFHOME    # your own tree (differs on macOS and Linux)
kpsewhich -var-value=TEXMFLOCAL   # machine-wide tree, outside the year directory
kpsewhich -var-value=TEXMFDIST    # the distribution itself - do not edit by hand

# The whole search order, including the !! markers
kpsewhich -expand-path='$TEXMF'

どちらに置くかの判断は単純です。自分の原稿のためのファイルは TEXMFHOME、共有マシンで全員に使わせたいものは TEXMFLOCALTEXMFHOME なら管理者権限が要らず、OS の再インストールでもホームごと移せます。ディレクトリの中は配布物と同じ構成(TDS)に従い、LaTeX のスタイルなら tex/latex/ の下に置きます。この構成の全体像は「ディレクトリ構成とパス」に譲りますが、実務では下のコード例の階層を覚えておけばだいたい足ります。なお 原稿フォルダに .sty の古いコピーを置くのは避けてください。TeX はカレントディレクトリを最優先で探すので、tlmgr で更新しても古い方が勝ち続け、原因の掴めない不具合になります。

terminal
# A personal class file, in the tree that belongs to you
HOME_TREE="$(kpsewhich -var-value=TEXMFHOME)"
mkdir -p "$HOME_TREE/tex/latex/local"
cp mythesis.cls "$HOME_TREE/tex/latex/local/"
kpsewhich mythesis.cls    # should print the path immediately

# Let tlmgr manage that tree too, with no root required
tlmgr init-usertree
tlmgr --usermode install siunitx

mktexlsr / texhash はいつ必要か

答えは明快で、TEXMFLOCAL やシステムのツリーに手でファイルを置いたときは必要、TEXMFHOME に置いたときは不要 です。理由は冒頭に書いた !! にあります。この機械で TEXMF を展開すると、/usr/local/texlive/texmf-localtexmf-dist の前には !! が付き、~/Library/texmf には付いていません。!! は kpathsea への「このツリーはディスクを見ず、ls-R データベースだけを信じよ」という指示なので、ls-R を更新しない限り新しいファイルは存在しないのと同じ です。裏づけとして、ls-R を持つツリーの一覧である TEXMFDBS にも TEXMFHOME は含まれていません。実際 texmf-dist/ls-R はこの機械で 276,953 行あり、22 万を超えるファイルを毎回走査せずに済ませているのはこの索引のおかげです。

索引を作り直すコマンドが mktexlsr で、TEXMFDBS に挙がったツリーすべての ls-R を再生成します。texhash は別のコマンドではありません ——この機械で確かめると、texhashmktexlsr へのシンボリックリンク、つまり同じプログラムです。どちらの名前で呼んでも構いません。システムのツリーを更新するので sudo が要ります。ちなみに tlmgrgetnonfreefonts は自分で必要な更新を済ませてくれるので、手で叩く場面は「自分でファイルをコピーしたとき」だけ だと考えてよいでしょう。

terminal
# The same file in the system tree DOES need the index rebuilt
LOCAL_TREE="$(kpsewhich -var-value=TEXMFLOCAL)"
sudo mkdir -p "$LOCAL_TREE/tex/latex/local"
sudo cp mythesis.cls "$LOCAL_TREE/tex/latex/local/"
sudo mktexlsr          # texhash is a symlink to this same program

kpsewhich mythesis.cls # now it resolves
kpsewhich -all mythesis.cls  # and shows every copy, if several collide

CTAN から手で入れる — .dtx と .ins

tlmgr に無いもの——投稿先が配る専用クラス、公開されたばかりのパッケージ、作者のサイトにしかない版——を入れるときだけ手作業になります。CTAN で配られるパッケージは .sty がそのまま置かれていることもありますが、多くは .dtx(ソースと文書が同居したファイル)と .ins(取り出し用の指示書) の対で配られています。この場合 tex foo.ins を走らせると .dtx から foo.sty が生成されるので、それを TEXMFHOME の適切な位置へ写します。.dtx は「プログラムと解説を一つのファイルに書く」という文芸的プログラミングの流儀そのもので、pdflatex foo.dtx を走らせればソース入りの解説書が PDF で出てきます。

terminal
# A package that ships as .dtx + .ins: extract, then place
tex foo.ins                     # writes foo.sty (and foo.cls, if any)
pdflatex foo.dtx                # optional: build the annotated manual

HOME_TREE="$(kpsewhich -var-value=TEXMFHOME)"
mkdir -p "$HOME_TREE/tex/latex/foo"
cp foo.sty "$HOME_TREE/tex/latex/foo/"
kpsewhich foo.sty

MiKTeX の場合 — mpm と自動インストール

MiKTeX には tlmgr がありません。コマンドラインは mpm(MiKTeX Package Manager)、GUI は MiKTeX Console が担当し、更新もパッケージ追加もそちらに寄せます。そして最大の違いが オンザフライ導入 で、文書が要求した未導入パッケージを組版の最中にダウンロードして続行します(Console の設定で「常に入れる/毎回確認する/入れない」を選べます)。ただしこの自動化には条件があり、全ユーザ共有でインストールした MiKTeX でも、その場で取得したパッケージは実行したユーザの AppData\Roaming 側へ落ちます。共有マシンでは、必要なパッケージを管理者モードで先に入れておくのが確実です。

フォントマップの管理 — updmap と getnonfreefonts

フォントマップ は「TeX がこの名前で呼ぶフォントは、実際にはどのファイルで、PDF にどう埋め込むか」を一行ずつ書いた対応表です。pdftexdvipdfmx が使う pdftex.mapdvips が使う psfonts.map、日本語用の kanjix.map などがあり、これらは手で書くものではなく updmap が生成 します。規模を実感するには行数を見るのが早く、この機械の pdftex.map45,443 行 あります。パッケージを入れて updmap が走ったあとにこの表が更新され、はじめてそのフォントが PDF に埋め込めるようになります。

updmap には updmap-sys(システム全体)updmap-user(自分だけ) の二つの顔があり、ここに TeX Live の設定まわりで最も刺さる罠が潜んでいます。updmap --help は自分でこう警告しています——updmap-user を一度でも実行すると、それ以降 updmap-sys を実行しても何の効果もなくなる」。個人用の設定ファイルが作られ、それがシステム側を覆い隠してしまうためです。updmap-sys は実行時にこの旨を警告しますが、原因を知らないと「管理者権限で実行したのにフォントが変わらない」と延々悩むことになります。基本は updmap-sys だけを使い、updmap-user には手を出さない のが安全です。

日本語・中国語・韓国語のフォント埋め込みには専用の入口があり、kanji-config-updmap-sys が担当します。裏で updmap を呼び、どの CJK フォント族を PDF に埋め込むかを切り替える道具です。status を渡せば現状を教えてくれます——この機械では現在の日本語ファミリが haranoaji、切り替え可能な候補が haranoajiipaipaex と出ます。つまり TeX Live に同梱される日本語フォントは原ノ味(Harano Aji)と IPA / IPAex であり、Noto CJK や源ノ角ゴシック(Source Han)は同梱されていません。それらを使いたい場合は OS 側のフォントを参照させるか、別途導入することになります。

terminal
# Ask, without changing anything: which CJK family is embedded?
kanji-config-updmap-sys status

# Switch the embedded Japanese family, machine-wide
sudo kanji-config-updmap-sys haranoaji

# Rebuild the map files after a manual font install
sudo updmap-sys        # never updmap-user: it permanently shadows updmap-sys

最後に、配布物に入れられないフォント の話をしておきます。「使うのは自由だが販売は不可」といったライセンスのフォントは、有償 DVD でも頒布される TeX Live に同梱できません。これを取ってくるのが TUG の getnonfreefonts スクリプトで、CTAN からフォント本体と TeX 用サポートファイルを取得し、TeX が見つけられる形まで設定してくれます。鍵は --userTEXMFHOME へ)と --sys(システムツリーへ)の使い分け。古い解説に出てくる getnonfreefonts-sys という別コマンドは現在ありません——全ユーザ向けなら getnonfreefonts --sys … を管理者権限で実行します。何が入れられるかは --lsfonts で一覧できます。

terminal
# See what is on offer, then install into your own tree
getnonfreefonts --user --lsfonts
getnonfreefonts --user luximono

# Or system-wide, for everyone on the machine
sudo getnonfreefonts --sys luximono
  • 汎用パッケージは tlmgr で入れる。 原稿フォルダに置いた古いコピーは、更新後も勝ち続けて原因不明の不具合になります。
  • 学会テンプレート専用のファイルは原稿リポジトリに置いてよい。 配布物ではなく、その投稿セットの一部だからです。
  • 共有マシン・CI では、TeX Live の年版・追加したパッケージ名・固定したリポジトリや Docker タグを README や .latexmkrc に残す。 「自分の端末で一度入れた」は再現性ではありません。
  • 提出直前に tlmgr update --self --all を走らせない。 昨日と違うパッケージで PDF を作ることになります。更新は別の日に試します。
  • updmap-user は使わない。 一度でも走らせると updmap-sys が効かなくなり、原因が非常に見つけにくくなります。