# Why subfig renders wrong caption numbering with custom macro?

Subfigures display the wrong caption number when wrapping them in a custom macro. The funny thing is, without the macro, but with technically the same commands, the caption numbers are correct.

With this code:

\documentclass[a4paper]{scrbook}

\usepackage{subfig}
\usepackage{graphicx}
\usepackage{calc}
\usepackage{ifthen,changepage}

\begin{document}

\newlength{\alength}
\newlength{\blength}
\newcommand{\widefloat}[1]{%
\setlength{\alength}{\textheight-\pagetotal}
\setlength{\blength}{\totalheightof{\parbox{\linewidth}{#1}}}
\ifdim\alength<\blength\clearpage\fi
\ifthispageodd{\noindent\makebox[\textwidth][l]{#1}}{\noindent\makebox[\textwidth][r]{#1}}
}

\begin{figure}
%\noindent\makebox[\textwidth][r]{
\widefloat{
\subfloat[]{\includegraphics[scale=.5]{example-image-a}}
\subfloat[]{\includegraphics[scale=.5]{example-image-b}}}
\caption{ Two foo figures. }%
\end{figure}

\end{document}


We get wrong caption labels (c and d):

Now, if we switch the two lines:

  %\noindent\makebox[\textwidth][l]{
\widefloat{


to

  \noindent\makebox[\textwidth][l]{
%\widefloat{


The result is this image:

I cannot figure out what's wrong given that the two lines should technically be interpreted the same way. The widefloat macro is supposed to detect if whatever is inside it is on an odd or even page. Then it flushes the contents to either the left or right margin.

• You're typesetting the captions twice, one for measuring them, the other one for actually printing them. What's the purpose of the measure, if you use a figure environment anyway? – egreg Oct 26 '18 at 17:25
• Measuring is needed because the macro ifthispageodd reads the aux file to figure out the page number. The problem is that the rendered figure can later change pages if it doesn't fit where it was originally placed. – UndeadKernel Oct 26 '18 at 17:53

The code is meant to typeset the “float” not as a real float, but “just there”.

If you plan to use \widefloat in a figure environment the measuring is completely unnecessary. This solves the issue with the subfigure labels, because they're not typeset twice any longer.

\documentclass[a4paper]{scrbook}

\usepackage{subfig}
\usepackage{graphicx}

\begin{document}

\newcommand{\widefloat}[1]{%
\centering
\ifthispageodd
{\makebox[\textwidth][l]{#1}}%
{\makebox[\textwidth][r]{#1}}%
}

\begin{figure}
\widefloat{
\subfloat[]{\includegraphics[scale=.5]{example-image-a}}
\subfloat[]{\includegraphics[scale=.5]{example-image-b}}
}
\caption{Two foo figures.}
\end{figure}

\begin{figure}
\widefloat{
\subfloat[]{\includegraphics[scale=.5]{example-image-a}}
\subfloat[]{\includegraphics[scale=.5]{example-image-b}}
}
\caption{Two foo figures.}
\end{figure}

\begin{figure}
\widefloat{
\subfloat[]{\includegraphics[scale=.5]{example-image-a}}
\subfloat[]{\includegraphics[scale=.5]{example-image-b}}
}
\caption{Two foo figures.}
\end{figure}

\begin{figure}
\widefloat{
\subfloat[]{\includegraphics[scale=.5]{example-image-a}}
\subfloat[]{\includegraphics[scale=.5]{example-image-b}}
}
\caption{Two foo figures.}
\end{figure}

\end{document}


With some changes, you can also get the (global) caption to be left or right flush, if it fits one line.

\documentclass[a4paper]{scrbook}

\usepackage{subfig}
\usepackage{graphicx}

\DeclareCaptionStyle{singleleft}[justification=raggedright]{}
\DeclareCaptionStyle{singleright}[justification=raggedleft]{}

\newcommand{\widecaption}{%
\ifthispageodd
{\captionsetup{style=singleleft}}
{\captionsetup{style=singleright}}
\caption
}

\begin{document}

\newcommand{\widefloat}[1]{%
\centering
\ifthispageodd
{\makebox[\textwidth][l]{#1}}%
{\makebox[\textwidth][r]{#1}}%
}

\begin{figure}
\widefloat{
\subfloat[]{\includegraphics[scale=.5]{example-image-a}}
\subfloat[]{\includegraphics[scale=.5]{example-image-b}}
}
\widecaption{Two foo figures.}
\end{figure}

\begin{figure}
\widefloat{
\subfloat[]{\includegraphics[scale=.5]{example-image-a}}
\subfloat[]{\includegraphics[scale=.5]{example-image-b}}
}
\widecaption{Two foo figures.}
\end{figure}

\begin{figure}
\widefloat{
\subfloat[]{\includegraphics[scale=.5]{example-image-a}}
\subfloat[]{\includegraphics[scale=.5]{example-image-b}}
}
\widecaption{Two foo figures.}
\end{figure}

\begin{figure}
\widefloat{
\subfloat[]{\includegraphics[scale=.5]{example-image-a}}
\subfloat[]{\includegraphics[scale=.5]{example-image-b}}
}
\widecaption{Two foo figures.}
\end{figure}

\end{document}


As @egreg explained in his comment, the issue is that you actually typeset everything twice. Typesetting it only once and later using the saved box does solve your issue:

\documentclass[a4paper]{scrbook}

\usepackage{subfig}
\usepackage{graphicx}

\begin{document}

\newlength{\alength}
\newlength{\blength}
\newsavebox\widefloatBox
\newcommand{\widefloat}[1]
{%
\setlength{\alength}{\dimexpr\textheight-\pagetotal\relax}%
\sbox\widefloatBox{\parbox{\linewidth}{#1}}%
\setlength{\blength}{\dimexpr\ht\widefloatBox+\dp\widefloatBox\relax}%
\ifdim\alength<\blength\clearpage\fi
\ifthispageodd
{\noindent\makebox[\textwidth][l]{\usebox\widefloatBox}}
{\noindent\makebox[\textwidth][r]{\usebox\widefloatBox}}%
}

\begin{figure}
\widefloat
{%
\subfloat[]{\includegraphics[scale=.5]{example-image-a}}
\subfloat[]{\includegraphics[scale=.5]{example-image-b}}
}%
\caption{Two foo figures.}%
\end{figure}

\end{document}