[Tex/LaTex] How to highlight a freestanding regexp in string style

listings

I'm using listings to format a piece of JavaScript code, and I met a problem for the following code:

...
regex = /abc/;
...
ratio = 1.0/2.0;
...

I want the regex is highlighted as a string, but if I use the following definition, the division sign will be recognized as a beginning of a string:

\lstdefinelanguage{JavaScript}{
morekeywords={break,case,catch,continue,debugger,default,delete,do,else,finally,for,function,if,in,instanceof,new,return,switch,this,throw,try,typeof,var,void,while,with},
morekeywords=[2]{class,enum,export,extends,import,super,implements,interface,let,package,private,protected,public,static,yield},
morekeywords=[3]{prototype},
morestring=[b]{"},
morestring=[b]{'},
morestring=[b]{/},
morecomment=[l]{//},
morecomment=[s]{/*}{*/}
}

How can I fix this? Can I escape the division sign in some way?


Source here:

\documentclass{article}

\usepackage{tikz}
\usepackage{listings}

\begin{document}

\lstset{
basicstyle=\footnotesize\ttfamily\bfseries\color{cyan!50!black},
keywordstyle=\color{green!50!black},
keywordstyle=[2]\color{red!50!black},
stringstyle=\color{yellow!80!black},
commentstyle=\itshape\color{gray!50!white},
identifierstyle=\color{blue!80!white},
escapeinside={(*@}{@*)}}

\lstdefinelanguage{JavaScript}{
morekeywords={break,case,catch,continue,debugger,default,delete,do,else,finally,for,function,if,in,instanceof,new,return,switch,this,throw,try,typeof,var,void,while,with},
morekeywords=[2]{class,enum,export,extends,import,super,implements,interface,let,package,private,protected,public,static,yield},
morekeywords=[3]{prototype},
morestring=[b]{"},
morestring=[b]{'},
morestring=[b]{/},
morecomment=[l]{//},
morecomment=[s]{/*}{*/}}

\begin{lstlisting}[language=JavaScript]
function foo()
{
    // comments
    var regex = /abc/;
    var ratio = 1.0/2.0;
    return 0;
}
\end{lstlisting}

\end{document}

Best Answer

I can't think of a way that would allow you to do that without altering the original listing. What you can do is define custom delimiters that apply string style to their content, using

moredelim=[is][stringstyle]{<opening-delim>}{<closing-delim>}

The i in [is] means that those delimiters don't get printed in the output. Then surround all your regexp with those delimiters. That is kind of tedious, but I don't think you have any other option.

enter image description here

\documentclass{article}

\usepackage{tikz}
\usepackage{listings}

\begin{document}

\lstset{
basicstyle=\footnotesize\ttfamily\bfseries\color{cyan!50!black},
keywordstyle=\color{green!50!black},
keywordstyle=[2]\color{red!50!black},
stringstyle=\color{yellow!80!black},
commentstyle=\itshape\color{gray!50!white},
identifierstyle=\color{blue!80!white},
escapeinside={(*@}{@*)}}

\lstdefinelanguage{JavaScript}{
morekeywords={break,case,catch,continue,debugger,default,delete,do,else,finally,
  for,function,if,in,instanceof,new,return,switch,this,throw,try,typeof,var,void,while,with},
morekeywords=[2]{class,enum,export,extends,import,super,implements,interface,let,package,private,protected,public,static,yield},
morekeywords=[3]{prototype},
morestring=[b]{"},
morestring=[b]{'},
morecomment=[l]{//},
morecomment=[s]{/*}{*/},
moredelim=[is][stringstyle]{@<}{>@}, %<--- custom, invisible delimiters for highlighting ``unquoted'' strings
}

\begin{lstlisting}[language=JavaScript]
function foo()
{
    // comments
    var regex = @</abc/>@;
    var ratio = 1.0/2.0;
    return 0;
}
\end{lstlisting}

\end{document}