Como usar deletekeywords para remover palavras-chave do lstlisting?

Como usar deletekeywords para remover palavras-chave do lstlisting?

Estou tentando usar lstlistingalgum código Python com formato personalizado. O problema é que algumas palavras são reconhecidas como palavras-chave, embora eu não as queira como tal. Tentei usar o comando deletekeywordsmas sem sucesso.

A seguir está um documento mcve tex reproduzindo meu problema: as palavras applye hashserão exibidas em azul, cor atribuída às palavras-chave.

\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}

Responder1

O arquivo lstlang1.sty(use o comando kpsewhich lstlang1.stypara encontrá-lo) contém a definição das linguagens Python para listings. As palavras-chave são definidas em dois grupos:

  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},%

As palavras-chave applye hashestão no segundo grupo. Para excluí-los, você deve usar:

deletekeywords=[2]{hash,apply},

Aqui está o seu MWE corrigido (com uma vírgula no final docadachave):

\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}

insira a descrição da imagem aqui

Responder2

Bem, acho que sei qual é o seu problema. Você acha que "deletekeywords" exclui uma palavra-chave predefinida, mas na verdade exclui uma palavra-chave da lista personalizada que você criou em "morekeywords".

Infelizmente, a única coisa que funcionaria para mim seria definir um estilo personalizado para Python do zero, usando o que você já possui. Em seguida, você deve adicionar manualmente as palavras-chave desejadas em “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}}

Então, para usar este estilo, use

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

Provavelmente não é o melhor, mas deve funcionar enquanto alguém tiver uma resposta melhor.

informação relacionada