3

I am using listings to highlight some keywords. The problem I am having is that I want a keyword to be formatted and the word that follows the keyword to be formatted differently. The keyword will always be the same but the word that follows might be different.

Here's an example that I mocked up in MS Word to show what I want.

Sample of formatted text

Anytime the word answer is in the lstlisting environment, it should boldface that word, which I have handled already, and make the next word red, which will always be followed by a comma.

I have looked at a few answers such as Emphasize (color) contents between two delimiters in listings, but not the delimiters themselves but I can't modify that to work for me.

Here is what I have tried.

\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}
\lstdefinestyle{MyList}{%
    basicstyle=\ttfamily,%
    keywords={Answer},%
    keywordstyle=\bfseries,%
}
\lstset{%
    moredelim=**[is][\beginlstdelim{Answer:\ }\color{red}]{,},
}
\begin{document}

\begin{lstlisting}
Here is some question text.
Answer: True, because of theorem 1.3.
\end{lstlisting}
\end{document}

That code causes a lot of problems.

1 Answer 1

3

It takes some finesse to listings to behave. The basic idea of making Answer: and , paired delimiters works, but we don't want the delimiters to be red too so you use the i invisible key. Then you need to reinsert Answer: and , somehow. Answer: is easy -- you can just type it out as part of the style code.

The listings package doesn't expose an easy hook to add code at the end delimiter, so that's a bit harder. The trick here is that listings needs to have a group in order to keep the scope of the style code local, and after the delimited text, it must close the group to end your style code. As a consequence of this, we can use the crazy tex primitive \aftergroup to insert the comma after the group closes. Instead of crashing (which is the expected outcome of using \aftergroup in the middle of unknown code), this inserts the comma exactly where we need it.

There's one last gotcha, which is that for some strange reason if we put this code directly into the style argument, listings breaks with some weird error. To fix this, I put it into a separate command and then put that command into the style argument.

\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{geometry}

\newcommand\mydelimcode{\textbf{Answer:}\color{red}\aftergroup,}

\lstset{%
    basicstyle=\ttfamily,
    moredelim=**[is][\mydelimcode]{Answer:}{,},
}

\begin{document}
\begin{lstlisting}
Here is some question text.
Answer: True, because of theorem 1.3.

Here is some question text.
Answer: False, because of theorem 2.6.

Here is some question text.
Answer: 6^2, because you have 6 choices for each entry in a list of length 2.
\end{lstlisting}
\end{document} 
2
  • Don't use \def, use \newcommand. Jan 31, 2018 at 10:59
  • This works great. Thanks. And, if I want to change the format of the word Answer: I can do that in the \def\mydelimcode{\textbf{Answer:}\color{red}\aftergroup,} line of code.
    – tmbrauch
    Jan 31, 2018 at 14:04

You must log in to answer this question.

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