standalone

standalone は、図やTikZの絵をひとつだけ、中身の大きさに切り詰めた一枚の LaTeX 文書として組むためのクラスです。値打ちは切り詰めそのものより、同じファイルが二つの顔を持つ ことにあります。figure.tex は単体でコンパイルすれば図だけの PDF になり、論文から \input すれば一文字も変えずに本文へ流れ込みます。切り詰めの仕掛けにも由来があって、いま既定になっている crop が入る前、standalone が使っていたのは Emacs の AUCTeX から生まれた preview パッケージ——エディタ上に数式のプレビューを浮かべる、あの機能そのものでした。このページはクラスとパッケージの側、つまり border= の効き方、multisubpreambles、そして実際に出るエラーを扱います。書き出した図を PNG や SVG にする工程は別ページの担当です。

同じ図ファイルを、単体でも本文でも使う

大きな文書を書いていると、図を別ファイルに切り出したくなります。ところが、その図ファイルだけを試しにコンパイルしようとすると、\documentclass\begin{document} という枠を毎回書き足すことになり、しかも出力は本文用の大きな白いページの片隅に図が乗っただけのものになります。standalone クラスはその両方を一度に片づけます。図ファイルの先頭に \documentclass{standalone} と書いておけば、単体でコンパイルでき、出力は 中身の大きさに切り詰められた 一枚(PDF・DVI・PS)になり、ページ番号もヘッダもフッタも出ません。

latex
% figure.tex — a figure that is its own document
\documentclass[tikz,border=2pt]{standalone}
\begin{document}
\begin{tikzpicture}
  \draw[thick,->] (0,0) -- (3,0) node[right] {$x$};
  \draw[blue,thick] (0,0) .. controls (1,2) .. (3,1);
\end{tikzpicture}
\end{document}

standalone は二枚看板です。図ファイル側で使う クラス\documentclass{standalone})と、本体文書側で読み込む パッケージ\usepackage{standalone})。クラスが「一枚を単体で組む」役、パッケージが「その一枚を本文に取り込む」役を受け持ちます。作者は Martin Scharrer 氏で、TeX Live 2024 に入っているのは 2022 年 10 月版の v1.3b。依存関係はクラス側が xkeyval、パッケージ側はそれに加えて currfilegincltexfilemodadjustbox で、いずれも TeX Live と MiKTeX に最初から入っています。

crop と preview の違い、そして既定はどこで決まるか

既定は crop、余白は 0pt です。ただし、その既定はクラスファイルではなく 設定ファイル standalone.cfg に書かれています。standalone.cls 自身は preview と 0.50001bp を既定にしていて(これは v0.x の挙動です)、オプションの処理が始まる直前に standalone.cfg が読み込まれ、\standaloneconfig{crop}\standaloneconfig{border=0pt} で上書きするのです。この二段構えには使い道があります。自分用の standalone.cfg をプロジェクトのディレクトリか local な TEXMF ツリーに置けば、その環境のすべての standalone ファイルの既定を変えられます。配布物の cfg は更新のたびに上書きされるので、自分の設定は必ず別に置いてください。

croppreview は排他で、どちらも指定すると 後に書いたほうが勝ち、両方とも float=false を道連れにします。実際の違いは測ると出ます。2 cm × 1 cm の長方形だけの図を TeX Live 2024 で組むと、既定の crop では 57.09 × 28.75 bp。ここで \end{document} の前に空行を一つ入れると、crop では何も変わりませんが、preview を指定していると幅が 343.71 bp に跳ね上がります。空行が段落の切れ目とみなされ、中身が \linewidth いっぱいの段落になるからです。「図の右側に広い余白ができる」という定番の症状はこれで、crop が既定になったのはまさにこれを避けるためでした。それでも preview が残っているのは、XeLaTeX で TikZ のシェーディングがうまく出ないときの逃げ道が要るからです。

border= で余白を足す——値の読まれ方

