listings
的麻烦
在 LaTeX 中实现语法高亮的老牌方案是 listings
,然而这种方案用起来非常麻烦:
- 默认的字体效果很糟糕,居然是 Serif 系列的;
- 定义一种新语言需要先耗费大量时间了解帮助手册,还可能需要了解很多奇怪的规则;
- 代码跨页时需要一些额外的工作;
- 代码中的单引号,双引号问题;
- 中文支持问题1。
- 甚至对 LaTeX 的语法高亮支持也需要做许多额外工作。
当然,不是说 listings
包的功能不够强大,从《给语法高亮内容中的部分内容进行高亮标识》这个方案可以看到,利用 escape character 除了可以解决中文的问题外,还可以实现更多自定义的效果,比如《在代码中添加公式》。如果是英文文档,定义一个类似于 \verb|.|
的命令,实现 inline code 式的命令也很容易2。
因此,虽然 listings
包理论上可以满足我们的需求,但是要解决特定的问题往往需要耗费相当的精力和时间,对初学者并不算太友好。
minted
宏包需要的支持
LaTeX 中的 minted
宏包实际上是调用 Python 的 pygments
来完成语法高亮的,高亮效果好,支持的语法充分,可以实现代码内的公式3,通过 \mintinline
命令实现行内代码的同时4可以指定语言的名称5,需要的额外配置少,唯一目前要做就是在安装完 Python 后,通过下面的命令安装 pygments
:
pip install pygments
之后编译时用下面的命令:
xelatex -shell-escape demo.tex
或
lualatex -shell-escape demo.tex
对于使用 WinEdt 或者 Sublime Text 界面接口的用户,可能选项 -shell-escape
会比较麻烦一些,但由于自己是直接调用 bat 文件来处理编译问题,因此这个选项完全不是问题。
现在
knitr
转成 pdf 的语法高亮应该也是由pygments
完成的,并且完全不需要用户干预(不确定在knitr
时pygments
是否需要提前安装。)。
可能的麻烦
提醒:尝试在 CTeX 2.9.2 下面直接将最新版的 minted
相关文件复制到相应的目录,但结果出错,说找不到 fvextra
宏包,然而添加了该宏包之后仍然会有其它错误,估计是相关的依赖包没有更新的原因,因此推荐使用最新版的 TeXLive 或者将整个 CTeX 套装的宏包都进行更新来解决这个问题,但是在线更新 MikTeX 之后,再更新相关宏包时,同样会出现各种各样的奇怪问题,像 picins
这要的宏包甚至会认为是过时的而直接删除,导致其它很多麻烦,最终放弃更新 CTeX。
好像更新新的 ctex
宏包后,ctexsetup
命令也不再推荐使用。
简单例子
这个例子来自 https://zhuanlan.zhihu.com/p/27996164。
\documentclass[a4paper]{article}
\usepackage{minted}
\usepackage{xcolor}
\definecolor{bg}{rgb}{0.95,0.95,0.95}
\usepackage[margin=2.5cm]{geometry}
\begin{document}
\begin{minted}[bgcolor=bg]{rust}
fn foo(v1: Vec<i32>, v2: Vec<i32>) -> (Vec<i32>, Vec<i32>, i32) {
// Do stuff with `v1` and `v2`.
// Hand back ownership, and the result of our function.
(v1, v2, 42)
}
let v1 = vec![1, 2, 3];
let v2 = vec![1, 2, 3];
let (v1, v2, answer) = foo(v1, v2);
\end{minted}
\begin{minted}[bgcolor=bg]{go}
import "math"
type Shape interface {
Area() float64
}
type Square struct { // Note: no "implements" declaration
side float64
}
func (sq Square) Area() float64 { return sq.side * sq.side }
type Circle struct { // No "implements" declaration here either
radius float64
}
func (c Circle) Area() float64 { return math.Pi * math.Pow(c.radius, 2) }
\end{minted}
\end{document}
下面是实际的高亮效果:
- 中文支持后期已经基本解决,参考 CTeX #76123 和 CTeX #77046。 ↩
- 中文里面还有 bug,参见 GitHub #282 以及《语法高亮:在
lstinline
中给行内代码添加背景颜色 z》。 ↩ - 参见帮助文档。 ↩
- 可进一步参考 Stack Exchange #45756。 ↩
- 参考 Stack Exchange #45756,这个功能需要
minted
2.0 以上版本,CTeX 2.9.2 套装默认的版本不行。 ↩