llmkの基本

2020-12-20 (updated: 2025-12-08) #LaTeX #llmk

本稿はTeX & LaTeX Advent Calendar 2020の20日目の記事です。19日目はhid_alma1026さんでした。21日目はmattskalaさんです。

llmk(Light LaTeX Make)⁠「軽量、シンプルであること」⁠を目指したLaTeX専用ビルドツールです。LaTeX文書ソースのマジックコメント(または専用の設定ファイルllmk.toml)に文書の処理方法を記述することで、LaTeXソースのビルド — 現代では「PDF化」とほぼ同義 — を簡略できます。TeX Live/MiKTeXに含まれており、追加のインストールをすることなく、どんな環境でも使用することができます。

本稿では、llmkの基本的な使い方を解説します1

Warning

本稿は2025年11月の改訂時点の最新版v1.2.1に基づく解説です。その後のバージョンアップにより仕様が変更になっている可能性があります。必要に応じて最新のREADME公式リファレンスも確認してください。

llmkのロゴ

イントロダクション

llmkはLaTeX文書に特化したビルドツールです。昨今では、LaTeX文書を処理する方法は多様です。しかし「どれか1つのツールが究極の正解で、ほかを選ぶ余地がない」という状況ではなく、それぞれにメリットとデメリットがあるため、どれを採用するかは文書の性質に応じて決める必要があります。具体的には、次のような選択肢がよく知られています。

  • LaTeXエンジン:pdfLaTeX, XeLaTeX, LuaLaTeX, (u)pLaTeX, etc.
  • DVIウェア:dvipdfmx, dvips, etc.
  • 参考文献処理システム:BibTeX, (u)pBibTeX, etc.
  • 索引処理システム:makeindex, xcindy, (up)mendex

LaTeX文書の作成者は、こうした選択肢の中からある文書を処理する「正しい方法」を1つ選ぶことになります。例えば、典型的なpLaTeX文書であればplatexpbibtexplatexplatexdvipdfmxと順に利用して、LaTeXソースを最終的なPDFに変換する手順がよく用いられるはずです。こうした一連の流れを⁠「ワークフロー」⁠と呼ぶことにします。

llmkの目的は、こうしたワークフローを簡単に記述し、環境をまたいで共有できるようにすることです。LaTeX文書にllmkの設定さえ書いておけば、OSを問わず、さらにはOverleaf、Cloud LaTeX、arXivなどのオンライン環境であっても、まったく同じようにワークフローの解釈・実行ができるようにすることを目指しています(現時点ではまだ道半ばです)。

llmkの機能は、このようなワークフローの簡単な記述およびその共有を第一に考えて設計されています。

  • シンプルで簡単な設定記述言語(TOML)でワークフローを記述できることができる
  • ワークフローはLaTeXソースに直接書くことも、別の専用ファイルllmk.tomlに書くこともできる
  • TeX LiveさえあればOSを問わず動作する(クロスプラットフォーム)
  • どのような環境でも、ワークフロー記述はまったく同じように解釈・処理される

LaTeX専用のビルドツールはlatexmkやararaなど、いくつもの選択肢が存在しますが、llmkと同じ目的を持ち、上記の性質をすべて同時に満たすツールは他にないはずです。

Important — llmkの設計思想と限界

llmkは⁠「軽量、シンプルであること」⁠を目指したLaTeX専用ビルドツールです。複雑だったり、標準的な処理手順から大きく逸脱したLaTeX文書のワークフロー記述には必ずしも適さないかもしれません。そのような場合は、Make等の汎用ビルドツールや、ほかの高機能志向のLaTeX専用ビルドツールを利用するといいでしょう。llmkを用いて別のビルドツール/スクリプトを呼び出すような使い方が便利なこともあるかもあるかもしれません。

インストール

llmkは最新のTeX LiveとMiKTeXにlight-latex-makeという名で収録されています。これらのディストリビューションを使用している場合には、原則として特別なことをせずとも最初からインストールされています2

お使いのTeXシステムにllmkが含まれていない場合や開発版の最新バージョンを利用したいという場合は、手動でインストールしてください。llmkのソースコードその他すべての関連成果物はGitHubリポジトリから入手可能です。llmkの実装は単一のスクリプトファイル(llmk.lua)であり、インストール手順は非常に単純です。同ファイルをダウンロードしてtexlua $LLMK_PATH/llmk.lua(ここでは$LLMK_PATHはダウンロードしたllmk.luaの位置を表すことにします)を実行すれば動作します。

基本の使い方

llmkの最も簡単な使い方は、LaTeX文書のワークフローをLaTeXの文書ソース(ナンチャラ.texファイル)内で直接指定することです。

