Edit: easier more robust method described here. Original answer below.
You can set the colors to custom commands like commentstyle=\mycommentcolor
instead of directly using commentstyle=\color{colorname}
, and then you can switch the definition of the commands during the listing using escapeinside
.
MWE:
\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}
\begin{document}
\def\setallcolors{%
\gdef\mybasiccolor{\color{black}}%
\gdef\mykwcolor{\color{blue}}%
\gdef\myndkwcolor{\color{darkgray}}%
\gdef\myidcolor{\color{black}}%
\gdef\mycommentcolor{\color{purple}}%
\gdef\mystringcolor{\color{red}}%
}
\def\setallgray{%
\gdef\mybasiccolor{\color{gray}}%
\gdef\mykwcolor{\color{gray}}%
\gdef\myndkwcolor{\color{gray}}%
\gdef\myidcolor{\color{gray}}%
\gdef\mycommentcolor{\color{gray}}%
\gdef\mystringcolor{\color{gray}}%
}
\setallcolors
\lstdefinelanguage{JavaScript}{
basicstyle=\mybasiccolor,
keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, let, if, in, while, do, else, case, break},
keywordstyle=\mykwcolor\bfseries,
ndkeywords={class, export, boolean, throw, implements, import, this},
ndkeywordstyle=\myndkwcolor\bfseries,
identifierstyle=\myidcolor,
sensitive=false,
comment=[l]{//},
morecomment=[s]{/*}{*/},
commentstyle=\mycommentcolor\ttfamily,
stringstyle=\mystringcolor\ttfamily,
morestring=[b]',
morestring=[b]"
}
\lstset{numbers=left,escapeinside={(*@}{@*)}}
Let's create variables:
\begin{lstlisting}[language=JavaScript,name=Variables]
let msg = "Hello";
let name = "Jody";
\end{lstlisting}
And then add the method for printing:
\begin{lstlisting}[language=JavaScript,name=Printing]
(*@\setallgray@*)let msg = "Hello";
let name = "Jody";
(*@\setallcolors@*)// My first hack
console.log(msg + " " + name);
\end{lstlisting}
\end{document}
Result same as in the original answer below.
Original answer:
A possible approach is to define two languages, one in color or black and one in gray, and switch between these two. Some tricks are needed to make them appear as one listing, for example setting aboveskip
and belowskip
if needed, and resuming line numbers. The language definition is adapted from language option supported in listings. Alternatively you could try something like Automatic background coloring in listings using tikzmark or http://www.texample.net/tikz/examples/tikz-listings/.
MWE:
\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}
\begin{document}
\lstdefinelanguage{JavaScript}{
keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, let, if, in, while, do, else, case, break},
keywordstyle=\color{blue}\bfseries,
ndkeywords={class, export, boolean, throw, implements, import, this},
ndkeywordstyle=\color{darkgray}\bfseries,
identifierstyle=\color{black},
sensitive=false,
comment=[l]{//},
morecomment=[s]{/*}{*/},
commentstyle=\color{purple}\ttfamily,
stringstyle=\color{red}\ttfamily,
morestring=[b]',
morestring=[b]"
}
\lstdefinelanguage{JavaScriptGray}{
basicstyle=\color{gray},
keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, let, if, in, while, do, else, case, break},
keywordstyle=\color{gray}\bfseries,
ndkeywords={class, export, boolean, throw, implements, import, this},
ndkeywordstyle=\color{gray}\bfseries,
identifierstyle=\color{gray},
sensitive=false,
comment=[l]{//},
morecomment=[s]{/*}{*/},
commentstyle=\color{gray}\ttfamily,
stringstyle=\color{gray}\ttfamily,
morestring=[b]',
morestring=[b]",
belowskip=-5pt
}
\lstset{numbers=left}
Let's create variables:
\begin{lstlisting}[language=JavaScript]
let msg = "Hello";
let name = "Jody";
\end{lstlisting}
And then add the method for printing:
\begin{lstlisting}[language=JavaScriptGray]
let msg = "Hello";
let name = "Jody";
\end{lstlisting}
\begin{lstlisting}[language=JavaScript,firstnumber=last]
// My first hack
console.log(msg + " " + name);
\end{lstlisting}
\end{document}
Result:
