% File icphexam.cls
%
% History
%
%  18 Dec 2007 1st attempt
%  28 Dec 2007 Fixed scope for centering for Section
%              Fixed marks text to print [1 mark]
%  2  Jan 2008 changed \qmarks to use \pushright construct and to
%              work in $$...$$ maths. 
%  13 Jan 2008 fixed \thesubqno and \thesubsubqno to match formatting
%  15 Feb 2008 added \qendmatter for material after Total marks on same page
%  25 Feb 2008 added font options, with cmr default
%  15 Mar 2008 changed rubric
%              added \interruptsubq and ...subsubq
%              added questionendmatter and examendmatter
%              implemented lastpage approach to trigger End of Exam footer
%              (thanks to Ed Grace); question environment left with optional
%              argument that is ignored for backward compatibility
%  30 Mar 2008 A couple of cosmetic changes
%  10 Apr 2008 Reset equation, figure, table counters for each question
%              Use pushright in end{question} for Total marks
%   7 May 2008 twoside printing footers
%   5 Jul 2008 Fixed bug in examendmatter @\oddfoot; added cmbright as default
%  23 Oct 2008 Added \Q and \A commands to include answers
%  14 Dec 2008 Fixed linespacing for long examtitles. Added shorttitle opt arg.
%  17 Sep 2009 Added option to suppress pagebreak after each question
%  23 Nov 2009 Added arev font option
%  16 Mar 2010 Switch to onesided - repeat footer page instructions for non-booklet

% To do:

%   Re-work displayed equations so work with \qmarks (requires
%   over-riding the base latex). I had another look at this, and the QED.sty
%   package, and decided to give up. 

\ProvidesClass{icphexam}[2010/03/16 by Steve Schwartz]
\typeout{for BSc and MSci and MSc exams in Physics at Imperial College London;}
\typeout{Modelled after exam.cls by Francis J Wright, Queen Mary, U of London}
\typeout{ICPHEXAM WARNING:  qmarks command works in text and $$ ... $$ constructs. LaTeX backslash-[ .... backslash-] constructs throw a latex error that you can type 's' to ignore. If you need numbered equations, use the leqno package. Numbered equations with  qmarks also throw ignorable errors.}

\NeedsTeXFormat{LaTeX2e}[2001/06/01]

\RequirePackage{ifthen}

% Font selection:
%
%  default is cmbright. This is sans serif and should be available on all
%  installations.
%
%  sans is an alternative, using the sfmath package (available from tex archives).
%     It produces darker fonts, especially when used, as below, with txfonts. Some
%     people seem to have problems with txfonts, but it is worth trying.
%
%  arev is a bit bigger (try dropping to 11 pt) but also isn't universally
%     available in default installations. Has better ell's and eye's.
%
%  mathptmx is the standard latex "math-plus-times-extended" alternative to
%     tex Computer Modern fonts. Essentially standard postscript times roman
%     with math bits to match. College style, together with advice on visually
%     impaired readability, is sans-serif.
%
%  cmr will invoke default latex computer modern fonts. If these dont work,
%     something is seriously wrong with the users tex installation.

\newboolean{defaultfont}\setboolean{defaultfont}{true}
\newboolean{arev}\setboolean{arev}{false}

\DeclareOption{mathptmx}{%
	\setboolean{defaultfont}{false}
	\AtEndOfClass{\usepackage{mathptmx}}
}
\DeclareOption{sans}{%
	\setboolean{defaultfont}{false}
	\AtEndOfClass{%
		\usepackage{txfonts}
		\usepackage{sfmath}
		\renewcommand\familydefault{\sfdefault}
	}
}
\DeclareOption{cmr}{
	\setboolean{defaultfont}{false}
	\AtEndOfClass{}
}

\DeclareOption{cmbright}{%
	\setboolean{defaultfont}{false}
	\AtEndOfClass{\usepackage{cmbright}}
}

\DeclareOption{arev}{%
	\setboolean{defaultfont}{false}
        \setboolean{arev}{true}
	\AtEndOfClass{\usepackage{arev}}
}


\DeclareOption{BSc}{\def\BSc@MSc{BSc}}
\DeclareOption{MSc}{\def\BSc@MSc{MSc}}
\DeclareOption{MSci}{\def\BSc@MSc{MSci}}
\DeclareOption{BScMSci}{\def\BSc@MSc{BSc/MSci}}

\newboolean{DRAFTEXAM}
\setboolean{DRAFTEXAM}{false}  %default
\DeclareOption{draftexam}{\setboolean{DRAFTEXAM}{true}}
\DeclareOption{DRAFTEXAM}{\setboolean{DRAFTEXAM}{true}}

\newboolean{PRINTANS}
\setboolean{PRINTANS}{false}  %default
\DeclareOption{PRINTANS}{\setboolean{PRINTANS}{true}}
\DeclareOption{printans}{\setboolean{PRINTANS}{true}}

\newboolean{HIDEQ}
\setboolean{HIDEQ}{false}  %default
\DeclareOption{HIDEQ}{\setboolean{HIDEQ}{true}}
\DeclareOption{hideq}{\setboolean{HIDEQ}{true}}

\newboolean{NOPAGEBREAK}
\setboolean{NOPAGEBREAK}{false} %default
\DeclareOption{NOPAGEBREAK}{\setboolean{NOPAGEBREAK}{true}}
\DeclareOption{nopagebreak}{\setboolean{NOPAGEBREAK}{true}}

\newcommand{\Q}[1]{\ifthenelse{\boolean{HIDEQ}}{}{#1}}
\newcommand{\A}[1]{\ifthenelse{\boolean{PRINTANS}}
{\textbf{\ifthenelse{\boolean{HIDEQ}}{}{\newline}ANSWER: }#1}{}
}

\ExecuteOptions{BScMSci}    % default is BSc and MSci
\ProcessOptions*

%\ifthenelse{\boolean{arev}}{\LoadClass[twoside,11pt,a4paper]{article}}
%{\LoadClass[twoside,12pt,a4paper]{article}}

\ifthenelse{\boolean{arev}}{\LoadClass[oneside,11pt,a4paper]{article}}
{\LoadClass[oneside,12pt,a4paper]{article}}

\ifthenelse{\boolean{defaultfont}}{\usepackage{cmbright}}{}


\raggedbottom   % twoside defaults to flushbottom ! 

\oddsidemargin 0pt
\evensidemargin 0pt
\topmargin 0pt
\ifthenelse{\boolean{DRAFTEXAM}\OR\boolean{PRINTANS}}{}{\headheight 0pt \headsep 0pt}
\textwidth \paperwidth
\addtolength{\textwidth}{-2in}
\textheight \paperheight
\addtolength{\textheight}{-2in}
\addtolength{\textheight}{-\headheight}
\addtolength{\textheight}{-\headsep}
\addtolength{\textheight}{-\footskip}

\sloppy

% Exam header:

%\newcommand{\examtitle}[1]{\newcommand{\exam@title}{\uppercase{#1}}}
\newcommand{\examtitle}[2][\shorttitle]{\def\shorttitle{#2}\newcommand{\exam@title}{\uppercase{#2}}\newcommand{\short@title}{#1}}
\newcommand{\examtime}[1]{\newcommand{\exam@time}{#1}}
\newcommand{\exammonth}[1]{\newcommand{\exam@month}{#1}}
\newcommand{\examlevel}[1]{\newcommand{\exam@level}{#1}}
\newcommand{\examid}[1]{\newcommand{\exam@id}{#1}}
\newcommand{\exid}{\exam@id}
\newcommand{\numberofbooks}[1]{\newcommand{\number@ofbooks}{#1}}
\newcommand{\nbooks}{\number@ofbooks}

\AtBeginDocument{%
	\providecommand{\exam@title}{}% empty defaults
	\providecommand{\exam@time}{}
	\providecommand{\exam@month}{}
	\providecommand{\exam@level}{}
	\providecommand{\exam@id}{}
	\providecommand{\number@ofbooks}{}
	%
}

% Exam footer:
% Note: the \rightmark is the FIRST one defined on the present page (see
% fancyhdr documentation for explanation. Since we use marks for page turning
% instructions, we want the last mark on the page, so use the leftmark. The 
% odd-numbered pages need to be turned, so put the leftmark in their footers
% and put no mark in the even ones.

\def\@oddfoot{%
  \begin{tabular}{@{}p{0.4\textwidth}@{}p{0.2\textwidth}@{}p{0.4\textwidth}@{}}
  \textnormal{\parbox[b]{0.4\textwidth}{%
 \ifthenelse{\thepage=1}%
  {\flushleft\mbox{\copyright\ Imperial College London \number\year}\\%
  \exid}{\exid}}} & %
  \hfil\ifthenelse{\boolean{PRINTANS}}{\textbf{ANSWERS }}{}{\textnormal{\thepage}}\hfil & %
  \parbox[b]{0.4\textwidth}{\flushright\leftmark}\\
  \end{tabular}
}
% \leftmark outputs the LAST "left" mark set by \markboth
\let\@evenfoot\@oddfoot

% Obsolete twoside-relevant code:
%\def\@evenfoot{\makebox[0pt][l]{\small\textnormal{%
% \ifthenelse{\thepage=1}%
%  {\begin{tabular}{l}\copyright\ Imperial College London \number\year\\%
%  \exid\end{tabular}}{\exid}}}%
%  \hfil\ifthenelse{\boolean{PRINTANS}}{\textbf{ANSWERS }}{}\textnormal{\thepage}\hfil%
%  \makebox[0pt][r]{}}    % no mark here - these are facing pages

\newcommand\draftstring{\ifthenelse{\boolean{DRAFTEXAM}}{DRAFT}{}}
\newcommand\ansstring{\ifthenelse{\boolean{PRINTANS}}{ANSWERS\hfil}{}}

\ifthenelse{\boolean{DRAFTEXAM}\OR\boolean{PRINTANS}}{
  \def\@oddhead{\textbf{\short@title\ \exam@month\  \hfil \ansstring \draftstring \hfil \today}}
  \let\@evenhead\@oddhead
}{}

% Automate "End of Examination" - takes some work!
\AtEndDocument{% From Ed Grace
  % Ruthlessly borrowed from lastpage.sty, renamed to avoid potential clashes.
   \message{Final page:  setting counter @icphexam@last}%
   \clearpage\@pagefinal@putlabel%
}
% Defined to get the last page number, so we can tell when we are
% processing the last page and mark the end of the exam.
\newcommand\@pagefinal@putlabel{%
  \addtocounter{page}{-1}%
  % Write out the page reference as icphexam@last
  \immediate\write\@auxout{\string
    \newlabel{icphexam@last}{{}{\thepage}}}%
  \addtocounter{page}{1}%
}

% Section command and rubric environment:

\renewcommand{\section}[1]%
  {	{\centering\large\bfseries SECTION #1\par}
	\vspace{\baselineskip}
}

\newenvironment{rubric}[1][]%
  {	\markboth{\textit{[Examination instructions continue on next page\ldots]}}{}
	{\parindent 0pt
	\LARGE\noindent Imperial College London \\[0.4em]
	\BSc@MSc\ EXAMINATION \exam@month \\[1.0em]
	{\small\em This paper is also taken for the relevant Examination for the Associateship}\\[1.0em]
	{\exam@title\par\vspace{1.0em}}
	} 
	{\noindent\Large {\bfseries \exam@level}\\[0.4em]
	\exam@time\\
	}
	\vfill\parindent 0pt
	\begingroup\em%
  }% end of pre-environment commands
  {	\\Marks shown on this paper are indicative of those the Examiners anticipate assigning.\par\endgroup
	\vfill
	\textbf{General Instructions}\\[1.0em]
	Complete the front cover of each of the \nbooks\ answer books provided.\\[1.0em]
	If an electronic calculator is used, write its serial number at the top of the front cover of each answer book.\\[1.0em]
	\uppercase{Use one answer book for each question.}\\[1.0em]
	Enter the number of each question attempted in the box on the front cover of its corresponding answer book.\\[1.0em]
	Hand in \nbooks\ answer books even if they have not all been used.\\[1.0em]
	\textbf{You are reminded that Examiners attach great importance to legibility, accuracy and clarity of expression.}
	\vfill
	\markboth{\textbf{Go to the next page for questions}}{}\pagebreak
  }

% Question environments:

\newcounter{qno}
\renewcommand{\theqno}{\arabic{qno}}
\newenvironment{questions}%
  {\begin{list}{\textbf{\arabic{qno}.}}%
   {\usecounter{qno}}}%
  {\end{list}%
   \markboth{\textbf{Next section overleaf}}{}%
  }%

\newcounter{nmarks}
\newcommand\marksword[1]{\ifthenelse{#1=1}{mark}{marks}}

% added 98-11-8 - based on P. Taylor macro
\def\pushright#1{{%        set up
    \parfillskip=0pt            % so \par doesnt push \square to left
    \widowpenalty=10000         % so we dont break the page before \square
    \displaywidowpenalty=10000  % ditto
    \finalhyphendemerits=0      % TeXbook exercise 14.32
   %
   %                 horizontal
    \leavevmode                 % \nobreak means lines not pages
    \unskip                     % remove previous space or glue
    \nobreak                    % dont break lines
    \hfil                       % ragged right if we spill over
    \penalty50                  % discouragement to do so
    \hskip.2em                  % ensure some space
    \null                       % anchor following \hfill
    \hfill                      % push \square to right
    {#1}                        % the end-of-proof mark (or whatever)
   %
   %                   vertical
    \par}}                      % build paragraph

\newcommand\qmarks[1]{%
\addtocounter{nmarks}{#1}%
\ifmmode \eqno \hbox{\sffamily[#1~\marksword{#1}]}
  \else \pushright{\hbox{\quad\sffamily[#1~\marksword{#1}]}}\fi
}

\newenvironment{question}[1][]%
  { \setcounter{nmarks}{0}
    \setcounter{equation}{0}  % restart numbering of eqns, figs, etc.
    \setcounter{figure}{0}
    \setcounter{table}{0}
    \item%
    \markboth{\textit{[This question continues on the next page \ldots]}}{}%
  }
{\pushright{\sffamily[Total~\arabic{nmarks}~\marksword{\value{nmarks}}]}
  \qendmatter\par
  \ifthenelse{\equal{\thepage}{\pageref{icphexam@last}}}%
    { \let\@evenfoot \@oddfoot
      \markboth{\textbf{End of examination paper}}{}}%
    {\markboth{\textbf{Please go to the next page}}{}}
    \ifthenelse{\boolean{NOPAGEBREAK}}{}{\pagebreak}
}

% Sub-question environments:
%  For long labels change the value of \labelwidth in the source file
%  e.g. \begin{subquestions} \settowidth{\labelwidth}{(viii)}

\newcounter{subqno}
\renewcommand{\thesubqno}{\roman{subqno}}
\newenvironment{subquestions}%
  {\begin{list}{(\roman{subqno})}{\usecounter{subqno}}}%
  {\end{list}}%
\newcommand{\subquestion}{\item{}}

\newcounter{savesubqno}
\newcommand\interruptsubq[1]{%
\setcounter{savesubqno}{\value{subqno}}%
\end{subquestions}{#1}%
\begin{subquestions}\setcounter{subqno}{\value{savesubqno}}
}

\newcounter{subsubqno}
\renewcommand{\thesubsubqno}{\alph{subsubqno}}
\newenvironment{subsubquestions}%
  {\begin{list}{(\alph{subsubqno})}{\usecounter{subsubqno}}}%
  {\end{list}}%
\newcommand{\subsubquestion}{\item{}}

\newcounter{savesubsubqno}
\newcommand\interruptsubsubq[1]{%
\setcounter{savesubsubqno}{\value{subsubqno}}%
\end{subsubquestions}{#1}%
\begin{subsubquestions}%
\setcounter{subsubqno}{\value{savesubsubqno}}
}

\newcommand\qendmatter{}
\newcommand\questionendmatter[1]{\renewcommand\qendmatter{#1}}

\newenvironment{examendmatter}
  { \markboth{\textbf{Please go to the next page}}{}%
  }%
  {\par
   \ifthenelse{\equal{\thepage}{\pageref{icphexam@last}}}%
    {\let\@evenfoot \@oddfoot   % to get end of exam footer
     \markboth{\textbf{End of examination paper}}{}}%
    {\markboth{\textbf{Please go to the next page}}{}}
    \par\pagebreak}%


% End of file icphexam.cls
