3

Following up this answer, the first run of compilation results in the following error:

Undefined control sequence. This exam contains \textbf{\NAMEquestions}

which has to be eliminated by running it for the second time. So, how can I get rid of the error at the first run in order to be able to use arara?

% arara: lualatex: { options: [ '-synctex=1', '-shell-escape','-interaction=nonstopmode' ]}
% arara: lualatex: { options: [ '-synctex=1', '-shell-escape','-interaction=nonstopmode' ]}
\documentclass[addpoints]{exam}

\usepackage{fmtcount,etoolbox}

\makeatletter
\let\NAMEquestions\numquestions
\patchcmd{\NAMEquestions}{\exam@numquestions}{{\NUMBERstringnum\exam@numquestions} question\ifnum\exam@numquestions>1 s\fi}{}{}
\let\NAMEpages\numpages
\patchcmd{\NAMEpages}{\exam@lastpage}{{\NUMBERstringnum\exam@lastpage} page\ifnum\exam@lastpage>1 s\fi}{}{}
\let\NAMEpoints\numpoints
\patchcmd{\NAMEpoints}{\exam@numpoints}{{\NUMBERstringnum\exam@numpoints} mark\ifnum\exam@numpoints>1 s\fi}{}{}
\makeatother

\begin{document}

This exam contains \textbf{\NAMEquestions} in \textbf{\NAMEpages} (including the cover) for a total of \textbf{\NAMEpoints}.

\begin{questions}
  \question[10] single question
\end{questions}

\end{document}
Diaa
  • 9,599
  • This is because the definition of the macro is written into the aux file in the first run, and only available in the second run. Is your question also how to get rid of the error? –  Oct 31 '19 at 22:44
  • 1
    Is your question also how to get rid of the error? Yes, I have asked for a solution to be able to use arara :) – Diaa Oct 31 '19 at 22:47

2 Answers2

1

The exam class takes precautions to check that the commands are defined, your code doesn't, because the braces are in the wrong position.

\documentclass[addpoints]{exam}

\usepackage{fmtcount,etoolbox}

\makeatletter
\newcommand{\diaa@plural}[1]{\ifnum#1>1 s\fi}
\let\NAMEquestions\numquestions
\patchcmd{\NAMEquestions}
  {\exam@numquestions}
  {{\NUMBERstringnum\exam@numquestions\ question\diaa@plural\exam@numquestions}}
  {}{}
\let\NAMEpages\numpages
\patchcmd{\NAMEpages}
  {\exam@lastpage}
  {{\NUMBERstringnum\exam@lastpage\ page\diaa@plural\exam@lastpage}}
  {}{}
\let\NAMEpoints\numpoints
\patchcmd{\NAMEpoints}
  {\exam@numpoints}
  {{\NUMBERstringnum\exam@numpoints\ mark\diaa@plural\exam@numpoints}}
  {}{}
\makeatother

\begin{document}

This exam contains \textbf{\NAMEquestions} in \textbf{\NAMEpages} (including the cover) for a total of \textbf{\NAMEpoints}.

\begin{questions}
  \question[10] single question
\end{questions}

\end{document}

The definition of \numquestions is

% exam.cls, line 1604:
\def\numquestions{\@ifundefined{exam@numquestions}%
  {\mbox{\normalfont\bfseries ??}}%
  \exam@numquestions
}% numquestions

and the token \exam@newquestions is the third argument to \@ifundefined. With your patch, only \NUMBERstringnum\exam@numquestions is taken as the third argument and from question on the code is executed anyway.

egreg
  • 1,121,712
1

I do not know anything about arara (since I am not a duck) but this avoids errors.

\documentclass[addpoints]{exam}

\usepackage{fmtcount,etoolbox}

\makeatletter
\ifcsname exam@numquestions\endcsname%
\let\NAMEquestions\numquestions
\patchcmd{\NAMEquestions}{\exam@numquestions}{{\NUMBERstringnum\exam@numquestions} question\ifnum\exam@numquestions>1 s\fi}{}{}
\fi
\ifcsname exam@lastpage\endcsname%
\let\NAMEpages\numpages
\patchcmd{\NAMEpages}{\exam@lastpage}{{\NUMBERstringnum\exam@lastpage} page\ifnum\exam@lastpage>1 s\fi}{}{}
\let\NAMEpoints\numpoints
\fi
\ifcsname exam@numpoints\endcsname%
\patchcmd{\NAMEpoints}{\exam@numpoints}{{\NUMBERstringnum\exam@numpoints} mark\ifnum\exam@numpoints>1 s\fi}{}{}
\fi%
\def\safetouse#1{%
\ifcsname#1\endcsname%
\csname#1\endcsname%
\fi}
\makeatother

\begin{document}

This exam contains \textbf{\safetouse{NAMEquestions}} in
\textbf{\safetouse{NAMEpages}} (including the cover) for a total of
\textbf{\safetouse{NAMEpoints}}.

\begin{questions}
  \question[10] single question
\end{questions}

\end{document}
  • Thanks for the help :) – Diaa Oct 31 '19 at 22:59
  • May I ask an off-topic question about TikZ shape anchors? – Diaa Nov 01 '19 at 08:59
  • @Diaa Yes, you may. –  Nov 01 '19 at 13:56
  • Thanks. In my previous question, is it possible for the cylinder to use something like anchor= ( $(c.before top)!0.5!(c.after top)$ ) inside the draw command without having to draw the cylinder first, then refer to it when drawing the horizontal line? – Diaa Nov 01 '19 at 17:34
  • @Diaa I do not think so because before drawing the cylinder there is no (documented and probably no undocumented) anchor at that place. However, what prevents you from using anchor=top and adding the missing stretch either explicitly or via append after command? –  Nov 01 '19 at 17:46
  • I don't know how to do it that way. If you don't mind you can leave a comment on my question about how do it in a robust way without having to stretch the line by guessing. – Diaa Nov 01 '19 at 17:49