# How to postpone the set up of a conditional?

I'm about to produce a series of assessment texts. Some of these assessments have annexes, others don't. I would like to be able to define a specific class, like this :

\documentclass{myexam}
\begin{document}
\frontmatter
\section{Easy steps}
\section*{Appendix}
\end{document}


And the \frontmatter macro should print something like :

This text consists of 5 pages plus an appendix of 2 pages.

while, in absence of appendix, it should print like :

This text consists of 5 pages.

I tried to use labels together with a conditional (\newif\ifannex and so on), but it doesn't seem to work. Ideas ?

-
More details : I had the idea of putting a \label{append} within the appendix (easy) and to define in the preamble a macro like this : \def\apndx{\ref{append}}. When the appendix is present, \apndx gets a value, fine. Else the compiler sends a warning (normal) and \apndx seems to get the value ?? and not \relax. –  rcabane Oct 14 '12 at 18:44
What did you try to do? \ref and \label need a second compilation run. –  Qrrbrbirlbel Oct 14 '12 at 19:22
Of course, twice (or more) ! –  rcabane Oct 14 '12 at 21:01

You can use the lastpage and refcount packages, but modifying the way you introduce your appendix.

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

\newcommand{\frontmatter}{%
% Whatever you need to put at the beginning
\computepages
This text consists of \pageorpages{\textpages}%
\ifannex
\ plus an appendix of \pageorpages{\appendixpages}%
\fi
.%
}
\newcommand\pageorpages[1]{#1~page\ifnum#1=1 \else s\fi}
% Just in case we need them
\newcommand\textpages{0}
\newcommand\appendixpages{0}

\makeatletter
\newcommand{\computepages}{%
\ifannex
\edef\textpages{\number\numexpr\getpagerefnumber{annexstart}-1\relax}%
\edef\appendixpages{\number\numexpr\getpagerefnumber{LastPage}-\getpagerefnumber{annexstart}+1\relax}%
\else
\edef\textpages{\getpagerefnumber{LastPage}}%
\fi
}

\newif\ifannex
\newcommand{\annex}[1]{%
\immediate\write\@auxout{\noexpand\global\noexpand\annextrue}%
\section*{#1}%
\label{annexstart}%
}
\makeatother

\begin{document}

\frontmatter

\section{Easy steps}

\newpage

\newpage
\annex{Appendix}

\end{document}


This correctly shows

This text consists of 2 pages plus an appendix of 1 page.

while, if the \annex line is commented out, the output is

This text consists of 2 pages.

Of course, a couple of compilations are needed for the numbers to synchronize.

-
Great ! I'll check this tomorrow. Anyway, I was convinced it was necessary to write and read directly to the aux file, that was the trick you just implemented. Thank you. –  rcabane Oct 14 '12 at 20:59
Is there any drawback in using something like \ifx\r@annexstart\@undefined (as I did in my humble attempt) to check if \annex is called, aside from the fact that the user may use the label without \annex? \label{annexstart} writes to .aux anyway, why not use it? –  Qrrbrbirlbel Oct 14 '12 at 23:20
@Qrrbrbirlbel Why did you delete the answer? Your method is good, but I prefer to state explicitly what I want, that's all. –  egreg Oct 14 '12 at 23:25
I did not know of refcount, otherwise I would've tried to use \numexpr, too. (And would have avoided running into problems with hyperref and the like.) –  Qrrbrbirlbel Oct 14 '12 at 23:33

This solution uses \ztotpages of package zref's module zref-totpages for the number of total pages. This number does not depend on the page numbering scheme. The question mentioned \frontmatter. Usually this uses \pagenumbering{roman} and a following \mainmatter uses \pagenumbering{arabic} with resetting the page counter. The label LastPage of package lastpage will not see the pages before \mainmatter.

However it is not clear, on which class myexam is based. The use of \section would assume a article based class, but that does not provide \frontmatter. Classes with \frontmatter would use \chapter. Therefore the solution defines \frontmatter if it is not given, otherwise \frontmatter is extended to print the additional text.

The appendix is detected by the presence of zref label StartAppendix. For convenience the label setting and \section*{Appendix} is put into macro \Appendix. If the label is detected, then the number of appendix pages is added to the text.

\documentclass{exam}

\usepackage{zref-totpages}
\makeatletter
\newcommand*{\AppendixStartLabel}{%
\@bsphack
\zref@labelbyprops{StartAppendix}{abspage}%
\zref@refused{StartAppendix}%
\@esphack
}
\newcommand*{\printpages}[1]{%
\ifcase#1%
\textbf{??}~pages%
\or
1~page%
\else
\number#1~pages%
\fi
}
\newcommand*{\FrontmatterText}{%
\noindent
This text consists of \printpages{\ztotpages}%
\zref@ifrefundefined{StartAppendix}{%
}{%
\newcommand*{\appendix@pages}{}%
\edef\appendix@pages{%
\numexpr\zref@extractdefault{LastPage}{abspage}{0}%
-\zref@extractdefault{StartAppendix}{abspage}{0}%
+1%
}%
\space including an appendix of \printpages{\appendix@pages}%
}%
.\par
}
\@ifundefined{frontmatter}{%
\newcommand*{\frontmatter}{%
\clearpage
\FrontmatterText
}%
}{%
}
\newcommand{\Appendix}{%
\clearpage
\section*{\appendixname}%
\AppendixStartLabel
}
\makeatother

\begin{document}
\frontmatter
\section{Easy steps}
\Appendix
\end{document}


-
Hello, I think this is the best solution (in my opinion), quite simple and elegant. –  rcabane Oct 15 '12 at 20:38
Works fine; I just think there is a minor error, e.g. the line \space plus an appendix of \printpages{\appendix@pages}% should be \space including an appendix of \printpages{\appendix@pages}% isn't it ? –  rcabane Oct 16 '12 at 6:59
@rcabane You are right, I had used the wording of the question, but with a different meaning of "text". Getting the pages without the appendix is left as exercise for the reader (not too difficult with \numexpr, for example). –  Heiko Oberdiek Oct 16 '12 at 8:36

# Better solution

After finding out about refcount we can skip the calculations with counters (and avoid running into problems with hyperref and other packages that redefine \ref so that it is more than just some digits).

I have now borrowed the idea of egreg to outsource the calculations. It makes a much cleaner code.

## Code

\documentclass{article}
\usepackage{lastpage}
\usepackage{refcount}
\newcounter{tempcounter}

\newcommand*{\pageorpages}[1]{#1~page\ifnum#1=1 \else s\fi}

\makeatletter
\newcommand*{\textpages}{%Calculation of _text_ pages
\ifx\r@DontYouDareUseThisLabelApndxStart\@undefined% without appendix
\number\numexpr\getpagerefnumber{LastPage}+1-\getpagerefnumber{FirstTextPage}\relax
\else % with appendix
\number\numexpr\getpagerefnumber{DontYouDareUseThisLabelApndxStart}-\getpagerefnumber{FirstTextPage}\relax
\fi%
}

\newcommand*{\apndxpages}{% Calculation of _appendix_ pages.
\ifx\r@DontYouDareUseThisLabelApndxStart\@undefined0\else % to prevent errors if this is called accidently
\number\numexpr\getpagerefnumber{LastPage}-\getpagerefnumber{DontYouDareUseThisLabelApndxStart}+1\relax
\fi
}

\newcommand*{\howmanypages}{% \frontmatter is already defined in some classes
The following text consists of \pageorpages{\textpages}%
\ifx\r@DontYouDareUseThisLabelApndxStart\@undefined\else % with appendix
\space plus an appendix of \pageorpages{\apndxpages}%
\fi.
\clearpage % again, no sketchy calculations
\label{FirstTextPage}
}
\makeatother

\newcommand*{\apndx}{
\clearpage
\section*{Appendix}
\label{DontYouDareUseThisLabelApndxStart} % and I mean it!
}

\usepackage{lipsum}
\begin{document}
\lipsum
\howmanypages
\section{Easy steps}
\lipsum
\lipsum
\apndx
\lipsum
\end{document}


# Bad Solution (breaks with hyperref and what not)

With the use of one auxiliary counter you can accomplish something like this very easily.

### \apndx

The macro apndx uses a \clearpage so that it actually starts on an own page. Otherwise the calculation may be sketchy. The label apndxstart is not only used to get the actual page number, but also to check if there is even an appendix (via the macro \r@apndxstart).

### \howmanypages

This macro checks whether a appendix is used:

\ifx\r@apndxstart\@undefined


and then proceed to calculate the actual page numbers.

### lastpage package

The lastpage packages is used to get the last page number (with or without appendix).

## Code

\documentclass{article}
\usepackage{lastpage}
\newcounter{tempcounter}

\makeatletter
\newcommand*{\howmanypages}{% \frontmatter is already defined in some classes
\ifx\r@apndxstart\@undefined % without appendix
\setcounter{tempcounter}{\pageref{LastPage}}
\else% with appendix
\setcounter{tempcounter}{\pageref{apndxstart}}%
\fi%
This text consists of \thetempcounter{} page\ifnum\thetempcounter=1\else s\fi
\ifx\r@apndxstart\@undefined % without appendix
.
\else % with appendix
\setcounter{tempcounter}{\pageref{LastPage}}%
\space plus an appendix of \thetempcounter{} page\ifnum\thetempcounter=1\else s\fi.
\fi
\label{FirstPage}
}
\makeatother

\newcommand*{\apndx}{
\clearpage
\section*{Appendix}
\label{apndxstart}
}

\usepackage{lipsum}
\begin{document}
\lipsum
\howmanypages
\section{Easy steps}
\lipsum

Oh it could be that I mistakenly borrowed my file from the bad solution, not from the good one. I got : No file apndx3.aux. [1{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] ! Missing number, treated as zero. <to be read again> \protect l.36 \howmanypages –  rcabane Oct 16 '12 at 7:02