The floating behaviour and exchange is very intricate. My suggestion would be to lay out your document as you normally would without regard for any of the \label
-\ref
requirements you mention. And then, at the end, worry about possibly shuffling things around.
What I propose is to tap into \ref
and let it give you an indication of whether or not the \label
it references is occurs before or after the current position. Below I've redefined \ref
to issue a warning if it doesn't meet your restrictions - things is something you can easily check at the end of your compilation. Since the suggested solution uses the \label
-\ref
system itself, you may have to compile at least twice on the first go.
Here is a minimal example that can be adapted:
\documentclass{article}
\usepackage{lipsum,graphicx,refcount}
\makeatletter
\setrefcountdefault{99999}
\let\oldref\ref
\renewcommand{\ref}[1]{%
\label{#1*}%
\ifnum\getpagerefnumber{#1*}<\getpagerefnumber{#1}% \ref on page < \label
\@latex@warning{...figure `#1' is on page \getpagerefnumber{#1},
but referenced on \getpagerefnumber{#1*}}%
\fi
\oldref{#1}%
}
\makeatother
\begin{document}
\sloppy% Just for this example
\tableofcontents
\listoffigures
\section{A section}
\lipsum[1-50]
Figure~\ref{fig:first}. % This is fine...
Figure~\ref{fig:second}.% ...but this creates a warning.
\begin{figure}[ht]
\centering\includegraphics[width=.5\linewidth]{example-image}
\caption{A figure}\label{fig:first}
\end{figure}
\lipsum[1-50]
\begin{figure}[ht]
\centering\includegraphics[width=.5\linewidth]{example-image}
\caption{A figure}\label{fig:second}
\end{figure}
\lipsum[1-50]
\begin{figure}[ht]
\centering\includegraphics[width=.5\linewidth]{example-image}
\caption{A figure}\label{fig:third}
\end{figure}
\lipsum[1-50]
\begin{figure}[ht]
\centering\includegraphics[width=.5\linewidth]{example-image}
\caption{A figure}\label{fig:fourth}
\end{figure}
\lipsum[1-50]
\begin{figure}[ht]
\centering\includegraphics[width=.5\linewidth]{example-image}
\caption{A figure}\label{fig:fifth}
\end{figure}
\lipsum[1-50]
\begin{figure}[ht]
\centering\includegraphics[width=.5\linewidth]{example-image}
\caption{A figure}\label{fig:sixth}
\end{figure}
\lipsum[1-50]
\begin{figure}[ht]
\centering\includegraphics[width=.5\linewidth]{example-image}
\caption{A figure}\label{fig:seventh}
\end{figure}
Figure~\ref{fig:sixth}. % This is fine...
Figure~\ref{fig:seventh}.% ...but this is not, as the figure was pushed to the following page.
\end{document}
The .log
outputs (somewhere):
LaTeX Warning: ...figure `fig:second' is on page 20, but referenced on 10 on in
put line 31.
The warning allows you to identify the label used, the respective page numbers (of the \label
and \ref
), as well as the line in the input file.
There should be no difference between the first and subsequent \ref
s for the same \label
in the above example.
\captionof
from the caption or capt-of packages, or[H]
from the float package and position your figures "by hand" that way they will stay where you put them. Otherwise you are always going to be fighting the float placement algorithm which is absolutely not designed to help you here.