8

How to add square brackets as a caption in a listing? I tried putting caption inside of "{}", but then the output is quiet weird.

\documentclass{article}

\usepackage{listings}

\begin{document}
    \begin{lstlisting}[caption={Algorithm [1] - example}]
    example
    \end{lstlisting}
\end{document}
Ivan
  • 167
  • Potential duplicate: [ ] inside an optional argument](https://tex.stackexchange.com/q/99495) In any event, the rules for nested square brackets are explained there. – barbara beeton Jan 02 '22 at 19:48
  • @barbarabeeton Don't think it's a duplicate of that one. Note that the problem still occur when the user wrap in a single brace group (some internal interference of packages make it so that 4 levels of nested brace groups is required to avoid the issue, or alternatively make it "unbreakable" (with TeX automatically remove brace groups) e.g. {{Algorithm [1] - example}\relax} – user202729 Jan 05 '22 at 14:17

2 Answers2

8
\begin{lstlisting}[caption={Algorithm \unexpanded{[1]} - example}]

works on me. or as Manuel said:

\begin{lstlisting}[caption={Algorithm {[1]} - example}]
MaestroGlanz
  • 2,348
  • 5
    Just {[1]} is enough. – Manuel May 29 '16 at 10:45
  • @Manuel I misunderstood, what he said. I thought, he meant, that this doesnt work. – MaestroGlanz May 29 '16 at 10:46
  • 1
    @Ivan You might have seen, that Latex used the [1] somehow. To prevent Latex from using stuff \noexpand or \unexpanded can help. If you have no output, it is one expansion to less or at the wrong point. But this happens only in rare cases. Apparently, in this case { } is enough. – MaestroGlanz May 29 '16 at 11:24
0

I think the problem is due to the way in which the \lstKV@OptArg-mechanism of the listings-package is defined:

Using listings 2020/03/24 Version 1.8d, the MWE

\documentclass{article}

\usepackage{listings}

\begin{document} \begin{lstlisting}[caption={Algorithm [1] - example}] example \end{lstlisting} \end{document}

yields the following output:

enter image description here

The caption-key is defined as follows:

3373 \lst@Key{caption}\relax{\lstKV@OptArg[{#1}]{#1}%
3374     {\def\lst@caption{##2}\def\lst@@caption{##1}}%
3375     \let\lst@title\@empty}

The \lstKV@OptArg-mechanism in turn is defined as follows:

431 \def\lstKV@OptArg[#1]#2#3{%
432     \gdef\@gtempa[##1]##2{#3}\lstKV@OptArg@{#1}#2\@}
433 \def\lstKV@OptArg@#1{\@ifnextchar[\lstKV@OptArg@@{\lstKV@OptArg@@[#1]}}
434 \def\lstKV@OptArg@@[#1]#2\@{\@gtempa[#1]{#2}}

Both \lstKV@OptArg@ and \lstKV@OptArg@@ pass arguments to other macros as ]-delimited arguments without taking into account the case of these arguments as well containing that delimiter, which at the time of carrying out these other macros yields erroneous matching-up of argument-delimiters.

If this is taken into account by having \lstKV@OptArg@ and \lstKV@OptArg@@ pass ]-delimited arguments nested between {..}, like in the example

\documentclass{article}

\usepackage{listings} \makeatletter \def\lstKV@OptArg@#1{@ifnextchar[\lstKV@OptArg@@{\lstKV@OptArg@@[{#1}]}}% \def\lstKV@OptArg@@[#1]#2@{@gtempa[{#1}]{#2}}% \makeatother

\begin{document} \begin{lstlisting}[caption={Algorithm [1] - example}] example \end{lstlisting} \end{document}

, then you get:

enter image description here

Ulrich Diez
  • 28,770