%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ymexam.cls, University examination paper LaTeX 2e class file
%
% SPE 1996/04/15 -- 2010/12/14
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%
% 2e isms
%

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{ymexam}[2010/12/14]
\PassOptionsToClass{12pt,a4paper,twoside}{extarticle}
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{extarticle}}
\ProcessOptions
\LoadClass{extarticle}
\RequirePackage{etex}
\RequirePackage{amsmath}
\RequirePackage{amsfonts}
\RequirePackage{verbatim}
\RequirePackage{fancybox}
%\RequirePackage{a4wide}
\RequirePackage[headings]{fullpage}

% 
% clash between eTeX's \marks and established class macro \marks.
% 

\let\emarks=\marks
\newmarks\qmarks

%
% Tunable lengths
%

\let\emarks=\marks
\newmarks\qmarks

\newlength{\qindent}          % distance from LH margin to question
\newlength{\qlabelsep}        % space between label and item in lower-
                              % level lists
\newlength{\qskip}            % vertical space between questions
\newlength{\qparindent}       % paragraph indent inside a question
\newlength{\qparskip}         % space between paragraphs inside a question

\setlength{\qindent}{5em}
\setlength{\qlabelsep}{1em}
\setlength{\qskip}{4ex}
\setlength{\qparindent}{0pt}
\setlength{\qparskip}{1ex}

\setlength{\footskip}{6ex}

%
% Outer page layout. Not user-tunable: in normal use, everything in
% the document is in a subsidiary list environment so these parameters
% don't really apply anyway. \control is added to each new definition of
% \par generated by \@setpar; setting it to \nopagebreak stops page breaks
% between paragraphs (which \samepage allows), setting it to \relax restores
% normal behaviour.
%

\parskip=0pt
\parindent=0pt
\raggedbottom
\let\control=\relax
\def\@setpar#1{\def\par{\control#1}\def\@par{\control#1}}

% remember the last question so we can print "1 (of 4)" etc. on later passes

\newif\ifquestioncount
\questioncounttrue
\newcommand{\questioncount}{\global\questioncounttrue}
\newcommand{\noquestioncount}{\global\questioncountfalse}
\AtEndDocument{\immediate\write\@auxout{\string\gdef\string\ofcount{ (of \thequestion)}}}
\gdef\ofcount{\relax}

% facility to put page numbers in the form "1 (of 2)", by putting a standard
% LaTeX \label on the last page of questions. If solutions are present, this
% is done by the first solution environment; if not, it's done by the
% \AtEndDocument below. \ifinquestion is used to stop an extra label being 
% dropped if the solution counter is reset to zero (which happens if solutions
% are numbered within sections)

\newif\ifinquestion
\inquestiontrue
\newif\ifpagecount
\pagecounttrue
\newcommand{\pagecount}{\global\pagecounttrue}
\newcommand{\nopagecount}{\global\pagecountfalse}
\newcommand{\theqpage}{\hfil\textnormal{%
\ifpagecount Page~\fi%
\thepage~%
\ifpagecount(of~\pageref{lastqpage})\fi%
\hfil}}
\AtEndDocument{\ifnum\c@solution=0%
\ifinquestion\label{lastqpage}\global\inquestionfalse\fi\fi}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Topmatter: builds the rigidly-specified front page of the paper
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\let\thenumber\relax
\let\thetitle\relax
\let\theyear\relax
\let\thetime\relax
\let\thequestion\relax

\newif\ifresit
\resitfalse
\def\resit{\global\resittrue}
\def\noresit{\global\resitfalse}

