# listings: highlight part of a delimited word starting with space

I would like to create a lstlisting language for a syntax that highlights namespaces for readability. Here's what I want to achieve:

\documentclass{standalone}
\usepackage{listings}
\usepackage{xcolor}

\definecolor{gray}{rgb}{0.4,0.4,0.4}
\definecolor{darkblue}{rgb}{0.0,0.0,0.6}
\definecolor{cyan}{rgb}{0.0,0.6,0.6}

\lstset{
basicstyle=\ttfamily,
columns=fullflexible,
showstringspaces=false,
}

\lstdefinelanguage{turtle}
{
stringstyle=\color{black},
identifierstyle=\color{darkblue},
keywordstyle=\color{cyan},
moredelim=[is][\color{orange!80!black}]{!}{!},
moredelim=[l][\color{orange!80!black}]{\ }{:} % my best guess: does not work
}

\begin{document}
\lstset{language=turtle}
\begin{lstlisting}
!a!:b !c!:d !e!:f .
\end{lstlisting}
\end{document}


However, I would like to avoid having to put ! explicitly in the input to wrap the namespaces. The command moredelim=[l][\color{orange!80!black}]{\ }{:} has no effect unless I put a space directly before and after each :.

You can insert color codes into the identifiers using a regular expression with expl3 (see also https://tex.stackexchange.com/a/238832/89417) as follows:

1. include the prefix in the identifier tokens with alsoletter{:}
2. define a new command as identifierstyle to which the tokens are passed by lstlisting
3. expand the current token (using the o argument specifier)
4. add the color commands with a regex (using the syntax for building commands with \c{} and \cB{,\cE}) on the two matching groups \1 and \2
5. print the replaced token
6. return a command to identifierstyle which will be applied to the current token by lstlisting, define this command such that nothing is printed.

Note that it would be cleaner to modify c{lst@token} in-place (instead of step 5 and 6), but due to my lack of knowledge about expl3 I didn't do that :)

MWE:

\documentclass{article}
\usepackage{listings,xparse}
\usepackage{expl3}
\usepackage{xcolor}
\definecolor{darkblue}{rgb}{0.0,0.0,0.6}
\colorlet{orangeb}{orange!80!black}
\def\noprint#1{}

\ExplSyntaxOn
\NewDocumentCommand \namespaces { }
{
\tl_set:No \l_demo_tl {\the\use:c{lst@token}}
\regex_replace_all:nnN { ([a-zA-Z]*):([a-zA-Z]*) } { \c{textcolor}\cB{ orangeb \cE}\cB{ \1 \cE}:\c{textcolor}\cB\{ darkblue \cE\}\cB{ \2 \cE} } \l_demo_tl
\tl_use:N \l_demo_tl
\noprint
}

\ExplSyntaxOff

\lstset{
basicstyle=\ttfamily,
alsoletter={:},
columns=fullflexible,
identifierstyle=\namespaces
}

\begin{document}

\begin{lstlisting}
a:b c:d e:f .
\end{lstlisting}

\end{document}


Result:

• Many thanks (and thanks for the explanation (and the introduction to exp3!)!). – badroit Nov 21 '17 at 13:05