代码列表和高亮显示的包

有许多包提供代码列表和高亮显示,以下是最受欢迎的几个:

  • listings:它功能强大且非常有用。你可以直接插入代码,或者提供包含代码的文件名。(它不应与算法和伪代码混淆。)

  • minted:它使用外部的 Python 库 Pygments 进行代码高亮,截至 2021 年 2 月,Pygments 支持超过 537 种语言和文本格式。由于该包依赖于外部 Python 代码,因此设置起来比通常的 LaTeX 包多一些步骤,建议查看其 GitHub 仓库和手册。

listings

listings 包的主要用途是在文档中以良好的格式插入任何编程语言的源代码。该包支持所有常见编程语言的高亮显示,并且高度可定制。如果你只想在文档中写代码,包提供了 lstlisting 环境:

要使用该包,你需要在 LaTeX 文档的导言部分包含 \usepackage{listings} 并定义 (\usepackage{listings})。一个完整的示例如下:

% 在导言部分
\usepackage{listings}

% 在正文中
\begin{document}
\begin{lstlisting}
Put your code here.
\end{lstlisting}
\end{document}

有三种方法可以在 .tex 文件中包含源代码。

  1. 在文中直接插入源代码 \lstinline{<code here>}

  2. lstlisting 环境中编写编程语言代码,如上所示。

  3. 使用以下命令从文件本身直接输入源代码:\lstinputlisting{source_filename.py}。如果你创建了一个包含多个文件的程序,并且仍在编辑它,这个方法非常有用。通过这种方式,如果你修改了源代码,只需要重新编译 LaTeX 代码,你的文档就会被更新。

为了清晰起见,我们将上述三种示例合并为单个代码:

\lstset{language=C}     % 默认语言设置
\begin{document}
% 使用方式 1
代码可以内联插入,例如强调关键字 \lstinline{while, for}。

% 使用方式 2
\begin{lstlisting}
这段代码放在 listing 环境中。
\end{lstlisting}

% 使用方式 3
\lstinputlisting{source_filename.py}
\end{document}

如上例所示,你可以通过提供完整的文件名来包含任何文件。该文件将被视为纯文本,并根据你的默认语言进行高亮显示。在上述示例中,\lstset{} 命令用于定义默认语言为 C。你也可以在插入代码时定义语言,如下例所示(language=python)。你还可以指定从文件中包含的行数,考虑以下示例:

\lstinputlisting[language=Python,firstline=37,lastline=45]{source_filename.py}  
\lstinputlisting[language=Python, linerange={37-45,48-50}]{source_filename.py}

如果你确文件不会发生变化(至少在指定的行之前),这种方法会很有用。你也可以省略 firstlinelastline 参数:这意味着从此点开始或到此点为止的所有内容。

这是一个简单的 Pascal 代码示例:

\documentclass{article}
\usepackage{listings}             % 引入 listings 包
\begin{document}
\lstset{language=Pascal}          % 设置语言(你可以为每个代码块单独设置语言)

\begin{lstlisting}[frame=single]  % 开始代码块
for i:=maxint to 0 do
begin
{ do nothing }
end;
Write('Case insensitive ');
Write('Pascal keywords.');
\end{lstlisting}

\end{document}

支持的语言

listings 包支持以下编程语言:

ABAP2,4, ACSL, Ada4, Algol4, Ant, Assembler2,4, Awk4, bash, Basic2,4, C#5, C++4, C4, Caml4, Clean, Cobol4, Comal, csh, Delphi, Eiffel, Elan, erlang, Euphoria, Fortran4, GCL, Go (golang), Gnuplot, Haskell, HTML, IDL4, inform, Java4, JVMIS, ksh, Lisp4, Logo, Lua2, make4, Mathematica1,4, Matlab, Mercury, MetaPost, Miranda, Mizar, ML, Modelica3, Modula-2, MuPAD, NASTRAN, Oberon-2, Objective C5, OCL4, Octave, Oz, Pascal4, Perl, PHP, PL/I, Plasm, POV, Prolog, Promela, Python, R, Reduce, Rexx, RSL, Ruby, S4, SAS, Scilab, sh, SHELXL, Simula4, SQL, tcl4, TeX4, VBScript, Verilog, VHDL4, VRML4, XML, XSLT。

