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.
minted
package overleaf.com/learn/latex/Code_Highlighting_with_mintedminted
needs to be run with-shell-escape
, and that's a big issue.