\def\coursehandbookdate{6 December 2024} \def\coursehandbookversion{1.0.3} \def\coursehandbookshortdate{2024/12/06} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Document class for course handbooks. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Version History % v1.0 Initial version. % v1.0.1 Added siunitx to required packages. % v1.0.2 Modified header generation to translate short teaching period strings % into long equivalents (e.g., "S1" => "Semester One"). % v1.0.3 Replaced deprecated ifpdf and ifxetex with iftex. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \NeedsTeXFormat{LaTeX2e}[2001/06/01] \ProvidesClass{coursehandbook}% [\coursehandbookshortdate\space v\coursehandbookversion\space INFO course handbook style] \RequirePackage{iftex} \RequirePackage{kvoptions} % Key-value option handling. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Option processing. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \SetupKeyvalOptions{family=handbook, prefix=handbook@} \DeclareBoolOption{showanswers} \DeclareComplementaryOption{hideanswers}{showanswers} \DeclareStringOption[INFO]{subjectcode} \DeclareStringOption[!!PAPER NUMBER UNDEFINED!!]{papernumber} \DeclareStringOption[!!PAPER TITLE UNDEFINED!!]{papertitle} \DeclareStringOption[!!PAPER YEAR UNDEFINED!!]{paperyear} \DeclareStringOption[!!PAPER PERIOD UNDEFINED!!]{paperperiod} \DeclareStringOption[!!AUTHORS UNDEFINED!!]{authors} % \DeclareBoolOption{pdftex} % \DeclareBoolOption{xetex} % % \ifxetex % \DeclareVoidOption{xetex} % \OptionNotUsed{pdftex} % \else\ifpdf % \DeclareBoolOption{pdftex} % \OptionNotUsed{xetex} % \else % \ClassError{coursehandbook}{The coursehandbook document class only\MessageBreak\ supports PDF(La)TeX and XeTeX.}{The coursehandbook document class only supoprts the pdftex and\MessageBreak\ xetex drivers. Please use one of these.} % \fi \DeclareDefaultOption{% \ifx\CurrentOptionValue\relax% \expandafter\PassOptionsToClass% \expandafter{\CurrentOption}{book}% \else% \@unknownoptionerror% \fi% } \ProcessKeyvalOptions* \LoadClass{book} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % A bunch o' packages. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ifxetex \RequirePackage{fontspec} % Font handling for XeTeX. \RequirePackage{xunicode} \RequirePackage{xltxtra} \else % Note that fontenc freaks out if any of the keyval option values % are surrounded by braces (?!). Spaces get eaten without braces, % so instead use \ in \documentclass to preserve them. \RequirePackage[T1]{fontenc} \RequirePackage{textcomp} \fi \RequirePackage{mathpazo} % Palatino for text and maths. \RequirePackage{graphicx} % Include graphics of all sorts. \RequirePackage{color} % Color handling. \RequirePackage[hmargin=68.393315pt,% Sensible margins, essentially the same as a4wide. top=107.1438pt,% bottom=116.90304pt]{geometry} % \RequirePackage{makeidx} \RequirePackage{amssymb} % AMS maths symbols. \RequirePackage{latexsym} % Extra LaTeX maths symbols. \RequirePackage{relalg} % Relational algebra symbols. % \RequirePackage{longtable} % For multi-page tables. \RequirePackage{multirow} % Multi-row cells in tables. \RequirePackage{rotating} % Rotate stuff. \RequirePackage{fancyhdr} % Fancy page headers & footers. \RequirePackage{verbatim} % Enhanced verbatim handling. \RequirePackage{listings} % Nicely formatted code listings. \RequirePackage[normalem]{ulem} % Fancy underlining, strike-through, etc. \usepackage[detect-all,binary-units]{siunitx} % SI unit and number formatting. % \RequirePackage{moreverb} % \RequirePackage{listings} % Pretty-print code listings; not currently used. \RequirePackage{count1to} % Needed to get the absolute page numbers. \RequirePackage{calc} % Needed to calculate page numbers for 2-up version. \RequirePackage{parskip} % Space-separated rather than indented paragraphs. \RequirePackage[% plainpages=false, % Stops pdfTeX complaining about duplicate page numbers. colorlinks=true,% urlcolor=blue, % Acceptable for print or screen linkcolor=blue, % Acceptable for print or screen bookmarks=true,% bookmarksopen=true,% bookmarksnumbered=true,% pdfpagemode=UseOutlines,% pdfstartview=FitB,% ]{hyperref} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Various setup macros to enable on-the-fly option changing. % These are particularly necessary for paper detail options (such as % papertitle) that may contain spaces. From the kvoptions documentation: % % ================================================== % * Spaces are removed, regardless where: % \documentclass[box=0 0 400 600]{article} % Now each package will see box=00400600 as global option. % % * In the previous case also braces would not help: % \documentclass[box={0 0 400 600}]{article} % The result is an error message: % ! LaTeX Error: Missing \begin{document}. % % * The requirements on robustness are extremly high. LATEX expands the % option. All that will not work as environment name will break also % as option. Even a \relax will generate an error message: % ! Missing \endcsname inserted. % Of course, LATEX does not use its protecting mechanisms. On contrary % \protect itself will cause errors. % ================================================== % % The upshot is that in the \documentclass, spaces are eaten, but we can't use % {} or macros like \space or "\ " to escape them. The only thing that does % work is: % % papertitle=some\csname space\endcsname name % % which is particularly ugly. A better solution is to follow the hyperref % model and have a "setup" macro that sets these options AFTER the % \documentclass. % % These also call \hypersetup to ensure that the PDF metadata match. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Set arbitrary class options. \newcommand{\handbooksetup}[1]{% \setkeys{handbook}{#1}% \@updatepdfmetadata% } % \papersetup is intended to be for setting paper detail options, but is % essentially just a synonym of \handbooksetup. \let\papersetup\handbooksetup % Macros for setting specific paper detail options. \newcommand{\setsubjectcode}[1]{% \@setpaperoption{subjectcode}{#1}% } \newcommand{\setpapernumber}[1]{% \@setpaperoption{papernumber}{#1}% } \newcommand{\setpapertitle}[1]{% \@setpaperoption{papertitle}{#1}% } \newcommand{\setpaperyear}[1]{% \expandafter\@setpaperoption{paperyear}{#1}% } \newcommand{\setpaperperiod}[1]{% \@setpaperoption{paperperiod}{#1}% } \newcommand{\setauthors}[1]{% \@setpaperoption{authors}{#1}% } \newcommand{\@setpaperoption}[2]{% \setkeys{handbook}{#1={#2}} \@updatepdfmetadata% } \def\@updatepdfmetadata{% \hypersetup{% pdftitle={\expandafter\handbook@subjectcode\ \expandafter\handbook@papernumber\ Handbook, \expandafter\handbook@paperyear},% pdfauthor={\expandafter\handbook@authors},% pdfsubject={Student Handbook for \expandafter\handbook@subjectcode\ \expandafter\handbook@papernumber, \expandafter\handbook@paperyear.}% }% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Set up fonts. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ifxetex \defaultfontfeatures{Mapping=tex-text} \setmainfont{TeX Gyre Pagella} \setmonofont[Scale=MatchLowercase]{Letter Gothic 12 Pitch} % Not sure about these? \setsansfont[Scale=MatchLowercase]{Futura Book} \newfontfamily\headerfont[Size=11]{Futura Light} \else \renewcommand{\sfdefault}{bfu} \renewcommand{\ttdefault}{blg} \DeclareFixedFont{\headerfont}{T1}{bfu}{lc}{n}{11} \fi %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Set up listings. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Pre-load the most obviously used languages. You can still use other languages, % just not as quickly. \lstloadlanguages{Oracle,Java} % Set defaults. \lstset{basicstyle=\ttfamily,basewidth=0.5em,escapeinside={(@}{@)}, showspaces=false,showstringspaces=false} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Miscellaneous stuff. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Useful macros for paper code, etc. \def\PaperCode{\expandafter\handbook@subjectcode\ \expandafter\handbook@papernumber} \def\ShortPaperCode{\expandafter\handbook@subjectcode\expandafter\handbook@papernumber} \def\PaperTitle{\expandafter\handbook@papertitle} \def\PaperYear{\expandafter\handbook@paperyear} \def\PaperPeriod{\expandafter\handbook@paperperiod} \def\HandbookAuthors{\expandafter\handbook@authors} % Stolen from ouexam :). \def\@SONE{S1} \def\@STWO{S2} \def\@SS{SS} \def\@FY{FY} \newcommand{\PaperLongPeriod}{% \ifx\handbook@paperperiod\@SONE Semester One% \else\ifx\handbook@paperperiod\@STWO Semester Two% \else\ifx\handbook@paperperiod\@SS Summer School% \else\ifx\handbook@paperperiod\@FY Full Year% \else\PaperPeriod% \fi\fi\fi\fi% } % Handbook name. \newcommand{\handbookname}{Student Handbook} % "Chapter" names. Note that the lab and tutorial names are dependent on % the setting of the showanswers class option. \newcommand{\introchaptername}{Introductory Chapter} \newcommand{\labname}{\ifhandbook@showanswers Selected Answers for \fi\PaperCode\ Lab} \newcommand{\tutorialname}{\ifhandbook@showanswers Selected Answers for \fi\PaperCode\ Tutorial} % listings.sty has problems with in-line verbatim code and fancy styles % (backgrounds, borders), hence this: \newcommand{\code}[1]{\texttt{#1}} % Other useful macros. \newcommand{\term}[1]{\textit{#1}} \newcommand{\foreign}[1]{\textit{#1}} \newcommand{\BookTitle}[1]{\textit{#1}} % Backslashes - what a pain! \newcommand{\bs}{\(\backslash{}\)} % We want "chapter" numbers to reset for each part. \@addtoreset{chapter}{part} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Set up fancy headings. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Although we don't actually use the "fancy" page style, we have to set it % initially in order for the page marks to be set up correctly. \pagestyle{fancy} \fancyhf{} % Page marks. \partmark is completely new, the others are standard. \newcommand{\partmark}[1]{\markboth{\partname\ \thepart---#1}{}} \renewcommand{\chaptermark}[1]{\markright{\@chapapp\ \thechapter---#1}} \renewcommand{\sectionmark}[1]{} \setlength{\headheight}{15pt} % No running head or foot rules. \renewcommand{\headrulewidth}{0pt} \renewcommand{\footrulewidth}{0pt} % Use | to separate items in the header/footer. \newcommand{\LeftHeadingBullet}{\(\vert\)} \newcommand{\RightHeadingBullet}{\(\vert\)} \newlength{\HeadingBulletSpacing} \setlength{\HeadingBulletSpacing}{0.5em} % The headers and footers are set up as follows, where "TOC" = table of % contents, "1st" = first page of part or chapter, "part" = title page of % a part, "plain" = plain page style, "empty" = empty page style, % "#" = page number, "LO" = left odd, "RE" = right even, etc. If something % isn't mentioned, it's empty. % % Note that we're optimising for 2-up printing, so the placement of page % numbers on even/odd pages is the opposite of what you'd normally expect. % TODO: make this a switchable option? % % Headers: % {plain,TOC} LO # | <subjectcode> <papernumber> STUDENT HANDBOOK % {plain,TOC} RO <paperperiod>, <paperyear> % TOC LE <empty> % TOC RE CONTENTS | # % plain LE PART <partnumber>---<parttitle> % plain RE <sectiontype> <sectionnumber>---<sectiontitle> | # % {empty,1st,part} * <empty> % % Footers: % {plain,TOC,empty,part} * <empty> % 1st LO # | % 1st RE | # % % For ease of definition, here are some macros: \def\@plainHeadLO{\headerfont{\thepage{}\hspace{\HeadingBulletSpacing}\LeftHeadingBullet\hspace{\HeadingBulletSpacing}\MakeUppercase{\PaperCode\ \handbookname}}} \def\@plainHeadRO{\headerfont{\MakeUppercase{\PaperLongPeriod, \PaperYear}}} \def\@plainHeadLE{\headerfont{\MakeUppercase{\leftmark}}} \def\@plainHeadRE{\headerfont{\MakeUppercase{\rightmark}\hspace{\HeadingBulletSpacing}\RightHeadingBullet\hspace{\HeadingBulletSpacing}\thepage}} \def\@tocHeadLE{} \def\@tocHeadRE{\headerfont{\MakeUppercase{\contentsname}\hspace{\HeadingBulletSpacing}\RightHeadingBullet\hspace{\HeadingBulletSpacing}\thepage}} \def\@firstFootLO{\headerfont{\thepage\hspace{\HeadingBulletSpacing}\LeftHeadingBullet}} \def\@firstFootRO{\headerfont{\LeftHeadingBullet\hspace{\HeadingBulletSpacing}\thepage}} % Plain style is automatically set when we use \chapter or \part, but % this becomes a bit complicated, because we want a different appearance % for the first page of a chapter (simple footer only) vs. the title page of % a part (no header or footer at all). The simplest solution seems to be to % define a \newif that tells us if we're in part mode (default false) and sets % up the style accordingly. We then just have to overload the original % \chapter and \part macros to set the flag appropriately (see below). \newif\if@inpart \@inpartfalse \fancypagestyle{plain}{% \fancyhf{}% \if@inpart\else% \fancyfoot[LO]{\headerfont{\thepage\hspace{\HeadingBulletSpacing}\LeftHeadingBullet}}% \fancyfoot[RE]{\headerfont{\LeftHeadingBullet\hspace{\HeadingBulletSpacing}\thepage}}% \fi% } % Heading style for table of contents. \fancypagestyle{toc}{% \fancyhf{}% \fancyhead[LO]{\@plainHeadLO}% \fancyhead[RO]{\@plainHeadRO}% \fancyhead[LE]{\@tocHeadLE}% \fancyhead[RE]{\@tocHeadRE}% } % "normal" is the new "plain" :) % We use this rather than just \pagestyle{fancy}, because we need to % explicitly switch styles in a couple of places (e.g., TOC). It would % probably have made more sense to just redefine the "fancy" style, but % that seems to make LaTeX grind to a halt. \fancypagestyle{normal}{% \fancyhf{}% \fancyhead[LO]{\@plainHeadLO}% \fancyhead[RO]{\@plainHeadRO}% \fancyhead[LE]{\@plainHeadLE}% \fancyhead[RE]{\@plainHeadRE}% } \pagestyle{normal} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Create title page. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\maketitlepage}{% % TODO: % - Add University logo? \thispagestyle{empty}% \vspace*{\stretch{1}}% \begin{flushright}% \Huge\PaperCode \\% \PaperTitle \\% \rule{\textwidth}{3pt} \\[0.25\baselineskip]% \huge \handbookname \\[1.1\baselineskip]% \Large\HandbookAuthors% \end{flushright}% \vspace*{\stretch{2}}% \begin{center}% \scshape\Large Department of Information Science \\% University of Otago \\[0.25\baselineskip]% \PaperYear% \end{center}% \vspace*{\stretch{0.3}}% \clearpage\thispagestyle{empty}% blank, empty page } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Table of contents. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Add a wrapper around the book class's \tableofcontents macro so we can % easily change the page style for the TOC section (and more importantly, % change it back). This also lets us hook in our own tracking of various % things like chapter titles. \let\@booktableofcontents\tableofcontents \renewcommand\tableofcontents{% \pagestyle{toc}% \@booktableofcontents% \clearpage\thispagestyle{toc}% \pagestyle{normal}% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Different modes for different parts of the document. The behaviour here % is analogous to the \appendix macro. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This macro updates relevant internal parameters in hyperref so that % correct PDF bookmarks are generated. \newcommand\@hyperrefsetup[1]{% \def\Hy@chapapp{#1}% \renewcommand{\theHchapter}{\theHpart.\arabic{chapter}}% \renewcommand{\theHsection}{\theHpart.\theHchapter.\arabic{section}}% \renewcommand{\theHsubsection}{\theHpart.\theHchapter.\theHsection.\arabic{subsection}}% \renewcommand{\theHsubsubsection}{\theHpart.\theHchapter.\theHsection.\theHsubsection.\arabic{subsubsection}}% } % Introduction part. \newcommand\intro{% \gdef\@chapapp{\introchaptername}% \@hyperrefsetup{introchapter}% } % Labs part. \newcommand\labs{% \gdef\@chapapp{\labname}% \@hyperrefsetup{lab}% } % Tutorials part. \newcommand\tutorials{% \gdef\@chapapp{\tutorialname}% \@hyperrefsetup{tutorial}% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Sectioning. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Wrappers for \chapter for each of labs, tutorials and "ordinary" chapters. % These all make the chapter title available through \CurrentChapterTitle. % % TODO: I wanted to override \chapter and refactor \general to \chapter, but % the TOC seems to wig out when I try it. Probably not that crucial... %\let\@bookchapter\chapter % % \renewcommand{\chapter}[1]% % {% % \@bookchapter{#1}% % \renewcommand{\CurrentChapterTitle}{#1}% % } % % TODO: prehaps rename \general to \introchapter? \newcommand{\general}[1]{\@inpartfalse\chapter{#1}} \newcommand{\lab}[1]{\@inpartfalse\chapter{#1}} \newcommand{\tutorial}[1]{\@inpartfalse\chapter{#1}} \newcommand{\handbookpart}[1]{\@inparttrue\part{#1}\partmark{#1}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Answers handling. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ifhandbook@showanswers \newenvironment{answer}{\par\vspace{0.5em}\itshape}{\normalfont\vspace{0.5em}} \else \newenvironment{answer}{% \@bsphack% \let\do\@makeother\dospecials\catcode`\^^M\active% \let\verbatim@startline\relax% \let\verbatim@addtoline\@gobble% \let\verbatim@processline\relax% \let\verbatim@finish\relax% \verbatim@% }{\@esphack} \fi %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Set up auxiliary file so that we can write out the first and last % absolute page number for each tutorial and lab exercise. We can then use % this to automatically generate a separate PDF for each exercise. % \newcounter{absolutepage} \newcounter{absolutepagetwoup} \newcommand{\markfirstpage}[1]{% \setcounter{absolutepage}{\the\count1}% \stepcounter{absolutepage}% \immediate\write\@auxout{\string\@writefile{bmk}{\string#1.1up.first=\theabsolutepage}}% \setcounter{absolutepagetwoup}{\value{absolutepage}/2+1}% \immediate\write\@auxout{\string\@writefile{bmk}{\string#1.2up.first=\theabsolutepagetwoup}}% } \newcommand{\marklastpage}[1]{% \cleardoublepage% can't just add 1 because we may be skipping 2 pages \immediate\write\@auxout{\string\@writefile{bmk}{\string#1.1up.last=\the\count1}}% \setcounter{absolutepagetwoup}{\the\count1/2}% \immediate\write\@auxout{\string\@writefile{bmk}{\string#1.2up.last=\theabsolutepagetwoup}}% } \endinput