前言
最近做集创赛要写论文,需要插入很多很多代码。
之前 试过Listings,但是Listings的高亮很糟糕,而且支持的语言也很少。之前还给他们提交了一个RISCV的语法高亮方案。
有没有比Listings更方便的代码高亮方案呢?有的兄弟有的,那就是minted。
minted使用Pygments作为语法高亮方案,支持更多的高亮特性,且得益于Python后端的原因,可以轻松自定义语法高亮方案。
使用
依赖导入
嵌入代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| \begin{minted}{cpp} // 继电器闭合 void CBIT_Control(int num, bool on) { if (num < 0) { cout << "Invalid CBIT index: " << num << endl; return; } const string cbitName = "CBIT" + to_string(num);
if (on) { cbit.Signal(cbitName).SetOn(); } else { cbit.Signal(cbitName).SetOff(); }
sys.DelayUs(DELAY_LONG); cbit.Signal(cbitName).GetStatus(CBIT_RESULT);
for (size_t count = 0; count < CBIT_RESULT.size(); count++) { cout << "Signal Name : " << CBIT_RESULT[count].strSigName << endl; cout << "Site id : " << CBIT_RESULT[count].ulSite << endl; cout << "value : " << CBIT_RESULT[count].dbValue << endl; } } \end{minted}
|
引用文件内代码
1 2 3
| \inputminted[ fontsize=\xiaowu, ]{cpp}{code/Test.cpp}
|
自用代码格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| \setminted{ style=default, bgcolor=white, fontsize=\xiaowu, fontfamily=tt, linenos, baselinestretch=1.36, breaklines, breakanywhere, breaksymbolleft={}, breaksymbolright={}, breakanywheresymbolpre={}, breakanywheresymbolpost={}, tabsize=4, frame=single, framerule=0.6pt, framesep=0.6em, rulecolor=\color{black}, numbersep=0.6em, xleftmargin=2em }
\makeatletter \newcommand{\atelog@patch@pygments@escape}[2]{ \ifcsname\minted@styleprefix#1\endcsname \expandafter\def\csname\minted@styleprefix#1\endcsname##1{#2} \fi } \newcommand{\atelog@patch@pygments@ligatures}{ \atelog@patch@pygments@escape{Zlt}{\char`\<} \atelog@patch@pygments@escape{Zgt}{\char`\>} \atelog@patch@pygments@escape{Zhy}{\char`\-} } \apptocmd{\minted@patch@PygmentsStyledef}{\atelog@patch@pygments@ligatures}{}{} \renewcommand*\verbatim@nolig@list{} \makeatother
|
以及字体定义中要指定好等宽字体的斜体与粗体:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| \setmonofont[ AutoFakeBold=false, Ligatures = Common, CharacterVariant={1,62}, StylisticSet={3,7}, Path = ./fonts/, UprightFont = Maple.ttf, ItalicFont = MapleItalic.ttf, FontFace = {b}{n}{MapleBold.ttf}, FontFace = {bx}{n}{MapleBold.ttf} ]{Maple} \setCJKmonofont[ AutoFakeBold=false, Ligatures = Common, CharacterVariant={1,62}, StylisticSet={3,7}, Path = ./fonts/, UprightFont = Maple.ttf, ItalicFont = MapleItalic.ttf, FontFace = {b}{n}{MapleBold.ttf}, FontFace = {bx}{n}{MapleBold.ttf} ]{Maple} \DeclareFontSeriesDefault[tt]{bf}{bx}
|
看看效果:

本地自定义语法高亮
开启许可后,lexer可执行任意Python代码。请勿在未审查的LaTeX模板仓库内开启此功能。
开启任意lexer执行权限
在用户目录或 TEXMFHOME 的 .latexminted_config 里启用:
1 2 3 4 5
| { "security": { "enable_cwd_config": true } }
|
自定义Lexer高亮
写一个mylexer.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from pygments.lexer import RegexLexer from pygments.token import Text, Keyword, Name
class CustomLexer(RegexLexer): name = "MyLang" aliases = ["mylang"]
tokens = { "root": [ (r"\b(if|else|end)\b", Keyword), (r"[a-zA-Z_]\w*", Name), (r"\s+", Text), (r".", Text), ] }
|
默认类名应为 CustomLexer。如果类名不是这个,比如 MyLexer,在 LaTeX 里要写成 mylexer.py:MyLexer。
然后算下HASH:
1
| python -c "import hashlib, pathlib; p=pathlib.Path('mylexer.py'); print(hashlib.sha256(p.read_bytes()).hexdigest())"
|
项目内配置
同样在项目内创建 .latexminted_config:
1 2 3 4 5
| { "custom_lexers": { "mylexer.py": "0d000721..." } }
|
LaTeX内使用
如果类名是默认的 CustomLexer:
1 2 3 4 5 6 7 8 9 10 11 12
| \documentclass{article} \usepackage{minted}
\begin{document}
\begin{minted}{./mylexer.py} if foo bar end \end{minted}
\end{document}
|
如果类名是 MyLexer:
1
| \inputminted{./lexers/mylexer.py:MyLexer}{example.my}
|
新版 minted 允许把自定义 lexer 文件直接放在内置 lexer 名称的位置,例如 \inputminted{lexer.py}{<file>} 或 \inputminted{./path/lexer.py:LexerClass}{<file>}。
编译
新版的minted v3已经不强制要求-shell-escape参数了。正常编译即可。