summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/exam-n
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2022-10-10 20:22:56 +0000
committerKarl Berry <karl@freefriends.org>2022-10-10 20:22:56 +0000
commit1a12075ba4cc3ca26d4c82b08bcb87b2e2aa62cc (patch)
tree382db7df13f634f4acf716cc4338db26e63286da /Master/texmf-dist/source/latex/exam-n
parent793d2c31e077f91a0573b85c8a499a45dd4a2e0e (diff)
exam-n (10oct22)
git-svn-id: svn://tug.org/texlive/trunk@64674 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/exam-n')
-rw-r--r--Master/texmf-dist/source/latex/exam-n/exam-n.drv78
-rw-r--r--Master/texmf-dist/source/latex/exam-n/exam-n.dtx1518
-rw-r--r--Master/texmf-dist/source/latex/exam-n/release-notes.dtx43
3 files changed, 1179 insertions, 460 deletions
diff --git a/Master/texmf-dist/source/latex/exam-n/exam-n.drv b/Master/texmf-dist/source/latex/exam-n/exam-n.drv
index ee1e949bbd2..7adfd8aca29 100644
--- a/Master/texmf-dist/source/latex/exam-n/exam-n.drv
+++ b/Master/texmf-dist/source/latex/exam-n/exam-n.drv
@@ -6,10 +6,13 @@
%%
%% exam-n.dtx (with options: `driver')
%% exam-n: format exam questions
-%% Release version 1.1.4, 2016 December 19.
+%% Release version exam-n-1.4.0, 2022 October 10.
+%% See https://purl.org/nxg/dist/exam-n
+%% and https://heptapod.host/nxg/exam-n
+%% and https://www.ctan.org/pkg/exam-n
%%
%%%% File: exam-n.dtx
-%%%% Copyright 2005--2016, Norman Gray
+%%%% Copyright 2005--2022, Norman Gray
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
@@ -21,84 +24,36 @@
%%
%% This work has the LPPL maintenance status `maintained'.
%%
-%% The Current Maintainer of this work is Norman Gray <http://nxg.me.uk>
+%% The Current Maintainer of this work is Norman Gray <https://nxg.me.uk>
%%
%% This work consists of the files exam-n.dtx and exam-n.ins,
%% the derived file exam-n.cls,
%% and the associated *.clo files.
-%%%% Source: Mercurial revision e8a612cb25f4, 2016-12-19 16:49 +0000, tag exam-n-1.1.4 + 0
+%%%% Source: a91e9cff7cac, 2022-10-10T13:33:17+01:00
%%
\documentclass{ltxdoc}
\title{exam-n: exam papers}
-\author{Norman Gray\\(\texttt{norman@astro.gla.ac.uk})}
-\date{Release 1.1.4}
+\author{Norman Gray\\(\texttt{norman.gray@glasgow.ac.uk})}
+\date{Version exam-n-1.4.0, 2022 October 10}% ...rather than exam-n-1.4.0, which isn't reader-focused
\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
+\newcommand\Lpackage[1]{[\textsf{#1}]} %packages
{\catcode`\<=\active
\gdef<#1>{{\ensuremath\langle\normalfont\textsl{#1}\ensuremath\rangle}}}
\def\cmd{\begingroup
- \catcode`\\=12 \catcode`\{=12 \catcode`\}=12
+ \catcode`\\=12 \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\bs{$\backslash$}
-\makeatletter
-\newcommand\BSc{B.Sc.{}}
-\newcommand\MSci{M.Sci.{}}
-\newcommand\MSc{M.Sc.{}}
-\newcommand\MA{M.A.{}}
-\newcommand\MEng{M.Eng.{}}
-\newcommand\BEng{B.Eng.{}}
-\newcommand{\dd}{\mathrm{d}}
-\newcommand{\ddd}{\,\mathrm{d}} % inside an integral, including thinspace
+\def\secref#1{Sect.~\ref{#1}}
-\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}
-\def\e{{\mathrm e}}
-\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
-\def\au{au}
-\def\lambdabar{\setbox\@tempboxa\hbox{$\lambda$}%
- \hbox to 0pt{\hbox to \wd\@tempboxa{\hss$\bar{}$\hss}\hss}\box\@tempboxa}
-\makeatother
+\usepackage{examndefs}
\begin{document}
\maketitle
@@ -109,6 +64,13 @@
+\@ifl@t@r\fmtversion{2020/10/01}
+ {\typeout{Format is \fmtversion -- OK!}}
+ {\ClassError{exam-n}
+ {You need a more recent version of LaTeX}
+ {This class now requires a
+ LaTeX version at least 2020/10/01; version
+ \fmtversion\ is too old}}
\endinput
%%
%% End of file `exam-n.drv'.
diff --git a/Master/texmf-dist/source/latex/exam-n/exam-n.dtx b/Master/texmf-dist/source/latex/exam-n/exam-n.dtx
index 043d2c9f7c9..ce752727b85 100644
--- a/Master/texmf-dist/source/latex/exam-n/exam-n.dtx
+++ b/Master/texmf-dist/source/latex/exam-n/exam-n.dtx
@@ -3,10 +3,13 @@
%
% Generated file : DO NOT EDIT
%
-%% Release version 1.1.4, 2016 December 19.
+%% Release version exam-n-1.4.0, 2022 October 10.
+%% See https://purl.org/nxg/dist/exam-n
+%% and https://heptapod.host/nxg/exam-n
+%% and https://www.ctan.org/pkg/exam-n
%%
%%%% File: exam-n.dtx
-%%%% Copyright 2005--2016, Norman Gray
+%%%% Copyright 2005--2022, Norman Gray
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
@@ -18,136 +21,47 @@
%%
%% This work has the LPPL maintenance status `maintained'.
%%
-%% The Current Maintainer of this work is Norman Gray <http://nxg.me.uk>
+%% The Current Maintainer of this work is Norman Gray <https://nxg.me.uk>
%%
%% This work consists of the files exam-n.dtx and exam-n.ins,
%% the derived file exam-n.cls,
%% and the associated *.clo files.
-%<+package|driver|example>%%%% Source: Mercurial revision e8a612cb25f4, 2016-12-19 16:49 +0000, tag exam-n-1.1.4 + 0
+
+%<+package|driver|example>%%%% Source: a91e9cff7cac, 2022-10-10T13:33:17+01:00
%%
%<*package|driver>
%</package|driver>
%<+package>\NeedsTeXFormat{LaTeX2e}
-%<+package>\ProvidesClass{exam-n}[2016/12/19 1.1.4]
-%<+package>\typeout{Class: `exam-n 1.1.4 <2016/12/19>}
+%<+package>\ProvidesClass{exam-n}[2022/10/10 exam-n-1.4.0]
+%<+package>\typeout{Class: `exam-n-1.4.0 <2022/10/10>}
%
%<*driver>
\documentclass{ltxdoc}
\title{exam-n: exam papers}
-\author{Norman Gray\\(\texttt{norman@astro.gla.ac.uk})}
-\date{Release 1.1.4}
+\author{Norman Gray\\(\texttt{norman.gray@glasgow.ac.uk})}
+\date{Version exam-n-1.4.0, 2022 October 10}% ...rather than exam-n-1.4.0, which isn't reader-focused
\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
+\newcommand\Lpackage[1]{[\textsf{#1}]} %packages
+%Make command strings easier to write, with \cmd|\foo|
%{\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`\\=12 \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\secref#1{Sect.~\ref{#1}}
-\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
+% Various definitions of this package, so we can document them.
+\usepackage{examndefs}
% Uncomment \OnlyDescription to skip the implementation
%\OnlyDescription
@@ -214,14 +128,74 @@
% |\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.
+% \Lopt{mathtime}, \Lopt{mtpro2}, \Lopt{stix2}]
+% The \Lopt{cmfonts} option (the default) uses the Computer Modern fonts for the
+% document, and the other options use PostScript or OpenType fonts.
+%
+% The \Lopt{mathtime} or \Lopt{mtpro2} options select PostScript
+% Times Roman, Helvetica and Courier for the body text, plus either Mathtime or
+% Mathtime Professional~2 to typeset maths (this is commercially
+% distributed by
+% PC\TeX\footnote{\url{https://www.pctex.com/mtpro2.html}}, and
+% designed to be compatible with Times Roman). A broadly
+% compatible alternative to this is to use the \Lopt{mathptm}
+% option, but although this is free, the results aren't impressive.
+%
+% A final option is to use the \Lopt{stix2} option to choose
+% specifically and exclusively the
+% (free) STIX2 font set\footnote{\url{https://www.stixfonts.org}}
+% for both text and maths.
+% On this site, you will need to download and install
+% the files in the \url{static_otf.zip} bundle.
+% Note that the support for this option is somewhat experimental, and
+% at present, this package simply uses (serif) STIX2 roman
+% for all font shapes. Since the exam style doesn't use any sans serif by
+% default, this doesn't matter, at some level. The
+% \Lopt{sansserif} option is not compatible with this option (the option
+% won't produce any error, but neither will it produce any effect).
+%
+% \textbf{FIXME: remove this when unicode-math is working.}
+% \textbf{Note:} because of an unfortunate interaction between packages, the
+% \Lpackage{stix2} and \Lpackage{siunitx} packages can produce unexpected
+% results with some combinations of \TeX\ engine and package version
+% (specifically, \Lpackage{stix2} plus \Lpackage{siunitx}
+% and \cmd|\micro| or \cmd|\circ| can produce garbled characters
+% without \LaTeX\ reporting an error). Before \TeX Live 2021, this
+% worked correctly with Xe\LaTeX\ and Lua\LaTeX, but not with
+% pdf\LaTeX; from \TeX Live 2021 this works as expected with
+% pdf\LaTeX, but works with the other two \emph{only} if you load
+% the \Lpackage{siunitx} package with
+% \cmd|\usepackage{siunitx}[=v2]|. I hope that future versions of
+% one or other of these packages will make clear how this package
+% should handle them, in a way which avoids this special-casing.
+% \iffalse See
+% https://github.com/josephwright/siunitx/issues/550
+% https://github.com/josephwright/siunitx/issues/547
+% https://github.com/stipub/stixfonts/issues/235
+% \fi
+%
+% The handling of non-standard fonts has always been slightly
+% fragile in \LaTeX.
+% The \Lopt{mtpro2} and \Lopt{stix2} options are those currently
+% most used by the author, and are therefore the ones most likely
+% to get the various font nuances correct.
+%
+% \item[\Lopt{uprightpi}]By default $\pi$ is set slanted, as is the
+% usual \LaTeX\ default. When this is referring to the circular
+% constant, however, this should (in some typesetting styles) be set as an upright letter, in
+% fonts which support this. If the option \Lopt{uprightpi} is
+% present, then |\pi| is defined to produce an upright letter, and
+% the command |\italicpi| is defined to produce the slanted version.
+% Whether this option is supplied or not, the macro |\uppi| will
+% produce a single upright~$\pi$.
+% Note: this is at present implemented
+% only for the \Lopt{mtpro2} and \Lopt{stix2} options,
+% and the combination of pdflatex+stix2 does not support |\uppi| at present.
+%
+% \item[\Lopt{(no)siunitx}] Load the \Lpackage{siunitx} package, or
+% not. The default is yes. The |\units| macro, described below,
+% still exists as an alternative, but will be removed in a
+% forthcoming release (probably after 1.4.x).
%
% \item[\Lopt{(no)showsolutions}]
% These control whether the solutions to
@@ -235,7 +209,7 @@
% 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
+% See \secref{s:question} for more discussion (this
% option was called \Lopt{showmarks} up to release 0.15).
%
% \item[\Lopt{(no)pageperquestion}]
@@ -269,8 +243,9 @@
% \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
+% easier or harder for dyslexic students to read (there seems to be
+% a variety of advice here, in both directions, ranging from
+% confident to dogmatic, but remarkably little solid evidence
% either way).
%
% \item[\Lopt{largefont}, or \Lopt{hugefont}]
@@ -283,9 +258,9 @@
% \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}
+% The only generic style option is \Lopt{myclass}
% (which is included as an example of how such a file is written).
-% See section~\ref{s:custom} below.
+% See \secref{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
@@ -390,6 +365,9 @@
% preamble. After that, you must provide a question-number argument
% (in square brackets) for every question.
%
+% Using |\label| within a question sets a label for the question number;
+% using it within a |\part| (see below) labels the part number.
+%
% 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
@@ -467,7 +445,8 @@
% 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),
+% the \Lenv{document} environment, and zero or more |\usepackage|
+% or |\RequirePackage| commands),
% then you can most conveniently import them unedited using the
% |\includequestion| command.
% \begin{verbatim}
@@ -483,6 +462,12 @@
% question, you will have to make sure that whoever is assembling the
% master file includes those packages there, too.
%
+% That is, we don't try too hard to support including just any old \LaTeX, here:
+% any complicated preamble requirements in an included file should
+% probably be managed by the exams convener transplanting them into
+% the preamble of the main document. This may be an overly
+% simple-minded approach, and may change in future versions.
+%
% 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
@@ -505,7 +490,7 @@
% (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.
+% \secref{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
@@ -515,6 +500,13 @@
% 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.
%
+% In some (rare) cases, you may want to force a particular part
+% number. You can do that with an optional argument |\part[99]|
+% which overrides the auto-incremented numbering. Note that this
+% skips the auto-increment of the number but doesn't cancel it, so
+% if you do this for one part number you should probably do it for
+% all of them.
+%
% \DescribeMacro{\partmarks}
% \DescribeMacro{\partmarks*}
% Macros \cmd|\partmarks{<num>}| and \cmd|\partmarks*{<num>}| announce
@@ -523,21 +515,55 @@
% 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 |\partmarks| command will most typically go at the end of a
+% paragraph, but it may also appear inside an equation (that is, in
+% |\[...\]|; don't use |$$...$$|), inside one or other
+% \Lpackage{amsmath} display or \Lenv{equation} environments, or in
+% a list or other environment. If it appears
+% inside an environment, the indicator will appear at the
+% \emph{end} of the environment, independent of where in the
+% environment the command was typed (which implies that you can't
+% have more than one inside an environment). The alignment of
+% the partmarks indicator is not currently as good as I'd like it
+% to be, in the case of \Lpackage{amsmath} alignments, but this
+% turns out to be hard to improve.
+%
+% The starred version is similar, but budges its indicator upwards
+% a little, and is a heuristic alternative which is useful in some
+% cases \emph{after} a list or display, if the placement of the
+% indicator is otherwise inaesthetic
+% (if the style of the part-marks indicators happens to be such
+% that the indicator may be mistaken for an equation number, then
+% it would be wise to use either |\partmarks| or |\partmarks*|
+% after the equation, instead). If you use |\partmarks*| within a
+% display, you might be confronted by an error message, talking
+% about |\eqno| in maths mode, which is even more incomprehensible
+% than most \LaTeX\ messages.
%
% 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.
%
+% The |\partmarks| command has an optional argument which
+% indicates the category of the question, thus `bookwork', `unseen',
+% and so on. If this is present, then the category is included in the
+% marks indicator.
+%
+% The |\partmarks| category/comment will typically be only one or two words
+% long, and can sit comfortably in the margin. If an author wants to
+% write more here, then it will be turned into a footnote on the
+% page. This will obviously change the layout of the page, though
+% since this text appears only in \Lopt{showsolutions} mode, that
+% shouldn't be a problem.
+%
+% \DescribeMacro{\defaultpartmarkscategory}
+% If the exams convener wishes to \emph{oblige} people to
+% include such a category, then they might call
+% |\defaultpartmarkscategory{category?}| in a package-options (|.clo|)
+% file, to default the category with a highlighted remark to the question setter.
+%
% \DescribeMacro{\comment}
% \cmd|\comment{<text>}| associates a comment with a part of the text.
% This is ignored in \Lopt{final} mode, but appears in the margin in the
@@ -585,11 +611,10 @@
% 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
+% friends (see \secref{s:othercommands}) to set the degree names
% appropriately.
%
% \DescribeMacro{\universitycoursecode}
-% \DescribeMacro{\schoolcoursecode}
% \DescribeMacro{\degreedescriptions}
% \DescribeMacro{\coursetitle}
% Declare the identity of the exam with
@@ -600,11 +625,6 @@
% 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]
@@ -623,6 +643,13 @@
% |\rubric|) are suppressed. The layout may end up looking a little
% funny.
%
+% \DescribeMacro{\schoolcoursecode}
+% There is also a command |\schoolcoursecode|, which is a more
+% informal, but possibly 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. Its use is optional.
+%
% \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
@@ -645,7 +672,7 @@
% 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\}}
+% \cmd|\examtime{9.30am -- 12 noon\\ (or) 9.30am -- 1.45am}|.
%
% \DescribeMacro{\rubric}
% \DescribeMacro{\norubric}
@@ -666,6 +693,12 @@
% You will typically not have to change this, but if you do for some
% reason, you can override it with the |\baserubric| command.
%
+% Note that the |\baserubric| command is typically used within a |.clo|
+% file, within the argument to |\OverrideFormatting|. If you wish to
+% further override this on a per-exam basis, then you will need to do
+% so after |\OverrideFormatting| has done its work, and thus
+% immediately after the |\begin{document}|.
+%
% \DescribeMacro{\numquestions}
% Finally, declare the number of questions which are to be in the
% paper with |\numquestions|.
@@ -711,6 +744,13 @@
% There is analogous support for partial derivatives with |\Partial|.
%
% \DescribeMacro{\units}
+% You should generally type units, and numbers with units, using
+% the \Lpackage{siunitx} package, which is loaded by the
+% \Lopt{siunitx} option (which is now enabled by default). However
+% this class currently also supports a basic |\units| command,
+% described below. This macro will be removed in a future version
+% of the class.
+%
% 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
@@ -719,19 +759,20 @@
% $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.
+% qualifying a number.
%
-% For other useful symbols, see table~\ref{t:symbols}.
+% \def\cs#1{$\backslash$\texttt{#1}}
+% For other useful symbols, see table~\ref{t:symbols}.\footnote{The
+% package used to support an \cs{au} macro, for astronomical
+% unit, and \cs{lambdabar} for Compton wavelength, but these have
+% since been removed. The former is available via
+% \Lpackage{siunitx}.}
%
% \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
@@ -741,7 +782,7 @@
% \section{Customising the exam style}
% \label{s:custom}
%
-% As described in section~\ref{s:options} above, any unrecognised
+% As described in \secref{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
@@ -751,7 +792,7 @@
% 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.
+% See the sample file |myclass.clo| for examples.
%
% Examine this sample \file{SpecialExam.clo} file:
% \begin{verbatim}
@@ -817,13 +858,32 @@
% 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
+% described in \secref{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.
%
+% \DescribeMacro{\CheckExamMetadata}
+% One of the things you may change within the |\maketitle| is the
+% checking of exam metadata -- which fields are required and which are
+% optional. You can change these from the default (in
+% \secref{s:preamble}) by defining a command |\CheckExamMetadata|.
+% \DescribeMacro{\RequiredMetadata}
+% This macro takes no arguments, and should use the command
+% \cmd|\RequiredMetadata{<field>}{<description>}{<help-text>}| to
+% perform its tests.
+% {\catcode`\<=\active Here <field> is the metadata key, such as
+% |{examdate}|, which corresponds to the macro |\examdate|, <description> is
+% a brief description of the field, such as |{exam date}|, and
+% <help-text> is a longer bit of explanation. If the corresponding
+% data is missing, then \LaTeX\ stops with an error, and the user can
+% examine the <help-text> by pressing the \texttt h key. You can
+% adjust the test by examining the value of
+% |\iffussydescription ... \fi|, which is set to |\false| if the \Lopt{sloppydescription}
+% option was provided.}
+%
% 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.
@@ -944,12 +1004,11 @@ $\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.
+follows a circular orbit of period 2.986 days and radius \SI{0.038}{\astronomicalunit}.
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$].
+[Schwartzschild radius of the Sun: \SI{3e3}m; $\SI1\astronomicalunit = \SI{1.5e11}m$]
\begin{solution}
In the first type of calculation, we do a calculation in the LIF, in
@@ -987,6 +1046,12 @@ have a clue.
%</example>
% \end{macrocode}
%
+% \section{Release notes}
+% Recent release notes are below. For older notes, see the source
+% distribution.
+%
+% \input{release-notes.dtx}
+%
% \subsection*{Acknowledgements}
% \addcontentsline{toc}{subsection}{Acknowledgements}
%
@@ -998,6 +1063,26 @@ have a clue.
% \section{Implementation}
%
+% \subsection{\LaTeX3 compatibility}\label{s:compatibility}
+%
+% As of release 1.4.0, we depend on the \LaTeX3 hooks mechanism, which
+% was introduced in 2020. We therefore cannot work with versions
+% older than that.
+%
+% Note that we can't use the (apparently preferable)
+% |\IfFormatAtLeastTF| command to do this test: we want to continue to
+% work even when we're using a \LaTeX\ which is too old for this
+% command to be defined.
+% \begin{macrocode}
+\@ifl@t@r\fmtversion{2020/10/01}
+ {\typeout{Format is \fmtversion -- OK!}}
+ {\ClassError{exam-n}
+ {You need a more recent version of LaTeX}
+ {This class now requires a
+ LaTeX version at least 2020/10/01; version
+ \fmtversion\ is too old}}
+% \end{macrocode}
+%
% \subsection{Options}
%
% First, process the compose/draft/final option.
@@ -1031,13 +1116,33 @@ have a clue.
% 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
+% on the \texttt{TEXINPUTS} path such as \texttt{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}
+\DeclareOption{stix2}{\@psfontstrue\examn@mtselect=3}
+% \end{macrocode}
+%
+% The letter $\pi$ is usually the circular constant, and as such
+% should be set in an upright greek font. Don't this by default,
+% since that goes against the usual \LaTeX\ default, but instead
+% define the [uprightpi] option to support this, where possible.
+% Not all fonts make this easy.
+% \begin{macrocode}
+\newif\ifexamn@uprightpi \examn@uprightpifalse
+\DeclareOption{uprightpi}{\examn@uprightpitrue}
+% \end{macrocode}
+%
+% Load the \Lpackage{siunitx} package, or not, defaulting yes.
+% This is now preferred to the |\units| macro, and the latter will be
+% removed in a forthcoming release.
+% \begin{macrocode}
+\newif\ifexamn@siunitx \examn@siunitxtrue
+\DeclareOption{siunitx}{\examn@siunitxtrue}
+\DeclareOption{nosiunitx}{\examn@siunitxfalse}
% \end{macrocode}
%
% Switch between serif and sans serif fonts. We make little attempt
@@ -1109,12 +1214,12 @@ have a clue.
% \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
+% the required exam metadata is provided. Failing this, we object, fatally, to
% missing information.
% \begin{macrocode}
-\newif\if@fussydescription
-\@fussydescriptiontrue
-\DeclareOption{sloppydescription}{\@fussydescriptionfalse}
+\newif\iffussydescription
+\fussydescriptiontrue
+\DeclareOption{sloppydescription}{\fussydescriptionfalse}
% \end{macrocode}
%
% The university logo is typeset in colour by default; the \Lopt{mono}
@@ -1127,7 +1232,7 @@ have a clue.
% \begin{macrocode}
\def\examn@header@shoutformat#1{{\Large\bfseries #1}}
\DeclareOption{mono}{
- \PassOptionsToPackage{monochrome}{color}
+ \PassOptionsToPackage{monochrome}{xcolor}
\def\examn@header@shoutformat#1{{\Huge\bfseries #1}}
}
\DeclareOption{colour}{}
@@ -1137,13 +1242,16 @@ have a clue.
% 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
+% 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';
+% The flag |\ifbigfont| is true if the font is `significantly large',
+% in the sense that exam text, or hyphenation or layout, may have to
+% be adjusted in this case:
% option \Lopt{hugefont} sets it true, option \Lopt{largefont} does
-% not; it's intended to be a user-visible and -settable flag.
+% 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}
@@ -1174,10 +1282,20 @@ have a clue.
\@styleoverrides={}
\def\OverrideFormatting{\@styleoverrides=}
% \end{macrocode}
+%
+% There are a few other settings which may be defaulted within a
+% \file{.clo} file:
+% \begin{itemize}
+% \item |\constantsheet{...}|: is a table of, for example, physical
+% constants which should appear in exams associated with a particular
+% course. Despite the name, this can be any text which should appear
+% on the first non-cover sheet of the exam.
+% \item |\baserubric|: a modified `base rubric' -- see the
+% documentation of |\rubric| below.
+% \end{itemize}
+%
% 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.
+% .clo file), then display it on a page by itself.
% \begin{macrocode}
\newtoks\@constantstoks
\def\@@displayconstants{%
@@ -1198,6 +1316,38 @@ have a clue.
\@constantstoks=}
% \end{macrocode}
%
+% Similarly for the |\baserubric| and |\rubric| commands.
+%
+% 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}
+% \end{macrocode}
+% \dots and the base rubric:
+% \begin{macrocode}
+\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}
+%
+% The |\defaultpartmarkscategory| macro creates a default partmarks
+% `category'. See below. This is declared here, so that it can be
+% used in a |.clo| file without error.
+% \begin{macrocode}
+\let\examn@defaultpartmarkscategory\relax
+\def\defaultpartmarkscategory#1{\def\examn@defaultpartmarkscategory{#1}}
+% \end{macrocode}
+%
% Spit out the style overrides at the beginning of the document,
% rather than here.
% \begin{macrocode}
@@ -1279,11 +1429,23 @@ have a clue.
\hrule}}
% \end{macrocode}
%
-% Other required packages
+% Other required packages.
% \begin{macrocode}
\RequirePackage[english]{babel} % UK hyphenation
\RequirePackage{amsmath}
-\RequirePackage{color}
+\ifexamn@siunitx
+ \RequirePackage{siunitx}
+\fi
+% \end{macrocode}
+% We use the \Lpackage{xcolor} package, in preference to
+% \Lpackage{color}, so that we are compatible with TikZ (TikZ loads
+% the \Lpackage{xcolor} package internally, and that isn't compatible
+% with \Lpackage{color}). We could probably work around this some
+% other way, but \Lpackage{xcolor} seems to be relatively standard,
+% and appears to be backward compatible with \Lpackage{color},
+% so this change is harmless.
+% \begin{macrocode}
+\RequirePackage{xcolor}
% \end{macrocode}
%
% I think flush-left equations look MUCH better than centred, but
@@ -1294,74 +1456,52 @@ have a clue.
%
% \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
+% \subsubsection{The \TeX\ engine}
+% Identify the \TeX\ engine we're using. If we are using pdf\TeX,
+% Xe\TeX, or Lua\TeX, we presume we're generating PDF. The
+% \Lpackage{ifpdf} package exists, and evaluates to true for Lua\TeX,
+% but doesn't distinguish between Xe- and Lua\TeX.
+% It would be nice to use a package such as \Lpackage{iftex}, but (as of late
+% 2017) this seems to do something sufficiently exotic with
+% respect to |\if| nesting, that it confuses the logic here.
+% It seems safer to do this test ourselves, so (a) we know what
+% we're getting, and (b) we have the result in a convenient integer form.
+% \begin{macrocode}
+\newcount\examn@engine
+\examn@engine=0
+\expandafter\ifx\csname pdfmatch\endcsname\relax
+ \expandafter\ifx\csname XeTeXinterchartoks\endcsname\relax
+ \expandafter\ifx\csname directlua\endcsname\relax
+ \examn@engine=0 % this is presumably original-TeX (how unutterably retro!)
+ \else
+ \examn@engine=3
\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
+ \else
+ \examn@engine=2
\fi
-}
-\AtBeginDocument{\examn@setdocident\@SetDocumentInfo}
+\else
+ \ifnum\pdfoutput>0
+ \examn@engine=1
+ \else
+ % this _is_ pdftex, but it's in generate-dvi mode
+ % (we decide not to detect this case with the other engines)
+ \examn@engine=0
+ \fi
+\fi
% \end{macrocode}
%
+% \subsubsection{Fonts}
+%
% Choose the font set, based on |\if@psfonts| and |\examn@mtselect|.
+% The following is \emph{messy}, and it's not clear to me if it's
+% irreducibly so, or whether I'm just doing it the wrong way.
+%
+% Case |\examn@mtselect| is 0: the rather hacky \Lpackage{mathptm} solution.
% \begin{macrocode}
+\def\ex@fontlabel{???}
\if@psfonts
\ifcase\examn@mtselect
+ \def\ex@fontlabel{mathptm}
\ifexamn@serif
\RequirePackage{times}
\else
@@ -1369,7 +1509,14 @@ have a clue.
\fi
\RequirePackage{mathptm}
\ClassWarningNoLine{exam-n}{Using mathptm fonts}
- \or % use mathtime fonts
+% \end{macrocode}
+%
+% Case |\examn@mtselect| is 1 or 2: use mathtime or Mathtime Pro 2 fonts
+% for maths. We use postscript Times and Helvetica for the body fonts
+% in both cases.
+% \begin{macrocode}
+ \or
+ \def\ex@fontlabel{mathtime}
\RequirePackage[LY1]{fontenc} % specify text font encoding
\RequirePackage[LY1,mtbold]{mathtime} % switch math fonts
\ifexamn@serif
@@ -1379,6 +1526,7 @@ have a clue.
\fi
\ClassWarningNoLine{exam-n}{Using Mathtime fonts}
\or % use mtpro2 fonts
+ \def\ex@fontlabel{mtpro2}
\RequirePackage[T1]{fontenc}
\RequirePackage{textcomp}
\ifexamn@serif
@@ -1389,13 +1537,103 @@ have a clue.
\fi
\RequirePackage[mtpbb]{mtpro2}
\ClassWarningNoLine{exam-n}{Using MTPro2 fonts}
+% \end{macrocode}
+%
+% Finally, case |\examn@mtselect| is 3: use STIX2 fonts: \url{http://www.stixfonts.org}.
+% Since this requires fontspec, it also requires either XeLaTeX or
+% LuaLaTeX. If we are in this branch, and not using either
+% engine, then fail with what we hope is a reasonably clear error.
+%
+% First off, refuse to work with original TeX.
+% \begin{macrocode}
+ \or
+ \def\ex@fontlabel{stix2}
+ \ifcase\examn@engine
+ \ClassError{exam-n}
+ {You can't use STIX fonts with original/DVI LaTeX}
+ {You must use either XeLaTeX or LuaLaTeX}
+% \end{macrocode}
+%
+% Use of the STIX fonts with pdflatex mostly works, but there is a
+% tricky current/legacy issue here.
+% The \Lpackage{stix2} package is intended to use the STIX2
+% fonts with `legacy' \TeX\ engines. Does this apply to pdflatex, now
+% it defaults to unicode input? See the discussion of
+% \Lpackage{unicode-math} below.
+%
+% As of TeXLive 2022, this mostly works, in the sense that we do use STIX
+% fonts, but the upright-pi support below fails (no LaTeX errors, but
+% |\uppi| produces slanted pi).
+% \begin{macrocode}
+ \or % pdflatex
+ \RequirePackage{stix2}
+% \end{macrocode}
+%
+% We support only Xe\TeX\ and Lua\TeX\ here, since only these can use
+% `system' fonts. For Xe\LaTeX\ we use `system' Helvetica and Courier
+% fonts (slightly scaled) as the sans and mono fonts, respectively, for the sake of
+% completeness.
+%
+% Note: unicode-math is a little complicated. As I (unfortunately)
+% discovered via mistaken bug report
+% \url{https://github.com/stipub/stixfonts/issues/235},
+% the \Lpackage{stix} package is intended to be used \emph{only} for
+% `legacy' \TeX\ engines, and \Lpackage{unicode-math} for current ones
+% such as Xe\LaTeX\ and Lua\LaTeX.
+% I'm fairly confident (as of 2022 July 11) that the following does
+% the right thing, but not yet 100% confident.
+%
+% Note that (as explained in the \Lpackage{unicode-math} manual, we
+% should use the STIX Two \emph{Math} font for symbols, and not the
+% text font.
+% \begin{macrocode}
+ \or % XeLaTeX
+ \RequirePackage[bold-style=ISO,math-style=ISO]{unicode-math}
+ \setmathfont{STIX Two Math}
+ \setmainfont{STIX Two Text}
+ \or % LuaLaTeX: like XeLaTeX
+ \RequirePackage[bold-style=ISO,math-style=ISO]{unicode-math}
+ \setmathfont{STIX Two Math}
+ \setmainfont{STIX Two Text}
+ \fi
+% \end{macrocode}
+% The no-match case shouldn't happen.
+% \begin{macrocode}
\else
- \ClassError{exam-n}{Impossible value of mtselect: \examn@mtselect}
+ \def\ex@fontlabel{ERROR}
+ \ClassError{exam-n}
+ {Impossible value of mtselect: \examn@mtselect}
+ {This shouldn't happen -- this is a class file bug}
\fi
+% \end{macrocode}
+%
+% There are no font complications when using CM fonts. That's nice.
+% \begin{macrocode}
\else
+ \def\ex@fontlabel{CM}
\ClassWarningNoLine{exam-n}{Using CM fonts}
\fi
% \end{macrocode}
+%
+% Report what engine and font configuration we're using.
+% \begin{macrocode}
+\typeout{Environment:
+ engine: \ifcase\examn@engine original/DVI\or pdfTeX\or XeTeX\or LuaTeX\else ???\fi;
+ fonts: \ex@fontlabel;
+ options: % show any non-default options
+ \ifexamn@uprightpi uprightpi, \fi
+ \ifexamn@siunitx siunitx, \fi
+ \ifexamn@serif\else noserif, \fi
+ \if@pageperquestion pageperquestion, \fi
+ \if@perquestionmarks\else noperquestionmarks, \fi
+ \if@showmarktotals\else noshowmarktotals, \fi
+ \if@twosidepages twoside, \fi
+ \if@fleqn fleqn, \fi
+ \iffussydescription\else sloppydescription, \fi
+ \ifbigfont hugefont, \fi
+ \if@showsolutions showsolutions\else noshowsolutions\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|.
@@ -1415,6 +1653,14 @@ have a clue.
% \begin{macrocode}
\ifcase\examn@fontvariant
% default: do nothing
+ \def\examn@bodyfontchange{
+ % ...apart from redefine \small to be more clearly distinct from \normalsize
+ \renewcommand\small{%
+ \@setfontsize\normalsize{9}{11}%
+ \abovedisplayskip 9\p@ \@plus1.5\p@ \@minus5\p@
+ \abovedisplayshortskip \z@ \@plus2.5\p@
+ \belowdisplayshortskip 5\p@ \@plus2.5\p@ \@minus2.5\p@
+ \belowdisplayskip \abovedisplayskip}}
\or
% font variant 1: 18pt
\def\examn@bodyfontchange{
@@ -1425,6 +1671,12 @@ have a clue.
\belowdisplayshortskip 10\p@ \@plus5\p@ \@minus5\p@
\belowdisplayskip \abovedisplayskip
\let\@listi\@listI}
+ \renewcommand\small{%
+ \@setfontsize\normalsize{12}{16}%
+ \abovedisplayskip 12\p@ \@plus2\p@ \@minus6\p@
+ \abovedisplayshortskip \z@ \@plus4\p@
+ \belowdisplayshortskip 6.5\p@ \@plus3\p@ \@minus3\p@
+ \belowdisplayskip \abovedisplayskip}
\parindent=24pt
\parskip=18pt
% Redefine \FormatPartMarks so that it doesn't push the text off the paper
@@ -1440,6 +1692,12 @@ have a clue.
\belowdisplayshortskip 21\p@ \@plus10.5\p@ \@minus10.5\p@
\belowdisplayskip \abovedisplayskip
\let\@listi\@listI}
+ \renewcommand\small{%
+ \@setfontsize\normalsize{24}{28}%
+ \abovedisplayskip 24\p@ \@plus5\p@ \@minus12\p@
+ \abovedisplayshortskip \z@ \@plus8\p@
+ \belowdisplayshortskip 14\p@ \@plus8\p@ \@minus8\p@
+ \belowdisplayskip \abovedisplayskip}
\parindent=48pt
\parskip=36pt
% Redefine \FormatPartMarks so that it doesn't push the text off the paper
@@ -1466,6 +1724,79 @@ have a clue.
\fi}
% \end{macrocode}
%
+% Adjust maths font sizes for the various cases:
+% \begin{macrocode}
+\DeclareMathSizes\@xiipt{12}{9}{7}
+\DeclareMathSizes\@xipt{10}{8}{6}
+% \end{macrocode}
+%
+% \subsubsection{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.
+%
+% 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).
+% \begin{macrocode}
+\def\examn@setdocident{%
+ \begingroup
+ \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}
+%
+% Add information to the PDF document metadata.
+% \begin{macrocode}
+\ifcase\examn@engine
+ \let\@SetDocumentInfo\relax % original TeX
+\or % pdfTeX
+ \def\@SetDocumentInfo{\pdfinfo{/Title (\examn@docident)}}%
+ % Don't put out an /Author(xxx) info entry -- there may be
+ % multiple authors, and it isn't obviously useful
+\or % XeTeX
+ % dvipdfm special -- see the dvipdfm manual
+ \def\@SetDocumentInfo{\special{pdf: docinfo << /Title (\examn@docident) >>}}%
+\or % LuaTeX
+ % from the LuaTeX manual
+ \def\@SetDocumentInfo{\pdfextension info {/Title (\examn@docident)}}%
+\fi
+\AtBeginDocument{\examn@setdocident\@SetDocumentInfo}
+% \end{macrocode}
+%
% \subsubsection{Exam metadata}
%
% \begin{macrocode}
@@ -1508,25 +1839,6 @@ have a clue.
\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
@@ -1623,7 +1935,10 @@ images may not be used in examinations without prior arrangement.
%% headheight=\the\headheight, headsep=\the\headsep, topmargin=\the\topmargin}
\marginparsep=0.5cm
}
-
+% \end{macrocode}
+% In the \Lopt{draft} case, we nudge the text block to the side, to
+% give a larger margin.
+% \begin{macrocode}
\ifnum\@draftstatus > 0
\@settextblock{2cm}
\else
@@ -1660,7 +1975,7 @@ images may not be used in examinations without prior arrangement.
% |begingroup |ttfamily
% \catcode`\{=12 \catcode`\}=12 \catcode`\\=12
% |noindent \newcommand\FormatPartNumber{|linebreak
-% |noindent|quad\hbox to 2em{(\StylePartNumber{partnumber})\hss}}
+% |noindent|null|quad\hbox to 2em{(\StylePartNumber{partnumber})\hss}}
% |endgroup
% \end{quotation}
% works adequately as a part number,
@@ -1782,7 +2097,7 @@ images may not be used in examinations without prior arrangement.
\fancyhead[C]{\examn@bighead{\highlighted{DRAFT + SOLUTIONS, p\thepage/\pageref{lastpage}}}}
\else
\fancyhead[C]{\examn@bighead{\highlighted{DRAFT, p\thepage/\pageref{lastpage}}}}
- \fi
+ \fi
\else
\if@showsolutions
% Add a very prominent banner
@@ -1805,8 +2120,9 @@ images may not be used in examinations without prior arrangement.
%
% \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|
+% Define a special page style for the title page.
+%
+% There is 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}
@@ -1817,53 +2133,52 @@ images may not be used in examinations without prior arrangement.
% \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}
+\def\RequiredMetadata#1#2#3{
+ \expandafter\ifx\csname @#1\endcsname\@empty
+ \ClassError{exam-n}{#2}{#3 (command \@backslashchar #1)}
+ \else
+ \typeout{#1 check OK}
+ \fi}
+% \end{macrocode}
+% Define a |\CheckExamMetadata| test, but only if the macro wasn't defined in a |.clo| file.
+% \begin{macrocode}
+\@ifundefined{CheckExamMetadata}{
+ \def\CheckExamMetadata{
+ % First, data which is always required
+ \RequiredMetadata{examdate}
+ {No exam date given}
+ {Specify an exam date}
+ \RequiredMetadata{examtime}
+ {No exam time given}
+ {Specify an exam time}
+ \RequiredMetadata{exambanner}
+ {No exam banner given}
+ {Specify an exam banner (eg Examination for the degree...)}
+ \iffussydescription
+ % The following tests can be skipped by using the option [sloppydescription]
+ \RequiredMetadata{universitycoursecode}
{No paper title given}
- {Specify a university course code (eg PHYS3031) using \protect\universitycoursecode}
- \fi
- \ifx\@coursetitle\@empty
- \ClassError{exam-n}
+ {Specify a university course code (eg PHYS3031)}
+ \RequiredMetadata{coursetitle}
{No course title given}
- {Specify a course title (eg Quantum Mechanics) using \protect\coursetitle}
- \fi
- \ifx\@degreedescriptions\@empty
- \ClassError{exam-n}
+ {Specify a course title (eg Quantum Mechanics)}
+ \RequiredMetadata{degreedescriptions}
{No paper subject given}
- {Specify a 'degree description' (eg Physics 3) using \protect\degreedescriptions}
- \fi
- \ifx\@rubric\@empty
- \ClassError{exam-n}
+ {Specify a 'degree description' (eg Physics 3)}
+ \RequiredMetadata{rubric}
{No rubric given}
- {Specify a rubric using \protect\rubric, or declare its absence with \protect\norubric}
- \fi
+ {Specify a rubric, or declare its absence with \protect\norubric}
\fi
+ }}{}
+% \end{macrocode}
+% Start the |\maketitle| command.
+% First, handle the 'final' or 'draft' versions.
+% \begin{macrocode}
+\renewcommand\maketitle{
+ \ifnum\@draftstatus < 2 % final or draft version
+ \CheckExamMetadata
% \end{macrocode}
% All OK so far\dots. Now produce the actual text.
% \begin{macrocode}
@@ -2073,6 +2388,8 @@ images may not be used in examinations without prior arrangement.
%
% \subsection{Structuring commands}
%
+% \subsubsection{Sections}
+%
% Define simple sectioning commands. We also check that these aren't
% inside questions.
% \begin{macrocode}
@@ -2143,6 +2460,7 @@ images may not be used in examinations without prior arrangement.
\@starttoc{toc}}
% \end{macrocode}
%
+% \subsubsection{Questions and solutions}
% Counters:
% \begin{macrocode}
\newcount\marktotal % number of marks accumulated so far
@@ -2155,9 +2473,17 @@ images may not be used in examinations without prior arrangement.
% within a question. It's a \LaTeX\ counter, so we can use |\roman|.
%
% We override the \Lenv{article} |\part| command.
+%
+% FIXME:
+% We would like to use |\StylePartNumber| here, but can't, because
+% that's defined as being eg |\alph|, and not |\@alph|. To change
+% this, we'll have to retire |\StylePartNumber|, in favour of saying
+% that, to change the formatting here, it's merely necessary to
+% redefine |\thepartnumber|.
% \begin{macrocode}
\newcounter{partnumber}
-\renewcommand\part{%
+\renewcommand\thepartnumber{\thequestionnumber\@alph\c@partnumber}
+\renewcommand\part[1][]{%
\if@nobreak \else
\par
\@nobreakfalse
@@ -2166,14 +2492,28 @@ images may not be used in examinations without prior arrangement.
\vskip 0pt plus 4\bigskipamount
\penalty-50
\fi
- \stepcounter{partnumber}%
- \noindent\FormatPartNumber
+ \def\@tempa{#1}%
+ \ifx\@tempa\@empty
+ \refstepcounter{partnumber}%
+ \noindent\FormatPartNumber
+ \else
+ \noindent\FormatPartNumber[#1]%
+ \fi
}
% \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}}
+\newcommand\FormatPartNumber[1][]{%
+ \def\@tempa{#1}%
+ \hbox to \parindent{(%
+ \ifx\@tempa\@empty
+ \StylePartNumber{partnumber}%
+ \else
+ \@tempa
+ \fi
+ )\hss}%
+}
% \end{macrocode}
% And by default we use alphanumeric counters for parts (we abstract
% this, rather than simply including |\alph| in the definition of
@@ -2235,102 +2575,355 @@ images may not be used in examinations without prior arrangement.
}
% \end{macrocode}
%
+% \subsubsection{Partmarks}
+%
% |\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
+% |\partmarks*| is used only 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.
+%
+% It's also permissible to use |\partmarks| in the solution, to
+% indicate precisely where marks accrue. It's reasonable for this to
+% be more fine-grained than in the question. We don't check that the
+% partmarks in the solution add up to the mark goal.
+%
+% Manage the partmarks comments as the contents of a zero-width hbox,
+% which is sized to fit reasonably well in the margin. We insert this
+% into the output just before formatting the partmarks.
+%
+% The |\defaultpartmarkscategory| macro creates a default partmarks
+% `category'. If this is something like |{category?}|, then this
+% should prompt question authors to indicate the category in each call
+% to |\partmarks|. This can be declared within a |.clo| option file
+% (and is declared above, so that it can be read from there without error).
+%
+% Below, we must add the footnote text after the end of the paragraph,
+% otherwise this inserts vertical mode material, which causes a
+% linebreak, at least in the case where the last line is almost full.
+% Because we are using the hook mechanism, this package now depends on
+% the expl3 modules, and thus on TeXLive versions which aren't too old
+% (how old is too old? I'm not sure, but I expect TeXLive 2020 is new enough).
+% \begin{macrocode}
+\newbox\examn@partmarkscomment
+\def\examn@makepartmarkscomment#1{%
+ \setbox0=\hbox{\small #1}%
+ \ifdim\wd0 < 3\marginparwidth % let shortish comments wrap here
+ \setbox\examn@partmarkscomment=\hbox to 0pt{\hbox{%
+ \vtop to 0pt{%
+ \hsize=\marginparwidth
+ \parindent=0pt
+ \parskip=0pt
+ \leftskip=1em % 1em matches the hskip in default \FormatPartMarks
+ \rightskip=0pt plus 0.5\marginsize
+ \hangindent=2em \hangafter=-1
+ \small
+ #1\vss}}\hss
+ }%
+ \else
+ \stepcounter\@mpfn
+ \protected@xdef\@thefnmark{\thempfn}%
+ \@footnotetext{#1}%
+ % 3em matches the \leftskip+\hangindent above
+ \setbox\examn@partmarkscomment=\hbox to 0pt{%
+ \hskip3em\highlighted{\small [comment \thempfn]}\hss}%
+ \fi
+ }
+\def\examn@getpartmarkscomment{%
+ \ifhbox\examn@partmarkscomment
+ \box\examn@partmarkscomment
+ \fi}
+% \end{macrocode}
+% Now, finally, define the actual |\partmarks| command.
% \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
+% Check whether there's an optional (comment/category) argument,
+% enclosed in |[...]|.
+% \begin{macrocode}
+\def\@partmarks{%
+ \@ifnextchar[%]
+ \@@partmarks{\@@partmarks[]}}
+% \end{macrocode}
+% 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{%
+\def\@@partmarks[#1]#2{%
\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
+ \@@partmarks@solution{#1}{#2}%
+ \else
+ \@@partmarks@question{#1}{#2}%
+ \fi
+ \else
+ \ClassError{exam-n}{\string\partmarks\ is not compatible with
+ noperquestionmarks}{Either remove \string\partmarks\ or remove
+ the noperquestionmarks option}
+ \fi
+}
+% \end{macrocode}
+%
+% Finally, implement the two partmarks variants for questions and solutions.
+%
+% The |\@@partmarks@endenv| command is called when |\partmarks| is
+% invoked within an environment, and is used to add a suitable vbox to
+% an after-environment hook.
+%
+% First prepare the vbox that's to be inserted, and then work out how
+% to place it. The |\vskip\baselineskip| in the |\@partmarksbox| is
+% to better position the box relative to where it ends up in the
+% vertical list, and the value has a large heuristic element.
+% \begin{macrocode}
+\newbox\@partmarksbox
+\def\@@partmarks@endenv@display{\@tempswatrue\@@partmarks@endenv@common}
+\def\@@partmarks@endenv@nodisplay{\@tempswafalse\@@partmarks@endenv@common}
+\def\@@partmarks@endenv@common#1{%
+ \ifvbox\@partmarksbox % ooops -- been here before: two \partmarks in one env
+ \ClassError{exam-n}
+ {Two partmarks commands in one environment! First one IGNORED!}
+ {You can (currently) have only one partmarks command per environment}
+ \fi
+ \global\setbox\@partmarksbox=\vbox to 0pt{\vss
+ \hbox to \textwidth{%
+ \strut\hfill
+ \examn@getpartmarkscomment
+ \FormatPartMarks{#1}}%
+ \vskip\baselineskip}%
+ %\dp\@partmarksbox=0pt
+% \end{macrocode}
+% Test whether we have the |{question}| environment as our immediate
+% container, as opposed to being in an inner environment.
+% \begin{macrocode}
+ \def\@tempa{question}%
+ \ifx\@tempa\@currenvir
+ \setbox1=\vbox to 0pt{\vss\box\@partmarksbox}%
+ \ifvmode
+ \box1
+ \else
+ \vadjust{\box1}%
+ \fi
+ \else
+% \end{macrocode}
+% Generally the \cmd|env/<env>/end| hook seems to
+% produce better results, in terms of positioning things at the end of
+% environments, but this does not work for environments
+% where the command is located inside a display (ie, in \TeX\ terms,
+% inside |$$...$$|); in these situations we have to use the
+% \texttt{.../after} hook instead. Such displays are most typically amsmath
+% alignment environments, but an \cmd|\halign| inside a display will
+% also qualify (see the discussion of `alignment displays' in \TeX
+% Book ch.19). There isn't a completely straightforward way of
+% detecting this situation (though amsmath's \cmd|\start@align| sets
+% \cmd|\xatlevel@| to be non-\cmd|\@empty|, which we take to indicate the
+% amsmath case), so we have to rely on the caller of this
+% command to invoke the \texttt{...@display} or \texttt{...@nodisplay}
+% variant appropriately.
+% \begin{macrocode}
+ \if@tempswa % display variant
+ \AddToHookNext{env/\@currenvir/after}{%
+ %\typeout{hook:endenv/display #1}%
+ \ifvmode\box\@partmarksbox
+ \else\vadjust{\box\@partmarksbox}\fi}%
+ \else
+ \AddToHookNext{env/\@currenvir/end}{%
+ %\typeout{hook:endenv/nodisplay: env/\@currenvir/end #1}%
+ \ifvmode\box\@partmarksbox
+ \else\vadjust{\box\@partmarksbox}\fi}%
+ \fi
+ \fi
+}
+% \end{macrocode}
+%
+% First, define the questions version, for appearing in the version candidates see.
+% Here, \cmd|#1| is the possibly empty `classification' text, and \cmd|#2| is the
+% number of marks. At this point |\if@tempswa| is true if we got here
+% via the \cmd|\partmarks*| variant, and false if it's the unstarred one.
+%
+% The argument |#2| must be a number: any non-number text will not
+% cause an error but will appear in the text.
+%
+% But first\dots!
+%
+% The |\partmarks| command increments a global counter, and we
+% \emph{don't} want to do this when an \Lpackage{amsmath} alignment is evaluating
+% the content in its `measuring' phase. Fortunately,
+% \Lpackage{amsmath} has an (internal) flag |\ifmeasuring@| which is
+% true in that phase, which it uses for this purpose, so make this macro a no-op in that case.
+% \begin{macrocode}
+\def\@@partmarks@question{%
+ \ifmeasuring@
+ \let\@@partmarksnext\@gobbletwo
+ \else
+ \let\@@partmarksnext\@@partmarks@question@do
+ \fi
+ \@@partmarksnext
+}
+% \end{macrocode}
+% On with the main business.
+% \begin{macrocode}
+\def\@@partmarks@question@do#1#2{%
+ \global\advance\marktotal #2
+ \let\@@partmarksnext\relax % base case
+% \end{macrocode}
+% Display the `part category', \emph{visible in the question},
+% if \Lopt{showsolutions} is true, either
+% explicitly, or implicitly as a consequence of the
+% compose/draft/final mode. It's arguable that this should be
+% dependent on the mode only, but after some discussion, it ended up
+% seeming more reasonable to tie this to \Lopt{showsolutions} directly.
+% \begin{macrocode}
+ \if@showsolutions
+ \def\@tempa{#1}%
+ \ifx\@tempa\@empty
+ \ifx\examn@defaultpartmarkscategory\relax
+ \let\examn@category\relax
\else
- \vadjust{\nointerlineskip\box0}%
+ \examn@makepartmarkscomment{\highlighted{\examn@defaultpartmarkscategory}}%
\fi
\else
- \global\advance\marktotal #1
- \if@tempswa
+ \examn@makepartmarkscomment{\highlighted{#1}}%
+ \fi
+ \fi
% \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
+%
+% If |\@tempswa|, then this is the starred form of |\partmarks|.
+% This is intended to be used only occasionally, after a display or
+% list environment, where for some reason the command can't go inside
+% the environment.
+% \begin{macrocode}
+ \if@tempswa
+ \ifdim\displaywidth>0pt
+ \ClassError{exam-n}
+ {Don't use \partmarks* inside a display}
+ {Use \partmarks inside the display, or \partmarks*
+ after it, if necessary}
% \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.
+% Else we are most likely just after an equation or just after a list
+% environment, or something similar.
+% (here and below we include some |{#2:n}| debugging code for when I,
+% inevitably, revisit this to worry about the spacing).
% \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
+ \else
+ \@@partmarks@endenv@nodisplay{#2}%{#2:1*}%
+ \fi
+% \end{macrocode}
+% We've called the unstarred version of |\partmarks|.
+% This is the more usual mode.
+% \begin{macrocode}
+ \else
+ \ifdim\displaywidth>0pt
+% \end{macrocode}
+% We're in a display, after |$$|: \TeX\ is probably (but not certainly) in
+% maths mode just now; if we're in an amsmath alignment, we're in
+% specifically inner maths mode; there are other, rarer, ways of being
+% in an `alignment display'. Additionally, and commonly, if we're in
+% an \Lenv{equation} environment now -- which we can detect because
+% that, amongst other amsmath environments, sets |\eqnsw| to be true
+% -- then we're \emph{not} in an alignment, but we \emph{are} in a
+% case where the |\eqno| technique will fail (with `You can't use
+% `eqno' in math mode.'), so catch that.
+%
+% CONSIDER: is this |\@eqnsw| test in fact the only one I have to do
+% -- is the inner math mode test equivalent? That is, is this, when
+% it comes down to it, testing the actual thing I need to test here?
+% This will require another dive into the amsmath magic.
+% \begin{macrocode}
+ \@tempswafalse
+ \ifmmode\ifinner \else \@tempswatrue \fi\fi
+ \if@tempswa
+ \if@eqnsw % not so fast... we're in an {equation}
+ \@tempswafalse
\fi
+ \fi
+ \if@tempswa
% \end{macrocode}
-% We've called the unstarred version of |\partmarks|. We also end the paragraph here
-% (this technique is filched from the TeXBook, p106).
+% We're in outer maths mode, which we can take to mean a |\[...\]| equation.
+% In this case, we can very neatly position the partmarks indicator
+% using |\eqno|.
+% \begin{macrocode}
+ \def\@@partmarksnext{\eqno \hbox to 1sp{% the \eqno argument must not be zero size
+ \examn@getpartmarkscomment
+ \FormatPartMarks{#2}%{#2:1}
+ \hss}}%
+% \end{macrocode}
+% Or we're in one or other type of display.
% \begin{macrocode}
\else
+ \def\@@partmarksnext{\@@partmarks@endenv@display{#2}}%
+ %\def\@@partmarksnext{\@@partmarks@endenv@display{#2:2,\@currenvir}}%
+ \fi
+% \end{macrocode}
+%
+% Otherwise, |\displaywidth=0pt|, and we're not in a display.
+% If we are in the |{question}| environment, as opposed to any sub-environment,
+% we end the paragraph here and put the partmarks indicator at the end
+% of the final line of the paragraph (this technique is filched from the TeXBook, p106).
+% Otherwise, we add a suitable box to an end-of-environment hook.
+%
+% Omitting the |{question}| test below, and handling all cases with
+% the end-of-paragraph technique, works in most case, in the sense of
+% looking fine. Where it fails is in the case of, eg, |{quote}|,
+% where the end-of-line ends up indented from the right.
+%
+% Using the hook has the additional advantage that |\partmarks| can be anywhere
+% within the environment and this locates it at the end.
+%
+% The dimension |\@partmarksspace| controls how much space the
+% partmarks-number takes up, the default is the special case of 0pt,
+% which puts it in the margin.
+% \begin{macrocode}
+ \else
+ \def\@tempa{question}%
+ \ifx\@tempa\@currenvir
\ifdim\@partmarksspace > 0pt
{\unskip\nobreak\hfil\penalty50 \hskip\@partmarksspace
- \hbox{}\nobreak\hfil\FormatPartMarks{#1}%
+ \hbox{}\nobreak\hfil\examn@getpartmarkscomment\FormatPartMarks{#2}%{#2:3}%
\parfillskip=0pt \finalhyphendemerits=0 \par}
\else
- \unskip\nobreak\hfill\FormatPartMarks{#1}\par
+ \unskip\nobreak\hfill\examn@getpartmarkscomment\FormatPartMarks{#2}\par%{#2:4}\par
\fi
+ \let\@@partmarksnext\relax
+ \else
+ \def\@@partmarksnext{\@@partmarks@endenv@nodisplay{#2}}%
+ %\def\@@partmarksnext{\@@partmarks@endenv@nodisplay{#2:5,\@currenvir}}%
\fi
\fi
- \else
- \ClassError{exam-n}{\string\partmarks\ is not compatible with
- noperquestionmarks}{Either remove \string\partmarks\ or remove
- the noperquestionmarks option}
\fi
+% \end{macrocode}
+%
+% The `question' variant of this macro includes an |\ignorespaces| at the
+% end, since that is generally the right thing to do (the command
+% almost always appears at the end of paragraphs, or after equations).
+% \begin{macrocode}
+ \@@partmarksnext
\ignorespaces
}
% \end{macrocode}
+% Then the solutions version, for the benefit of markers, which is
+% typically more finely itemized, and which isn't summed (ie, we don't
+% at present confirm that the marks here match the question's marks goal).
+% The solutions variant of this macro omits the |\ignorespaces|
+% (since in solutions this macro is scattered within the text).
+% Setting |\dp0=0pt| is probably unnecessary, but guarantees that box0
+% has zero depth, so no extra vertical space appears because of
+% this new box.
+% \begin{macrocode}
+\def\@@partmarks@solution#1#2{%
+ \setbox0=\vbox to 0pt{\vss
+ \hbox to \textwidth{\hfil\hbox to 0pt{\quad\small[\dots #2]\hss}}
+ \vskip0.25ex }%
+ \dp0=0pt
+ \ifvmode
+ \box0
+ \else
+ \vadjust{\nointerlineskip\box0}%
+ \fi
+}
+% \end{macrocode}
%
% The code above permits page-breaks between lists and |\partmarks|.
% That's because |\@endparenv|, which is called within |\endtrivlist|,
@@ -2340,7 +2933,6 @@ images may not be used in examinations without prior arrangement.
% \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.
@@ -2430,7 +3022,7 @@ images may not be used in examinations without prior arrangement.
% \begin{macrocode}
\def\item{\@tempswafalse\ex@mcqitem}
\def\answer{\@tempswatrue\ex@mcqitem}
-% \end{macrocode
+% \end{macrocode}
% Initialise counters, and invoke the common |\do@question| macro.
% \begin{macrocode}
\ex@mcqi=0
@@ -2863,9 +3455,15 @@ images may not be used in examinations without prior arrangement.
% \end{macrocode}
%
% The |\includequestion| command includes a question from another
-% file. For convenience, we disable |\documentclass|, |\usepackage|, and the
+% file. For convenience, we disable
+%|\documentclass|, |\usepackage|, |\RequirePackage|, and the
% \Lenv{document} environment, so that the included file may be a
% complete \LaTeX\ document.
+% We don't try too hard to support including just any old \LaTeX, here:
+% any complicated preamble requirements in an included file should
+% probably be managed by the exams convener transplanting them into
+% the preamble of the main document. This may be an overly
+% simple-minded approach, and may change in future versions.
% \begin{macrocode}
\def\dummy@documentclass{%
\@ifnextchar[\dummy@@documentclass{\dummy@@documentclass[]}}
@@ -2877,7 +3475,7 @@ images may not be used in examinations without prior arrangement.
\begingroup
\let\documentclass\dummy@documentclass
\let\document\@empty % not \relax: makes \begin think {document} is undef'd
- \let\enddocument\relax
+ \let\enddocument\endinput % stop reading, discarding any junk below \end{document}
\def\@tempa{#1}
\ifx\@tempa\@empty \else
\def\@includequestionoverridenumber{#1}
@@ -2885,6 +3483,7 @@ images may not be used in examinations without prior arrangement.
\fi
\def\usepackage##1{\ClassWarning{exam-n}
{Ignoring \string\usepackage{##1} in included question #2}}
+ \let\RequirePackage\usepackage
\input{#2}
\endgroup
}
@@ -2930,6 +3529,15 @@ images may not be used in examinations without prior arrangement.
% 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.
+%
+% Solutions are shown in a slightly smaller size (namely |\small|).
+% It's debatable whether this is a good thing or not. Note that if
+% this is changed by removing the |\small|, then
+% |\examn@dummycaptions| will have to be adjusted, too.
+%
+% If either of the `enlarged font' options has been given, then we set
+% the solutions in the same large font, since these might be
+% distributed to students as model answers.
% \begin{macrocode}
\def\@formatsolution{\par
\if@insolution
@@ -2937,7 +3545,7 @@ images may not be used in examinations without prior arrangement.
\else
\@insolutiontrue % this happens within a group
\fi
- \examn@dummycaptions % dummy captions within solutions
+ \examn@dummycaptions % dummy captions within solutions
\typeout{SHOWING SOLUTIONS}
\let\part\examn@solutionpart
% \end{macrocode}
@@ -2948,9 +3556,7 @@ images may not be used in examinations without prior arrangement.
\parskip 0.5\baselineskip
\raggedright
\color{solutiontext}%\slshape
- \ifbigfont \else
- \small
- \fi
+ \normalsize
\hrule
\hbox to \textwidth{\vrule height 1ex \hfil \vrule height 1ex}
\nobreak
@@ -2984,20 +3590,32 @@ images may not be used in examinations without prior arrangement.
\if@showsolutions
\let\solution\@formatsolution
\let\endsolution\end@formatsolution
+% \end{macrocode}
+% In the case where we're not showing solutions, note that we
+% \emph{do} format the contents, so any |\global| effects will still
+% happen, unless we take action to avoid them.
+%
+% In particular, |\part|, which is normally redefined in solutions to
+% increment \texttt{answerpartnumber} rather than
+% \texttt{partnumber}, would increment \texttt{partnumber} in answers
+% unless we take action to stop it.
+% \begin{macrocode}
\else
- \def\solution{%
+ \def\solution{% make a vbox...
+ \par
\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
+ \examn@dummycaptions % dummy captions avoid counter increments
+ \let\part\relax % make \part a no-op in discarded {solution}
\@ifundefined{includepdf}{}{\let\includepdf\examn@disabledpdfpages}
- \par
\setbox\@tempboxa\vbox\bgroup
- \@insolutiontrue}
- \def\endsolution{%
- \egroup % ...and do nothing with this box
+ \@insolutiontrue
+ }
+ \def\endsolution{%...and do nothing with this box
+ \egroup
}
\fi
% \end{macrocode}
@@ -3025,9 +3643,14 @@ images may not be used in examinations without prior arrangement.
% re-using the standard LaTeX parameter means that \caption works
\def\@captype{#1}
\setbox\@tempboxa\vbox\bgroup}
+% \end{macrocode}
+% End both |{figure}| and |{table}| environments.
+% End the |\@tempboxa| and add some space and good breaks before displaying it.
+% We're typically in hmode here, but don't depend on it.
+% \begin{macrocode}
\def\examn@endfloat{%
\egroup % end \@tempboxa
- \unskip
+ \ifvmode\else \unskip \fi % bare \unskip would can an error in vmode
\nobreak
% add lots of stretchability, but non-infinite, for the sake of tidiness
\vskip 0pt plus 0.5\textheight
@@ -3055,6 +3678,18 @@ images may not be used in examinations without prior arrangement.
\let\endfigure\examn@endfloat
\let\endtable\examn@endfloat
% \end{macrocode}
+% And disable the \texttt{figure*} and \texttt{table*} environments.
+% \begin{macrocode}
+\expandafter\def\csname figure*\endcsname{%
+ \ClassError{exam-n}
+ {Bad environment figure* -- there is no figure* environment in exam-n}
+ {Use plain {figure} instead. See the documentation for discussion}}
+\expandafter\def\csname table*\endcsname{%
+ \ClassError{exam-n}
+ {Bad environment table* -- there is no table* environment in exam-n}
+ {Use plain {table} instead. See the documentation for discussion}}
+% \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
@@ -3110,25 +3745,83 @@ images may not be used in examinations without prior arrangement.
\WriteLastPageLabel}
% \end{macrocode}
%
+% \iffalse extradefs:start
+% This is a magic comment -- see Makefile.
+% these definitions are referred to, in order to document
+% them, both in this class's documentation, and in the
+% notes-for-authors. \fi
+%
% \subsection{Other formatting niceties}
%
% Format vectors (the default for |\vec| is a symbol with an arrow
% over it):
+%
+% Note: the STIX2+(XeLaTeX/LuaLaTeX) support depends on the LaTeX hook
+% mechanism released in 2020. It therefore does not work on versions of
+% LaTeX older than that. There is a check for this above (see
+% Sect~\ref{s:compatibility}).
% \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?
+\if@psfonts
+ \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$}}}
+ \ifexamn@uprightpi
+ \ClassWarning{exam-n}{Can't do uprightpi in [mathptm] -- sorry}
+ \let\italicpi\pi
+ \examn@uprightpifalse
+ \fi
+ \or % mathtime (should this be the same for mathtime as for mtpro2?
+ \let\vec\mathbf
+ \ifexamn@uprightpi
+ \ClassWarning{exam-n}{Can't do uprightpi in [mathtime] -- sorry}
+ \let\italicpi\pi
+ \examn@uprightpifalse
+ \fi
+ \or % mtpro2
+ \let\vec\mathbold
+ % \uppi is predefined in mtpro2
+ \ifexamn@uprightpi
+ \let\italicpi\pi
+ \let\pi\uppi
+ \fi
+ \else
+ % STIX2: the unicode-math package provides a \symbf for bold math symbols,
+ \ifnum\examn@engine<2 % pdflatex
+ \let\vec\mathbf
+ % pdftex (or original tex)
+ % The following should, I think, create an upright pi, but doesn't
+ \def\uppi{\mathrm{\pi}}
+ \let\italicpi\pi %for consistency
+ \let\symup\mathrm %not fully the right thing, but avoid errors below
+ \else % xelatex or lualatex
+ % This is where the dependence on a recent LaTeX enters.
+ \let\vec\symbf
+ \typeout{stix2: upright=\ifexamn@uprightpi true\else false\fi}
+ \AddToHook{begindocument/end}{\gdef\uppi{\symup{𝜋}}}
+ \ifexamn@uprightpi
+ \AddToHook{begindocument/end}{\gdef\italicpi{\symit{𝜋}}\global\let\pi\uppi}
+ \fi
+ \fi
+ \fi
+\else
+ % CM fonts: \mathbf doesn't work with greek in CM
\let\vec\mathbf
-\or % mtpro2
- \let\vec\mathbold
+ \ifexamn@uprightpi
+ % upright greek is hard to do portably, so give up
+ % See eg https://tex.stackexchange.com/questions/145926/ for discussion
+ \ClassWarning{exam-n}{Can't do uprightpi in [cmfonts] -- sorry}
+ \let\italicpi\pi
+ \let\uppi\pi %but avoid errors
+ \examn@uprightpifalse
+ \fi
\fi
% \end{macrocode}
-% Abbreviations for degrees.
+%
+% Abbreviations for various degrees.
% \begin{macrocode}
\newcommand\BSc{B.Sc.{}}
\newcommand\MSci{M.Sci.{}}
@@ -3138,10 +3831,22 @@ images may not be used in examinations without prior arrangement.
\newcommand\BEng{B.Eng.{}}
% \end{macrocode}
%
-% Tweaks to differentials.
+% Formatting differentials, and the base of natural logs,
+% which should be in an upright font.
+% See section~\ref{s:othercommands}, or the `notes for authors',
+% for a description of these macros.
+% The macro |\ddd| is used inside an integral, and includes a leading thinspace
% \begin{macrocode}
-\newcommand{\dd}{\mathrm{d}}
-\newcommand{\ddd}{\,\mathrm{d}} % inside an integral, including thinspace
+\ifnum\examn@mtselect>2
+ % ie, STIX2, and thus using the unicode-math package (see above)
+ \def\e{\symup{e}}
+ \newcommand{\dd}{\symup{d}}
+ \newcommand{\ddd}{\,\symup{d}}
+\else
+ \def\e{\mathrm{e}}
+ \newcommand{\dd}{\mathrm{d}}
+ \newcommand{\ddd}{\,\mathrm{d}}
+\fi
\def\Diffl{\@ifstar\@Difflflat\@Diffl}
\def\Partial{\@ifstar\@Partialflat\@Partial}
@@ -3165,19 +3870,31 @@ images may not be used in examinations without prior arrangement.
\fi}
% \end{macrocode}
%
-% The exponential sign
-% \begin{macrocode}
-\def\e{{\mathrm e}}
-% \end{macrocode}
+% Physical units in upright roman. This macro is now deprecated in
+% favour of use of the \Lopt{siunitx} option (which uses the
+% \Lpackage{siunitx} package, qv), and it will be removed in a
+% minor release after v1.4.
%
-% Physical units in |\rm|. Unstarred version includes leading
-% |\thinspace|. Starred version doesn't, and is used when referring to
+% The unstarred version includes leading
+% |\thinspace|. The 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.
+% Separate units with either \texttt{.} or |~|, as in |\units{m~s^{-1}}| or
+% |\units{m.s^{-1}}|.
+% Note that although \texttt{.} and |~| are both possible unit separators in
+% general, the former won't work if used within a table (due to the timing of
+% token-reading).
+%
+% This is a rather simple-minded approach to unit formatting. For a much more
+% comprehensive treatment, see the \texttt{siunitx} package,
+% \url{https://ctan.org/pkg/siunitx}, which is now preferred, in place
+% of further use of this macro.
+%
+% Note: there are detailed prescriptions on the formatting of units and symbols in
+% ISO-80000-1:2009, Sect. 7.
% \begin{macrocode}
-\def\units{\begingroup
+\def\units{\examn@unitswarning
+ \begingroup
\catcode`\.=\active
\@ifstar{\let\un@tsspace\relax \un@ts}%
{\let\un@tsspace\thinspace\un@ts}}
@@ -3191,18 +3908,15 @@ images may not be used in examinations without prior arrangement.
\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}
+\newif\ifexamn@warnunits \examn@warnunitstrue
+\def\examn@unitswarning{\ifexamn@warnunits
+ \ClassWarning{exam-n}{The units macro will be removed in the next
+ version; the [siunitx] option is now on by default, so you can use
+ the macros in the siunits package}%
+ \global\examn@warnunitsfalse
+\fi}
+% \end{macrocode}
+% \iffalse extradefs:end % magic comment -- see Makefile \fi
%
% All done.
% \begin{macrocode}
diff --git a/Master/texmf-dist/source/latex/exam-n/release-notes.dtx b/Master/texmf-dist/source/latex/exam-n/release-notes.dtx
new file mode 100644
index 00000000000..84cde9c3a5e
--- /dev/null
+++ b/Master/texmf-dist/source/latex/exam-n/release-notes.dtx
@@ -0,0 +1,43 @@
+% \begin{description}\item[1.4.0, 2022 October 10]\relax \P\thinspace The [siunitx] option is now on by default, and the
+% |\units| macro produces a one-time-per-document
+% warning that it will be removed in the next version. \P\thinspace Having two |\partmarks| commands in an
+% environment is now detected as an error (it was documented as an
+% error, but not checked, so the extra |\partmarks|
+% commands were simply ignored).\par\item[1.4.0-b1, 2022 August 7]\relax \P\thinspace The class file now depends on a version of LaTeX which is at least
+% the 2020/10/01 release. This is so that we can use the current LaTeX
+% hooks mechanism. \P\thinspace Rework |\partmarks|: the |\partmarks|
+% indicator can now go \emph{inside} most environments, including
+% list, quotes, unnumbered equations, and the various amsmath displays. In these
+% cases, the indicator will automatically appear at the end of the
+% environment. The starred variant of the command still exists, but
+% should rarely be necessary.\par\item[1.3.5-b1, 2022 July 11]\relax \P\thinspace Fix erroneous broken line before |\partmarks|, in
+% compose mode, when a paragraph fills the last line. \P\thinspace Fix support for STIX2 fonts in XeLaTeX and LuaLaTeX (it was
+% working inaccurately before). \P\thinspace Add an optional argument for |\part| to override part numbering. \P\thinspace Use the |xcolor| package for colour management, instead
+% of the core |color| package (the |xcolor|
+% package is well-known and stable, and this means that we are
+% compatible with TikZ). \P\thinspace |\partmarks| in solutions no longer gobble trailing space
+% (doing so is probably right in questions, and is still the case, but
+% |\partmarks| in solutions tend to be more interspersed with
+% text). \P\thinspace |\label| within a |\part| now refers to the
+% part number (as opposed to the question number). \P\thinspace Avoid a ‘You can't use `\unskip' in vertical mode’ error,
+% in certain circumstances. \P\thinspace Add the |[siunitx]| option, indicating that we should
+% load the siunitx\footnote{\url{https://www.ctan.org/pkg/siunitx}} package (default no).
+% This is now preferred to the |\units| macro, and the latter will be
+% removed in a forthcoming release. \P\thinspace Renamed |A1.clo| to clearer |myclass.clo| \P\thinspace Repository moved from bitbucket to
+% https://heptapod.host/nxg/exam-n\footnote{\url{https://heptapod.host/nxg/exam-n}},
+% when bitbucket dropped support for Mercurial.
+% This means, incidentally, that links to specific issues at bitbucket
+% are now broken. \P\thinspace Bold-italic maths should now work correctly with STIX. \P\thinspace Long |\partmarks| comments now appear as footnotes. \P\thinspace Solutions are now set |\normalsize|. \P\thinspace Bugfix: move definition of |\defaultpartmarkscategory|
+% so it can be invoked within a |.clo| file straightforwardly. \P\thinspace Define the |[uprightpi]| option to set |\pi|
+% as an upright character, as appropriate for a constant (this is
+% implemented fully only for the |[mtpro2]| and
+% |[stix2]| options).. \P\thinspace Note that the |\units| macro is likely to be deprecated
+% in a forthcoming version, and replaced by a recommendation to use the
+% standard |[siunitx]| package.\par\item[1.3, 2018 November 21]\relax \P\thinspace Add a ‘category’ optional argument to |\partmarks|, and
+% add |\defaultpartmarkscategory|.\par\item[1.2.1, 2018 July 2]\relax \P\thinspace Bugfix: ignore any content which appears after
+% |\end{document}|, in |\includequestion| (author)
+% files (fixes issue 6). \P\thinspace The environments |{figure*}| and |{table*}| now produce an error. \P\thinspace The macro |\vec| now produces correct greek bold maths. \P\thinspace Docmentation: notes on unit formatting.\par\item[1.2, 2017 December 1]\relax \P\thinspace Use serif STIX2 fonts for sans and monospace cases, when using
+% Lua- or XeLaTeX (the style doesn't use/encourage any sans-serif text,
+% so this shouldn't matter). \P\thinspace Fix font sizes in solutions. \P\thinspace Adjustments to font-handling, which appear to have fixed LuaLaTeX differences. \P\thinspace Add the |stix2| option, to use the
+% STIX2 font set\footnote{\url{http://www.stixfonts.org/}}. \P\thinspace Make it possible to use |\rubric| and |\baserubric| within a |.clo| file.
+% This was advertised as being possible, but it seems it had never been tested!\par\end{description} \ No newline at end of file