13

I'd like to display the following code fragment in a lstlisting environment:

\begin{tikzpicture}
  \duck[stripes=text]
  \stripes{}
\end{tikzpicture}

The syntax highlighting should be

  • red for tikzpicture
  • blue for commands \begin \duck \stripes \end
  • orange for keyword stripes
  • other elements like text should remain black (or should at least have another colour then the keywords)

I tried to misuse emphstyle to colour the keyword, but as there is a command of the same name \stripes also changes colour, while I only want stripes to be in orange and \stripes to remain blue.

This seems to be a known bug, from p. 31 of the listings documentation:

Bug: texcs... interferes with other keyword lists. If, for example, emph contains the word foo, then the control sequence \foo will show up in emphstyle.

Is there any other way to colour keywords or workaround?

MWE:

\documentclass{article}

\usepackage{xcolor}
\usepackage{listings}

\lstdefinestyle{duckstyle}{%
    language={[latex]TeX},
    basicstyle=\footnotesize\ttfamily,
    %
    keywordstyle=\color{red!60!black}\bfseries,
    morekeywords={tikzpicture},
    %
    texcsstyle=*\color{blue}\bfseries,
    moretexcs={duck,stripes},
    %
    emphstyle=\color{orange!70!black},
    emph={stripes}
}

\lstset{style=duckstyle}

\begin{document}

\begin{lstlisting}
\begin{tikzpicture}% <- Perfect color
  \duck[stripes=text]% <- Perfect color
  \stripes{}% <- \stripes should be blue :(
\end{tikzpicture}% <- Perfect color
\end{lstlisting}

\end{document}

enter image description here


EDIT

To make things even more complicated, my real use case is to show the code in a tcblisting which has the unfortunate side effect that the perfect solution of Ulrike Fischer fails to compile the output of the listing.

\documentclass{article}

\usepackage{tikzducks}% needs version 0.4
% this will be available on ctan sometime in the next 24 hours
% currently: https://github.com/samcarter8/tikzducks/blob/master/tikzducks.sty

\usepackage{listings}
\usepackage[most]{tcolorbox}

\lstdefinestyle{duckstyle}{%
    language={[latex]TeX},
    basicstyle=\footnotesize\ttfamily,
    %
    keywordstyle=\color{red!60!black}\bfseries,
    morekeywords={tikzpicture},
    %
    texcsstyle=*\color{blue}\bfseries,
    moretexcs={duck,stripes},
    %
    moredelim=[is][\footnotesize\ttfamily\color{orange!70!black}]{|}{|},
}

\lstset{style=duckstyle}

\tcbset{listing options={style=duckstyle}}

\begin{document}

\begin{tcblisting}{title={duck}}
\begin{tikzpicture}
  \duck[|stripes|]
  \stripes{}
\end{tikzpicture}
\end{tcblisting}

\end{document}

EDIT2

Getting closer: The \pgfkeys{/duck/|stripes|/.style={stripes=#1}} solution works for \duck[|stripes|], but fails for \duck[|stripes|={\stripes[color=blue]}] with the error message

! Extra \fi.
\pgfkeyscurrentkey ->color\fi 
                              \ifduck@cape \begin {pgfinterruptboundingbox} ...
l.2     \duck[|stripes|={\stripes[color=blue]}]

I'm ignoring this; it doesn't match any \if.

MWE:

\documentclass{article}

\usepackage{tikzducks}% needs version 0.4
% this will be available on ctan sometime in the next 24 hours
% currently: https://github.com/samcarter8/tikzducks/blob/master/tikzducks.sty

\usepackage{listings}
\usepackage[most]{tcolorbox}

\lstdefinestyle{duckstyle}{%
    language={[latex]TeX},
    basicstyle=\footnotesize\ttfamily,
    %
    keywordstyle=\color{red!60!black}\bfseries,
    morekeywords={tikzpicture},
    %
    texcsstyle=*\color{blue}\bfseries,
    moretexcs={duck,stripes},
    %
    moredelim=[is][\footnotesize\ttfamily\color{orange!70!black}]{|}{|},
}

\lstset{style=duckstyle}

\tcbset{listing options={style=duckstyle}}

\pgfkeys{/duck/|stripes|/.style={stripes=#1}}

\begin{document}

\begin{tcblisting}{title={working}}
\begin{tikzpicture}
  \duck[|stripes|]
  \stripes{}
\end{tikzpicture}
\end{tcblisting}

\begin{tcblisting}{title={not working}}
\begin{tikzpicture}
    \duck[|stripes|={\stripes[color=blue]}]
\end{tikzpicture}
\end{tcblisting}

\end{document}
4
  • Did you see the Bug mention in the manual? Page 31, under directivestyle (right below texcsstyle)
    – daleif
    Sep 1, 2017 at 13:57
  • perhaps you should try minted:-) Sep 1, 2017 at 13:59
  • @daleif Thanks, I had not seen it before. I still hope for some workaround. Sep 1, 2017 at 14:00
  • @DavidCarlisle If there would only be some nice overview comparing the (dis)advantages ... (I never managed to get minted to work, probably too many different python installation cluttering my system) Sep 1, 2017 at 14:02

1 Answer 1

8
+250

As a work-around you can use a delimiter to get orange keywords:

\documentclass{article}

\usepackage{xcolor}
\usepackage{listings}

\lstdefinestyle{duckstyle}{%
    language={[latex]TeX},
    basicstyle=\footnotesize\ttfamily,
    %
    keywordstyle=\color{red!60!black}\bfseries,
    morekeywords={tikzpicture},
    %
    texcsstyle=*\color{blue}\bfseries,
    moretexcs={duck,stripes},
    %
    moredelim=[is][\footnotesize\ttfamily\color{orange!70!black}]{|}{|},
}

\lstset{style=duckstyle}

\begin{document}

\begin{lstlisting}
\begin{tikzpicture}% <- Perfect color
  \duck[|stripes|=text]% <- Perfect color
  \stripes{}% <- \stripes should be blue :(
\end{tikzpicture}% <- Perfect color
\end{lstlisting}

\end{document}

enter image description here

Edit

When using tcblisting (where the code is also executed) one must ensure that the key |stripes| is not unknown and does something senseful.

The easiest is to define alias-keys:

  \pgfkeys{/duck/|stripes|/.style={stripes={#1}}}
9
  • Thanks a lot for your answer! This solves exactly the problem I posted in my questions. However in my real document, I use tcblisting to show both the code and output and the | prevents the output from being compiled. Do you maybe know of any other delimiter I could try which would be ignored in the compilation of the result? (added a code example to the question) I know this was not part of the original question and if you don't have a solution for this new problem I will eventually accept your answer anyway (if no better answer comes around) Sep 4, 2017 at 11:07
  • @samcarter: I added an edit. Sep 4, 2017 at 13:42
  • Arrrg, I found yet another problem, sorry! Your solution works fine for \duck[|stripes|], but as soon as I try to pass any argument, i.e. \duck[|stripes|={\stripes[color=blue]}] it fails -- for the error message, please see my second edit. But nevertheless, thanks a lot for your edit! Sep 4, 2017 at 14:16
  • Difficult to analyse without the style. Does it works (beside the code color) if you use \duck[stripes={\stripes[color=blue]}]? Sep 4, 2017 at 14:19
  • Yes, that works fine. In case it helps, the v0.4 .sty file can be found at github.com/samcarter8/tikzducks/blob/master/tikzducks.sty Sep 4, 2017 at 14:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .