3

I try to create a floating environment with a layout similar to this:

_____________________  ___________________
|                    | |                 |
|                    | |                 |
|                    | |                 |
_____________________  ___________________
(a) First sublisting   (c) Third sublisting

__________________________________________
|                                        |
|                                        |
|                                        |
__________________________________________
             (b) Second sublisting

Listing 3.1: Main caption for all sublistings

I use \usepackage{subcaption} and \usepackage{lstlisting}

My current approach is that I put the three listings in subfigures inside a figure. Afterwards I use several tricks:

  1. In the figure I use \captionof{lstlisting}{Main caption for all sublistings} to explicitly use a listing caption instead a caption for a figure
  2. Although I use \captionof{lstlisting}{...}, the counter for figures is increased. Thus I manually decrease it after the figure environment via \addtocounter{figure}{-1}.
  3. Although I use \captionof{lstlisting}{...}, an \autoref{} to this figure prints "Figure 3.1" instead "Listing 3.1". Thus I have to reference it via Listing \ref{...}

With this approach the listings are laid out correct, have subcaptions and a main caption and are in a floating environment. They appear in the correct list (list of figures vs. list of listings) and references use the correct naming.

My question is: Is there an easier way of doing this? Manually modifying the index of figures and using \ref instead \autoref just feels kind of wrong.

Is it possible to tell the figure environment to increase its counter only if its caption is actually a caption for figures? Is it possible to modify \autoref to use the correct reference when \captionof{lstlisting}{...} in a figure is used?

Example

\documentclass[a4paper]{book}
\usepackage{subcaption}
\usepackage{listings}
\usepackage{hyperref}

\begin{document}

This is a reference to Listing~\ref{lst:mylisting}.
In contrast to this, autoref prints \autoref{lst:mylisting}.

\begin{figure}[tb]
    \begin{subfigure}[t]{0.45\textwidth}
        \renewcommand{\thesubfigure}{a}
        \begin{lstlisting}
bla bla
        \end{lstlisting}
        \caption{First listing}
    \end{subfigure}
    \hfill
    \begin{subfigure}[t]{0.45\textwidth}
        \renewcommand{\thesubfigure}{c}
        \begin{lstlisting}
bla bla
        \end{lstlisting}
        \caption{Third listing}
    \end{subfigure}

    \vspace{10mm}

    \begin{subfigure}[t]{1\textwidth}
        \renewcommand{\thesubfigure}{b}
        \begin{lstlisting}
bla bla
        \end{lstlisting}
        \caption{Second listing}
    \end{subfigure}
    \captionof{lstlisting}{Main caption for all sublistings}
    \label{lst:mylisting}
\end{figure}
% modify numbering of figures
\addtocounter{figure}{-1}

\begin{figure}[tb]
    \caption{A following figure with correct numbering}

    This is the figure content
\end{figure}

\listoffigures
\lstlistoflistings

\end{document}
  • If you use cleveref, as in \usepackage{hyperref} \usepackage{cleveref} and them cref prints \cref{lst:mylisting} you get the right name. – Gonzalo Medina Sep 26 '15 at 14:04
  • I got an additional issue: How can I reference the subfigures? Not only that they are referenced via Figure x, but they are also referenced with the index of the figure instead of the listing. – mihca Sep 26 '15 at 19:19
1

I suggest you set up a correct subcaption type, then you can use the \subcaption command directly. In the "figure" containing listings, just declare use \setcaptiontype to lstlisting to get it in the correct sequence separate from figures. With cleveref you can get correct references.

Sample output

\documentclass[a4paper]{book}

\usepackage{subcaption}
\usepackage{listings}
\usepackage{hyperref}
\usepackage{cleveref}

\AtBeginDocument{\DeclareCaptionSubType{lstlisting}}
\crefname{sublstlisting}{listing}{listings}
\Crefname{sublstlisting}{Listing}{Listings}

\begin{document}

This is a reference to Listing~\ref{lst:mylisting}.
In contrast to this, cleveref prints \cref{lst:mylisting} and \cref{sublst:b}.

\begin{figure}[tb]
  \setcaptiontype{lstlisting}
    \begin{minipage}[t]{0.45\textwidth}
        \begin{lstlisting}
bla bla
        \end{lstlisting}
        \subcaption{First listing}
        \label{sublst:a}
    \end{minipage}
    \hfill
    \begin{minipage}[t]{0.45\textwidth}
      \begin{lstlisting}
bla bla
        \end{lstlisting}
        \subcaption{Second listing}
        \label{sublst:b}
    \end{minipage}

    \vspace{10mm}

    \begin{minipage}[t]{1\textwidth}
        \begin{lstlisting}
bla bla
        \end{lstlisting}
        \subcaption{Third listing}
        \label{sublst:c}
    \end{minipage}
    \caption{Main caption for all sublistings}
    \label{lst:mylisting}
\end{figure}

\begin{figure}[tb]
    \caption{A following figure with correct numbering}

    This is the figure content
\end{figure}

\listoffigures
\lstlistoflistings

\end{document}

Note the declaration of the subtype for listings has to be postponed to the beginning of the document, as that is when the corresponding float type is first definied.

I will let you play with the counter values to get your non-standard ordering of labels.

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.