\section{Introduction and usage}%% ===> this file was generated automatically by noweave --- better not edit it
\label{exam-intro}

Many courses use exams as the tool for assessment.
Usually the exam is repeated a few times during the year and over the years.
This is quite repetitive, so we want to make it as easy as possible.
This makefile, {\Tt{}\LA{}exam.mk~{\nwtagstyle{}\subpageref{nw@notdef}}\RA{}\nwendquote}, will automate as much as possible using the 
{\Tt{}examgen\nwendquote} program~\cite{examgen}.
(It is recommended that you read the documentation of {\Tt{}examgen\nwendquote} before you 
continue, or at least run {\Tt{}examgen\ -h\nwendquote}.)

We assume that the exams will have the following structure.
There is a main TeX file called {\Tt{}exam-uniqueID.tex\nwendquote}.
If this is not the case, one will automatically be created using 
{\Tt{}./exam-template.tex\nwendquote} as the base.
This file contains the code which uses the exam document class and, in 
particular, contains the following code:
\begin{minted}{latex}
\begin{questions}
  \input{questions-ID.tex}
\end{questions}
\end{minted}
The file {\Tt{}questions-ID.tex\nwendquote} will be automatically generated by the exam
generator.
The prefixes of the filenames can be controlled using the following variables:
\nwfilename{exam.mk.nw}\nwbegincode{1}\sublabel{NW22dMcK-29jjeg-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22dMcK-29jjeg-1}}}\moddef{variables~{\nwtagstyle{}\subpageref{NW22dMcK-29jjeg-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22dMcK-1HSLS8-1}}\nwprevnextdefs{\relax}{NW22dMcK-29jjeg-2}\nwenddeflinemarkup
EXAM_NAME?=     exam
EXAM_TEMPLATE?= template
EXAM_QNAME?=    questions
\nwalsodefined{\\{NW22dMcK-29jjeg-2}\\{NW22dMcK-29jjeg-3}\\{NW22dMcK-29jjeg-4}\\{NW22dMcK-29jjeg-5}}\nwused{\\{NW22dMcK-1HSLS8-1}}\nwendcode{}\nwbegindocs{2}\nwdocspar

With this structure, we only need to keep track of the unique identifiers, 
\enquote{ID} in the example.
We will use {\Tt{}EXAM{\_}IDS\nwendquote} as a space-separated list containing all IDs.
(The default is a single ID, which is today's date.)
\nwenddocs{}\nwbegincode{3}\sublabel{NW22dMcK-29jjeg-2}\nwmargintag{{\nwtagstyle{}\subpageref{NW22dMcK-29jjeg-2}}}\moddef{variables~{\nwtagstyle{}\subpageref{NW22dMcK-29jjeg-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22dMcK-1HSLS8-1}}\nwprevnextdefs{NW22dMcK-29jjeg-1}{NW22dMcK-29jjeg-3}\nwenddeflinemarkup
EXAM_IDS?=    $(shell date +%y%m%d)
\nwused{\\{NW22dMcK-1HSLS8-1}}\nwendcode{}\nwbegindocs{4}\nwdocspar

Now let us proceed to the contents, \ie {\Tt{}questions-ID.tex\nwendquote}.
The \acp{ILO} of a course rarely changes, so usually several exams share the 
same set of \acp{ILO}.
This means that we would like to generate exams with the same parameters for 
several exams, \eg the same databases and the same tags.
These parameters are given to {\Tt{}examgen\nwendquote} as a set of tags, \ie 
a space-separated list.
\nwenddocs{}\nwbegincode{5}\sublabel{NW22dMcK-29jjeg-3}\nwmargintag{{\nwtagstyle{}\subpageref{NW22dMcK-29jjeg-3}}}\moddef{variables~{\nwtagstyle{}\subpageref{NW22dMcK-29jjeg-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22dMcK-1HSLS8-1}}\nwprevnextdefs{NW22dMcK-29jjeg-2}{NW22dMcK-29jjeg-4}\nwenddeflinemarkup
EXAM_TAGS?=     ILO1 ILO2 ... ILOn
\nwused{\\{NW22dMcK-1HSLS8-1}}\nwendcode{}\nwbegindocs{6}{\Tt{}examgen\nwendquote} also needs to get the questions from somewhere, we will use 
{\Tt{}EXAM{\_}DBS\nwendquote} as a space-separated list of question database files.
The default value is all previous exams\footnote{%
  This also includes all future exams, but {\Tt{}examgen\nwendquote} will ignore those since 
  they do not yet exist.
}.
\nwenddocs{}\nwbegincode{7}\sublabel{NW22dMcK-29jjeg-4}\nwmargintag{{\nwtagstyle{}\subpageref{NW22dMcK-29jjeg-4}}}\moddef{variables~{\nwtagstyle{}\subpageref{NW22dMcK-29jjeg-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22dMcK-1HSLS8-1}}\nwprevnextdefs{NW22dMcK-29jjeg-3}{NW22dMcK-29jjeg-5}\nwenddeflinemarkup
EXAM_DBS?=      $(foreach id,$\{EXAM_IDS\},$\{EXAM_QNAME\}-$\{id\}.tex)
\nwused{\\{NW22dMcK-1HSLS8-1}}\nwendcode{}\nwbegindocs{8}\nwdocspar

Sometimes we might want a different set of tags or databases per exam.
E.g.\ we want to generate one exam per student, where each student has an 
individual set of \acp{ILO} to be assessed on.
For this reason we allow {\Tt{}EXAM{\_}TAGS-ID\nwendquote} to override the contents of 
{\Tt{}EXAM{\_}TAGS\nwendquote} when dealing with ID.

We can also pass specific flags to the examgen program using the {\Tt{}EXAM{\_}FLAGS\nwendquote} 
variable.
We set the default value as follows.
\nwenddocs{}\nwbegincode{9}\sublabel{NW22dMcK-29jjeg-5}\nwmargintag{{\nwtagstyle{}\subpageref{NW22dMcK-29jjeg-5}}}\moddef{variables~{\nwtagstyle{}\subpageref{NW22dMcK-29jjeg-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22dMcK-1HSLS8-1}}\nwprevnextdefs{NW22dMcK-29jjeg-4}{\relax}\nwenddeflinemarkup
EXAM_FLAGS?=        -NCE
\nwused{\\{NW22dMcK-1HSLS8-1}}\nwendcode{}\nwbegindocs{10}Note that the flags can be target-specific too, \ie by setting 
{\Tt{}EXAM{\_}FLAGS-ID\nwendquote}.

We conclude with a usage example.
\begin{example}
  This will generate two exams: {\Tt{}exam-161014.pdf\nwendquote} and {\Tt{}exam-dbosk.pdf\nwendquote}.
  The first will be generated from the {\Tt{}questions.tex\nwendquote} database with the 
  complete tag set.
  The second will be generated from the same database, but only using the tag 
  \enquote{ILOn}.
  \begin{minted}{make}
EXAM_IDS=   161014 dbosk

EXAM_TAGS=  ILO1 ILO2 ... ILOn
EXAM_DBS=   questions.tex

EXAM_TAGS-dbosk=  ILOn
  \end{minted}
\end{example}


\section{Implementation}

We want to create a makefile {\Tt{}\LA{}exam.mk~{\nwtagstyle{}\subpageref{nw@notdef}}\RA{}\nwendquote} for inclusion.
The file will have the following outline:
\nwenddocs{}\nwbegincode{11}\sublabel{NW22dMcK-1HSLS8-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22dMcK-1HSLS8-1}}}\moddef{\code{}exam.mk\edoc{}~{\nwtagstyle{}\subpageref{NW22dMcK-1HSLS8-1}}}\endmoddef\nwstartdeflinemarkup\nwenddeflinemarkup
\LA{}variables~{\nwtagstyle{}\subpageref{NW22dMcK-29jjeg-1}}\RA{}
\LA{}generate targets for exam TeX files~{\nwtagstyle{}\subpageref{NW22dMcK-3BwaOm-1}}\RA{}
\LA{}generate targets for exam PDF files~{\nwtagstyle{}\subpageref{NW22dMcK-3QaIVO-1}}\RA{}
\LA{}generate targets for questions~{\nwtagstyle{}\subpageref{NW22dMcK-214cFe-1}}\RA{}
\nwnotused{[[exam.mk]]}\nwendcode{}\nwbegindocs{12}As suggested above, each exam {\Tt{}exam-ID.pdf\nwendquote} depends on at least two files: 
{\Tt{}exam-ID.tex\nwendquote} and {\Tt{}questions-ID.tex\nwendquote}.
First, we will describe how to generate {\Tt{}exam-ID.tex\nwendquote} from a template found in 
{\Tt{}./exam-template.tex\nwendquote} ({\Tt{}\LA{}generate targets for exam TeX files~{\nwtagstyle{}\subpageref{NW22dMcK-3BwaOm-1}}\RA{}\nwendquote}).
Then we will describe how we automatically generate these targets by iterating 
over the list in {\Tt{}EXAM{\_}IDS\nwendquote} ({\Tt{}\LA{}generate targets for exam PDF files~{\nwtagstyle{}\subpageref{NW22dMcK-3QaIVO-1}}\RA{}\nwendquote}).
Finally, we will describe how we generate the questions.

\subsection{Generating targets for exam TeX files}

As mentioned in \cref{exam-intro}, we will generate the file {\Tt{}exam-ID.tex\nwendquote} 
based on {\Tt{}exam-template.tex\nwendquote} if it doesn't exist.
The {\Tt{}exam\nwendquote} prefix was controlled by {\Tt{}EXAM{\_}NAME\nwendquote} and the template suffix 
controlled by {\Tt{}EXAM{\_}TEMPLATE\nwendquote}.
Thus we get this target structure:
\nwenddocs{}\nwbegincode{13}\sublabel{NW22dMcK-3BwaOm-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22dMcK-3BwaOm-1}}}\moddef{generate targets for exam TeX files~{\nwtagstyle{}\subpageref{NW22dMcK-3BwaOm-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22dMcK-1HSLS8-1}}\nwenddeflinemarkup
define exam_tex_files
$\{EXAM_NAME\}-$(1).tex:
  $\{CAT\} $\{EXAM_NAME\}-$\{EXAM_TEMPLATE\}.tex | \\
    \LA{}sed substitutions for exam with id in (1)~{\nwtagstyle{}\subpageref{NW22dMcK-4UKMrr-1}}\RA{} \\
    > $$@
endef
$(foreach id,$\{EXAM_IDS\},$(eval $(call exam_tex_files,$\{id\})))
\nwused{\\{NW22dMcK-1HSLS8-1}}\nwendcode{}\nwbegindocs{14}Note that we don't have any dependency.
Normally, it would be natural to add the template {\Tt{}exam-template.tex\nwendquote} as a 
dependency, however, we don't want to update old exams just because we update 
the template --- that should only affect future exams.

\subsection{Substituting fields from template}

To generate the exam file from the template, we perform the following 
substitutions:
\nwenddocs{}\nwbegincode{15}\sublabel{NW22dMcK-4UKMrr-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22dMcK-4UKMrr-1}}}\moddef{sed substitutions for exam with id in (1)~{\nwtagstyle{}\subpageref{NW22dMcK-4UKMrr-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22dMcK-3BwaOm-1}}\nwenddeflinemarkup
$\{SED\} \\
  -e "s/<EXAM_DATE>/$\{EXAM_DATE-$(1)\}/g" \\
  -e "s/<EXAM_ID>/$(1)/g" \\
  -e "s/<EXAM_QNAME>/$\{EXAM_QNAME\}/g"
\nwused{\\{NW22dMcK-3BwaOm-1}}\nwendcode{}\nwbegindocs{16}\nwdocspar

\subsection{Generating targets for exam PDFs}

We will not provide any recipe for compiling the PDFs, that is left for the user 
or the use of {\Tt{}tex.mk\nwendquote}.
What we will do is the following:
\nwenddocs{}\nwbegincode{17}\sublabel{NW22dMcK-3QaIVO-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22dMcK-3QaIVO-1}}}\moddef{generate targets for exam PDF files~{\nwtagstyle{}\subpageref{NW22dMcK-3QaIVO-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22dMcK-1HSLS8-1}}\nwenddeflinemarkup
\LA{}define target-specific variables~{\nwtagstyle{}\subpageref{NW22dMcK-2FNrCs-1}}\RA{}
\LA{}define callable exam definition~{\nwtagstyle{}\subpageref{NW22dMcK-2Hdtdv-1}}\RA{}
\LA{}call the exam definition for each ID~{\nwtagstyle{}\subpageref{NW22dMcK-1f1Elj-1}}\RA{}
\nwused{\\{NW22dMcK-1HSLS8-1}}\nwendcode{}\nwbegindocs{18}\nwdocspar

We want the possibility of overriding {\Tt{}EXAM{\_}NAME\nwendquote} and {\Tt{}EXAM{\_}QNAME\nwendquote} for 
certain targets.
We let the user set them, but if unset we set them to the default values.
\nwenddocs{}\nwbegincode{19}\sublabel{NW22dMcK-2FNrCs-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22dMcK-2FNrCs-1}}}\moddef{define target-specific variables~{\nwtagstyle{}\subpageref{NW22dMcK-2FNrCs-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22dMcK-3QaIVO-1}}\nwenddeflinemarkup
define target_variables
EXAM_NAME-$(1)?=   $\{EXAM_NAME\}
EXAM_QNAME-$(1)?=  $\{EXAM_QNAME\}
endef
$(foreach id,$\{EXAM_IDS\},$(eval $(call target_variables,$\{id\})))
\nwused{\\{NW22dMcK-3QaIVO-1}}\nwendcode{}\nwbegindocs{20}\nwdocspar

We do the same for the actual targets.
As stated above, we only set the dependencies and leave the recipe to the user 
(or {\Tt{}tex.mk\nwendquote}).
\nwenddocs{}\nwbegincode{21}\sublabel{NW22dMcK-2Hdtdv-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22dMcK-2Hdtdv-1}}}\moddef{define callable exam definition~{\nwtagstyle{}\subpageref{NW22dMcK-2Hdtdv-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22dMcK-3QaIVO-1}}\nwenddeflinemarkup
define exam_target
$\{EXAM_NAME-$(1)\}-$(1).pdf: $\{EXAM_NAME-$(1)\}-$(1).tex
$\{EXAM_NAME-$(1)\}-$(1).pdf: $\{EXAM_QNAME-$(1)\}-$(1).tex
endef
\nwused{\\{NW22dMcK-3QaIVO-1}}\nwendcode{}\nwbegindocs{22}Now we call the above variable and ask make(1) to evaluate it as code.
\nwenddocs{}\nwbegincode{23}\sublabel{NW22dMcK-1f1Elj-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22dMcK-1f1Elj-1}}}\moddef{call the exam definition for each ID~{\nwtagstyle{}\subpageref{NW22dMcK-1f1Elj-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22dMcK-3QaIVO-1}}\nwenddeflinemarkup
$(foreach id,$\{EXAM_IDS\},$(eval $(call exam_target,$\{id\})))
\nwused{\\{NW22dMcK-3QaIVO-1}}\nwendcode{}\nwbegindocs{24}\nwdocspar

\subsection{Generating targets for exam questions}

We also said above that the file {\Tt{}questions-ID.tex\nwendquote} will automatically be 
generated by {\Tt{}examgen\nwendquote}.
We will now provide the target that accomplishes just that.
(Since the exam depends on this file, we will automatically generate the 
questions when we try to make the exam --- if it does not already exist.)
The structure of the code will be similar as for the exam.
\nwenddocs{}\nwbegincode{25}\sublabel{NW22dMcK-214cFe-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22dMcK-214cFe-1}}}\moddef{generate targets for questions~{\nwtagstyle{}\subpageref{NW22dMcK-214cFe-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22dMcK-1HSLS8-1}}\nwenddeflinemarkup
\LA{}define target-specific questions variables~{\nwtagstyle{}\subpageref{NW22dMcK-1B7ZcU-1}}\RA{}
\LA{}define the questions target~{\nwtagstyle{}\subpageref{NW22dMcK-49tIim-1}}\RA{}
\nwused{\\{NW22dMcK-1HSLS8-1}}\nwendcode{}\nwbegindocs{26}\nwdocspar

The ID-specific variables are defined analogously to those for the exam.
The variables that are relevant to make specific are the following.
\nwenddocs{}\nwbegincode{27}\sublabel{NW22dMcK-1B7ZcU-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22dMcK-1B7ZcU-1}}}\moddef{define target-specific questions variables~{\nwtagstyle{}\subpageref{NW22dMcK-1B7ZcU-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22dMcK-214cFe-1}}\nwenddeflinemarkup
define questions_variables
EXAM_TAGS-$(1)?=    $\{EXAM_TAGS\}
EXAM_DBS-$(1)?=     $\{EXAM_DBS\}
EXAM_FLAGS-$(1)?=   $\{EXAM_FLAGS\}
endef
$(foreach id,$\{EXAM_IDS\},$(eval $(call questions_variables,$\{id\})))
\nwused{\\{NW22dMcK-214cFe-1}}\nwendcode{}\nwbegindocs{28}\nwdocspar

Finally, we can define target as follows.
The target file \enquote{questions-ID.tex} depends on the questions databases 
to exist.
Then the recipe simply runs {\Tt{}examgen\nwendquote} with the set parameters.
\nwenddocs{}\nwbegincode{29}\sublabel{NW22dMcK-49tIim-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22dMcK-49tIim-1}}}\moddef{define the questions target~{\nwtagstyle{}\subpageref{NW22dMcK-49tIim-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22dMcK-214cFe-1}}\nwenddeflinemarkup
define questions_target
.PRECIOUS: $\{EXAM_QNAME-$(1)\}-$(1).tex
$\{EXAM_QNAME-$(1)\}-$(1).tex:
  examgen $\{EXAM_FLAGS-$(1)\} -d $\{EXAM_DBS-$(1)\} -t $\{EXAM_TAGS-$(1)\} > $$@
endef
$(foreach id,$\{EXAM_IDS\},$(eval $(call questions_target,$\{id\})))
\nwused{\\{NW22dMcK-214cFe-1}}\nwendcode{}

\nwixlogsorted{c}{{\code{}exam.mk\edoc{}}{NW22dMcK-1HSLS8-1}{\nwixd{NW22dMcK-1HSLS8-1}}}%
\nwixlogsorted{c}{{call the exam definition for each ID}{NW22dMcK-1f1Elj-1}{\nwixu{NW22dMcK-3QaIVO-1}\nwixd{NW22dMcK-1f1Elj-1}}}%
\nwixlogsorted{c}{{define callable exam definition}{NW22dMcK-2Hdtdv-1}{\nwixu{NW22dMcK-3QaIVO-1}\nwixd{NW22dMcK-2Hdtdv-1}}}%
\nwixlogsorted{c}{{define target-specific questions variables}{NW22dMcK-1B7ZcU-1}{\nwixu{NW22dMcK-214cFe-1}\nwixd{NW22dMcK-1B7ZcU-1}}}%
\nwixlogsorted{c}{{define target-specific variables}{NW22dMcK-2FNrCs-1}{\nwixu{NW22dMcK-3QaIVO-1}\nwixd{NW22dMcK-2FNrCs-1}}}%
\nwixlogsorted{c}{{define the questions target}{NW22dMcK-49tIim-1}{\nwixu{NW22dMcK-214cFe-1}\nwixd{NW22dMcK-49tIim-1}}}%
\nwixlogsorted{c}{{generate targets for exam PDF files}{NW22dMcK-3QaIVO-1}{\nwixu{NW22dMcK-1HSLS8-1}\nwixd{NW22dMcK-3QaIVO-1}}}%
\nwixlogsorted{c}{{generate targets for exam TeX files}{NW22dMcK-3BwaOm-1}{\nwixu{NW22dMcK-1HSLS8-1}\nwixd{NW22dMcK-3BwaOm-1}}}%
\nwixlogsorted{c}{{generate targets for questions}{NW22dMcK-214cFe-1}{\nwixu{NW22dMcK-1HSLS8-1}\nwixd{NW22dMcK-214cFe-1}}}%
\nwixlogsorted{c}{{sed substitutions for exam with id in (1)}{NW22dMcK-4UKMrr-1}{\nwixu{NW22dMcK-3BwaOm-1}\nwixd{NW22dMcK-4UKMrr-1}}}%
\nwixlogsorted{c}{{variables}{NW22dMcK-29jjeg-1}{\nwixd{NW22dMcK-29jjeg-1}\nwixd{NW22dMcK-29jjeg-2}\nwixd{NW22dMcK-29jjeg-3}\nwixd{NW22dMcK-29jjeg-4}\nwixd{NW22dMcK-29jjeg-5}\nwixu{NW22dMcK-1HSLS8-1}}}%
\nwbegindocs{30}\nwdocspar

\nwenddocs{}
