From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/exam-n/exam-n.dtx | 3213 ++++++++++++++++++++++++++++++++ 1 file changed, 3213 insertions(+) create mode 100644 macros/latex/contrib/exam-n/exam-n.dtx (limited to 'macros/latex/contrib/exam-n/exam-n.dtx') 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 +%% +%% 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>\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} +% +% +% \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} +% +% \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\else\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{}| +% 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{}| and \cmd|\partmarks*{}| 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{}| 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 +% +% \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} +% +% \end{macrocode} +% \Finale +% +\endinput -- cgit v1.2.3