latex中代码高亮显示宏包minted用法

1. 前提

使用minted需要安装python环境,以及Pygments模块,因为minted依赖于该模块提供超过300种语言的语法高亮。

latex编译时也需要添加选项-shell-escape,因为它需要调用Pygments程序,所以要通过该选项告诉tex编译器。

2. 基本用法:

\begin{minted}{<language>}
<code>
\end{minted}

一个完整的例子是这样的:

\documentclass{article}
\usepackage{minted}
\begin{document}
\begin{minted}{c}
int main() {
printf("hello, world");
return 0;
}
\end{minted}
\end{document}

除了可以使用minted环境外,也可以使用\mint命令来代替该环境,比如:

\mint{python}|import this|

另外,也可以在行内使用,比如:

words\mintinline{python}{print(x**2)}words

也可以通过文件来输入需要高亮的代码:

\inputminted[<options>]{<language>}{<filename>}.

minted宏包也提供了listing浮动体环境,用于代码的浮动显示。比如:

\begin{listing}[H]
\mint{cl}/(car (cons 1 '(2)))/
\caption{Example of a listing.}
\label{lst:example}
\end{listing}

还可以利用\listoflistings生成代码listing的目录。

3. 更换不同的高亮风格

评论有同学问,默认的风格不好看,怎么改高亮的风格。这的确是一个重要问题,我们使用minted就是为了好看的高亮效果的。

所以这里我们先介绍怎么更换风格再详细介绍minted宏包的其它细节。

由于Pygments已经提供了很多样式,所以切换的操作,只是调用对应的样式即可。命令为:

\usemintedstyle{stylename}

stylename可以通过 https://pygments.org/demo/ 或者命令pygmentize -L styles查看,下面的示例代码中,我也全部列出来,选择一个就可以。

示例代码如下:

\documentclass{minimal}
\usepackage[b6paper]{geometry}
\usepackage{ctex}
\usepackage{minted}

\usemintedstyle{lovelace}
%Styles:
%~~~~~~~
%* default:
%    The default style (inspired by Emacs 22).
%* emacs:
%    The default style (inspired by Emacs 22).
%* friendly:
%    A modern style based on the VIM pyte theme.
%* colorful:
%    A colorful style, inspired by CodeRay.
%* autumn:
%    A colorful style, inspired by the terminal highlighting style.
%* murphy:
%    Murphy's style from CodeRay.
%* manni:
%    A colorful style, inspired by the terminal highlighting style.
%* material:
%    This style mimics the Material Theme color scheme.
%* monokai:
%    This style mimics the Monokai color scheme.
%* perldoc:
%    Style similar to the style used in the perldoc code blocks.
%* pastie:
%    Style similar to the pastie default style.
%* borland:
%    Style similar to the style used in the borland IDEs.
%* trac:
%    Port of the default trac highlighter design.
%* native:
%    Pygments version of the "native" vim theme.
%* fruity:
%    Pygments version of the "native" vim theme.
%* bw:
%
%* vim:
%    Styles somewhat like vim 7.0
%* vs:
%
%* tango:
%    The Crunchy default Style inspired from the color palette from the Tango Icon Theme Guidelines.
%* rrt:
%    Minimalistic "rrt" theme, based on Zap and Emacs defaults.
%* xcode:
%    Style similar to the Xcode default colouring theme.
%* igor:
%    Pygments version of the official colors for Igor Pro procedures.
%* paraiso-light:
%
%* paraiso-dark:
%
%* lovelace:
%    The style used in Lovelace interactive learning environment. Tries to avoid the "angry fruit salad" effect with desaturated and dim colours.
%* algol:
%
%* algol_nu:
%
%* arduino:
%    The Arduino® language style. This style is designed to highlight the Arduino source code, so exepect the best results with it.
%* rainbow_dash:
%    A bright and colorful syntax highlighting theme.
%* abap:
%
%* solarized-dark:
%    The solarized style, dark.
%* solarized-light:
%    The solarized style, light.
%* sas:
%    Style inspired by SAS' enhanced program editor. Note This is not meant to be a complete style. It's merely meant to mimic SAS' program editor syntax highlighting.
%* stata:
%    Light mode style inspired by Stata's do-file editor. This is not meant to be a complete style, just for use with Stata.
%* stata-light:
%    Light mode style inspired by Stata's do-file editor. This is not meant to be a complete style, just for use with Stata.
%* stata-dark:
%
%* inkpot:
%
%* zenburn:
%    Low contrast Zenburn style.
%* gruvbox-dark:
%    Pygments version of the "gruvbox" dark vim theme.
%* gruvbox-light:
%    Pygments version of the "gruvbox" Light vim theme.

\begin{document}

\begin{minted}[linenos=true]{c++}
#include <iostream>
int main() {
std::cout << "Hello "
<< "world"
<< std::endl;
}
\end{minted}

\begin{minted}[linenos=true]{python}
# -*- coding: utf-8 -*-

import torch
import numpy as np
from matplotlib import pyplot as plt
import random

#创建输入和输出随机张量
#x = torch.randn(N, D_in)
#y = torch.randn(N, D_out)
datanp = np.loadtxt('res.csv', delimiter=',')
\end{minted}

\end{document}

结果为:
lovelace样式
若换成vs,则结果为:

vs样式结果
如果我们给代码块加上背景还可以实现dark风格的样式比如:

\documentclass{minimal}
\usepackage[b6paper]{geometry}
\usepackage{ctex}
\usepackage{xcolor}
\usepackage{minted}

\usemintedstyle{paraiso-dark}

\begin{document}

\begin{minted}[bgcolor=black,linenos=true]{c++}
#include <iostream>
int main() {
std::cout << "Hello "
<< "world"
<< std::endl;
}
\end{minted}

\begin{minted}[bgcolor=black,linenos=true]{python}
# -*- coding: utf-8 -*-

import torch
import numpy as np
from matplotlib import pyplot as plt
import random

#创建输入和输出随机张量
#x = torch.randn(N, D_in)
#y = torch.randn(N, D_out)
datanp = np.loadtxt('res.csv', delimiter=',')
\end{minted}

\end{document}

结果为:
dark风格
如果我们结合tcolorbx可以得到更为漂亮的效果,比如:

\documentclass{article}
\usepackage[b6paper]{geometry}
%\usepackage{ctex}
\usepackage{xcolor}

\usepackage{tcolorbox}
\tcbuselibrary{skins}
\tcbuselibrary{minted}
\usemintedstyle{paraiso-dark}

\begin{document}

\begin{tcblisting}{listing engine=minted,boxrule=0.1mm,
colback=blue!5!white,colframe=blue!75!black,
listing only,left=5mm,enhanced,sharp corners=all,
overlay={\begin{tcbclipinterior}\fill[red!20!blue!20!white] (frame.south west)
rectangle ([xshift=5mm]frame.north west);\end{tcbclipinterior}},
minted language=c++,
minted style=tango,
minted options={fontsize=\small,breaklines,autogobble,linenos,numbersep=3mm}}
#include <iostream>
int main() {
std::cout << "Hello "
<< "world"
<< std::endl;
}
\end{tcblisting}

\begin{tcblisting}{listing engine=minted,boxrule=0.1mm,
colback=blue!5!white,colframe=blue!75!black,
listing only,left=5mm,
minted language=c++,
minted style=paraiso-dark,
minted options={bgcolor=black,fontsize=\small,breaklines,
autogobble,linenos,numbersep=3mm}}
#include <iostream>
int main() {
std::cout << "Hello "
<< "world"
<< std::endl;
}
\end{tcblisting}
\end{document}

结果为:
tcolorbox结合minted示例

4. 选项

minted使用选项的方式可以用key=value方式给出,而仅给出key则使用默认的选项。另外也可以针对文档中同一语言的所有代码显示设置相同的选项,
行间和行内代码分别用命令\setminted\setmintedinline设置。

下面介绍一些常用的选项:

  • langlinenos 选项可以使得不同语言的高亮代码的行数连续计数。

  • autogobble 选项可以去掉最前面的空格

  • baselinestretch 选项设置行距的比例值

  • beameroverlays 选项可以使得在beamer中实现overlay功能,比如使用\only<1>{...}

  • breakafter 选项可以指定行内代码的可以换行在其后换行的字符,
    字符集则是一个字符串,比如breakafter=-/d

\begin{minted}[breaklines, breakafter=d]{python}
some_string = 'SomeTextThatGoesOnAndOnForSoLongThatItCouldNeverFitOnOneLine'
\end{minted}
  • breakaftergroup 选项默认为true,表示当使用breakafter选项时,若断行字符有相邻的相同字符,则在最后一个字符后断行。

  • breakaftersymbolpre和breakaftersymbolpost 选项用于指定断行前后时添加的字符。

  • breakanywhere 选项用于行间代码环境中,当breaklines=true时,可以在任意字符处断行。

  • breakanywheresymbolpre和breakanywheresymbolpost 与breakaftersymbolpre和breakaftersymbolpost 选项类似。

  • breakautoindent 选项用于设置断行后的行的自动缩进。

  • breakbefore 类似于breakafter。

  • breakbeforegroup 类似于breakaftergroup。

  • breakbeforesymbolpre,breakbeforesymbolpost也类似于breakaftersymbolpre和breakaftersymbolpost。

  • breakbytoken 选项阻止在记号内部断行。

  • breakbytokenanywhere 选项阻止在记号内部断行,但允许在记号间断行。

  • breakindent 选项用于设置断行后接续的行的缩进距离,比如1em

  • breakindentnchars 选项可以将缩进距离设置成单字符宽度的倍数,比如2倍。

  • breaklines 选项允许代码的断行。

  • breaksymbol等价于breaksymbolleft,用于设置断行后接续行前面加入的字符。

  • breaksymbolright 用于设置断行处右侧的字符。

  • breaksymbolindent 等价于breaksymbolindentleft,设置breaksymbolleft字符的缩进距离

  • breaksymbolindentnchars 等价于 breaksymbolindentleftnchars,设置breaksymbolleft字符的缩进距离,用字符宽度倍数表示。

  • breaksymbolindentright 是右侧额外的缩进距离,用于给breaksymbolright提供空间。

  • breaksymbolindentrightnchars 是右侧额外的缩进距离,用于给breaksymbolright提供空间。用字符宽度倍数表示。

  • breaksymbolsep 等同breaksymbolsepleft,设置breaksymbolleft和相邻文本的间距。

  • breaksymbolsepnchars 等同breaksymbolsepleftnchars,设置breaksymbolleft和相邻文本的间距。用字符宽度倍数表示。

  • breaksymbolsepright,设置breaksymbolright和相邻文本的间距。

  • breaksymbolseprightnchars ,设置breaksymbolright和相邻文本的间距。用字符宽度倍数表示。

  • bgcolor 设置背景颜色。如果要使用更高级的颜色设置,可以将minted环境放置在mdframed或tcolorbox这样的环境中,若使用tcolorbox,则可以设置\tcbuselibrary{minted}。然后直接使用tcblisting环境,比如:

\begin{tcblisting}{<tcb options>,
minted language=<language>,
minted style=<style>,
minted options={<option list>} }
<code>
\end{tcblisting}
  • codetagify 可以用于高亮注释或docstrings中的特殊代码标签,比如todo,bug,note等。

  • curlyquotes 运行将```和'字符转换为引号。

  • encoding 设置Pygments可识别的文件编码。

  • escapeinside 用于设置逃逸的字符对,在该字符对中的代码会被latex正常解析。要在代码中使用latex命令就需要使用该选项。

比如:

\begin{minted}[escapeinside=||]{py}
def f(x):
y = x|\colorbox{green}{**}|2
return y
\end{minted}

  • firstline 设置显示代码的第一行,该行前面的所有行都将被忽略。

  • firstnumber 设置第一行的行号。

  • fontfamily 设置预定义的字族,比如,tt,courier等。

  • fontseries 设置预定义的字系。

  • fontsize 设置预定义的字号。

  • fontshape 设置预定义的字形。

  • formatcom 输出抄录代码前执行的命令,这是一个钩子。

  • frame 设置代码周围的线。none | leftline | topline | bottomline | lines | single

  • framerule 设置框线的宽度。

  • framesep 设置框线与内容的间距。

  • gobble 设置每行行首去掉的字符数。

  • highlightcolor 设置需要高亮行的颜色。

  • highlightlines 设置需要高亮的行的行号,是一个字符串,比如highlightlines={1, 3-4}

  • keywordcase 设置关键字的大小写,lower, upper, or capitalize.

  • label 在代码周围打印一个标签的内容。

  • labelposition 设置标签的位置,比如none | topline | bottomline | all

  • lastline 设置显示代码的最后一行。该行后面不显示。

  • linenos 设置是否显示行号。若要更改行号的样式,需要重定义\theFancyVerbLine宏。

比如:

\renewcommand{\theFancyVerbLine}{\sffamily
\textcolor[rgb]{0.5,0.5,1.0}{\scriptsize
\oldstylenums{\arabic{FancyVerbLine}}}}
\begin{minted}[linenos,
firstnumber=11]{python}
def all(iterable):
for i in iterable:
if not i:
return False
return True
\end{minted}
  • numberfirstline 设置是否总是对第一行进行编号,而忽略stepnumber.

  • numbers 用于设置行号的位置left | right | both | none

  • mathescape 用于设置是否可以在逃逸字符对内使用数学模式。

  • numberblanklines 设置是否对断行后的行进行编号。

  • numbersep 设置行号和行首的间距。

  • obeytabs 设置是否将tabs仅作为tab而不转换为空格。

  • outencoding 设置Pygments输出的高亮后的文本的文件编码。

  • resetmargins 设置是否重设在其它环境中的左侧边距。

  • rulecolor 设置边框的颜色

  • samepage 设置所有代码放到相同页,即便不合适。

  • showspaces 是否显示空格。

  • showtabs 是否显示tabs。

  • space 设置显示空格用的字符

  • spacecolor 设置空格显示的颜色

  • style 设置Pygments用的样式表。

  • stepnumber 显示行号的间隔数字。

  • stepnumberfromfirst 设置是否从第一行开始设置间隔显示行号。默认情况下,显示的行号n的情况为,mod(n,stepnumber)==0时,使用该选项后,则变为:
    mod(n-firstnumber,stepnumber)==0.

  • stepnumberoffsetvalues 设置是否在设置间隔行号显示时忽略第一行的行号,即要显示的行与第一行的行号无关,而与真实的行数有关,当行号的值仍然是设置了第一行行号后的值。因此显示行号n的情况为,mod(n-firstnumber+1,stepnumber)==0

  • stripall 设置是否去除所有输入中的起始和末尾的空格

  • stripnl 设置是否去除所有输入中的起始和末尾的换行符(newline)

  • tab 设置tab的显示字符,注意仅当showtabs=true时才有效,可以使用\FancyVerbTab\rightarrowfill等字符。

  • tabcolor 设置tab的显示颜色

  • tabsize 设置一个tab中包含空格的数量

  • texcl 设置是否启用在注释中使用latex代码。类似于listings的用法。这种用法对于需要在注释中增加label用于引用时是有用的。当然也可以直接使用escapeinside。

  • texcomments 功能同texcl。

  • xleftmargin 代码块左侧增加的缩进

  • xrightmargin 代码块右侧增加的缩进

5. 定义新的环境

有时我们希望在一个文档中使用多种不同命名的环境来显示不同的代码,而不是简单的使用minted环境。类似于listings宏包的\lstnewenvironment,minted宏包提供了\newminted命令用于定义一个新的环境,比如:

\newminted{cpp}{gobble=2,linenos}
\begin{cppcode}
template <typename T>
T id(T value) {
return value;
}
\end{cppcode}

上述代码中定义了一个cppcode的环境,用于显示cpp代码。如果要在cppcode环境使用在定义时未设置的选项,那么需要在使用时带上*号,比如:

\begin{cppcode*}{linenos=false,
frame=single}
int const answer = 42;
\end{cppcode*}

类似的对于\mint\mintinline\inputminted类命令,也可以通过
\newmint\newmintinline\newmintedfile命令重新定义一个针对不同语言的命令。

6. 总结

上述主要是针对minted宏包说明文档,做了用法介绍,没有特别的应用。下一篇将介绍一个关于代码显示的不错应用。

7. 关于编译

需要注意使用minted宏包的文档编译,需要使用-shell-escape选项。同时在编译时,因为需要调用Pygments程序,所以对于python安装环境有一定的要求。如果安装的时官方的python,那么程序的搜索路径一般是没有问题的。但如果使用的时anaconda一套软件,并且没有将anaconda路径设置为系统的路径,那么Pygments程序可能会出现问题。因此需要在anaconda提供的命令行中来进行编译。比如:

xelatex --synctex=-1 -shell-escape ega.tex

8. 关于tab

需要注意的时,在不同编辑器之间的文本复制过程中,tab可能会产生变化。比如从notepad++的文档中拷贝代码到winedt内,tab会发生变化。如果没有办法解决该问题,那么可以先将tab转换成空格,然后再复制。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