16

I'm producing a document (book class) that will ultimately be produced using offset lithography. It's therefore useful to ensure the total number of pages is a multiple of four by adding as many blank pages to the end as is appropriate.

This answer deals with adding a page if necessary to make the total number even. I can't figure out how to adapt it to deal with multiples of four. Is there a way?

cms_mgr
  • 263
  • 5
    Are you sure you will need it? Aren't such systems able to add blank pages during the printing process? – Ulrike Fischer Nov 20 '12 at 12:06
  • 2
    That's a fair comment Ulrike and yes, 'need' would be too strong a word. It just seemed like a handy thing to be able to automate at the production side so I wanted to give it a shot. – cms_mgr Nov 20 '12 at 12:24
  • 1
    on production side are no single pages printed ... –  Nov 20 '12 at 12:54
  • See also https://tex.stackexchange.com/a/630150/43807 which deals with forcing a back cover as multiple of 4, absolute PDF page numbers (for when the usual counter is reset somewhere in the document), and forcing an extra blank page (for the inner back cover) – mirabilos Jan 14 '22 at 02:02

3 Answers3

13

\numexpr divisions round, so they are not so good in this case:

\documentclass{article}
\usepackage{refcount,lastpage}
\usepackage{kantlipsum}

\makeatletter
\newcommand{\checkmultipleoffour}{%
  \count@=\getpagerefnumber{LastPage}%
  \@tempcnta=\count@
  \divide\@tempcnta by 4
  \multiply\@tempcnta by 4
  \count@=\numexpr\count@-\@tempcnta\relax
  \ifnum\count@>0
    \pagestyle{empty}
    \loop\ifnum\count@<4
      \null\clearpage
      \advance\count@\@ne
    \repeat
  \fi
}
\makeatother

\AtEndDocument{\checkmultipleoffour}

\begin{document}

\kant[1-11] % for a 4 page document

% \kant[1-15] % for a 5 page document

\end{document}

The same in expl3 syntax:

\documentclass{article}
\usepackage{xparse}
\usepackage{refcount,lastpage}
\usepackage{kantlipsum}

\ExplSyntaxOn
\NewDocumentCommand{\checkmultipleoffour} { }
 {
  \prg_replicate:nn
   { \int_mod:nn { 4 - \int_mod:nn { \getpagerefnumber{LastPage} } { 4 } } { 4 } }
   { \thispagestyle{empty}\null\clearpage }
 }
\ExplSyntaxOff
\AtEndDocument{\checkmultipleoffour}

\begin{document}

\kant[1-11] % for a 4 page document

% \kant[1-15] % for a 5 page document

\end{document}

With \frontmatter and \mainmatter the situation is a bit more complicated.

\documentclass{book}
\usepackage{xparse}
\usepackage{refcount,lastpage,etoolbox}
\usepackage{kantlipsum}

\makeatletter
\patchcmd\mainmatter{\cleardoublepage}
  {%
   \clearpage\edef\@currentlabel{\number\numexpr\arabic{page}\ifodd\arabic{page}+1\fi\relax}%
   \label{LastFrontmatterPage}%
   \cleardoublepage
  }{}{}
\makeatother

