The problem is, that caption
need to internally typeset the caption more than once, to do the single line check and either print the single or the multi line caption. So with option singlelinecheck=false
, the problem already does not occur but results in a different alignment of single line captions:
\documentclass{article}
\usepackage{graphicx}
\usepackage[singlelinecheck=false]{caption}
\newcounter{counter}
\setcounter{counter}{1}
\begin{document}% Moved to do all declarations in the preamble!
\begin{figure}
\includegraphics{example-image}
\caption
{
\thecounter
\protect\stepcounter{counter}
\thecounter
\protect\stepcounter{counter}
\thecounter
\protect\stepcounter{counter}
}
\end{figure}
\end{document}
Package caption
also provides a hook to execute some code before doing the single line check. So you could deactivate \stepcounter
inside the single line check:
\documentclass{article}
\usepackage{graphicx}
\usepackage{caption}
\newcounter{counter}
\setcounter{counter}{1}
\makeatletter
\AtCaptionSingleLineCheck{\let\stepcounter\@gobble}
\makeatother
\begin{document}% Moved to do all declarations in the preamble!
\begin{figure}
\includegraphics{example-image}
\caption
{
\thecounter
\protect\stepcounter{counter}
\thecounter
\protect\stepcounter{counter}
\thecounter
\protect\stepcounter{counter}
}
\end{figure}
\end{document}
But note, that with this very simple deactivation of \stepcounter
the decision to use a single line caption instead of a multi line caption can be wrong, i.e., if one of the \stepcounter
would change the number of digits of the counter (or generally the output width). So maybe using
\documentclass{article}
\usepackage{graphicx}
\usepackage{caption}
\newcounter{counter}
\setcounter{counter}{1}
\makeatletter
\AtCaptionSingleLineCheck{%
\renewcommand*{\stepcounter}[1]{\expandafter\advance\@nameuse{c@#1}\@ne\relax}%
}
\makeatother
\begin{document}% Moved to do all declarations in the preamble!
\begin{figure}
\includegraphics{example-image}
\caption
{
\thecounter
\protect\stepcounter{counter}
\thecounter
\protect\stepcounter{counter}
\thecounter
\protect\stepcounter{counter}
}
\end{figure}
\end{document}
would be better.
Note: Both solutions do only work as long as the single line check is done inside a group (as it is currently and IMHO will be in future, too).
Caveat: You are also writing \setcounter{counter}
to the lof
-file. So adding \listoffigures
will also change your result, because the counter
will also be increased while printing the List of Figures. So the LoF will not show the same numbers as the caption itself. However, this wasn't the question. So if you need an answer how to change this, please ask another question.
\stepcounter
may be evaluated a variable number of times, depending on the length of the caption. The standard code (like the caption package code) evaluates the caption first as a single line and if that is too wide re-evaluates it as a paragraph, and if you have\listoffigures
it will be evaluated again in the list.