% UOFTEXAM.STY % LaTeX style file for typesetting University of Toronto exams % Version 1.81 % % Martin J. Osborne (http://www.economics.utoronto.ca/osborne) % % History: % 1.0 2000/1/29 Developed from style written in 1996 % 1.1 2000/3/19 \PointTable reimplemented as an alignment, with split % between two tables allowed via optional argument giving % number of columns % 1.2 2005/1/28 Added PointsAtRight option. % 1.3 2005/2/28 Added solutions option, \solution macro, and \roughpage macro. % 1.4 2005/3/19 Added \xitem to deal with itemizations within questions % or solutions. % 1.5 2005/11/20 Added \PointTotal to allow for exams with optional question. % 1.6 2013/3/22 Added StudentNumberOnly option. % 1.61 2016/2/17 Bug in effect of draft and solutions options on \PointTable corrected % 1.7 2016/10/22 Added crowdmark option, which adjusts format to suit Crowdmark test % 1.71 2016/10/24 Bug in setup of options corrected % 1.8 2017/10/15 Added crowdmarkAuto option, which, in combination with the crowdmark option, % generates a format with space on the front page for the boxes for student % information required for automatic matching % 1.81 2017/12/1 Implemented crowdmarkAuto option for final exam as well as test. % % Problems: % - Cannot handle an enumeration outside the one that contains the list of % questions. (But can handle other lists outside that list.) % - Cannot handle \begin{center} ... \end{center} within document (presumably % because it calls \item??) Use \hspace{\fill} ... \hspace{\fill} % instead. % % load after article.cls % % Future work: Could use \newfield construct from tcilcomm.tex (copy in % \xy\let) to make style more friendly to SW users---can put all arguments % at start of document in fields, which will display in SW, and put everything % in a Shell. % \newcommand{\SP}[1]{\vspace*{#1mm}} \newcommand{\pad}{\vspace*{\fill}} \newcommand\nextpage{% \vfil\par\hspace*{\fill}{\bf Page \thepage\ of \protect\pageref{lastpage}}\par\penalty -\@M% } % \qcontnextpage puts a statement that the question continues on the % next page at the bottom of the page, and ends the current page \newcommand{% \qcontnextpage}{\hspace*{\fill}\emph{Question continues on next page}\nextpage% } % \scontnextpage puts a statement that space for answer continues on the % next page at the bottom of the page, and ends the current page \newcommand{% \scontnextpage}{\hspace*{\fill}\emph{Space for answer continues on next page}\nextpage% } \newcommand{\roughpage}[1]{\nextpage{\bfseries #1}\pad} \newif\ifutx@Draft % \def\PointTable{} in following probably doesn't have any effect, because \PointTable is defined later? \DeclareOption{draft}{% \utx@Drafttrue% \renewcommand\pad{}% \renewcommand\nextpage{}% \renewcommand\qcontnextpage{}% \renewcommand\scontnextpage{}% \renewcommand\SP{}% \renewcommand{\roughpage}[1]{}% \newcommand\PointTable{}% } \newif\ifutx@PointsAtRight \DeclareOption{PointsAtRight}{\utx@PointsAtRighttrue} \newif\ifutx@PleaseHandIn \DeclareOption{PleaseHandIn}{\utx@PleaseHandIntrue} \newif\ifutx@Solutions \DeclareOption{solutions}{\utx@Solutionstrue} \newif\ifutx@StudentNumberOnly \DeclareOption{StudentNumberOnly}{\utx@StudentNumberOnlytrue} \newif\ifutx@Crowdmark \DeclareOption{crowdmark}{\utx@Crowdmarktrue} \newif\ifutx@CrowdmarkAuto \DeclareOption{crowdmarkAuto}{\utx@CrowdmarkAutotrue} \ProcessOptions \ifutx@Crowdmark% \renewcommand\nextpage{\vfil\hspace*{\fill}\par\penalty -\@M} % \qcontnextpage puts a statement that the question continues on the % next page at the bottom of the page, and ends the current page \renewcommand{\qcontnextpage}{\hspace*{\fill}\emph{Question continues on next page}\nextpage} % \scontnextpage puts a statement that space for answer continues on the % next page at the bottom of the page, and ends the current page \renewcommand{\scontnextpage}{\hspace*{\fill}\emph{Space for answer continues on next page}\nextpage} \fi % The following settings assume you are using a driver that automatically adds a one inch % margin (which is probably true). If not, you'll need to make adjustments. \ifutx@Crowdmark \oddsidemargin -0.6in \evensidemargin -0.6in \topmargin -0.05in \textwidth 7.5in \textheight 9in \else \oddsidemargin 0in \evensidemargin 0in \topmargin 0in \textwidth 6.5in \textheight 9in \fi \long\def\solution#1{% \ifutx@Solutions \begin{description}\xitem[Solution:]#1\end{description}% \else\fi} \long\def\comment#1{% \ifutx@Solutions \begin{description}\xitem[Comment:]#1\end{description}% \else\fi} \long\def\solutionx#1{% \ifutx@Solutions#1\else\fi} \def\endexam{% \ifutx@Solutions% \vfil\label{lastpage}% \else\vfil\begin{center}\label{lastpage}{\bfseries End of examination}\\% \bfseries Total pages: \protect\pageref{lastpage}\\% \bfseries Total marks: \totalpoints% \end{center}% \fi% } \newcommand{\Course}[2]{\def\@coursenumber{#1}\def\@coursename{#2}} \newcommand{\Instructor}[1]{\def\@instructor{#1}} \newcommand{\TestName}[1]{\def\@testname{#1}} \newcommand{\Date}[1]{\def\@testdate{#1}} \newcommand{\Time}[1]{\def\@testtime{#1}} \newcommand{\Aids}[1]{\def\@aids{#1}} \newcommand{\QToBeAnswered}[1]{\def\@qtba{#1}} \gdef\@pointtotal{} \newcommand{\PointTotal}[1]{\gdef\@pointtotal{#1}} \newcommand{\SpInstructions}[1]{\def\@spinstructions{#1}} \def\@studentnameandnumber{% \noindent\hspace*{\fill}{\bfseries Given name}:\rule{46mm}{0.6pt}\hspace*{2mm}{\bfseries Family name}:\rule{43mm}{0.6pt}\hspace*{\fill}\par\vspace{5mm} \noindent\hspace*{\fill}{\bfseries Student number}:\rule{45mm}{0.6pt}\hspace*{2mm}%{\bfseries Signature}:\rule{60mm}{0.6pt}\hspace*{\fill} } \def\@studentnumber{\noindent\hspace*{\fill}{\bfseries Student number}:\rule{40mm}{0.6pt}\hspace*{\fill}} \def\@studentemailnamenumber{% \renewcommand{\arraystretch}{1.5}% \hspace*{\fill}% \begin{tabular}{rl} {\bfseries U of T email address}&\rule{60mm}{0.6pt}\texttt{@mail.utoronto.ca}\\ {\bfseries Surname (last name)}&\rule{60mm}{0.6pt}\\ {\bfseries Given name (first name)}&\rule{60mm}{0.6pt}\\ {\bfseries Student number}&\rule{60mm}{0.6pt}\\ {\bfseries Signature}&\rule{60mm}{0.6pt} \end{tabular}% \hspace*{\fill}% } \ifutx@Solutions% \def\@studentinfo{}% \else \ifutx@Crowdmark% \ifutx@CrowdmarkAuto% \def\@studentinfo{}% \else% \def\@studentinfo{\@studentemailnamenumber}% \fi \else \ifutx@StudentNumberOnly% \def\@studentinfo{\@studentnumber}% \else \def\@studentinfo{\@studentnameandnumber}% \fi \fi \fi \def\@uofthead{\textbf{UNIVERSITY OF TORONTO}\\% \textbf{Faculty of Arts and Science}\\[4mm]} \def\@testheader{\begin{center}% \@uofthead% \textbf{\@coursenumber\ (\@coursename)}\\% Instructor: \@instructor\\[4mm] \textbf{\@testname}\\ \textbf{\@testdate}\\[4mm]% \textbf{Duration: \@testtime}\\[4mm]% \ifutx@CrowdmarkAuto \vspace{9cm} \fi \textbf{\@aids}\end{center}% \noindent \ifutx@Solutions% \else This examination paper consists of \textbf{\protect\pageref{lastpage}} pages and \textbf{\protect\ref{lastquestion}} questions. Please alert an invigilator to any discrepancy. \fi The number in brackets at the start of each question is the number of points the question is worth.\vspace*{3mm}\par \noindent \@qtba\vspace*{3mm}\par \noindent \@spinstructions} \def\@crowdmarkheader{\begin{center}% \@uofthead% \textbf{\@coursenumber\ (\@coursename)}\\% Instructor: \@instructor\\[4mm] \textbf{\@testname}\\ \textbf{\@testdate}\\[4mm]% \textbf{Duration: \@testtime}\\[4mm]% \textbf{\@aids}\end{center}% \noindent \ifutx@Solutions% \else This examination paper consists of \textbf{\protect\pageref{lastpage}} pages and \textbf{\protect\ref{lastquestion}} questions. Please bring any discrepancy to the attention of an invigilator. \fi The number in brackets at the start of each question is the number of points the question is worth.\vspace*{3mm}\par \noindent \@qtba\vspace*{3mm}\par \noindent \@spinstructions} \def\@finalheader{\begin{center}% \@uofthead% \ifutx@PleaseHandIn{% \vspace*{-4mm}\hspace*{80mm}\includegraphics[bb=0 0 250 80,height=5mm]{/xy/m/courses/phandin.jpg}\\[-1mm]% }\else\fi% \textbf{\@testdate}\\[3mm] \textbf{\@coursenumber\ (\@coursename)}\\% Instructor: \@instructor\\[3mm] \textbf{Duration: \@testtime}\\[3mm]% \textbf{\@aids}\end{center}% \ifutx@CrowdmarkAuto \vspace{9cm} \fi% \noindent This examination paper consists of \textbf{\protect\pageref{lastpage}} pages and \textbf{\protect\ref{lastquestion}} questions. Please bring any discrepancy to the attention of an invigilator. The number in brackets at the start of each question is the number of points the question is worth.\vspace*{3mm}\par \noindent \@qtba\vspace*{3mm}\par \noindent \@spinstructions% } \def\@compheader{\begin{center}% \@uofthead% \textbf{\@testdate}\\[4mm] {\large\textbf{\@coursename}}\\[4mm] \textbf{Duration: \@testtime}\\[4mm]% \textbf{\@aids}\end{center}% \noindent This examination paper consists of \textbf{\protect\pageref{lastpage}} pages and \textbf{\protect\ref{lastquestion}} questions. Please bring any discrepancy to the attention of an invigilator. The number in brackets at the start of each question is the number of points the question is worth.\vspace*{3mm}\par \noindent \@qtba\vspace*{3mm}\par \noindent \@spinstructions} \newcommand{\Test}{\thispagestyle{empty}% \@testheader} \newcommand{\WriteOnTest}{\thispagestyle{empty}% \ifx\@studentinfo\empty% \else\@studentinfo% \vspace*{4mm}% \fi \@testheader} \newcommand{\Final}{\thispagestyle{empty}% \@finalheader} \newcommand{\WriteOnFinal}{\thispagestyle{empty}% \ifx\@studentinfo\empty% \else\@studentinfo% \vspace*{4mm}% \fi \@finalheader} \newcommand{\WriteOnComp}{\thispagestyle{empty}% \ifx\@studentinfo\empty% \else\@studentinfo% \vspace*{4mm}% \fi \@compheader} \let\origendenumerate=\endenumerate % redefine \end{enumerate} at level 1 to put a label for the last question % and write number of points for last question and total points on test % to AUX file (see \item, below) \def\endenumerate{\ifnum\@enumdepth = 1% \@bsphack \protected@write\@auxout{}% {\string\newlabel{Q\theenumi}{{\theqpoints}{\thepage}}}% \typeout{Label Q\theenumi\space written by endenumerate}% \@esphack% \@bsphack \ifx\@pointtotal\@empty \gdef\totalpoints{\thepoints} \else \gdef\totalpoints{\@pointtotal} \fi \protected@write\@auxout{}% {\string\newlabel{pointtotal}{{\totalpoints}{\thepage}}}% \@esphack% \label{lastquestion}% \typeout{***** Total points on test: \totalpoints}\fi% \origendenumerate} \let\origenddocument=\enddocument \def\enddocument{\endexam\origenddocument} \renewcommand{\ps@plain}{% \ifutx@Crowdmark% \renewcommand{\@oddhead}{}% \else% \renewcommand{\@oddhead}{\hfil\textsc{page \thepage}}% \fi% \renewcommand{\@evenhead}{\@oddhead}% \renewcommand{\@oddfoot}{}% \renewcommand{\@evenfoot}{}} \pagestyle{plain} \newcounter{points} \newcounter{qpoints} % Redefine \item so that optional argument in parentheses is number of points % (while optional argument in brackets has original meaning---for lists % within questions). Original definition of \item from LATEX.LTX: % \def\item{\@inmatherr\item % \@ifnextchar [\@item{\@noitemargtrue \@item[\@itemlabel]}} % Also make \item at list depth 1 write the number of points on the PREVIOUS % question (held in qpoints) to the AUX file and reset the qpoints counter. \def\xitem{% \@inmatherr\item \@ifnextchar [\@item{\@noitemargtrue \@item[\@itemlabel]} } % For points at right at end of each question \ifutx@PointsAtRight \def\@pointsox{\@pointsoe} \else \def\@pointsox{\@pointsob} \fi \def\item{% \ifnum\@enumdepth=1\ifnum\thepoints>0% \@bsphack \protected@write\@auxout{}% {\string\newlabel{Q\theenumi}{{\theqpoints}{\thepage}}}% \typeout{Label Q\theenumi\space written by item}% \@esphack% \setcounter{qpoints}{0}\fi\fi% \@ifnextchar(% {\@pointsox}% {\@ifnextchar[% {\@item}% {\@points} }% } % Next group of lines for case of number of points in brackets % after question number \def\@pointsob(#1){\@noitemargtrue \@item[\@itemlabel] {[#1]}\addtocounter{points}{#1}\addtocounter{qpoints}{#1}} % Next group of lines for case of number of point right-justified % on last line of question. REQUIRES SYNTAX \item (5){Question text} % (NOTE BRACES!!). \long\def\@pointsoe(#1)#2{\@noitemargtrue \@item[\@itemlabel]% \addtocounter{points}{#1}\addtocounter{qpoints}{#1}#2% {\unskip\nobreak\hfil\penalty50\quad\hbox{}\nobreak\hfill% \hbox{[#1]}}} \def\@points{\@noitemargtrue \@item[\@itemlabel]} \newcounter{qnumber} \setcounter{qnumber}{1} % Optional argument of \PointTable splits table into several tables, set % beside each other (so they fit on first page); argument is number of columns. % This is the table inserted by the \@pointtable macro \ifutx@Crowdmark \def\MakePointTable{% See example on p. 246 of TeXbook. Note ## instead of # here, because this is a macro \vtop{\offinterlineskip% \hrule \halign{ &\vrule##&\strut\quad\hfil##\hfil\quad\cr% height2pt&\omit&&\omit&\cr% extend rules to meet properly &Question\hfil&&Points&\cr% row of text height2pt&\omit&&\omit&\cr% extend rules to meet properly \noalign{\hrule}% put a horizontal rule height2pt&\omit&&\omit&\cr% extend rules to meet properly \enoughrows\cr% the set of rows below the header (\enoughrows is defined when \MakePointTable is run) height0pt&\omit&&\omit&\cr } \hrule } } \else \def\MakePointTable{% \vtop{\offinterlineskip% \halign{% \vrule##\tabskip 8pt&% \strut\hfil##&% no of question \strut\hfil##&% no of points \vrule##&% \strut\hfil##\hfil&% space for score \vrule##\tabskip=0pt\cr% \noalign{\hrule}\cr &&&&Score&\cr \noalign{\hrule}\cr height2pt&\omit&\omit&&\omit&\cr \enoughrows\cr \noalign{\hrule height1.3pt}\cr height2pt&\omit&\omit&&\omit&\cr \ifnum\theNoCols=1 &Total&(\protect\ref{pointtotal})&&&\cr\noalign{\hrule}\egroup\egroup% \else &\multispan2\hfil{\normalsize Subtotal}&&&\cr\noalign{\hrule} } } \fi } \fi \def\PointTable{\@ifnextchar [{\@pointtableo}{\@pointtable{1}}} %\def\PointTable{\ifutx@Solutions\else\ifutx@Draft\else{\@ifnextchar [{\@pointtableo}{\@pointtable{1}}}\fi} \ifutx@Solutions \def\@pointtableo[#1]{} \else \ifutx@Draft \def\@pointtableo[#1]{} \else \def\@pointtableo[#1]{\@pointtable{#1}} \fi \fi % If lastquestion not yet defined (no AUX file, because this is first run) % then make \@pointtable null. (If not, will get TeX error when run before % AUX file exists.) \ifutx@Solutions \def\@pointtable#1{} \else \ifutx@Draft \def\@pointtable#1{} \else \ifutx@Crowdmark \def\@pointtable#1{\@ifundefined{r@lastquestion}{}% {% \newcounter{NoCols}\setcounter{NoCols}{#1}% \newcounter{NoColsLeft}\setcounter{NoColsLeft}{#1}% \newcounter{NoOfQPerCol} \newcounter{NoOfQ} \newcounter{QLeft} \newcounter{QLimit}\setcounter{QLimit}{0} \hskip 0pt% attempt to correct vertical spacing (messes up horiz spacing) % first set NoOfQ equal to number of questions on test % (\setcounter doesn't seem to work with \ref{lastquestion}) \loop\ifnum\theNoOfQ<\ref{lastquestion}\addtocounter{NoOfQ}{1}\repeat \setcounter{QLeft}{\value{NoOfQ}} {\ifnum\theNoCols<4\large\fi% for crowdmark, use \large in all cases \ifnum\theNoCols=4\large\fi% \loop\ifnum\theNoColsLeft>0% \setcounter{NoOfQPerCol}{\value{QLeft}}% % divide NoOfQ by number of columns left to get NoOfQPerCol \divide\value{NoOfQPerCol} by\value{NoColsLeft}% \addtocounter{QLimit}{\value{NoOfQPerCol}}% \xdef\enoughrows{}% see p. 373 of TeXbook re. next few lines {\loop% must be within group (TeXbook example bottom p. 218) \ifnum\theqnumber<\theQLimit% \xdef\enoughrows{% \enoughrows% &\theqnumber&&\protect\ref{Q\theqnumber}&\cr% height2pt&\omit&&\omit&\cr% }% \addtocounter{qnumber}{1}% \repeat}% \xdef\enoughrows% add last row {% \enoughrows &\theqnumber&&\protect\ref{Q\theqnumber}&\cr% }% \hfil\MakePointTable\hfil% \addtocounter{qnumber}{1}% \addtocounter{NoColsLeft}{-1}% \addtocounter{QLeft}{-\value{NoOfQPerCol}}% \repeat% \ifnum\theNoCols>1{% \par\vskip 8mm\par\hfill\begin{tabular}{|c|c|}\hline\large Total&\protect\ref{pointtotal}\\\hline% \end{tabular}\hfill% }\fi% }% end of scope of \Large }% end of second argument of \@ifundefined }% end of @pointtable \else \def\@pointtable#1{\@ifundefined{r@lastquestion}{}% {% \vspace{5mm}\hspace*{\fill}For graders' use:\hspace*{\fill}\par \newcounter{NoCols}\setcounter{NoCols}{#1}% \newcounter{NoColsLeft}\setcounter{NoColsLeft}{#1}% \newcounter{NoOfQPerCol} \newcounter{NoOfQ} \newcounter{QLeft} \newcounter{QLimit}\setcounter{QLimit}{0} \hskip 0pt% attempt to correct vertical spacing (messes up horiz spacing) % first set NoOfQ equal to number of questions on test % (\setcounter doesn't seem to work with \ref{lastquestion}) \loop\ifnum\theNoOfQ<\ref{lastquestion}\addtocounter{NoOfQ}{1}\repeat \setcounter{QLeft}{\value{NoOfQ}} {\ifnum\theNoCols<4\Large\fi% if 4 or more cols, \Large doesn't fit \ifnum\theNoCols=4\large\fi% \loop\ifnum\theNoColsLeft>0% \setcounter{NoOfQPerCol}{\value{QLeft}}% % divide NoOfQ by number of columns left to get NoOfQPerCol \divide\value{NoOfQPerCol} by\value{NoColsLeft}% \addtocounter{QLimit}{\value{NoOfQPerCol}}% \xdef\enoughrows{}% see p. 373 of TeXbook re. next few lines {\loop% must be within group (TeXbook example bottom p. 218) \ifnum\theqnumber<\theQLimit% \xdef\enoughrows{% \enoughrows% &\theqnumber&(\protect\ref{Q\theqnumber})&&&\cr% \noalign{\hrule}% height2pt&\omit&\omit&&\omit&\cr% }% \addtocounter{qnumber}{1}% \repeat}% \xdef\enoughrows% add last row {% \enoughrows &\theqnumber&(\protect\ref{Q\theqnumber})&&&\cr% }% \hfil\MakePointTable\hfil% \addtocounter{qnumber}{1}% \addtocounter{NoColsLeft}{-1}% \addtocounter{QLeft}{-\value{NoOfQPerCol}}% \repeat% \ifnum\theNoCols>1{% \par\vskip 8mm\par\hfill\begin{tabular}{|c|c|}\hline\Large Total (\protect\ref{pointtotal})&\phantom{XXXX}\\\hline% \end{tabular}\hfill% }\fi% }% end of scope of \Large }% end of second argument of \@ifundefined }% end of @pointtable \fi \fi \fi % Miscellaneous commands unconnected with exam format \renewcommand{\descriptionlabel}[1]{\hspace\labelsep \normalfont\bfseries #1\phantom{.}} \setlength\tabcolsep{12\p@} \long\def\@makecaption#1#2{% \vskip\abovecaptionskip \sbox\@tempboxa{\footnotesize{\bf #1}. #2}% \ifdim \wd\@tempboxa >\hsize \footnotesize{\bf #1}. #2\par \else \global \@minipagefalse \hbox to\hsize{\hfil\box\@tempboxa\hfil}% \fi \vskip\belowcaptionskip} \def\argmax{\mathop{\rm arg\,max}} \def\argmin{\mathop{\rm arg\,min}} \def\realR{\mathbb{R}} \renewcommand{\section}{\@startsection {section}{1}{\z@}% {-3.5ex \@plus -1ex \@minus -.2ex}% {2.3ex \@plus.2ex}% {\reset@font\bfseries}} \renewcommand{\subsection}{\@startsection{subsection}{2}{\z@}% {-3.25ex\@plus -1ex \@minus -.2ex}% {1.5ex \@plus .2ex}% {\reset@font\itshape}} \renewcommand{\subsubsection}{\@startsection{subsubsection}{3}{\z@}% {-3.25ex\@plus -1ex \@minus -.2ex}% {-1em}% {\reset@font\normalsize\itshape}} \renewcommand{\paragraph}{\@startsection{paragraph}{4}{\z@}% {3.25ex \@plus1ex \@minus.2ex}% {-1em}% {\reset@font\normalsize\itshape}} \renewcommand{\subparagraph}{\@startsection{subparagraph}{5}{\parindent}% {3.25ex \@plus1ex \@minus .2ex}% {-1em}% {\reset@font\normalsize\bfseries}}