\ExplSyntaxOn
\cs_new:Npn \egreg_int_coremainder:nn #1 #2
 {
  \int_mod:nn { #2 - \int_mod:nn { #1 } { #2 } } { #2 }
 }
\NewDocumentCommand{\checkmultipleoffour} { O{0} }
 {
  \prg_replicate:nn
   {
    \egreg_int_coremainder:nn { #1 + \getrefnumber{LastFrontmatterPage} + \getpagerefnumber{LastPage} } { 4 }
   }
   { \thispagestyle{empty}\null\clearpage }
 }
\ExplSyntaxOff
\AtEndDocument{\checkmultipleoffour}

\begin{document}

\frontmatter

\tableofcontents

\mainmatter

\chapter{A}

\kant[1-11]

\end{document}

The \checkmultipleoffour has also an optional argument where specifying possible pages before \frontmatter (an unnumbered frontispiece, for instance).

Note that a couple of LaTeX runs may be needed, because these macros require the \label-\ref system to synchronize.

egreg
  • 1,121,712
6

I realise that the goal of this is probably to implement a TeX solution, but it really, really is easier after the document has been completed.

file=UITutorial.pdf; pdftk A=$file B=blank.pdf cat A1-end $(repeat $(( (4-(${$(pdfinfo $file| grep '^Pages:'):s/Pages://:s/ /})%4)%4 )) print -n "B1 ") output ${file:r}_4pgs.pdf

or if you prefer it spaced out a bit:

file=UITutorial.pdf; \
pdftk A=$file B=blank.pdf \
cat A1-end \
$(repeat $(( (4-(${$(pdfinfo $file| grep '^Pages:'):s/Pages://:s/ /})%4)%4 )) print -n "B1 ")\
output ${file:r}_4pgs.pdf

Works with zsh on Unix (Linux, MacOSX, ...), don't know if it would work with other shells. Needs blank.pdf to be a PDF consisting of a single blank page.

Explanation:

file=UITutorial.pdf; \

sets the file we'll use so that we only have to refer to it once

pdftk A=$file B=blank.pdf \

Our inputs will be our given file and the blank PDF.

cat A1-end \

The cat command says "Concatenate the following pages into our output" and the first set of pages are all of those from the main file.

$(repeat $(( (4-(${$(pdfinfo $file| grep '^Pages:'):s/Pages://:s/ /})%4)%4 )) print -n "B1 ")\

The second set is a bit more complicated. We find out how many pages our PDF has via the pdfinfo command. Then we take this modulo 4. We want to round up to the nearest multiple of 4 so we want to take 4 - <this number> except that if <this number> is already a multiple of 4 we don't want to add any. So we work out (4 - <pages>%4)%4. Then we insert into the page specification B1 that number of times. This says "Take page 1 from source B" (which was the blank one) and we do it the right number of times.

output ${file:r}_4pgs.pdf

Now we direct our output to <filename>_4pgs.pdf, where <filename> is what we originally specified but with the extension stripped off.

Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751
5

Hijacking Davids code, try

\makeatletter
\def\emptyclearquadpage
{%
  \clearpage
  \@emptyclearquadpage
}
\def\@emptyclearquadpage
{%
  \ifnum\numexpr((\c@page+1)/4-1)*4+1\relax=\c@page
   \else
    \thispagestyle{empty}%
    \hbox{}\newpage\if@twocolumn\hbox{}\newpage\fi
    \expandafter
    \@emptyclearquadpage
  \fi
}
\makeatother

This will basically produce empty pages to fill up the page counter to a multiple of 4. Adjust as needed.

Sorry for the clumsy numexpr, the totally irrational rounding of integer division is driving me mad...

Edit

Thanks to Ulrike for pointing out that \pagenumbering resets the page counter, so it's not safe to count on it ;-)

Fascinating that \cleardoublepage also only works by coincidence and well-behaving document classes then...

Try

\documentclass{book}

\usepackage{etoolbox}

\makeatletter

\def\emptyclearquadpage
{%
  \clearpage
  \@emptyclearquadpage
}
\def\@emptyclearquadpage
{%
  \@tempcnta=\numexpr\c@page+\totalpages-\@ne\relax
  \ifnum\numexpr((\@tempcnta+2)/4-1)*4\relax=\@tempcnta
   \else
    \thispagestyle{empty}%
    \hbox{}\newpage\if@twocolumn\hbox{}\newpage\fi
    \expandafter
    \@emptyclearquadpage
  \fi
}

\newcount\totalpages

\pretocmd{\pagenumbering}
{\global\advance\totalpages\numexpr\c@page-\@ne\relax}{}{}

\makeatother


\begin{document}

\frontmatter

\clearpage foo
\clearpage foo

\mainmatter

\clearpage foo
\clearpage foo
\clearpage foo


\emptyclearquadpage

\end{document}