2

I would like to place a figure on an even page, then the caption on the following page.

The reason for that is that the figure + caption is too big to fit in one page, but I want the reader to be able to see both image and caption.

Here is a MWE to compile with xelatex:

\documentclass[12pt,english]{extbook}
\usepackage{fontspec}
\usepackage{xunicode}
\usepackage[a4paper]{geometry}
\usepackage[english]{babel}
\usepackage{caption}
\usepackage{afterpage}
\usepackage{ifoddpage}
\usepackage{blindtext}

% Create big picture
\renewcommand{\includegraphics}[2][]{%
  \setlength{\fboxsep}{-\fboxrule}%
  \framebox{\rule{0pt}{15cm}\rule{10cm}{0pt}}%
}

% Add figure on even page and caption on odd page, plus a ruler to separate caption from text
\newcommand{\doublesidefigurewithruler}[5][1]{%
  \afterpage{
    \newpage
    \checkoddpage
    \ifoddpage
      \doublesidefigurewithruler[#1]{#2}{#3}{#4}{#5}
    \else
      \doublesidefigurecontent{#1}{#2}{#3}{#4}{#5}{1}
    \fi
  }
}%

% Add the figure and the caption
\newcommand{\doublesidefigurecontent}[6]{%
  \begin{center}
    \vspace*{\fill}
    \includegraphics[width=#1\textwidth]{#2}
    \captionof{figure}[]{#4}
    \label{#3}
    \vspace*{\fill}
  \end{center}

  \newpage

  \addtocounter{figure}{-1}
  \captionof{figure}[#4]{#4 #5}

  \ifnum \numexpr#6=1
    \noindent\rule{\textwidth}{0.2pt}
  \fi
}%

\begin{document}
  \Blindtext

  \doublesidefigurewithruler[1]{%
    bigfigure}{%
    mylabel}{%
    Mytitle}{%
    \blindtext
    \blindtext
  }

  \Blindtext
  \Blindtext
  \Blindtext
\end{document}

It does work, but there is probably a better way to do it, right? In addition, figure numbering is sometimes wrong if I mix this with regular figure environment, and I have to add \clearpage between two \doublesidefigurewithruler....

Besides, I would prefer to place the caption at the bottom of the next page if possible, and I would rather prefer to have an environment:

\begin{doublesidefigure}
  \centering
  \includegraphics...
  \caption[for the toc]{My content}
  \label{mylabel}
\end{doublesidefigure}

What I did work, but it is not very robust. How can I do it properly?

  • Do you want the caption centered in an otherwise empty page, or just at the top before the text continues? Also, the lisr of figures will use the page the caption is on, not the figure. (Technically it should be called the list of captions.) – John Kormylo Dec 3 '15 at 5:14
  • I would like the caption to be at the top of the page (or even better at the bottom), and the rest of the page filled with normal text. – Slagt Dec 3 '15 at 12:29
3

I take it you plan on having a really long caption, as it looks a little weird right now. Are you sure you don't want to put the caption in the margin instead?

BTW, since the odd page test is at the start of a new page, the page counter is accurate.

\documentclass[12pt,english]{extbook}
%\usepackage{fontspec}% don't need them myself
%\usepackage{xunicode}
\usepackage[a4paper]{geometry}
\usepackage[english]{babel}
\usepackage{caption}
\usepackage{afterpage}
\usepackage{environ}
\usepackage{mwe}
\usepackage{showframe}

\newsavebox{\doublepagecaption}
\newsavebox{\doublepageimage}

\NewEnviron{doublepagefigure}[2][]% #1=short caption (optional), #2=caption
{\global\setbox\doublepagecaption=\hbox{%
  \parbox{\textwidth}{\captionof{figure}[#1]{#2}}}%
 \global\setbox\doublepageimage=\hbox{\parbox{\textwidth}{\BODY}}%
 \afterpage{\clearpage
 \ifodd\value{page}%
   \afterpage{%
    \vspace*{\fill}\vspace{-\baselineskip}%
    \noindent\usebox{\doublepageimage}\vfill\pagebreak
    \begin{figure}[b]\usebox{\doublepagecaption}\end{figure}}%
 \else
   \vspace*{\fill}\vspace{-\baselineskip}%
   \noindent\usebox{\doublepageimage}\vfill\pagebreak
   \begin{figure}[b]\usebox{\doublepagecaption}\end{figure}%
 \fi}}

\renewcommand{\bottomfraction}{0.5}% fraction of page allowed for bottom floats

\begin{document}

\listoffigures
\bigskip
Reference to Figure \ref{fig:test}.
\bigskip

\lipsum[1]

\begin{doublepagefigure}[short caption]{long caption\label{fig:test}}
\centering\fbox{\includegraphics[width=.95\textwidth,height=.95\textheight]{example-image}}
\end{doublepagefigure}

\lipsum[2-16]

\end{document}

\afterpage waits until the page break to execute. If a paragraph is split, it will insert text BEFORE the second half. Calling \afterpage inside \afterpage waits two pages, and so on.

\clearpage forces any outstanding floats to be printed now, even if it adds a page. (You probably don't need it, but in general you want floats to be printed in the correct order.)

I use box registers to implement the figure and caption, just like normal floats. The system is smart enough to delay writing to the TOC until the box is displayed. It also increments the figure counter NOW.

All local definitions are lost at the end of an environment, and \savebox is a local definition. Hence the \global\setbox\name=\hbox{...} form.


Here is a stylistically updated version. It does not require the environ or caption packages.

\documentclass[12pt,english]{extbook}
%\usepackage{fontspec}% don't need them myself
%\usepackage{xunicode}
\usepackage[a4paper]{geometry}
\usepackage[english]{babel}
\usepackage{afterpage}
\usepackage{graphicx,lipsum}
\usepackage{showframe}

\newsavebox{\doublepagecaption}
\newsavebox{\doublepageimage}

\makeatletter
\newenvironment{doublepagefigure}[2][]% #1=short caption (optional), #2=caption
{\def\@captype{figure}%
  \global\setbox\doublepagecaption=\vbox{\caption[#1]{#2}}%
  \begin{lrbox}{\doublepageimage}}% body goes here
{\end{lrbox}%
  \global\setbox\doublepageimage=\box\doublepageimage
  \afterpage{\clearpage
    \ifodd\value{page}%
      \afterpage{%
        \vspace*{\fill}\vspace{-\baselineskip}%
        \noindent\usebox{\doublepageimage}\vfill\pagebreak
        \begin{figure}[b]\usebox{\doublepagecaption}\end{figure}}%
    \else
      \vspace*{\fill}\vspace{-\baselineskip}%
      \noindent\usebox{\doublepageimage}\vfill\pagebreak
      \begin{figure}[b]\usebox{\doublepagecaption}\end{figure}%
    \fi}}
\makeatother

\renewcommand{\bottomfraction}{0.5}% fraction of page allowed for bottom floats

\begin{document}

\listoffigures
\bigskip
Reference to Figure \ref{fig:test}.
\bigskip

\lipsum[1]

\begin{doublepagefigure}[short caption]{long caption\label{fig:test}}
\centering\fbox{\includegraphics[width=.95\textwidth,height=.95\textheight]{example-image}}
\end{doublepagefigure}

\lipsum[2-16]

\end{document}
  • Wow, that's a difficult thing for me. Could you explain it a little bit? It does work btw, thanks! The problem with scientific figure is that we are limited to a couple of figure per article, so we gather every related results into one figure. Then we describe the results in the caption which can be very long. – Slagt Dec 3 '15 at 12:25
  • I moved the caption to the bottom of the second page. I experimented with allowing the caption to go on the first page if it fit, but decided not to. If you can fit the caption on the same page, you should use a regular figure. – John Kormylo Dec 3 '15 at 16:13
  • BTW, do not create a second doublepagefigure until the first is displayed, as you will overwrite the box registers. (Didn't want to complicate matters with dynamic box allocation. See tex.stackexchange.com/questions/185140/reusing-saveboxes) – John Kormylo Dec 3 '15 at 16:42
  • thanks! It works perfectly and explanation are clear enough! – Slagt Dec 5 '15 at 7:53

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.