いちばんよく使うオプションが border=(別名 margin=)です。値を一つ書けば四辺すべて、二つなら左右と上下、四つなら左・下・右・上の順で効きます。空白で区切った複数の値は、全体を波括弧で包んで border={10pt 5pt} のように書きます。単位を省いた裸の数値は bp(PostScript ポイント)として読まれます。先ほどの 57.09 × 28.75 bp の図で確かめると、border=5pt67.05 × 38.71 bp(各辺に 5pt = 約 4.98bp)、border={10pt 5pt}77.02 × 38.71 bp になります。bordervarwidth は文書全体に効く設定ではないので、プリアンブルでも、multi が有効なら本文の途中でも、\standaloneconfig{...} で後から変えられます。

オプション効果既定
crop中身を箱に収め、ページを中身+余白の大きさに切り詰めるtruestandalone.cfg が設定)
previewpreview パッケージ(active・tightpage 付き)で切り詰める旧方式。crop と排他off
border / margin切り詰めに足す余白。値 1 個=四辺、2 個=左右と上下、4 個=左・下・右・上0pt
varwidth中身を varwidth 環境で包み、段落が自然な幅を取れるようにする。varwidth=6cm で上限を与えるoff
tikz / pstricks絵のパッケージを読み、その環境を一枚ずつ切り出す(multi=tikzpicturevarwidth=false を設定)off
multi / ignorerest中身を複数ページに分け、各ページを個別に切り詰める。ignorerest は宣言した環境の外側を捨てるoff
class下層に読み込むクラスを選ぶ。class=jsarticle のように日本語クラスも指定できるarticle
beamer切り詰めをやめ、中身を空の beamer フレームに載せて組むoff

1 ファイルから複数の図を切り出す(multi)

既定では、document 環境の中身がまるごと一枚のページになります。multi を有効にすると、指定した環境が現れるたびに一枚ずつ切り出され、それぞれ独立に切り詰められます。\documentclass[tikz]{standalone} が便利なのはこのためで、tikz オプションは内部で multi=tikzpicturevarwidth=false を設定します。つまり tikzpicture を二つ並べて書けば、PDF は 2 ページになります(PSTricks には pstricks オプションが同じことをします)。任意の環境を対象にしたいときは \standaloneenv{myfig} を宣言し、環境の外に何も置かないようにします。どうしても外側に書きたいものがあるときだけ ignorerest を足してください。数式を一つずつ切り出す math オプションもあり、こちらは multiignoreempty に加えて余白 0.50001bp を自動で設定します。

standalone でよく出るエラーと症状

standalone のエラーはどれも原因がはっきりしていて、症状から一対一で戻れます。もっとも多いのが figure 環境を standalone ファイルの中に置いてしまう例で、croppreview が働いていると ! LaTeX Error: Not in outer par mode. や「Float(s) lost」が出ます。切り詰めは中身を箱に詰めることで実現されており、箱の中ではフロートが浮かべないからです。croppreview はどちらも自動で float=false を設定するので、このエラーが出るのは 後から手で float=true を書いた場合だけ です。フロートは本体文書に置き、standalone ファイルには絵そのものだけを入れてください。

  • 図の右に広い余白ができる。 中身が段落になっています。\end{document} の直前の空行や余計な \par を消すか、varwidth を付けるか、multi\standaloneenv で環境を宣言してください。
  • 右端が切れて中身が欠ける。 varwidth の上限(既定は \linewidth)が狭すぎます。varwidth=15cm のように広げるか、varwidth=false で切ってください。
  • オプションの値が通らない。 真偽値のキーに truefalse 以外を書くと ! Class standalone Error: Invalid value 'maybe' for boolean key 'crop'. のように止まります。
  • 複数ページに余計なページが混じる。 multi を使っていて、宣言した環境の外に組版される中身があります。それを消すか ignorerest を有効にしてください。
  • DVI 経由だと切り詰めがおかしい。 crop は DVI モードでは PostScript の命令を書き出す実装で、マニュアル自身が実験的だと断っています。latex 経由なら preview のほうが安定することがあります。

パッケージ側——本体から \input する

本体文書のプリアンブルの できるだけ早い段階\usepackage{standalone} を読み込むと、パッケージは \documentclass を再定義し、\input した図ファイルの \documentclass から \begin{document} までを 読み飛ばす ようにします。図ファイルの document 環境はただの TeX グループとして扱われ、\end{document} の後ろに書いてあるものも無視されます。つまり本体側からは、図ファイルの中身だけが流れ込みます。前提はひとつ、図ファイルが必要とするパッケージは本体側でも読み込んでおく こと。図ファイルのプリアンブルは飛ばされるので、tikz などは本体が読むしかありません。

