[Tex/LaTex] How to get identifier style to apply to ‘%’ (in a Perl listing)

listingsperl

When using Perl variable names with sigils with listings, the $ and @ sigils somehow get coloured in identifierstyle, but the % sigil remains unstyled.

Therefore, this code:

\documentclass{article}

\usepackage{listings,xcolor}

\lstdefinestyle{perl}{
   language=Perl,
   basicstyle=\ttfamily,
   keywordstyle=\bfseries\color{green!40!black},
   commentstyle=\color{purple!40!black},
   identifierstyle=\color{blue},
   stringstyle=\color{orange},
}

\lstset{style=perl}

\begin{document}
    \begin{lstlisting}
        my ($a, $b, $c) = ('a'..'z');
        my ($a, $b, @c) = ('a'..'z');
        my ($a, $b, %c) = ('a'..'z');
    \end{lstlisting}
\end{document}

gives this result:

unstyled sigil

Is there a way I could make listings understand that % should have the same style as $ or @?

The manual is pretty clear about keywords and comments, but it didn't help me understand the difference between an identifier and an operator (?) that doesn't get styled. Looking at the Perl language definition in lstlang1.sty didn't help either since there is nothing there about either $ and @ or %.

Best Answer

Short answer

By default, identifiers cannot start by %. You can allow identifiers to start by % by specifying alsoletter={\%} in the definition of your custom perl style.

Detailed answer

Look up the alsoletter key in subsection 4.18 of the listings manual:

All identifiers (keywords, directives, and such) consist of a letter followed by alpha-numeric characters (letters and digits). For example, if you write keywords={one-two,\#include}, the minus sign must become a digit and the sharp a letter since the keywords can’t be detected otherwise.

According to Table 2, % is (by default) treated, not as a "letter", but as "other". The Perl style (which is defined in lstdrvrs.dtx, a file that ships with listings.sty) doesn't change that.

Therefore, in order to allow identifiers to begin by %, you must specify alsoletter={\%}. Note that % must be escaped, here; see item 5 in subsection 4.1 for more details.

enter image description here

\documentclass{article}

\usepackage{listings,xcolor}

\lstdefinestyle{perl}
{
   language=Perl,
   basicstyle=\ttfamily,
   keywordstyle=\bfseries\color{green!40!black},
   commentstyle=\color{purple!40!black},
   identifierstyle=\color{blue},
   stringstyle=\color{orange},
   alsoletter={\%},
}

\lstset{style=perl}

\begin{document}
    \begin{lstlisting}
        my ($a, $b, $c) = ('a'..'z');
        my ($a, $b, @c) = ('a'..'z');
        my ($a, $b, %c) = ('a'..'z');
    \end{lstlisting}
\end{document}
Related Question