まずは用意した文書ソースのなるべく先頭に近い位置に、llmk用の設定を記述します。ワークフロー設定は3つ以上の連続する+マークのみ3を含む行で挟むように、TOML形式で記述することができます。このように+++を含む行で区切られたTOMLによるワークフロー指定を記述できる領域を⁠「TOMLフィールド」⁠と呼びます。

% +++
% latex = "xelatex"
% +++

\documentclass{article}
\begin{document}

Hello \textsf{llmk}!

\end{document}

latex = "xelatex"の部分がllmkに解釈させるためのワークフロー設定です。意味としては — 自明と思われますが — LaTeXコマンドとしてxelatexを使用するように指示しています。

上のコードをhello.texという名前で保存します。このファイルをllmkで処理するためには、ファイルと同じディレクトリで次のコマンドを実行します。

$ llmk hello.tex

これでllmkはhello.texのTOMLフィールドを読み取り、そのワークフロー設定に従って組版処理を実行します。すなわち、この例ではXeLaTeXを使用してhello.pdfが作成されます。

llmkのリポジトリにあるexamplesディレクトリには、いくつかllmk用の設定が記述されたLaTeX文書の例が置かれているので、参考にしてください。

専用設定ファイルの使用

文書ソースにコメントの形で直接ワークフローを指定する代わりに、llmk.tomlという名前の特別な外部ファイルにワークフローを設定することもできます。そもそもどのファイルが文書ソースなのかをシステムや共著者が知り得ないような場合(*.texファイルが複数あるなど)には、こちらの方法を用いる方が適しているかもしれません。

llmk.tomlの記述方法はTOMLフィールドの記述方法とほぼ同一ですが、必ずsourceキーを用いてどのファイルが文書ソースなのかを明示しなければいけません。例えば、次のような具合です。

# llmk.toml
latex = "platex"
source = "hello-ja.tex"

この内容をllmk.tomlというファイル名で保存します。llmkコマンド実行時に、何の引数も与えない場合は自動的にカレントディレクトリのllmk.tomlが読み込まれ、その設定にしたがって処理が行われます。

$ llmk

すなわち、いま考えている例では、platexを用いてhello-ja.texの処理が実行されます。

ちなみにpLaTeXは直接PDFを生成するのではなくDVIの出力を行います。DVIファイルが生成された場合、llmkはデフォルトでdvipdfmxを使用してDVI → PDFの変換を行います。つまり、上記のシンプルな設定だけで日本語文書のPDF生成まで一通りの処理が自動で行われます。

他のマジックコメント形式の使用

再び文書ソースに直接ワークフローを指定する話に戻ります。TOMLフィールドはllmk独自の形式ですが、既存ツールの中に、別形式のワークフロー指定をサポートするものがあります。llmkはこうした形式のいくつかをサポートしています。

Note

llmkの機能をフルに活用するにはTOMLフィールドを利用する以外の方法はありません。最初からllmkでの処理を前提に文書を作成する場合はTOMLフィールドまたはllmk.tomlの利用がおすすめです。

例えばTeXShopやその派生プロジェクトは% !TeXという形で始まるマジックコメントでLaTeXやBibTeXの種類を指定することができます。

%! TEX TS-program = xelatex
%! BIB TS-program = biber
\documentclass{article}

この形式はllmkでもサポートしており、TOMLフィールドで次のように指定したのと同じように扱われます。

% +++
% latex = "xelatex"
% bibtex = "biber"
% +++
\documentclass{article}

またEmacsのLaTeX向け拡張機能YaTeXではシェバン風のよりシンプルな記法でLaTeXエンジンを指定することができます。

%#!pdflatex
\documentclass{article}

llmkはこの指定を次と等価なものとして扱います。

% +++
% latex = "pdflatex"
% +++
\documentclass{article}

なおこのシェバン風の記法はファイルの先頭行でないと認識されないので注意してください(オリジナルの仕様と同じです)。またファイル内にTOMLフィールドが存在する場合は、TOMLフィールドが最優先され、ほかのすべての形式のマジックコメントは無視されます4

生成ファイルの削除

LaTeXによる処理を行うと、中間生成ファイル等がたくさん作られるので、これをまとめて削除したいということがよくあります。llmkのコマンドラインオプション--clean-c)や--clobber-C)を使用すると、ワークフロー実行によって生成されたファイルを一括で削除することができます。

  • --clean (-c): auxやlog等の中間生成ファイルを削除
  • --clobber (-C): 中間生成ファイルに加え、PDFを含むすべての生成ファイルを削除

引数の与え方は基本的にワークフロー実行をしたい場合と同様です。つまり

$ llmk --clean <file>

