zoukankan      html  css  js  c++  java
  • LaTeX中Python代码的语法高亮

    LaTeX中Python代码的语法高亮

    本文中,“{}”中的字母为LaTeX或Python的包名,只有“Pygments”是Python的包,其他都是LaTeX的包。

    LaTeX提供了功能丰富的包(package),以实现某些特定的排版功能。其中,{listings}包和{minted}包主要用于文档中程序代码语法的高亮显示,支持常见的编程语言。

    • {listings}基于内置或用户提供的关键字高亮程序代码语法,高亮的内容受限于关键词的数量,代码的着色功能也是有限。
    • {minted}使用Pymgent高亮程序代码,提供了更多的高亮内容,基本类似在Jupyter Notebook或Jupyter Qtconsole中的代码高亮。

    使用{listings}包

    {listings}的使用简洁明了:

    • 在导言区加载包,并设置包选项。
    • 在文档区使用egin{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}	
    
    ewcommand{emptyaccsupp}[1]{BeginAccSupp{ActualText={}}#1EndAccSupp{}}
    
    usepackage{listings}
    lstset{						%高亮代码设置
    	language=python, 					%Python语法高亮
    	linewidth=0.9linewidth,      		%列表list宽度
    	%basicstyle=	tfamily,				%tt无法显示空格
    	commentstyle=color{commentcolor},	%注释颜色
    	keywordstyle=color{keywordcolor},	%关键词颜色
    	stringstyle=color{stringcolor},	%字符串颜色
    	%showspaces=true,					%显示空格
    	numbers=left,						%行数显示在左侧
    	numberstyle=	inyemptyaccsupp,		%行数数字格式
    	numbersep=5pt,						%数字间隔
    	frame=single,						%加框
    	framerule=0pt,						%不划线
    	escapeinside=@@,					%逃逸标志
    	emptylines=1,						%
    	xleftmargin=3em,					%list左边距
    	backgroundcolor=color{backcolor},	%列表背景色
    	tabsize=4,							%制表符长度为4个字符
    	gobble=4							%忽略每行代码前4个字符
    	}
    
    egin{document}
    这是Python语法高亮
    
    egin{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}包
    • 通过 cbuselibrary加载
      usepackage{tcolorbox}   
      	cbuselibrary{minted}  %加载{minted}包
      

    如果要定义新环境或命令,{tcolorbox}提供了如下命令:

    • cbset设置所有tcolorbox的参数。
    • tcolorboxtcblisting环境建立box或列表list。
    • ewtcblisting ewtcbinputlisting创建新的列表环境(tcblisting)或宏。
    • ewtcolorbox ewtcbox创建新的tcolorbox环境或宏。
    • DeclareTCBListingNewTCBListing创建有一个可选参数的列表(还是要2个以上的参数)。需要加载{xparse,listings},但是{minted}应该在{listings}的后面,否则会覆盖minted选项的设置。
      usepackage[xparse,listings,minted]{tcolorbox}  
      或  
      	cbuselibrary{xparse,listings,minted}  
      
    • 加载{xparse}后,选项中可以使用逻辑选项(对应xparse中的宏):IfNoValueTFIfValueTFIfBooleanTF,注意用法。
    • 结合{minted}的 ewminted命令,可以方便定制基于{minted}的语法高亮。
    • {minted}内部使用了{fancyvrb},要定义新的minted环境,必须包含命令VerbatimEnvironment,如下定义了cpp代码环境(minted.pdf,P30):
      
      ewminted{cpp}{gobble=2,linenos}  
      
      ewenvironment{env}  
         {VerbatimEnvironmentegin{cppcode}}  
         {end{cppcode}}  
      
    • ewtcblistingDeclareTCBListing等创建的列表不需要如此!

    编译过程注意以下几点(以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%的正文宽度
    
    ewtcblisting{pylistings}[1][]{
        frame empty,size=minimal,breakable,center,width=0.9linewidth,
    	listing only, 
    	minted language=python,
    	minted options={ %自动移除前置空白、制表为4字符、mathhe和||内的不处理
    		autogobble,tabsize=4,mathescape,escapeinside=||,
    		linenos,numberblanklines=false,numbersep=2pt,#1}}
    
    egin{document}
    
    egin{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}
    
    egin{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}
    
    	cbset{pycode/.style={
    	frame empty,size=minimal,breakable,center,width=0.9linewidth,
    	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}}}
    
    egin{document}
    
    egin{pylistings}
    	|$sum_{x}^{2}$| #不处理
    	def prtmotto(n):
    		for i in range(0,n):
    			print("lift is short, i use Python!")
    end{pylistings}
    
    egin{pylistings}*[]
    	|$sum_{x}^{2}$| #注意和上一个比较!
    	def prtmotto(n):
    end{pylistings}
    
    egin{pylistings}*[showspaces]
    	# test
    	def prtmotto(n):
    		for i in range(0,n):
    			print("lift is short, i use Python!")
    end{pylistings}
    end{document}
    

    问题

    • "||"中的字符转义后,前后空一格
    • 环境名后无参数,且代码第一行为注释语句时,注释语句会被当成参数而报错。仍旧能编译成功,但多出来一个"#"。可传递一个空参数,即{pylisting}*[]

    可参考的处理方案

    如果一个文档中包含了集中不同的程序语言,要高亮显示,可以参考如下方法:

    
    ewcommand{mynewminted}[3]{%
    	
    ewminted[#1]{#2}{#3}%
    		cbset{myminted/#1/.style={minted language=#2,minted options={#3}}}}
    
    mynewminted{mypylb}{python}{autogobble,mathescape,escapeinside=||,
    					linenos,numberblanklines=false,numbersep=2pt}
    
    
    ewtcblisting{pylistings}[2][]{listing only,myminted/#2,#1}
    
    %2 %用tcolorbox, breakable选项可跨页
    
    ewminted[mypyc]{python}{autogobble,mathescape,escapeinside=||} 
    
    ewenvironment{mypy}[2][]
    {% 
    	defmypyenvironment{#1}%save the environments
    	VerbatimEnvironment%
    	egin{tcolorbox}[#2]%
    		egin{mypyenvironment}}%
    		{%
    		end{mypyenvironment}%
    	end{tcolorbox}%
    }
    
    %% 用法
    egin{pylistings}{mypylb}
    def fun():  #fanhui
       return   
    end{pylistings}
    
    egin{mypy}{mypyc}{}
    def fun():  #fanhui
       return  
    end{mypy}
    

    minipage不能跨页(page break),不用考虑。如果代码的第一行使用了“||”貌似有问题,看前面的例子。

    {xparse}包

    {xparse}的NewDocumentCommandNewDocumentEnvironment的使用中,参数(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

  • 相关阅读:
    Git Cannot rebase: You have unstaged changes.
    importError: DLL load failed when import matplotlib.pyplot as plt
    install tushare in python 3.6
    pd.qcut, pd.cut, df.groupby()等在分组和聚合方面的应用
    从池子里的beta看秋香, 个性迥异
    个股和股票池的beta系数的估算
    检验两个随机序列的beta系数
    spyder里的"查找文件里的特定字符串"非常方便
    地图上道路编号中的G S X Y
    场内的代码表, 感觉水很深
  • 原文地址:https://www.cnblogs.com/ourweiguan/p/11827524.html
Copyright © 2011-2022 走看看