1

I want to define a flexible manner in which to include pieces of source code and/or figures to a group that acts as a floating figure environment.

The idea is to be able to select the counter with the parameter type of the command \insertCaption. If it is 'Listing' use one counter, if it is 'Figure', use the other.

The problem I am facing is that I cannot correctly select the counter. It displays well in the caption, but whenever I reference the group, it does not show the correct numbering.Please consider the following non-working example:

\documentclass{book}
\usepackage{geometry}
\geometry{margin=0.2in,papersize={8.5in,11in}}
\usepackage{graphicx}
\usepackage{pgfkeys}
\usepackage{subcaption}
\usepackage{ifthen}
\usepackage{listings}
\usepackage{xcolor}
\definecolor{lightgray}{gray}{0.9}

\makeatletter

\pgfkeys{/fig/entities/.cd,
    file/.initial={},
    width/.initial={},
    caption/.initial={},
    label/.initial={},
}
\def\fig@set@keys#1{\pgfkeys{/fig/entities/.cd,#1}}
\def\fig@get#1{\pgfkeysvalueof{/fig/entities/#1}}
\def\fig@set@defaults{\pgfkeys{/fig/entities/.cd,
    file/.initial={DUMMY},
    width/.initial={0.6},
    caption/.initial={},
    label/.initial={},
}}
\newcommand\insertFigure[1]{%%
    \fig@set@defaults%%
    \fig@set@keys{#1}%%
    \bgroup\begin{subfigure}[b]{\fig@get{width}\textwidth}%%
        \centering%%
        \includegraphics[width=1\textwidth]{\fig@get{file}}%%
        \ifthenelse{\NOT\equal{\fig@get{caption}}{}}{%%
            \ifthenelse{\equal{\fig@get{caption}}{abc}}{%%
                \caption{}%%
            }{%%
                \caption{\fig@get{caption}}%%
            }%%
            \ifthenelse{\NOT\equal{\fig@get{label}}{}}{%%
                \label{\fig@get{label}}%%
            }{}%%
        }{}%%
    \end{subfigure}\egroup%%
}


\pgfkeys{/code/entities/.cd,
    file/.initial={},
    width/.initial={},
    caption/.initial={},
    label/.initial={},
}
\def\code@set@keys#1{\pgfkeys{/code/entities/.cd,#1}}
\def\code@get#1{\pgfkeysvalueof{/code/entities/#1}}
\def\code@set@defaults{\pgfkeys{/code/entities/.cd,
    file/.initial={DUMMY},
    width/.initial={0.6},
    caption/.initial={},
    label/.initial={},
}}
\newcommand\insertCode[1]{%%
    \code@set@defaults%%
    \code@set@keys{#1}%%
    \bgroup\begin{subfigure}[b]{\code@get{width}\textwidth}%%
        \centering%%
        \fcolorbox{lightgray}{lightgray}{%%
            \begin{minipage}[t]{0.98\textwidth}
                \hspace{0pt}\vspace{-1pt}%% hack to align \fbox with \lstinputlisting.
                \lstinputlisting[basicstyle=\ttfamily\scriptsize]%%
                                {\code@get{file}}%%
            \end{minipage}%%
        }%%
        \ifthenelse{\NOT\equal{\code@get{caption}}{}}{%%
            \ifthenelse{\equal{\code@get{caption}}{abc}}{%%
                \caption{}%%
            }{%%
                \caption{\code@get{caption}}%%
            }%%
            \ifthenelse{\NOT\equal{\code@get{label}}{}}{%%
                \label{\code@get{label}}%%
            }{}%%
        }{}%%
    \end{subfigure}\egroup%%
}


\pgfkeys{/capt/entities/.cd,
    type/.initial={},
    caption/.initial={},
    label/.initial={},
}
\def\capt@set@keys#1{\pgfkeys{/capt/entities/.cd,#1}}
\def\capt@get#1{\pgfkeysvalueof{/capt/entities/#1}}
\def\capt@set@defaults{\pgfkeys{/capt/entities/.cd,
    type/.initial={Figure},
    caption/.initial={},
    label/.initial={},
}}
% counter for captions of type 'Figure' and 'Listing'
\newcounter{figurecounter}[chapter]
\newcounter{codecounter}[chapter]
\DeclareCaptionLabelFormat{figurefmt}{Figure~\thechapter.\thefigurecounter}
\DeclareCaptionLabelFormat{codefmt}{Listing~\thechapter.\thecodecounter}

\newcommand\insertCaption[1]{%%
    \capt@set@defaults%%
    \capt@set@keys{#1}%%
    \ifthenelse{\NOT\equal{\capt@get{caption}}{}}{%%
        \ifthenelse{\equal{\capt@get{type}}{Listing}}{%%
            \captionsetup{name=Listing}%%
            \refstepcounter{codecounter}%%
            \captionsetup{labelformat=codefmt}%%
        }{%%
            \captionsetup{name=Figure}%%
            \refstepcounter{figurecounter}%%
            \captionsetup{labelformat=figurefmt}%%
        }%%
        \ifthenelse{\equal{\capt@get{caption}}{abc}}{%%
            \caption{}%%
        }{%%
            \caption{\capt@get{caption}}%%
        }%%
        \ifthenelse{\NOT\equal{\capt@get{label}}{}}{%%
            \label{\capt@get{label}}%%
        }{}%%
    }{}%%
}

\newcommand\FloatingElements[1]{%%
    \begin{figure}[h!]\centering#1\end{figure}%%
}

\begin{document}
\chapter{Chapter One}
\FloatingElements{
  \insertFigure{
    file={figA},
    width=0.2,
    caption={abc},
  }\hfil%%
  \insertCode{
    file={textA.txt},
    width=0.3,
    caption={abc},
    label={the-first-text}
  }%%
  \insertCaption{
    type=Figure,
    caption={This is a figure with some text, use the Figure counter.},
    label={group1},
  }%%
}

\FloatingElements{
  \insertCode{
    file={textB.txt},
    width=0.8,
  }%%
  \insertCaption{
    type=Listing,
    caption={This is just text B, so use the Listing counter.},
    label={group2},
  }%%
}

\FloatingElements{
  \insertFigure{
    file={figB},
    width=0.2,
  }%%
  \insertCaption{
    type=Figure,
    caption={This is just a figure, so use the Figure counter.},
    label={group3},
  }%%
}

\FloatingElements{
  \insertCode{
    file={textC.txt},
    width=0.2,
    caption={abc},
    label={text-c}
  }\hfil%%
  \insertCode{
    file={textD.txt},
    width=0.2,
    caption={abc},
  }%%
  \insertCaption{
    type=Listing,
    caption={These are texts C and D, so use the Listing counter.},
    label={group4},
  }%%
}

\textbf{Cross references:}\\
Figure~\ref{group1} has the figureA and textA. Listing~\ref{the-first-text} is within the same Figure~\ref{group1}.\\
Listing~\ref{group2} only has the textB.\\
Figure~\ref{group3} only has the figureB.\\
Listing~\ref{group4} has the texts C and D. And sub-listing~\ref{text-c} is textC.

\end{document}

Assuming the text and image files are there, I get the following pdf:

PDF obtained from the above code

As it can be seen, the numbers from the caption and cross-references do not match.

8
  • 3
    If this is for real life: define a new float to use for code listings using one of the existing packages. That gets a new counter. You already have a counter for figures, so you don't need another there. If this is a learning exercise: \label has to come after \caption. Please provide code we can compile - so not snippets we have to figure out how to put together.
    – cfr
    Commented May 1 at 3:32
  • 1
    When I try to put your code together to reproduce your output, I don't get the output you show. I get: Figure 0.1: Fig1 Listing 0.1: Cod1 Figure 0.2: Fig2 then First pair of figures number: 1. First Code number: 1. Second Figure number: 2. Second Code number: 2. and finally Listing 0.2: Cod2.
    – cfr
    Commented May 1 at 3:39
  • Actually, the counter name for a caption is given by \@captype, (Floats are not counted or listed, only captions.) It is also used in \addcontentsline. Commented May 1 at 14:28
  • @cfr I just edited the question to provide a minimum (non)working example. The label is now placed after the caption.
    – onlycparra
    Commented May 1 at 20:20
  • 1
    @onlycparra I meant the images in the mwe package: example-image-a etc. You don't need to load the package - you can just use the images directly. Alternatively, just use draft when loading graphicx and specify the dimensions if they matter.
    – cfr
    Commented May 3 at 0:33

2 Answers 2

2

I'm not offering a solution because you've not clarified whether you're using this as a learning exercise or for real use, so I don't know which kind of answer to give.

This is an answer to the 'why?' rather than the 'how?'

Each time you use \caption inside a figure environment, the figure counter is incremented. Information is written to the .aux file for use in cross-references etc.

You've altered the appearance of the caption label format, but you've not touched the counter which is used. Your format doesn't use the counter used. That is, it doesn't use figure. So you don't see the value used in the figure environment itself. You see your custom counters only. But those aren't being used for the cross-reference. So when you reference it later, you get the information written to the .aux, which uses figure. And the format you've specified isn't active here, so the value of the counter is used this time.

To understand what's happening, look at the .aux:

\relax
\@writefile{toc}{\contentsline {chapter}{\numberline {1}Chapter One}{1}{}\protected@file@percent }
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\@writefile{lol}{\contentsline {lstlisting}{indentfirst.sty}{1}{}\protected@file@percent }
\providecommand*\caption@xref[2]{\@setref\relax\@undefined{#1}}
\newlabel{the-first-text}{{1.1b}{1}{}{}{}}
\newlabel{sub@the-first-text}{{b}{1}{}{}{}}

Note that these are using what we'd expect.

\@writefile{lof}{\contentsline {figure}{\numberline {1.1}{\ignorespaces This is a figure with some text, use the Figure counter.}}{1}{}\protected@file@percent }
\newlabel{group1}{{1.1}{1}{}{}{}}

Here's our first figure.

\@writefile{lol}{\contentsline {lstlisting}{indentfirst.sty}{2}{}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {1.2}{\ignorespaces This is just text B, so use the Listing counter.}}{2}{}\protected@file@percent }
\newlabel{group2}{{1.2}{2}{}{}{}}

Here we see the information written for the second float. Note the value written to the .aux is using the figure counter, even though this is not used anywhere in the format of the caption.

\@writefile{lof}{\contentsline {figure}{\numberline {1.3}{\ignorespaces This is just a figure, so use the Figure counter.}}{2}{}\protected@file@percent }
\newlabel{group3}{{1.3}{2}{}{}{}}
\@writefile{lol}{\contentsline {lstlisting}{indentfirst.sty}{3}{}\protected@file@percent }

So now we get 3 for the third float. Again, the value of figure isn't used in typesetting the captions.

\newlabel{text-c}{{1.4a}{3}{}{}{}}
\newlabel{sub@text-c}{{a}{3}{}{}{}}

Again, we get the figure counter incremented, even though this is not meant to be a figure because it is happening inside the figure environment.

\@writefile{lol}{\contentsline {lstlisting}{indentfirst.sty}{3}{}\protected@file@percent }
\@writefile{lof}{\contentsline {figure}{\numberline {1.4}{\ignorespaces These are texts C and D, so use the Listing counter.}}{3}{}\protected@file@percent }
\newlabel{group4}{{1.4}{3}{}{}{}}
\gdef \@abspage@last{3}

If you prefer to see what's happening in a compiled document, here's some code which may help. You'll have to compile it as my images are toast due to an Okular bug. Be warned: the actual output is extremely ugly.

% WHY? NOT HOW?
\documentclass{book}
\usepackage{geometry}
\geometry{margin=0.2in,papersize={8.5in,11in}}
\usepackage[draft]{graphicx}
\usepackage{pgfkeys}
\usepackage{subcaption}
\usepackage{ifthen}
\usepackage{listings}
\usepackage{xcolor}
\definecolor{lightgray}{gray}{0.9}

\makeatletter

\pgfkeys{/fig/entities/.cd,
    file/.initial={},
    width/.initial={},
    caption/.initial={},
    label/.initial={},
}
\def\fig@set@keys#1{\pgfkeys{/fig/entities/.cd,#1}}
\def\fig@get#1{\pgfkeysvalueof{/fig/entities/#1}}
\def\fig@set@defaults{\pgfkeys{/fig/entities/.cd,
    file/.initial={DUMMY},
    width/.initial={0.6},
    caption/.initial={},
    label/.initial={},
}}
\newcommand\insertFigure[1]{%%
  \fig@set@defaults%%
  \fig@set@keys{#1}%%
  \bgroup\begin{subfigure}[b]{\fig@get{width}\textwidth}%%
    \centering%%
    \includegraphics[width=1\textwidth]{\fig@get{file}}%%
    \ifthenelse{\NOT\equal{\fig@get{caption}}{}}{%%
      \ifthenelse{\equal{\fig@get{caption}}{abc}}{%%
        \caption{}%%
      }{%%
        \caption{\fig@get{caption}}%%
      }%%
      \ifthenelse{\NOT\equal{\fig@get{label}}{}}{%%
        \label{\fig@get{label}}%%
      }{}%%
    }{}%%
  \end{subfigure}\egroup%%
}


\pgfkeys{/code/entities/.cd,
    file/.initial={},
    width/.initial={},
    caption/.initial={},
    label/.initial={},
}
\def\code@set@keys#1{\pgfkeys{/code/entities/.cd,#1}}
\def\code@get#1{\pgfkeysvalueof{/code/entities/#1}}
\def\code@set@defaults{\pgfkeys{/code/entities/.cd,
    file/.initial={DUMMY},
    width/.initial={0.6},
    caption/.initial={},
    label/.initial={},
}}
\newcommand\insertCode[1]{%%
  \code@set@defaults%%
  \code@set@keys{#1}%%
  \bgroup\begin{subfigure}[b]{\code@get{width}\textwidth}%%
    \centering%%
    \fcolorbox{lightgray}{lightgray}{%%
      \begin{minipage}[t]{0.98\textwidth}
        \hspace{0pt}\vspace{-1pt}%% hack to align \fbox with \lstinputlisting.
        \lstinputlisting[basicstyle=\ttfamily\scriptsize]%%
        {\code@get{file}}%%
      \end{minipage}%%
    }%%
    \ifthenelse{\NOT\equal{\code@get{caption}}{}}{%%
      \ifthenelse{\equal{\code@get{caption}}{abc}}{%%
        \caption{}%%
      }{%%
        \caption{\code@get{caption}}%%
      }%%
      \ifthenelse{\NOT\equal{\code@get{label}}{}}{%%
        \label{\code@get{label}}%%
      }{}%%
    }{}%%
  \end{subfigure}\egroup%%
}


\pgfkeys{/capt/entities/.cd,
  type/.initial={},
  caption/.initial={},
  label/.initial={},
}
\def\capt@set@keys#1{\pgfkeys{/capt/entities/.cd,#1}}
\def\capt@get#1{\pgfkeysvalueof{/capt/entities/#1}}
\def\capt@set@defaults{\pgfkeys{/capt/ent    type/.initial={Figure},
    caption/.initial={},
    label/.initial={},ities/.cd,
    type/.initial={Figure},
    caption/.initial={},
    label/.initial={},
}}
% counter for captions of type 'Figure' and 'Listing'
\newcounter{figurecounter}[chapter]
\newcounter{codecounter}[chapter]
\DeclareCaptionLabelFormat{figurefmt}{Figure~\thechapter.\thefigurecounter}
\DeclareCaptionLabelFormat{codefmt}{Listing~\thechapter.\thecodecounter}

\newcommand\insertCaption[1]{%%
  \capt@set@defaults%%
  \capt@set@keys{#1}%%
  \ifthenelse{\NOT\equal{\capt@get{caption}}{}}{%%
    \ifthenelse{\equal{\capt@get{type}}{Listing}}{%%
      \captionsetup{name=Listing}%%
      \refstepcounter{codecounter}%%
      \captionsetup{labelformat=codefmt}%%
    }{%%
      \captionsetup{name=Figure}%%
      \refstepcounter{figurecounter}%%
      \captionsetup{labelformat=figurefmt}%%
    }%%
    \ifthenelse{\equal{\capt@get{caption}}{abc}}{%%
      \caption{}%%
    }{%%
      \caption{\capt@get{caption}}%%
    }%%
    \ifthenelse{\NOT\equal{\capt@get{label}}{}}{%%
      \label{\capt@get{label}}%%
    }{}%%
  }{}%%
}

\NewDocumentCommand \displaycounter { O {figure} }
{%
  \texttt{\textbackslash the#1} is \csname the#1\endcsname
}
\newcommand\FloatingElements[1]{%%
  \displaycounter
  \begin{figure}[ht!]
    \displaycounter
    
    \centering#1
    
    \displaycounter
  \end{figure}\par
  \displaycounter
}

\begin{document}
\chapter{Chapter One}
\FloatingElements{
  \insertFigure{
    file={example-image-a},
    width=0.2,
    caption={abc},
  }\hfil
  \insertCode{
    file={indentfirst.sty},
    width=0.3,
    caption={abc},
    label={the-first-text}
  }
  
  \displaycounter
%   \displaycounter[lstlisting]
  \insertCaption{
    type=Figure,
    caption={This is a figure with some text, use the Figure counter.},
    label={group1},
  }
  
  \displaycounter
%   \displaycounter[lstlisting]
}

\FloatingElements{
  \insertCode{
    file={indentfirst.sty},
    width=0.8,
  }%%
  \insertCaption{
    type=Listing,
    caption={This is just text B, so use the Listing counter.},
    label={group2},
  }%%
}

\FloatingElements{
  \insertFigure{
    file={example-image-b},
    width=0.2,
  }%%
  \insertCaption{
    type=Figure,
    caption={This is just a figure, so use the Figure counter.},
    label={group3},
  }%%
}

\FloatingElements{
  \insertCode{
    file={indentfirst.sty},
    width=0.2,
    caption={abc},
    label={text-c}
  }\hfil%%
  \insertCode{
    file={indentfirst.sty},
    width=0.2,
    caption={abc},
  }%%
  \insertCaption{
    type=Listing,
    caption={These are texts C and D, so use the Listing counter.},
    label={group4},
  }%%
}\displaycounter

\textbf{Cross references:}

Figure~\ref{group1} has the figureA and textA. Listing~\ref{the-first-text} is within the same Figure~\ref{group1}.

Listing~\ref{group2} only has the textB.

Figure~\ref{group3} only has the figureB.

Listing~\ref{group4} has the texts C and D. And sub-listing~\ref{text-c} is textC.

\end{document}
8
  • Thanks for the thorough answer, now I better understand what is going on. I forgot to mention that this is intended to be used in a real scenario, it is not a learning exercise. How should I approach this idea of "Having groups that act as floats, that are composed by combinations of code/images; where these groups can belong to different counting categories"?
    – onlycparra
    Commented May 2 at 20:53
  • 1
    @onlycparra Hard to say because I find it difficult to think about how it is supposed to work from the reader's perspective. Maybe this is a useful question: what should your lists of figures and listings show, for example? You can create as many types of floats as you want. (Well, there's a limit, but you can have a lot.) Each of those gets its own series and its own listing. So what makes sense in terms of the content? Should the mixed ones be figures, listings or a third type?
    – cfr
    Commented May 3 at 0:39
  • My use case is snippets of code that produce figures, these snippets are 1:1 related to the figure, so I thought it would be good idea to put them together, like Figure 1.1 in the question. Sometimes I will show the code and its generated figure, other times I, instead, will compare two or three figures side by side. sometimes just a figure... So I wanted to have a unified manner to incorporate both, the images and the code from external files. Having said that, I see your point, "what is a figure+text? I was thinking in "all is a figure unless it is only text". (thanks for the patience)
    – onlycparra
    Commented May 3 at 18:54
  • 1
    Are you aware @onlycparra there are already solutions for that? You might want to look at how it is done in the documentation of graphics packages, for example. prooftrees definitely has that kind of mixture: sometimes tree beside code, sometimes the code is separate etc. But that's probably not the best example. I think I'd go for a common numbering scheme: every float gets a number. Anything inside gets a sub-number if there's more than one. And you call them 'figures' or 'boxes' or whatever. But I don't know the context, so I can't really know whether that will make most sense for you.
    – cfr
    Commented May 3 at 20:51
  • 1
    @onlycparra I wouldn't worry. If it does something really bad, somebody will tell you. Otherwise, It's reasonable to expect people to judge for themselves. You might get a comment saying 'don't do this', but that's not a bad thing if there's some reason not to do it ;). In general, having separate series of floats is fine: figures, tables, listings of code. It's only that you seemed to want them to overlap and not overlap in a way I wasn't sure made sense. But as long as you keep them distinct, it's very usual and readers shouldn't have any trouble.
    – cfr
    Commented May 4 at 6:06
0

OP (I) was putting everything within a figure environment (see the \FloatingElements command) and just changing the appearance of the captions, but they were figure environments with their own figure counter anyway. That is why \ref didn't get the (according to me) "correct" number.

As pointed out by @cfr, you can create different floats! So I better create a new float code and instead of having just one \FloatingElements and a parameter type, now I have two \FigureGroup and \CodeGroup, each of them with their own counter.

Sorry I am still not using the package mwe, but assuming you have the figures and text files in the folder, here is a working example:

\documentclass{book}
\usepackage{geometry}
\geometry{margin=0.2in,papersize={8.5in,11in}}
\usepackage{xcolor}
\definecolor{lightgray}{gray}{0.9}

\usepackage{graphicx}
\usepackage{pgfkeys}
\usepackage{subcaption}
\usepackage{ifthen}
\usepackage{listings}

\makeatletter
%%%% FIGURE %%%%
\pgfkeys{/fig/entities/.cd,
  file/.initial={},
  width/.initial={},
  caption/.initial={},
  label/.initial={},
}
\def\fig@set@keys#1{\pgfkeys{/fig/entities/.cd,#1}}
\def\fig@get#1{\pgfkeysvalueof{/fig/entities/#1}}
\def\fig@set@defaults{\pgfkeys{/fig/entities/.cd,
  file/.initial={},
  width/.initial={0.6},
  caption/.initial={},
  label/.initial={},
}}
\newcommand\fig@addcontent{%%
  \ifthenelse{\NOT\equal{\fig@get{file}}{}}{%%
    \includegraphics[width=1\textwidth]{\fig@get{file}}%%
  }{}%%
  \ifthenelse{\NOT\equal{\fig@get{caption}}{}}{%%
    \ifthenelse{\equal{\fig@get{caption}}{abc}}{%%
      \caption{}%%
    }{%%
      \caption{\fig@get{caption}}%%
    }%%
    \ifthenelse{\NOT\equal{\fig@get{label}}{}}{%%
      \label{\fig@get{label}}%%
    }{}%%
  }{}%%
}


%%%% CODE %%%%
\pgfkeys{/code/entities/.cd,
  file/.initial={},
  width/.initial={},
  caption/.initial={},
  label/.initial={},
}
\def\code@set@keys#1{\pgfkeys{/code/entities/.cd,#1}}
\def\code@get#1{\pgfkeysvalueof{/code/entities/#1}}
\def\code@set@defaults{\pgfkeys{/code/entities/.cd,
  file/.initial={},
  width/.initial={0.6},
  caption/.initial={},
  label/.initial={},
}}
\newcommand\code@addcontent{%%
  \ifthenelse{\NOT\equal{\code@get{file}}{}}{%%
    \fcolorbox{lightgray}{lightgray}{%%
      \begin{minipage}[t]{0.98\textwidth}
        \hspace{0pt}\vspace{-1pt}%% hack to align \fbox with \lstinputlisting.
        \lstinputlisting[basicstyle=\ttfamily\scriptsize]{\code@get{file}}%%
      \end{minipage}%%
    }%%
  }{}%%
  \ifthenelse{\NOT\equal{\code@get{caption}}{}}{%%
    \ifthenelse{\equal{\code@get{caption}}{abc}}{%%
      \caption{}%%
    }{%%
      \caption{\code@get{caption}}%%
    }%%
    \ifthenelse{\NOT\equal{\code@get{label}}{}}{%%
      \label{\code@get{label}}%%
    }{}%%
  }{}%%
}


%%%% CAPTIONS %%%%
\pgfkeys{/capt/entities/.cd,
  caption/.initial={},
  label/.initial={},
}
\def\capt@set@keys#1{\pgfkeys{/capt/entities/.cd,#1}}
\def\capt@get#1{\pgfkeysvalueof{/capt/entities/#1}}
\def\capt@set@defaults{\pgfkeys{/capt/entities/.cd,
  caption/.initial={},
  label/.initial={},
}}
\newcommand\capt@addcontent{%%
  \ifthenelse{\NOT\equal{\capt@get{caption}}{}}{%%
    \ifthenelse{\equal{\capt@get{caption}}{abc}}{%%
      \caption{}%%
    }{%%
      \caption{\capt@get{caption}}%%
    }%%
    \ifthenelse{\NOT\equal{\capt@get{label}}{}}{%%
      \label{\capt@get{label}}%%
    }{}%%
  }{}%%
}

%%%%%%% FLOATING GROUPS AND THEIR COMPONENTS %%%%%%%
\usepackage{newfloat}
\DeclareFloatingEnvironment[
fileext=locode,
listname={List of Listings},
name=Listing,
placement=htbp,
within=chapter,
]{code}
\newcommand\FigureGroup[1]{\begin{figure}[h!]\centering#1\end{figure}}
\newcommand\CodeGroup[1]{\begin{code}[h!]\centering#1\end{code}}
\newcommand\addFigure[1]{%%
  \fig@set@defaults%%
  \fig@set@keys{#1}%%
  \bgroup%%
  \ifthenelse{\equal{\@currenvir}{figure}}{%%
    \begin{subfigure}[b]{\fig@get{width}\textwidth}\centering%%
      \fig@addcontent%%
    \end{subfigure}%%
  }{\ifthenelse{\equal{\@currenvir}{code}}{%%
    \begin{subcode}[b]{\fig@get{width}\textwidth}\centering%%
      \fig@addcontent%%
    \end{subcode}%%
  }{}}%%
  \egroup%%
}
\newcommand\addCode[1]{%%
  \code@set@defaults%%
  \code@set@keys{#1}%%
  \bgroup%%
  \ifthenelse{\equal{\@currenvir}{figure}}{%%
    \begin{subfigure}[b]{\code@get{width}\textwidth}\centering%%
      \code@addcontent%%
    \end{subfigure}%%
  }{\ifthenelse{\equal{\@currenvir}{code}}{%%
    \begin{subcode}[b]{\code@get{width}\textwidth}\centering%%
      \code@addcontent%%
    \end{subcode}%%
  }{}}%%
  \egroup%%
}
\newcommand\addCaption[1]{%%
  \capt@set@defaults%%
  \capt@set@keys{#1}%%
  \capt@addcontent%%
}

\makeatother


\begin{document}
\chapter{Chapter One}

\FigureGroup{%%
  \addFigure{
    file={figA},
    width=0.2,
    caption={abc},
  }\hfil%%
  \addCode{
    file={textA.txt},
    width=0.3,
    caption={abc},
    label={the-first-text},
  }%%
  \addCaption{
    caption={This is a figure with some text, use the Figure counter.},
    label={group1},
  }%%
}

\CodeGroup{%%
  \addCode{
    file={textB.txt},
    width=0.8,
  }%%
  \addCaption{
    caption={This is just text B, so use the Listing counter.},
    label={group2},
  }%%
}

\FigureGroup{%%
  \addFigure{
    file={figB},
    width=0.2,
  }%%
  \addCaption{
    caption={This is just a figure, so use the Figure counter.},
    label={group3},
  }%%
}

\CodeGroup{%%
  \addCode{
    file={textC.txt},
    width=0.2,
    caption={abc},
    label={text-c}
  }\hfil%%
  \addCode{
    file={textD.txt},
    width=0.2,
    caption={abc},
  }%%
  \addCaption{
    caption={These are texts C and D, so use the Listing counter.},
    label={group4},
  }%%
}

\textbf{Cross references:}\\
Figure~\ref{group1} has the figureA and textA. Listing~\ref{the-first-text} is within the same Figure~\ref{group1}.\\
Listing~\ref{group2} only has the textB.\\
Figure~\ref{group3} only has the figureB.\\
Listing~\ref{group4} has the texts C and D. And sub-listing~\ref{text-c} is textC.

\end{document}

The resulting pdf is this: enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .