プログラムのソースコードを、行番号やシンタックスハイライト(予約語・コメント・文字列の色分け)付きで美しく載せたい——そのための定番が listings と minted の二つのパッケージです。前者は外部ツール不要でどこでも動き、後者は外部の Pygments を呼んで圧倒的に正確なハイライトを行います。打ち込んだ通りに出すだけでよいなら、より素朴な verbatim 系で足ります。
二つのアプローチ
ソースコードの掲載には、考え方の異なる二つの道があります。listings は純粋な LaTeX マクロだけで実装されており、追加のソフトウェアを一切必要としません。Overleaf でも、設定をいじれない計算機室の環境でも、\usepackage{listings} と書けばそのまま動きます。一方の minted は、Python 製の本格的な字句解析器 Pygments に処理を委ね、その結果を LaTeX に取り込みます。Pygments は何百もの言語を正しく解釈できるため、ハイライトの精度は listings を大きく上回ります。
この違いがそのまま使い分けの基準になります。手軽さと可搬性を取るなら listings、ハイライトの品質を取るなら minted です。minted は外部プログラムを起動するため、後述の シェルエスケープ という特別な許可が要り、制限された環境では動かないことがあります。なお、コードを 加工せずそのまま 出したいだけ(色分けも行番号も不要)なら、verbatim や fancyvrb の方が軽量です。詳しくは「そのまま出力(verbatim 系)」を参照してください。
| listings | minted | |
|---|---|---|
ハイライト方式 / Highlighting | キーワード表ベース(簡易) | Pygments 字句解析器(高精度) |
外部依存 / Dependencies | なし(純 LaTeX) | Python + Pygments が必要 |
シェルエスケープ / Shell escape | 不要 | 原則必要(新しい TeX Live では例外あり) |
対応言語 / Languages | 主要言語を内蔵 | 500 以上を Pygments が網羅 |
listings の基本
まず \usepackage{listings} を読み込みます。コードのブロックは **lstlisting 環境で囲み、外部ファイルを丸ごと取り込むなら \lstinputlisting、本文中に短い断片を埋め込むなら \lstinline を使います。言語や見た目は、各所に毎回オプションを書くよりも、プリアンブルで \lstset{...}** にまとめて指定しておくのが定石です。
\usepackage{listings}
\usepackage{xcolor}
\lstset{
language=Python, % 言語 / language
basicstyle=\ttfamily\small, % 本文の書体 / base font
keywordstyle=\color{blue}\bfseries,
commentstyle=\color{teal}\itshape,
stringstyle=\color{red!60!black},
numbers=left, % 行番号を左に / line numbers on the left
numberstyle=\tiny\color{gray},
frame=single, % 枠線 / a single-line frame
breaklines=true, % 長い行を折り返す / wrap long lines
showstringspaces=false, % 文字列中の空白を記号化しない
tabsize=2,
}
\begin{lstlisting}[caption={階乗を計算する}, label=lst:fact]
def factorial(n):
# 再帰で階乗を求める
if n <= 1:
return 1
return n * factorial(n - 1)
\end{lstlisting}\lstset の主なキーは次の通りです。basicstyle で全体の書体(\ttfamily\small が定番)を、keywordstyle・commentstyle・stringstyle で予約語・コメント・文字列の見た目を指定します。numbers=left で左に行番号が付き、numberstyle でその書体を整えます。frame=single は枠線、breaklines=true は長い行の自動折り返し、caption= と label= を与えると図表のように番号付きの「リスト」になり \ref で参照できます。
個別のブロックには \begin{lstlisting}[language=C, numbers=none] のように [ ] 内でオプションを上書きできます。外部ファイルなら \lstinputlisting[language=Python, firstline=37, lastline=45]{sample.py} のように行範囲も切り出せます。本文への埋め込みは、\verb と同じ流儀で区切り文字を選び、\lstinline|while (i < n)| のように書きます。
listings の限界(UTF-8 と日本語)
listings のハイライトは、言語ごとに登録された キーワードの一覧 と単純な規則による近似で、本物の字句解析器ほど賢くはありません。文脈依存の色分け(たとえば同じ語が文脈によって型名にも変数名にもなる場合)は苦手で、複雑な言語ほどぎこちなさが出ます。これは仕組み上の限界です。
もう一つの実務的な落とし穴が マルチバイト文字 です。listings は本来 UTF-8 を前提にしておらず、コード中に日本語コメントなどがあると文字化けや桁ずれを起こすことがあります。対策は二つ。コード片を本文に直書きするなら \lstset{... literate={あ}{{あ}}1 ...} のように **literate=** で文字を一つずつ教えますが、文字数が多いと現実的ではありません。外部ファイルを取り込む場合に限り、listings の代わりに **listingsutf8** パッケージを読み込むのが簡単です(\lstinputlisting でのみ有効)。
minted の基本(Pygments)
\usepackage{minted} を読み込むと、コードブロックは **minted** 環境で書けます。\begin{minted}{python} のように 第一引数に言語名 を与えるのが listings との大きな違いです。単一行のショートカット **\mint、本文への埋め込み用 \mintinline、外部ファイル取り込みの \inputminted** も用意されています。
\usepackage{minted}
% ドキュメント全体の配色テーマ / a color theme for the whole document
\usemintedstyle{monokai}
\begin{minted}[linenos, bgcolor=black!90, fontsize=\small]{python}
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
\end{minted}
% 単一行 / a single line
\mint{python}|print("Hello!")|
% 本文中に埋め込む / inline in running text
\mintinline{python}{print("Hello!")}
% 外部ファイルを取り込む / include an external file
\inputminted[linenos]{python}{sample.py}オプションは環境名の直後に [ ] で **key=value 形式で渡します。よく使うのは、行番号を付ける linenos、Pygments のカラーテーマを選ぶ style=**(monokai など。テーマ一覧は pygments.org/styles)、背景色 **bgcolor=、文字サイズ fontsize=** など。文書全体に同じテーマを適用するなら \usemintedstyle{monokai}、より細かく既定値をまとめるなら \setminted{style=monokai, linenos} を使います。Pygments が未対応の言語や、あえてハイライトを切りたいときは言語名に text を指定します。
\mint と \mintinline のコードは、\verb と同様に 対になる区切り文字(|...| など任意の記号)か、波括弧 {...} で囲みます。ただし \mint は インライン用ではなく、コードが一行だけのときに環境を書く手間を省くためのものです。本文に溶け込ませたいときは必ず \mintinline を使ってください。
シェルエスケープ(minted の前提)
minted は外部の Python プログラムを起動するため、LaTeX に外部コマンドの実行を許す シェルエスケープ を有効にしてコンパイルする必要があります。pdfLaTeX なら -shell-escape オプションを付けて実行します。
pdflatex -shell-escape document.tex前提として Python 3.8 以上と Pygments が必要です。ただし minted バージョン 3(2025 年以降の完全な書き直し)からは事情が改善しました。TeX のパッケージ管理(tlmgr install minted など)で導入すると、Pygments を含む Python 一式が TeX 環境内に **latexminted** という専用実行ファイルとして同梱され、別途 Pygments を入れる手間がなくなりました。さらにこの latexminted は制限付きシェルエスケープに対応する設計で、**TeX Live 2024 以降では信頼済み実行ファイルとして登録されているため、-shell-escape を付けずにそのままコンパイルできます**。
それでも TeX Live 2024 より前のバージョンや MiKTeX では従来どおり -shell-escape(MiKTeX では -enable-write18)が要ります。シェルエスケープは任意の外部コマンドを実行させ得るため、信頼できないソースの文書には使わないでください。逆に言えば、Overleaf のように設定済みの環境や、ローカルで自分のコードを扱う分には問題ありません(Overleaf は minted を標準でサポートしています)。この「外部依存とシェルエスケープ」が、可搬性で勝る listings との最大のトレードオフです。
どちらを選ぶか
- 設定不要・どこでも動く安心感が欲しい → listings。Overleaf でも制限環境でも
\usepackageだけで完結します。 - ハイライトの正確さ・対応言語の広さを最優先 → minted。Pygments による色分けは別格です。
- 外部ツールを入れられない/シェルエスケープが使えない → listings 一択。
- コードを色分けせずそのまま出すだけ →
verbatimやfancyvrbで十分(「そのまま出力」を参照)。 - アルゴリズムを疑似コードで書きたい → 専用の
algorithm2e/algpseudocode(「アルゴリズム」を参照)。