%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% exam.cls, University examination paper LaTeX 2e class file
%
% SPE 15/4/96 -- 11/11/04
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%
% 2e isms
%

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{exam}[2000/03/01]
\PassOptionsToClass{12pt,a4paper,twoside}{article}
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessOptions
\LoadClass{article}
\RequirePackage{amsmath}
\RequirePackage{amsfonts}
\RequirePackage{verbatim}
\RequirePackage{fancybox}

%
% Tunable parameters
%

\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}}

%
% Topmatter:
%

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

\newsavebox{\rubricbox}

\def\codenumber#1{\gdef\thenumber{#1}}
\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}}}

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

\newif\ifquestioncount
\questioncounttrue
\AtEndDocument{\immediate\write\@auxout{\string\gdef\string\ofcount{ (of \thequestion)}}}
\gdef\ofcount{\relax}

\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}

\newif\ifresit
\resitfalse

\newif\ifbabsc
\babsctrue
\def\BABSctrue{\babsctrue}
\def\BABScfalse{\babscfalse}
\newif\ifbabscfirst
\newif\ifbabsclast
\newif\ifmmath
\mmathtrue
\def\MMathtrue{\mmathtrue}
\def\MMathfalse{\mmathfalse}
\newif\ifmmathfirst
\newif\ifmmathlast
\newif\ifmsc
\def\MSctrue{\msctrue}
\def\MScfalse{\mscfalse}
\newif\ifmscfirst
\newif\ifmsclast
\newif\ifmres
\def\MRestrue{\mrestrue}
\def\MResfalse{\mresfalse}
\newif\ifmresfirst
\newif\ifmreslast

\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%
}

%
% 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.
%

% old code which didn't always work

%\def\@oddhead{\ifcontinued\textit{continued from previous page}%
%\global\continuedfalse\fi%
%\hfil\textrm{\thenumber}}
%\let\@evenhead=\@oddhead
%\def\@oddfoot{\hfil\textrm{\thepage}\hfil%
%\makebox[0pt][r]{\ifcontinuing\textit{continued on next page}%
%\else\textit{Turn over}\fi}}
%\def\@evenfoot{\hfil\textrm{\thepage}\hfil%
%\ifcontinuing\makebox[0pt][r]{\textit{continued on next page}}\fi}

% define \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*\topmark\textit{continued from previous page}\fi%
\hfil\textrm{\thenumber}}
\let\@evenhead=\@oddhead
\def\@oddfoot{\hfil\textrm{\thepage}\hfil%
\makebox[0pt][r]{\if*\botmark\textit{continued on next page}%
\else\if+\botmark\else\textit{Turn over}\fi\fi}}
\def\@evenfoot{\hfil\textrm{\thepage}\hfil%
\if*\botmark\makebox[0pt][r]{\textit{continued on next page}}\fi}%
}%

\pagestyle{question}

% define \pagestyle{solution}

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

\AtEndDocument{\mark{+}}

%
% remarks environment for comments to checker and/or external examiner.
% \nomarks stops the remarks being printed, also stops the marks and
% totals (see below) being printed.
%

\newif\ifmarks
\markstrue
\newenvironment{remarks}{\noindent\par\textbf{Remarks.} \itshape}{\par}
\newcommand{\nomarks}%
{\marksfalse\let\remarks=\comment\let\endremarks=\endcomment}

%
% \rightframe prints its argument in a flush-right framebox. 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\rightframe#1{%
\if@display%
\ifx\tag\dft@tag\eqno\ovalbox{#1}\else\tag*{\ovalbox{#1}}\fi%
\else%
\hspace*{\fill}\ovalbox{#1}\linebreak%
\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.

\newcounter{paperpart}
\renewcommand{\thepaperpart}{\Alph{paperpart}}
\def\part#1{\refstepcounter{paperpart}%
\noindent\par\textbf{Part \thepaperpart. #1}%
\noindent\par\vspace{\qskip}}
\newcommand{\nextpart}{\part{}}
\newcommand{\skippart}[1][1]{\addtocounter{paperpart}{#1}}

%
% Keeping track of marks. Individual mark is printed flush right in a frame,
% total is printed in the same format at the end of question or solution
% (if \marks has been used within that environment). \marksfalse suppresses
% printing of marks, but \nomarks which also suppresses the remarks
% environment should normally be used for this purpose.
%

\newcounter{marks}
\def\marks#1%
{\ifmarks\addtocounter{marks}{#1}\rightframe{#1 Mark\ifnum#1>1 s\fi}\fi}

%
% 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, \mark{+} to suppress "Turn over",
% \cleardoublepage then switch to \pagestyle{solution}
%
% \skipquestion and \skipsolution just step the counters.
%

%\newif\ifcontinued  % if current page started with a continuation
%\newif\ifcontinuing % if current page ends with a continuation
\newcounter{question}
\newcounter{solution}
\newif\ifshowpart
\newif\ifnumberinpart
\renewcommand{\thequestion}{\ifshowpart\thepaperpart\fi\arabic{question}}
\renewcommand{\thesolution}{\ifshowpart\thepaperpart\fi\arabic{solution}}

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

\newenvironment{question}%
{\mark{*}\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}\ifnumberinpart\setcounter{question}{1}\fi\samepage\item}%
{\ifnum\c@marks>0\rightframe{Total:~\arabic{marks}~Mark%
\ifnum\c@marks>1s\fi.}\fi%
\end{list}\mark{}\pagebreak[0]}

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

%\def\questionbreak{\global\continuingtrue\clearpage\global\continuedtrue%
%\global\continuingfalse%
%\makebox[0pt][r]{\makebox[\@totalleftmargin][l]{\thequestion~\textit{cont}.}}}

%\newcommand{\skipsolution}[1][1]%
%{\ifnum\c@solution=0\global\let\@oddfoot=\@evenfoot\cleardoublepage%
%\gdef\@oddhead{\hfil SOLUTIONS\hfil\textrm{\thenumber}}%
%\global\let\@evenhead=\@oddhead\fi%
%\addtocounter{solution}{#1}}

\newcommand{\skipsolution}[1][1]%
{\ifnum\c@solution=0\mark{+}\cleardoublepage\pagestyle{solution}\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\rightframe{Total: \arabic{marks} Marks}\fi\end{list}}

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

\newif\ifroman

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

%
% \nosolutions command to suppress printing of solutions
%

\newcommand{\nosolutions}%
{\let\solution=\comment\let\endsolution=\endcomment}

%
% extra utility commands
%

\newcommand{\half}{\ensuremath{\frac{1}{2}}}
\newcommand{\jase}%
{\renewcommand{\thepage}{May the force $\vdash$\fbox{\arabic{page}}$\dashv$ be with you!}}

%% end of exam.sty