を実行すると<file>の処理によって生成されたファイルが削除されます(<file>は一度に複数指定することもできます)。また引数<file>を指定しなかった場合はllmk.tomlが読み込まれ、その中でsourceに指定されているファイルの処理で生成されたファイルが削除されます。なお--clean, --clobberそれぞれで削除するファイルはTOMLフィールド等でカスタマイズすることも可能です。

ちょっと発展的な使い方

そもそも本稿はllmkの基本についての記事なので、ここでは「発展編の入門」程度の範囲を簡単に述べるに留めます。

ここまでで紹介した単純なケースでは、TOMLによるllmkへのワークフロー指定のトップレベルでlatexbibtexキーを用いて使用したいコマンド名を与えるだけでしたが、これではより複雑な設定(例えば各コマンドに与える具体的な引数の指定)を行うことはできません。そうした細かな制御を行いたい場合には、llmkのワークフロー制御に関する知識が必要になります。

ワークフローの柔軟な制御

llmkのワークフロー制御の仕組みもそれほど複雑ではありません。鍵となるのはsequence配列とprogramsテーブルという2つのデータ構造です。

このうちsequence配列はワークフローで実行したいプログラムの名前を、実行する順番で格納するためのものです。もう1つのprogramsテーブルには各プログラムの実行方法に関して詳細な情報を持たせます。つまり実際のワークフロー処理にあたっては、llmkは「sequenceに指定されているプログラムを、逐次programsテーブルの持つ詳細な設定を参照しながら実行していく」ことになります。

まずは比較的シンプルな例として、普通のupLaTeX文書の処理をすべてptex2pdfに丸投げする例を考えてみます。

# 文書ソースはhoge.tex
source = "hoge.tex"

# カスタムsequence
sequence = ["ptex2pdf"]

# ptex2pdfに関する詳細設定
[programs.ptex2pdf]
command = "ptex2pdf"
opts = ["-u", "-l"]
args = ["%T"]

上記をllmk.tomlに保存して

$ llmk

を実行するとptex2pdf -u -l "hoge.tex"1回実行されて(hoge.texが正当なupLaTeX文書ならば)hoge.pdfが生成されます。

このワークフロー指定を詳しく見ていきます。まずsequenceに単一のプログラム名ptex2pdfが指定されているので、llmkはワークフロー処理時にこのプログラムを実行します。その際に必要な詳細な設定は[programs.ptex2pdf]テーブルに記述されています。コマンド名(command)がptex2pdfで、与えたいコマンドラインオプション(opts)が-u-lだと指定されていることはすぐにわかるでしょう。

問題はコマンドライン引数(args)の指定["%S"]です5。各プログラムに対する指定の中でargsキーに対しては%Sなどの特別な指定子を使用することができます。llmkで利用できる指定子の例を挙げると:

  • %S: 文書ソースのファイル名
  • %B: %Sのベース名(ファイル名から拡張子を除いたもの)

ということで、先の例では%Sの部分が文書ソース(hoge.tex)に置換されて最終的にptex2pdf -u -l "hoge.tex"が実行されることになります。

細かい点はさておき、ここではワークフローで実行したいプログラム名をsequence配列に実行順に指定して、それぞれのプログラムに関する詳細な設定を[programs.<プログラム名>]以下に記述するということがわかってもらえれば大丈夫です。

programsテーブルでは、それなりに色々な設定を行うことができますが、本稿ではその1つ1つを網羅的に解説することはしません。そうした詳細はリファレンスマニュアルに記載しているので、必要に応じて参照してください。

デフォルト設定

llmkは、ユーザーがsequenceprogramsの内容を毎回ゼロから書かずとも済むように、典型的なLaTeX文書の処理を行う際に都合がいいようなデフォルト設定を持っています。デフォルトのsequenceの設定では、(u)pLaTeXなどDVIファイルを生成するようなLaTeXエンジンが用いられた場合は自動でdvipdfmxを利用してPDF化を行います。これは、llmkのデフォルトのsequenceが本質的には次のようになっているからです6

# デフォルトsequence(抜粋)
sequence = ["latex", "dvipdf"]

現在の日本語TeXでは主流な方法ではありませんが、dvipdfmxの代わりにdvips + ps2pdfを用いてPDF化を行いたい場合は、sequenceを次のように指定します。

# カスタムsequence
sequence = ["latex", "dvips", "ps2pdf"]

llmkのデフォルトのsequence設定ではdvipsps2pdfプログラムが呼び出されることはありませんが、programsテーブルには、最初からこれらのプログラムについてのよくある設定が収録されています。そのため、単純にdvips + ps2pdfの経路を使いたいということだけであればprogramsテーブルについては一切いじる必要がありません。もちろん、これらのプログラムに何らかの特別なコマンドラインオプションを与えたいという場合にはprogramsテーブルの指定も併せて行う必要があります。

