如何使用 deletekeywords 从 lstlisting 中删除关键字?

如何使用 deletekeywords 从 lstlisting 中删除关键字?

我正在尝试使用lstlisting一些具有自定义格式的 Python 代码。问题是有些单词被识别为关键字,尽管我并不想这样。我尝试使用该命令,deletekeywords但没有成功。

以下是重现我的问题的 mcve tex 文档:单词applyhash将显示为蓝色,即分配给关键字的颜色。

\documentclass[12pt, letterpaper]{article}
\usepackage{listings}
\usepackage[dvipsnames,table,xcdraw]{xcolor}

\begin{document}

\lstset{language=Python,
    tabsize=4,
    %frame=lines,
    caption={Python function to split between train and test sets.},
    label={lst:code_direct},
    literate={~} {$\sim$}{1},
   backgroundcolor=\color{white},   % choose the background color; you must add \usepackage{color} or \usepackage{xcolor}
  basicstyle=\footnotesize,               % the size of the fonts that are used for the code
  breakatwhitespace=false,              % sets if automatic breaks should only happen at whitespace
  %breaklines=true,                                 % sets automatic line breaking
  captionpos=b,                                 % sets the caption-position to bottom
  commentstyle=\color{gray}\textit,    % comment style
  %  deletekeywords={hash},                 % if you want to delete keywords from the given language
  escapeinside={\%*}{*)},               % if you want to add LaTeX within your code
  extendedchars=true,                   % lets you use non-ASCII characters; for 8-bits encodings only, not work with UTF-8
  frame=tb,                                     % adds a frame around the code
  keepspaces=true,                          % keeps spaces in text, useful for keeping indentation of code (possibly needs    columns=flexible)
  keywordstyle=\color{blue}\bfseries,       % keyword style
  language=Python,                          % the language of the code (can be overrided per snippet)
  %otherkeywords={*,...},                       % if you want to add more keywords to the set
  numbers=left,                                 % where to put the line-numbers; possible values are (none, left, right)
  numbersep=5pt,                            % how far the line-numbers are from the code
  numberstyle=\tiny\color{gray}, % the style that is used for the line-numbers
  rulecolor=\color{black},              % if not set, the frame-color may be changed on line-breaks within not-black text (e.g. comments (green here))
  showspaces=false,                         % show spaces everywhere adding particular underscores; it overrides 'showstringspaces'
  showstringspaces=false,               % underline spaces within strings only
  showtabs=false,                           % show tabs within strings adding particular underscores
  stepnumber=1,                             % the step between two line-numbers. If it's 1, each line will be numbered
  stringstyle=\ttb\color{red},  % string literal style
  tabsize=2,                                        % sets default tabsize to 2 spaces
  title=\lstname,                               % show the filename of files included with \lstinputlisting; also try caption instead of title
  columns=fixed,                            % Using fixed column width (for e.g. nice alignment)
  emph ={split_train_test_by_id, test_set_check},
  emphstyle=\color{red},
  morekeywords={split_train_test_by_id}  
  deletekeywords={hash,apply}
}

\begin{lstlisting}
def split_train_test_by_id(data, test_ratio, id_column, 
                hash=hashlib.md5):
    ids = data[id_column];
    in_test_set = ids.apply(lambda _id: test_set_check(_id, 
                                test_ratio, hash));
    return data.loc[~in_test_set], data.loc[in_test_set];

# The check on the id is to see the value of the last byte
# If this value is less then test_ratio*256 (assuming uniform 
# distribution) 
# then will return true otherwise false. The fraction of true
# will be  equal to test_ratio
def test_set_check(identifier, test_ratio, hash):
    limit = test_ratio*256; #1byte
     #digest will calculate the hash value 
    res = hash(np.int64(identifier)).digest()[-1];
    return res<limit;
\end{lstlisting}

\end{document}

答案1

该文件lstlang1.sty(使用命令kpsewhich lstlang1.sty找到它)包含 Python 语言的定义listings。关键字分为两组:

  morekeywords={access, and, break, class, continue, def, del, elif, else,%
    except, exec, finally, for, from, global, if, import, in, is, lambda,%
    not, or, pass, print, raise, return, try, while},%
  % Built-ins
  morekeywords=[2]{abs, all, any, basestring, bin, bool, bytearray,%
    callable, chr, classmethod, cmp, compile, complex, delattr, dict, dir,%
    divmod, enumerate, eval, execfile, file, filter, float, format,%
    frozenset, getattr, globals, hasattr, hash, help, hex, id, input, int,%
    isinstance, issubclass, iter, len, list, locals, long, map, max,%
    memoryview, min, next, object, oct, open, ord, pow, property, range,%
    raw_input, reduce, reload, repr, reversed, round, set, setattr, slice,%
    sorted, staticmethod, str, sum, super, tuple, type, unichr, unicode,%
    vars, xrange, zip, apply, buffer, coerce, intern},%

apply关键字hash位于第二组中。要删除它们,必须使用:

deletekeywords=[2]{hash,apply},

这是你更正后的 MWE(末尾有一个逗号每个钥匙):

