8

\lstinline of the listings package doesn't work in math mode. When I try to use it, I get the error that \ttfamily is invalid in math mode.

However, when reasoning about program semantics, it is often necessary to put snippets of program code inside mathematical constructs and, ideally, this would be done with \lstinline in order to keep a consistent style between inline snippets and larger code blocks.

There are several ad-hoc case-by-case solutions, of course. I've been able to make \lstinline work within a \text command, being extra careful to escape certain characters. Sometimes I don't use \lstinline at all and format the code snippet by hand. Neither is really convenient.

Is there a generally applicable solution? Ideally I could just use \lstinline in math mode (well, its \lstMakeShortInline shortcut anyway) without any error. I do occasionally use mathescape inside code snippets. Having that still work would be nice, but is not essential.

  • 1
    just a wild guess ... if you're using amsmath, try wrapping the lstinline string in \text{...}. (i don't use listings, so this is totally off the wall.) – barbara beeton Aug 6 '13 at 19:13
  • @barbarabeeton Like I said, using \text sometimes works (I think the listings developer(s) had a hard time making that sort of thing work, actually). But then I need to escape special characters. All in all, it's more verbose than I'd like. My question is: can I make \lstinline work as is? – mhelvens Aug 6 '13 at 19:21
5

If you do not need the resizing feature of \text and a simple \hbox (\mbox) suffices, then the following redefinition patches the first \bgroup to add \hbox in math mode:

\documentclass{article}
\usepackage{listings}

\usepackage{letltxmacro}
\newcommand*{\SavedLstInline}{}
\LetLtxMacro\SavedLstInline\lstinline
\DeclareRobustCommand*{\lstinline}{%
  \ifmmode
    \let\SavedBGroup\bgroup
    \def\bgroup{%
      \let\bgroup\SavedBGroup
      \hbox\bgroup
    }%
  \fi
  \SavedLstInline
}

\lstset{basicstyle=\ttfamily}
\begin{document}
\centering
Text: \lstinline|\foo%&$bar|
\[
  x = \lstinline|\foo%&$bar|
\]
\end{document}

Result

Patching via package etoolbox:

\documentclass{article}
\usepackage{listings}

\usepackage{etoolbox}
\expandafter\patchcmd\csname \string\lstinline\endcsname{%
  \leavevmode
  \bgroup
}{%
  \leavevmode
  \ifmmode\hbox\fi
  \bgroup
}{}{%
  \typeout{Patching of \string\lstinline\space failed!}%
}

\lstset{basicstyle=\ttfamily}
\begin{document}
\centering
Text: \lstinline|\foo%&$bar|
\[
  x = \lstinline|\foo%&$bar|
\]
\end{document}
  • That will do just fine, thanks! :-) I've been trying to patch the command too, but my way was very convoluted (and didn't work). This is quite elegant. – mhelvens Aug 6 '13 at 21:19
  • The package code has a comment right at the line we're patching: % \hbox\bgroup --> \bgroup. Does this mean they once had an \hbox there but removed it? :-) I guess with the \hbox there, inline code cannot wrap around a newline (but no worries, I don't need that). – mhelvens Aug 6 '13 at 22:02

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.