latex
\documentclass{article}
% load the standalone package early
\usepackage{standalone}
% and everything the sub-files need
\usepackage{tikz}

\begin{document}
\begin{figure}
  \input{figure}%  the standalone file from above
  \caption{A sub-file}
\end{figure}
\end{document}

プリアンブルを手で写すのが面倒なら、\usepackage[subpreambles=true]{standalone} で自動的に集められます。各図ファイルのプリアンブルが補助ファイルにまとめられ、次の処理で本体に取り込まれます。sort を加えると、図が読み込むパッケージとそのオプションが重複なく整理され、\PassOptionsToPackage 経由で読み込まれるのでオプション衝突を避けられます。自分で本体プリアンブルに書き写したいときは print を使いますが、これは収集専用のモードで、Package standalone Warning: Running 'standalone' package in sub-preamble print mode. All body content of file 'figure.tex' is ignored! と警告が出るとおり、本文は組まれません

\includestandalone と mode= — ソースか、画像か

\input の代わりに \includestandalone{figure} と書くと、取り込み方をパッケージオプション mode= で切り替えられます。値は tex(ソースを取り込む。既定)、image(すでにある PDF・EPS を \includegraphics で取り込む)、image|tex(画像があれば画像、なければソース)、build(毎回ビルドしてから使う)、buildmissing(画像が無いときだけビルド)、buildnew(ソースのほうが新しいときだけビルド。XeLaTeX では動きません)。複雑な図を毎回組み直さずに済むので本体のビルドが速くなる、というのがこの機能の狙いです。外部コマンドを呼ぶのは build 系の三つだけ で、そのときは -shell-escape が要ります。ビルドに失敗した場合は警告を出してソースの取り込みに戻る、と公式マニュアルに明記されています。

ここから先——切り詰めた PDF を PNG や SVG に書き出す工程、pdfcrop で既存の PDF から余白を落とす方法、dvisvgm の使い方、convert= に渡す設定——は「画像として書き出す」のページが受け持ちます。standalone のクラス側で覚えておくべきなのは、余白を作らないほうが、あとから切り落とすより速くて正確 だということだけです。

プロジェクトに組み込む形

実際の論文では、standalone ファイルを「図のソース」として扱い、本文とは別に点検できる形にしておくと強くなります。本文を paper.tex、図を figures/ に置き、本文では \input{figures/energy-flow} とだけ書く。こうしておけば、図を直す人は figures/energy-flow.tex だけを単体でコンパイルして確認でき、本文側はキャプション・番号・参照だけを管理します。レビューでは単体 PDF を添えて「図だけを見る」回を作れば、本文全体の再ビルドを待たずに図の質を上げられます。

terminal
paper.tex
standalone.cfg          # optional: your own defaults for every figure
figures/
  energy-flow.tex
  apparatus-layout.tex
  timing-diagram.tex

図の中身が本文と同じ組版規則に従うべきときは、class= で下層のクラスを合わせます。日本語のラベルを持つ図なら \documentclass[class=jsarticle,border=5pt]{standalone} を upLaTeX で、LuaLaTeX なら class=ltjsarticle を使えば、和文の字間や書体が本文とそろいます。クラスとパッケージが共通で提供する \ifstandalone\IfStandalone{単体のとき}{本体のとき}\onlyifstandalone{...} も便利です。図ファイルだけに縮尺やデバッグ用の枠を出す、といった書き分けが一行でできます。

subfiles・TikZ external との違い

目的の似た仕組みが二つあり、どちらも 向きが逆 です。subfiles では子ファイルが本体のプリアンブルを取り込みます。standalone は逆に、子ファイルのプリアンブルを本体へ集められます。だから、一枚の図を論文・スライド・学位論文と 複数の文書で使い回す なら standalone、本体と子が一対一で対応する章立ての分割なら subfiles が向いています。TikZ の external ライブラリ は本体から一時画像を書き出す仕組みで、これも standalone とは反対向きです。もっとも、standalone ファイルを \includestandalone[mode=buildnew] で使えば、実質同じ「重い絵をキャッシュする」効果が、図をひとつの独立したファイルに保ったまま得られます。