4

I have read multiple questions on this site like How to influence the position of float environments like figure and table in LaTeX? and it seems to me that default behaviour of floats is not what I need.

The behaviour that I would like: If there is eneough space left on the page -> place float where it is called. Start the next paragraph after the float. Else place it in queue and check after every following paragraph -> if float can be placed there -> do it.

What float actually does is either splits some paragraph (on page breaks) leaving single last word of paragraph after the float or it waits for a long time skipping spots where the float would have fitted nicely between paragraphs.

Is there any package or tool that does what I want - simply place figures and tables between paragraphs as soon as there is place left on that page?

I understand that float might not be the correct term as this behaviour might be called by other name, but what is it?

  • 2
    if you use [htp] then it tries here or puts it on a queue the only difference is that the check for using the queue is at page breaks not every paragraph (doing the latter would be hard in tex, and you'd need some mechanism to prevent the floats at "internal" paragraphs where you don't want it to appear such as sections headings, list labels, etc. Because of tex's asynchronous page breaker what you ask isn't simple at all, tex may collect multiple pages worth of material before invoking the page breaker so you can not simply ask if anything fits "here" until you know the page breaking. – David Carlisle May 21 '15 at 8:10
  • @DavidCarlisle, are you saying that such behaviour would be near impossible? Or there is a chance that some package might deliver that? I dislike floating at page breaks because it leaves couple of lonely words from previous paragraph after float. Paragraph splitting is OK for page break but not OK if there is a float in the middle. – Džuris May 21 '15 at 10:45
  • people can write xml parsers or regex engines in tex so nothing's impossible (and this is likely easier than that) but it isn't simple and might require more code than a typical answer here (but I have some thoughts on a possible approach so may answer one day....:-) Note latex's behaviour is perhaps closer to traditional journal figure placement than your requested behaviour, I don't think in traditional layouts an inserted figure would ever be inserted mid-page. – David Carlisle May 21 '15 at 11:29
  • @DavidCarlisle Good point about journals. Maybe if floats would differ a bit it would be ok. I'll try adding borders or changing formatting of caption. Btw Here is a disastrous example - section's last word is left alone after figure...on a new page :) – Džuris May 21 '15 at 11:44
  • 2
    You could always use a minipage and \captionof instead of a float. – John Kormylo May 21 '15 at 14:45
7

Something like this, the command \flushhere if placed between paragraphs tries to take a float off the deferred list and make it a here float at this point, if it succeeds it tries to pop the next deferred float and so on until it runs out.

So if you use [hp] floats between paragraphs and put \flushhere after subsequent paragraphs, any floats that didn't get placed "here" should be flushed out between paragraphs...

Only tested in this file, I probably missed something...

enter image description here

\documentclass{article}


\setcounter{totalnumber}{30}% lots of here floats

\def\a{One two \stepcounter{enumi}\roman{enumi} three four five six. }
\def\b{\a\a  red \stepcounter{enumi}\roman{enumi} red green yellow 
random longer typesetting expressions that might invoke hyphenation. }
\def\c{\a\b\a\a\b\b\a}

\def\f#1{\begin{figure}[hp]\centering\rule{2cm}{1cm}\par\caption{ff: #1}\end{figure}}
\def\t#1{\begin{table}[hp]\centering\caption{tt: #1}\par\bigskip\begin{tabular}{cc}1&2\\33&44\\555&666\end{tabular}\end{table}}

\makeatletter
\def\flushhere{\par{%
 \let\s@deferlist\@deferlist
 \let\@currbox\relax
\@next\@currbox\@deferlist{%
  \ifodd\count\@currbox
\typeout{Trying \meaning\@currbox (\number\@currbox/\the\count\@currbox),
        adding to \meaning\@currlist}%
    \@cons\@currlist\@currbox
\typeout{added: to \meaning\@currlist}%
\typeout{deferlist was \s@deferlist, now \@deferlist}%
\let\s@@deferlist\@deferlist\@empty
\global\let\@deferlist\@empty
    \@floatpenalty -\@Miii
      \penalty -\@Miv
      \@tempdima\prevdepth
      \vbox{}%
      \prevdepth\@tempdima
      \penalty\@floatpenalty
       \@@par
   \ifx\@deferlist\@empty
\typeout{float placed here}%
\global\let\@deferlist\s@@deferlist
   \flushhere
\else
\typeout{float not placed here}%
\global\let\@deferlist\s@deferlist
\fi
    \else
\typeout{not h}%
    \global\let\@deferlist\s@deferlist
    \fi
   }%
  {%
\typeout{no pending float}%
}\par}}

\makeatother

%\let\flushhere\relax

\begin{document}

AA \c \verb|\t{a}\f{a}|

\t{a}\f{a}

BB \c\b \verb|\t{b}\t{c}|

\t{b}\t{c}

BB2 \b \verb|\f{b}\f{c}|

\flushhere

\f{b}\f{c}

CC2 \a

\flushhere

CC \c \verb|\t{d}|

\flushhere
\t{d}

DD \c

\typeout{before DD2}
\flushhere

DD2 \c

\flushhere
\f{d}

EE \c

\typeout{before FF}
\flushhere

FF \c\b 

%\flushhere

\end{document}
  • This is actually brilliant! It seems to surely deliver what I was willing for. Only thing that's missing is a routine that puts \flushhere automatically between all there paragraphs. It couldn't harm in any way, could it? – Džuris May 22 '15 at 10:12
  • Although this solution requires a little input between paragraphs, the answer makes it very easy to solve what I was asking for and is useful for me. Therefore I mark it as accepted. – Džuris May 22 '15 at 10:15
  • @Juris as I mentioned the difficulty is deciding which paragraphs are safe you wouldn't want to flush floats after a heading (or inside a heading, which internally is a paragraph) or between a list bullet and the item text or.... – David Carlisle May 22 '15 at 10:15
  • @DavidCarlisle could you explain more please? I couldn't really understand where to add \flushhere. I would appreciate if you could provide simple MWE. – aan Sep 5 at 22:24
  • @aan the answer already contains a test document? – David Carlisle Sep 5 at 22:34

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.