用 LaTeX 排版代码的主要问题有两个。一是希望代码中的特殊字符不被 LaTeX 处理;二是希望能有代码高亮。前者称为「原样抄写」,也就是 verbatim。剩下的边框、编号、交叉引用,都属于 LaTeX 比较好实现的「额外功能」。
在 LaTeX 中,最基本的原样抄写是通过 \verb 命令和 verbatim 环境实现的。在不执行其他程序排版代码的情况下,此二者是所有原样抄写的基础。基本的做法,是遇到标志位时,改变字符的 TeX 分类码(catcode, catalogue code);在遇到第二个标记位时,恢复这些分类码。
\verb 命令采取两个相同的特殊字符作为标记位;具体来说,\verb 会将其后的第一个非字母的字符作为标记位(除了 * 这个字符)。这些特殊字符可以是任意非字母的字符,比如下列用法都是合法的;但通常我们使用 | 或者 + 作为标记位。
\documentclass{article}
\begin{document}
\verb|python|, \verb+python+, \verb\python\, \verb{python{, \verb python , \verb1python1
\end{document}
verbatim 环境,则使用 \begin{verbatim} 和 \end{verbatim} 作为标记位。必须在代码中,显式地出现 \end{verbatim},原样抄写环境才会正常地结束。因此,简单地通过 \newenvironment 或者 \newcommand 去「包装」verbatim 环境是不可行的。
\documentclass{article}
\begin{document}
\begin{verbatim}
for x in range(101):
print('fizz'[x%3*4:] + 'buzz'[x%5*4:] or x)\end{verbatim}
\end{document}
\verb 命令和 verbatim 环境解决了原样抄写的问题;但是,这样得出的效果没有任何高亮:简短的代码看起来还好,较长的代码看起来就很费劲了。解决这个问题,我们需要引入专门排版代码的宏包 listings;当然,为了好看,你需要做一些配置。以下是我惯常使用的配置。
\documentclass{article}
\usepackage{xcolor}
\usepackage{listings}
\lstdefinestyle{lfonts}{
basicstyle = \footnotesize\ttfamily,
stringstyle = \color{purple},
keywordstyle = \color{blue!60!black}\bfseries,
commentstyle = \color{olive}\scshape,
}
\lstdefinestyle{lnumbers}{
numbers = left,
numberstyle = \tiny,
numbersep = 1em,
firstnumber = 1,
stepnumber = 1,
}
\lstdefinestyle{llayout}{
breaklines = true,
tabsize = 2,
columns = flexible,
}
\lstdefinestyle{lgeometry}{
xleftmargin = 20pt,
xrightmargin = 0pt,
frame = tb,
framesep = \fboxsep,
framexleftmargin = 20pt,
}
\lstdefinestyle{lgeneral}{
style = lfonts,
style = lnumbers,
style = llayout,
style = lgeometry,
}
\lstdefinestyle{python}{
language = {Python},
style = lgeneral,
}
\begin{document}
\lstinline[style = python]|print('Hello world!')|
\begin{lstlisting}[style = python]
for x in range(101):
print('fizz'[x%3*4:] + 'buzz'[x%5*4:] or x)\end{lstlisting}
\end{document}
Pygments 是一个 Python 模块,可用作排版代码。Pygments 也可以在 LaTeX 中调用。为此,你需要安装好 Python 环境,以及 Pygments 模块;此外,你还需要在编译 TeX 源码时,加入 --shell-escape,以便调用外部的 Python 程序。一个简单的示例如下。
\documentclass{article}
\usepackage{minted}
\begin{document}
\mint{python}|print('Hello world!')|
\begin{minted}{Python}
for x in range(101):
print('fizz'[x%3*4:] + 'buzz'[x%5*4:] or x)\end{minted}
\end{document}
此处仅是简单介绍;listings 和 minted 宏包的具体用法,可以参见它们的用户说明手册。