[Tex/LaTex] Package caption Warning: The caption type was already set to `quadro’ on input line 38

captionsenvironmentslistingsminted

With the following minimal example, there are the nested environments code and quadro, where both use captionsetup. And when building the the example, I got the warning: Package caption Warning: The caption type was already set to `quadro' on input line 38.See the caption package documentation for explanation

I managed to fix it by replacing the line \captionsetup[quadro]{skip=1mm} by \AtBeginEnvironment{quadro}{\captionsetup{skip=1mm}}.

But I do not understand what is happening. Reading the documentation it says:

The caption type was already set to ‘htypei’.
This warning informs you about mixed caption options. For example if you use a \captionsetup{type=table} or \captionof{table}{. . . } inside a figure environment,
this would result in using both option sets for that specific caption, the one for figure
(specified with \captionsetup[figure]{. . .}) and the one for table (specified with
\captionsetup[table]{. . . }) as well.
(You can suppress this warning by using the starred form \captionsetup*{type=. . .}.)
(See section 3.2: Setting options)

Why replacing \captionsetup[quadro]{skip=1mm} by \AtBeginEnvironment{quadro}{\captionsetup{skip=1mm}} fixes the warning?

\documentclass[
brazilian,brazil,
12pt, % Padrão UFSC para versão final
a4paper, % Padrão UFSC para versão final
twoside, % Impressão nos dois lados da folha
chapter=TITLE, % Título de capítulos em caixa alta
section=TITLE, % Título de seções em caixa alta
]{abntex2}

\usepackage{caption}
\usepackage{listings}
\usepackage[newfloat,chapter]{minted}

\newenvironment{code}{
  \captionsetup{type=listing}
}{}

\AtBeginEnvironment{code}{\setcounter{listing}{\value{lstlisting}}
  \captionsetup{skip=0pt}
}

\def\listofquadrosname{List of Frames}
\def\quadrosname{Frame}
\DeclareFloatingEnvironment[fileext=loq,placement={!hbtp},name=\quadrosname,within=chapter,listname=\listofquadrosname]{quadro}

\captionsetup[quadro]{skip=1mm}
% \AtBeginEnvironment{quadro}{\captionsetup{skip=1mm}}

\begin{document}

\begin{quadro}[h]
\caption{Example}
    \begin{code}
    \caption{File}
    Something.
    \end{code}
\end{quadro}

\end{document}

Best Answer

At \begin{quadro} the caption type is set to quadro and any options declared with \captionsetup[quadro]{...} will be applied.

At \begin{code} the caption type is set to listings (since code is defined that way) and any options declared with \captionsetup[listings]{...} will be applied.

If you put a code inside a quadro you end up with a mixture of both options, the ones declared with \captionsetup[quadro]{...} and the ones declared with \captionsetup[listings]{...}. As a result a caption inside a regular code looks different than a caption inside a code which is placed inside a quadro, for example:

\documentclass{article}
\usepackage{caption,newfloat}
\DeclareFloatingEnvironment{listing}
\DeclareFloatingEnvironment{quadro}
\newenvironment{code}{\captionsetup{type=listing}}{}

\captionsetup[quadro]{font=it}

\begin{document}

\begin{code}
\caption{Test}
\end{code}

\begin{quadro}
\begin{code}
\caption{Test}
\end{code}
\end{quadro}

\end{document}

Both captions look different although both are captions of code.

In most cases this is an unwanted effect and something the user doesn't want to get. All captions of code should be formatted the same way, at least that is the common expectation.

For this reason the caption package issue a warning if such mixture of options from different environments happens.

Now to the second part of the question:

If \captionsetup[quadro]{...} is not used the warning disappears. The caption package knows that quadro does not have any special options anymore, and therefore a caption inside code will be formatted the same way as a caption inside code placed inside quadro.

But what about this document:

\documentclass{article}
\usepackage{caption,newfloat}
\DeclareFloatingEnvironment{listing}
\DeclareFloatingEnvironment{quadro}
\newenvironment{code}{\captionsetup{type=listing}}{}

\begin{document}

\begin{code}
\caption{Test}
\end{code}

\begin{quadro}
\captionsetup{font=it}
\begin{code}
\caption{Test}
\end{code}
\end{quadro}

\end{document}

This code has exactly the same output as the one above, but no warning is issued here, why? Because in this case the option "font=it" was placed inside the environment explicitly by the user, so here the caption package assumes the user knows what he it doing.

Same with \AtBeginEnvironment{quadro}{\captionsetup{font=it}}. Since the caption packages does not know if \captionsetup{font=it} is part of a macro or not, it classifies this change as "explicit" (and not implicit) and therefore does not issue a warning.

I hope this answer makes it more clear why the caption package behaves this way. If there are any questions left, please don't hesitate to ask.