I hope I got parity right. It seems that the OP wants the figures to come on the page following the one which references them, and that pages of text should be odd-numbered and on the right, which I would call recto, but Village asked for verso. I went for the OP's requirements. Also, it would make more sense I think to put figures on the page before they are referenced, so that the reader can see them as he reads the corresponding text, but I didn't manage to do that.
I use Heiko Oberdiek's atbegshi
package to capture pages just before they are output to the pdf file (at "shipout" time), and add one page of figures per shipout. In order to keep the correct even/odd layout, I increase the page
counter for each page of figures (this way, \value{page}
is always the true page number in the pdf), but I change \thepage
to display the number of text pages (total minus figures).
The figures are collected as we go in \sos@figures
, which flushes itself when used (\sos@rest@figures
). Each figure added with \addfig
is placed in a \vbox
, with \vfill
between them, so that figures are nicely distributed along the page's height.
Somehow, \shipout\vbox{...}
does not simply send the \vbox
to the pdf centered on the page, so I move the box by \sos@top
and \sos@right
to put it at a place which looks like the left-page layout. Any better solution is welcome.
The mechanism can be turned on and off using \SOStrue
and \SOSfalse
(global switches). The example uses \lipsum
, but with paragraph breaks disabled, so that \lipsum[1-10]
builds one big paragraph.
\documentclass{book}
\usepackage{atbegshi}
\makeatletter
\newlength{\sos@top}
\newlength{\sos@right}
\newcounter{sos@pages}
\newif\ifSOS
\renewcommand{\thepage}{\the\numexpr\value{page}-\value{sos@pages}\relax}
\newcommand{\addfig}[1]{\g@addto@macro\sos@figures{\vbox{\centering#1}\vfill}}
\newcommand{\sos@reset@figures}
{\gdef\sos@figures{\sos@reset@figures\vfill}}
\sos@reset@figures
\newcommand{\sos@shipout@figures}
{%
\begingroup
\stepcounter{page}%
\stepcounter{sos@pages}%
\let\protect\relax
\setbox\z@\vbox to\vsize{\sos@figures}%
\let\protect\string
\AtBeginShipoutOriginalShipout\vbox
{\vbox to\sos@top{}\moveright\sos@right\box\z@}%
\endgroup
}
\AtBeginShipout{%
\ifSOS\ifodd\c@page
\begingroup
\let\protect\string
\AtBeginShipoutOriginalShipout\box\AtBeginShipoutBox
\global\AtBegShi@Discardedtrue
\sos@shipout@figures
\endgroup
\fi\fi
}%
\newcommand{\SOSshipout}{\clearpage\sos@shipout@figures}
\renewcommand{\SOStrue}{\clearpage\global\let\ifSOS\iftrue}
\renewcommand{\SOSfalse}{\clearpage\global\let\ifSOS\iffalse}
\setlength{\sos@top}{2cm}
\setlength{\sos@right}{2cm}
\makeatother
% Test example
\usepackage{booktabs,caption}
\usepackage{lipsum}
\usepackage{hyperref}
\begin{document}
\title{Hello world}
\author{Bruno Le Floch}
\maketitle
\tableofcontents
\listoffigures
\listoftables
\part{Abc}
\SOStrue
\chapter{Hello}
\addfig{\begin{tabular}{p{5cm}p{5cm}}
\toprule
Abc def & ghijk lmno pq \\
\midrule
\lipsum[1] & \lipsum[2] \\
\bottomrule
\end{tabular}
\captionof{table}{\label{tab:atable}A table}}
\addfig{%
\rule{8cm}{3cm}%
\captionof{figure}{A figure}}
\lipsum[1-10]
\addfig{\rule{1cm}{3cm}\captionof{figure}{Another figure}}
\addfig{\rule{8cm}{3cm}\captionof{figure}{A figure}}
\addfig{\rule{1cm}{3cm}\captionof{figure}{Another figure}}
\chapter{Bye}
\makeatletter
\renewcommand{\lips@par}{ } % now \lipsum[1-10] makes one big par
\makeatother
\addfig{\rule{8cm}{3cm}\captionof{figure}{That should be figure 5.}}
\addfig{\rule{1cm}{3cm}\captionof{figure}{Perhaps the sixth}}
\lipsum[1-10]
\addfig{\rule{8cm}{3cm}\captionof{figure}{Yet another one}}
\addfig{\rule{1cm}{3cm}\captionof{figure}{One last figure for now.}}
\SOSfalse
\chapter{Back to normal}
\addfig{\rule{8cm}{3cm}\captionof{figure}{That figure won't be lost.}}
\lipsum[11-15]
\addfig{\rule{4cm}{5cm}\captionof{figure}{Nor will that one.}}
\lipsum[16-20]
\lipsum[21-30]
See Table~\ref{tab:atable}.
\SOSshipout
\SOStrue
\chapter{Figures, again}
\addfig{\rule{5cm}{2cm}\captionof{table}{Let's pretend it's a table}}
\lipsum[21-25]
\addfig{\rule{5cm}{2cm}\captionof{table}{Let's pretend it's a table}}
\lipsum[26-30]
\addfig{\rule{4cm}{1cm}\captionof{table}{Last table}}
\end{document}
EDIT: the other advantage of leaving \c@page
alone is that hyperref and references work. (Added to the example.)
I think it's enough to define
\makeatletter
\def\@floatplacement{\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%<<<<<<<
\@fpmin \floatpagefraction\@colht}
\makeatother
In which the marked line has been changed to set the number of allowed floats to zero (\z@
) on even pages and the value of the LaTeX counter totalnumber (\c@totalnumber
) on even pages.
In the original definition in LaTeX this line is
\global\@colnum\c@totalnumber
and the totalnumber counter applies to all non-float pages. See Frank's full description of the float parameters here How to influence the position of float environments like figure and table in LaTeX?
Best Answer
You can use the
dpfloat
package for that: