[Tex/LaTex] Other keywords and symbols highlighting with lstlisting

listings

Trying to make my own style of C++ listings I met the problem.

First of all I decide to highlight semicolons. I read in docs

otherkeywords is designed to define keywords like =>, ->, –>, –, ::,
and so on.

Fine, that is what I need:

\documentclass{article}

\usepackage{xcolor}

\definecolor{main-color}{rgb}{0.6627, 0.7176, 0.7764}
\definecolor{back-color}{rgb}{0.1686, 0.1686, 0.1686}
\definecolor{string-color}{rgb}{0.3333, 0.5254, 0.345}
\definecolor{key-color}{rgb}{0.8, 0.47, 0.196}

\usepackage{listings}

\lstdefinestyle{mystyle}
{
    language = C++,
    basicstyle = {\ttfamily \color{main-color}},
    backgroundcolor = {\color{back-color}},
    stringstyle = {\color{string-color}},
    otherkeywords = {;},
    keywordstyle = {\color{key-color}},
}

\begin{document}

\begin{lstlisting}[style = mystyle]
#include <iostream>

using namespace std;

int x = 2;

//comment
for (int i = 0; i < x; ++i) {
    cout << "stand_alone_complex" << endl;
}
\end{lstlisting}

\end{document}

It works pretty well. Then I want to highlight << and >> with another color. Changed part of example is here:

\lstdefinestyle{mystyle}
{
    language = C++,
    basicstyle = {\ttfamily \color{main-color}},
    backgroundcolor = {\color{back-color}},
    stringstyle = {\color{string-color}},
    otherkeywords = {;},
    keywordstyle = {\color{key-color}},
    classoffset = 1,
    otherkeywords = {<<, >>},
    morekeywords = {<<, >>},
    keywordstyle = {\color{yellow}},
    classoffset = 0,
}

If I keep only otherkeywords = {<<, >>}, it would highlight "<<",">>" by key-color, not yellow. If I keep only morekeywords = {<<, >>},, it wouldn't work. So I keep both of them like here and it works, but semicolons are not highlighted anymore.
Seems like the last otherkeyword is only valid.
If I use code below, nothing highlights.

\lstdefinestyle{mystyle}
{
    language = C++,
    basicstyle = {\ttfamily \color{main-color}},
    backgroundcolor = {\color{back-color}},
    stringstyle = {\color{string-color}},
    otherkeywords = {;},
    keywordstyle = {\color{key-color}},
    keywordstyle = [2]{\color{blue}},
    morekeywords = [2]{<<, >>},
    % or otherkeywords = [2]{<<, >>},
    % or both 
}

How does it work? How can I highlight two different symbols in two different colors?

Thank you for your help.

Best Answer

As far as I can recall, the correct way is to claim all otherkeywords you need at once and then classify them in different morekeywords=[i].

(To be more precise, otherkeywords does not support [i]-syntax. Also it will erase old list on the second call, as you just observed.)

(correct is in italic because the manual does not mention this sort of usage. It might fail in the future version.)

The following will work

\lstdefinestyle{mystyle}
{
    language = C++,
    basicstyle = {\ttfamily \color{main-color}},
    backgroundcolor = {\color{back-color}},
    stringstyle = {\color{string-color}},
    keywordstyle = {\color{key-color}},
    keywordstyle = [2]{\color{lime}},
    keywordstyle = [3]{\color{yellow}},
    keywordstyle = [4]{\color{teal}},
    otherkeywords = {;,<<,>>,++},
    morekeywords = [2]{;},
    morekeywords = [3]{<<, >>},
    morekeywords = [4]{++},
}


The full code

\documentclass{article}

\usepackage{xcolor}
\definecolor{main-color}{rgb}{0.6627, 0.7176, 0.7764}
\definecolor{back-color}{rgb}{0.1686, 0.1686, 0.1686}
\definecolor{string-color}{rgb}{0.3333, 0.5254, 0.345}
\definecolor{key-color}{rgb}{0.8, 0.47, 0.196}

\usepackage{listings}

\lstdefinestyle{mystyle}
{
    language = C++,
    basicstyle = {\ttfamily \color{main-color}},
    backgroundcolor = {\color{back-color}},
    stringstyle = {\color{string-color}},
    keywordstyle = {\color{key-color}},
    keywordstyle = [2]{\color{lime}},
    keywordstyle = [3]{\color{yellow}},
    keywordstyle = [4]{\color{teal}},
    otherkeywords = {;,<<,>>,++},
    morekeywords = [2]{;},
    morekeywords = [3]{<<, >>},
    morekeywords = [4]{++},
}

\begin{document}

\begin{lstlisting}[style = mystyle]
#include <iostream>

using namespace std;

int x = 2;

//comment
for (int i = 0; i < x; ++i) {
    cout << "stand_alone_complex" << endl;
}
\end{lstlisting}

\end{document}
Related Question