4

Please excuse my lack of knowledge - I am completely new to LaTeX. I think I have a question regarding the height of a section... To be more specific, I am compiling a poetry book, using the verse package. Environment set up as follows:

\documentclass[12pt,a5paper,twoside]{article} 
\pdfpageheight=210mm
\pdfpagewidth=148mm
\usepackage[a5paper]{geometry}
\geometry
{
    portrait,
    top=2.3cm,
    left=2cm,
    right=1.3cm,
    bottom=2cm
} 
\usepackage{verse}

I want to know if a particular poem will break over two pages, and depending on the answer (and whether I am on an odd page currently), introduce a page break.

Can this be done in a macro of some sort at the beginning of the poem, linked to the \poemtitle ?

If the current page is even, I want to leave it, and if the current page is odd (and the poem spans two pages), I want to introduce a page break, so that two-page poems do not have a page turn between them. Is this possible somehow? I notice a similar question here which I don't think was answered yet:

Variable page break penalty for odd/even pages?

4
  • There is \cleardoublepage, but it always starts on an odd page. Aug 11, 2016 at 22:00
  • Thank you, but I already know how to create a new page, for example \newpage\null\thispagestyle{empty}\newpage The question is more to do with knowing how many pages a section will span ahead of time, then automatically inserting a page break if needed. I suppose in the end of the day, I can simply look at the output and insert breaks manually... but I wanted the code to do this for me! Ultimate laziness of a hobbyist programmer...
    – Adam
    Aug 11, 2016 at 22:23
  • If I understand correctly, you normally fit more than one poem per page, you do not want poems to break over the end of an odd page, but you do want poems to break over the end of an even page. Most of this can be done using needspace and afterpage. The worst case is when a short poem which was already moved using needspace and a long poem moved by afterpage together are more than two pages long. Aug 12, 2016 at 13:32
  • Almost... thank you for your hints, John. I will have a look at "needspace" and "afterpage" I also like the answer below from Gustavo Mezzetti which I will be experimenting with.
    – Adam
    Aug 12, 2016 at 18:15

2 Answers 2

3

This solution manually performs the page breaks using \vsplit. Odd pages can only break between addblock environments. The drawback is that EVERYTHING must be written in addblock environments, otherwise it gets confused.

Box \pagebox is used to store the page so far (global). It is merged with the contents of the new block and tested. If the combined blocks are more than 2 pages, or if they are more than one page and one is on an odd page, then \pagebox is written to this page and we move to the next even page. When an even page is filled, \vsplit performs the page break and the first page is written.

Local registers \box0 and \box1 do not have to be saved globally. Their contents will be lost at \end{addblock}. Note: \stepcounter changes counters globally (in this case, the section number), so we only want to expand \BODY once.

\documentclass[12pt,a5paper,twoside]{article} 
\pdfpageheight=210mm
\pdfpagewidth=148mm
\usepackage[a5paper,showframe]{geometry}
\geometry
{
    portrait,
    top=2.3cm,
    left=2cm,
    right=1.3cm,
    bottom=2cm
} 
\usepackage{verse}
\usepackage{environ}
\usepackage{lipsum}% generic text

\newsavebox{\pagebox}
\newif\ifevenpage

\NewEnviron{addblock}{\setbox1=\vbox{\BODY\par}% only once for counters
  \setbox0=\vbox{\unvcopy\pagebox\unvcopy1}%
  \ifdim\ht0>2\textheight
    \unvbox\pagebox
    \newpage
    \ifevenpage
      \null\newpage
    \else
      \global\evenpagetrue
    \fi
    \setbox0=\box1
  \fi
  \loop\ifdim\ht0>\textheight
    \ifevenpage
      \setbox1=\vsplit0 to \textheight
      \unvbox1
      \pagebreak
      \global\evenpagefalse
      \setbox\pagebox=\copy0
    \else
      \unvbox\pagebox
      \newpage
      \global\evenpagetrue
      \setbox0=\box1
    \fi
  \repeat
  \global\setbox\pagebox=\box0
\ignorespaces}

\AtEndDocument{\unvbox\pagebox}

\begin{document}
  \begin{addblock}
    \section{first}
    \lipsum[1]
  \end{addblock}
  \begin{addblock}
    \section{second}
    \lipsum[1-4]
  \end{addblock}
  \begin{addblock}
    \section{third}
    \lipsum[1]
  \end{addblock}
  \begin{addblock}
    \section{fourth}
    \lipsum[2]
  \end{addblock}
  \begin{addblock}
    \section{fifth}
    \lipsum[1-4]
  \end{addblock}
  \begin{addblock}
    \section{sixth}
    \lipsum[2]
  \end{addblock}
\end{document}
2
  • Thank you, John, I also like this, because there are slightly fewer elements I don't quite understand!! Thank you all for your help!
    – Adam
    Aug 13, 2016 at 17:44
  • I particularly like how this solution takes account of shorter sections and fits them in if there is space on the same page - not something I had even considered properly, I am so new to this!
    – Adam
    Aug 13, 2016 at 17:56
