# multiple classes not working with otherkeywords in listings package

I'm using the listings package to format some code. The language isn't one of the ones supported out of the box, so I provided my own language definition using \lstdefinelanguage as described in the docs for the package. The problems is that most of the things I want to highlight are non-letter symbols and I want to highlight them into several classes. Here is my definition:

\lstdefinelanguage{mylang}{%
keywordsprefix={\#},%
alsoletter={\#},%
otherkeywords={[,],<,>,<!,!>,.\,},
otherkeywords={[2]:=,:+},%
morecomment=[l]\%,
morestring=[b]",%
morestring=[d]',%
sensitive=true%
}


You can see that I'm trying to highlight words marked with a # and some punctuation-based symbols. The issue is that because my "keywords" are based on punctuation, I have to use otherkeywords instead of morekeywords. And using a second list of otherkeywords doesn't seem to work---I don't get any error, but I don't see any result when trying to apply a style. I define some colors, then try to assign them to keywords and keywords[2], but to no avail:

% Define Colors
\usepackage{color}
\definecolor{blue}{RGB}{42,0.0,255}
\definecolor{green}{RGB}{63,127,95}
\definecolor{purple}{RGB}{127,0,85}
\definecolor{orange}{RGB}{225,100,0}

\lstset{
language={mylang}, %
stringstyle=\color{blue}, % style of strings
keywordstyle=\color{purple}, % style of keywords
keywordstyle={[2]\color{orange}} % style of 2nd keywords
}


I thought about trying to adding these punctuation symbols into alsoletter, and then using morekeywords instead of otherkeywords. This partially solves the problem, because I can get multiple styles using the [2] indexes on morekeywords, however the issue is now that after making these into letters, the parser won't find them when they're sitting next to a word without whitespace separating. Making them letters means that the blah]. won't find the ] or the ..

Any thoughts or ideas? I started looking through the developers guide but maybe a better idea would be just to look at the source code and see if I can extend the [index] functionality to otherkeywords.

In case it's helpful, the language has statements that look like this:

a := b & c &
[ D #e,
F #e & g,
H [ I <! k, l !> ]].


I'd like to be able to show the "hashtagged" items in a different color from the delimiters, and ideally the operators like := and & . in a third color.

I've been using xelatex but I don't guess that's relevant.

EDIT:

Comments have requested a compilable example, which makes sense, here you go:

\documentclass{article}
\usepackage{listings}
% Define Colors
\usepackage{color}
\definecolor{blue}{RGB}{42,0.0,255}
\definecolor{green}{RGB}{63,127,95}
\definecolor{purple}{RGB}{127,0,85}
\definecolor{orange}{RGB}{225,100,0}
\definecolor{gray}{RGB}{150,150,150}

\lstdefinelanguage{mylang}{%
keywordsprefix={\#},%
alsoletter={\#},%
otherkeywords={[2]<,>,[,],<!,!>,.\,},
otherkeywords={[3]:=,:+},%
morecomment=[l]\%,
morestring=[b]",%
morestring=[d]',%
sensitive=true%
}

\begin{document}

\lstset{
language={mylang},
basicstyle=\ttfamily,
stringstyle=\color{blue}, % style of strings
keywordstyle=\color{purple}, % style of keywords
keywordstyle={[2]\color{orange}}, % style of 2nd keywords
keywordstyle={[3]\color{gray}}, % style of 3nd keywords
morekeywords={}
}

\begin{lstlisting}
% this is a comment
a := b & c &
[ D #e,
F #e & g,
H [ I <! k, l !>,
M "nop" ]].
\end{lstlisting}

\end{document}


Hopefully the example makes clear that the intention here is to highlight the brackets and the := :+ operators in two different styles, according to the idiom of using [i], to group items and style them---as described in the package documentation.

When I compile this simple example, I see the styling on the comment, on the string and on the #e, but nothing on the otherkeywords either [2] or [3]. Like this:

Some workaround which I tried was to add the punctuation symbols to alsoletter, but this actually causes other unwanted behavior (the inability to parse ]]. as a series of three keywords).

Aside:

the line in \lstset which says morekeywords={} is required to get this to compile. I think it has to do with the prefix being assigned to keywords then not having any keywords (some kind of interaction between keywords and otherkeywords.

Love to hear any ideas.

EDIT 2:

I've been looking in the listings source, specifically in lstmisc.sty, I find these lines:

\lst@Key{otherkeywords}{}{%
\let\lst@otherkeywords\@empty
\lst@for{#1}\do{%
\lst@MakeActive{##1}%
\lst@lExtend\lst@otherkeywords{%
\expandafter\lst@CArg\lst@temp\relax\lst@CDef
{}\lst@PrintOtherKeyword\@empty}}}


I'm still looking through the developers guide to understand what's happening here, but it looks like there might be an opportunity to pass in a second parameter here to \lst@Key and then use it enable grouping on otherkeywords.

• Please make your code snippets compilable ... – Mensch Jun 16 '17 at 23:40
• I cannot look deeply into your question now, but the following question, which I happened to answer one year ago, could be related: Colorize symbols with lstdefinelanguage in latex. – GuM Jun 17 '17 at 2:10
• @GustavoMezzetti thanks! In fact, I believe my situation is a little more complicated, but you're right that they are related. In that case, the author just needed to learn about otherkeywords and use the indexing on keywords. I'm in a situation where I need more than a single class of otherkeywords, and it doesn't seem to be working "out of the box". I'm willing to modify listings source code if anyone has any pointers. Cheers! – JawguyChooser Jun 18 '17 at 19:24