3

I want to implement a function name color highlighting and I use the listings package. My 'regex' for this is def %s( where def (including space) is the first delimiter %s is the function name and ( is the second delimtier. Now my aim is to color only %s in purple. So basically I want to only touch the part between the delimiters and the delimiters should stay untouched.

Here is what I tried so far:

\documentclass{article}
\usepackage{xcolor,listings}
\usepackage[ngerman]{babel}
\usepackage{fontspec}
\setmonofont{Courier New}

\begin{document}

\lstset{language=Python,
    escapebegin=\color{orange},
    keywordstyle=\color{blue}\bfseries,
    commentstyle=\color{orange!80!red},
    stringstyle=\ttfamily\color{gray},
    %moredelim = [is][\color{blue}\bfseries def \mdseries\color{purple}]{def\ }{(},
    moredelim = [s][\color{purple}]{def\ }{(},
    showstringspaces=false}‎
\lstset{literate=%
   *{0}{{{\color{red}0}}}1
    {1}{{{\color{red}1}}}1
    {2}{{{\color{red}2}}}1
    {3}{{{\color{red}3}}}1
    {4}{{{\color{red}4}}}1
    {5}{{{\color{red}5}}}1
    {6}{{{\color{red}6}}}1
    {7}{{{\color{red}7}}}1
    {8}{{{\color{red}8}}}1
    {9}{{{\color{red}9}}}1
}

‎‎\begin{lstlisting}[basicstyle=\ttfamily,mathescape]
def fancy_function_name(page_url = 'tex.stackexchange.com'):
    return page_url.split('.')[0]
\end{lstlisting}

\end{document}

This code will generate: enter image description here

You can see that it matches the right place but is too greedy and colors the delimiters too. So I thought about the uncommented line: %moredelim = [is][\color{blue}\bfseries def \mdseries\color{purple}]{def\ }{(}, If I use this one and uncomment the line below I get this result:

enter image description here

It's nearly what I wan't but I cannot add the last, now missing ( in black color.

Does anyone has a solution for this without pretouching the code and add all the @@ symbols?

1 Answer 1

5

You can define your own command, taking one argument and adding appropriate characters before and after printing this argument:

\documentclass{article}
\usepackage{xcolor,listings}
\usepackage[ngerman]{babel}
%\usepackage{fontspec}
%\setmonofont{Courier New}

\begin{document}

\newcommand{\functionDefHighlight}[1]{\bfseries\textcolor{blue}{def} \textcolor{purple}{\mdseries #1}(}

\lstset{language=Python,
    escapebegin=\color{orange},
    keywordstyle=\color{blue}\bfseries,
    commentstyle=\color{orange!80!red},
    stringstyle=\ttfamily\color{gray},
    %moredelim = [is][\color{blue}\bfseries def \mdseries\color{purple}]{def\ }{(},
    %moredelim = [s][\color{purple}]{def\ }{(},
    moredelim = [is][\functionDefHighlight]{def\ }{(},
    showstringspaces=false}‎
\lstset{literate=%
   *{0}{{{\color{red}0}}}1
    {1}{{{\color{red}1}}}1
    {2}{{{\color{red}2}}}1
    {3}{{{\color{red}3}}}1
    {4}{{{\color{red}4}}}1
    {5}{{{\color{red}5}}}1
    {6}{{{\color{red}6}}}1
    {7}{{{\color{red}7}}}1
    {8}{{{\color{red}8}}}1
    {9}{{{\color{red}9}}}1
}

‎‎\begin{lstlisting}[basicstyle=\ttfamily,mathescape]
def fancy_function_name(page_url = 'tex.stackexchange.com'):
    return page_url.split('.')[0]
\end{lstlisting}

\end{document}

print screen of result

2
  • Thank you very much, that works perfect! Didn't find anything about it in the manual though...
    – user49121
    Commented Oct 3, 2015 at 22:27
  • 1
    There is small hint about it in section 1.3: "The styles use two different kinds of commands. \ttfamily and \bfseries both take no arguments but \underbar does; it underlines the following argument. In general, the very last command may read exactly one argument, namely some material the package typesets. There’s one exception. The last command of basicstyle must not read any tokens—or you will get deep in trouble."
    – jkuczm
    Commented Oct 3, 2015 at 22:36

You must log in to answer this question.