4

Well, if all the problems boil down to having a variant of \cleardoublepage that always jumps to an even-numbered page, instead of to an odd-numbered one, this is easily accomplished:

\documentclass[%
        twoside,%   this is crucial!
        a4paper%    this is not, of course!
    ]{article}
\usepackage[T1]{fontenc}    % Not always necessary, but recommended.
\usepackage{lipsum}

\makeatletter

% Use "\clearevenpage" if you want the possible extra page to *have*
% running heads:
\newcommand*\clearevenpage{\par
  \clearpage
  \if@twoside \ifodd\c@page
    \null\newpage
  \fi\fi
}

% Use "\clearevenemptypage" if you want the possible extra page *not* to have
% running heads:
\newcommand*\clearevenemptypage{\par
  \clearpage
  \if@twoside \ifodd\c@page
    \thispagestyle{empty}%
    \null\newpage
  \fi\fi
}

\makeatother



\begin{document}

\lipsum[1-6]

We should now be on an even-numbered page.

\clearevenpage

This test appears on the next \emph{even} page; an empty page has been
automatically inserted.

\lipsum[7-12]

We should now be on an odd-numbered page.

\clearevenpage

This text appears on the next even page too, but this time no additional empty
page was needed.

\end{document}

Edit: Re-reading the question more carefully, I realize this is not what you are asking for. (So, I’ll remove this answer after a grace period of 48 hours, to let it witness to my stupidity… ;-) You want to jump to an even-numbered page only if the ensuing poem spans two pages, right? (By the way: what is the expected behavior if the ensuing poem is more than two pages long, so that the reader is forced to turn over the page anyway?)


Addition

The following code defines a Poem environment that measures the text inside it and, if the proper conditions are met, jumps to the next even-numbered page. More precisely, if both the following are true:

  • the document is being typeset in twoside mode;

  • the contents of the environment are more than a page long;

then the contents are printed beginning on the next even-numbered page; otherwise, they will be printed starting on the next page, be it even-numbered or odd-numbered. The examples included in the code illustrate this.

\documentclass[%
        twoside,%   this is crucial!
        a4paper%    this is not, of course!
    ]{article}
\usepackage[T1]{fontenc}    % Not always necessary, but recommended.
\usepackage{lipsum}

\makeatletter

\newenvironment*{Poem}{%
  \setbox\z@ \vbox\bgroup
    \boxmaxdepth\maxdepth
    \color@begingroup
    % the following penalty will be used later, see (*):
    \penalty-\@M
}{%
    \@@par
    \color@endgroup
    \global \dimen@i \prevdepth
  \egroup
  % (*) What follow is a hack to insert the "\topskip" glue atop "\box0";
  % nothing will actually be split off to "\box2":
  \splitmaxdepth \maxdepth
  \splittopskip \topskip
  \setbox\tw@ \vsplit\z@ to\z@ % everything actually stays in "\box0"
  \clearpage
  \if@twoside
    \ifdim \ht\z@>\textheight
      \ifodd\c@page
        % uncomment the following line if you wish so:
        % \thispagestyle{empty}% <-- ...but leave this "%" in place
        \null\newpage
      \fi
    \fi
  \fi
  \unvbox\z@
  \prevdepth \dimen@i
}

\makeatother



\begin{document}

The contents of the \texttt{Poem} environment can be ordinary paragraphs as 
well as verses.

\begin{Poem}
    \section{First poem}
    \lipsum[1-6]
\end{Poem}

\begin{Poem}
    \section{Second poem}
    \lipsum[7-20]
\end{Poem}

\begin{Poem}
    \section{Third poem}
    \lipsum[20-22]
\end{Poem}

\begin{Poem}
    \section{Fourth poem}
    \lipsum[22-24]
\end{Poem}

\begin{Poem}
    \section{Fifth poem}
    \lipsum[24-32]
\end{Poem}

\begin{Poem}
    \section{Sixth poem}
    \lipsum[33]
\end{Poem}

\begin{Poem}
    \section{Seventh poem}
    \lipsum[34]
\end{Poem}

\begin{Poem}
    \section{Eighth poem}
    \lipsum[35-36]
\end{Poem}

\begin{Poem}
    \section{Ninth poem}
    \lipsum[37-48]
\end{Poem}

And so on\ldots\space (Check for \verb|\prevdepth|.)

\end{document}

Note that the contents of the Poem environment can consist of ordinary paragraphs, section titles, lists, verses… The only things you should avoid are:

  • explicit page breaks (they mess up the measurement of the text);

  • any commands that imply a page break, like \chapter (for the same reason);

  • floating environments;

  • footnotes (alas, so it is!).

The last limitation is admittedly cumbersome.

1
  • My goodness, what a wonderful response! And so quick too! I will experiment with this as soon as I get the opportunity, thank you so much!
    – Adam
    Aug 12, 2016 at 9:20

You must log in to answer this question.

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