3

Context: In a personal class (for two sided documents), I'd like to translate the layout area towards inner or outer margins (thanks to geometry package's settings), depending on the total pages number.

In order to get the total pages number, I make use of \zref@extractdefault{LastPage}{page}{0} from zref-lastpage package. Unfortunately, as pointed out by the following MWE:

  • \zref@extractdefault{LastPage}{page}{0} gives the correct number only after \begin{document} (compare the total page number in the .log file and in the document),
  • \geometry settings have to be done in the preamble.

I wonder if there is a way to get the correct total pages number even in preamble.

\begin{filecontents*}{myclass.cls}
\NeedsTeXFormat{LaTeX2e}
%
\RequirePackage{zref-lastpage}
\RequirePackage[letterpaper]{geometry}
%
\LoadClass{article}
%
\newcommand{\totpagenumber}{%
  This document has
  \zref@extractdefault{LastPage}{page}{0}
  pages.
}
\message{^^J\totpagenumber^^J^^J}
%
\ifnum\zref@extractdefault{LastPage}{page}{0}<10
\geometry{%
  inner=10mm,
  outer=35mm
}
\else
\geometry{%
  inner=15mm,
  outer=30mm,
}
\fi
\end{filecontents*}
%
\documentclass{myclass}
\usepackage{mwe}
\begin{document}
\totpagenumber

\lipsum[1-15]
\end{document}
10
  • It requires two runs anyway, or am I missing the point?
    – user31729
    Apr 16, 2015 at 10:50
  • After a false answer on my part, it dawned on me that there may not be a workable answer. Imagine the margin settings such that one way, it gives 11 pages and the other way, 9 pages. An infinite loop could conceivably be set up, where 11 pages resets the margins to produce a margin that gives 9 pages, that resets the margins which produces 11 pages.... However, I don't think LaTeX could even get this far, as I don't think the total page count can be known until the margins are set. You have defined a chicken/egg problem. Apr 16, 2015 at 11:17
  • @StevenB.Segletes: The question itself was to get the total number of pages in the preamble. You're trying to get the full solution for the OP concerning the geometry. Perhaps you're right, that the later is 'impossible', but I did not try to attack the bigger problem. I think, you should undelete your answer, as it's a clever way to get the page number in the preamble too (did not know about the totpages package so far). I think your answer is useful
    – user31729
    Apr 16, 2015 at 11:29
  • @ChristianHupfer Indeed, that would require two runs but even after the necessary and sufficient number of runs (according to latexmk), the total number of pages is not the same in the preamble and after \begin{document}. Apr 16, 2015 at 11:37
  • 1
    But the fact remains that a total page count cannot be known without prior knowledge of the margins, and therefore issuing a margin setting macro based on a page count seems problematic. But perhaps some enterprising TeXemist can turn lead into gold. Apr 16, 2015 at 11:45

1 Answer 1

3

The .aux files are read in \begin{document}, therefore all label based references are not available in the preamble. However, the labels can be imported via \zexternaldocument of package zref-xr:

\RequirePackage{zref-xr}
\zexternaldocument[self]{\jobname}
\edef\selftotpages{\zref@extractdefault{internLastPage}{abspage}{0}}

Then \selftotpages contains the number of pages of the previous LaTeX run (or zero) in the preamble already.

Full example:

\RequirePackage{filecontents}
\begin{filecontents*}{myclass.cls}
\NeedsTeXFormat{LaTeX2e}
%
\RequirePackage{zref-totpages, zref-xr}
\RequirePackage[letterpaper]{geometry}
%
\LoadClass{article}

\zexternaldocument[self]{\jobname}

\edef\selftotpages{\zref@extractdefault{selfLastPage}{abspage}{0}}

\newcommand{\totpagenumber}{%
  This document has
  \ifcase\selftotpages\space
    no (not yet) pages.%
  \or
    1 page.%
  \else
    \selftotpages\space pages.
  \fi
}
\message{^^J\totpagenumber^^J^^J}
%
\ifnum\selftotpages<10
  \geometry{%
    inner=10mm,
    outer=35mm
  }
\else
  \geometry{%
    inner=15mm,
    outer=30mm,
  }
\fi
\end{filecontents*}
%
\documentclass{myclass}
\usepackage{lipsum}
\begin{document}
\totpagenumber

\lipsum[1-15]
\end{document}

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.