4

The lstlisting environment provided by the listings package allows you to escape out of the environment and insert arbitrary LaTeX code which is evaluated using the usual (non-verbatim) rules. What I am interested in is whether it is possible to insert text into an lstlisting environment using a macro that is then still parsed by the lstlisting environment.

The motivation for wanting to do this is the following. I am working on a project with lots of lstlisting environments and we want to provide macros for certain code snippets that frequently occur so that (i) it enforces standardization across the document, and (ii) if we want to change the snippets then we only have to do it in one place.

The MWE below hopefully demonstrates what I'm trying to achieve. This isn't a very realistic example of the kind of situation that we would use this for, but hopefully makes for a clear example. The goal of the MWE would be to have the lstlisting environment recognize the text inserted by the macro as a comment and consequently typeset it using a bold font. An image of the compiled example is shown at the very bottom.

Also notice that the macro is inserting an extra space for some reason in the second code block.

\documentclass{article}

\usepackage{listings}

\lstset{%
  language=bash,
  basicstyle=\fontfamily{pcr}\selectfont,
  commentstyle=\bfseries,
  escapeinside={(*@}{@*)}
}

\newcommand{\comment}[1]{\# here is a comment: #1}


\begin{document}

This is how the example currently looks after compilation.  Notice that the text
after the pound sign in the second code block isn't typeset using bold font.

\begin{lstlisting}
# here is a comment: hardcoded
echo example 1
\end{lstlisting}

\begin{lstlisting}
(*@\comment{using a macro}@*)
echo example 2
\end{lstlisting}


\end{document}

enter image description here

  • 2
    can you not simply say \newcommand{\comment}[1]{\bfseries\# here is a comment: #1} (or \lst@commentstyle instead of \bfseries)? The extra space is from \nonfrenchspacing being in effect, so \frenchspacing will fix it. – Robert Nov 28 '17 at 3:19
  • @Robert that would indeed work for this particular example, so this may not have been the best illustration. The greater goal though is to allow for not just comments but actual code so that listings can perform typesetting for keywords and such. – dpritch Nov 28 '17 at 4:06
1

It seems you want to escape from the lstlisting just to silently re-enter it again for highlighting keywords or other syntax parts in your comment later. So why not just stay in the lstlisting? You can define a new delimited environment with mordelim=**[is] that removes the delimiters from the output but still applies all other styles to the text between them. With that a new comment environment [*@ ... @*] might look like this:

\documentclass{article}

\usepackage{listings}
\usepackage{xcolor}

\lstset{%
  language=bash,
  basicstyle=\fontfamily{pcr}\selectfont,
  commentstyle=\bfseries,
  escapeinside={(*@}{@*)},
  moredelim=**[is][\commentstyle]{[*@}{@*]},
  keywordstyle={\color{blue}}
}

\newcommand{\commentstyle}{\frenchspacing \bfseries \# here is a comment: }
\newcommand{\comment}[1]{\# here is a comment: #1}

\begin{document}
This is how the example currently looks after compilation.  Notice that the text
after the pound sign in the second code block isn't typeset using bold font.

\begin{lstlisting}
# here is a comment: hardcoded
echo example 1
\end{lstlisting}

\begin{lstlisting}
(*@\comment{using a macro}@*)
echo example 2
\end{lstlisting}

\begin{lstlisting}
[*@with keywords like echo@*]
echo example 3
\end{lstlisting}
\end{document}

enter image description here

  • 1
    This is really slick, thanks so much for answering this after all this time! – dpritch Oct 22 '18 at 17:15

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.