# How to highlight operators and brackets in a C listing?

How can I apply a certain style to C (or, well, any other programming language) operators? So that when I write

\begin{lstlistings}[language=C++]
int i = 0;
if(i > 1) {
// do something
}
\end{lstlisting}


I'll get = and > (and other operators, and preferably also ( and ), { and }) highlighted in red, for instance? I managed to treat those characters like other keywords (bold and blue in my case), but this isn't the behavior I want, and it destroys comment definitions.

-
What did you try? –  Antal S-Z Nov 19 '10 at 0:33
Have you looked at minted? –  Joseph Wright Nov 19 '10 at 8:06
I second @Joseph's suggestion: either Minted or Pygments will probably repay the initial time investment quickly here. Look at Syntax Coloring in LaTeX. –  Charles Stewart Nov 19 '10 at 8:34
Ok, I have tried only few tricks with listings, I tried to add some emphs, keywords, otherkeywords, etc. Haven't looked at any other package and didn't try to make more "hackish tricks" like the one proposed by Antal S-Z yet. –  silmeth Nov 19 '10 at 9:33

Well, here's a hackish approach with unfortunate code duplication:

\newcommand{\CodeSymbol}[1]{\textcolor{red}{#1}}
\begin{lstlisting}[language=C++, literate={\{}{{\CodeSymbol{\{}}}1
{\}}{{\CodeSymbol{\}}}}1
{(}{{\CodeSymbol{(}}}1
{)}{{\CodeSymbol{)}}}1
{>}{{\CodeSymbol{$>$}}}1
{=}{{\CodeSymbol{$=$}}}1
{;}{{\CodeSymbol{$;$}}}1]
int i = 0;
if(i > 1) {
// do something
}
\end{lstlisting}


This gives the desired output:

The literate key is intended to allow you to, for instance, replace the -> operator with \to; here, we're abusing it for highlighting purposes. It takes a space-separated list of triples, each of the following form: {SYMBOL}{{REPLACEMENT}}WIDTH. Then the listings package will replace each symbol with the replacement, and pretend it occupies WIDTH characters. Here, we're just replacing symbols with a highlighted version. Unfortunately, in my limited testing, I couldn't store that text in a macro, so it looks like it'll have to be put in by hand, which is a lot of grunt work. Of course, it can be specified once per document in an \lstset{...}, but even so. I imagine the reason things like keyword and emph don't work—or, at least, didn't in my testing—is that they only accept words, and not symbols. However, it is possible to create different keyword and emph classes using emph={[2]emphasize,this}, emphstyle={[2]\color{red}}. Also, I was a little vague/imprecise about some of the syntax here, so be sure to check out the manual.

-
Ok, thanks, that's kind of solution. I'll search in manual for other, maybe nicer, one, but at least this one works. –  silmeth Nov 19 '10 at 9:14
There are, howver, some problems: when I highlight "/" this way, then comments don't work (and I can't force them using eg. "morecomment" options), and, I don't understand why, I can't highlight "&". –  silmeth Nov 19 '10 at 9:24
Yeah, it's not pretty, but it does the job. Minted's very nice, as Joseph Wright said, though it is slower. As for your specific questions: you can highlight & just fine, but since it's a special character, you need to escape it like the braces, and specify {\&}{{\CodeSymbol{\&}}}1. As for /, though… :-/ I can't see a good way to fix that, other than saying "don't divide anything". –  Antal S-Z Nov 19 '10 at 10:56

Here is a workaround that doesn't break one-line comments and only applies the desired style to operators outside comments and strings.

Caveats:

• I've had to define all digits as "letters" to prevent my operator style from being applied to them; there may be side effects associated with that.
• Outside comments and strings, the operator style will be applied to all characters that listings classifies as "other".

\documentclass{article}

\usepackage{xcolor}
\usepackage{listings}

\newcommand\opstyle{\color{red}} % <--- customise operator style here

\makeatletter

\lstset
{%
language=C++,
alsoletter=0123456789,% to prevent \opstyle from being applied to digits
}

% Hook into listings

% helper macro
\newcommand\ProcessOther@silmeth
{%
\ifnum\lst@mode=\lst@Pmode%     % If we're in Processing' mode...
\def\lst@thestyle{\opstyle}%  % ... redefine the style locally
\fi%
}

\makeatother

\begin{document}
\begin{lstlisting}[]
int i = 0;
if(i > 1) && (1/2 < 2) {

// one-line comment ()={}><;&

printf("string: ()={}><;&");

/*
block comment ()={}><&;
*/
}
\end{lstlisting}
\end{document}
`
-