I am currently writing a language definition with the listings package. My language should be colored in the following way:
- all comments are supposed to be completely green without any exception
- all strings are supposed to be completely red without any exception
- all keywords are supposed to be blue (keywords may contain numbers)
- identifiers are supposed to be black (indentifiers may contain numbers)
- numbers are supposed to be magenta (but not those in keywords or identifiers)
- mathematical operators, brackets, etc are supposed to be cyan
Colouring my language exactly that way is actually not difficult. I managed that by setting basicstyle to magenta, keywordstyle to blue, commentstyle to green, stringstyle to red and then using the * version of literate to color the mathematical operators with cyan. Everything works like a charm. However my language definition must also make it possible to have German umlauts like "ü" in strings or comments. As we know this is a little tricky since listings and the utf8 encoding causes some trouble, but it can in general be achieved by using the literate version without the star.
And here comes the problem. As you can see I must literate a few things with the * version while at the same time literating other things without the star. I have seen that this can be theoretically done like it was done here: How to apply the star (*) to only a few of the literates in listings environment?
This works, but not in all cases. I get into trouble trying to literate the = sign as well as trying to literate the . The problem seems to be that the delimiter for my comments contains a = and that within strings itself the " is excaped by \". Any idea how to fix this?
I have created a MWE and made three outputs, accodring to the comments in the MWE:
\documentclass{standalone}
\usepackage[utf8]{inputenc}
\usepackage{xcolor}
\usepackage{listings}
\lstdefinelanguage{testlang}{
morekeywords={int32,string},
morecomment=[l]{\#},
morecomment=[n]{\#=}{=\#},
morestring=[b]{"}
}[keywords,comments,strings]
\makeatletter
\newcommand{\jPm}[1]{%
\ifnum\lst@mode=\lst@Pmode\relax%
{\color{cyan}#1}%
\else%
#1%
\fi%
}
\begin{document}
% defining the colors
\lstset{basicstyle={\color{magenta}\ttfamily}, keywordstyle={\color{blue}\bfseries},
commentstyle={\color{green}\textit}, stringstyle={\color{red}}, identifierstyle={\color{black}}}
% defining the literals
\lstset{extendedchars=true}
\lstset{literate={ü}{{\"u}}{1} {+}{{{\jPm{+}}}}{1} % the first result does not use the next two lines
%{\\}{{{\jPm{\textbackslash{}}}}}{1} % the second result does not use the next line
%{=}{{{\jPm{=}}}}{1} % the third result also uses this line
}
\lstset{language=testlang}
\begin{lstlisting}
#= A comment that is longer than one line,
and that contains the German word "Blüte". =#
# Single comment: We will calculate 5 + 2 \ 8
string mystr = "An \"escaped string\", a Blüte and 1 + 1 = 2."
int32 my2ndvar = 8
int32 myres = 5 + 2 \ my2ndvar
\end{lstlisting}
\end{document}
Output when only ü and + are literated: