Force floats to appear where referenced

I like to work with different files.
In particular I like to have the text of my document in the file main.tex and my figures in figures.tex. I include the figures.tex file at the end of my main.tex file using \input{figures}.
In this way all the figures appear at the end of the file.

What I would like is that the figures appear automatically near the place in the text where they are referenced for the first time (I might refer to them more than once, I don't care if before or after the actual place in the text, they just need to be around there).
I don't want to put any statement like \input or \includegraphics, etc. every time I refer to a figure in my text, the fact that I am calling \cref is enough information to know that the figure should appear around that place.

I want to keep the number of files at a minimum, hence (e.g.) I don't want to generate a file for each figure I have or stuff like that. Just two files, one declaring the figures and one with the text (and of course I have a folder with all the image files).

A MWE is given below.

main.tex:

\documentclass{article}

\usepackage{graphicx}
\usepackage{cleveref}

\begin{document}

Bla bla bla, a lot of text.

In \cref{fig:plot} we see that bla bla bla ...

Some other text.
...
...

Here we are basically at the end of the file.
\input{figures}

\end{document}


figures.tex:

\begin{figure}
\centering
\includegraphics{path/to/file}
\caption{A nice figure.}
\label{fig:plot}
\end{figure}


Ah, and I would like this to work for tables too, but I guess if a solution exists for figures, it should trivially work for tables too since they are both floats.

Cheers

• This might be possible if you input the file at the beginning, not much hope if you input the file at the end. – David Carlisle Nov 21 '16 at 13:53

If you input the figures at the end, there is not much tex can do, but if you input them at the start, and change the syntax a bit, then it is easy enough to store up the figures and let them out one at a time.

figures.tex

\def\zzz#1#2{%
\expandafter\gdef\csname fig-#1\endcsname{\begin{figure}#2\label{#1}\end{figure}}}
\def\zzzcref#1{%
\csname fig-#1\endcsname\cref{#1}}

\zzz{fig:plot}{%
\centering
\includegraphics{path/to/file}
\caption{A nice figure.}
}

\zzz{fig:zzz}{%
\centering
\includegraphics{path/to/file}
\caption{An even better figure.}
}


document

\documentclass{article}

\usepackage[demo]{graphicx}
\usepackage{cleveref}
\input{figures}
\begin{document}

Bla bla bla, a lot of text.

In \zzzcref{fig:plot} we see that bla bla bla ...

Some other text.
...
...

\newpage

Here we are basically at the end of the file \zzzcref{fig:zzz}.

\end{document}

• Let me see if I understand what you are doing here. Basically the \zzz and the \zzzcref are newly defined commands, and the fact that you can input the figure.tex file in the preamble is because everything in there is wrapped from the new command \zzz (for instance, if I leave even just one figure environment, it would complain, right?). So, in principle I could redefine \cref (instead of defining \zzzcref) so I don't need to change in my text the command. While for \zzz I have only that possibility. Did I get it right? – Batta Nov 22 '16 at 13:57
• @Batta yes you could redefine cref, it would be possible to take a file of figure environments and input it with some local redefinitions that made the figures be saved but likely to be fragile and tricky to support all the places you might use \label so simpler to wrap it in a specific command that handles the label and makes the definition. – David Carlisle Nov 22 '16 at 15:32