3

Consider the following MWE - let's say it's called test.tex:

\batchmode %
\ifx\article\undefined %
  \documentclass[12pt,journal,onecolumn,twoside,draftcls,letterpaper]{IEEEtran} %
\else %
  \documentclass{article} %
\fi

\usepackage{xcolor} % \pagecolor
\pagecolor{yellow!15}
\usepackage{lipsum}
\usepackage[demo]{graphicx}

\begin{document}
\lipsum[1-6] HERE1

\begin{figure}[p]
\includegraphics[width=0.9\textwidth,height=0.9\textheight]{demo.png}
\caption{Demo figure One}
\label{fig:one}
\end{figure}

\lipsum[7-9] HERE2

\begin{figure}[p]
\includegraphics[width=0.9\textwidth,height=0.9\textheight]{demo.png}
\caption{Demo figure Two}
\label{fig:two}
\end{figure}

\lipsum[9-13]

\errorstopmode % if in batchmode, this will allow print of just the number of output pages and such
\end{document}

You can compile this using the following bash one-liner:

for ix in "article" "ieeetran" ; do \
  cmd="pdflatex -jobname test-$ix \"\def\\$ix{}\input{test.tex}\""; \
  echo "$cmd" ; \
  eval "$cmd" ; \
done

... or directly:

pdflatex -jobname test-article "\def\article{}\input{test.tex}"
pdflatex -jobname test-ieeetran "\def\ieeetran{}\input{test.tex}"

This will generate two pdfs - with contents from page 2 to 5 shown below (click for full-size):

  •  test-article.pdf: test-article.png
  • test-ieeetran.pdf: test-ieeetran.png

So, this is what I want to do: if the first figure (fig:one) is first encountered at page current_page; then schedule fig:one (as it is a full-page [p] float) to appear on page current_page+1; and schedule fig:two to appear on page current_page+3 -- that is, have a page of text between these two floats, so they're both either on even or on odd pages.

Now, here, that clearly happened for test-ieeetran.pdf, because the start and end of \lipsum[7-9] happen to be on different pages (as indicated by "HERE1" and "HERE2") - so the algo naturally schedules the floats for the next page after encountering them.

But for test-article.pdf, that didn't happen, and the floats are right one after another; clearly, that's because the in-between text \lipsum[7-9] fits entirely on the same page (2); so the algo will encounter both floats on the same page (given that when it encounters them, it defers them for later, and keeps on typesetting text); schedule them both to the next page (3); and seeing they cannot fit both on page 3, it will push fig:two to the page after that (4). I think that because of this (floats seen both on the same page), none of the tricks like \afterpage{\clearpage} or \FloatBarrier worked when I experimented with them in this case.

So, to keep the question general: is there a way to schedule floats to appear on specific pages later - regardless of, if the current document class would see them both as on same page, or not?

1

Well, eventually I do hope for an erudite answer to this - but for the time being, I did somewhat solve the specific case in the OP; so I thought I'd post, as a reminder of how complicated this can get :). Now both document classes show fig:one on pg3, and fig:two on pg5, and otherwise the text flows in between; in particular test-article is now as required, like this:

test-articleb.png

The code is below - I wish I could explain how it works, but I'm confused myself :) It is something with tricking \afterpage with itself; I mostly arrived at a solution by bruteforcing and looking at printouts - here a comparison of the two classes' printouts for the current code:

% % ieeetran                                  | % article
%
% Completed box being shipped out [1] []      |  Completed box being shipped out [1] []
%   \floatpageset to 3 ..                     |    \floatpageset to 3 ..
% Completed box being shipped out [2] []      |    presecond: pg.2(3) 2
%   in \@floatplacement: 3, vs. 3, vs. 3; !!  |  Completed box being shipped out [2] []
%   'tis 3=3                                  |    in \@floatplacement: 3, vs. 3, vs. 3; !!
% Completed box being shipped out [3] []      |    'tis 3=3
%   in \@floatplacement: 4, vs. 4, vs. 3; !!  |  Completed box being shipped out [3] []
%   'tis 4!= 3                                |    in \@floatplacement: 4, vs. 4, vs. 3; !!
%   \floatpageset to 5 ..                     |    'tis 4!= 3
%   presecond: pg.4(5) 2                      |    \floatpageset to 5 ..
%   fig:two afterpage at pg.4                 |    fig:two afterpage at pg.4
% Completed box being shipped out [4] []      |  Completed box being shipped out [4] []
%   in \@floatplacement: 5, vs. 5, vs. 5; !!  |    in \@floatplacement: 5, vs. 5, vs. 5; !!
%   'tis 5=5                                  |    'tis 5=5
% Completed box being shipped out [5] []      |  Completed box being shipped out [5] []