对于一些语言,支持多个方言。更多息请参考随包附带的文档,通常位于你的分发版中,文件名为 listings-*.dvi

注意事项

  • 仅在你以纯文本格式输入时,listings 才支持 Mathematica 代码。你不能像其他编程语言一样使用 \lstinputlisting{...} 包含 *.NB 文件,但 Mathematica 可以导出为格式良好的 LaTeX 源代码。

  • 对于这些语言,必须指定方言(例如:language={[x86masm]Assembler})。

  • Modelica 通过 dtsyntax 包提供支持,包可以从此处获取。

  • 对于这些语言,支持多个方言。例如,C 语言有 ANSI、Handel、Objective 和 Sharp 方言。有关更多息,请参阅 listings 手册的第12页。

自定义设置

你可以修改多个参数(详细息请参见 listings 包的开发者指南),这些设置会影响代码的显示方式。你可以在文档中的任何位置(无论是在 \begin{document} 之前还是之后)放置以下代码,并根据需要修改它。每行旁边都有解释。

\usepackage{listings}
\usepackage{color}

\definecolor{mygreen}{rgb}{0,0.6,0}
\definecolor{mygray}{rgb}{0.5,0.5,0.5}
\definecolor{mymauve}{rgb}{0.58,0,0.82}

\lstset{ 
  backgroundcolor=\color{white},   % 选择背景颜色;必须添加 \usepackage{color} 或 \usepackage{xcolor};应作为最后一个参数
  basicstyle=\footnotesize,        % 设置代码的字体大小
  breakatwhitespace=false,         % 设置是否仅在空格处自动换行
  breaklines=true,                 % 启用自动换行
  captionpos=b,                    % 设置标题位置为底部
  commentstyle=\color{mygreen},    % 注释的样式
  deletekeywords={...},            % 删除给定语言中的关键字
  escapeinside={\%*}{*)},          % 如果要在代码中添加 LaTeX 命令
  extendedchars=true,              % 允许使用非 ASCII 字符;仅适用于 8 位编码,不适用于 UTF-8
  firstnumber=1000,                % 从行号 1000 开始编号
  frame=single,                    % 给代码添加框架
  keepspaces=true,                 % 保留文本中的空格,有助于保留代码的缩进(可能需要设置 columns=flexible)
  keywordstyle=\color{blue},       % 关键字的样式
  language=Octave,                 % 代码的语言
  morekeywords={*,...},            % 如果要为语言添加更多的关键字
  numbers=left,                    % 设置行号的位置;可选值为 (none, left, right)
  numbersep=5pt,                   % 设置行号与代码之间的距离
  numberstyle=\tiny\color{mygray}, % 行号的样式
  rulecolor=\color{black},         % 如果未设置,则框架颜色可能会在换行时改变(例如注释中的绿色)
  showspaces=false,                % 是否显示空格,添加特定的下划线;此设置覆盖 'showstringspaces'
  showstringspaces=false,          % 仅在字符串中下划线空格
  showtabs=false,                  % 在字符串中显示制表符,添加特定的下划线
  stepnumber=2,                    % 行号间的步长。如果设置为 1,每行都会编号
  stringstyle=\color{mymauve},     % 字符串字面量的样式
  tabsize=2,                       % 设置默认制表符大小为 2 个空格
  title=\lstname                   % 显示包含的文件名,如果使用 \lstinputlisting 引入文件;也可以使用 caption 替代 title
}

属性分类及其功能

关键字 解释
常规设置 language=Python 设置代码的编程语言,例如 Python。
title=\lstname 如果使用 \lstinputlisting{FNAME.PY} 输入文件,默认标题是文件名,即 FNAME.PY
captionpos=b 设置标题位置为底部。
backgroundcolor=\color{white} 设置背景颜色;必须添加 \usepackage{color}\usepackage{xcolor},应作为最后一个参数
字体和样式 basicstyle=\footnotesize 设置代码的字体大小
换行设置 breaklines=true 启用自动换行
空格和制表符设置 showspaces=false 是否显示空格
showtabs=false 是否显示制表符
tabsize=2 设置默认制表符大小为 2 个空格
框架设置 frame=single 给代码添加框架
行号设置 numbers=left 行号放置在代码的左侧
numberstyle=\tiny\color{mygray} 行号的样式
关键字和字符串设置 keywordstyle=\color{blue} 关键字的样式
stringstyle=\color{mymauve} 字符串字面量的样式
注释设置 commentstyle=\color{mygreen} 注释的样式
逃逸序列 escapeinside={(*}{*)} 在代码环境内执行 LaTeX 命令

更多设置和选项可以根据需要进行调整。

escapeinside

escapeinside 选项需要一些解释。选项 escapeinside={A}{B} 将定义用于转义到 LaTeX 代码的定界符,即,所有位于字符串 "A" 和 "B" 之间的代码将作为 LaTeX 进行解析,覆盖当前的 listings 样式。在上述示例中,Octave 的注释以 % 开头,并将被打印在文档中,除非它们以 %* 开头,这种情况下它们会作为 LaTeX 被读取(所有 LaTeX 命令会被执行),直到它们以另一个 *) 结束。

如果你添加了上述段落,以下代码可以用于在代码中更改设置:

\lstset{language=C,caption={Descriptive Caption Text},label=DescriptiveLabel}

还有许多其他选项,请查看 listings 包的开发者指南。

样式定义

该包允许你定义样式,即指定一组设置的配置文件。

示例:

\lstdefinestyle{customc}{
  belowcaptionskip=1\baselineskip,
  breaklines=true,
  frame=L,
  xleftmargin=\parindent,
  language=C,
  showstringspaces=false,
  basicstyle=\footnotesize\ttfamily,
  keywordstyle=\bfseries\color{green!40!black},
  commentstyle=\itshape\color{purple!40!black},
  identifierstyle=\color{blue},
  stringstyle=\color{orange},
}

\lstdefinestyle{customasm}{
  belowcaptionskip=1\baselineskip,
  frame=L,
  xleftmargin=\parindent,
  language=[x86masm]Assembler,
  basicstyle=\footnotesize\ttfamily,
  commentstyle=\itshape\color{purple!40!black},
}

\lstset{escapechar=@,style=customc}

在我们的示例中,我们只全局设置了两个选项:默认样式和转义字符。

使用:

\begin{lstlisting}
#include <stdio.h>
#define N 10
/* Block
 * comment */

int main()
{
    int i;

    // Line comment.
    puts("Hello world!");
    
    for (i = 0; i < N; i++)
    {
        puts("LaTeX is also great for programmers!");
    }

    return 0;
}
\end{lstlisting}

\lstinputlisting[caption=Scheduler, style=customc]{hello.c}

C 部分将打印为:


自动化文件包含

如果你有一堆源文件需要包含,你可能会发现自己重复做同样的事情。这时宏就能发挥它们的真正威力。

\newcommand{\includecode}[2][c]{\lstinputlisting[caption=#2, escapechar=, style=custom#1]{#2}<!---->}
% ...

\includecode{sched.c}
\includecode[asm]{sched.s}
% ...

\lstlistoflistings

在这个示例中,我们创建了一个命令来简化源代码的包含。我们将默认样式设置为 customc。所有的列表都会有它们的文件名作为标题:通过宏,我们不需要重复写文件名。最后,我们使用 \lstlistoflistings 命令列出文档中的所有“algorithm”环境。

更多详细息请参考宏部分。

编码问题

默认情况下,listings 不支持多字节编码的源代码。extendedchar 选项仅适用于 8 位编码,如 latin1

要处理 UTF-8 编码,你需要告诉 listings 如何解释特殊字符,可以这样定义:

\lstset{literate=
  {á}{{\'a}}1 {é}{{\'e}}1 {í}{{\'i}}1 {ó}{{\'o}}1 {ú}{{\'u}}1
  {Á}{{\'A}}1 {É}{{\'E}}1 {Í}{{\'I}}1 {Ó}{{\'O}}1 {Ú}{{\'U}}1
  {à}{{\`a}}1 {è}{{\`e}}1 {ì}{{\`i}}1 {ò}{{\`o}}1 {ù}{{\`u}}1
  {À}{{\`A}}1 {È}{{\`E}}1 {Ì}{{\`I}}1 {Ò}{{\`O}}1 {Ù}{{\`U}}1
  {ä}{{\"a}}1 {ë}{{\"e}}1 {ï}{{\"i}}1 {ö}{{\"o}}1 {ü}{{\"u}}1
  {Ä}{{\"A}}1 {Ë}{{\"E}}1 {Ï}{{\"I}}1 {Ö}{{\"O}}1 {Ü}{{\"U}}1
  {â}{{\^a}}1 {ê}{{\^e}}1 {î}{{\^i}}1 {ô}{{\^o}}1 {û}{{\^u}}1
  {Â}{{\^A}}1 {Ê}{{\^E}}1 {Î}{{\^I}}1 {Ô}{{\^O}}1 {Û}{{\^U}}1
  {ã}{{\~a}}1 {ẽ}{{\~e}}1 {ĩ}{{\~i}}1 {õ}{{\~o}}1 {ũ}{{\~u}}1
  {Ã}{{\~A}}1 {Ẽ}{{\~E}}1 {Ĩ}{{\~I}}1 {Õ}{{\~O}}1 {Ũ}{{\~U}}1
  {œ}{{\oe}}1 {Œ}{{\OE}}1 {æ}{{\ae}}1 {Æ}{{\AE}}1 {ß}{{\ss}}1
  {ű}{{\H{u}}}1 {Ű}{{\H{U}}}1 {ő}{{\H{o}}}1 {Ő}{{\H{O}}}1
  {ç}{{\c c}}1 {Ç}{{\c C}}1 {ø}{{\o}}1 {Ø}{{\O}}1 {å}{{\r a}}1 {Å}{{\r A}}1
  {€}{{\euro}}1 {£}{{\pounds}}1 {«}{{\guillemotleft}}1
  {»}{{\guillemotright}}1 {ñ}{{\~n}}1 {Ñ}{{\~N}}1 {¿}{{?`}}1 {¡}{{!`}}1 
}

上述表格将涵盖大多数拉丁语言字符。有关 literate 选项的更多详细说明,请查看 Listings Documentation 的第 5.4 节。

另一种方法是将 \usepackage{listings}(在导言部分)替换为 \usepackage{listingsutf8},但这仅适用于 \lstinputlisting{...}

自定义标题

你可以使用 caption 包为 listings 中的标题(或标题)进行自定义。以下是 listings 的一个示例:

\usepackage{caption}
\usepackage{listings}

\DeclareCaptionFont{white}{ \color{white} }
\DeclareCaptionFormat{listing}{
  \colorbox[cmyk]{0.43, 0.35, 0.35,0.01 }{
    \parbox{\textwidth}{\hspace{15pt}#1#2#3}
  }
}
\captionsetup[lstlisting]{ format=listing, labelfont=white, textfont=white, singlelinecheck=false, margin=0pt, font={bf,footnotesize} }

% ...

\lstinputlisting[caption=My caption]{sourcefile.lang}

参考资料

更详细的息可以在 Carsten Heinz 和 Brooks Moses 的 PDF 文件中找到。

关于 Listings 包的详细息和文档可以在其 CTAN 网站上找到。


Last modified: Tuesday, 22 April 2025, 11:01 AM