1

For a particular application, I need to know whether or not a page contains a top float. I have therefore taken the definition of the conditional \iftopfloat{<true>}{<false>} given in the following link: Is there a way to determine if there is a float on a page?.

Initially, this conditional was used in document headers and footers. But in my case, I need to use it in the "body" of the document. However, the conditional doesn't work in this context and always executes the true branch regardless of the presence or absence of a top float.

How do you determine (from the document "body") whether or not there is a top float on a page?

\documentclass{article} \usepackage{mwe} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % From : https://tex.stackexchange.com/questions/56673/is-there-a-way-to-determine-if-there-is-a-float-on-a-page \makeatletter \let\latex@makecol\@makecol \def\@makecol{% \let\topfloat\@toplist% \latex@makecol% } \def\iftopfloat#1#2{\ifx\topfloat\empty #2\else #1\fi} \makeatother %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} \iftopfloat{Yes}{No} \clearpage \begin{figure}[t] \centering \includegraphics{example-image} \end{figure} \iftopfloat{Yes}{No} \clearpage\iftopfloat{Yes}{No} \clearpage \begin{figure}[t] \centering \includegraphics{example-image} \end{figure} \iftopfloat{Yes}{No} \clearpage \begin{figure}[t] \centering \includegraphics{example-image} \end{figure} \iftopfloat{Yes}{No} \clearpage\iftopfloat{Yes}{No} \clearpage\iftopfloat{Yes}{No} \end{document} 
3
  • you can't. Floats are added way after all macros in the document body have been evaluated. Commented Mar 10, 2024 at 11:12
  • consider \clearpage\iftopfloat{Yes}{No} after the clearpage there are no pending floats but you can not test at that point if later in the document there is a figure that floats to the top of this page. Commented Mar 10, 2024 at 12:23
  • 1
    what you can do is use \pdflastypos to see on the next run of latex if the first line is at the top of the page, and if not assume a float has been inserted and choose the correct code branch Commented Mar 10, 2024 at 16:44

2 Answers 2

2

You can not test within the body of the document, but you can detect whether the first line after a clear page was set at the top of the page on the last run, and so choose an appropriate branch. This will always take at least two runs to converge.

enter image description here

\documentclass{article} \usepackage{graphicx} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \makeatletter % pdftex version, others would be similar \def\iftopfloat{% \leavevmode \pdfsavepos \write\@auxout{\string\gdef\string\TPF\roman{page}{\the\pdflastypos}}% \ifdim\ifcsname TPF\roman{page}\endcsname \csname TPF\roman{page}\endcsname sp\else\z@\fi >400pt \expandafter\@secondoftwo \else \expandafter\@firstoftwo \fi } \makeatother %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} \Huge\bfseries \iftopfloat{Yes}{No} \clearpage \begin{figure}[t] \centering \includegraphics{example-image} \end{figure} \iftopfloat{Yes}{No} \clearpage\iftopfloat{Yes}{No} \clearpage \begin{figure}[t] \centering \includegraphics{example-image} \end{figure} \iftopfloat{Yes}{No} \clearpage \begin{figure}[t] \centering \includegraphics{example-image} \end{figure} \iftopfloat{Yes}{No} \clearpage\iftopfloat{Yes}{No} \clearpage\iftopfloat{Yes}{No} \end{document} 
1
  • Thanks for your reply. I've taken inspiration from it, using the idea of two successive compilations and writing to the auxiliary file. I've tried to generalise so that a \clearpage command is no longer necessary. Commented Mar 11, 2024 at 12:13
1

Taking up David Carlisle's idea of two successive compilations and writing to the .aux file, I've modified the \@combinefloats command so that it writes to the .aux file the pages in which there is a top float.

\documentclass{article} \usepackage{mwe,lipsum,refcount} \makeatletter \def \@combinefloats {% \ifx \@toplist\@empty% \else% \@cflt% \immediate\write\@auxout{\string\global\string\@namedef{pageWithTopFloat-\thepage}{1}}% \fi% \ifx \@botlist\@empty \else \@cflb \fi% } \newcounter{ifTopFloatCnt} \def\iftopfloat#1#2{% \global\advance\c@ifTopFloatCnt\@ne% \label{\the\c@ifTopFloatCnt @ifTopFloat}% \ifcsname pageWithTopFloat-\getpagerefnumber{\the\c@ifTopFloatCnt @ifTopFloat}\endcsname% {\Large\bfseries #1}% \else% {\Large\bfseries #2}% \fi% } \makeatother \begin{document} \iftopfloat{Yes}{No} \noindent p. 1: \ifcsname pageWithTopFloat-1\endcsname yes \else no \fi\\ p. 2: \ifcsname pageWithTopFloat-2\endcsname yes \else no \fi\\ p. 3: \ifcsname pageWithTopFloat-3\endcsname yes \else no \fi\\ p. 4: \ifcsname pageWithTopFloat-4\endcsname yes \else no \fi\\ p. 5: \ifcsname pageWithTopFloat-5\endcsname yes \else no \fi\\ p. 6: \ifcsname pageWithTopFloat-6\endcsname yes \else no \fi\\ p. 7: \ifcsname pageWithTopFloat-7\endcsname yes \else no \fi \lipsum[1-4] \clearpage \begin{figure}[t] \centering \includegraphics{example-image} \end{figure} \iftopfloat{Yes}{No} \lipsum[1-4] \iftopfloat{Yes}{No} \lipsum[1-4] \begin{figure}[t] \centering \includegraphics{example-image} \end{figure} \iftopfloat{Yes}{No} \lipsum[1-4] \begin{figure}[t] \centering \includegraphics{example-image} \end{figure} \iftopfloat{Yes}{No} \lipsum[1-4] \iftopfloat{Yes}{No} \lipsum[1-4] \iftopfloat{Yes}{No} \end{document} 
5
  • 1
    this test is not at all guaranteed to give a reasonable result \ifcsname pageWithTopFloat-\thepage\endcsname% never access \thepage from the body you need to set a \label at that point and then test \pageref to see what page you are on. Commented Mar 11, 2024 at 12:58
  • 1
    to see the issue make a document with a load of \begin{figure}[t] then a long multipage paragraph, The figures will be inserted where they are inserted but all tests in a paagraph will have the same value of \thepage so you will test page 1 for all cases. Commented Mar 11, 2024 at 13:00
  • 1
    expansion like \ifcsname and \thepage happens as the input is read, before the paragraph is typeset into a long line that is then broken in to lines, and the lines broken in to pages, so all such macros always reflect the same value even if a paragraph is broken over a page and even the value at the start of the paragraph will be wrong if float pages are inserted. Commented Mar 11, 2024 at 13:51
  • @DavidCarlisle Thanks for your feedback, I've corrected the definition of \iftopfloat to make it more robust. Commented Mar 12, 2024 at 16:29
  • yep that looks more like it:-) Commented Mar 12, 2024 at 16:36

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.