The exam package

Hans van der Meer hansm@fwi.uva.nl

vs.3.19 - 1995/03/10

Contents

1 Usage

1.1 Exam production

An exam can be built from the following template. For special issues as the use of default names for various directories, language selection, etc. see the implementation section. You may customize the typesetting by providing a file exam.cfg in the search path; this file is read just before typesetting begins.

 \documentclass[options]{exam}
 \title{title of exam}
 \author{the examinator}
 \target{the students}
 \begin{document}
 \begin{exam}[startvalue random generator]{date of exam}
 \question{directory}{file}
 \question[parameter value]{directory}{file} % parametrized
 ....
 \end{exam}
 ... % possibly other exams
 \end{document}

1.2 Format of a problem

A problem is built by environment problem. In it several elements can be placed. These are:

1. \parameterproblem{text}: used to communicate to the maintainer of the problems the possibilities offered by the transfer of macro \parameter on posing the question; an example of this will follow. Can also find a place before the problem declaration.

2. \begin{problem}[#1]; the optional parameter can have the value \compact (no pagebreak within problem, default) or the value \split (pagebreak may occur in problem).

3. \problemdate{date}: a macro to remember on which day the problem was born;

4. \score{value}: use this macro for the number of points the answer is worth; it is possible to include several score items in one problem for partial rewards. The score value is not shown when an exam is typeset, the student must earn these points!

5. text of the question.

6. the answer or multiple choice list; see the description below.

7. \remark[h]{b}: a boxed remark with heading h and body b.

8. \end{problem}.

problem — coding —

\begin{problem}
\problemdate{\today}
What is the question?
\score{2}
\shortanswer{To be or not to be.}
\end{problem}

problem — result — left without answers, right with answers, series Problem 0. What is the

question?

Answer: . . . . . . . . . . . . . . .

Problem 0. What is the

question?

Answer: To be or not to be.

June 19, 1996

The next example shows the use of a parameter for the selection of alternate questions.

parameterproblem — coding —

\parameterproblem{1= to be\\2= not to be}
\begin{problem}
\problemdate{\today}
\score{2}
\def\parameter{2} % normally comes from \question[2]...
What is\ifnum\parameter=1\relax\else n't\fi\ the question?
\shortanswer{\ifnum\parameter=1\relax To be or n\else N\fi ot to be.}
\end{problem}

parameterproblem — result — left parameter = 1, right parameter = 2

Parameter Problem: 1= to be 2= not to be

Problem 0. What is the question? Answer: To be or not to be.

June 19, 1996

Parameter Problem: 1= to be 2= not to be

Problem 0. What isn’t the question? Answer: Not to be.

June 19, 1996

Another method for the selection of alternatives is via the mechanism implemented in macros \loaditem and friends (See sections ?? and ??. Pieces text can be loaded (in this implementation at most 5) and selectively dumped into the typeset input stream.

Macro \loaditem can be used to load from one to five items in a data store. This data store can be shuffled by a call to \shuffle. Popping items from the store is effected by macros \dumpitem (pop one item) and \dumpitems (all items). Clearing of the store is done by \resetloadcounter. With \SRtest{1}{2} one can make a random choice between two alternatives.

load and dump — coding —

\SRset{349}              % startup random generator
\resetloadcounter        % initialize load stack
\loaditem{\fbox{item 1}\space} % load 4 items of text
\loaditem{\fbox{item 2}\space}
\loaditem{\fbox{item 3}\space}
\loaditem{\fbox{item 4}\space}
Here comes nr~2: \dumpitemno{2}\par
\shuffle                 % randomize
Here comes nr~2 again after randomization: \dumpitemno{2}\par
Dump the whole lot: \dumpitems

load and dump — result —

Here comes nr 2: item 2

Nr 2 again after randomization: item 4

Dump the whole lot: item 1 item 3 item 4 item 2

1.3 Answers

The basic macros for showing and suppressing answers are \answer that shows its argument when the answers option is chosen, and \altanswer that alternates its two arguments. Both macros have a first, optional argument for specifying the width of the box wherein the text is placed.

answer/altanswer — coding —

 \answer[.3\linewidth]{answer}\\
 \altanswer[.3\linewidth]{answers NO}{answers YES}

answer/altanswer — result — left without answers, right with answers

answers NO  answer answers YES

Some questions can be answered by a few words, a short sentence. The command \shortanswer serves this purpose; its first argument is optional and used for the width of the answerbox, its second argument is the answer itself.

short answer — coding —

 Answer the next question:
 \shortanswer[.35\linewidth]{The answer.}

short answer — result — left without answers, right with answers Answer the next question:

Answer: . . . . . . . .

Answer the next question: Answer: The answer.

When however more space is needed by the student, the environment longanswer can be used. This environment has one optional parameter, meant for specifying the amount of white space to be reserved for the students answer.

long answer — coding —

 Answer the next question:
 \begin{longanswer}[5mm]
 The answer.
 \end{longanswer}

long answer — result — left without answers, right with answers

Answer the next question:

Answer:

Answer the next question:

Answer:

The answer.

The answer is headed by a call to \answerstart; redefine to your taste.

The default of white space reserved for the depth of the short answer can be changed by redefinition of \shortwhite. The default for the white space of the long answer can be changed by redefinition of \longwhite.

1.4 Multiple Choice

Multiple choice is provided for by environment choice. Within this environment a itemized list of alternatives is given. However instead of \item one codes \baditem{text} for wrong answers and \gooditem{text} for the correct one; the answer being put into the argument of these two macros. The optional parameter of this environment can be \ordered for production of the alternatives in the order specified, or \random for randomization; randomize is the default, unless the series option is specified in the \documentclass call.

 \end{choice}

multiple choice example — coding — Choose the most appropriate alternative:

\begin{choice}[\ordered] \baditem{first wrong answer} \gooditem{the right answer} \baditem{second wrong answer}

multiple choice — result — left without answers, right with answers Choose appropriate alternative:

◯ first wrong answer ◯ the right answer ◯ second wrong an-

swer

Choose appropriate alternative:

◯ first wrong answer √ the right answer ◯ second wrong an-

swer

The marks for the multiple choice items are produced by the macros \badmark and \goodmark. For their redefinition see the implementation section of this document.

1 ⟨∗package⟩

2 Identification

This document class can only be used with L^{A}TEX 2ε, so we make sure that an appropriate message is displayed when another TEX format is used. We require the latest version that has no known troubles with this class.

 2 \NeedsTeXFormat{LaTeX2e}[1994/12/01]

Announce the Class name and its version.

 3 \ProvidesClass{exam}[\filedate\space vs\fileversion\space Exam package]
\examerror  Define \examerror and \examwarning to issue a proper \ClassError or

\examwarning \ClassWarning in case of errors. Note that the error macro provides for a help text in its second argument.

\examerror
\examwarning
 4 \newcommand\examerror[2]{\ClassError{exam}{!!!! #1}{#2}}
 5 \newcommand\examwarning[1]{\ClassWarning{exam}{!!!! #1}}

3 Declaration of Class Options

In this part we define the options for this class that are additional to those of its parent class.

3.1 Switching answers on and off

The flag \ifanswers governs the production of answers in the typesetting of problems. With the answers options in the optional argument of the document class this option is turned on. Then also we show the score values.

\ifanswers
 6 \newif\ifanswers
 7 \DeclareOption{answers}{\answerstrue\scorestrue}

3.2 Suppress options list

The flag \ifhelpful governs the presentation of the options list.

\ifhelpful
 8 \newif\ifhelpful
 9 \helpfultrue
10 \DeclareOption{nohelp}{\helpfulfalse}

3.3 Each problem on separate page

The flag \ifpages governs the typesetting of problems on separate pages, or their collection of more than one to a page. If separate pages are chosen, a separator between problems is unnecessary.

\ifproblempages
11 \newif\ifproblempages
12 \DeclareOption{pages}{\problempagestrue\problemsepfalse}

3.4 Suppress prompt for answer

The flag \ifreservespace governs the typesetting of space for answers. If true, all reservation of answer space is suppressed. It is set by option questiononly; this option has no effect when the answers option is on.

\ifreservespace
13 \newif\ifreservespace
14 \reservespacetrue
15 \DeclareOption{questiononly}{\reservespacefalse}

3.5 Visible separation between problems

The value of flag \ifproblemsep determines the appearance of a visible separation between successive problems.

\ifproblemsep
16 \newif\ifproblemsep
17 \problemseptrue
18 \DeclareOption{nosep}{\problemsepfalse}

3.6 Showing score values

The flag \ifshowscores determines when score values are printed.

\ifscores
19 \newif\ifscores
20 \DeclareOption{scores}{\scorestrue}

3.7 Typeset a Catalogue of Problems

The flag \ifseries initiates the production of a problem catalogue. In order to show answers and score values, the respective flags are set.

\ifseries
21 \newif\ifseries
22 \DeclareOption{series}{\seriestrue\answerstrue\scorestrue}

4 Loading of Parent Class

\parentclass Since the exam class is implemented as a modification of an existing document class, we must load the parent class. In order to make changes in parent class easy, the name of this class is parametrized in macro \parentclass. Obvious candidates are article and report. In order to provide some flexibility, we allow for the case that the user has already defined \parentclass (before the call to \documentclass. In that case we refrain from redefinition.

\parentclass
23 \providecommand\parentclass{article}

The options of the \documentclass call which are not specific for the exam class must be passed to the parent class. We take the opportunity to select the production of a titlepage (not automatically added if the parent class is article. After this we process the local options.

24 \DeclareOption*{\PassOptionsToClass{\CurrentOption}{\parentclass}}
25 \PassOptionsToClass{titlepage}{\parentclass}
26 \ProcessOptions

Show options to the user (if not suppressed)

27 \ifhelpful
28 \ClassWarningNoLine{exam}{%
29  documentclass `exam' version \fileversion, date \filedate.
30  \MessageBreak
31  available options:
32  \MessageBreak
33  answers:\space show questions with answers;
34  \MessageBreak
35  nohelp:\space suppress this message;
36  \MessageBreak
37  nosep:\space no separators between problems;
38  \MessageBreak
39  pages:\space each problem on a page;
40  \MessageBreak
41  questiononly:\space suppress answer space in exams;
42  \MessageBreak
43  scores:\space typeset score values always;
44  \MessageBreak
45  series:\space\space typeset catalogue of problems}
46 \fi

Then we load the parent class.

47 \LoadClass{\parentclass}

5 Produce an Exam

First we need a counter for exams, since in one run more than one exam can be produced. By stepping this counter we will effect the automatic reset of the counter that numbers the problems and the counter that remembers the score value.

\examnum
48 \newcounter{examnum}

exam Exams are produced within the exam environment. This environment takes 2 parameters. The first one is optional and provides the initial value of the random generator.^{1} The default is 0, which effectively shuts off randomness. The second parameter must be present, but can be empty. It fixes the date for which the exam is planned; an empty argument fills in the current date.

exam
49 \newenvironment{exam}[2][0]{%
50 \stepcounter{examnum}%
51 \@ifemptyarg{#2}{}{\date{#2}}%
52 \ifseries\else\ifanswers
53  \addcontentsline{toc}{section}{\Exam~\theexamnum~---~\@date}%
54 \fi\fi

When answers are requested we start with a titlepage^{2} and a table of contents. In the case of exam production, typesetting of the titlepage is deferred to the end of the exam, so that we may print on it the number of problems. We write a few messages to the table of contents (date and initial value of the random generator) when an exam with answers is in production.

55 \ifanswers
56  \pagenumbering{roman}%
57  \maketitle\tableofcontents\cleardoublepage
58 \fi
59 \pagenumbering{arabic}%
60 \ifseries\SRset{0}\else
61  \SRset{#1}%
62  \addcontentsline{toc}{subsection}{Start value random generator = #1}%
63 \fi

In each separate exam the first page gets the number one.

64 \setcounter{page}{1}}%

At the end of the exam produced for the students a titlepage is produced. If answers are given for an exam we provide the total value of the scores.

65 {\ifseries\else
66  \typeout{Total value scores = \thetotalscore}%
67  \ifanswers
68  \addcontentsline{toc}{subsection}{Total value scores = \thetotalscore}%
69  \else\maketitle
70  \fi\fi}

1Not used when a series is run.

2If not inhibited by the notitlepage option.

6 Choice of Problems

We start with a counter \problemnum with which the problems of the exam are neatly numbered. This counter is automatically reset each time a new exam environment is entered. A textual identification of the current problem is collected in token register \problemid.

\problemnum \problemid
71 \newcounter{problemnum}[examnum]
72 \newtoks\problemid

\question Each question resides in its own file, which is called up by macro \question. Of its three parameters the first is optional and provides a means of communication with the problem itself. To achieve this the first argument of \question is cached in macro \parameter.^{3} The default behaviour here is not touching the the definition of \parameter in case of an empty argument; in many cases a forgotten argument will then lead to a “missing something” error. The benefit of not touching \parameter in case of an empty argument is that this macro now also can be initialized by other means, e.g. by definition earlier in the problem coding.

The second parameter of \question is the name of the (sub)directory where the file named in the third parameter can be found. This second parameter doubles up as section name in the series production.^{4}

\question
73 \newcommand\question[3][]{%
74 \@ifemptyarg{#1}{}{\renewcommand\parameter{#1}}%

When a series is run we look for the start of a new section and perform the appropriate actions if indeed a new section is found. I.e. eject the page and then reset the section name and the problem counter. Note the use of uppercase in order to smooth out differences in typing. The identification of the problem is set to its file name and, in the case of a series, is mentioned in the output. Then the problem number is incremented.

75 \ifseries
76  \uppercase{\def\@namesection{#2}}%
77  \ifx\namesection\@namesection
78  \else
79  \newpage
80  \global\let\namesection=\@namesection
81  \addcontentsline{toc}{subsection}{\namesection}%
82  \setcounter{problemnum}{0}%
83  \fi
84 \fi
85 \problemid={\uppercase{#3}}%

3As most uses of this mechanism boil down to a choice between several alternatives, the number 1 is provided by macro \parameterproblem as a convenient default value. See also the discussion under the heading “Parametrized Problems”.

4It is silently assumed that all problems of a given category reside in a common directory.

86 \ifseries
87  \noindent\underbar{\emph{File\,:}~\texttt{\the\problemid}}\par
88  \nopagebreak\medskip\nopagebreak
89 \fi
90 \stepcounter{problemnum}%

Reading of the problem itself is surrounded by calculations on the score that this question will bring. Scores are mentioned on the console except when a series is run. In a problem all contributions from the various parts of the problem are collected in counter scorecounter. At the end of the problem totalscore is updated with this value.^{5} The code guards against typing errors in the name of the file.

91 \IfFileExists{\mainfolder#2:#3}{\@@input \mainfolder#2:#3}%
92  {\examwarning{File \mainfolder#2:#3 not found}}%
93 \ifseries\else
94  \addtocounter{totalscore}{\value{scorecounter}}%
95  \typeout{\Problem\space\theproblemnum: score=\thescorecounter}%
96 \fi

If appropriate a summary of this problem is written to the table of contents.

97 \ifanswers
98  \addcontentsline{toc}{subsubsection}%
99  {\hbox to1cm{\theproblemnum:\hss}%
100  \hbox{#3~~[score = \thescorecounter]}}%
101 \fi}

Macro \namesection gets its initial value here:

namesection
102 \newcommand\namesection{\Collection}

6.1 Parametrized Problems

\parameter A parametrized problem gets its parameter from the first argument of macro \question, as already have been mentioned. This is effected by definition of macro \parameter to the value of that argument. We add code here to (re)initialize this macro.

\reset@parameter
103 \newcommand\reset@parameter{\gdef\parameter{}}
104 \reset@parameter

\parameterproblem The first argument is optional and serves as default value for \parameter. The default value for this is the number 1. It is recommended that the macro \parameterproblem is placed in the problem before the use of \parameter. Then this macro provides a check on the proper definition of \parameter when in exam production; if it is not yet defined this macro will receive the default value of \parameterproblem and issue a warning. The macro will typeset its second argument in a framed box. Usually it tells the reader which options are available; however, only in the case a series is run, otherwise ‘silence’ is the word.

5Note the resets for totalscore with examnum and scorecounter with problemnum in their declaration.

The description is placed in a framed parbox, hanging with an indent from the intro text by macro \remark.

\parameterproblem
105 \newcommand\parameterproblem[2][1 ]{%
106 \ifx\parameter\@empty
107  \ifseries\else\examwarning{\string\parameter\space undefined,
108  value `#1' taken}\fi
109  \renewcommand\parameter{#1}%
110 \fi
111 \remark[Parameter \Problem]{#2}}

7 Typesetting a Problem

\everyproblem Each problem must be enclosed in an environment problem. Within this environment a default setup exists. By supplying code in token register \everyproblem one can influence the typesetting of each problem.

\everyproblem
112 \newtoks\everyproblem

problem The problem environment also has one optional parameter for specific adjustments of the options setting. Execution of options occurs in the order: default setup, possible modification by \everyproblem and final customization through the optional parameter. This mechanism provides for maximum flexibility.

problem
113 \newenvironment{problem}[1][]{%

Calling of options is guarded by a mechanism that makes them active when necessary. Only when the switch \if@tagsforbid is set false has calling of such an option any effect. The relevant macros are described in section ??.

Choose by default for keeping the whole problem on a page, execute any code in the token register and honor the option calls from the user. Finally shut off option processing.

114 \@tagsforbidfalse\compact\the\everyproblem#1\@tagsforbidtrue

In order to keep everything on page we will enclose the problem in a vbox, coded in macro \@boxing. Otherwise \@boxing is a noop and TEX’s pagebuilder can choose its breakpoint freely. For the declaration of \@boxing see section ??.

The problem is typeset with a standard opening programmed in \problemstart, completing the opening manoeuvres of the environment.

115 \@boxing\bgroup\noindent\problemstart\ignorespaces}%

After processing the body of the problem some postprocessing follows and the possible vbox is closed by an \egroup.

In particular a visual separation from the next problem is added, if not suppressed. In the case of series production the origin date of the problem is added too.^{6}

116 {\par\ifproblemsep
117  \nopagebreak\smallskip\nopagebreak
118  \hbox to\linewidth{\hrulefill
119  \ifseries
120  \emph{\footnotesize\thinspace\the\@problemdate}%
121  \fi}\fi
122 \egroup\par

Start a new page or separate the problem from the next one by a skip.

123 \ifproblempages\newpage\else\bigskip\fi

The origin date and the communicated value in macro \parameter are cleared for the next problem.

124 \reset@problemdate\reset@parameter}

7.1 Code for Options to Problem

The options to problem are \compact or \split. These options govern the possibility for the problem to be split between successive pages or the necessity to keep everything on page; the last one being the favoured behaviour in this implementation. Note the \noident before the \vbox that prevents an unwanted shift to the right.

\compact \split
125 \newcommand\compact{\@chktag\compact\def\@boxing{\noindent\vbox}\fi}
126 \newcommand\split{\@chktag\split\def\@boxing{\@empty}\fi}

The \@chktag macro is provided. Note the open ended \if...\else which will be closed by a \fi in the option definition.

\if@tagsforbid
\@chktag
127 \newif\if@tagsforbid \@tagsforbidtrue
128 \providecommand\@chktag[1]{%
129 \if@tagsforbid\@warning{tag \string#1\space ignored here}\else}

7.2 Numbering the Problem

A problem gets a standard opening clause, coded in macro \@problemstart. The opening code is used to format the first paragraph with a nice indentation.^{7}

6Only if it has been provided to it by the proper macro call, of course.

7This indentation is also used in the left margin in multiple choice listings in order to limit the variation in margins.

\@problemstart
\problemstart
130 \newcommand\@problemstart{%
131 \textbo{\Problem\,\ifnum\value{problemnum}<10 \phantom{0}\fi
132 \theproblemnum}.\enskip}
133 \newcommand\problemstart{%
134 \hangafter-2\settowidth\hangindent{\@problemstart}%
135 \noindent\llap{\@problemstart}}

7.3 Date of Origin

\problemdate The user may specify an original date or date of last change for the problem to be printed when a series is produced. The global assignments are here just in case things happen in a deeper nested level.

\@problemdate
\problemdate
\@resetproblemdate

136 \newtoks\@problemdate
137 \newcommand\problemdate[1]{\global\@problemdate={#1}\ignorespaces}
138 \newcommand\reset@problemdate{\global\@problemdate={}}
139 \reset@problemdate

7.4 Score Values

Associated with each problem are of course the benefits the student receives for a good answer to (part of) the problem. The \score macro exists for this purpose. If answers are not included, just an empty square is printed into which the teacher can express his satisfaction with the answer given. When answers are included in the printout the each call \score{value} shows up in the right margin of the document.^{8}

These counters collect the values. Note that \totalscore is reset for each new exam and \scorecounter for each problem.

\totalscore
\scorecounter
140 \newcounter{totalscore}[examnum]
141 \newcounter{scorecounter}[problemnum]

The next commands are used for the production of the box for the score value.

\scoreboxsize
\scorebox
142 \newcommand\scoreboxsize{6mm}
143 \newcommand\scorebox[1]{%
144 \fbox{\vbox to\scoreboxsize{\vss\hbox to\scoreboxsize{\hss#1\hss}\vss}}}

\score Finally the next code puts the score box on paper. It takes the value of the score as its argument and adds it to the running sum for this problem.

8At the end of each problem a summary of its total score plus a grand total are presented on the console.

\score
145 \newcommand\score[1]{%
146 \addtocounter{scorecounter}{#1}%
147 \rightnote{\scorebox{\ifscores#1\fi}}%
148 \ignorespaces}

We do not use \marginpar for the placement of the score values, because we do not want these items wandering around, as \marginpar’s sometimes do. The optional argument to the ..note macros specifies a vertical amount to be skipped in the placement of the note. We use \providecommand because we may have them incorporated already in other packages. Note the \noindent before the \vadjust that also leaves vmode for the benefit of the \vadjust.

\leftnote \rightnote \@rlnote
149 \providecommand\leftnote[1][-\baselineskip]{\@rlnote l{#1}}
150 \providecommand\rightnote[1][-\baselineskip]{\@rlnote r{#1}}
151 \providecommand\@rlnote[3]{%
152 \noindent\vadjust{\vbox to\z@{%
153  \vskip#2\leftskip\z@skip\rightskip\z@skip\noindent
154  \if#1l\llap{#3\hskip\marginparsep}%
155  \else\hfill\rlap{\hskip\marginparsep#3}\fi
156  \vss\vskip\z@skip}}}

7.5 Adding remarks

\remark In making a catalogue of problems (option series selected) it is useful when remarks can be added that stand out against the rest of the text. Macro \remark provides such a mechanism. Its first (optional) argument is set emphasized, its second argument hangs on the first. The complete remark is placed in a \parbox and then boxed and centered.

\remark
157 \newcommand\remark[2][]{%
158 \ifseries
159  \begin{center}%
160  \fbox{\parbox{.9\linewidth}{%
161  \sloppy\hangafter\@ne
162  \setbox\z@=\hbox{\emph{#1}\@ifemptyarg{#1}{}{:~}}%
163  \hangindent=\wd\z@
164  \strut\box\z@ #2}}%
165  \end{center}\nopagebreak
166  \addvspace{5mm}\nopagebreak
167 \fi}

8 Answers

In this section various ways of typesetting answers are provided.

\longwhite We start with two definitions for long and short stretches of white space. These \shortwhite are meant for leaving room for the students answer.

\longwhite \shortwhite
168 \newcommand\longwhite{25mm}
169 \newcommand\shortwhite{8mm}

\answerstart Just as with the typesetting of the problem, we provide a macro to start an answer. Note that the text is parametrized in order to keep switching to other languages simple.

\answerstart
170 \newcommand\answerstart{\noindent\emph{\Answer}:\enspace}

8.1 Switching Answer On and Off

\answer Macro call \answer holds the answer and shows it when answers are requested. The optional first argument specifies a width for the box into which the typesetting takes places. The answer is centered by default; change it with \hfil’s. Implementation of \answer is by the next macro \altanswer.

\answer
171 \newcommand\answer[2][]{\altanswer[#1]{}{#2}}

8.2 Alternating Some Stuff and Answer

\altanswer With \altanswer the text alternates between two possibilities: the first one is typeset when answers are suppressed, the second one for the opposite case. Optional width argument and placement are the same as for \answer.

\altanswer
172 \newcommand\altanswer[3][]{%
173 \@ifemptyarg{#1}%
174  {\mbox{\ifanswers#3\fi}}%
175  {\makebox[#1]{\ifanswers#3\else#2\fi}}%

176 }

8.3 Problem with a Short Answer

\shortanswer A question “Give a short answer to … ” is formatted in \shortanswer. Usually the answer will fit on one line. In the exam a row of dots is produced, otherwise the answer will show. The optional argument provides the width of the box into which the data are typeset.

\shortanswer
177 \newcommand\shortanswer[2][.75\linewidth]{\par
178 \ifanswers
179  \addvspace{\smallskipamount}%

180  \answerstart\parbox[t]{#1}{\noindent #2}%
181  \par\medskip
182 \else\ifreservespace
183  \addvspace{\shortwhite}%
184  \answerstart\makebox[#1]{\dotfill}%
185  \par\medskip
186 \fi\fi

187 }

8.4 Problem with a Long Answer

longanswer For elaborate questions, problems, etc. an environment is available. The longanswer environment takes as optional argument the length of white to be reserved for the student.

Code for opening of the environment. It opens a box in order to let the answer disappear and places a rule in order to guarantee sufficient white space.

longanswer
188 \newenvironment{longanswer}[1][\longwhite]{
189 \par
190 \ifanswers
191  \addvspace{\medskipamount}\answerstart
192  \nopagebreak\par\noindent
193 \else\ifreservespace
194  \addvspace{\medskipamount}\answerstart
195  \nopagebreak\par\noindent
196  \hrule\@height#1\@width\z@\par
197  \fi
198  \setbox\z@\vbox\bgroup\leavevmode
199 \fi}

Aftermath of longanswer. If necessary close the box and empty it to get rid of the answer.

200 {\ifanswers\par\medskip\else\egroup\setbox\z@\hbox{}\fi}

9 Multiple Choice Questions

Multiple choice problems must be placed in an choice environment, a modification

of itemize.

We will make it possible to shuffle the items of a multiple choice problem randomly. These items are held in a series of token registers declared below.

We need a counter into which to keep the number of items at any time loaded into the token registers declared above. Also we provide for resetting, incrementing and decrementing of this register. Note the global assignments.

\loadcounter
\resetloadcounter
\incloadcounter
\decloadcounter

201 \newcount\loadcounter
202 \newcommand\resetloadcounter{\global\loadcounter\z@}

203 \newcommand\incloadcounter{\global\advance\loadcounter\@ne}
204 \newcommand\decloadcounter{\global\advance\loadcounter\m@ne}

We want a specific behaviour when the list of items is typeset. However, we cannot be sure at which listlevel this will occur. Therefore we predeclare a replacement for \@listi, \@listii, or whatsoever, and swap the \@list.. at the right time. Note the choice for the leftside margin, derived from the width of the text with which the problem starts. This choice diminishes the number of different margins. It is easily adapted to your own taste.

\@listk
205 \newcommand\@listk{%
206 \settowidth{\leftmargin}{\@problemstart}%
207 \topsep\medskipamount
208 \partopsep\z@
209 \itemsep\smallskipamount
210 \parsep\z@}

9.1 Typesetting Multiple Choice

choice The multiple choice environment choice takes one argument, the modifier options to the environment typesetting. Here the options are \random and \ordered; the names speak for themselves. Note that random permutation is not executed if a series is run. Furthermore the counter for the number of items loaded is reset.

choice
211 \newenvironment{choice}[1][]{%
212 \@tagsforbidfalse\ifseries\ordered\else\random\fi#1\@tagsforbidtrue
213 \resetloadcounter

The following code is taken from L^{A}TEX’s itemize. I did not find a more elegant way to bend this environment to my whims.

214 \ifnum\@itemdepth>3 \@toodeep \else
215 \advance\@itemdepth\@ne
216 \expandafter\let
217  \csname @list\romannumeral\the\@itemdepth\endcsname=\@listk
218 \list{\badmark}{\def\makelabel##1{\hss\llap{##1}}}%
219 \fi}%

At the end of choice we dump all the items that may have been collected inbetween and finish the list.

220 {\@dumpitems\endlist}

9.2 Code for Options to Choice

The option \random codes macros \@loaditem and \@dumpitems so that the items are actually loaded, then shuffled and dumped afterwards. The \ordered option makes them noops and thus the items will be typeset on the fly.

\random \ordered
221 \newcommand\random{\@chktag\random
222  \def\@loaditem{\loaditem}%
223  \def\@dumpitems{\shuffle\dumpitems}%
224 \fi}
225 \newcommand\ordered{\@chktag\ordered
226  \def\@loaditem{}%
227  \def\@dumpitems{}%
228 \fi}

9.3 Formatting the Item Mark

\marksize We require two marks: one for the bad guys and one for the good guy. We use the

\badmark
\goodmark

two symbols \square and \boxtimes, but provide replacements in case these are undefined. Typeset these marks in fixed size (unchanged baselineskip) provided

 by macro \marksize.
\square \boxtimes \marksize \badmark \goodmark
229 \providecommand\square{\bigcirc}
230 \providecommand\boxtimes{\surd}
231 \newcommand{\marksize}{\fontsize{12}{\f@baselineskip}\selectfont}
232 \newcommand{\badmark}{{\marksize\ensuremath{\square}}}
233 \newcommand{\goodmark}%
234 {\ifanswers{\marksize\ensuremath{\boxtimes}}\else\badmark\fi}

\baditem Each item can either be right or wrong. We take the precaution to suppress \gooditem the difference when typesetting the actual exam. Enclose each item in your list

in the argument to \gooditem and \baditem. They will load the item in memory prior to (possible) random shuffling.

\baditem \gooditem
235 \newcommand{\baditem}[1]{\@loaditem{\item[\badmark]#1}}
236 \newcommand{\gooditem}[1]{\@loaditem{\item[\goodmark]#1}}

9.4 Loading and Dumping Items

This series of token registers can hold five alternatives. The mechanism that loads the items is sufficiently general to use it for other purposes too. Use your imagination! That there are five of them is remembered in a definition because we will need this number to prevent overfilling the store.

\@itemA
\@itemB
\@itemC
\@itemD
\@itemE
\@itemstore

237 \newtoks\@itemA
238 \newtoks\@itemB
239 \newtoks\@itemC
240 \newtoks\@itemD
241 \newtoks\@itemE
242 \newcommand\@itemstore{5}

\loaditem According to the value of loadcounter the token registers \@itemA, etc. are filled. Argument to macro \loaditem is the contents of the item.

\loaditem
243 \newcommand\loaditem[1]{%
244 \ifcase\loadcounter
245  \@itemA={#1}%
246  \or\@itemB={#1}%
247  \or\@itemC={#1}%
248  \or\@itemD={#1}%
249  \or\@itemE={#1}%
250 \fi
251 \ifnum\loadcounter<\@itemstore \incloadcounter
252 \else\examwarning{\string\loaditem\space ignored, too many}\fi}

\dumpitem Produce items that were loaded. With \dumpitem the last one comes out and is

\dumpitems
\dumpitemno

chopped off from the stack, with \dumpitems the whole lot is dumped. By means of \dumpitemno one can peek inside the stack: its parameter gives the position to be produced, the item itself remains on the stack.

\dumpitemno \dumpitem \dumpitems
253 \newcommand\dumpitemno[1]{%
254 \ifnum#1>\loadcounter
255  \examwarning{\string\dumpitemno[#1] ignored, out range}%
256 \else\ifcase#1\relax
257  \or\the\@itemA
258  \or\the\@itemB
259  \or\the\@itemC
260  \or\the\@itemD
261  \or\the\@itemE
262 \fi\fi}
263 \newcommand\dumpitem{\dumpitemno{\loadcounter}\decloadcounter}
264 \newcommand\dumpitems{\@whilenum\loadcounter>\z@\do{\dumpitem}}

9.4.1 Shuffling Items

\shuffle This macro permutes loadcounter items in the token registers \@itemA, etc. Undoubtedly it can be done better, but who’s perfect?

\shuffle
265 \newcommand\shuffle{%
266 \ifcase\loadcounter
267  \or
268  \or\shuffle@ii
269  \or\shuffle@\@itemA\@itemC \shuffle@ii \shuffle@\@itemB\@itemC
270  \or\shuffle@iv
271  \or\shuffle@\@itemD\@itemE \shuffle@iv \shuffle@\@itemD\@itemE
272  \fi

273 }

Random interchange of two and four items.

\@item@ \shuffle@ \shuffle@ii \shuffle@iv
274 \newtoks\@item@
275 \newcommand\shuffle@[2]{\SRtest{}{\@item@=#1 #1=#2 #2=\@item@}}
276 \newcommand\shuffle@ii{\shuffle@\@itemA\@itemB}
277 \newcommand\shuffle@iv{%
278 \SRtest{\shuffle@\@itemA\@itemB}{\shuffle@\@itemC\@itemD}%
279 \SRtest{\shuffle@\@itemA\@itemC}{\shuffle@\@itemB\@itemD}}

9.4.2 Random Generator Implementation

\SRtest Not much commentary with these macros. They are described in Tugboat 1994, vol. 15.1, p. 57–58.

\@SR
\@SRconst
\SRset
\@SRadvance
\SRbit
\SRtest
\SRvalue

280 \ifx\@SR\undefined\newcount\@SR\fi
281 \providecommand\@SRconst{2097152}
282 \providecommand\SRset[1]{\global\@SR#1 \ignorespaces}
283 \providecommand\@SRadvance{%
284 \begingroup
285 \ifnum\@SR<\@SRconst\relax\count@\z@\else\count@\@ne\fi
286 \ifodd\@SR\advance\count@\@ne\fi
287 \global\divide\@SR\tw@
288 \ifodd\count@\global\advance\@SR\@SRconst\relax\fi
289 \endgroup}
290 \providecommand\SRbit{\@SRadvance\ifodd\@SR1\else0\fi}
291 \providecommand\SRtest[2]{\@SRadvance\ifodd\@SR#2\else#1\fi\ignorespaces}
292 \providecommand\SRvalue{\number\@SR }
293 \SRset{0}

10 Page Style

For a page style examheadings is offered. Choose it by supplying to \pagestyle.

\thehead
\ps@examheadings
294 \newcommand\thehead{%
295 \textsl{\@title\enspace:\enspace
296 \ifseries\namesection\else\@date\fi}}
297 \newcommand\ps@examheadings{%
298 \let\@oddfoot\@empty
299 \let\@evenfoot\@empty
300 \renewcommand\@oddhead{%
301  \vbox{%
302  \hbox to\textwidth{\headerfont\thehead\hfil\upshape\thepage}%
303  \vskip1.5\p@
304  \hrule\@height.5\p@\@width\textwidth
305  }}%
306 \let\@evenhead\@oddhead}

11 Titlepage

\target With target we denote the group of students for whom the exam is meant. Define with \target and call up with \@target.

\target
307 \newcommand\target[1]{\gdef\@target{#1}}\def\@target{}

The titlepage is best set by a redefined \maketitle. Of course it needs to be suppressed if the notitlepage option is given on the \documentclass call. Provide two versions, one for a real exam and one for collections and/or answers.

12 Miscellaneous

12.1 Language Adjustments

Predefine all language specific macros, default is the English language.

\Exam \Collection \Answers \Answer \Problem
308 \newcommand\Exam{EXAM}
309 \newcommand\Collection{COLLECTION OF EXAMS}
310 \newcommand\Answers{ANSWERS}
311 \newcommand\Answer{Answer}
312 \newcommand\Problem{Problem}

\onlanguage A small problem arose with the Babel system. If a language is not defined with \addlanguage an \errmessage interfers with the smooth processing. We avoid this problem with the following macro.

\onlanguage
313 \newcommand\onlanguage[4]{% {language}{current}{knwon}{unknown}
314 \expandafter\ifx\csname l@#1\endcsname\relax
315 #4\else\ifnum\csname l@#1\endcsname=\language #2\else#3\fi\fi}

Below follow macros that on the presence of the Babel system automatically redefine the language specific expressions.

12.1.1 English

Put here all english equivalents.

\englishExamNames
316 \newcommand\englishExamNames{%
317 \renewcommand\Answers{ANSWERS}%
318 \renewcommand\Answer{Answer}%
319 \renewcommand\Exam{EXAM}%
320 \renewcommand\Collection{COLLECTION OF EXAMS}%
321 \renewcommand\Problem{Problem}%

322 }

If appropriate set one of these languages at the start of the document.

323 \AtBeginDocument{\onlanguage{english}{\englishExamNames}{}{}}
324 \AtBeginDocument{\onlanguage{american}{\englishExamNames}{}{}}

12.1.2 Dutch

Put here all dutch equivalents.

\dutchExamNames
325 \newcommand\dutchExamNames{%
326 \renewcommand\Answers{ANTWOORDEN}%
327 \renewcommand\Answer{Antwoord}%
328 \renewcommand\Exam{TENTAMEN}%
329 \renewcommand\Collection{TENTAMENBUNDEL}%
330 \renewcommand\Problem{Opgave}%

331 }

332 \AtBeginDocument{\onlanguage{dutch}{\dutchExamNames}{}{}}

12.1.3 Private Language Dependent Specialties

Customize at will. Here the student is told (in dutch) that a full derivation is required, not just the answer.

\fullanswer
333 \newcommand\fullanswer{Geef de volledige afleiding; %
334 slechts het antwoord vermelden wordt \emph{niet} goed gerekend.}

12.2 Macros Needed but Possibly Missing

I like bold more than bold extended (small hack to mf-files), but if you don’t have bold, replace it by bold extended.

\textbo
335 \providecommand\textbo{\textbf}

Testing for the presence or absence of a parameter.

\@ifemptyarg
336 \providecommand\@ifemptyarg[1]{% {absence}{presence}
337 \ifx\@empty#1\@empty
338 \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}

13 Initializations

13.1 Fonts

\headerfont Fonts for pageheader, body of the text and on the titlepage.

\bodyfont
\titlefont

\headerfont \bodyfont \titlefont
339 \newcommand\headerfont{\rmfamily\small}
340 \newcommand\bodyfont{\sffamily}
341 \newcommand\titlefont{\rmfamily\upshape}

And initialize to \bodyfont.

342 \bodyfont

13.2 Directory Localization

\Mainfolder Specify folders (directories) for the main source, a common folder for related ma-

\Commonfolder
\Figuresfolder

terial and a folder for e.g. EPSF figures etc.

\Mainfolder
\Commonfolder
\Figuresfolder

343 \newcommand\Mainfolder[1]{\def\mainfolder{#1}}
344 \newcommand\Commonfolder[1]{\def\commonfolder{#1}}
345 \newcommand\Figuresfolder[1]{\def\figuresfolder{#1}}

Initialize them

346 \Mainfolder{}
347 \Commonfolder{}
348 \Figuresfolder{}

13.3 Configuration File

Last, but not least, see if there is a configuration file exam.cfg and read it for the final adjustments.

349 \InputIfFileExists{exam.cfg}{}{}

350 ⟨/package⟩