The problem:
Is it possible to highlight all the numbers inside a lstenvironment except the numbers in comments, strings or variable names?
Example of expected output (Python in Google Colaboratory):
What I have tried:
Using How can I change the color of digits when using the listings package? I've managed to highlight the numbers this way:
In particular, I thought I had found the solution in the listings package:
literate = [*]<replacement item>. . .<replacement item>First note that there are no commas between the items. Each item consists of three arguments:
{<replace>}{<replacement text>}{<length>}.<replace>is the original character sequence. Instead of printing these characters, we use<replacement text>, which takes the width of<length>characters in the output.[...]
The optional star indicates that literate replacements should not be made in strings, comments, and other delimited text.
Because of using the star: \literate=* numbers inside strings and comments are not being colored, that's nice, but numbers in the name of variables are being colored. I have read a lot of answers about highlight numbers using listings but none of them satisfy my requirement.
I think it will be possible to programming that "every number inside my lstenvironment should be colored except the ones preceded by letter or not colored number", but I'm not sure, and I do not know where to start.
Possible duplicates that do not work for me:
- Not viable but useful answers
Add:
alsoletter=0123456789,
keywords={[4]@invariant,0,1,2,3,4,5,6,7,8,9},
keywordstyle={[4]\color{greenpy}}
to the definition of mypy (the lststyle I defined).
This will work only if I add manually all the numbers appearing in my code as keywords (and . in decimal numbers wouldn't be colored).
- Gonzalo Medina's answer here: listing package: colored numbers, but not colored in variable names
Adding to lstset: literate=*{number}{{{\color{greenpy}number}}}1 and escapeinside={!!}
- karlkoeller answer here: Listings: recognize numbers and `1e-3`
2 and 3 will work only if I enclose (with some escape sign, using escapeinside) manually all the numbers appearing in my code.
I can't use neither of this solutions because I have lots of code.
- Answers that don't respond to my question.
MWE:
\documentclass{article}
\DeclareFixedFont{\ttm}{T1}{txtt}{m}{n}{10} % It will be the basic font style
\usepackage{xcolor}
\definecolor{purpy}{rgb}{0.769,0.02,0.894} % Custom highlighting colors
\definecolor{bluepy}{rgb}{0.082,0.02,1}
\definecolor{brownpy}{rgb}{0.557,0.388,0.184}
\definecolor{greenpy}{rgb}{0.118,0.553,0.388}
\definecolor{strpy}{rgb}{0.796,0.102,0.118}
\definecolor{commentpy}{rgb}{0.024,0.514,0.078}
\definecolor{Background}{rgb}{0.9,0.95,0.95}
\usepackage{listings}
\lstdefinestyle{mypy}{ %My Python style definition (based on Google Colaboratory)
language=Python,
numbers=left,
numberstyle=\footnotesize,
numbersep=1em,
xleftmargin=1em,
framextopmargin=2em,
framexbottommargin=2em,
showspaces=false,
showtabs=false,
showstringspaces=false,
columns=flexible,
keepspaces=true,
tabsize=4,
basicstyle=\ttm,
backgroundcolor=\color{Background},
keywords={as,assert,async,await,break,continue,del,elif,else,except,finally,for,from,if,import,pass,raise,return,try,while,with,yield},
keywordstyle={\ttm\color{purpy}},
keywords={[2]@invariant,False,None,True,and,class,def,global,in,is,lambda,nonlocal,not,or},
keywordstyle={[2]\ttm\color{bluepy}},
keywords={[3]@invariant,abs,all,any,ascii,bin,bool,bytearray,bytes,callable,chr,classmethod,compile,complex,delattr,dict,dir,divmod,enumerate,eval,exec,filter,float,format,frozenset,getattr,globals,hasattr,hash,help,hex,id,input,int,isinstance,issubclass,iter,len,list,locals,map,max,memoryview,min,next,object,oct,open,ord,pow,print,property,range,repr,reversed,roundset,setattr,slice,sorted,@staticmethod,str,sum,super,tuple,type,vars,zip, myfun}, % myfun should be brown in its definition
keywordstyle={[3]\ttm\color{brownpy}},
stringstyle=\color{strpy},
commentstyle=\color{commentpy},
%
literate=
*{0}{{{\color{greenpy}0}}}1 % Coloring all the digits
{1}{{{\color{greenpy}1}}}1
{2}{{{\color{greenpy}2}}}1
{3}{{{\color{greenpy}3}}}1
{4}{{{\color{greenpy}4}}}1
{5}{{{\color{greenpy}5}}}1
{6}{{{\color{greenpy}6}}}1
{7}{{{\color{greenpy}7}}}1
{8}{{{\color{greenpy}8}}}1
{9}{{{\color{greenpy}9}}}1
{.0}{{{\color{greenpy}.0}}}2
{.1}{{{\color{greenpy}.1}}}2
{.2}{{{\color{greenpy}.2}}}2
{.3}{{{\color{greenpy}.3}}}2
{.4}{{{\color{greenpy}.4}}}2
{.5}{{{\color{greenpy}.5}}}2
{.6}{{{\color{greenpy}.6}}}2
{.7}{{{\color{greenpy}.7}}}2
{.8}{{{\color{greenpy}.8}}}2
{.9}{{{\color{greenpy}.9}}}2
{e+}{{{\color{greenpy}e+}}}2
{e-}{{{\color{greenpy}e-}}}2
}
% Displaying minus symbol properly
\makeatletter
\lst@CCPutMacro
\lst@ProcessOther{"2D}{\lst@ttfamily{-{}}{-}}
@empty\z@@empty
\makeatother
% Desired environment definition
\lstnewenvironment{python}[1][]{
\lstset{style=mypy, frame=l, numbers=none}
}{}
\begin{document}
\begin{python}
def myfun(a11,a12):
return a11-a12+15+0.35;
print("H3ll0 W0rld")
\end{python}
\end{document}
Extra question:
Is it possible to highlight every function name automatically? (But just in its definition) Every word between def and (, just like def myfun(a11,a12):
In the example above, everytime I call myfun, its name will be displayed brown, and it is supposed to be highlighted just in its definition.



mintedpackage https://www.overleaf.com/learn/latex/Code_Highlighting_with_minted – Alan Xiang May 10 '21 at 02:50mintedneeds to be run with-shell-escape, and that's a big issue. – Blooment May 10 '21 at 07:39finalizecacheandfrozencacheoptions ofminted? Might be a possibility to avoid-shell-escape. – Linear Christmas May 10 '21 at 10:34listings. That's why I'm looking for a detailed answer that complement my post, not another different solution. But thanks for your help. – Blooment May 10 '21 at 16:25mintedonly a couple of times, and exclusively withshell-escape(my personal, small documents). From what I gather, if you usemintedwithfinalizecacheandfrozencache, thenPygments/Pythonare *not* used at all. But you might lose some options you require fromminted, or lose a degree of freedom. I do not know anything in depth, this is from a cursory look at the documentation. Good luck with your question, however! – Linear Christmas May 10 '21 at 17:15listingsdeprecated? – hola May 11 '21 at 12:35mintedworks because Pygments contains a syntax parser that distinguishes variable names, number literals, strings, etc. Thelistingspackage is unable to do this, it doesn't have a powerful syntax parser, which means a generic solution is essentially impossible. If you only have just several short code snippets, I would recommend using theescapeinsidefeature to color them manually. If you are looking for a pure LaTeX solution, you need to write a Python parser in LaTeX. – Alan Xiang May 13 '21 at 05:51columns=flexible+keepspaces=truethat allows you to copy the source from pdf without losing the indentation. 2º Customize a pygments.style is way hard than modifylistingsoptions (e.g. to add new keywords you would need to write your own lexer. It would be such a pain trying to declare different styles of keywords, and the listo go on). – Blooment May 13 '21 at 10:59mintednow and customization is way way hard thanlistings. – Blooment May 13 '21 at 11:01