2

I'm using the listings package with verbatim code in Table \caption commands. When I stay away from TeX command sequences (texcsstyle in listings), all is well, as for example when I use only an emphstyle identifier.

When I use a texcsstyle TeX command sequence like \lstinline|\newcommand|, I first have to escape the \ because I'm using the \lstinline inside the argument of \caption, so I use \caption{\lstinline|\\newcommand|}. (In the below MWE, I include the troublesome text within a \section command to confirm that, when properly escaped, \newcommand is formatted with texcsstyle (blue).)

But I still don't get satisfactory results. Exactly what happens depends on whether I load the caption package.

  • Without also loading the caption package, no caption is displayed in the List of Tables. (The "1" for Table 1 is displayed, but only empty text for the caption itself on that line.)
  • If I load the caption package, a caption is displayed. However, (a) \newcommand is formatted as basicstyle (red) rather than as texcsstyle (blue) and (b) newcommand is displayed without its prefixing \.

I know the following workaround: Specify optional text for the List of Tables: \caption[optional text]{original text} and format the optional text by hand.

I'm asking (a) can I can salvage the automatically correct behavior (that I get using emph identifiers) when I use texcs identifiers?

Further, out of curiosity,

(b) why does loading the caption package partially salvage what was otherwise the total fail of a blank caption line in the List of Tables?

(c) Why do I have a problem with texcsstyle but not the other styles (which aren't LaTeX specific)?

Here's my MWE:

\documentclass{article}
\usepackage{listings,xcolor}
\usepackage{caption}
\lstset{language=[LaTeX]TeX,%
    basicstyle=\color{red}\ttfamily,%
    emphstyle=\color{green},%
    texcsstyle=*\color{blue},%
    moreemph={mykey}%
    }
\begin{document}
\listoftables
\bigskip
\section{Caption 1 text outside of caption: Emph: \lstinline|mykey|; texcs: \lstinline|\\newcommand|}
\noindent
Caption 1 text outside of caption: Emph: \lstinline|mykey|; texcs: \lstinline|\newcommand|\\
Caption 2 text outside of caption: Only Emph: \lstinline|mykey|
\begin{table}[h]
    \caption{1 Emph: \lstinline|mykey|; texcs: \lstinline|\\newcommand|}
    \begin{tabular}{|c|c|}
    \hline
       x  &  y\\
         \hline
    \end{tabular}
\end{table}
\begin{table}[h]
    \caption{2 Only Emph: \lstinline|mykey|}
    \begin{tabular}{|c|c|}
    \hline
       x  &  y\\
         \hline
    \end{tabular}
\end{table}
\end{document}

With the caption package loaded I see: enter image description here

When I comment-out the caption package, the List of Tables looks like: enter image description here

  • @DavidCarlisle, that seems too strong a statement w.r.t. \lstinline because the listings documentation, §5.1, "Listings inside arguments," and §4.1 at #5, specifies how to escape {}\#% in order to include \lstinline in an argument. And indeed it works fine within \footnote{}, \section{}, and \mbox{}. It even works fine for \caption in as far as producing the caption to the table. The problem is when those captions are compiled for a List of Tables. The problem seems more-specific than that general principle. – Jim Ratliff Oct 1 '18 at 18:20
  • Oh unfair ploy, quoting documentation at me:-) I guess so (I'll delete the comment) – David Carlisle Oct 1 '18 at 18:25
  • so it's fragile command in moving argument problem, – David Carlisle Oct 1 '18 at 18:26
2

If you look in the .lot file you can see the problem

\contentsline {table}{\numberline {1}{\ignorespaces 1 Emph: \lstinline |mykey|; texcs: \lstinline | newcommand|\relax }}{1}
\contentsline {table}{\numberline {2}{\ignorespaces 2 Only Emph: \lstinline |mykey|\relax }}{1}

some commands have been made safe to stop them expanding but the end result is that it is corrupted, notably the \\ before\newcommand (\listinlines special definition didn't take effect as it was prevented from expanding so it was written as \lstinline to the lot file.

Simplest is probably to hide the listings in custom robust commands

\documentclass{article}
\usepackage{listings,xcolor}
\usepackage{caption}
\lstset{language=[LaTeX]TeX,%
    basicstyle=\color{red}\ttfamily,%
    emphstyle=\color{green},%
    texcsstyle=*\color{blue},%
    moreemph={mykey}%
    }
\begin{document}
\DeclareRobustCommand\lstA{\lstinline|\\newcommand|}
\DeclareRobustCommand\lstB{\lstinline|mykey|}
\listoftables
\bigskip
\section{Caption 1 text outside of caption: Emph: \lstinline|mykey|; texcs: \lstinline|\\newcommand|}
\noindent
Caption 1 text outside of caption: Emph: \lstinline|mykey|; texcs: \lstinline|\newcommand|\\
Caption 2 text outside of caption: Only Emph: \lstinline|mykey|
\begin{table}[h]
    \caption{1 Emph: \lstB; texcs: \lstA}
    \begin{tabular}{|c|c|}
    \hline
       x  &  y\\
         \hline
    \end{tabular}
\end{table}
\begin{table}[h]
    \caption{2 Only Emph: \lstB}
    \begin{tabular}{|c|c|}
    \hline
       x  &  y\\
         \hline
    \end{tabular}
\end{table}
\end{document}
| improve this answer | |
  • That's awesome. It looks like you need only \lstA but don't need \lstB because mykey doesn't include any of the tricky characters ({}#%). Note that you didn't substitute \lstB in Caption 1 and it still displayed correctly in the caption of Table 1. – Jim Ratliff Oct 1 '18 at 18:46
  • 1
    @JimRatliff yes I was trying to suggest doing doing it always rather than getting lucky in some cases and avoiding doing it, as you won't always get a tex error and it's not always obvious what characters survive the lot file, so consistently avoiding the problem rather than checking every case by eye seems like a safer plan (I'll fix the lstB in caption 1:-) – David Carlisle Oct 1 '18 at 18:51

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.