The escaped part is a group, so color command issued there are lost at the end. There is no official way to set a color globally but you can look here How can I change the text color in such a way that the effect transcends groups?.
Beside this you can try to set the color with \aftergroup
(but color of keywords will overwrite this settings):
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xcolor}
\usepackage{listings}
\begin{document}
\def\redcolor{\color{red}}
\def\blackcolor{\color{black}}
\begin{lstlisting}[escapechar=@]
#@\aftergroup\redcolor@include@\aftergroup\blackcolor@ <fstream.h>
void main () {
fail
pass
}
\end{lstlisting}
\end{document}
While not exactly what the OP asks, it may suffice. First, it uses \detokenize
, not verbatim
, which means 1) that braces {}
must be balanced, 2) that the %
symbol is still interpreted as a comment, 3) that a space is inserted after all detokenized macro names, and 4) Hash marks #
are doubled in number.
Also, I just \allowbreak
between words, using the \fboxsep
of the colorbox to create the interword spaces.
EDITED to use \ttfamily
for the \mytokens
macro.
EDITED to fix line height, since the combination of a \strut
and \fboxsep
blew the allowed baselineskip budget.
Originally, I was not using interword space but allowed the \fboxsep
to suffice. But this caused margin issues, as nothing could stretch. So, upon RE-EDIT, I insert a space of 0pt minus \fboxsep
between words, which seems to allow enough compression to address the margin issues, while still leaving enough space between words (otherwise 2\fboxsep
).
I also rearranged the \grayspace
and allowbreak
, upon RE-EDIT, so that a linebreak would not occur before trailing punctuation.
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xcolor}
\newcommand\mytokens[1]{\mytokenshelp#1 \relax\relax}
\def\mytokenshelp#1 #2\relax{\allowbreak\grayspace\tokenscolor{#1}\ifx\relax#2\else
\mytokenshelp#2\relax\fi}
\newcommand\tokenscolor[1]{\colorbox{gray!20}{\textcolor{blue}{%
\ttfamily\mystrut\smash{\detokenize{#1}}}}}
\def\mystrut{\rule[\dimexpr-\dp\strutbox+\fboxsep]{0pt}{%
\dimexpr\normalbaselineskip-2\fboxsep}}
\def\grayspace{\hspace{0pt minus \fboxsep}}
\begin{document}
Here is my leading text
\mytokens{Fie Fi Fo Fum, I smell the $#@*& blood of an \Englishman.
I will continue this text to observe the margins.
Fie Fi Fo Fum, I smell the \textbf{blood} of an Englishman.}
and my trailing text. And here is more text to find where the margin end
really should be.
Standard MATLAB formats are allowed, such as \mytokens{1.2}, \mytokens{-.2i},
\mytokens{1.}, \mytokens{-1.2e3}, \mytokens{+.2E-3j}. \mytokens{i} and
\mytokens{j} denote...
\end{document}
SUPPLEMENT
In response to a comment request, here is a version that takes the background color as an optional argument.
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xcolor}
\newcommand\mytokens[2][gray!20]{\mytokenshelp{#1}#2 \relax\relax}
\def\mytokenshelp#1#2 #3\relax{\allowbreak\grayspace\tokenscolor[#1]{#2}\ifx\relax#3\else
\mytokenshelp{#1}#3\relax\fi}
\newcommand\tokenscolor[2][gray!20]{\colorbox{#1}{\textcolor{blue}{%
\ttfamily\mystrut\smash{\detokenize{#2}}}}}
\def\mystrut{\rule[\dimexpr-\dp\strutbox+\fboxsep]{0pt}{%
\dimexpr\normalbaselineskip-2\fboxsep}}
\def\grayspace{\hspace{0pt minus \fboxsep}}
\begin{document}
Here is my leading text
\mytokens{Fie Fi Fo Fum, I smell the $#@*& blood of an \Englishman.
I will continue this text to observe the margins.
Fie Fi Fo Fum, I smell the \textbf{blood} of an Englishman.}
and my trailing text. And here is more text to find where the margin end
really should be.
Standard MATLAB formats are allowed, such as \mytokens{1.2},
\mytokens{-.2i}, \mytokens[red!40]{1.}, \mytokens{-1.2e3},
\mytokens{+.2E-3j}. \mytokens[cyan!30]{i} and
\mytokens[green!20]{j} denote...
\end{document}
Best Answer
Put
\hl{..}
inside.