LaTeX中Python代碼的語法高亮

LaTeX中Python代碼的語法高亮

本文中,「{}」中的字母爲LaTeX或Python的包名,只有「Pygments」是Python的包,其餘都是LaTeX的包。html

LaTeX提供了功能豐富的包(package),以實現某些特定的排版功能。其中,{listings}包和{minted}包主要用於文檔中程序代碼語法的高亮顯示,支持常見的編程語言。python

  • {listings}基於內置或用戶提供的關鍵字高亮程序代碼語法,高亮的內容受限於關鍵詞的數量,代碼的着色功能也是有限。
  • {minted}使用Pymgent高亮程序代碼,提供了更多的高亮內容,基本相似在Jupyter Notebook或Jupyter Qtconsole中的代碼高亮。

使用{listings}包

{listings}的使用簡潔明瞭:shell

  • 在導言區加載包,並設置包選項。
  • 在文檔區使用\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}包。ide

{mdframed}和{tcolorbox}都是定製框(box)的包,前者要本身hacker,後者的已有功能十分豐富,且定製功能強大。{tcolorbox}提供了minted庫,經過以下形式之一使用:函數

  • \usepackage[minted]{tcolorbox}。自動加載{minted}包
  • 經過\tcbuselibrary加載
    \usepackage{tcolorbox}   
    \tcbuselibrary{minted}  %加載{minted}包

若是要定義新環境或命令,{tcolorbox}提供了以下命令:測試

  • \tcbset設置全部tcolorbox的參數。
  • tcolorboxtcblisting環境創建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中的宏):IfNoValueTFIfValueTFIfBooleanTF,注意用法。
  • 結合{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編譯爲例):ui

  • {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點:spa

  • 即便沒有參數,環境後也要有對中括號「[]」,不然會報錯(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,而後調整樣式。
  • 這是看到:Mckinney201七、VanderPlas2017後想到的。

後記

學生實訓,臨時起意,給學生講Python基礎。先是用{listings},後來不滿意。直接用{minted},又想控制部分代碼的空格顯示。用了{tcolorbox}後,仍是想很好的控制空格顯示,發現用網上的方法和自定義函數並不能令本身滿意。看{tcolorbox}文檔,接觸{xparse}中的參數控制,造成了最後一個例子的結果。

記錄上面過程,比較辛苦,但總歸是有了兩種以上的方法可供選擇,這應該是好事!

參考文章

https://tex.stackexchange.com/questions/124657/combine-minted-and-tcolorbox

相關文章
相關標籤/搜索