6

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,
    commentstyle=\color{gray}\upshape
}

\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}

desired output

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 :.

7

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:

enter image description here

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.