如果想把程序源代码排得漂亮,并带有行号和语法高亮(关键字、注释、字符串用不同颜色区分),常用的两个包是 listings 和 minted。前者不需要外部工具,几乎哪里都能运行;后者调用外部的 Pygments 引擎,能提供准确得多的高亮。如果只是要按原样输出输入的内容,更朴素的 verbatim 系列就够了。
两种做法
排版源代码有两条思路不同的路线。listings 完全由 LaTeX 宏实现,不需要任何额外软件;无论在 Overleaf,还是在无法自行配置的机房环境中,只要写 \usepackage{listings} 就能工作。相比之下,minted 把工作交给 Python 编写的正式词法分析器 Pygments,再把结果带回 LaTeX。Pygments 能真正解析数百种语言,因此高亮准确度远高于 listings。
这个差异正好就是选择标准:想要简单和可移植性就选 listings,想要高质量高亮就选 minted。minted 会启动外部程序,因此需要后面说明的 shell escape 特殊许可,在受限环境中可能无法运行。如果只是想把代码 逐字原样 输出,不需要颜色和行号,那么 verbatim 或 fancyvrb 更轻量;参见“Verbatim”页面。
| listings | minted | |
|---|---|---|
ハイライト方式 / Highlighting | 基于关键字列表(简单) | Pygments 词法分析器(高精度) |
外部依存 / Dependencies | 无(纯 LaTeX) | 需要 Python + Pygments |
シェルエスケープ / Shell escape | 不需要 | 通常需要(新 TeX Live 有例外) |
対応言語 / Languages | 内置主要语言 | Pygments 覆盖 500 多种 |
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= 后,代码块会像图表一样成为带编号的“listing”,可用 \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 为前提,因此代码中的日文注释等可能出现乱码或列位置错乱。有两种补救办法。若代码片段直接写在正文中,可以用 literate= 逐个教它字符,例如 \lstset{... literate={あ}{{あ}}1 ...},但字符一多就不现实。若是导入外部文件,简单做法是用 listingsutf8 包代替 listings(只对 \lstinputlisting 有效)。
minted 基础(Pygments)
加载 \usepackage{minted} 后,代码块写在 minted 环境中。它与 listings 的大区别是 第一个参数就是语言名,例如 \begin{minted}{python}。此外还有单行快捷命令 \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。
Shell escape(minted 的关键条件)
因为 minted 会启动外部 Python 程序,所以编译时必须启用 shell escape,也就是允许 LaTeX 执行外部命令的权限。使用 pdfLaTeX 时,传入 -shell-escape 选项。
pdflatex -shell-escape document.tex它还需要底层有 Python 3.8 以上和 Pygments。不过 minted 版本 3(2025 年以后发布的完全重写版)改善了这一点。通过 TeX 包管理器安装时(如 tlmgr install minted),包含 Pygments 的整套 Python 侧程序会作为专用可执行文件 latexminted 随 TeX 树一起提供,因此不必另装 Pygments。而且 latexminted 设计为支持受限 shell escape:在 TeX Live 2024 及以后版本中,它已登记为可信可执行文件,因此可以完全不加 -shell-escape 直接编译。
即便如此,在 TeX Live 2024 以前的版本以及 MiKTeX 上,仍然需要像过去一样使用 -shell-escape(MiKTeX 中是 -enable-write18)。由于 shell escape 可能执行任意外部命令,不要在不可信来源的文档上使用它。反过来说,在 Overleaf 这样已配置好的环境中,或在本地处理自己的代码时通常没有问题(Overleaf 默认支持 minted)。这种“外部依赖 + shell escape”就是它相对于更可移植的 listings 的主要取舍。
如何选择
- 想要零配置,并确信哪里都能跑 → listings。在 Overleaf 或受限机器上,
\usepackage就够了。 - 最看重高亮准确度和语言覆盖范围 → minted。Pygments 的着色是另一个层级。
- 不能安装外部工具 / 不能使用 shell escape → listings,没有悬念。
- 只需要原样输出代码,不要着色 →
verbatim或fancyvrb就够了(见“Verbatim”)。 - 想把算法写成伪代码 → 专用的
algorithm2e/algpseudocode(见“Algorithms”)。