The good thing, though, is that it allows (more-less) for the figures to be "wrapped" with code in their original location, which I like. Anyways, the fixed test.tex code is:

\batchmode %
\ifx\article\undefined %
  \documentclass[12pt,journal,onecolumn,twoside,draftcls,letterpaper]{IEEEtran} %
\else %
  \documentclass{article} %
\fi

\usepackage{xcolor} % \pagecolor
\pagecolor{yellow!15}
\usepackage{lipsum}
\usepackage[demo]{graphicx}
\input{pgfutil-common}
\usepackage{pgfkeys,pgfmath}
%\usepackage{trace}
\usepackage{afterpage}
%\usepackage[verbose]{placeins} % doesn't really print if unused

\tracingoutput=1
\tracingonline=1

\makeatletter
\let\orig@floatplacement\@floatplacement
\gdef\floatpage{0}
\def\setFloatpage#1{%
  \xdef\floatpage{#1}%
  \typeout{\string\floatpage set to #1 ..}%
}
% based on:
% % http://tex.stackexchange.com/q/124245/ensure-figures-are-placed-on-an-odd-page/#130000
\newcommand*{\floatsonpageonly}{%
  %\clearpage
  \xdef\floatsonpageonlyStartedAtPg{\thepage}%
  \def\@floatplacement{%
    % \thepage is == to \the\c@page
    \typeout{in \string\@floatplacement: \thepage, vs. \the\c@page, vs. \floatpage; !!}% \the\c@totalnumber
    \ifnum\the\c@page=\floatpage%
                        \typeout{'tis \the\c@page=\floatpage}%
                      \else%
                        \typeout{'tis \the\c@page != \floatpage}%
                      \fi%
    \global\@topnum\c@topnumber
    \global\@toproom \topfraction\@colht
    \global\@botnum  \c@bottomnumber
    \global\@botroom \bottomfraction\@colht
    %\global\@colnum  \ifodd\c@page\c@totalnumber\else\z@\fi%<<<<<<<
    \global\@colnum   \ifnum\the\c@page=\floatpage%
                        %\typeout{...}% NO \typeouts here!
                        \c@totalnumber% % total floats per page allowed
                      \else%
                        \z@%
                      \fi%
    \@fpmin   \floatpagefraction\@colht}%
}
\newcommand*{\floatsnormal}{%
  %\clearpage
  % NOTE: just the original \let:
  %\let\@floatplacement\orig@floatplacement
  % ... seems not to be enough; apparently needs
  % to be globalized, else the modified function 
  % will not stop - pushing all further floats to end!
  \global\let\@floatplacement\orig@floatplacement
}
\makeatother

\begin{document}
\errorstopmode
\lipsum[1-6] HERE1

\pgfmathtruncatemacro{\tmpc}{\thepage+1}
\setFloatpage{\tmpc}
\floatsonpageonly
\afterpage{
  \begin{figure}[p]
  \includegraphics[width=0.9\textwidth,height=0.9\textheight]{demo.png}
  \caption{Demo figure One}
  \label{fig:one}
  \end{figure}
  \afterpage{
    \pgfmathtruncatemacro{\tmpc}{\tmpc+2}
    \setFloatpage{\tmpc}
  }
  \clearpage
}

\lipsum[7-9] HERE2

% \pgfmathtruncatemacro{\tmpc}{\tmpc+2} % no can do; still on same page here
% \setFloatpage{\tmpc}                  % -- likewise --
% now prevent processing this at first go, too; but only if on same page as when the op started (must wrap it in \def, because we need to call afterpage with that as argument conditionally)
\typeout{presecond: pg.\thepage (\floatpage) \floatsonpageonlyStartedAtPg}
\def\myFigTwo{%
\typeout{fig:two afterpage at pg.\thepage}
\begin{figure}[p]
\includegraphics[width=0.9\textwidth,height=0.9\textheight]{demo.png}
\caption{Demo figure Two}
\label{fig:two}
\end{figure}
\afterpage{\floatsnormal} % restore normal after done!
}
\ifnum\thepage=\floatsonpageonlyStartedAtPg %
  \afterpage{\myFigTwo} %
\else %
  \myFigTwo %
\fi

\lipsum[9-13]
\lipsum[14-15] % bit more

\errorstopmode % if in batchmode, this will allow print of just the number of output pages and such
\end{document}

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.