LaTeX中Python代码的语法高亮
LaTeX中Python代码的语法高亮
本文中,“{}”中的字母为LaTeX或Python的包名,只有“Pygments”是Python的包,其他都是LaTeX的包。
LaTeX提供了功能丰富的包(package),以实现某些特定的排版功能。其中,{listings}包和{minted}包主要用于文档中程序代码语法的高亮显示,支持常见的编程语言。
- {listings}基于内置或用户提供的关键字高亮程序代码语法,高亮的内容受限于关键词的数量,代码的着色功能也是有限。
- {minted}使用Pymgent高亮程序代码,提供了更多的高亮内容,基本类似在Jupyter Notebook或Jupyter Qtconsole中的代码高亮。
使用{listings}包
{listings}的使用简洁明了:
- 在导言区加载包,并设置包选项。
- 在文档区使用
\begin{lstlisting}\end{lstlisting}包围代码。 - 编译文档,PDF文件中,代码高亮显示。
可以根据自己的需要,通过\lstset设置列表参数,或定义自己的列表新环境。如果没有特殊的需求,使用{listings}已经足够。如下使用{listings}高亮Python代码。
例 1
% !TeX program = xelatex
\documentclass{ctexart}
\usepackage{xcolor} %高亮使用的颜色
\definecolor{commentcolor}{RGB}{85,139,78}
\definecolor{stringcolor}{RGB}{206,145,108}
\definecolor{keywordcolor}{RGB}{34,34,250}
\definecolor{backcolor}{RGB}{220,220,220}
\usepackage{accsupp}
\newcommand{\emptyaccsupp}[1]{\BeginAccSupp{ActualText={}}#1\EndAccSupp{}}
\usepackage{listings}
\lstset{ %高亮代码设置
language=python, %Python语法高亮
linewidth=0.9\linewidth, %列表list宽度
%basicstyle=\ttfamily, %tt无法显示空格
commentstyle=\color{commentcolor}, %注释颜色
keywordstyle=\color{keywordcolor}, %关键词颜色
stringstyle=\color{stringcolor}, %字符串颜色
%showspaces=true, %显示空格
numbers=left, %行数显示在左侧
numberstyle=\tiny\emptyaccsupp, %行数数字格式
numbersep=5pt, %数字间隔
frame=single, %加框
framerule=0pt, %不划线
escapeinside=@@, %逃逸标志
emptylines=1, %
xleftmargin=3em, %list左边距
backgroundcolor=\color{backcolor}, %列表背景色
tabsize=4, %制表符长度为4个字符
gobble=4 %忽略每行代码前4个字符
}
\begin{document}
这是Python语法高亮
\begin{lstlisting}
def prtmotto(n):
for i in range(0,n):
print("lift is short, i use Python!")
\end{lstlisting}
\end{document}
}
使用{minted}包
{minted}包使用Python库(包)Pygments进行语法着色,所以首先必须安装Python,并安装Pygments库,同时使Python处于Windows系统路径。
{minted}的代码语法着色十分具有吸引力,但它没有{listings}好使用——简单的直接使用例外。当要在一个环境中包含minted环境,经常会带来许多问题。如果要定义自己的minted环境,比较方便的形式是使用{tcolorbox}包。
{mdframed}和{tcolorbox}都是定制框(box)的包,前者要自己hacker,后者的已有功能十分丰富,且定制功能强大。{tcolorbox}提供了minted库,通过如下形式之一使用:
\usepackage[minted]{tcolorbox}。自动加载{minted}包- 通过
\tcbuselibrary加载\usepackage{tcolorbox}
\tcbuselibrary{minted} %加载{minted}包
如果要定义新环境或命令,{tcolorbox}提供了如下命令:
\tcbset设置所有tcolorbox的参数。tcolorbox和tcblisting环境建立box或列表list。\newtcblisting或\newtcbinputlisting创建新的列表环境(tcblisting)或宏。\newtcolorbox或\newtcbox创建新的tcolorbox环境或宏。\DeclareTCBListing或\NewTCBListing创建有一个可选参数的列表(还是要2个以上的参数)。需要加载{xparse,listings},但是{minted}应该在{listings}的后面,否则会覆盖minted选项的设置。\usepackage[xparse,listings,minted]{tcolorbox}
或
\tcbuselibrary{xparse,listings,minted}
- 加载{xparse}后,选项中可以使用逻辑选项(对应xparse中的宏):
IfNoValueTF、IfValueTF、IfBooleanTF,注意用法。 - 结合{minted}的
\newminted命令,可以方便定制基于{minted}的语法高亮。 - {minted}内部使用了{fancyvrb},要定义新的minted环境,必须包含命令
\VerbatimEnvironment,如下定义了cpp代码环境(minted.pdf,P30):\newminted{cpp}{gobble=2,linenos}
\newenvironment{env}
{\VerbatimEnvironment\begin{cppcode}}
{\end{cppcode}}
\newtcblisting、\DeclareTCBListing等创建的列表不需要如此!
编译过程注意以下几点(以xelatex编译为例):
- {minted}将制表符转义为形如
^^T的符号。在xelatex的编译选项中加入-8bit可避免此问题。 - 由于要调用Python的Pygments库,xelatex的编译选项中应加入
-shell-escape。 - 在VScode中,即使文件第一行指定了xelatex编译,但是仍使用recipes中的
latexmk(这道菜的做法和xelatex这道菜的做法不同!),因此要专门选择recipes中的xelatex编译。尽量配置快捷键,见 VScode 配置为 LaTeX IDE
例 2
% !TEX program = xelatex
\documentclass{ctexart}
\usepackage[breakable,minted]{tcolorbox}
%tcolorbox设置:列表无边框、无边距、可跨页、位于页面中心、90%的正文宽度
\newtcblisting{pylistings}[1][]{
frame empty,size=minimal,breakable,center,width=0.9\linewidth,
listing only,
minted language=python,
minted options={ %自动移除前置空白、制表为4字符、mathhe和||内的不处理
autogobble,tabsize=4,mathescape,escapeinside=||,
linenos,numberblanklines=false,numbersep=2pt,#1}}
\begin{document}
\begin{pylistings}[showspaces]
|$\sum_{x}^{2}$| |不处理|
def prtmotto(n): # 带一个参数参数
for i in range(0,n):
print("lift is short, i use Python!")
prtmotto(2)
\end{pylistings}
\begin{pylistings}[]
print("如果没有参数,环境开始后也要带一个空的中括号")
\end{pylistings}
\end{document}
例2定义的列表环境包含了一个参数,方便调整某些代码的格式。使用中要注意以下2点:
- 即使没有参数,环境后也要有对中括号“[]”,否则会报错(tcolorbox.pdf中的有些例子也使如此处理的)。
- 参数以逗号分割,因此不能同时传递2个参数,如[showspace,numbers=none]会出现错误!
例 3
例3使用了\DeclareTCBListing命令,要先加载{xparse,listings},放于{minted}之前。
为方便使用,定义了一个tcb样式pycode,就是常用选项的集合,使用方法也与选项相同。相同的选项参数,后面的设置会覆盖前面的!所以“minted options”选项移动到新列表的定义中,通过有无“*”判断是否使用新添加的选项。
pylistings是定义的新列表环境,一个可选参数和一个s参数,就是“*”号。使用了“*”就表示要添加额外的列表控制选项(主要控制空格的显示与否)。否则,就按照基本样式定制列表显示。和前一个例子的使用不同:如果没有添加新选项,环境后无需加中括号“[]”;否则,将新选项放在中括号中,前面加“*”并放于环境名后。
% !TEX program = xelatex
\documentclass{ctexart}
\usepackage[breakable,xparse,listings,minted]{tcolorbox}
\tcbset{pycode/.style={
frame empty,size=minimal,breakable,center,width=0.9\linewidth,
listing only,
minted language=python}}
\DeclareTCBListing{pylistings}{s o}{pycode,
IfBooleanTF={#1}
{minted options={ %自动移除前置空白、制表为4字符、mathhe和||内的不处理
autogobble,tabsize=4,mathescape,escapeinside=||,
linenos,numberblanklines=false,numbersep=2pt,#2}}
{minted options={ %自动移除前置空白、制表为4字符、mathhe和||内的不处理
autogobble,tabsize=4,mathescape,escapeinside=||,
linenos,numberblanklines=false,numbersep=2pt}}}
\begin{document}
\begin{pylistings}
|$\sum_{x}^{2}$| #不处理
def prtmotto(n):
for i in range(0,n):
print("lift is short, i use Python!")
\end{pylistings}
\begin{pylistings}*[]
|$\sum_{x}^{2}$| #注意和上一个比较!
def prtmotto(n):
\end{pylistings}
\begin{pylistings}*[showspaces]
# test
def prtmotto(n):
for i in range(0,n):
print("lift is short, i use Python!")
\end{pylistings}
\end{document}
问题:
- "||"中的字符转义后,前后空一格
- 环境名后无参数,且代码第一行为注释语句时,注释语句会被当成参数而报错。仍旧能编译成功,但多出来一个"#"。可传递一个空参数,即
{pylisting}*[]。
可参考的处理方案
如果一个文档中包含了集中不同的程序语言,要高亮显示,可以参考如下方法:
\newcommand{\mynewminted}[3]{%
\newminted[#1]{#2}{#3}%
\tcbset{myminted/#1/.style={minted language=#2,minted options={#3}}}}
\mynewminted{mypylb}{python}{autogobble,mathescape,escapeinside=||,
linenos,numberblanklines=false,numbersep=2pt}
\newtcblisting{pylistings}[2][]{listing only,myminted/#2,#1}
%2 %用tcolorbox, breakable选项可跨页
\newminted[mypyc]{python}{autogobble,mathescape,escapeinside=||}
\newenvironment{mypy}[2][]
{%
\def\mypyenvironment{#1}%save the environments
\VerbatimEnvironment%
\begin{tcolorbox}[#2]%
\begin{\mypyenvironment}}%
{%
\end{\mypyenvironment}%
\end{tcolorbox}%
}
%% 用法
\begin{pylistings}{mypylb}
def fun(): #fanhui
return
\end{pylistings}
\begin{mypy}{mypyc}{}
def fun(): #fanhui
return
\end{mypy}
minipage不能跨页(page break),不用考虑。如果代码的第一行使用了“||”貌似有问题,看前面的例子。
{xparse}包
{xparse}的\NewDocumentCommand或\NewDocumentEnvironment的使用中,参数(arguments)分为两类:
- 强制性(mandatory)参数(找不到会报错),分别用字母“m,r,R,v,b”表示,在环境名后以大括号“{}”包围实参。
- 可选(optional)参数,分别用字母“o,d,O,D,s,t,e,E”表示,在环境名后以中括号“[]”包围实参。
- 大写的字母一般要求提供一个默认值,如
{s O{test} m}。 - 不是必须有强制性参数!强制性是参数设置的属性。可以设置2个可选参数。
- 如果要定义的参数不多,比较方便的是在其他参数前加s参数(BooleanTrue),后跟其他参数。测试中只用一个o参数会报错,但又不想用强制参数,所以前面加s,需要了加个星号后跟参数,不需要的话什么都不做。比较方便。
代码使用Jupyter Notebook样式
- 在Jupyter Notebook或QTconsole中输入代码,并保存为LaTeX文件。
- 从中找到“In :”和“Out:”的颜色。
- LaTeX文件中:定义颜色;代码前加“In :”或“Out:”,并添加颜色。
- 也可以之间在Jupyter Notebook中输入为Markdown,导出为LaTeX,然后调整样式。
- 这是看到:Mckinney2017、VanderPlas2017后想到的。
后记
学生实训,临时起意,给学生讲Python基础。先是用{listings},后来不满意。直接用{minted},又想控制部分代码的空格显示。用了{tcolorbox}后,还是想很好的控制空格显示,发现用网上的方法和自定义函数并不能令自己满意。看{tcolorbox}文档,接触{xparse}中的参数控制,形成了最后一个例子的结果。
记录上面过程,比较辛苦,但总归是有了两种以上的方法可供选择,这应该是好事!
参考文章
https://tex.stackexchange.com/questions/124657/combine-minted-and-tcolorbox
LaTeX中Python代码的语法高亮的更多相关文章
- 用 highlight.js 为文章中的代码添加语法高亮
来源:http://www.ghostchina.com/adding-syntax-highlighting-to-ghost-using-highlight-js/ --------------- ...
- Word中的代码怎样语法高亮
在平常我们粘贴代码到Word中的时候,经常会遇到代码粘贴到Word中后没有语法高亮,看着很乱很不友好,Word自带的样式---语法使用着也不尽人意, 网上有很多做法可以使得在插入在Word中的代码能够 ...
- 在 Microsoft Word 文档 中粘贴代码实现语法高亮的方法
1.下载notepad++. 2.将代码粘贴进notepad++,或者直接用notepad++打开. 3.点击顶栏 ===> 插件 ===> NppExport ===> cope ...
- latex中显示代码
如何在latex中添加代码模块 首先在开头导入以下的包 \usepackage{listings} \usepackage{ctex} % 用来设置附录中代码的样式 \lstset{ basicsty ...
- MWeb 1.5 发布!增加打字机滚动模式、发布到 Evernote、印象笔记、Wordpress.com、Blogger、编辑器内代码块语法高亮
打字机滚动模式(Typewriter Scrolling) 快捷键:CMD + Option + T,菜单:View - Typewriter Scrolling ,效果如下图: 发布到 Everno ...
- 在word中使用notepad++实现代码的语法高亮
转载自:http://blog.csdn.net/woohello/article/details/7621651 有时写文档时需要将代码粘贴到word中,但直接粘贴到word中的代码虽能保持换行与缩 ...
- 在html中写python代码的语法和特点-----基于webpy的httpserver
在html文件里写python语法的内容,的注意事项: 1:python程序中的变量通过以下方法传入到html: 1:通过全局变量 :全局变量是不须要用$def with语法实现传递的,仅仅要定义了 ...
- 在word中使用notepad++实现代码的语法高亮 分类: C_OHTERS 2013-09-22 10:38 2273人阅读 评论(0) 收藏
转载自:http://blog.csdn.net/woohello/article/details/7621651 有时写文档时需要将代码粘贴到word中,但直接粘贴到word中的代码虽能保持换行与缩 ...
- Qt中文本编辑器实现语法高亮功能(Qscitinlla)
Scintilla是一个免费.跨平台.支持语法高亮的编辑控件.它完整支持源代码的编辑和调试,包括语法高亮.错误指示.代码完成(code completion)和调用提示(call tips).能包含标 ...
随机推荐
- [SQL]as的是否可以省略的问题
数据库中as主要作用是起别名,常规来说都可以省略,但是为了增加可读性,不建议省略.
- PAT 甲级 1012 The Best Rank (25 分)(结构体排序)
题意: 为了评估我们第一年的CS专业学生的表现,我们只考虑他们的三个课程的成绩:C - C编程语言,M - 数学(微积分或线性代数)和E - 英语.同时,我们鼓励学生强调自己的最优秀队伍 - 也就是说 ...
- ABAP程序拆分JOB
[ZDQFI_601_JOB 调用 ZDQFI_601拆分JOB] data: name type tbtcjob-jobname. data: number type tbtcjob-jobcoun ...
- windows下gitee WEBHOOK的坑...
折腾到凌晨五点,依然没有实现 windows下 分支 push之后服务器自动部署 主要是因为GIT的helper的配置上的问题.最后果断放弃了,最后祭出大招,用 WINDONS命令行自动循环..60 ...
- 知识点整理-网络IO知识总结
UNIX 系统下的 I/O 模型有 5 种 同步阻塞 I/O.同步非阻塞 I/O.I/O 多路复用.信号驱动 I/O 和异步 I/O 什么是I/O 所谓的I/O 就是计算机内存与外部设备之间拷贝数据的 ...
- Flutter 常用组件
无状态组件(StatelessWidget)是不可变的,这意味着它的属性不能改变,所有的值都是最终的. 有状态组件(StatefulWidget)持有的状态可能在Widget生命周期中发生变化.实现一 ...
- PJzhang:ms17-010永恒之蓝漏洞在windows 2008R2中的复现
猫宁!!! 参考: https://www.anquanke.com/post/id/86245 https://xz.aliyun.com/t/2536 https://www.cnblogs.co ...
- 攻防世界WEB新手练习
0x01 view_source 0x02 get_post 这道题就是最基础的get和post请求的发送 flag:cyberpeace{b1e763710ff23f2acf16c2358d3132 ...
- 【并行计算与CUDA开发】英伟达硬件加速编解码
硬件加速 并行计算 OpenCL OpenCL API VS SDK 英伟达硬件编解码方案 基于 OpenCL 的 API 自己写一个编解码器 使用 SDK 中的编解码接口 使用编码器对于 OpenC ...
- Redis 根据Key模糊批量查询数据
前言 经常会有这样一种业务逻辑,就是需要根据Redis中Key的规则,模糊查询对应的数据,当数据量少时,利用常规的命令也能满足需求,但是数据量大时,就会导致堵塞,就算是采用不堵塞的函数,如果数据需要显 ...