\documentclass[12pt, letterpaper]{article}
\usepackage{listings}
\usepackage[dvipsnames,table,xcdraw]{xcolor}

\begin{document}

\lstset{language=Python,
    tabsize=4,
    %frame=lines,
    caption={Python function to split between train and test sets.},
    label={lst:code_direct},
    literate={~} {$\sim$}{1},
   backgroundcolor=\color{white},   % choose the background color; you must add \usepackage{color} or \usepackage{xcolor}
  basicstyle=\footnotesize,               % the size of the fonts that are used for the code
  breakatwhitespace=false,              % sets if automatic breaks should only happen at whitespace
  %breaklines=true,                                 % sets automatic line breaking
  captionpos=b,                                 % sets the caption-position to bottom
  commentstyle=\color{gray}\textit,    % comment style
  %  deletekeywords={hash},                 % if you want to delete keywords from the given language
  escapeinside={\%*}{*)},               % if you want to add LaTeX within your code
  extendedchars=true,                   % lets you use non-ASCII characters; for 8-bits encodings only, not work with UTF-8
  frame=tb,                                     % adds a frame around the code
  keepspaces=true,                          % keeps spaces in text, useful for keeping indentation of code (possibly needs    columns=flexible)
  keywordstyle=\color{blue}\bfseries,       % keyword style
  language=Python,                          % the language of the code (can be overrided per snippet)
  %otherkeywords={*,...},                       % if you want to add more keywords to the set
  numbers=left,                                 % where to put the line-numbers; possible values are (none, left, right)
  numbersep=5pt,                            % how far the line-numbers are from the code
  numberstyle=\tiny\color{gray}, % the style that is used for the line-numbers
  rulecolor=\color{black},              % if not set, the frame-color may be changed on line-breaks within not-black text (e.g. comments (green here))
  showspaces=false,                         % show spaces everywhere adding particular underscores; it overrides 'showstringspaces'
  showstringspaces=false,               % underline spaces within strings only
  showtabs=false,                           % show tabs within strings adding particular underscores
  stepnumber=1,                             % the step between two line-numbers. If it's 1, each line will be numbered
  stringstyle=\ttb\color{red},  % string literal style
  tabsize=2,                                        % sets default tabsize to 2 spaces
  title=\lstname,                               % show the filename of files included with \lstinputlisting; also try caption instead of title
  columns=fixed,                            % Using fixed column width (for e.g. nice alignment)
  emph ={split_train_test_by_id, test_set_check},
  emphstyle=\color{red},
  morekeywords={split_train_test_by_id}, % comma added!
  deletekeywords=[2]{hash,apply},        % [2] and comma added!
}

\begin{lstlisting}
def split_train_test_by_id(data, test_ratio, id_column, 
                hash=hashlib.md5):
    ids = data[id_column];
    in_test_set = ids.apply(lambda _id: test_set_check(_id, 
                                test_ratio, hash));
    return data.loc[~in_test_set], data.loc[in_test_set];

# The check on the id is to see the value of the last byte
# If this value is less then test_ratio*256 (assuming uniform 
# distribution) 
# then will return true otherwise false. The fraction of true
# will be  equal to test_ratio
def test_set_check(identifier, test_ratio, hash):
    limit = test_ratio*256; #1byte
     #digest will calculate the hash value 
    res = hash(np.int64(identifier)).digest()[-1];
    return res<limit;
\end{lstlisting}

\end{document}

在此处输入图片描述

答案2

嗯,我想我知道你的问题是。你认为“deletekeywords”删除了一个预定义的关键字,但实际上删除了你在“morekeywords”中创建的自定义列表中的关键字。

不幸的是,对我而言唯一可行的方法是使用已有的样式从头开始为 Python 定义自定义样式。然后,您应该在“morekeywords”中手动添加所需的关键字。

\lstdefinestyle{pythoncode}{
language={}, %You shall leave this blank 
tabsize=4,
caption={Python function to split between train and test sets.},
label={lst:code_direct},
literate={~} {$\sim$}{1},
backgroundcolor=\color{white},   
basicstyle=\footnotesize,        
breakatwhitespace=false,     
captionpos=b,
morecomment=[l]{##},   
commentstyle=\color{gray}\textit,  
escapeinside={\%*}{*)},            
  extendedchars=true,
  frame=tb, 
  keepspaces=true,
  keywordstyle=\color{blue}\bfseries,  
  morekeywords={return,def,apply,lambda}, %New keywords
  numbers=left,
  numbersep=5pt,
  numberstyle=\tiny\color{gray}, 
  rulecolor=\color{black},       
  showspaces=false, 
  showstringspaces=false,
  showtabs=false,       
  stepnumber=1, 
  stringstyle=\ttb\color{red},
  tabsize=2,                  
  title=\lstname,             
  columns=fixed,
  emph ={split_train_test_by_id, test_set_check},
  emphstyle=\color{red}}

然后,要使用这种风格,请使用

\begin{lstlisting}[style=pythoncode]
 **Your Python Code here**
\end{lstlisting}

它可能不是最好的,但当有人能找到更好的答案时,它应该能起到作用。

相关内容