Я пытаюсь использовать lstlisting
для некоторого кода Python с пользовательским форматом. Проблема в том, что некоторые слова распознаются как ключевые слова, хотя я не хочу, чтобы они были таковыми. Я пытался использовать команду, deletekeywords
но безуспешно.
Ниже приведен документ mcve tex, воспроизводящий мою проблему: слова apply
и hash
будут отображаться синим цветом, назначенным ключевым словам.
\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}
Возможно, это не лучший вариант, но он должен сработать, пока кто-нибудь не придумает лучший ответ.