The postnotes
package offers some infrastructure to store (and expand) some variables at the place the mark is set, and retrieve them when the note is printed at the end. This infrastructure is used by the package to port a number of variables like \thechapter
, \thesection
, \thepage
and so on, and also to add support for some packages which need to see some variables "as if they were at the place of the mark". But the mechanism can be leveraged by the user too.
The basic structure is that postnotes
provides a pair of hooks, postnotes/note/store
which is called where the mark is set, and postnotes/print/note/begin
which is called right before the note is printed at the end. And you can establish a connection between the two points by means of the note unique ID, which you can access at the first hook by \l_postnotes_note_id_tl
and in the second by \l_postnotes_print_note_id_tl
.
In practice:
\documentclass[a4paper]{exam}
% This is already the default nowadays.
% \usepackage[utf8]{inputenc}
\printanswers
\renewcommand{\solutiontitle}{\noindent\textbf{Solution \pnthequestion\pnthepartno\pnthesubpart\pnthesubsubpart:}\par\noindent} % like the exam documentation recommends
% I presume this is desired?
\counterwithin*{partno}{question}
\usepackage{postnotes}
\postnotesetup{
listenv=none,
format=\normalsize,
maketextmark=,
}
\renewcommand*{\pntitle}{Answers}
\NewDocumentCommand{\answer}{m}{%
\postnote[nomark]{\vspace*{-3.5ex}\begin{solution}#1\end{solution}}}
\NewDocumentCommand{\theanswers}{}{\printpostnotes}
\ExplSyntaxOn
\AddToHook { postnotes/note/store }
{
\prop_new:c { g__ypnia_exam_ \l_postnotes_note_id_tl _prop }
\prop_gput:cnx { g__ypnia_exam_ \l_postnotes_note_id_tl _prop }
{ thequestion } { \thequestion }
\prop_gput:cnx { g__ypnia_exam_ \l_postnotes_note_id_tl _prop }
{ thepartno } { \thepartno }
\prop_gput:cnx { g__ypnia_exam_ \l_postnotes_note_id_tl _prop }
{ thesubpart } { \thesubpart }
\prop_gput:cnx { g__ypnia_exam_ \l_postnotes_note_id_tl _prop }
{ thesubsubpart } { \thesubsubpart }
}
\AddToHook { postnotes/print/note/begin }
{
\prop_get:cnN
{ g__ypnia_exam_ \l_postnotes_print_note_id_tl _prop }
{ thequestion } \pnthequestion
\prop_get:cnN
{ g__ypnia_exam_ \l_postnotes_print_note_id_tl _prop }
{ thepartno } \pnthepartno
\prop_get:cnN
{ g__ypnia_exam_ \l_postnotes_print_note_id_tl _prop }
{ thesubpart } \pnthesubpart
\prop_get:cnN
{ g__ypnia_exam_ \l_postnotes_print_note_id_tl _prop }
{ thesubsubpart } \pnthesubsubpart
}
\ExplSyntaxOff
\begin{document}
\begin{questions}
\addpoints \question This is the first question
\begin{parts}
\part This is part one.
\answer{Answer 1.1}
\part This is part two.
\answer{Answer 1.2}
\end{parts}
\addpoints \question This the second question
\answer{This is the solution to question two.}
\end{questions}
\theanswers
\end{document}
Results in:
Note that the numbering scheme in:
\renewcommand{\solutiontitle}{\noindent\textbf{Solution \thequestion\thepartno\thesubpart\thesubsubpart:}\par\noindent}
is a little awkward. That is not the usual way to nest different levels of document counters in LaTeX, which is rather to incorporate the level above in the printed representation (\the...
). Concretely, you are relying on partno
, subpart
and subsubpart
being formatted the way they are by default in the class, such that a 0 does not produce output. That's probably fragile, but perhaps it makes sense in exam
, since the sublevels are seen very close to each other, so that the nesting would be overkill. Anyway, even if the usual nesting should not be applied, I'd still use something like:
\documentclass[a4paper]{exam}
% This is already the default nowadays.
% \usepackage[utf8]{inputenc}
\printanswers
\newcommand*{\pnsolution}{}
\AddToHook{env/questions/begin}{%
\renewcommand*{\pnsolution}{\thequestion}}
\AddToHook{env/parts/begin}{%
\renewcommand*{\pnsolution}{\thequestion\thepartno}}
\AddToHook{env/subparts/begin}{%
\renewcommand*{\pnsolution}{\thequestion\thepartno\thesubpart}}
\AddToHook{env/subsubparts/begin}{%
\renewcommand*{\pnsolution}{\thequestion\thepartno\thesubpart\thesubsubpart}}
\renewcommand{\solutiontitle}{\noindent\textbf{Solution \pnsolution:}\par\noindent} % like the exam documentation recommends
\usepackage{postnotes}
\postnotesetup{
listenv=none,
format=\normalsize,
maketextmark=,
}
\renewcommand*{\pntitle}{Answers}
\NewDocumentCommand{\answer}{m}{%
\postnote[nomark]{\vspace*{-3.5ex}\begin{solution}#1\end{solution}}}
\NewDocumentCommand{\theanswers}{}{\printpostnotes}
\ExplSyntaxOn
\AddToHook { postnotes/note/store }
{
\tl_new:c { g__ypnia_solution_ \l_postnotes_note_id_tl _tl }
\tl_gset:cx { g__ypnia_solution_ \l_postnotes_note_id_tl _tl }
{ \pnsolution }
}
\AddToHook { postnotes/print/note/begin }
{
\tl_set:Nv \pnsolution
{ g__ypnia_solution_ \l_postnotes_print_note_id_tl _tl }
}
\ExplSyntaxOff
\begin{document}
\begin{questions}
\addpoints \question This is the first question
\begin{parts}
\part This is part one.
\answer{Answer 1.1}
\part This is part two.
\answer{Answer 1.2}
\end{parts}
\addpoints \question This the second question
\answer{This is the solution to question two.}
\end{questions}
\theanswers
\end{document}
Note also that you need the latest release of postnotes
(v0.2.2) for the above.
endnotes
and the issues about expanding and numbering. Take a look at this summary of endnote packages: tex.stackexchange.com/questions/669517/…xsim
to write my exams and solutions. In this question I asked about changing the gradetable, but the code in the provided MWE (rather long) shows how I manage to have my solutions ordered according to section where the questions were, while maintaining continuous numbering. It may provide you with an alternative to usingexam
andendnotes
. The link is: tex.stackexchange.com/questions/491904/…. Please adapt the font selection astypeface
won't work anymore.