3

Is it possible to create a boolean that knows whether or not a float remains inline, or has been moved?

In my case, the float will be a raster image of known size. Sometimes it will fit inline where the code is written, and sometimes it will float to the top of the following page. There are no other situations. Single column, two-sided only. I compile with LuaLaTeX in a custom document class, but I can illustrate my question more simply. In this MWE I used \@float to make it independent of any particular packages:

\documentclass{article}
\newif \ifthisthingmoved % true if float is moved away from ordinary inline
\makeatletter
\def\ftype@figure{0} % not sure why, but seems to be necessary
\setlength\intextsep{0pt}
\setlength\textfloatsep{0pt}
\setlength\floatsep{0pt}
\newenvironment{fitme}
{\@float{figure}[!ht]}
{\end@float\par}
\makeatother
\usepackage{lipsum}
\begin{document}
\lipsum[1-4] % vary the number of paragraphs
\begin{fitme}
% Here is where I wish to test \ifthisthingmoved.
\rule{200pt}{200pt}
\end{fitme}
\lipsum
\end{document}

In the above, with the values shown, the rule will be moved to the second page. So, I would like \ifthisthingmoved to be true (then I will do something with it). I assume that the first page is shipped before the moved object is positioned on the second page, so (hopefully) the asynchronous layout won't be a problem.

  • your if test is inside the float so evaluated before either page is shipped out. Using \pageref you can test where the float was positioned on the previous run, but if you change the vertical size of the float there is no guarantee that it will go to the same position this run, or that the typesetting will ever converge no matter how many times you run latex – David Carlisle Jan 6 '18 at 10:34
  • not directly related to the question but I don't think \def\ftype@figure{0} % not sure why, but seems to be necessary works it just relies on some emergency fix up code (added in 1991) ftype should be a power of two. (ftype@figure is 1 in all the standard classes) – David Carlisle Jan 6 '18 at 11:36
1

The following uses the \label-\ref system to store the pages of where the fitme environment is placed and where it ends up. If the page numbers of these two labels are the same, it is assumed the float didn't move.

enter image description here

\documentclass{article}

\usepackage{refcount}
\usepackage{lipsum}

\newcounter{moved}

\newif\ifthisthingmoved % true if float is moved away from ordinary inline
\newcommand{\movedtrue}{\let\ifthisthingmoved\iftrue}
\newcommand{\movedfalse}{\let\ifthisthingmoved\iffalse}

\newenvironment{fitme}
  {\stepcounter{moved}%
   \label{moved-start-\themoved}%
   \begin{figure}[!ht]%
     \label{moved-end-\themoved}
     \ifnum\getpagerefnumber{moved-start-\themoved}=\getpagerefnumber{moved-end-\themoved}
       \movedfalse
     \else
       \movedtrue
     \fi}
     }
  {\end{figure}}

\begin{document}

\lipsum[1-4] % vary the number of paragraphs

\begin{fitme}
  \ifthisthingmoved
    Moving along \ldots !
  \fi

  \rule{200pt}{200pt}
\end{fitme}

\lipsum

\end{document}

The conditional could be simplified somewhat by using this:

\newcommand{\ifthisthingstayed}{%
  \ifnum\getpagerefnumber{moved-start-\themoved}=\getpagerefnumber{moved-end-\themoved}}
\newcommand{\ifthisthingmoved}{\ifthisthingstayed\else}

However, this would not allow for using

\ifthisthingmoved
  % <this thing moved>
\else
  % <this thing did not move>
\fi

However, this did not seem a requirement from the original question.


This could probably be expanded to check the location on the current page (using \pdflastypos or zref's savepos module) if the page numbers were the same, in order to establish whether the float moved on the place it was placed (to the [t]op or [b]ottom).

  • I believe your reply is "the best that can be done," thus accepted. Although my original question was about a boolean, in view of your answer that requirement is unnecessary. The ultimate purpose is to generate messages that can be read later, and the label-ref method provides enough. – user139954 Jan 6 '18 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy