0
\documentclass{article}
\usepackage{listings}
\usepackage{biblatex}
\usepackage{filecontents}

\addbibresource{\jobname.bib}

\begin{filecontents}{\jobname.bib}
@book{foo}
\end{filecontents}

\begin{document}
This is normal text. Text taken from~\cite[Chapter~x]{foo}.

\begin{lstlisting}[caption={This is the caption. Code taken from~\cite[Chapter~x]{foo}}]
clear all;
\end{lstlisting}

\end{document}

This is the actual result:

enter image description here


Why does it show the actual name of the reference (foo) in the caption and how can I remove that part?

The caption should simply be This is the caption. Code taken from [1, Chapter x].

  • 1
    @book{foo} is not a valid .bib entry for Biber, so this causes an unrelated error in your example. To focus the example on the relevant bit, I suggest you switch from \addbibresource{\jobname.bib} to \addbibresource{biblatex-examples.bib} and turn \cite[Chapter~x]{foo} into \cite[Chapter~x]{sigfridsson}. – moewe Feb 17 '22 at 21:01
  • 1
    The same issue can also be reproduced with the kernel definition of \cite (https://gist.github.com/moewew/225c27df94925608d410088bc37141cf), suggesting that this is not a biblatex-related issue, but a problem with listings grabbing or processing the caption. – moewe Feb 17 '22 at 21:14

1 Answers1

1

You can get the desired output if you change your curly braces a bit. The MWE below shows two possible solutions.

\documentclass{article}
\usepackage{listings}
\usepackage{biblatex}

\addbibresource{biblatex-examples.bib}

\begin{document} This is normal text. Text taken from~\cite[Chapter~x]{sigfridsson}.

\begin{lstlisting}[caption=This is the caption. Code taken from~{\cite[Chapter~x]{sigfridsson}}] clear all; \end{lstlisting}

\begin{lstlisting}[caption={{{{This is the caption. Code taken from~\cite[Chapter~x]{sigfridsson}}}}}] clear all; \end{lstlisting}

\end{document}

Listing 1: This is the caption. Code taken from [1, Chapter x]
Listing 2: This is the caption. Code taken from [1, Chapter x]

First of all, we need at least one pair of curly braces to 'hide' the square brackets for the optional argument of \cite inside the square brackets for the optional lstlisting. If we don't hide the brackets, the optional argument is not parsed correctly. (See ] inside an optional argument)

Unfortunately, the straightforward idea of just using one pair of curly braces for the entire caption does not work reliably. That is because the optional argument of lstlisting is parsed as a key-value option list. There are different key-value implementation in the LaTeX world (A big list of every keyval package), the one used here (the well-known keyval) strips up to two layers of outer braces from the argument during processing. I haven't traced what exactly happens on the listings side, but it is possible that additional processing steps strip additional outer layer of braces and do not take measures to stop square brackets from breaking in optional arguments.

So one solution is to brace not the entire caption, but only the bit that needs it. This works with comparably few braces, because they braces are not stripped during processing (as they are not outer braces). Another solution is to us as many outer braces as necessary to make sure not all of them are stripped away. Trial and error suggests four pairs of braces are needed here (on general you can't tell how many pairs of braces are needed in advance without tracing the code).

moewe
  • 175,683