Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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.

share|improve this question
    
What did you try? –  Antal S-Z Nov 19 '10 at 0:33
3  
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

2 Answers 2

up vote 2 down vote accepted

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".

enter image description here

\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
\lst@AddToHook{OutputOther}{\ProcessOther@silmeth}

% 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}
share|improve this answer

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:

Sample listing.

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.

share|improve this answer
    
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
1  
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.