本稿では、便宜的に簡略したデフォルトsequenceを簡単に紹介しましたが、実際のsequenceprogramsテーブルの完全なデフォルト設定はもう少し複雑です。例えば、デフォルトのlatexプログラムはauxファイルを監視して相互参照が解決されるまでコマンド実行を繰り返す(ただし上限も設定されている)ようになっていたり、bibファイルやidxファイルがある場合には自動的にbibtexmakeindexコマンドが実行され、さらにこれらの実行後には再びlatexプログラムによる処理が十分回数実行されるようになっていたりします。

こうしたデフォルト設定の詳細についても、やはりリファレンスマニュアルを参照してください。

ちょっと注意

上記の解説で察せられたかもしれませんが、llmkの根幹にある制御機構はとても単純で、ワークフロー指定や、ある指定の下での振る舞いを把握することはそこまで難しいことではありません。それは利点とも言えますが、単純すぎるがゆえにソースファイル間の依存関係が複雑な場合や、処理途中の状況に応じて処理を切り替えるようなことをする場合には、設定記述が複雑になり過ぎてしまったり、そもそも機能が足りなかったりということがあり得ます。

また、単一ソースから複数形式での出力したい(複数のタスクを定義したい)というようなニーズもサポートしていません。llmkは「典型ケースでシンプルにワークフローを指定できるようにすること」を目指しているため、複雑な処理が必要な非典型ケースでは必ずしも有効でありません。

llmkは何百ページもある書籍などの作成で複雑なことをしたいLaTeXのパワーユーザー向けというよりも、せいぜい数十ページの論文やレポート作成をしたいライトユーザー向けということを意識して設計されています。複雑なワークフロー制御をガシガシやっていくのが中心的な使い方ではなく、トップレベルのlatexbibtexキーを使用して、利用したいLaTeXエンジンを簡単に指定するだけでPDFにするところまでを“それっぽく”よしなに処理しておいて欲しいという方には向いていると思います。

要するに、ユースケースに応じて適切なツールを選ぶとよいでしょう。

さらなる情報

本稿では llmk の「基本」を解説しました。さらに多くの情報が必要という方のために、これまでに私が作成してきた llmk に関するほかの文献もご紹介しておきます。これらはすべて英語ですが、本稿で解説した基本的なことを押さえた上であれば、細かな仕様などについての解説は英語であったとしてもそこまで読むのは大変ではないと思われます。

  • リファレンスマニュアル:llmkの仕様を細部まで詳細に記述しています。原則としてあらゆる仕様を完全に網羅することを意図して書いており、実際その目的をほぼ達成していると思いますが、一方でllmkのことを何も知らない人が頭から読むのには適さない可能性が高いです。本稿を一通り読まれた方であれば、頭から読んだり、あるいは必要に応じて辞書的に読んだりしても十分活用できるはずです。
  • TUG 2020での講演ビデオ(YouTube):オンライン開催されたTeXの国際会議TUG 2020での講演ビデオです。このトークも英語です。冒頭でデモンストレーションをしています。
  • TUGboat 記事:上記講演に対応するTUGboat記事です。llmkの仕様を詳細に述べるのではなく、その設計思想を中心に解説しました。またlatexmkやararaなどの既存ツールとの比較についても議論しています。

おわりに

本稿の解説を読んで、もし「llmkってやつは使えそうだな」と思っていただけた方は、ぜひ実際に試してもらえると嬉しいです。


主な更新履歴

  • 2025-11-26: llmk v1.2.1に合わせた内容に更新。全体的なスタイルの調整

  1. 概ねllmk付属ドキュメントのREADMEの内容+αに相当します。 ↩︎

  2. TeX Liveをフルスキーム以外でインストールしていてllmkが含まれていないという場合はtlmgr install light-latex-makeでインストールしてください。 ↩︎

  3. ただしコメント文字の % と最初の + の間にはスペースを入れることができます。 ↩︎

  4. この仕様は「llmkのワークフロー指定にはTOMLフィールドを優先的に使って欲しいから」というのもありますが、それ以上に他ツール向けにマジックコメントでllmkの利用を指定して、実際の処理をllmkに丸投げする、ということを行った際に、llmkがまたllmk自身を指定するマジックコメントを解釈して無限再帰してしまうのを防ぐ意図もあります。 ↩︎

  5. 解説がややこしくなるのでargs["%S"]を指定しましたが、本当は["%T"]と指定する方が望ましいです。 ↩︎

  6. これは厳密なllmkのデフォルトのsequence設定ではありません。本稿の解説に関係のあるところだけを抜粋した形です。 ↩︎