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?

2

1 Answer 1

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}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .