summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/exam-n/exam-n.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/exam-n/exam-n.dtx
Initial commit
Diffstat (limited to 'macros/latex/contrib/exam-n/exam-n.dtx')
-rw-r--r--macros/latex/contrib/exam-n/exam-n.dtx3213
1 files changed, 3213 insertions, 0 deletions
diff --git a/macros/latex/contrib/exam-n/exam-n.dtx b/macros/latex/contrib/exam-n/exam-n.dtx
new file mode 100644
index 0000000000..043d2c9f7c
--- /dev/null
+++ b/macros/latex/contrib/exam-n/exam-n.dtx
@@ -0,0 +1,3213 @@
+% \iffalse
+% This is exam-n.dtx, which supports formatting exam papers.
+%
+% Generated file : DO NOT EDIT
+%
+%% Release version 1.1.4, 2016 December 19.
+%%
+%%%% File: exam-n.dtx
+%%%% Copyright 2005--2016, Norman Gray
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%%
+%% The Current Maintainer of this work is Norman Gray <http://nxg.me.uk>
+%%
+%% This work consists of the files exam-n.dtx and exam-n.ins,
+%% the derived file exam-n.cls,
+%% and the associated *.clo files.
+
+%<+package|driver|example>%%%% Source: Mercurial revision e8a612cb25f4, 2016-12-19 16:49 +0000, tag exam-n-1.1.4 + 0
+%%
+%<*package|driver>
+
+%</package|driver>
+%<+package>\NeedsTeXFormat{LaTeX2e}
+%<+package>\ProvidesClass{exam-n}[2016/12/19 1.1.4]
+%<+package>\typeout{Class: `exam-n 1.1.4 <2016/12/19>}
+%
+%<*driver>
+\documentclass{ltxdoc}
+\title{exam-n: exam papers}
+\author{Norman Gray\\(\texttt{norman@astro.gla.ac.uk})}
+\date{Release 1.1.4}
+\usepackage{url}
+\newcommand\Lopt[1]{\textsf {#1}} % options
+\newcommand\file[1]{\texttt {#1}}
+\newcommand\Lcount[1]{\textsl {\small#1}}
+\newcommand\Lenv[1]{\texttt{\{#1\}}} %environments
+\newcommand\Lpackage[1]{\{\textsf{#1}\}} %packages
+%Make command strings easier to write
+%{\catcode`\<=\active \gdef<#1>{\meta{#1}}}
+{\catcode`\<=\active
+ \gdef<#1>{{\ensuremath\langle\normalfont\textsl{#1}\ensuremath\rangle}}}
+\def\cmd{\begingroup
+ \catcode`\\=12 \catcode`\{=12 \catcode`\}=12
+ \catcode`\<=\active \catcode`\|=12
+ \docmd}
+\def\docmd|#1|{\texttt{#1}\endgroup}
+%%% \url macro (url.sty does this better)
+%\def\setpathdots{\discretionary{.}{}{.}}
+%\def\setpathslash{\discretionary{/}{}{/}}
+%{\catcode`\.=\active
+% \catcode`\/=\active
+% \gdef\pathcats{%
+% \catcode`\%=12 \catcode`\~=12
+% \catcode`\.=\active \let.\setpathdots
+% \catcode`\/=\active \let/\setpathslash
+% \catcode`\#=12 \catcode`\_=12}%
+% }
+%\def\setpath#1{\ttfamily <\nobreak #1\nobreak>\endgroup}
+%\def\url{\begingroup\pathcats\setpath}
+
+\def\bs{$\backslash$}
+\makeatletter
+% See Makefile for gymnastics here...
+% This hoiks the extra symbols at the bottom of the file, into the
+% text here, so they can be documented.
+% Abbreviations for degrees.
+% \begin{macrocode}
+\newcommand\BSc{B.Sc.{}}
+\newcommand\MSci{M.Sci.{}}
+\newcommand\MSc{M.Sc.{}}
+\newcommand\MA{M.A.{}}
+\newcommand\MEng{M.Eng.{}}
+\newcommand\BEng{B.Eng.{}}
+% \end{macrocode}
+%
+% Tweaks to differentials.
+% \begin{macrocode}
+\newcommand{\dd}{\mathrm{d}}
+\newcommand{\ddd}{\,\mathrm{d}} % inside an integral, including thinspace
+
+\def\Diffl{\@ifstar\@Difflflat\@Diffl}
+\def\Partial{\@ifstar\@Partialflat\@Partial}
+\def\@Partial{\@ifnextchar[{\@@Diffl\partial}{\@@Diffl\partial[]}}
+\def\@Partialflat{\@ifnextchar[{\@@Difflflat\partial}{\@@Difflflat\partial[]}}
+\def\@Diffl{\@ifnextchar[{\@@Diffl\dd}{\@@Diffl\dd[]}}
+\def\@Difflflat{\@ifnextchar[{\@@Difflflat\dd}{\@@Difflflat\dd[]}}
+\def\@@Diffl#1[#2]#3#4{%
+ \def\@tempa{#2}%
+ \ifx\@tempa\empty
+ \frac{#1#3}{#1#4}%
+ \else
+ \frac{{#1}^{#2}#3}{#1{#4}^{#2}}%
+ \fi}
+\def\@@Difflflat#1[#2]#3#4{%
+ \def\@tempa{#2}%
+ \ifx\@tempa\empty
+ #1#3\mskip-0.8mu/\mskip-1.2mu #1#4%
+ \else
+ {#1}^{#2}#3\mskip-0.8mu /\mskip-1.2mu #1{#4}^{#2}%
+ \fi}
+% \end{macrocode}
+%
+% The exponential sign
+% \begin{macrocode}
+\def\e{{\mathrm e}}
+% \end{macrocode}
+%
+% Physical units in |\rm|. Unstarred version includes leading
+% |\thinspace|. Starred version doesn't, and is used when referring to
+% the unit by itself (eg axis is |$B/\units*T$|), and is not qualifying
+% a number.
+% FIXME: |\mu| in |\units| can come out wrong in some fonts (mtpro2?)
+% -- needs investigation.
+% \begin{macrocode}
+\def\units{\begingroup
+ \catcode`\.=\active
+ \@ifstar{\let\un@tsspace\relax \un@ts}%
+ {\let\un@tsspace\thinspace\un@ts}}
+\begingroup
+ \catcode`\.=\active
+ \gdef\un@ts#1{\let~\thinspace\let.\thinspace
+ \ifmmode
+ \un@tsspace\mathrm{#1}%
+ \else
+ \nobreak$\un@tsspace\mathrm{#1}$%
+ \fi
+ \endgroup}
+\endgroup
+% \end{macrocode}
+%
+% Other miscellaneous symbols:
+% The AU is nothing exciting, but may be adjusted in future
+% \begin{macrocode}
+\def\au{au}
+% \end{macrocode}
+% The symbol for Compton wavelength is a crossed lambda -- the following isn't perfect, but is OK for now.
+% \begin{macrocode}
+\def\lambdabar{\setbox\@tempboxa\hbox{$\lambda$}%
+ \hbox to 0pt{\hbox to \wd\@tempboxa{\hss$\bar{}$\hss}\hss}\box\@tempboxa}
+% \end{macrocode}
+\makeatother
+
+% Uncomment \OnlyDescription to skip the implementation
+%\OnlyDescription
+\begin{document}
+\maketitle
+\tableofcontents
+\bigskip
+\DocInput{exam-n.dtx}
+\end{document}
+%</driver>
+%
+% \fi
+%
+% \noindent This class file supports creating exam papers.
+% This is intended as part of a slightly larger system for assembling
+% and managing the papers, by combining questions from multiple authors.
+%
+% This document is addressed to the exams convener, or someone
+% responsible for the overall exam; it goes into complete detail about
+% the class file, and how to customise it. There is more compact
+% documentation for the class, addressed to the authors of individual
+% questions, in the companion document `Notes for Authors'.
+%
+% The most up-to-date version of this class can be found at
+% \url{http://purl.org/nxg/dist/exam-n}.
+%
+% \newpage
+%
+% \section{Description}
+%
+% Usage:
+% \begin{verbatim}
+% \documentclass[options...]{exam-n}
+% <preamble declarations>
+% \begin{document}
+% \maketitle
+% \begin{question}...\end{question}
+% ...
+% \end{document}
+% \end{verbatim}
+%
+% \subsection{Class options}
+% \label{s:options}
+%
+% The class takes the following options. Note that these options are
+% processed in order, so if an option changes a default
+% (for example, \Lopt{draft} sets \Lopt{showsolutions} by default),
+% then it can be overridden by an option later in the list.
+% \begin{description}
+% \item[\Lopt{compose}, \Lopt{draft}, \Lopt{final}]
+% When composing questions, you should give
+% the \Lopt{compose} option to \Lenv{exam-n}; when assembling the paper, you
+% should use \Lopt{draft}; and you should use \Lopt{final} only for
+% the final version.
+% The \Lopt{draft} option switches on the \Lopt{showsolutions}
+% option (below), displays |\comment| remarks,
+% and makes some mild layout changes.
+% The \Lopt{compose} option implies the \Lopt{showsolutions} option,
+% causes questions to be formatted one per page, and turns off
+% various checks on the number of questions; the \Lopt{draft} option
+% should have the same pagination as the final paper and shifts the
+% body of the paper to the left so that marginal comments are
+% easier to write and read; the \Lopt{final} option turns off the
+% |\comment| command.
+%
+% \item[\Lopt{cmfonts}, \Lopt{psfonts}, \Lopt{mathptm},
+% \Lopt{mathtime}, \Lopt{mtpro2}]
+% The \Lopt{cmfonts} option uses the Computer Modern fonts for the
+% document, and the \Lopt{psfonts} uses PostScript fonts. In this
+% latter case, you will possibly want to use one of the
+% \Lopt{mathtime} or \Lopt{mtpro2} options also, to use the
+% mathtime or MTPro2 font set for the maths in the document;
+% alternatively you can use the \Lopt{mathptm} option to use that
+% free but less good alternative.
+%
+% \item[\Lopt{(no)showsolutions}]
+% These control whether the solutions to
+% the questions are shown on the paper or not. \Lopt{showsolutions} is the
+% default when the either \Lopt{draft} or \Lopt{compose} options is
+% present, and \Lopt{noshowsolutions} in \Lopt{final} case,
+% though this will be overridden by one of the
+% \Lopt{\{no\}showsolutions} options later in the list.
+%
+% \item[\Lopt{(no)perquestionmarks} and \Lopt{(no)showmarktotals}]
+% These control whether mark totals and subtotals are tracked within
+% the question (perquestionmarks), and whether the total available
+% marks are displayed at the end of the question (showmarktotals).
+% See Sect.\,\ref{s:question} for more discussion (this
+% option was called \Lopt{showmarks} up to release 0.15).
+%
+% \item[\Lopt{(no)pageperquestion}]
+% If the option \Lopt{pageperquestion} is present, then each
+% question is on a separate page. Option \Lopt{nopageperquestion}
+% is the default. This is most often set by default by one of the
+% other options, or by a \file{.clo} file.
+%
+% \item[\Lopt{oneside}, \Lopt{twoside}]
+% These control whether the document is formatted for
+% one- or twosided printing. This is a standard option, which is
+% redundant in this case, since in this document style there is no
+% difference in formatting. You may in principle use other
+% {article} options, though you are encouraged not to.
+%
+% \item[\Lopt{fleqn}]
+% Display equations flush-left, rather than centred. You generally
+% won't set this in the |\documentclass| options -- it's here so
+% that it can be set in a |.clo| file.
+%
+% \item[\Lopt{sloppydescription}]
+% Disables the requirement that all exam metadata be present. See
+% the discussion of |\universitycoursecode| below.
+%
+% \item[\Lopt{mono}, \Lopt{colour}]
+% The university logo is typeset in colour by default, as is the
+% solution text; the \Lopt{mono} option causes everything to be in
+% mono instead. The \Lopt{colour} option does nothing, but is
+% present for symmetry.
+%
+% \item[\Lopt{sansserif}]
+% Use a sans serif font for the body text. This is plug-ugly, not
+% least because it doesn't match the maths font; also, it may be
+% easier or harder for dyslexic students to read (depending on your
+% superstition -- there seems remarkably little actual evidence
+% either way).
+%
+% \item[\Lopt{largefont}, or \Lopt{hugefont}]
+% Produce a version of the paper in a `big' font (18pt) or `huge' font (36pt) for
+% the benefit of students with visual impairments. See notes below.
+%
+% \end{description}
+%
+% Any other options are interpreted as an instruction to read in a
+% \file{.clo} file, containing course-, department- or group-specific style
+% modifications. Most typically, these changes will affect the
+% rubric, and the sheet of physical constants.
+% The only generic style option is \Lopt{A1}
+% (which is included as an example of how such a file is written).
+% See section~\ref{s:custom} below.
+%
+% In some circumstances -- for example when processing exam scripts
+% under the control of a Makefile or script -- it can be convenient to
+% control package options from outside the package. If there is a
+% file called \texttt{exam-n.config} in the input path (most likely in
+% the same directory as the exam paper), then this is read in when any
+% exam script is processed, and will supplement any
+% options in the |\documentclass| line. For example, if this file were present
+% and contained the line |\ExecuteOptions{showsolutions}|, then the
+% typeset exam would include the solutions. Note that this will
+% supplement, \emph{but not override}, options in the input file's |\documentclass|;
+% it is therefore useful only for switching options away from the default.
+%
+% The exam-n class includes the \Lpackage{amsmath} package, so you can
+% make immediate use of amsmath features if you wish (see
+% \texttt{\small http://www.ams.org/tex/amslatex.html} for discussion).
+%
+% The change of font size with the \Lopt{hugefont} option requires a
+% couple of minor layout changes. You may need to force some similar
+% changes in the exam paper, in this case. You can do that by bracketing the
+% adjusted text in \cmd|\ifbigfont<big font material>\else<normal font
+% material>\fi|; the |\ifbigfont| flag is true in the case of
+% \Lopt{hugefont}, but not \Lopt{largefont}. If you want the
+% |\ifbigfont| flag to apply to \Lopt{largefont}, too, then you may
+% set |\bigfonttrue| in a suitable place. The \Lpackage{amsmath}
+% \texttt{multline} environment can be useful here. The exams
+% convener should review the result carefully: a few judicious
+% \cmd|\ifbigfont\newpage\fi| insertions can make the result look less
+% awful. The \Lopt{largefont} and \Lopt{hugefont} options apply to
+% the content of solutions if the \Lopt{showsolutions} option is
+% present; this may or may not be the optimal choice.
+%
+% At the bottom of each page, you see a faint identification code, such
+% as `QM/123-456'. This consists of an exam identifier, extracted from
+% the exam preamble, plus a code which changes each time \LaTeX\ is
+% run. This helps you avoid collation accidents, and to distinguish
+% between slightly different versions of the printed document.
+% The identifier is based on the date and time, so changes each time
+% you run \LaTeX\ on the file (that is, it identifies a printing,
+% rather than a source-file version).
+%
+% \subsection{The Question environment}
+% \label{s:question}
+%
+% Within the document, you include questions within a \Lenv{question}
+% environment, within which you may further have
+% \Lenv{questiondata} and \Lenv{solution} environments.
+%
+% \DescribeEnv{question}
+% The \Lenv{question} environment delimits a single exam question.
+%
+% Usage, with \Lopt{perquestionmarks}:
+% \begin{quotation}
+% \noindent
+% |\begin{question}|\oarg{questionnumber}\marg{marks}\\
+% \dots\\
+% |\end{question}|
+% \end{quotation}
+% Or, with \Lopt{noperquestionmarks}:
+% \begin{quotation}
+% \noindent
+% |\begin{question}|\oarg{questionnumber}\\
+% \dots\\
+% |\end{question}|
+% \end{quotation}
+%
+% There are two variants of this environment, depending on whether the
+% \Lopt{perquestionmarks} option is present or not. If it is present
+% (the default) then the \Lenv{question} environment takes a non-empty
+% argument showing the total marks available for a question.
+% In addition, the class checks that the |\partmarks| commands within the
+% question (see below) add up to this declared goal mark.
+% If the \Lopt{showmarktotals} option is present, then this (expected and
+% checked) total is displayed at the end of the question.
+%
+% If the \Lopt{perquestionmarks} option is \emph{not} present,
+% then questions have no individual marks, the
+% environment takes no marks argument, and no marks are shown (this is usual
+% in essay-question exams, which typically comprise a sequence of
+% short equal-valued questions with an explanatory rubric).
+% Also, in this case the |\partmarks| command cannot be used within the question.
+%
+% The \Lenv{question} environment takes an optional argument, giving
+% the expected question number. In \Lopt{compose} mode, this is used
+% as the question number (unsurprisingly). In the two other modes,
+% this is compared with the question number which would be generated based on the
+% position in the sequence of \Lenv{question} environments in the file, so
+% that the first \Lenv{question} environment is for question one, the
+% second for question two, and so on. If these do not match, the exam
+% class displays a warning in \Lopt{draft} mode, and produces a fatal
+% error in \Lopt{final} mode.
+% The intention is that this can act as a check that all expected
+% questions are present; see also the |\numquestions| command.
+% \iffalse XXX How useful is this in fact? Should I just discard this,
+% especially since includequestion has a similar features? \fi
+%
+% \DescribeMacro{\QuestionNumberChecksOff}
+% In some cases, the questions are not numbered in this
+% straightforward fashion, so that you might have questions~`2A'
+% and~`2B'. In this case, the check is not meaningful, and you must
+% suppress it by calling the macro |\QuestionNumberChecksOff| in the
+% preamble. After that, you must provide a question-number argument
+% (in square brackets) for every question.
+%
+% In some odder circumstances, you might not want to have any question
+% numbers at all; for example, you might want to require examinees to
+% attempt \emph{all} of the questions, and so simply have a mark for
+% the whole exam. There isn't a mode for this as such, but if you use
+% the \cs{QuestionNumberChecksOff} macro, and give |[\space]| as the
+% optional `question number' at the beginning of the \Lenv{question}
+% environment, then this will have the desired effect.
+%
+% \DescribeEnv{solution}
+% The \Lenv{solution} environment, contained within the \Lenv{question}
+% environment, contains the solution to the question, or other
+% notes. It is displayed by default in \Lopt{compose} mode, and
+% suppressed by default in the others, though this behaviour may be
+% overridden in either case with the \Lopt{(no)showsolutions}
+% option. You can have one \Lenv{solution} at the end of your
+% question, or have multiple ones scattered throughout it. You may
+% use the |\partmarks| macro within the solution, to indicate the
+% distribution of marks within (this part of) the solution --
+% these, of course, do not count towards the total mark for the
+% question. You must not have a solution inside a solution.
+%
+% \DescribeEnv{questiondata}
+% At the end of a question, it is frequently useful to include further
+% information, such as extra equations, or numerical data. These
+% should be included within a \Lenv{questiondata} environment, in
+% order for them to be formatted appropriately. You may include
+% multiple paragraphs, equations, and displays in this environment, as
+% appropriate. Typically, you will have only one such environment per
+% question, appearing at the end, but may have several of them if you
+% really wish to.
+%
+% \DescribeEnv{mcq}
+% Some exams include multiple-choice questions rather than
+% extended-answer ones. These are numbered in the same sequence as
+% the other questions, but are formatted and marked-up differently.
+% \begin{verbatim}
+% \begin{mcq}
+% In 1908, where was there an airburst `impact'?
+% \answer Tunguska
+% \item Arizona
+% \item Off the Mexican coast
+% \item Egypt
+% \end{mcq}
+% \end{verbatim}
+% That is, the \Lenv{mcq} environment contains a list of possible
+% answers, all of which are indicated by |\item|, except precisely one
+% correct answer, indicated by |\answer|.
+% \DescribeMacro{\multiplechoiceanswers}
+% All multiple-choice questions must have the same number of possible
+% answers, which is declared with the command \cmd|\multiplechoiceanswers{<n>}|
+% The \Lenv{mcq} environment is permitted only after |\multiplechoiceanswers|.
+% It's OK to have a \Lenv{solution} within an \Lenv{mcq} environment,
+% which might provide further commentary on the correct answer.
+%
+% There are various other commands which you may or should use within
+% the document.
+%
+% \DescribeMacro{\includequestion}
+% It may be convenient to split your exam into a number of separate
+% source files, such as having one \texttt{.tex} file for each
+% question. You can include these various source files using the
+% usual |\input| command.
+%
+% If the separate source files have the simple form:\label{s:includequestion}
+% \begin{verbatim}
+% \documentclass[compose]{exam-n}
+% \usepackage{graphicx} % for example
+% \begin{document}
+% \begin{question}
+% ...
+% \end{question}
+% \end{document}
+% \end{verbatim}
+% then they can be \LaTeX ed separately, for example by the authors of
+% different questions, but cannot be |\input|
+% unedited, as described above. If, however, they have \emph{only}
+% these structures (that is, only the |\documentclass| command,
+% the \Lenv{document} environment, and zero or more |\usepackage| commands),
+% then you can most conveniently import them unedited using the
+% |\includequestion| command.
+% \begin{verbatim}
+% \includequestion{dynamics2}
+% \end{verbatim}
+% This acts like the |\input| command, but disables the listed structures.
+% It also puts the included command into a group, so that any
+% (re)definitions of commands are made local-only.
+%
+% Recall that the definition of the |\includequestion| command means
+% that any |\usepackage| commands will be ignored. If you, as a
+% question author, need certain packages to be present for your
+% question, you will have to make sure that whoever is assembling the
+% master file includes those packages there, too.
+%
+% The |\includequestion| command takes an optional argument which
+% overrides the question number. This caters for the case where
+% question authors have (unhelpfully) included question numbers in the
+% files' \Lenv{question} environments, and the case where questions
+% are not numbered in a straightforward sequence, for example `1',
+% `2A', `2B', and so on.
+%
+% \DescribeMacro{\section}
+% \DescribeMacro{\subsection}
+% Some exams are divided into sections, or have other structure which
+% needs to be spelled out. These are described with the |\section|
+% command, in a form such as |\section{II}|. You can also add smaller
+% headers before individual questions with something like
+% |\subsection{Second semester questions}|. These can appear only
+% between questions; it is an error to include one of these commands
+% within a \Lenv{question} or \Lenv{mcq} environment.
+%
+% \DescribeMacro{\part}
+% Questions may be subdivided into parts, such as (a), (b),
+% (c)..., or (i), (ii), (iii), and so on. Precede each of these with
+% this |\part| command. The formatting of the part numbers is
+% controlled by the exam style, as customised in
+% Sect.~\ref{s:custom}. This macro starts a new paragraph.
+%
+% You can use the |\part| macro within solutions: this is useful if
+% you have the entire \Lenv{solution} environment at the end of the
+% question, but distracting if you intersperse the \Lenv{solution}
+% environments between question parts. The |\part| macro within
+% solutions increments separately from the increments within the question,
+% so if you use this in the solutions, you must have as many
+% |\part|s in the solution as there are parts in the question.
+%
+% \DescribeMacro{\partmarks}
+% \DescribeMacro{\partmarks*}
+% Macros \cmd|\partmarks{<num>}| and \cmd|\partmarks*{<num>}| announce
+% the number of marks associated with the current part of a question.
+% The class checks that the number of marks here does add up to the
+% number declared at the beginning of the {question} environment.
+% You will typically have just one |\partmarks| per |\part|, but
+% you can have more if you want.
+% The starred version differs by adjusting the position of the mark
+% indicator, and should be used either (i) after (for example) an
+% itemized list, or some other structure which leaves an expanse of
+% white space on the right-hand side of the page; or (ii) within
+% an \emph{unnumbered} equation. If, in case (ii), the style of
+% the part-marks indicators is such that the indicator may be
+% mistaken for an equation number, then it would be wise to use
+% either |\partmarks*| or plain |\partmarks| after the equation,
+% instead.
+%
+% The unstarred version should only be used at the end of a
+% paragraph, and in fact forces a paragraph end; the starred
+% version should on stylistic grounds generally be used only at the
+% end of a paragraph, but it doesn't force one.
+%
+% \DescribeMacro{\comment}
+% \cmd|\comment{<text>}| associates a comment with a part of the text.
+% This is ignored in \Lopt{final} mode, but appears in the margin in the
+% other modes.
+%
+% \DescribeMacro{\author}
+% The |\author| command is a convenience. Used within a
+% \Lenv{question} environment -- most naturally just after the
+% |\begin{question}| -- it creates a comment with the author's
+% name. Its functionality may be expanded in future, so you should
+% use this command, rather than a generic |\comment|, when noting
+% the authorship of a question.
+%
+% \DescribeMacro{\shout}
+% If there is part of a question which is, for example, incomplete,
+% and which needs a more prominent callout than `comment', then you
+% should |\shout{...}| it. Shouts appear in all modes (\emph{including}
+% \Lopt{final}) and appear whether or not the class is showing solutions.
+% This makes a prominent remark in the text, and also in a list of
+% shouts at the end of the text. Your co-authors, or the exam
+% proof-checker, really have no excuse for missing it after that.
+%
+% \DescribeMacro{\leftnudge}
+% For various reasons, most often because of printing problems, it can
+% be useful to nudge the textblock left or right a little. You should
+% call the |\leftnudge| command to do this, rather than fiddling with
+% the underlying \LaTeX\ dimensions yourself. Give the command a dimension
+% argument such as |\leftnudge{1cm}| to nudge the textblock leftwards
+% by 1cm. You can give a negative dimension to nudge it rightwards
+% instead. The \Lopt{draft} option automatically nudges the text
+% block leftwards, to create a larger right-hand margin for notes.
+%
+% \DescribeMacro{\questionpreamble}
+% If |\questionpreamble| is called, then its contents are displayed
+% just before the start of the next question. This is useful for text like
+% |\questionpreamble{And one of\dots}| which might reinforce information in
+% the examination rubric.
+%
+% \subsection{Preamble}
+% \label{s:preamble}
+%
+% \DescribeMacro{\exambanner}
+% The |\exambanner| macro supplies text like `Examination for the
+% degrees of\dots'.
+% Since the contents of this command is automatically uppercased in
+% some styles, and there are per-department specifics about the punctuation
+% of abbreviations, you should use the commands |\BSc|, |\MSci|, and
+% friends (see section~\ref{s:othercommands}) to set the degree names
+% appropriately.
+%
+% \DescribeMacro{\universitycoursecode}
+% \DescribeMacro{\schoolcoursecode}
+% \DescribeMacro{\degreedescriptions}
+% \DescribeMacro{\coursetitle}
+% Declare the identity of the exam with
+% |\universitycoursecode|, |\schoolcoursecode|, |\coursetitle| and
+% |\degreedescriptions|. The distinction between these is as follows:
+% \begin{description}
+% \item[University course code]
+% This is the code for the course (and thus for the paper) as it
+% appears in university information systems, and is a
+% university-unique code such as `PHYS3031'.
+% \item[School course code]
+% This is a more informal, but more recognisable, code for the
+% course/paper, as it is generally recognised within the school;
+% for example, the honours Quantum Mechanics course is known
+% within the school as P304H.
+% \item[Course title]
+% This is just a textual name for the course, for example `Quantum Mechanics'.
+% \item[Degree descriptions]
+% This is a textual description of the qualifications that the
+% students doing this exam are heading for. This text has little
+% formal weight, but might help a lost student realise they're in
+% completely the wrong exam room\dots. This is something like
+% |{Physics 3\\Chemical Physics 3}| (separate each description
+% using |\\|).
+% \end{description}
+% All of these are required elements, and the \LaTeX\ compilation will
+% halt if they are absent. If for some reason the exam
+% paper does not need these to be present -- perhaps it is a class
+% test, for example -- then give the class option
+% \Lopt{sloppydescription}, and the checks for these elements (and for
+% |\rubric|) are suppressed. The layout may end up looking a little
+% funny.
+%
+% \DescribeMacro{\paperident}
+% It can be convenient to add some identification to each page, if for
+% no other reason than to double-check that you haven't inserted a
+% field theory question into an `astronomy for poets' exam. The command |\paperident|
+% allows you to declare some text which appears at the bottom of each
+% page of the exam. It will typically repeat some of the text in the
+% |\schoolcoursecode| or |\degreedescriptions| arguments.
+% This is generally not necessary, however, as in its absence the
+% class generates an identifier. This identifier contains the name of
+% the exam, plus a pair of counters (for example \emph{QM2/98-1177}). The
+% function is two-fold: (i) since the counters increase monotonically
+% (they actually encode the date and time when the document
+% was \LaTeX ed), you can tell which of two superficially similar
+% documents is the later; and (ii) if you drop a sheaf of papers on the
+% photocopier floor, you can work out which one is which.
+%
+% \DescribeMacro{\examdate}
+% \DescribeMacro{\examtime}
+% Give the date and time of the exam with |\examdate| and |\examtime|.
+% Sometimes an exam may
+% have different time limits for different qualifications: this case,
+% separate the various times with |\\|, as in
+% \texttt{\bs examtime\{9.30am -- 12 noon\bs\bs (or) 9.30am -- 1.45am\}}
+%
+% \DescribeMacro{\rubric}
+% \DescribeMacro{\norubric}
+% The rubric, provided unsurprisingly by the command |\rubric|, may
+% contain more than one paragraph,
+% delimited by the usual blank line. Any emphasised words should be
+% marked with |\emph| -- they are typically
+% emphasised with a bold font. The class checks that a rubric has
+% been specified (unless \Lopt{sloppydescription} is present); if you
+% really wish to suppress this rubric -- perhaps because the
+% |\baserubric| is sufficient -- then give the command |\norubric|.
+% \DescribeMacro{\baserubric}
+% As well as this exam-specific rubric, the style produces an additional
+% boilerplate rubric, containing the usual material such as `Do not on
+% any account attempt to write on both sides of the paper at once.
+% Calculations may be done on the fingers, but candidates should avoid
+% counting on their toes unless special permission has been obtained beforehand.'
+% You will typically not have to change this, but if you do for some
+% reason, you can override it with the |\baserubric| command.
+%
+% \DescribeMacro{\numquestions}
+% Finally, declare the number of questions which are to be in the
+% paper with |\numquestions|.
+% The class issues a warning if we don't have this number, in draft or
+% final mode. This is optional -- no check is done if this isn't present.
+%
+%
+% \subsection{Other useful commands}
+% \label{s:othercommands}
+%
+% \DescribeMacro{\BSc\ and friends}
+% Macros |\BSc|, |\MSci|, |\MSc|, |\MA|, |\MEng| and |\BEng| are used
+% within the preamble macros to give appropriately capitalised and punctuated
+% versions of the degree types.
+%
+% \DescribeMacro{\vec}
+% Macro |\vec| is redefined to give bold-font vectors, rather than
+% vectors with arrows, which is the (weird) \LaTeX\ default. This
+% should work for bold greek as well as roman.
+%
+% \DescribeMacro{\dd}
+% Macros |\dd| and |\ddd|: |\dd| is a roman d, as used for
+% differentials; |\ddd| is the same with a preceding thinspace,
+% as used within integrals; for example
+% \[
+% |\int f(x)\ddd x = \int f(x)\,\dd x| = \int f(x)\ddd x
+% \]
+%
+% \DescribeMacro{\Diffl}
+% You can typeset derivatives neatly:
+% \begin{center}
+% \def\dd{\mathrm{d}}
+% \begin{tabular}{ll}
+% |\Diffl{a}{b}| & $\displaystyle \Diffl ab$ \\[2ex]
+% |\Diffl[2]{a}{b}| & $\displaystyle \Diffl[2]ab$\\[2ex]
+% |\Diffl*{a}{b}| & $\Diffl* ab$ \\
+% |\Diffl*[2]{a}{b}| & $\Diffl*[2]ab$\\
+% \end{tabular}
+% \end{center}
+% The unstarred versions are for displayed equations, the starred
+% ones for inline maths.
+% \DescribeMacro{\Partial}
+% There is analogous support for partial derivatives with |\Partial|.
+%
+% \DescribeMacro{\units}
+% Macros |\units|, |\units*|: you can typeset physical units in
+% |\rm|, with tilde or dot
+% acting as a separator between units. Since this is typeset in maths mode, all
+% other spacing is ignored. The unstarred version includes
+% leading |\thinspace|, as in |$v=10\units{m.s^{-1}}$|, giving
+% $v=10\units{m.s^{-1}}$. The starred
+% version can be used when referring to the unit by itself
+% (eg axis is |$B/\units*T$|, or $B/\units*T$), and is not
+% qualifying a number. These macros might be replaced, in the
+% future, by a recommendation to use the \Lpackage{siunitx} package.
+%
+% For other useful symbols, see table~\ref{t:symbols}.
+%
+% \begin{table}
+% \hrule \medskip
+% \begin{tabular}{rlp{8cm}}
+% |\e|&$\e^{i\pi}=-1$& the exponential is typeset in an upright rather than
+% italic shape, as in |$\e^{i\pi}=-1$|.\\
+% |\au|&10\au& use this macro for astronomical units.\\
+% |\lambdabar|&$\lambdabar$& the Compton wavelength, as a lambda with a
+% bar through it.\\
+% \end{tabular}
+% \caption{\label{t:symbols}Miscellaneous symbols}
+% \medskip\hrule
+% \end{table}
+%
+%
+% \section{Customising the exam style}
+% \label{s:custom}
+%
+% As described in section~\ref{s:options} above, any unrecognised
+% options are interpreted as an instruction to search for and include
+% a class options file, formed from the name of the unrecognised
+% option, suffixed with \file{.clo}, which can be anywhere in the
+% \TeX\ include path. This options file has a fair amount of leeway
+% to override and adjust the layout of the exam.
+%
+% The most typical changes here will be to adjust the exam rubric for
+% a particular class, with the command |\baserubric|, and to change the
+% sheet of physical constants, with the command |\constantssheet|.
+% See the sample file |A1.clo| for examples.
+%
+% Examine this sample \file{SpecialExam.clo} file:
+% \begin{verbatim}
+% \typeout{Physics Special exam options, for Special people}
+% \ExecuteOptions{pageperquestion}
+%
+% \OverrideFormatting{
+% \renewcommand\FormatPartMarks[1]{\{#1\}}
+% \renewcommand\FormatPartNumber
+% {\hbox to 0pt{\hss (\StylePartNumber{partnumber})\hskip1em}}
+% \let\StylePartNumber\roman % as opposed to \alph
+% \renewcommand\FormatQuestionNumber
+% {\hbox to 0pt{\hss \textbf{\@currentquestion}\hskip2.5em}}
+% }
+%
+% \constantssheet{
+% \begin{center}
+% $E=mc^2$ and $c=3\times10^8 {\rm m\,s^{-1}}$
+% \end{center}
+% }
+% \end{verbatim}
+% This announces itself, then invokes the exam style's \Lopt{pageperquestion}
+% option.
+%
+% It then includes a number of formatting adjustments,
+% enclosed within the |\OverrideFormatting| command; the formatting
+% hooks are described below.
+%
+% Then it declares a `constants sheet', which is a display of
+% constants or equations, or indeed anything else, which is to be
+% displayed on the second page of the exam.
+%
+% The available formatting hooks are as follows:
+% \begin{description}
+%
+% \item[FormatPartMarks]
+% This formats the indication of the marks carried by a particular
+% part of a question. In this case, we have chosen to have the marks
+% contains inside curly brackets, rather than the default square
+% brackets. By default, the part-marks text will be placed at the end
+% of the paragraph it completes, flush right, and with at least 2em of
+% space before it. You can change this default space with
+% |\@partmarksspace|; as a special case, you can have the text sitting
+% in the margin instead, by having |\FormatPartMarks| generate a
+% zero-width box, and setting |\@partmarksspace=0pt|.
+%
+% \item[FormatPartNumber]
+% This overrides how to format the various |\part| markers within a
+% question, using the \texttt{partnumber} counter. In this case, the
+% markers will jut into the left-hand margin, rather than being
+% run-in.
+%
+% \item[StylePartNumber]
+% This overrides how to style the |\part| markers. The default is
+% |\alph|, but you might prefer, for example, |\Roman| or |\arabic|.
+% Override this with |\let\StylePartNumber\Roman|.
+%
+% \item[FormatQuestionNumber]
+% If you adjust the part marks, you should probably adjust the
+% formatting of the question number also.
+% \end{description}
+%
+% If you really want to go to town on reformatting, you can redefine
+% the command |\maketitle|, which formats the front-page title. When
+% formatting this, you have access to each of the fragments of text
+% described in section~\ref{s:preamble}, via a macro named after the
+% corresponding command. Thus the argument of the |\exambanner| command
+% is available in the macro |\@exambanner|. The exception is
+% |\numquestions|. If you find yourself needing to do this, it might
+% be worth having a discussion with the style's maintainer -- there
+% may be a simpler way to get what you want.
+%
+% No more clues. If you want to hack at this, see the definition of
+% |\maketitle| in the class file \file{exam-n.cls}.
+% Aspire not to break things.
+
+% \iffalse %%%CONFIGURE%%% change the following to iffalse for a locally-distributed version\fi
+% \iftrue
+% \section{A work-flow}
+% This class file was developed as part of a move to `\LaTeX ify' the
+% production of exams in the School of Physics and Astronomy, in the
+% University of Glasgow. The work-flow which emerged was, roughly, as
+% follows:
+% \begin{enumerate}
+% \item The exam convener (the person in charge of assembling the exam
+% for a given course or lecture series) creates a Sharepoint directory
+% which contains a master file
+% (which consists mostly of |\includequestion| macros),
+% plus subdirectories each containing a short template file for the
+% benefit of question authors, and a copy of the
+% \texttt{notes-for-authors.pdf} instructions.
+% \item Each of those `question' directories is made visible to, and
+% read-writable by, the lecturer responsible for that question. They
+% write and \LaTeX ed their question, and upload it back to
+% Sharepoint.
+% \item The exam convener, who has access to the whole tree of
+% questions, downloads or network-mounts the Sharepoint folder, and
+% either edits the questions or negotiates with the authors, until
+% the exam \LaTeX s successfully. The result can then be
+% snapshotted, and sent off to the external examiner.
+% \end{enumerate}
+% This provides a centralised and easily manageable repository
+% for a previously fiddly and error-prone process.
+%
+% In step one, the template file is just one with a \texttt{[compose]}
+% option, following the brief example on p.\pageref{s:includequestion}.
+% We had excellent secretarial help to manage this step; it was fiddly the
+% first couple of times, but largely mechanical thereafter. In Sharepoint,
+% this step can in principle be automated, though we concluded this
+% was unnecessary in our case.
+%
+% Sharepoint (possibly slightly surprisingly) worked smoothly for us;
+% in other circumstances a group-writable source code repository, or
+% an institutional CMS, or even just a shared drive, would work just
+% as well. The advantage of Sharepoint, from our point of view, was
+% that it integrated with the university's existing authentication
+% framework, and was (axiomatically) acceptably secure for the process
+% of creating exams.
+%
+% The majority of our authors were habitual users of \LaTeX\ for
+% writing journal articles, and with subsequently submitting them to
+% journals or the arXiv; and when the process was presented in
+% those terms, with the same advantages, it was readily accepted.
+%
+% Thanks to Graham Woan and Rachael MacLaughlan for the numerous
+% iterations of this process until both it and the class file were stable.
+% \fi
+
+% \section{Example}
+%
+% Here is a short example file. There are further examples in the
+% \texttt{sample/} directory of the distribution.
+% \begin{macrocode}
+%<*example>
+%%%START example (Makefile strips out this block)
+\documentclass{exam-n} % standard final version
+%%\documentclass[draft,showsolutions]{exam-n} % draft style, showing solutions
+%%\documentclass[compose]{exam-n} % compose (author's) style
+
+\examdate{Wednesday, 18 May 2005}
+\examtime{9.30am -- 12 noon\\(or) 9.30am -- 1.45am}
+
+\exambanner{Examination for the Degrees of \BSc(Science) and
+ \MSci\ on the Honours Standard}
+\schoolcoursecode{P304D and P304H}
+\universitycoursecode{PHYS3031 and PHYS4025}
+\coursetitle{Quantum Mechanics}
+%\degreedescriptions{Physics 3, Chemical Physics 3, Physics with
+% Astrophysics 3, Theoretical Physics 3M, Joint Physics 3}
+\degreedescriptions{Physics 3\\Chemical Physics 3\\Physics with
+ Astrophysics 3\\Theoretical Physics 3M\\Joint Physics 3}
+\paperident{GR/P304}
+
+\rubric{Candidates for examination in \emph{Quantum Mechanics} should
+ answer question 1 (16 marks) and \emph{either 2A or 2B} (24 marks each)}
+
+\numquestions{3}
+
+\begin{document}
+\maketitle
+
+\section{I}
+
+\begin{question}{20}
+\part At various points in the development of the mathematical theory of
+General Relativity, we pick a coordinate system in which
+differentiation is simple, and do a calculation using non-covariant
+differentiation, indicated by a comma. We then immediately deduce the
+covariant result, replacing this comma with a semicolon.
+
+Separately, the strong equivalence principle is sometimes
+referred to as the `comma goes to semicolon' rule.
+
+Explain the logic of each of these replacements of a comma with a
+semicolon, putting particular stress on the distinction between
+them.\partmarks{10}
+
+\part The radial and angular coordinates, $r$ and $\phi$ respectively,
+of a test particle moving in the Schwartzschild metric exterior to a
+star of mass $M\ll r$, are related by the equation
+\[
+ r = \frac{h^2}M \left(
+ 1 + e\cos\phi + \frac{3M^2}{h^2}e\phi\sin\phi
+ \right)^{-1},
+\]
+where $h$ and $e$ are constants. Show that this equation takes the
+form of a precessing ellipse, of semi-latus rectum $l=h^2/M$, in which
+the pericentre line advances each orbit by an amount
+$\Delta=6\pi M^2/h^2$, stating clearly any assumptions that
+you make.\partmarks{6}
+
+The solar-mass star HD83443 has a 0.35 Jupiter-mass planet that
+follows a circular orbit of period 2.986 days and radius 0.038\units\au.
+Calculate the rate of precession, in arcseconds per year, of the
+pericentre line of the planet's orbit.\partmarks{4}
+
+[Schwartzschild radius of the Sun${}= 3.0\times10^3\units{m}$,
+$1\units\au=1.5\times10^{11}\units m$].
+
+\begin{solution}
+ In the first type of calculation, we do a calculation in the LIF, in
+which~$\Gamma^i_{jk}=0$, so that single partial differentiation is the
+same as covariant differentiation. If this process produces a
+geometrical object such as a scalar or a tensor, then we know that the
+result is frame-invariant. If the result involves only single partial
+differentiation -- that is, no second derivatives -- then since
+partial differentiation is the same as covariant differentiation in
+these coordinates, we cannot distinguish partial and covariant
+derivatives, and can replace the commas by semicolons. Since these
+are now manifestly covariant derivatives, so that the result is a
+tensor, and thus frame-invariant, the same expression would be true in
+any frame.
+
+The second situation is the statement that the expressions of physical
+laws in SR, such as the conservation equation
+$T^{\mu\nu}_{,\nu}=0$, must take the same \emph{form} when written
+as a covariant equation in GR, crucially without any curvature
+coupling. The slogan `comma goes to semicolon' is just a mnemonic for
+this.
+
+The distinction is that the first is a mathematical trick, of sorts,
+whereas the second is a version of the equivalence principle, and thus
+a statement with deep physical content.
+
+They don't have to explain things at this length or with this
+coherence (?) to get quite a few marks. They just have to show they
+have a clue.
+\end{solution}
+\end{question}
+
+\end{document}
+%%%END example
+%</example>
+% \end{macrocode}
+%
+% \subsection*{Acknowledgements}
+% \addcontentsline{toc}{subsection}{Acknowledgements}
+%
+% This class has greatly benefitted from comments and bug-reports from
+% Harry Ward, Graham Woan, and Nicolas Labrosse;
+% and it has received code contributions from Morag Casey.
+%
+% \StopEventually{}
+
+% \section{Implementation}
+%
+% \subsection{Options}
+%
+% First, process the compose/draft/final option.
+% Flag |\@draftstatus| 0 represents the final version; 1 is a draft exam; 2 is a
+% single question being composed
+% \begin{macrocode}
+%<*package>
+\newcount\@draftstatus
+\@draftstatus=0 % default is final
+\DeclareOption{compose}{\@draftstatus=2
+ \@showsolutionstrue
+ \@pageperquestiontrue}
+\DeclareOption{draft}{\@draftstatus=1
+ \@showsolutionstrue
+ \@pageperquestionfalse}
+\DeclareOption{final}{\@draftstatus=0
+ \@showsolutionsfalse
+ \@pageperquestionfalse}
+% \end{macrocode}
+%
+% Set true to use PostScript fonts
+% \begin{macrocode}
+\newif\if@psfonts\@psfontsfalse
+\DeclareOption{psfonts}{\@psfontstrue}
+\DeclareOption{cmfonts}{\@psfontsfalse}
+% \end{macrocode}
+%
+% Given that we're using PS fonts, should we use the mathtime fonts,
+% rather than just the mathptm ones (which aren't really ideal)? It
+% turns out that we can't test for the presence of the mathtime fonts
+% from within this class file -- the only reliable way of checking if
+% they're present is to look for something like rmtmi.pfa, but
+% |\IfFileExists| isn't able to search for any of those files, only ones
+% on the TEXINPUTS path such as mathtime.sty, which can be, and are
+% often, installed without the fonts themselves being present.
+% \begin{macrocode}
+\newcount\examn@mtselect \examn@mtselect=0
+\DeclareOption{mathptm}{\@psfontstrue\examn@mtselect=0}
+\DeclareOption{mathtime}{\@psfontstrue\examn@mtselect=1}
+\DeclareOption{mtpro2}{\@psfontstrue\examn@mtselect=2}
+% \end{macrocode}
+%
+% Switch between serif and sans serif fonts. We make little attempt
+% to make the latter attractive; this is purely to conform to the
+% superstition (there seem no more grounds than that) that this is
+% better for dyslexic students.
+% \begin{macrocode}
+\newif\ifexamn@serif
+\examn@seriftrue
+\DeclareOption{serif}{\examn@seriftrue}
+\DeclareOption{sansserif}{\examn@seriffalse}
+% \end{macrocode}
+%
+% Set |\if@showsolutions| true if we are to show the contents of {solution} environments
+% \begin{macrocode}
+\newif\if@showsolutions
+\@showsolutionsfalse
+\DeclareOption{showsolutions}{\@showsolutionstrue}
+\DeclareOption{noshowsolutions}{\@showsolutionsfalse}
+% \end{macrocode}
+%
+% Set |\if@pageperquestion| true if we want a new page after each question
+% (set when printing solutions)
+% \begin{macrocode}
+\newif\if@pageperquestion
+\@pageperquestionfalse
+\DeclareOption{pageperquestion}{\@pageperquestiontrue}
+\DeclareOption{nopageperquestion}{\@pageperquestionfalse}
+% \end{macrocode}
+%
+% Set |\if@perquestionmarks| true if we are to expect a marks total to
+% be specified in the question, subtotals to be specified in the
+% question, and to include a check, at the end, that the two match up.
+% \begin{macrocode}
+\newif\if@perquestionmarks
+\@perquestionmarkstrue
+\DeclareOption{perquestionmarks}{\@perquestionmarkstrue}
+\DeclareOption{noperquestionmarks}{\@perquestionmarksfalse}
+% \end{macrocode}
+%
+% Set |\if@showmarktotals| true if we are to display the expected (and
+% checked to be actual) total marks at the end of the question.
+% \begin{macrocode}
+\newif\if@showmarktotals
+\@showmarktotalstrue
+\DeclareOption{showmarktotals}{\@showmarktotalstrue}
+\DeclareOption{noshowmarktotals}{\@showmarktotalsfalse}
+% \end{macrocode}
+%
+% Support the standard article oneside/twoside options, even though
+% they do nothing in this class.
+% \begin{macrocode}
+\newif\if@twosidepages
+\@twosidepagesfalse
+\DeclareOption{twoside}{\@twosidepagestrue}
+\DeclareOption{oneside}{\@twosidepagesfalse}
+% \end{macrocode}
+%
+% Some options styles want \Lopt{fleqn}, so make it an option to this
+% class, to be passed on to article and amsmath.
+% \begin{macrocode}
+\newif\if@fleqn
+\@fleqnfalse
+\DeclareOption{fleqn}{
+ \@fleqntrue
+ \PassOptionsToPackage{fleqn}{amsmath}
+ \PassOptionsToClass{fleqn}{article}
+}
+% \end{macrocode}
+%
+% If \Lopt{sloppydescription} is given, then we don't demand that all
+% the exam metadata is provided. Failing this, we object, fatally, to
+% missing information.
+% \begin{macrocode}
+\newif\if@fussydescription
+\@fussydescriptiontrue
+\DeclareOption{sloppydescription}{\@fussydescriptionfalse}
+% \end{macrocode}
+%
+% The university logo is typeset in colour by default; the \Lopt{mono}
+% option causes everything to be in mono instead. The \Lopt{colour}
+% option does nothing, but is present for symmetry. These have to be
+% |\def|s, by the way, not |\let|s, since the size macros aren't
+% defined until after \Lpackage{article} has been loaded. It seems
+% prudent to make the `showing solutions' text a bit more shouty in
+% this monochrome case.
+% \begin{macrocode}
+\def\examn@header@shoutformat#1{{\Large\bfseries #1}}
+\DeclareOption{mono}{
+ \PassOptionsToPackage{monochrome}{color}
+ \def\examn@header@shoutformat#1{{\Huge\bfseries #1}}
+}
+\DeclareOption{colour}{}
+% \end{macrocode}
+%
+% Options \Lopt{largefont} and \Lopt{hugefont} print versions of the
+% exam in `big' or `huge' font sizes, to help students with visual impairments.
+% The available font variants are represented as numbers.
+% Note: the |\examn@fontvariant| mechanism is in principle more
+% general than simply size variants, but some of the code below
+% assumes that |\examn@fontvariant| greater than zero means large
+% text, and so would need to be adjusted if this becomes untrue.
+%
+% The flag |\ifbigfont| is true if the font is `significantly large';
+% option \Lopt{hugefont} sets it true, option \Lopt{largefont} does
+% not; it's intended to be a user-visible and -settable flag.
+% \emph{Note:} the \Lopt{hugefont} option used to be \Lopt{bigfont};
+% the latter is deprecated and may be removed in v1.2.
+% \begin{macrocode}
+\newcount\examn@fontvariant
+ \examn@fontvariant=0 % the default
+\newif\ifbigfont
+ \bigfontfalse
+\DeclareOption{largefont}{\examn@fontvariant=1 \bigfontfalse}
+% Deprecate [bigfont]; consider removing in v1.2
+\DeclareOption{bigfont}{%
+ \ClassWarning{exam-n}{OPTION [bigfont] HAS BEEN DEPRECATED; use [hugefont] instead}
+ \examn@fontvariant=2 \bigfonttrue}
+\DeclareOption{hugefont}{\examn@fontvariant=2 \bigfonttrue}
+% \end{macrocode}
+%
+% This class is based on the article class. Load it, and pass the \texttt{a4paper}
+% option to it.
+% \begin{macrocode}
+\PassOptionsToClass{a4paper}{article}
+% \end{macrocode}
+%
+% We allow \file{.clo} files to override elements of the formatting,
+% such as |\maketitle| and the various |\Format...| hooks. They must
+% do this within a |\OverrideFormatting| command, using a sequence of
+% |\renewcommand|s. Carefully.
+% \begin{macrocode}
+\newtoks\@styleoverrides
+\@styleoverrides={}
+\def\OverrideFormatting{\@styleoverrides=}
+% \end{macrocode}
+% If \@constantssheet is defined (using |\constantsheet{...}| in a
+% .clo file), then display it on a page by itself. The macro
+% |\constantssheet| is declared above, before the point where we include
+% .clo files.
+% \begin{macrocode}
+\newtoks\@constantstoks
+\def\@@displayconstants{%
+ \clearpage
+ \begingroup
+ \the\@constantstoks
+ \endgroup
+ \clearpage }
+% \end{macrocode}
+% The macro |\constantssheet| has to be declared here, rather in the
+% more natural place below, with \@exambanner and friends, so that
+% it's usable within .clo files.
+% \begin{macrocode}
+\newtoks\@constantstoks
+\@constantstoks={}
+\let\@displayconstants\relax
+\def\constantssheet{\let\@displayconstants\@@displayconstants
+ \@constantstoks=}
+% \end{macrocode}
+%
+% Spit out the style overrides at the beginning of the document,
+% rather than here.
+% \begin{macrocode}
+\AtBeginDocument{\the\@styleoverrides}
+% \end{macrocode}
+%
+% Any remaining options are interpreted as filenames, and the
+% corresponding \file{.clo} file is read in. We do not permit any
+% other options, for example standard |{article}| options.
+% There's a complication here (which I haven't resolved, to my
+% puzzlement): if the .clo file includes for example
+% |\ExecuteOptions{pageperquestion}|, then a \Lopt{nopageperquestion}
+% appearing after the .clo option in the |\documentclass| line appears
+% to be ignored or overwritten, which is odd, since I thought that
+% options were executed in order; are these file options executed
+% later than others, perhaps?
+% \begin{macrocode}
+\DeclareOption*{\InputIfFileExists{\CurrentOption.clo}{}
+ {\ClassError{exam-n}
+ {Bad option \CurrentOption}
+ {I don't understand the option \CurrentOption\MessageBreak
+ (I didn't find file \CurrentOption.clo, if that's what you meant)}}}
+% \end{macrocode}
+%
+% The default options are set when the options are declared, above.
+%
+% If a file called \texttt{exam-n.config} exists, read it in. It may
+% usefully contain other |\ExecuteOptions{foo}| commands. Note that
+% these supplement but \emph{will not override} any options in the
+% |\documentclass| command; thus these are really only useful for
+% changing away from the default. This last behaviour is
+% unsatisfactory: it would be better if this would reliably override
+% any options supplied in |\documentclass|, but that turns out to be
+% hard to fix, given the \LaTeX\ option logic.
+% \begin{macrocode}
+\InputIfFileExists{exam-n.config}{}{}
+% \end{macrocode}
+% And finally process all the options marked so far.
+% \begin{macrocode}
+\ProcessOptions
+% \end{macrocode}
+%
+% \subsection{Dependencies}
+%
+% We depend on the \Lpackage{article} class.
+%
+% Note: we have to do this this way, so that
+% |\PassOptionsToClass{*side}{article}| is invoked only once --
+% \Lenv{article} gets confused if both options are passed to it
+% \begin{macrocode}
+\if@twosidepages
+ \PassOptionsToClass{twoside}{article}
+\else
+ \PassOptionsToClass{oneside}{article}
+\fi
+\PassOptionsToClass{12pt}{article}
+% \end{macrocode}
+%
+% If the document includes
+% the \Lpackage{graphicx} or \Lpackage{pdfpages} packages,
+% then we don't want the \Lopt{draft} option to be passed on.
+% So explicitly pass the \Lopt{final} option to these packages.
+% \begin{macrocode}
+\PassOptionsToPackage{final}{graphicx}
+\PassOptionsToPackage{final}{pdfpages}
+% \end{macrocode}
+%
+% %%%CONFIGURE%%%
+% Define a logo for the University, which will appear in the exam header.
+% This should be a macro which takes a single argument giving the
+% required width of the logo, and which produces a |\vbox|.
+% \begin{macrocode}
+\def\UniLogo#1{\vbox to 15.5mm{%
+ \hrule
+ \vss\hbox to #1{% Aspect ratio of logo is 100x31
+ \hss no logo available\hss
+ }%
+ \vss
+ \hrule}}
+% \end{macrocode}
+%
+% Other required packages
+% \begin{macrocode}
+\RequirePackage[english]{babel} % UK hyphenation
+\RequirePackage{amsmath}
+\RequirePackage{color}
+% \end{macrocode}
+%
+% I think flush-left equations look MUCH better than centred, but
+% Harry disagrees, so it's not the default.
+% \begin{macrocode}
+\LoadClass{article}
+% \end{macrocode}
+%
+% \subsection{Layout}
+%
+% First, handle PDF metadata, and other document identifiers.
+%
+% Generate an identifier, |\examn@docident| for this paper. This is obtained
+% from the university or school course code, followed by the
+% day-of-year, and the number of minutes since midnight (the goal here
+% is to produce an identifier which automatically increments in time,
+% but which isn't obviously a date
+% \begin{macrocode}
+\def\examn@setdocident{%
+ \begingroup
+ % yes, a big \ifcase would be more straightforward;
+ % no, that wouldn't be any fun at all
+ % (also it ends up looking messy and even tricksier).
+ \def\@step##1##2\@nil{\advance\@tempcnta##1 \def\@tempa{##2}}
+ \def\@tempa{{31}{28}{31}{30}{31}{30}{31}{31}{30}{31}{30}{31}}%
+ \@tempcnta=\day % day of month
+ \@tempcntb=\month % month of year (unit-offset)
+ \loop
+ \advance\@tempcntb-1
+ \ifnum \@tempcntb>0
+ \expandafter\@step\@tempa\@nil
+ \repeat
+ \@tempcntb=\year % yes, do calculate leap years
+ \divide\@tempcntb 4 \multiply\@tempcntb 4
+ \ifnum\@tempcntb=\year
+ \ifnum\month>2 % but let's not worry about century years...
+ \advance\@tempcnta 1
+ \fi
+ \fi
+ % remove any \\ or ~ in the coursecode fields
+ \let\\\space
+ \let~\space
+ \xdef\examn@docident{% first element is based on uni/school course code
+ \ifx\@coursetitle\@empty
+ \ifx\@schoolcoursecode\@empty
+ exam%
+ \else
+ \@schoolcoursecode
+ \fi
+ \else
+ \@coursetitle
+ \fi
+ /\the\@tempcnta % day-of-year
+ -\the\time} % minutes since midnight
+ \endgroup
+}
+% \end{macrocode}
+% Check whether we're generating PDF, and define the |\ifpdf| macro
+% accordingly. This does depend on Oberdiek's \Lpackage{ifpdf} package being
+% available, but that's been available for quite a long while, and if
+% it isn't for some people's installations, we can potentially bring
+% back the code which it replaces.
+% \begin{macrocode}
+\RequirePackage{ifpdf}
+\def\@SetDocumentInfo{%
+ \ifpdf
+ {\pdfinfo{/Title (\examn@docident)}}%
+ % Don't put out an /Author(xxx) info entry -- there may be
+ % multiple authors, and it isn't obviously useful
+ \fi
+}
+\AtBeginDocument{\examn@setdocident\@SetDocumentInfo}
+% \end{macrocode}
+%
+% Choose the font set, based on |\if@psfonts| and |\examn@mtselect|.
+% \begin{macrocode}
+\if@psfonts
+ \ifcase\examn@mtselect
+ \ifexamn@serif
+ \RequirePackage{times}
+ \else
+ \RequirePackage{helvet}
+ \fi
+ \RequirePackage{mathptm}
+ \ClassWarningNoLine{exam-n}{Using mathptm fonts}
+ \or % use mathtime fonts
+ \RequirePackage[LY1]{fontenc} % specify text font encoding
+ \RequirePackage[LY1,mtbold]{mathtime} % switch math fonts
+ \ifexamn@serif
+ \RequirePackage{times}
+ \else
+ \RequirePackage{helvet}
+ \fi
+ \ClassWarningNoLine{exam-n}{Using Mathtime fonts}
+ \or % use mtpro2 fonts
+ \RequirePackage[T1]{fontenc}
+ \RequirePackage{textcomp}
+ \ifexamn@serif
+ \renewcommand\rmdefault{ptm} % the default
+ \else
+ \RequirePackage[scaled=0.9]{helvet}
+ \renewcommand\rmdefault{phv}
+ \fi
+ \RequirePackage[mtpbb]{mtpro2}
+ \ClassWarningNoLine{exam-n}{Using MTPro2 fonts}
+ \else
+ \ClassError{exam-n}{Impossible value of mtselect: \examn@mtselect}
+ \fi
+\else
+ \ClassWarningNoLine{exam-n}{Using CM fonts}
+\fi
+% \end{macrocode}
+% If we're using a sans serif font, then redefine |\normalfont| appropriately.
+% The macro |\examn@bodyfontchange| stores up these font changes until
+% they're applied just after |\maketitle|.
+% \begin{macrocode}
+\def\examn@bodyfontchange{}
+\ifexamn@serif \else
+ \ClassWarningNoLine{exam-n}{Using sans serif fonts}
+ \DeclareRobustCommand\normalfont
+ {\usefont\encodingdefault\sfdefault\seriesdefault\shapedefault \relax}
+\fi
+% \end{macrocode}
+% And similarly for the case where we want large fonts.
+% This (as it turns out) requires changing only |\normalsize| and not
+% |\normalfont|, so the two are in principle compatible; however we
+% implement both of them by redefining |\examn@bodyfontchange|, so
+% they're not in practice (a future fix, perhaps).
+% \begin{macrocode}
+\ifcase\examn@fontvariant
+ % default: do nothing
+\or
+ % font variant 1: 18pt
+ \def\examn@bodyfontchange{
+ \renewcommand\normalsize{%
+ \@setfontsize\normalsize{18}{24}%
+ \abovedisplayskip 18\p@ \@plus3.5\p@ \@minus9\p@
+ \abovedisplayshortskip \z@ \@plus5\p@
+ \belowdisplayshortskip 10\p@ \@plus5\p@ \@minus5\p@
+ \belowdisplayskip \abovedisplayskip
+ \let\@listi\@listI}
+ \parindent=24pt
+ \parskip=18pt
+ % Redefine \FormatPartMarks so that it doesn't push the text off the paper
+ \let\FormatPartMarks\examn@variantFormatPartMarks
+ }
+\or
+ % font variant 2: 36pt
+ \def\examn@bodyfontchange{
+ \renewcommand\normalsize{%
+ \@setfontsize\normalsize{36}{42}%
+ \abovedisplayskip 36\p@ \@plus7\p@ \@minus17.5\p@
+ \abovedisplayshortskip \z@ \@plus10.5\p@
+ \belowdisplayshortskip 21\p@ \@plus10.5\p@ \@minus10.5\p@
+ \belowdisplayskip \abovedisplayskip
+ \let\@listi\@listI}
+ \parindent=48pt
+ \parskip=36pt
+ % Redefine \FormatPartMarks so that it doesn't push the text off the paper
+ \let\FormatPartMarks\examn@variantFormatPartMarks
+ }
+\else
+ % Bad font variant
+ \ClassError{exam-n}
+ {Bad font variant \examn@fontvariant}
+ {I didn't expect to see that number (broken style file re largefont/hugefont?)}
+\fi
+% \end{macrocode}
+% The above font variants require a |\FormatPartMarks| variant which
+% avoids being pushed off the edge of the page.
+% \begin{macrocode}
+\def\examn@variantFormatPartMarks#1{%
+ \setbox0=\hbox{\hskip 1em \textbf{[#1]}}%
+ \@tempdima=0.8\marginsize
+ \ifdim\wd0>\@tempdima
+ \advance\@tempdima -\wd0
+ \hbox to 0pt{\hskip\@tempdima \box0\hss}%
+ \else
+ \hbox to 0pt{\box0\hss}%
+ \fi}
+% \end{macrocode}
+%
+% \subsubsection{Exam metadata}
+%
+% \begin{macrocode}
+\def\@exambanner{}
+\def\exambanner{\def\@exambanner}
+
+\def\@schoolcoursecode{}
+\def\schoolcoursecode{\def\@schoolcoursecode}
+
+\def\@universitycoursecode{}
+\def\universitycoursecode{\def\@universitycoursecode}
+
+\def\@paperident{}
+\def\paperident{\def\@paperident}
+
+\def\@examdate{}
+\def\examdate{\def\@examdate}
+
+\def\@examtime{}
+\def\examtime{\def\@examtime}
+
+\def\@coursetitle{}
+\def\coursetitle{\def\@coursetitle}
+% \end{macrocode}
+% Display the degree descriptions, which are separated by |\\|. Put
+% each one in an |\hbox|, so it doesn't break over the line.
+% \begin{macrocode}
+\def\@degreedescriptions{}
+\def\degreedescriptions{\def\@degreedescriptions}
+\def\@displaydegreedescriptions{%
+ \let\@tempb\leavevmode
+ \def\dd##1\\{%
+ \def\@tempa{##1}%
+ \ifx\@tempa\@empty
+ \let\next\relax
+ \else
+ \@tempb\hbox{##1}\let\next\dd
+ \fi
+ \def\@tempb{\discretionary{}{}{\kern0.5em--\kern0.5em}}%
+ \next}
+ \expandafter\dd\@degreedescriptions\\}
+% \end{macrocode}
+% The rubric is typically a per-exam thing. The `base rubric' is
+% more-or-less common to all exams, though it's possible to override
+% it in a .clo file.
+% \begin{macrocode}
+\def\@rubric{}
+\def\rubric{\long\def\@rubric}
+\def\norubric{\let\@rubric\@nnil}
+
+\def\@baserubric{%
+\textbf{Answer each question in a separate booklet}\par
+Candidates are reminded that devices able to store or display text or
+images may not be used in examinations without prior arrangement.
+\if@perquestionmarks
+ \par
+ Approximate marks are indicated in brackets as a guide for candidates.
+\fi
+}
+\def\baserubric{\long\def\@baserubric}
+% \end{macrocode}
+%
+% We can optionally check the total number of questions. Store this
+% if it is present, and add a check to the |\end{document}| to check
+% it at the end if it was indeed set at the beginning. Command
+% |\CheckTotalQuestions| is added to |\AtEndDocument| below.
+% \begin{macrocode}
+\def\@numquestions{}
+\def\numquestions{\def\@numquestions}
+\def\CheckTotalQuestions{%
+ \ifnum\@draftstatus < 2
+ \ifx\@numquestions\@empty \else
+ \ifnum\c@questionnumber=\@numquestions \else
+ \ClassWarning{exam-n}
+ {Expected \@numquestions\space questions, got \thequestionnumber!}
+ \ifnum\@draftstatus > 0 % draft mode
+ \begin{center}
+ \textbf{\highlighted{Expected \@numquestions\space questions, got \thequestionnumber}}
+ \end{center}
+ \fi
+ \fi
+ \fi
+ \fi
+}
+% \end{macrocode}
+%
+%
+% \subsection{Geometry and colours}
+%
+% Adjust the spacing for article and amsmath flush-left equations.
+% Amsmath doesn't use |\mathindent| in the same way \LaTeX\ does, and
+% this semi-workaround may break with early versions of amsmath. See
+% the amsmath FAQ at http://www.ams.org/tex/amsmath-faq.html for
+% some discussion.
+% \begin{macrocode}
+\if@fleqn
+ \mathindent\parindent
+ \@mathmargin=\parindent
+\fi
+% \end{macrocode}
+%
+% |\marginsize| is the size of the margin all round. Users shouldn't
+% change this in normal circumstances, but are free to if they have
+% some particular reason. Note that if all you want to do is move the
+% text to one side for printing reasons, use |\nudgeleft|.
+% \begin{macrocode}
+\newdimen\marginsize
+ \marginsize=35mm
+
+\headheight=15pt
+\headsep=15pt
+% \end{macrocode}
+%
+% It's useful to colour-code material that's present in the compose
+% and draft modes but which won't appear in the final version; this
+% partly reassures question authors that this is `meta' material.
+% \begin{macrocode}
+\definecolor{meta}{rgb}{0.7,0.2,0.2}
+\def\highlighted{\textcolor{meta}}
+% \end{macrocode}
+% We (currently) want solutions to appear as coloured blocks. The
+% colour is this one:
+% \begin{macrocode}
+\definecolor{solutiontext}{rgb}{0.2,0.2,0.5}
+% \end{macrocode}
+% And finally a colour for `discreet' information, such as identifier
+% numbers.
+% \begin{macrocode}
+\definecolor{discreettext}{rgb}{0.6,0.6,0.6}
+% \end{macrocode}
+%
+% Set up the textblock in |\@settextblock|.
+% The argument is the amount by which the text block is to be nudged
+% to the left.
+% \begin{macrocode}
+\newcommand\@settextblock[1]{
+ \textwidth=\paperwidth
+ \advance\textwidth -2\marginsize
+ \textheight=\paperheight
+ \advance\textheight -2\marginsize
+ \oddsidemargin=\marginsize
+ \advance\oddsidemargin -1in
+ \advance\oddsidemargin -#1
+ \evensidemargin=\oddsidemargin
+ \topmargin=\marginsize
+ \advance\topmargin -\headheight
+ \advance\topmargin -\headsep
+ \advance\topmargin -1in
+ \marginparwidth=\marginsize
+ \advance\marginparwidth -1.5cm
+ \advance\marginparwidth #1
+%% \typeout{paperwidth=\the\paperwidth, paperheight=\the\paperheight,
+%% textwidth=\the\textwidth, textheight=\the\textheight,
+%% oddsidemargin=\the\oddsidemargin,
+%% headheight=\the\headheight, headsep=\the\headsep, topmargin=\the\topmargin}
+ \marginparsep=0.5cm
+}
+
+\ifnum\@draftstatus > 0
+ \@settextblock{2cm}
+\else
+ \@settextblock{0pt}
+\fi
+% \end{macrocode}
+% |\leftnudge| is the amount by which the textblock is shifted
+% leftwards. This is usually zero, but is given a non-zero value in
+% draft modes, to give space for marginal comments, and may be given a
+% non-zero value by users, in the preamble, if that is required for
+% some reason by some limitation of the subsequent printing process.
+% It may be negative, to nudge the block rightwards.
+% \begin{macrocode}
+\let\leftnudge\@settextblock
+% \end{macrocode}
+%
+% Format the marginal paragraphs (ie, comments)
+% \begin{macrocode}
+\renewcommand\@marginparreset{%
+ \reset@font
+ \@setminipage
+ \raggedright
+ \small
+}
+% \end{macrocode}
+%
+% Add a few other formatting parameters.
+%
+% Note that the (default) layout of |\FormatPartNumber| depends on a
+% non-zero |\parindent|, so if the latter is changed, the former must
+% be, too. In fact, if |\parindent| is zero or otherwise small,
+% \begin{quotation}
+% \catcode`\|=0
+% |begingroup |ttfamily
+% \catcode`\{=12 \catcode`\}=12 \catcode`\\=12
+% |noindent \newcommand\FormatPartNumber{|linebreak
+% |noindent|quad\hbox to 2em{(\StylePartNumber{partnumber})\hss}}
+% |endgroup
+% \end{quotation}
+% works adequately as a part number,
+% though this does result in paragraphs being a little hard to make
+% out, unless there's a really generous |\parskip|.
+% \begin{macrocode}
+\setlength{\parindent}{2em}
+\setlength{\parskip}{\bigskipamount}
+% \end{macrocode}
+%
+% We must clear out any floats at the end of the paper, without
+% forcing a new page (figures and tables don't float, but there are
+% other packages which can generate floats, such as the
+% \Lenv{sidewaystable} from the \Lpackage{rotating} package).
+% This technique is simplified form Donald Arsenau's \Lpackage{placeins} package.
+% \begin{macrocode}
+\def\examn@flushfloats{\par
+ \begingroup
+ \edef\@tempa{\@deferlist\@dbldeferlist}
+ \ifx\@tempa\@empty \else
+ \clearpage
+ \fi
+ \endgroup
+}
+% \end{macrocode}
+% Text at the end of the paper. Command |\ClosingText| is added to
+% |\AtEndDocument|, below.
+% \begin{macrocode}
+\ifcase\@draftstatus % Final version
+ \def\ClosingText{
+ \examn@flushfloats
+ \begin{center}\textbf{End of Paper}\\\end{center}
+ \mark{END}}
+\or % Draft version
+ \def\ClosingText{
+ \examn@flushfloats
+ \begin{center}\textbf{End of Draft Paper}\\\end{center}
+ \mark{END}}
+\else % Compose version (nothing, because this would be on a page by itself)
+ \def\ClosingText{
+ \examn@flushfloats
+ \mark{END}}
+\fi
+% \end{macrocode}
+%
+% \subsection{Headings and marks}
+%
+% The headers and footers include continuation information.
+% \begin{macrocode}
+\RequirePackage{fancyhdr}
+\pagestyle{fancy}
+\setlength{\headwidth}{\textwidth}
+\renewcommand{\headrulewidth}{0pt}
+\renewcommand{\footrulewidth}{0pt}
+\fancyhead{}
+\fancyfoot{}
+% \end{macrocode}
+% Include an identifier in the footer, unless an identifier is present
+% in |\@paperident|.
+% \begin{macrocode}
+\fancyfoot[L]{{\tiny\textcolor{discreettext}{%
+ \ifx\@paperident\@empty\examn@docident\else\@paperident\fi
+}}}
+% \end{macrocode}
+% We use marks to determine whether, at the top of the page, we're
+% continuing a question or starting a new one. Set |\mark{n}| at the
+% beginning of a question, and |\mark{}| at the end. In principle, if
+% |\topmark| is non-empty, then we're currently in the given question,
+% and if it's empty, we're not. Now, the \LaTeX\ floats mechanism
+% (which is involved in the handling of marginpars as well as floats)
+% interferes with this because it can call the output routine other
+% than at the end of a page. Thus |\topmark| is essentially useless
+% within \LaTeX, if there's any change of a float appearing.
+%
+% However, we can work around this by setting |\examn@topmark| in the
+% page footer, to be the value of |\botmark| there. I think this has
+% exactly the same semantics as |\topmark|, possibly apart from some
+% pathological situations.
+%
+% So, for the footer, we include a continuation mark if and only if
+% |\examn@topmark| is non-empty. We additionally store |\botmark| into |\examn@topmark|.
+% \begin{macrocode}
+\fancyfoot[R]{%
+ \def\@tempa{END}
+ \xdef\examn@topmark{\botmark}
+ \ifx\examn@topmark\@empty
+ \formatcontinuations{Paper continued over\dots}%
+ \else\ifx\examn@topmark\@tempa
+ \formatcontinuations{END}
+ \else
+ \formatcontinuations{Q\,\examn@topmark\ continued over\dots}%
+ \fi\fi
+}
+\fancyfoot[C]{\thepage/\pageref{lastpage}}
+% \end{macrocode}
+% In the header, we perform essentially the same test, using the
+% |\examn@topmark| we saved in the previous page's footer.
+% \begin{macrocode}
+\def\examn@topmark{}
+\ifnum\@draftstatus=0
+ \fancyhead[L]{%
+ \ifx\examn@topmark\@empty \else
+ \formatcontinuations{Q\,\examn@topmark\ continued}%
+ \fi
+ }
+\fi
+% \end{macrocode}
+% We use the header to shout out the status of the paper, in
+% particular making it very clear if we're showing the exam answers:
+% we don't want this version to be accidentally distributed at the exam\dots.
+% The |\examn@bighead| macro sets its contents in a large box, but
+% without making the header any larger -- we want the headheight in
+% drafts to be the same as in the final version (because otherwise
+% we'd get different page breaks).
+% \begin{macrocode}
+\def\examn@bighead#1{\strut\vbox to 0pt{\vss\hbox{\examn@header@shoutformat{#1}}\vskip 10mm}}
+\ifnum\@draftstatus = 1
+ \if@showsolutions
+ \fancyhead[C]{\examn@bighead{\highlighted{DRAFT + SOLUTIONS, p\thepage/\pageref{lastpage}}}}
+ \else
+ \fancyhead[C]{\examn@bighead{\highlighted{DRAFT, p\thepage/\pageref{lastpage}}}}
+ \fi
+\else
+ \if@showsolutions
+ % Add a very prominent banner
+ \fancyhead[C]{\examn@bighead{\highlighted{SHOWING SOLUTIONS}}}
+ \fi
+\fi
+% \end{macrocode}
+%
+% Allow \texttt{.clo} files to override the formatting of the various
+% continuation markers.
+% \begin{macrocode}
+\def\formatcontinuations#1{\textbf{#1}}
+% \end{macrocode}
+%
+% Now define a command which writes out the page number of the last
+% page. This is added to |\AtEndDocument|, in the correct order, below.
+% \begin{macrocode}
+\def\WriteLastPageLabel{\label{lastpage}}
+% \end{macrocode}
+%
+% \subsubsection{The title page}
+%
+% Define a special page style for the title page
+% No header: all of the text on the page is handled by |\maketitle|
+% The first-page footer doesn't show anything, but it does have to set
+% |\examn@topmark| in case Q1 starts on this page.
+% \begin{macrocode}
+\def\ps@titlepage{
+ \def\@oddhead{}
+ \def\@oddfoot{\xdef\examn@topmark{\botmark}}
+}
+% \end{macrocode}
+%
+% Create a custom maketitle.
+% First, handle the 'final' or 'draft' versions.
+% Check all required information is present.
+% \begin{macrocode}
+\renewcommand\maketitle{
+ \ifnum\@draftstatus < 2 % final or draft version
+ \ifx\@examdate\@empty
+ \ClassError{exam-n}
+ {No exam date given}
+ {Specify an exam date using \protect\examdate}
+ \fi
+ \ifx\@examtime\@empty
+ \ClassError{exam-n}
+ {No exam time given}
+ {Specify an exam time using \protect\examtime}
+ \fi
+ \ifx\@exambanner\@empty
+ \ClassError{exam-n}
+ {No exam banner given}
+ {Specify an exam banner (eg Examination for the degree...) using \protect\exambanner}
+ \fi
+ \if@fussydescription
+ \ifx\@schoolcoursecode\@empty
+ \ClassError{exam-n}
+ {No school course code given}
+ {Specify a school course code (eg P304H) using \protect\schoolcoursecode}
+ \fi
+ \ifx\@universitycoursecode\@empty
+ \ClassError{exam-n}
+ {No paper title given}
+ {Specify a university course code (eg PHYS3031) using \protect\universitycoursecode}
+ \fi
+ \ifx\@coursetitle\@empty
+ \ClassError{exam-n}
+ {No course title given}
+ {Specify a course title (eg Quantum Mechanics) using \protect\coursetitle}
+ \fi
+ \ifx\@degreedescriptions\@empty
+ \ClassError{exam-n}
+ {No paper subject given}
+ {Specify a 'degree description' (eg Physics 3) using \protect\degreedescriptions}
+ \fi
+ \ifx\@rubric\@empty
+ \ClassError{exam-n}
+ {No rubric given}
+ {Specify a rubric using \protect\rubric, or declare its absence with \protect\norubric}
+ \fi
+ \fi
+% \end{macrocode}
+% All OK so far\dots. Now produce the actual text.
+% \begin{macrocode}
+ \thispagestyle{titlepage}
+ \begin{center}
+ \null
+ \vskip -1.5cm
+% \end{macrocode}
+% Firse produce headers at the top, which highlight things which make
+% the paper non-distributable (eg, it includes the answers!).
+% Only highlight the number of shouts when we're not showing
+% solutions. The highlights above indicate clearly that the
+% paper is not in its distributable format; the purpose of
+% this output here is to highlight that the paper is still not
+% distributable, \emph{even though} it's not showing solutions.
+% \begin{macrocode}
+ \if@showsolutions
+ \nointerlineskip
+ \vbox to 0pt{\vss
+ \examn@header@shoutformat{\shout{SHOWING SOLUTIONS}}
+ \vskip 1.5\bigskipamount}
+ \else
+ \ifnum\examn@shoutcounttotal>0
+ \typeout{SHOUTS: \the\examn@shoutcounttotal}
+ \nointerlineskip
+ \vbox to 0pt{\vss
+ \examn@header@shoutformat
+ {\highlighted{SHOUTS: \the\examn@shoutcounttotal\ (see end)}}
+ \vskip 1.5\bigskipamount}
+ \fi
+ \fi
+ \nointerlineskip
+% \end{macrocode}
+% The logo, in a zero-size box.
+% \begin{macrocode}
+ \hbox to \textwidth{% date and time
+ \vbox to 0pt{\vskip-2ex \UniLogo{50mm}\vss}
+ \hss
+% \end{macrocode}
+% Make the |\@examtime| box have zero depth, or else fancyhead
+% complains that the size of the header isn't big enough, and
+% ups it for the whole document. In this position, it's OK that
+% it juts out of the bottom of the header line.
+% \begin{macrocode}
+ \setbox0=\hbox{\vtop{% \vtop or \vbox here?
+ % Opinions differ:
+ % This week, Norman prefers \vtop because it gives a cleaner top line.
+ \hsize=0.5\textwidth
+ \leftskip=0pt plus1fil \rightskip=0pt \parfillskip=0pt
+ \baselineskip=2.5ex
+ \parskip=0.25ex
+ \let\\\par
+ \ifx\@examdate\@empty
+ \shout{missing exam date}
+ \else
+ \@examdate
+ \fi
+ \par
+ \ifx\@examtime\@empty
+ \shout{missing exam time}
+ \else
+ \@examtime
+ \fi
+ \par}}
+ \dp0=0pt
+ \box0}
+ \vskip4\bigskipamount
+ %\UoGname\\[\medskipamount]
+ {\uppercase\expandafter{\@exambanner}}\\[\medskipamount]
+ \vbox{}\hrule
+ \ifx\@degreedescriptions\@empty\else
+ \@displaydegreedescriptions\\
+ \fi
+% \end{macrocode}
+% Exam identification. The |\@coursetitle| is the most important
+% item, so make that biggest.
+% Adjust the size of the course title so that it fits on to one line
+% (though if |\Large| is still too big, then we give up and go to multiple lines).
+% \begin{macrocode}
+ \vskip 2\baselineskip plus 0.3fil
+ \def\@tempa{\def\@tempa{\vskip 0.5\baselineskip}}
+ \ifx\@schoolcoursecode\@empty\else
+ \@tempa
+ {\large\textbf{\@schoolcoursecode}}
+ \fi
+ \ifx\@universitycoursecode\@empty\else
+ \@tempa
+ {\large\textbf{[~\@universitycoursecode~]}}
+ \fi
+ \ifx\@coursetitle\@empty\else
+ \setbox0=\hbox{\Huge\textbf{\@coursetitle}}
+ \ifdim\wd0>\columnwidth
+ \setbox0=\hbox{\LARGE\textbf{\@coursetitle}}
+ \ifdim\wd0>\columnwidth
+ % we're not going any smaller than this
+ \setbox0=\vbox{\hsize\columnwidth
+ \Large\bfseries
+ \@coursetitle}
+ \fi
+ \fi
+ \vskip 1.2\ht0 % generous vertical skip, size-dependent
+ \ifhbox0
+ \hbox to \columnwidth{\hss\box0\hss}
+ \else
+ \box0
+ \fi
+ \fi
+% \end{macrocode}
+% Rubric(s). The macros |\@empty| and |\@nnil| both have an empty
+% expansion. The difference between them is that |\@rubric| is set to
+% |\@nnil| by |\norubric| to indicate that |\@rubric| is deliberately
+% empty, whereas if |\@rubric| is |\@empty|, that's trapped in the
+% checks above as an error.
+% \begin{macrocode}
+ \vskip 2\baselineskip plus 0.3fil
+ \parindent=0pt
+ \parskip=0.5\baselineskip
+ \ifnum\examn@fontvariant > 0
+ % Don't put the rubric here (see below)
+ {\LARGE Rubric: see overleaf}
+ \else
+ \ifx\@rubric\@empty\else
+ \ifx\@rubric\@nnil\else
+ % If there's a rubric, separate from the base rubric, then
+ % separate the two with an hrule (the per-exam rubric
+ % presumably represents special instructions for this exam,
+ % so should be highlighted)
+ \vbox{\let\emph\textbf
+ \@rubric
+ \par}
+ \vskip2\baselineskip
+ \hrule
+ \vskip1.5\baselineskip
+ \fi
+ \fi
+% \end{macrocode}
+% Let the base rubric be a justified block of text near the bottom.
+% \begin{macrocode}
+ \ifx\@baserubric\@empty \else
+ \@baserubric \par
+ \fi
+ \fi % end \ifbigfont \else ...
+ \end{center}
+% \end{macrocode}
+% These various fractions of fil glue don't add up as I'd expect
+% them to. No matter: the fractions here produce some spreading
+% out of the rubrics below the titles, which is what I'm after.
+% \begin{macrocode}
+ \vskip 2\baselineskip plus 0.6fil % \newpage is {\vfil\penalty-\@M}
+ \vbox to 0pt{\hbox to \textwidth{%
+ \tiny
+ \textcolor{discreettext}
+ {\hfil\ifx\@paperident\@empty\examn@docident\else\@paperident\fi\hfil}}\vss}
+ \penalty -\@M
+ \@displayconstants
+% \end{macrocode}
+% The compose version is nice and simple, because we don't have to do
+% any checks. FIXME: Hmm: this is largely redundant, because we don't
+% document, and so don't really support, including the metadata in the
+% [compose] mode preamble. However we clearly did include this as one
+% point: was that just out of whim, or was there a requirement for that?
+% \begin{macrocode}
+ \else % compose version
+ \begin{tabular}{rl}
+ \textbf{Exam}&
+ {\def\\{ / }\@schoolcoursecode}\\
+ \textbf{Course codes}&
+ \@universitycoursecode\\
+ %% \textbf{Subject}&
+ %% {\def\and{and}\begin{tabular}
+ %% {\@degreedescriptionstemplate}\@degreedescriptions
+ %% \end{tabular}}\\
+ \textbf{Date \& time}&
+ {\def\\{, }\@examdate, \@examtime}\\
+ \end{tabular}
+ \fi
+% \end{macrocode}
+% And chatter about what decision we've made.
+% \begin{macrocode}
+ \ifcase\@draftstatus
+ % Final version
+ \typeout{Exam \@schoolcoursecode: FINAL VERSION}
+ \or % Draft version
+ \typeout{Exam \@schoolcoursecode: DRAFT VERSION}
+ \else % Compose version
+ \typeout{Exam \@schoolcoursecode: COMPOSE VERSION}
+ \fi
+ %
+ \examn@bodyfontchange
+ \normalfont\normalsize
+ \ifnum\examn@fontvariant>0
+ % Put the rubric on a second page, in the 'huge' size.
+ \begin{center}
+ \parskip=18pt
+ \let\emph\textbf \@rubric\par
+ \vskip\baselineskip
+ \hrule
+ \vskip\baselineskip
+ \ifx\@baserubric\@empty \else
+ \@baserubric \par
+ \fi
+ \end{center}
+ \newpage
+ \fi
+}
+% \end{macrocode}
+%
+% \subsection{Structuring commands}
+%
+% Define simple sectioning commands. We also check that these aren't
+% inside questions.
+% \begin{macrocode}
+\setcounter{secnumdepth}{0}
+% \end{macrocode}
+% Redefine |\section|, to include a check that it's not being called
+% within a question (|\@currentquestion| is defined only inside the
+% \Lenv{question} or \Lenv{mcq} environments).
+% \begin{macrocode}
+\renewcommand\section{
+ \@ifundefined{@currentquestion}\@@section
+ {\ClassError{exam-n}{Misplaced section}
+ {You can't have a section inside a question;\MessageBreak
+ move it before the {question} environment starts}}}
+\newcommand\@@section{\@startsection{section}{1}{\z@}%
+ {-3.5ex \@plus -1ex \@minus -.2ex}%
+ {1ex \@plus.1ex \@minus 0.5ex}%
+ {\fmt@section}}
+\def\fmt@section#1{%
+ \examn@prequestionspace{}
+ \hbox to \textwidth{{\hfil\bfseries SECTION #1\hfil}}%
+}
+% \end{macrocode}
+% Redefine |\subsection| similarly.
+% \begin{macrocode}
+\renewcommand\subsection{
+ \@ifundefined{@currentquestion}\@@subsection
+ {\ClassError{exam-n}{Misplaced subsection}
+ {You can't have a subsection inside a question;\MessageBreak
+ move it before the {question} environment starts}}}
+\newcommand\@@subsection{\@startsection{subsection}{2}{\z@}
+ {-2ex \@plus -3ex \@minus -0.2ex}
+ {0.5ex \@plus .1ex \@minus 0.1ex}
+ {\fmt@subsection}}
+\def\fmt@subsection#1{%
+ \examn@prequestionspace{}
+ \noindent\textbf{#1}}
+% \end{macrocode}
+% We must redefine the section and subsection mark commands to gobble
+% their arguments. If we don't, then \LaTeX\ gets \emph{terribly}
+% confused about what the mark is. I don't quite follow what happens
+% in this case, but symptoms include Babel blowing up, and
+% \TeX\ running out of stack space. So: bad.
+% \begin{macrocode}
+\let\sectionmark\@gobble
+\let\subsectionmark\@gobble
+% \end{macrocode}
+%
+% Just to be safe, we should also disable the other sectioning
+% commands.
+% \begin{macrocode}
+\def\@badsection#1#2{\ClassError{guexam}{Bad section}
+ {The exam class goes not support subdivisions like #1{#2}}}
+\def\subsubsection{\@badsection{subsubsection}}
+\def\paragraph{\@badsection{paragraph}}
+\def\subparagraph{\@badsection{subparagraph}}
+% \end{macrocode}
+%
+% The above redefinitions break the |\tableofcontents| macro.
+% It's unlikely but \emph{possibly} useful, in some cases, to have a
+% table of contents in an exam paper. Whether or not it is, we should
+% avoid breaking it, on a principle of least surprise. The following
+% makes the macro work again, even though it's not particularly
+% pretty.
+% \begin{macrocode}
+\renewcommand\tableofcontents{\bigskip
+ \hbox to \textwidth{\hfil\textbf{\Large Contents}\hfil}%
+ \@starttoc{toc}}
+% \end{macrocode}
+%
+% Counters:
+% \begin{macrocode}
+\newcount\marktotal % number of marks accumulated so far
+\newcount\markgoal % number of marks we should have in the end
+\newcounter{questionnumber}
+\setcounter{questionnumber}0
+% \end{macrocode}
+%
+% Counter partnumber holds the number (i,ii,iii, etc) of the parts
+% within a question. It's a \LaTeX\ counter, so we can use |\roman|.
+%
+% We override the \Lenv{article} |\part| command.
+% \begin{macrocode}
+\newcounter{partnumber}
+\renewcommand\part{%
+ \if@nobreak \else
+ \par
+ \@nobreakfalse
+ \fi
+ \ifvmode
+ \vskip 0pt plus 4\bigskipamount
+ \penalty-50
+ \fi
+ \stepcounter{partnumber}%
+ \noindent\FormatPartNumber
+}
+% \end{macrocode}
+% The default |\FormatPartNumber| creates a box the same size as a
+% parindent. This therefore assumes that it's following a |\noindent|.
+% \begin{macrocode}
+\newcommand\FormatPartNumber{\hbox to \parindent{(\StylePartNumber{partnumber})\hss}}
+% \end{macrocode}
+% And by default we use alphanumeric counters for parts (we abstract
+% this, rather than simply including |\alph| in the definition of
+% |\FormatPartNumber|, so that we use the same style for the
+% `answerpartnumber' counter.
+% \begin{macrocode}
+\let\StylePartNumber\alph
+% \end{macrocode}
+%
+% A flag indicating whether we should start a new page before the next
+% question. This is manipulated by both |\section| and |\question|.
+% \begin{macrocode}
+\newif\if@newpagebeforequestion
+\if@pageperquestion
+ \@newpagebeforequestiontrue
+\else
+ \@newpagebeforequestionfalse
+\fi
+% \end{macrocode}
+%
+% The command |\examn@prequestionspace| is called just before we start a
+% new question, or before we start a header which precedes a
+% question. It adds some vertical space, given in the argument,
+% unless the |@pageperquestion| settings imply that this should be a
+% newpage instead, in which case the vertical space here is ignored.
+% \begin{macrocode}
+\def\examn@prequestionspace#1{%
+ \if@pageperquestion
+ \if@newpagebeforequestion
+ % Add all the stretchability here, rather than stretching out
+ % displays and lists above this on the page.
+ \newpage
+ % Clear the \@newpagebeforequestion flag, to suppress the action
+ % of any following calls to \examn@prequestionspace, until the end
+ % of the next question.
+ \global\@newpagebeforequestionfalse
+ \fi
+ \else
+ #1%
+ \fi
+}
+% \end{macrocode}
+%
+% Macro |\examn@endquestion| gathers here a couple of checks shared
+% between end-of-question macros (see the \Lenv{mcq} environment and
+% the |\endquestion| macro).
+% The argument to the |\examn@endquestion| macro is material (such as the
+% mark-total) which should go at the end of the question,
+% and be surrounded by various spacing and resetting actions.
+% \begin{macrocode}
+\long\def\examn@endquestion#1{%
+ \mark{} % the position of this call is slightly sensitive (but this works)
+ \if@pageperquestion
+ \global\@newpagebeforequestiontrue
+ \fi
+ #1
+ \@nobreakfalse
+ \everypar{}
+}
+% \end{macrocode}
+%
+% |\partmarks| is used at the end of a paragraph to indicate the
+% number of marks associated with this part. The starred variant
+% |\partmarks*| is used when the end of a part is the end of a display
+% maths block which doesn't have an equation number. This moves the
+% part note up a bit, which looks nicer.
+% \begin{macrocode}
+\def\partmarks{%
+ \@ifstar{\@tempswatrue \@partmarks}{\@tempswafalse \@partmarks}}
+\newdimen\@partmarksspace
+ \@partmarksspace=2em % default value
+% \end{macrocode}
+% Now implement the part marks indicator. First, check that
+% `perquestionmarks' is turned on; if it's not, then we shouldn't be
+% using |\partmarks|.
+% \begin{macrocode}
+\def\@partmarks#1{%
+ \if@perquestionmarks
+ \if@insolution
+ % visual display only -- doesn't count towards mark total
+ \setbox0=\vbox to 0pt{\vss
+ \hbox to \textwidth{\hfil\hbox to 0pt{\quad\small[\dots #1]\hss}}
+ \vskip0.25ex }%
+ % the next line is probably unnecessary, but guarantees that box0
+ % has zero depth, so no extra vertical space appears because of
+ % this new box
+ \dp0=0pt
+ \ifvmode
+ \box0
+ \else
+ \vadjust{\nointerlineskip\box0}%
+ \fi
+ \else
+ \global\advance\marktotal #1
+ \if@tempswa
+% \end{macrocode}
+% This is the starred form of |\partmarks|. That is, this is being invoked
+% (i) just after maths (or some other display which doesn't fill the line),
+% \emph{or} (ii) at the end of an unnumbered equation. In case (i),
+% we move the part mark up a bit; in case (ii), we format the
+% partmarks as a type of equation number
+%
+% We handle case (ii) first, by detecting whether we're in a maths
+% display. If so, we format the partmarks as an equation number, using
+% |\eqno|. Note that \Lpackage{amsmath} maths (which is what we're
+% using here) formats this differently if the material following
+% |\eqno| is of zero size, so we make this slightly larger than that.
+% \begin{macrocode}
+ \ifdim\displaywidth>0pt
+ \if@eqnsw
+ \ClassError{exam-n}{\string\partmarks* may not be used
+ within numbered equations}{Replace \string\partmarks*
+ with a \string\partmarks\ after the equation}
+ \global\advance\marktotal -#1 % to cause the mark total to be wrong
+ \else
+ \eqno \hbox to 1sp{\FormatPartMarks{#1}\hfil}%
+ \fi
+% \end{macrocode}
+% Case (i), not in maths: We don't automatically end the
+% paragraph here, because a display will often not be the end of a paragraph.
+% I am not at all convinced that this is the correct approach
+% to nudging the partmarks text up the right amount. The
+% following appears to do roughly the right thing, but there's a
+% strong element of trial and error in it.
+% \begin{macrocode}
+ \else
+ \setbox0=\vbox to 0pt{\vss
+ \hbox to \textwidth{\strut\hfill\FormatPartMarks{#1}}%
+ \vskip 1\baselineskip}% vskip means box has zero depth
+ \ifvmode
+ \box0
+ \else
+ \vadjust{\box0}%
+ \fi
+ \fi
+% \end{macrocode}
+% We've called the unstarred version of |\partmarks|. We also end the paragraph here
+% (this technique is filched from the TeXBook, p106).
+% \begin{macrocode}
+ \else
+ \ifdim\@partmarksspace > 0pt
+ {\unskip\nobreak\hfil\penalty50 \hskip\@partmarksspace
+ \hbox{}\nobreak\hfil\FormatPartMarks{#1}%
+ \parfillskip=0pt \finalhyphendemerits=0 \par}
+ \else
+ \unskip\nobreak\hfill\FormatPartMarks{#1}\par
+ \fi
+ \fi
+ \fi
+ \else
+ \ClassError{exam-n}{\string\partmarks\ is not compatible with
+ noperquestionmarks}{Either remove \string\partmarks\ or remove
+ the noperquestionmarks option}
+ \fi
+ \ignorespaces
+}
+% \end{macrocode}
+%
+% The code above permits page-breaks between lists and |\partmarks|.
+% That's because |\@endparenv|, which is called within |\endtrivlist|,
+% includes a negative |\@endparpenalty|. Override that here. This
+% applies to the whole document, but that's OK, since we want to
+% discourage inconvenient page-breaks generally.
+% \begin{macrocode}
+\@endparpenalty=\@M
+% \end{macrocode}
+
+%
+% The number of marks is formatted by the command |\FormatPartMarks|, which
+% may be overridden, using |\renewcommand| in a |.clo| file.
+% In this default case, |\FormatPartMarks| goes into the margin, so we
+% don't need to keep space for it, so set |\@partmarksspace| to zero.
+% \begin{macrocode}
+\newcommand\FormatPartMarks[1]{\hbox to 0pt{\hskip1em \textbf{[#1]}\hss}}
+\@partmarksspace=\z@
+% \end{macrocode}
+%
+% \subsubsection{The question environments: normal questions}
+%
+% The \Lenv{question} environment. Implement
+% this using with a |\question| macro, rather than using
+% |\newenvironment|, so that we can define an optional argument.
+% \begin{macrocode}
+\newcommand\question{%
+ \if@perquestionmarks
+ \let\ex@next\@questionmarks
+ \else
+ \let\ex@next\@questionnomarks
+ \fi
+ \@ifnextchar[%]
+ {\ex@next}{\ex@next[]}}
+% \end{macrocode}
+% Switch between the perquestionmarks and noperquestionmarks cases.
+% \begin{macrocode}
+\def\@questionmarks[#1]#2{%
+ \def\@tempa{#2}% marks available for this question
+ \ifx\@tempa\@empty
+ \ClassError{exam-n}
+ {Missing mark goal for question (using 0 instead)}
+ {Missing mark goal for question (using 0 instead)}
+ \def\@tempa{0}
+ \fi
+ \ifx\@includequestionoverridenumber\@empty
+ \do@question{#1}{\@tempa}%
+ \else
+ \ClassWarning{exam-n}{Forcing question number
+ \@includequestionoverridenumber, in included question #2}
+ \do@question{\@includequestionoverridenumber}{\@tempa}%
+ \fi
+}
+\def\@questionnomarks[#1]{%
+ \do@question{#1}{0}%
+}
+% \end{macrocode}
+%
+% \subsubsection{The question environments: multiple-choice questions}
+%
+% And finally multiple-choice questions. The \Lenv{mcq} environment
+% contains a list of possible answers, numbered from one up, including
+% precisely one correct answer, indicated by |\answer|. These are
+% laid out in a compact itemized list. We do not indicate the number
+% of marks, since these are always the same.
+%
+% First, counters:
+% \begin{itemize}
+% \item |\ex@nmcq| is the number of answers which MCQs can have. If
+% this is less than 1, it's a flag that MCQs haven't been enabled by
+% |\multiplechoiceanswers|.
+% \item |\ex@mcqi| is the running index of answers.
+% \item |\ex@mcqnanswer| is the number of correct answers found
+% (which is checked to be one, at the end).
+% \end{itemize}
+% \begin{macrocode}
+\newcount\ex@nmcq
+\ex@nmcq=-1
+\newcount\ex@mcqnanswer
+\def\multiplechoiceanswers#1{\ex@nmcq=#1}
+% \end{macrocode}
+% The \Lenv{mcq} environment takes a single argument indicating the
+% correct answer. The environment starts with the text question,
+% followed by a number of |\item| answers.
+% \begin{macrocode}
+\newenvironment{mcq}
+ {\parindent=0pt
+ \ifnum\ex@nmcq<1
+ \ClassError{exam-n}
+ {mcq environment without preceding multiplechoiceanswers declaration}
+ {The mcq environment may only be used if the number of
+ permitted MCQ answers has been declared with \string\multiplechoiceanswers}
+ \else
+% \end{macrocode}
+% Declare |\item| for the individual answers, and |\answer| for the
+% single correct answer.
+% \begin{macrocode}
+ \def\item{\@tempswafalse\ex@mcqitem}
+ \def\answer{\@tempswatrue\ex@mcqitem}
+% \end{macrocode
+% Initialise counters, and invoke the common |\do@question| macro.
+% \begin{macrocode}
+ \ex@mcqi=0
+ \ex@mcqnanswer=0
+ \do@question{}{1}
+ \fi}
+% \end{macrocode}
+% At the end of the \Lenv{mcq} environment, check that we found
+% |\ex@nmcq| answers, and that the count of correct answers,
+% |\ex@nmcqanswer|, is exactly one.
+% \begin{macrocode}
+ {\par
+ \ifnum\ex@mcqi<\ex@nmcq
+ \ClassWarning{exam-n}{Too few potential answers in MCQ \thequestionnumber}
+ \@shout{Too few potential answers in MCQ \thequestionnumber}
+ \ifnum\@draftstatus > 0
+ \highlighted{TOO FEW ANSWERS}\par
+ \fi
+ \fi
+ \ifcase\ex@mcqnanswer
+ \ClassWarning{exam-n}
+ {No correct MCQ answer provided in question \thequestionnumber}
+ \@shout{No correct MCQ answer provided in question \thequestionnumber}
+ \ifnum\@draftstatus > 0
+ \highlighted{NO CORRECT ANSWER PROVIDED}\par
+ \fi
+ \or
+ % ex@mcqanswer=1: correct -- do nothing
+ \else
+ \ClassWarning{exam-n}
+ {Too many correct MCQ answers provided in question \thequestionnumber}
+ \@shout{Too many correct MCQ answers provided in question \thequestionnumber}
+ \ifnum\@draftstatus > 0
+ \highlighted{TOO MANY CORRECT ANSWERS}\par
+ \fi
+ \fi
+% \end{macrocode}
+% Other end-question tidyups (compare |\endquestion|).
+% \begin{macrocode}
+ \examn@endquestion{\relax}
+ }
+% \end{macrocode}
+% Each |\item| within the environment (implemented by |\ex@mcqitem|)
+% creates a new paragraph.
+% \begin{macrocode}
+\newcount\ex@mcqi
+\def\ex@mcqitem{%
+ \par
+ \ifnum\ex@mcqi=0
+ % first one
+ \smallskip
+ \parskip=0pt % nothing fancy -- we assume these won't spread
+ % over more than one line
+ \advance\leftskip by 2em
+ \fi
+ \advance\ex@mcqi by 1
+ \noindent
+ \if@tempswa
+ % the correct answer
+ \advance\ex@mcqnanswer 1
+ \if@showsolutions
+ \hbox to 0pt{\hss \highlighted{$\Longrightarrow$ \@Alph\ex@mcqi . }}%
+ \else
+ \hbox to 0pt{\hss \@Alph\ex@mcqi . }%
+ \fi
+ \else
+ \hbox to 0pt{\hss \@Alph\ex@mcqi . }%
+ \fi
+}
+% \end{macrocode}
+%
+% \subsubsection{The question environments: the common handler}
+%
+% The common question handler. This is the macro which does the work.
+% Argument |#1| is the overriding question number (empty indicates the
+% next one in sequence); argument |#2| is the mark goal, which must be
+% non-zero.
+% \begin{macrocode}
+\def\do@question#1#2{%
+ \par % get that out of the way...
+ \markgoal=#2
+ \marktotal=0
+ \ifx\examn@questionpreamble\@empty
+ \else
+ \vspace{2\baselineskip}
+ \hbox to \textwidth{\hfil\textbf{\examn@questionpreamble}\hfil}
+ \questionpreamble{}
+ \fi
+ \setcounter{partnumber}{0}
+ \setcounter{answerpartnumber}{0}
+% \end{macrocode}
+% If the argument |#1| is non-empty, then it is a number, forcing the
+% question number. This is local, however -- don't use it to change
+% the sequence of questions, so don't set the `questionnumber'
+% counter, but only the current label.
+% \begin{macrocode}
+ \refstepcounter{questionnumber}
+ \def\@tempa{#1}
+ \ifx\@tempa\@empty \else
+ \edef\@currentlabel{#1}
+ \fi
+% \end{macrocode}
+%
+% If |pageperquestion| is true, then start a new page here (unless
+% this is the first question).
+% \begin{macrocode}
+ \examn@prequestionspace{%
+ \if@nobreak
+ % after a heading (or something like that)
+ \else
+ % we're not forcing a new page here, but this would be a good point to choose
+ \vskip 2\baselineskip plus 8\baselineskip
+ \penalty-200
+ \fi
+ }
+% \end{macrocode}
+%
+% The optional argument specifies a question number. In compose mode,
+% this unequivocally specifies the question number -- end of story.
+% In the two other modes, this is expected to match the question
+% number implied by the count of questions so far, and we check this,
+% and warn if it is not so.
+% \begin{macrocode}
+ \if@questionnumberchecks
+ \def\@tempa{#1}% intended question number
+% \end{macrocode}
+% If there's no optional argument, we've got nothing to do
+% \begin{macrocode}
+ \ifx\@tempa\@empty
+ % no optional argument -- easy
+ \def\@currentquestion{\thequestionnumber}
+% \end{macrocode}
+%
+% We have a non-null optional argument in |#1|.
+% Check the question number in the argument. If there's a
+% mismatch, warn in draft mode, and fail in final mode. First,
+% however, check that the argument |#1| is just a number (if it's not,
+% the author should have disabled this check in the preamble, and we
+% shouldn't be here at all). We do that check by setting a counter
+% inside a box. If |#1| is all number, then this will result in a
+% zero-width box; if not, then there will be unparsed characters and a
+% non-zero-width box (nifty, eh?).
+% \begin{macrocode}
+ \else
+ \setbox0=\hbox{\@tempcnta=#1}
+ \ifdim\wd0>0pt
+ \ClassWarning{exam-n}{Non-numeric question number, #1.
+ You probably want to put \string\QuestionNumberChecksOff in the preamble}
+ \par\textbf{Non-numeric question number, #1.
+ You probably want to put \hbox{$\backslash$\ttfamily QuestionNumberChecksOff} in the preamble}
+ (the formatting below may be messed up).\par
+ \fi
+% \end{macrocode}
+% Switch on the draft status: in the final version, this mismatch is an error
+% \begin{macrocode}
+ \ifcase\@draftstatus
+ % Final version
+ \@tempcnta=#1
+ \ifnum\c@questionnumber=\@tempcnta
+ \def\@currentquestion{#1}
+ \else
+ \ifx\@includequestionoverridenumber\@empty
+ \ClassError{exam-n}
+ {\string\question[#1] is actually question \thequestionnumber!}
+ {The question in {question} environment number
+ \thequestionnumber\space is specified as
+ \string\question[#1].\MessageBreak
+ This is an error in 'final' mode.\MessageBreak
+ Perhaps you need \string\QuestionNumberChecksOff?}
+ \def\@currentquestion{???}
+ \else
+ \ClassWarning{exam-n}{Forcing question number \@includequestionoverridenumber,
+ in {question} environment number \thequestionnumber}
+ \edef\@currentquestion{\@includequestionoverridenumber}% this doesn't seem to expand in fact!
+ \message{current question=\@currentquestion, override \@includequestionoverridenumber}
+ \fi
+ \fi
+% \end{macrocode}
+% In the other two modes, we simply need a warning.
+% \begin{macrocode}
+ \or
+ % Draft version -- let the given number override
+ % \the\questionnumber, but warn if there's a difference.
+ \@tempcnta=#1
+ \ifnum\c@questionnumber=\@tempcnta \else
+ \ClassWarning{exam-n}
+ {\string\question[#1] is actually question \thequestionnumber!}
+ \fi
+ \def\@currentquestion{#1}
+ \else
+ % compose mode -- argument overrides without question
+ \def\@currentquestion{#1}
+ \fi
+ \fi
+ \else
+ % skip question-number checks
+ \def\@tempa{#1}% intended question number
+ \ifx\@tempa\@empty
+ % no optional argument -- this is possibly an error, so warn
+ \ClassWarning{exam-n}{\string\QuestionNumberChecksOff\ is in
+ force, but this question has no [number]}
+ \def\@currentquestion{\thequestionnumber}
+ \else
+ \typeout{Forcing question \thequestionnumber\space to be #1}
+ \def\@currentquestion{#1}
+ \fi
+ \fi
+% \end{macrocode}
+% Format the question number, first removing and discarding any parindent
+% (the reason we don't just start with |\noindent| here is because
+% there may be a blank line between the |\begin{question}|, and the
+% text, so we'd (inadvertently) start another new paragraph when the
+% actual question starts).
+% The call to |\mark| should come \emph{after} setting the
+% question number: if it happens before, and there is a page-break
+% immediately before the new question, we can get a spurious
+% `Q?? continued' on the previous page.
+%
+% If a paragraph starts inside a level of grouping -- for example
+% |{\bf 1} text...| or even just |{T}ext| -- then the |\everypar|
+% tokens are expanded inside that group, which means that the
+% resetting of |\everypar| is local, with the result that the tokens
+% are reused for the next paragraph. Make the emptying of |\everypar|
+% global for that reason.
+% \begin{macrocode}
+ \everypar{\setbox0=\lastbox % discard \box0
+ \FormatQuestionNumber
+ \mark{\@currentquestion}%
+ \global\everypar{}}
+}
+% \end{macrocode}
+% Format the question number. This command is documented as existing,
+% so that it can be potentially overridden in a \texttt{.clo} file.
+% \begin{macrocode}
+\newcommand\FormatQuestionNumber
+ {\hbox to 0pt{\hss \textbf{\@currentquestion}\hskip1em}}
+% \end{macrocode}
+%
+% Finish off the question:
+% Format the indication of the total number
+% of marks, and do a few consistency checks.
+% \begin{macrocode}
+\def\endquestion{%
+ \ifnum\marktotal=\markgoal
+ \typeout{Question \@currentquestion\if@perquestionmarks, \the\marktotal\space marks\fi}
+ \iffalse % all of this is redundant, and ends up too shouty
+ \ifcase\@draftstatus
+ % Final version -- do nothing
+ \relax
+ \or % draft version
+ \relax % no, the above is too much; do nothing
+ \else % compose version
+ \par
+ \hfil\textbf{\highlighted{[Q\,\@currentquestion\if@perquestionmarks, \the\marktotal\space marks\fi]}}%
+ \break
+ \fi
+ \fi
+% \end{macrocode}
+% In the case where the mark total doesn't match, make a noise about it.
+% \begin{macrocode}
+ \else
+ \ClassWarning{exam-n}
+ {Question \@currentquestion\space has a total of \the\marktotal\space marks,
+ \MessageBreak
+ when it should have \the\markgoal}
+ \begin{center}
+ \edef\@tempa{Question \@currentquestion\space
+ has a total of \the\marktotal\space marks,
+ when it should have \the\markgoal}
+ \expandafter\shout\expandafter{\@tempa}
+ \end{center}
+ \fi
+% \end{macrocode}
+% Make a few tidyups in the end-question wrapper.
+% \begin{macrocode}
+ \examn@endquestion{%
+ \if@showmarktotals
+ \par % into vertical mode
+ \nobreak % keep the marks total with the question
+ \vbox to 2\baselineskip{
+ \vss
+ % this should be very similar to the call to
+ % \FormatPartMarks in \@partmarks, above
+ \hbox to \textwidth{\strut\hfill\FormatPartMarks{Total: \the\markgoal
+ \ifnum\@draftstatus>0
+ % in draft modes, put a fairly discreet confirmation in the total
+ \space
+ \highlighted{\ifnum\marktotal=\markgoal OK\else X\fi}%
+ \fi}}}
+ \fi
+ }
+}
+% \end{macrocode}
+%
+% \subsubsection{Other structures}
+%
+% The \Lenv{questiondata} environment allows the author to provide
+% some additional data or equations for the question.
+% This environment ends a preceding paragraph.
+% \begin{macrocode}
+\newenvironment{questiondata}{%
+ \par
+ \penalty50 % poor break
+ \vbox\bgroup
+ \slshape
+ \parindent=0pt \parskip=\medskipamount
+ \smallskip
+ \hrule
+ \nobreak
+ \smallskip
+ \noindent \ignorespaces
+}{%
+ \par
+ \nobreak
+ \medskip
+ \hrule width \textwidth
+ \par
+ \egroup % end of \vbox
+}
+% \end{macrocode}
+%
+% If |\questionpreamble| is called some time before the start of a
+% \Lenv{question} environment, then its contents will be printed at
+% the start of the next question.
+% \begin{macrocode}
+\newcommand\questionpreamble[1]{\gdef\examn@questionpreamble{#1}}
+\let\examn@questionpreamble\@empty
+% \end{macrocode}
+%
+% In those cases where the sequence of question numbers is not
+% supposed to match the sequence of question environments, declare
+% that we should turn off the corresponding checks within |\question|.
+% \begin{macrocode}
+\newif\if@questionnumberchecks
+\@questionnumbercheckstrue
+\newcommand\QuestionNumberChecksOff{\@questionnumberchecksfalse}
+% \end{macrocode}
+%
+% The underlying style (article) has enumerate and itemize
+% environments which have a rather generous amount of space. This
+% makes sense in an article, but within an exam, which already has a
+% lot of white space around, such lists end up looking unattractively
+% ragged. So redefine them slightly here, adjusting the spacing
+% appropriately. First `enumerate'\dots
+% \begin{macrocode}
+\def\enumerate{%
+ \ifnum \@enumdepth >\thr@@\@toodeep\else
+ \advance\@enumdepth\@ne
+ \edef\@enumctr{enum\romannumeral\the\@enumdepth}%
+ \expandafter
+ \list
+ \csname label\@enumctr\endcsname
+ {\usecounter\@enumctr
+ \topsep0pt
+ \partopsep0pt
+ %\parskip=5.0pt \parsep=\parskip
+ \def\makelabel##1{\hss\llap{##1}}}%
+ \fi}
+% \end{macrocode}
+% \dots then `itemize'.
+% \begin{macrocode}
+\def\itemize{%
+ \ifnum \@itemdepth >\thr@@\@toodeep\else
+ \advance\@itemdepth\@ne
+ \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}%
+ \expandafter
+ \list
+ \csname\@itemitem\endcsname
+ {\topsep0pt
+ \partopsep0pt
+ \def\makelabel##1{\hss\llap{##1}}}%
+ \fi}
+% \end{macrocode}
+% To match the format of the question number above, we have to make
+% sure that the enumerate environment's counters are different.
+% \begin{macrocode}
+\renewcommand\theenumi{\@roman\c@enumi}
+% \end{macrocode}
+%
+% \subsection{Other useful commands}
+%
+% |\comment| creates a marginal comment in non-final modes. There is an
+% interaction with the marks mechanism -- see the discussion about
+% |\topmark| above.
+% \begin{macrocode}
+\newcommand\comment[1]{%
+ \ifnum\@draftstatus > 0
+ \marginpar{\highlighted{#1}}%
+ % should we \@shout this, too?
+ \fi
+ \ignorespaces
+}
+% \end{macrocode}
+%
+% The |\author| command is a convenience. Used within a
+% \Lenv{question} environment, it creates a comment with the author's
+% name. I may expand its functionality in future.
+% \begin{macrocode}
+\renewcommand\author[1]{\comment{Author: #1}}
+% \end{macrocode}
+%
+% The |\@shout| macro is intended for use in all modes: it appends a
+% remark to a list of exclamations which are highlighted at the end of
+% the document.
+% The argument to |\@shout| can have expandable things (such as
+% |\thequestionnumber|) in it.
+% Shouts appear in all modes and cannot be suppressed.
+% \begin{macrocode}
+\newtoks\@allshouts \@allshouts={}
+\def\@shout#1{\edef\@tempa{#1}\expandafter\@@shout\expandafter{\@tempa}}
+\def\@@shout#1{\global\@allshouts=\expandafter{\the\@allshouts\t{#1}}}
+\def\showthe@shouts{%
+ {\def\t##1{{\LARGE\noindent\highlighted{NOTE: ##1}\par}}%
+ \the\@allshouts}%
+ % Remark on the number of shouts in the aux file
+ {\@tempcnta=0 \def\t##1{\advance\@tempcnta1}\the\@allshouts
+ \protected@write\@auxout{}%
+ {\string\examn@shoutcount{\the\@tempcnta}}}}
+% \end{macrocode}
+% Define the user macro |\shout|
+% \begin{macrocode}
+\def\shout#1{\textbf{\highlighted{#1}}\@shout{#1}}
+% \end{macrocode}
+% Take note of the number of shouts, and write this information to the
+% \texttt{.aux} file, so that it can be read in next time.
+% \begin{macrocode}
+\newcount\examn@shoutcounttotal
+\examn@shoutcounttotal=0
+\def\examn@shoutcount#1{\global\examn@shoutcounttotal=#1}
+% \end{macrocode}
+%
+% The |\includequestion| command includes a question from another
+% file. For convenience, we disable |\documentclass|, |\usepackage|, and the
+% \Lenv{document} environment, so that the included file may be a
+% complete \LaTeX\ document.
+% \begin{macrocode}
+\def\dummy@documentclass{%
+ \@ifnextchar[\dummy@@documentclass{\dummy@@documentclass[]}}
+\def\dummy@@documentclass[#1]#2{}
+\def\includequestion{
+ \@ifnextchar[%]
+ {\@includequestion}{\@includequestion[]}}
+\def\@includequestion[#1]#2{%
+ \begingroup
+ \let\documentclass\dummy@documentclass
+ \let\document\@empty % not \relax: makes \begin think {document} is undef'd
+ \let\enddocument\relax
+ \def\@tempa{#1}
+ \ifx\@tempa\@empty \else
+ \def\@includequestionoverridenumber{#1}
+ \message{includequestion override: \@includequestionoverridenumber}
+ \fi
+ \def\usepackage##1{\ClassWarning{exam-n}
+ {Ignoring \string\usepackage{##1} in included question #2}}
+ \input{#2}
+ \endgroup
+}
+\let\@includequestionoverridenumber\@empty
+% \end{macrocode}
+%
+% \subsection{The solution environment}
+%
+% The solution environment is made somewhat complicated by the way we
+% implement it. Rather than using a verbatim-like technique to omit
+% the source lines (as done successfully by, for example, the
+% \Lpackage{comments} package) we set the contents of the environment
+% in a box, which we throw away. This technique is more robust in
+% principle, but it does mean we have to disable some things which
+% have global side-effects.
+%
+% Maintain a flag which indicates whether we're in a solution
+% environment or not.
+% \begin{macrocode}
+\newif\if@insolution
+\@insolutionfalse
+% \end{macrocode}
+%
+% We want to use |\part| within solutions. If we were to do so naively
+% however, we would end up incrementing the |partnumber| counter
+% which that macro uses, which either disturbs the numbering of the
+% parts in the question (if the solutions are interspersed in the
+% question) or starts out of sequence (if the solutions are at the
+% end). So we maintain a separate counter. Additionally, we want to
+% force the formatting of the solution parts, to be independent of the
+% formatting in the main question
+% \begin{macrocode}
+\newcounter{answerpartnumber}
+\newcommand{\examn@solutionpart}{%
+ \par
+ \stepcounter{answerpartnumber}
+ \noindent\hbox to \parindent{(\StylePartNumber{answerpartnumber})\hss}}
+% \end{macrocode}
+%
+% Specify how solutions should be shown. The following makes them
+% ragged right, slightly smaller and slanted, with rules fore and aft.
+% This doesn't leap out, but the difference should be detectable.
+% Putting a box round the solution would be desirable (it keeps it all
+% together and would allow a coloured background), but that's rather
+% hard to arrange in practice.
+% \begin{macrocode}
+\def\@formatsolution{\par
+ \if@insolution
+ \ClassError{exam-n}{Misplaced solution}{You can't have a solution within a solution}
+ \else
+ \@insolutiontrue % this happens within a group
+ \fi
+ \examn@dummycaptions % dummy captions within solutions
+ \typeout{SHOWING SOLUTIONS}
+ \let\part\examn@solutionpart
+% \end{macrocode}
+% Checks done; now get on with the layout
+% \begin{macrocode}
+ \vskip 1ex plus 2\bigskipamount % add stretchable space...
+ \penalty-\@lowpenalty % ...and encouragement to break here
+ \parskip 0.5\baselineskip
+ \raggedright
+ \color{solutiontext}%\slshape
+ \ifbigfont \else
+ \small
+ \fi
+ \hrule
+ \hbox to \textwidth{\vrule height 1ex \hfil \vrule height 1ex}
+ \nobreak
+ \vskip -\parskip % cancel out the following parskip
+ \textbf{\highlighted{Solution:}}\hskip2em
+ \ignorespaces
+ \parindent=2em
+}
+% \end{macrocode}
+% The end of the solution environment is simple, and simply matches
+% the box above.
+% \begin{macrocode}
+\def\end@formatsolution{%
+ \par
+ \nobreak
+ \vskip -0.5ex
+ \hbox to \textwidth{\vrule height 1ex \hfil \vrule height 1ex}
+ \hrule
+}
+% \end{macrocode}
+%
+% The content of the \Lenv{solution} environment is balanced \LaTeX\
+% text, and so does not have to be complicated; in particular, it does
+% not have to have the generality, and the consequent restrictions, of
+% for example Eijkhout's \Lpackage{comment} package. If we're including the
+% solutions, then we simply format them in the usual sort of way,
+% inside a group; otherwise we're skipping them, so put the contents in a
+% box and throw it away. Note that \Lenv{solution} is an environment,
+% so we're inside a group at this point.
+% \begin{macrocode}
+\if@showsolutions
+ \let\solution\@formatsolution
+ \let\endsolution\end@formatsolution
+\else
+ \def\solution{%
+ \if@insolution
+ \ClassError{exam-n}{Misplaced solution}{You can't have a solution within a solution}
+ \fi
+ \let\endfigure\endfloat@skipsolutions
+ \let\endtable\endfloat@skipsolutions
+ \examn@dummycaptions % dummy captions avoid counter increments
+ \@ifundefined{includepdf}{}{\let\includepdf\examn@disabledpdfpages}
+ \par
+ \setbox\@tempboxa\vbox\bgroup
+ \@insolutiontrue}
+ \def\endsolution{%
+ \egroup % ...and do nothing with this box
+ }
+\fi
+% \end{macrocode}
+%
+% \subsubsection{Floats in solutions}
+%
+% Figures in solutions must be treated specially, since they mustn't
+% move outside the solution. The most straightforward thing seems to
+% be to avoid them floating at all. Additionally, this is probably true of
+% figures in the question as well (if a question refers to a figure,
+% it's probably civil to have the figure on the same page as the
+% text), so redefine {figure} so that in all cases figures are placed
+% `here', and never float. We also add generous amounts of vertical
+% space, to encourage figures to stay on the same page as the text
+% before them, if this is at all possible.
+%
+% \begin{macrocode}
+\def\examn@badfloat#1[#2]{
+ \ClassError{exam-n}
+ {Bad #1 option #2 ignored}
+ {In the exam-n class, the 'floating' environments take no argument,\MessageBreak
+ and are always placed 'here'}
+ \examn@float{#1}}
+\def\examn@float#1{%
+ % re-using the standard LaTeX parameter means that \caption works
+ \def\@captype{#1}
+ \setbox\@tempboxa\vbox\bgroup}
+\def\examn@endfloat{%
+ \egroup % end \@tempboxa
+ \unskip
+ \nobreak
+ % add lots of stretchability, but non-infinite, for the sake of tidiness
+ \vskip 0pt plus 0.5\textheight
+ \penalty50 % a pagebreak here discards following vskip
+ % (cf TeXBook p106; or try \filbreak of p111)
+ \vskip 2ex plus -0.5\textheight % negative stretch cancels previous vskip
+ \box\@tempboxa
+ %\vskip 1ex
+ \nobreak
+}
+\def\endfloat@skipsolutions{%
+ % variant when skipping solutions -- end the \@tempboxa and do nothing
+ \egroup
+}
+% \end{macrocode}
+% Now, finally, redefine the figure and table environments in terms of
+% these new macros.
+% \begin{macrocode}
+\def\figure{%
+ \@ifnextchar[{\examn@badfloat{figure}}{\examn@float{figure}}%]
+}
+\def\table{%
+ \@ifnextchar[{\examn@badfloat{table}}{\examn@float{table}}%]
+}
+\let\endfigure\examn@endfloat
+\let\endtable\examn@endfloat
+% \end{macrocode}
+% Within these 'floats', we must redefine |\caption|, so that we don't
+% increment the float counters. One motivation for this is so that we don't have
+% table numbers changing depending on whether solutions are included
+% or not; but since we're implementing the solutions by setting the
+% content in a discarded box, it turns out that we get the counter
+% increments whether we include the solutions or not. The following
+% definition of |\caption| is just the standard one, with
+% |\refstepcounter| removed and `Table nnn' redefined appropriately.
+% \begin{macrocode}
+\def\examn@dummycaptions{%
+ \def\fnum@figure{\figurename} % 'Figure nnn' changed to just 'Figure'
+ \def\fnum@table{\tablename}
+ \def\caption{%
+ \ifx\@captype\@undefined
+ \@latex@error{\noexpand\caption outside float}\@ehd
+ \expandafter\@gobble
+ \else
+ %\refstepcounter\@captype % omit this line from the standard definition
+ \expandafter\@firstofone
+ \fi
+ {\@dblarg{\@caption\@captype}}%
+ }
+}
+% \end{macrocode}
+%
+% \subsubsection{Solutions and pdfpages}
+%
+% It appears that the \Lpackage{pdfpages} package is incompatible with
+% the way that I implement \Lopt{noshowsolutions}, largely because (I
+% think) it bypasses \LaTeX\ and fiddles with the generated PDF
+% directly. Therefore, we have to disable the \Lpackage{pdfpages}
+% support when we're skipping solutions. We mustn't do this globally,
+% since sometimes (for example in a .clo option file's
+% constants sheet) we do need pdfpages in the no-show-solutions case.
+% \begin{macrocode}
+\def\examn@disabledpdfpages{\@ifnextchar[% ]
+ \examn@disabledpdfpages@
+ {\examn@disabledpdfpages@[]}}
+\def\examn@disabledpdfpages@[#1]#2{\relax}
+% \end{macrocode}
+%
+% \subsection{End-of-document actions}
+%
+% Add a number of actions to the end-of-document hook. Do them here,
+% rather than by calling |\AtEndDocument| multiple times, because the
+% order matters (in fact, the order here is the same as the order
+% they're defined in, but it's best to be explicit about this).
+% \begin{macrocode}
+\AtEndDocument{
+ \CheckTotalQuestions
+ \ClosingText
+ \showthe@shouts
+ \WriteLastPageLabel}
+% \end{macrocode}
+%
+% \subsection{Other formatting niceties}
+%
+% Format vectors (the default for |\vec| is a symbol with an arrow
+% over it):
+% \begin{macrocode}
+\ifcase\examn@mtselect
+ % mathptm fonts
+ % This is a very clumsy version, but it appears to be our only option
+ \def\vec#1{\mathchoice{\mbox{\boldmath $\displaystyle #1$}}
+ {\mbox{\boldmath $ #1$}}
+ {\mbox{\boldmath $\scriptstyle #1$}}
+ {\mbox{\boldmath $\scriptscriptstyle #1$}}}
+\or % mathtime (should this be the same for mathtime as for mtpro2?
+ \let\vec\mathbf
+\or % mtpro2
+ \let\vec\mathbold
+\fi
+% \end{macrocode}
+% Abbreviations for degrees.
+% \begin{macrocode}
+\newcommand\BSc{B.Sc.{}}
+\newcommand\MSci{M.Sci.{}}
+\newcommand\MSc{M.Sc.{}}
+\newcommand\MA{M.A.{}}
+\newcommand\MEng{M.Eng.{}}
+\newcommand\BEng{B.Eng.{}}
+% \end{macrocode}
+%
+% Tweaks to differentials.
+% \begin{macrocode}
+\newcommand{\dd}{\mathrm{d}}
+\newcommand{\ddd}{\,\mathrm{d}} % inside an integral, including thinspace
+
+\def\Diffl{\@ifstar\@Difflflat\@Diffl}
+\def\Partial{\@ifstar\@Partialflat\@Partial}
+\def\@Partial{\@ifnextchar[{\@@Diffl\partial}{\@@Diffl\partial[]}}
+\def\@Partialflat{\@ifnextchar[{\@@Difflflat\partial}{\@@Difflflat\partial[]}}
+\def\@Diffl{\@ifnextchar[{\@@Diffl\dd}{\@@Diffl\dd[]}}
+\def\@Difflflat{\@ifnextchar[{\@@Difflflat\dd}{\@@Difflflat\dd[]}}
+\def\@@Diffl#1[#2]#3#4{%
+ \def\@tempa{#2}%
+ \ifx\@tempa\empty
+ \frac{#1#3}{#1#4}%
+ \else
+ \frac{{#1}^{#2}#3}{#1{#4}^{#2}}%
+ \fi}
+\def\@@Difflflat#1[#2]#3#4{%
+ \def\@tempa{#2}%
+ \ifx\@tempa\empty
+ #1#3\mskip-0.8mu/\mskip-1.2mu #1#4%
+ \else
+ {#1}^{#2}#3\mskip-0.8mu /\mskip-1.2mu #1{#4}^{#2}%
+ \fi}
+% \end{macrocode}
+%
+% The exponential sign
+% \begin{macrocode}
+\def\e{{\mathrm e}}
+% \end{macrocode}
+%
+% Physical units in |\rm|. Unstarred version includes leading
+% |\thinspace|. Starred version doesn't, and is used when referring to
+% the unit by itself (eg axis is |$B/\units*T$|), and is not qualifying
+% a number.
+% FIXME: |\mu| in |\units| can come out wrong in some fonts (mtpro2?)
+% -- needs investigation.
+% \begin{macrocode}
+\def\units{\begingroup
+ \catcode`\.=\active
+ \@ifstar{\let\un@tsspace\relax \un@ts}%
+ {\let\un@tsspace\thinspace\un@ts}}
+\begingroup
+ \catcode`\.=\active
+ \gdef\un@ts#1{\let~\thinspace\let.\thinspace
+ \ifmmode
+ \un@tsspace\mathrm{#1}%
+ \else
+ \nobreak$\un@tsspace\mathrm{#1}$%
+ \fi
+ \endgroup}
+\endgroup
+% \end{macrocode}
+%
+% Other miscellaneous symbols:
+% The AU is nothing exciting, but may be adjusted in future
+% \begin{macrocode}
+\def\au{au}
+% \end{macrocode}
+% The symbol for Compton wavelength is a crossed lambda -- the following isn't perfect, but is OK for now.
+% \begin{macrocode}
+\def\lambdabar{\setbox\@tempboxa\hbox{$\lambda$}%
+ \hbox to 0pt{\hbox to \wd\@tempboxa{\hss$\bar{}$\hss}\hss}\box\@tempboxa}
+% \end{macrocode}
+%
+% All done.
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+% \Finale
+%
+\endinput