\newsavebox{\rubricbox}
% automatically prepend R if resit is true and there's no R there already
\def\codenumber#1{\ifresit\gdef\thenumber{R\ifx R#1\else#1\fi}\else\gdef\thenumber{#1}\fi}
\def\modulenumber#1{\gdef\thenumber{#1}}
\def\title#1{\gdef\thetitle{#1}}
\def\duration#1{\gdef\thetime{#1}}
% horrible hack as I forgot that \year is a TeX primitive and
% Paul Taylor's diagrams package uses it at startup
\AtBeginDocument{\def\year#1{\gdef\theyear{#1}}}

\newenvironment{rubric}%
{\begin{lrbox}{\rubricbox}\begin{minipage}[t]{\textwidth}%
\parindent=\qparindent\parskip=\qparskip\begin{flushleft}\itshape}%
{\end{flushleft}\end{minipage}\end{lrbox}%
\global\setbox\rubricbox=\copy\rubricbox}

% for historical reasons, horribly extensive list of ways of switching the 
% different qualifications on and off

\newif\ifbabsc
\babsctrue
\def\BABSctrue{\global\babsctrue}
\def\BABSc{\global\babsctrue}
\def\babsc{\global\babsctrue}
\def\BABScfalse{\global\babscfalse}
\def\noBABSc{\global\babscfalse}
\def\nobabsc{\global\babscfalse}
\newif\ifbabscfirst
\newif\ifbabsclast

\newif\ifmmath
\mmathtrue
\def\MMathtrue{\global\mmathtrue}
\def\MMath{\global\mmathtrue}
\def\mmath{\global\mmathtrue}
\def\MMathfalse{\global\mmathfalse}
\def\noMMath{\global\mmathfalse}
\def\nommath{\global\mmathfalse}
\newif\ifmmathfirst
\newif\ifmmathlast

\newif\ifmsc
\def\MSctrue{\global\msctrue}
\def\MSc{\global\msctrue}
\def\msc{\global\msctrue}
\def\MScfalse{\global\mscfalse}
\def\noMSc{\global\mscfalse}
\def\nomsc{\global\mscfalse}
\newif\ifmscfirst
\newif\ifmsclast

\newif\ifmres
\def\MRestrue{\global\mrestrue}
\def\MRes{\global\mrestrue}
\def\mres{\global\mrestrue}
\def\MResfalse{\global\mresfalse}
\def\noMRes{\global\mresfalse}
\def\nomres{\global\mresfalse}
\newif\ifmresfirst
\newif\ifmreslast

% control whether a page is automatically thrown after the title, or if
% a short question is allowed to fit below it.

\newif\ifquestionfrontpage
\questionfrontpagefalse
\def\questionfrontpage{\global\questionfrontpagetrue}
\def\noquestionfrontpage{\global\questionfrontpagefalse}

\renewcommand{\maketitle}{%
\begin{center}%
UNIVERSITY OF YORK \\\mbox{}\\\mbox{}\\%
\ifbabsc\babscfirsttrue%
\else\ifmmath\mmathfirsttrue%
\else\ifmsc\mscfirsttrue%
\else\ifmres\mresfirsttrue%
\else\PackageError{exam}{no degree type}%
{You must declare one or more of BABSc, MMath, MSc or MRes to be true}%
\fi\fi\fi\fi%
\ifmres\mreslasttrue%
\else\ifmsc\msclasttrue%
\else\ifmmath\mmathlasttrue%
\else\babsclasttrue%
\fi\fi\fi%
%
\ifbabsc%
\ifbabsclast{BA and BSc}\else{BA, BSc}\fi%
\fi%
\ifmmath%
\ifmmathfirst\else\ifmmathlast{ and }\else{, }\fi\fi%
MMath%
\fi%
\ifmsc%
\ifmscfirst\else\ifmsclast{ and }\else{, }\fi\fi%
MSc%
\fi%
\ifmres%
\ifmresfirst\else\ifmreslast{ and }\else{, }\fi\fi%
MRes%
\fi%
\ifresit{ Resit}\fi%
\ Examinations \theyear\\
MATHEMATICS\\
\textbf{\thetitle}\mbox{}\\%
\mbox{}\\%
Time Allowed: \thetime.%
\mbox{}\\
\end{center}%
\usebox{\rubricbox}%
\vspace{\qskip}%
%
\ifx\theyear\relax\PackageError{exam}{Missing year}%
{You haven't specified the year of the paper: put \string\year{1997}%
\space or whatever before the \string\maketitle\space command}\fi%
%
\ifx\thetitle\relax\PackageError{exam}{missing title}%
{You haven't specified the title of the paper: put \string\title{Algebra}%
\space or whatever before the \string\maketitle\space command}\fi%
%
\ifx\thetime\relax\PackageError{exam}{missing duration}%
{You haven't specified the duration of the paper: put %
\string\duration{1 hour}\space%
or whatever before the \string\maketitle\space command}\fi%
%
\ifx\therubric\relax\PackageError{exam}{missing rubric}%
{You haven't given a rubric: put a rubric environment before the%
 \string\maketitle\space command}\fi%
%
\ifx\thenumber\relax\PackageError{exam}{missing code number}%
{You haven't specified the code number of the paper: put %
\string\codenumber{12345}\space%
 or whatever before the \string\maketitle\space command}\fi%
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Parts:
%
% \part{title} prints a bold heading `Part X. title' and refsteps the part 
% counter.
% \nextpart is equivalent to \part{} for backward compatibility
% \skippart just steps the part counter. \skippart[x] steps by x.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcounter{paperpart}
\renewcommand{\thepaperpart}{\Alph{paperpart}}
\def\part#1{\ifnum\c@paperpart=0\ifquestionfrontpage\relax\else\clearpage%
\global\questionfrontpagetrue\fi\fi\refstepcounter{paperpart}%
\noindent\par\textbf{Part \thepaperpart. #1}%
\noindent\par\vspace{\qskip}}
\newcommand{\nextpart}{\part{}}
\newcommand{\skippart}[1][1]{\addtocounter{paperpart}{#1}}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Headers and footers. When a question breaks we want `continued on next
% page' in the footer and `continued from previous page' in the next header.
% Right-hand pages except the last one need `turn over' in the footer.
% All footers have page number centred, all headers have module number
% right aligned.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%
% \pagestyle{question}: track page breaks by writing a mark 
% of * when we enter a question and a mark of {} when we leave. If
% \topmark is *, then we're starting this page inside a question.
% If \botmark is * then we're finishing this page inside a question.
% If \botmark is + then we're on the last page of questions.
%

\def\ps@question{%
\def\@oddhead{\if*\topmarks\qmarks\textit{continued from previous page}\fi%
\hfil\textnormal{\thenumber}}
\let\@evenhead=\@oddhead
\def\@oddfoot{\theqpage%
\makebox[0pt][r]{\if*\botmarks\qmarks\textit{continued on next page}%
\else\if+\botmarks\qmarks\textit{End of examination.}\else\textit{Turn over}\fi\fi}}
\def\@evenfoot{\theqpage%
\if*\botmarks\qmarks\makebox[0pt][r]{\textit{continued on next page}}%
\else\if+\botmarks\qmarks\makebox[0pt][r]{\textit{End of examination.}}\fi\fi}%
}%

\pagestyle{question}

%
% \pagestyle{solution}: where we don't much care about the layout
%

\newcommand{\ps@solution}{%
\gdef\@oddhead{\hfil SOLUTIONS\hfil\makebox[0pt][r]{\textnormal{\thenumber}}}%
\global\let\@evenhead=\@oddhead%
\gdef\@oddfoot{\hfil\textnormal{\thepage}\hfil}%
\global\let\@evenfoot=\@oddfoot}

%
% \pagestyle{blank} for entirely blank pages.
%

\newcommand{\ps@blank}{%
\gdef\@oddhead{\relax}
\gdef\@evenhead{\relax}
\gdef\@oddfoot{\relax}
\gdef\@evenfoot{\relax}
}


%
% causes "end of examination" to be printed at \end{document} 
%

\AtEndDocument{\emarks\qmarks{+}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% remarks environment for comments to checker and/or external examiner.
% \noremarks stops the remarks being printed, \showremarks restores them.
% 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newenvironment{remarks}{\noindent\par\textbf{Remarks.} \itshape}{\par}
\let\saveremarks=\remarks
\let\saveendremarks=\endremarks
\newcommand{\noremarks}{\let\remarks=\comment\let\endremarks=\endcomment}
\newcommand{\showremarks}{\let\remarks=\saveremarks\let\endremarks=\saveendremarks}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Stuff to do with printing and totalling marks. 
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%
% \markstyle{x} redefines \markframe to \markx which controls the
% style used to display marks and totals. Predefined styles are box,
% oval, bracket and boldbracket, for rectangular box, round-cornered box,
% pair of square brackets, and pair of square brackets in bold.
%

\newcommand{\markstyle}[1]{\gdef\markframe{\csname mark#1\endcsname}}
\newcommand{\markbox}[1]{\fbox{#1}}
\newcommand{\markoval}[1]{\ovalbox{#1}}
\newcommand{\markbracket}[1]{\mbox{[#1]}}
\newcommand{\markboldbracket}[1]{\mbox{\textbf{[#1]}}}
\def\markframe{\markboldbracket}

%
% \rightframe prints its argument in a flush-right frame of the style
% defined by \markstyle. Can be used inside display math environments. 
% amsmath maintains the \if@display conditional and changes the \tag macro 
% whenever it becomes available; so we can test if \tag is usable by 
% comparing its expansion with its default
%

\def\rightalign#1{%
\if@display%
\ifx\tag\dft@tag\eqno #1\else\tag*{#1}\fi%
\else%
\space\hspace*{\fill}#1\linebreak%
\fi}

% 
% \displaymarks{caption}{marks} prints in a frame of the current
% style the caption followed by the number of marks and, if wordmarks 
% conditional is true, also prints "Mark" or "Marks" as appropriate afterwards
% \alignmarks does the same but used \rightalign to push the text to the
% right margin
% 

\newif\ifwordmarks
\wordmarkstrue
\newcommand{\wordmarks}{\global\wordmarkstrue}
\newcommand{\nowordmarks}{\global\wordmarksfalse}
\newcommand{\displaymarks}[2]%
{\markframe{#1#2\ifwordmarks\ Mark\ifnum#2>1 s\fi\fi}}
\newcommand{\alignmarks}[2]{\rightalign{\displaymarks{#1}{#2}}}

%
% if marks conditional is true, \marks{x} steps the marks counter by x
% and displays the mark using \alignmarks (i.e. on the right-hand margin). 
% \marks*{x} displays marks inline.
% \nomarks and \showmarks
% can be used to switch the conditional
%

\newif\ifmarks
\markstrue
\def\nomarks{\global\marksfalse}
\def\showmarks{\global\markstrue}
\newcounter{marks}

\def\marks{\@ifstar
\starmarks%
\nostarmarks%
}

\def\nostarmarks#1{\ifmarks\addtocounter{marks}{#1}\alignmarks{}{#1}\fi}
\def\starmarks#1{\ifmarks\addtocounter{marks}{#1}\displaymarks{}{#1}\fi}

%
% Finally a layer on top of that to control different styles for questions 
% and solutions. These record there answers in \ifqwordmarks, \qmarkstyle,
% \ifswordmarks and \smarkstyle, which are copied on to of \ifwordmarks
% and \markstyle at the beginning of the first question/solution. 
%
% No need to have this layered structure for \ifquestionotals and 
% \ifsolutiontotals as they're only used in \end{question} and \end{solution}
% whereas \marks is used in both environments
% 

\newif\ifqwordmarks
\qwordmarksfalse
\def\questionwordmarks{\global\qwordmarkstrue}
\def\noquestionwordmarks{\global\qwordmarksfalse}
\def\qmarkstyle{boldbracket}
\def\questionmarkstyle#1{\gdef\qmarkstyle{#1}}

\newif\ifswordmarks
\swordmarkstrue
\def\solutionwordmarks{\global\swordmarkstrue}
\def\nosolutionwordmarks{\global\swordmarksfalse}
\def\smarkstyle{oval}
\def\solutionmarkstyle#1{\gdef\smarkstyle{#1}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Question and solution environments. No need to worry about stopping
% pagebreaking because earlier penalties make it impossible, so
% question and solution are simple list environments, and \questionbreak
% is just \clearpage + reprint question number
% When the first solution is encountered, \emark\qmarks{+} to get 
% "end of examination" footer", create a blank even page if necessary, then 
% switch to \pagestyle{solution}
%
% \skipquestion and \skipsolution just step the counters.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcounter{question}
\newcounter{solution}
\newif\ifpartinquestion
\def\partinquestion{\global\partinquestiontrue}
\def\nopartinquestion{\global\partinquestionfalse}
\newif\ifnumberwithinpart
\def\numberwithinpart{\global\numberwithinparttrue}
\def\nonumberwithinpart{\global\numberwithinpartfalse}
\newif\ifquestiontotals
\questiontotalsfalse
\def\questiontotals{\global\questiontotalstrue}
\def\noquestiontotals{\global\questiontotalsfalse}
\newif\ifsolutiontotals
\solutiontotalstrue
\def\solutiontotals{\global\solutiontotalstrue}
\def\nosolutiontotals{\global\solutiontotalsfalse}

\renewcommand{\thequestion}{\ifpartinquestion\thepaperpart\fi\arabic{question}}
\renewcommand{\thesolution}{\ifpartinquestion\thepaperpart\fi\arabic{solution}}

\newcommand{\skipquestion}[1][1]{\addtocounter{question}{#1}}

\newenvironment{question}%
{\ifnum\c@question=0\markstyle{\qmarkstyle}%
\ifqwordmarks\global\wordmarkstrue\else\global\wordmarksfalse\fi%
\ifquestionfrontpage\relax\else\clearpage\global\questionfrontpagetrue
\fi%
\fi%
\emarks\qmarks{*}\setcounter{marks}{0}\let\control=\nopagebreak\begin{list}%
{\thequestion\ifquestioncount\ofcount\fi.\hfill}
{\labelwidth=\qindent\advance\labelwidth by -\qlabelsep\labelsep=\qlabelsep%
\leftmargin=\qindent\rightmargin=0pt\listparindent=\qparindent\parsep=\qparskip%
\topsep=0.5\qskip}
\refstepcounter{question}\ifnumberwithinpart\setcounter{question}{1}\fi\samepage\item}%
{\ifnum\c@marks>0\ifquestiontotals\alignmarks{Total: }{\arabic{marks}}\fi\fi%
\end{list}\emarks\qmarks{}\pagebreak[0]}

\def\questionbreak{\clearpage%
\makebox[0pt][r]{\makebox[\@totalleftmargin][l]%
{\thequestion\ifquestioncount\ofcount\fi~\textit{cont}.}}}

\newcommand{\skipsolution}[1][1]%
{\ifnum\c@solution=0\ifinquestion\label{lastqpage}\global\inquestionfalse%
\emarks\qmarks{+}\clearpage\pagestyle{blank}\cleardoublepage\pagestyle{solution}%
\markstyle{\smarkstyle}\ifswordmarks\global\wordmarkstrue\else\global\wordmarksfalse\fi%
\fi\fi%
\addtocounter{solution}{#1}}

\newenvironment{solution}
{\skipsolution\setcounter{marks}{0}\begin{list}{\thesolution.\hfill}%
{\labelwidth=\qindent\advance\labelwidth by -\qlabelsep\labelsep=\qlabelsep%
\leftmargin=\qindent\rightmargin=0pt\listparindent=\qparindent\parsep=\qparskip%
\topsep=0.5\qskip}
\item}%
{\ifnum\c@marks>0\ifsolutiontotals\alignmarks{Total: }{\arabic{marks}}\fi\fi\end{list}}

%
% \nosolutions command to suppress printing of solutions
%

\let\savesolutions=\solutions
\let\saveendsolutions=\endsolutions

\newcommand{\nosolutions}{\let\solution=\comment\let\endsolution=\endcomment}
\newcommand{\showsolutions}{\let\solution=\savesolution\let\endsolution=\endsavesolution}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% appearance of enumerations inside questions and solutions. Defaults to
% alpha then roman, making \romantrue swaps the order around.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newif\ifroman
\def\romanfirst{\global\romantrue}
\def\alphafirst{\global\romanfalse}

\renewcommand{\theenumi}{\ifroman\roman{enumi}\else\alph{enumi}\fi}
\renewcommand{\labelenumi}{(\theenumi)}
\renewcommand{\theenumii}{\ifroman\alph{enumii}\else\roman{enumii}\fi}
\renewcommand{\labelenumii}{(\theenumii)}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% extra utility commands
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\half}{\ensuremath{\frac{1}{2}}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% end of ymexam.cls
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
