在 lstlisting 中自动着色函数、方法和属性

在 lstlisting 中自动着色函数、方法和属性

我目前正在为我的 CS 课程准备一些材料,由于我使用 VSCode,所以我的目标是能够在 LaTeX 中忠实地重现 VSCode 中使用的颜色主题。

为此,我编写了一种 lstlisting 语言,它可以很好地完成这项工作(无论是明暗主题),如下面的图片所示。

左图:VSCode 原图右图:我的 LateX 输出

原来的乳胶

不幸的是有些事情还不够理想:

  1. 我必须手动添加函数名称(放入更多关键字中)才能正确着色
  2. 除非我指定整个 object.method 或者进行一些“黑客攻击”以便在它们前面放置一个空格和一个负 hspace,否则方法(类的)是不会着色的。

有办法解决这些问题吗?

理想情况下,我希望使用正则表达式来利用函数通常后面跟着一个左括号“(”这一事实来为它们着色,但我还没有设法利用这一点来发挥我的优势。

提前谢谢了

编辑

此代码定义样式并包含 MWE

\documentclass{standalone}
%Style definition
\usepackage{tikz}
\usepackage{listings}
\usepackage{setspace} 

%light colors
\newcommand{\light}{
\definecolor{Numbers}{RGB}{0,137,84}
\definecolor{Definitions}{RGB}{0,0,255}
\definecolor{Functions}{RGB}{126,93,23}
\definecolor{Variables}{RGB}{0,17,134}
\definecolor{Comments}{RGB}{0,100,0}
\definecolor{Strings}{RGB}{178,0,2}
\definecolor{Operators}{RGB}{0,0,0}
\definecolor{BaseFunctions}{RGB}{192,0,227}
\definecolor{Bakgroung}{RGB}{255,255,255}
\definecolor{ColumnNumber}{RGB}{0,122,150}
\definecolor{ExtraBaseFunctions}{RGB}{0,129,156}
}
%dark colors
\newcommand{\dark}{
\definecolor{Numbers}{RGB}{175,207,164}
\definecolor{Definitions}{RGB}{56,158,219}
\definecolor{Functions}{RGB}{220,220,164}
\definecolor{Variables}{RGB}{136,222,255}
\definecolor{Comments}{RGB}{0,100,0}
\definecolor{Strings}{RGB}{217,142,115}
\definecolor{Operators}{RGB}{212,212,212}
\definecolor{BaseFunctions}{RGB}{208 130,196}
\definecolor{Bakgroung}{RGB}{30,30,30}
\definecolor{ColumnNumber}{RGB}{133,133,133}
\definecolor{ExtraBaseFunctions}{RGB}{0,204,157}
}
\dark
\lstdefinelanguage{Python}{ 
alsoletter={.,*},
numbers=left, 
numberstyle=\footnotesize, 
numbersep=1em, 
xleftmargin=1em, 
framextopmargin=2em, 
framexbottommargin=2em, 
showspaces=false, 
showtabs=false, 
showstringspaces=false, 
%frame=l, 
tabsize=4, 
framesep=4.5mm,
framexleftmargin=2.5mm,
fillcolor=\color{Bakgroung},
numberstyle=\ttfamily\small\color{ColumnNumber},
% Basic 
basicstyle=\ttfamily\small\color{Variables}\setstretch{1}, 
backgroundcolor=\color{Bakgroung}, 
% Comments 
commentstyle=\color{Comments},%\slshape, 
% Strings 
stringstyle=\color{Strings},
%functionstyle = \color{FunctionName}, 
morecomment=[s][\color{Strings}]{'}{'}, 
morecomment=[s][\color{Strings}]{'''}{'''}, 
morecomment=[s][\color{Strings}]{"""}{"""}, 
% keywords 
morekeywords={import,from,for,while,if,is,in,elif,else,print,break,continue,return,access,as,del,except,exec,finally,global,import,lambda,pass,print,raise,try,assert}, 
keywordstyle={\color{BaseFunctions}\bfseries}, 
% additional keywords 
morekeywords={[2]@invariant,def,class,numpy,np,scipy,*,True,False,None,not,and,or}, 
keywordstyle={[2]\color{Definitions}\bfseries}, 
% additional keywords 3
morekeywords={[3]@invariant,__init__,len,max,min}, 
keywordstyle={[3]\color{Functions}\bfseries}, 
% additional keywords 4
morekeywords={[4]@invariant,int,float,str,list,tuple,range,tkinter,tk,Tk, Obj}, 
keywordstyle={[4]\color{ExtraBaseFunctions}\bfseries}, 
%emph={self},  
%moredelim=*[s][\color{red}]{def}{(},
literate=*%
{:}{{{\color{Operators}:}}}{1}%
{=}{{{\color{Operators}=}}}{1}%
{-}{{{\color{Operators}-}}}{1}%
{+}{{{\color{Operators}+}}}{1}%
{\%}{{{\color{Operators}\%}}}{1}%
{*}{{{\color{Operators}*}}}{1}%
{**}{{{\color{Operators}{**}}}}2%
{/}{{{\color{Operators}/}}}{1}%
{//}{{{\color{Operators}{//}}}}2%
{!}{{{\color{Operators}!}}}{1}%
{(}{{{\color{Operators}(}}}{1}%
{\{}{{{\color{Operators}\{}}}{1}%
{\}}{{{\color{Operators}\}}}}{1}%
{)}{{{\color{Operators})}}}{1}%
{[}{{{\color{Operators}[}}}{1}%
{]}{{{\color{Operators}]}}}{1}%
{<}{{{\color{Operators}<}}}{1}%
{>}{{{\color{Operators}>}}}{1}%
{,}{{{\color{Operators},}}}{1}%
{0}{{{\color{Numbers}0}}}1%
{1}{{{\color{Numbers}1}}}1%
{2}{{{\color{Numbers}2}}}1%
{3}{{{\color{Numbers}3}}}1%
{4}{{{\color{Numbers}4}}}1%
{5}{{{\color{Numbers}5}}}1%
{6}{{{\color{Numbers}6}}}1%
{7}{{{\color{Numbers}7}}}1%
{8}{{{\color{Numbers}8}}}1%
{9}{{{\color{Numbers}9}}}1,
} 

%Now to use it as in the MWE
\begin{document}
\begin{lstlisting}[language={Python}, escapechar=|,
morekeywords={[5]@invariant,fun}, keywordstyle={[5]\color{Functions}\bfseries}]
class Obj():
    def __init__(self):
        self.something = None

    def fun(self, nums):
        for x in range(len(nums)):
            if x != 12:
                return x
        
x = Obj()
x.fun()
\end{lstlisting}
\end{document}

相关内容