% \iffalse meta-comment % An Infrastructure for marking up Assignments % Copyright (c) 2007 Michael Kohlhase, all rights reserved % this file is released under the % LaTeX Project Public License (LPPL) % The original of this file is in the public repository at % http://github.com/KWARC/sTeX/ % \fi % % \iffalse %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{hwexam}[2019/03/20 v1.1 homework assignments and exams] %\ProvidesClass{hwexam}[2019/03/20 v1.1 assignment and exam documents] % %<*driver> \documentclass{ltxdoc} \usepackage[utf8]{inputenc} \usepackage{url,float} \usepackage{hwexam} \usepackage[show]{ed} \usepackage[hyperref=auto,style=alphabetic]{biblatex} \addbibresource{kwarcpubs.bib} \addbibresource{extpubs.bib} \addbibresource{kwarccrossrefs.bib} \addbibresource{extcrossrefs.bib} \usepackage{stex-logo} \usepackage{ctangit} \usepackage{hyperref} \makeindex \floatstyle{boxed} \newfloat{exfig}{thp}{lop} \floatname{exfig}{Example} \def\githubissue#1{\cite{sTeX:github:on}, \hyperlink{https://github.com/KWARC/sTeX/issues/#1}{issue #1}} \begin{document} \RecordChanges \DocInput{hwexam.dtx} \end{document} % % \fi %\CheckSum{464} % % \changes{v0.9}{2006/09/18}{First Version with Documentation} % \changes{v0.9a}{2010/06/25}{more semantic headers for exams} % \changes{v0.9b}{2010/09/20}{adding \texttt{assignment.cls}} % \changes{v0.9c}{2010/09/20}{renaming from \texttt{assignment} to \texttt{hwexam} to % avoid name clashes with existing \texttt{assignment.cls} on CTAN.} % \changes{v1.0}{2013/12/12}{adding MathHub support} % \changes{v1.1}{2015/11/04}{moving MathHub support out to separate package} % % \GetFileInfo{hwexam.sty} % % \MakeShortVerb{\|} % \def\scsys#1{{{\sc #1}}\index{#1@{\sc #1}}} % \def\latexml{\scsys{LaTeXML}} % % \title{\texttt{hwexam.sty/cls}: An Infrastructure for formatting Assignments % and Exams\thanks{Version {\fileversion} (last revised {\filedate})}} % \author{Michael Kohlhase\\ % FAU Erlangen-N\"urnberg\\ % \url{http://kwarc.info/kohlhase}} % \maketitle % % \begin{abstract} % The |hwexam| package and class allows individual course assignment sheets and % compound assignment documents using problem files marked up with the |problem| package. % \end{abstract} % \setcounter{tocdepth}{2}\tableofcontents\newpage % %\section{Introduction}\label{sec:intro} % % The |hwexam| package and class supplies an infrastructure that allows to format % nice-looking assignment sheets by simply including problems from problem files marked up % with the |problem| package~\cite{Kohlhase:problem:ctan}. It is designed to be % compatible with |problems.sty|, and inherits some of the functionality. % % \section{The User Interface} % % \subsection{Package and Class Options}\label{sec:user:options} % % The |hwexam| class takes the \DescribeMacro{mh}|mh| option that turns on MathHub % support. % % The |hwexam| package and class take the options |solutions|, |notes|, |hints|, |pts|, % |min|, and |boxed| that are just passed on to the |problems| package (cf. its % documentation for a description of the intended behavior). % % If the \DescribeMacro{showmeta}|showmeta| option is set, then the metadata keys are % shown (see~\cite{Kohlhase:metakeys:ctan} for details and customization options). % % The |hwexam| class additionally accepts the options |report|, |book|, |chapter|, |part|, % and |showignores|, of the |omdoc| package~\cite{Kohlhase:smomdl:ctan} on which it is % based and passes them on to that. For the |extrefs| option % see~\cite{Kohlhase:sref:ctan}. % % \subsection{Assignments} % % This package supplies the \DescribeEnv{assignment}|assignment| environment that groups % problems into assignment sheets. It takes an optional KeyVal argument with the keys % \DescribeMacro{number}|number| (for the assignment number; if none is given, 1 is % assumed as the default or --- in multi-assignment documents --- the ordinal of the % |assignment| environment), \DescribeMacro{title}|title| (for the assignment title; this % is referenced in the title of the assignment sheet), \DescribeMacro{type}|type| (for the % assignment type; e.g. ``quiz'', or ``homework''), \DescribeMacro{given}|given| (for the % date the assignment was given), and \DescribeMacro{due}|due| (for the date the % assignment is due). % % \subsection{Typesetting Exams} % % Furthermore, the |hwexam| package takes the option % \DescribeMacro{multiple}|multiple| that allows to combine multiple assignment sheets into % a compound document (the assignment sheets are treated as section, there is a table of % contents, etc.). % % Finally, there is the option \DescribeMacro{test}|test| that modifies the behavior to % facilitate formatting tests. Only in |test| mode, the macros |\testspace|, % |\testnewpage|, and |\testemptypage| have an effect: they generate space for the % students to solve the given problems. Thus they can be left in the {\LaTeX} source. % % \DescribeMacro{\testspace}|\testspace| takes an argument that expands to a dimension, % and leaves vertical space accordingly. \DescribeMacro{\testnewpage}|\testnewpage| makes % a new page in |test| mode, and \DescribeMacro{\testemptypage}|\testemptypage| generates % an empty page with the cautionary message that this page was intentionally left empty. % % Finally, the \DescribeEnv{testheading}|\testheading| takes an optional keyword argument % where the keys \DescribeMacro{duration}|duration| specifies a string that specifies the % duration of the test, \DescribeMacro{min}|min| specifies the equivalent in number of % minutes, and \DescribeMacro{reqpts}|reqpts| the points that are required for a perfect % grade. % \begin{exfig}[ht] % \makeatletter % \@problem{1.1}{4}{10} % \@problem{2.1}{4}{8} % \@problem{2.2}{6}{10} % \@problem{2.3}{6}{10} % \@problem{3.1}{4}{8} % \@problem{3.2}{4}{8} % \@problem{3.3}{2}{4} % \makeatother % \begin{verbatim} % \title{320101 General Computer Science (Fall 2010)} % \begin{testheading}[duration=one hour,min=60,reqpts=27] % Good luck to all students! % \end{testheading} % \end{verbatim} % \vspace*{-3ex}\hrule\vspace*{.5ex} formats to\vspace*{1ex} % \hrule\par\noindent\vspace*{2ex} % \title{320101 General Computer Science (Fall 2010)} % \begin{testheading}[duration=one hour,min=60,reqpts=27] % good luck % \end{testheading} % \caption{A generated test heading.}\label{fig:testheading} % \end{exfig} % % \subsection{Including Assignments} % % The \DescribeMacro{\includeassignment}|\includeassignment| macro can be used to include % an assignment from another file. It takes an optional KeyVal argument and a second % argument which is a path to the file containing the problem (the macro assumes that % there is only one |assignment| environment in the included file). The keys % \DescribeMacro{number}|number|, \DescribeMacro{title}|title|, % \DescribeMacro{type}|type|, \DescribeMacro{given}|given|, and \DescribeMacro{due}|due| % are just as for the |assignment| environment and (if given) overwrite the ones specified % in the |assignment| environment in the included file. % % \section{Limitations}\label{sec:limitations} % % In this section we document known limitations. If you want to help alleviate them, % please feel free to contact the package author. Some of them are currently discussed in % the \sTeX GitHub repository~\cite{sTeX:github:on}. % \begin{enumerate} % \item none reported yet. % \end{enumerate} % % \StopEventually{\newpage\PrintIndex\newpage\PrintChanges\printbibliography}\newpage % \newpage % % \section{Implementation: The hwexam Class}\label{sec:impl:cls} % % The functionality is spread over the |hwexam| class and package. The class provides % the |document| environment and pre-loads some convenience packages, whereas the package % provides the concrete functionality. % % \subsection{Class Options}\label{sec:impl:cls:options} % % To initialize the |hwexam| class, we declare and process the necessary options by % passing them to the respective packages and classes they come from. % % \begin{macrocode} %<*cls> \DeclareOption*{ \PassOptionsToClass{\CurrentOption}{omdoc} \PassOptionsToPackage{\CurrentOption}{stex} \PassOptionsToPackage{\CurrentOption}{hwexam} \PassOptionsToPackage{\CurrentOption}{tikzinput} } \ProcessOptions % \end{macrocode} % % We load |omdoc.cls|, and the desired packages. For the {\latexml} bindings, we make % sure the right packages are loaded. % % \begin{macrocode} \LoadClass{omdoc} \RequirePackage{stex} \RequirePackage{hwexam} \RequirePackage{tikzinput} \RequirePackage{graphicx} \RequirePackage{a4wide} \RequirePackage{amssymb} \RequirePackage{amstext} \RequirePackage{amsmath} % \end{macrocode} % Finally, we register another keyword for the |document| environment. We give a default % assignment type to prevent errors % \begin{macrocode} \newcommand\assig@default@type{\hwexam@assignment@kw} \addmetakey[\assig@default@type]{document}{hwexamtype} \def\document@hwexamtype{\assig@default@type} % % \end{macrocode} % % \section{Implementation: The hwexam Package} % % \subsection{Package Options} % % The first step is to declare (a few) package options that handle whether certain % information is printed or not. Some come with their own conditionals that are set by the % options, the rest is just passed on to the |problems| package. % % \begin{macrocode} %<*package> \newif\if@hwexam@mh@\@hwexam@mh@false \DeclareOption{mh}{\@hwexam@mh@true} \newif\iftest\testfalse \DeclareOption{test}{\testtrue} \newif\ifmultiple\multiplefalse \DeclareOption{multiple}{\multipletrue} \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{problem}} \ProcessOptions % \end{macrocode} % Then we make sure that the necessary packages are loaded (in the right versions). % \begin{macrocode} \RequirePackage{keyval}[1997/11/10] \if@hwexam@mh@\RequirePackage{hwexam-mh}\fi \RequirePackage{problem} % \end{macrocode} % % \begin{macro}{\hwexam@*@kw} % For multilinguality, we define internal macros for keywords that can be specialized in % |*.ldf| files. % \begin{macrocode} \AfterBabelLanguage{ngerman}{\input{hwexam-ngerman.ldf}} \AfterBabelLanguage{arabic}{\input{hwexam-arabic.ldf}} \newcommand\hwexam@assignment@kw{Assignment} \newcommand\hwexam@given@kw{Given} \newcommand\hwexam@due@kw{Due} \newcommand\hwexam@testemptypage@kw{This page was intentionally left blank for extra space}% \newcommand\correction@probs@kw{prob.}% \newcommand\correction@pts@kw{total}% \newcommand\correction@reached@kw{reached}% \newcommand\correction@sum@kw{Sum}% \newcommand\correction@grade@kw{grade}% \newcommand\correction@forgrading@kw{To be used for grading, do not write here} % \end{macrocode} % \end{macro} % % \subsection{Assignments} % % Then we set up a counter for problems and make the problem counter inherited from % |problem.sty| depend on it. Furthermore, we specialize the |\prob@label| macro to take % the assignment counter into account. % \begin{macrocode} \newcounter{assignment} \numberproblemsin{assignment} \renewcommand\prob@label[1]{\arabic{assignment}.#1} % \end{macrocode} % % We will prepare the keyval support for the |assignment| environment. % % \begin{macrocode} \srefaddidkey{assig} \addmetakey{assig}{number} \addmetakey*{assig}{title} \addmetakey{assig}{type} \addmetakey{assig}{given} \addmetakey{assig}{due} \addmetakey[false]{assig}{loadmodules}[true] % \end{macrocode} % % The next three macros are intermediate functions that handle the case gracefully, where % the respective token registers are undefined. % % The |\given@due| macro prints information about the given and due status of the % assignment. Its arguments specify the brackets. % % \begin{macrocode} \newcommand\given@due[2]{% \ifx \inclassig@given\@empty \ifx \assig@given\@empty \ifx \inclassig@due\@empty \ifx \assig@due\@empty% all empty do nothing \else #1% \fi \else #1% \fi \else #1% \fi \else #1% \fi \ifx\inclassig@given\@empty \ifx\assig@given\@empty% do nothing \else \hwexam@given@kw\xspace \assig@given% \fi \else \hwexam@given@kw\xspace \inclassig@given% \fi \ifx \inclassig@due\@empty \ifx \assig@due\@empty% do nothing \else \ifx \inclassig@given\@empty \ifx \assig@given\@empty% do nothing \else ,~% \fi \else ,~% \fi \fi \else \ifx \inclassig@given\@empty \ifx \assig@given\@empty% do nothing \else ,~% \fi \else ,~% \fi \fi \ifx \inclassig@due\@empty \ifx \assig@due\@empty% do nothing \else \hwexam@due@kw\xspace \assig@due% \fi \else \hwexam@due@kw\xspace \inclassig@due% \fi \ifx \inclassig@given\@empty \ifx \assig@given\@empty \ifx \inclassig@due\@empty \ifx \assig@due\@empty% all empty do nothing \else #2% \fi \else #2% \fi \else #2% \fi \else #2% \fi } % \end{macrocode} % % \begin{macro}{\assignment@title} % This macro prints the title of an assignment, the local title is overwritten, if there % is one from the |\includeassignment|. |\assignment@title| takes three arguments the % first is the fallback when no title is given at all, the second and third go around % the title, if one is given. % \begin{macrocode} \newcommand\assignment@title[3] {\ifx\inclassig@title\@empty% if there is no outside title \ifx\assig@title\@empty{#1}\else{#2\assig@title{#3}}\fi \else{#2}\inclassig@title{#3}\fi}% else show the outside title % \end{macrocode} % \end{macro} % % \begin{macro}{\assignment@number} % Like |\assignment@title| only for the number, and no around part. % \begin{macrocode} \newcommand\assignment@number% {\ifx\inclassig@number\@empty% if there is no outside number \ifx\assig@number\@empty\else\assig@number\fi \else\inclassig@number\fi}% else show the outside number % \end{macrocode} % \end{macro} % % With them, we can define the central |assignment| environment. This has two forms % (separated by |\ifmultiple|) in one we make a title block for an assignment sheet, and % in the other we make a section heading and add it to the table of contents. We first % define an assignment counter % % \begin{environment}{assignment} % For the |assignment| environment we delegate the work to the |@assignment| environment % that depends on whether |multiple| option is given. % \begin{macrocode} \newenvironment{assignment}[1][]{\metasetkeys{assig}{#1}\sref@target% \edef\@@num{\assignment@number}% \ifx\@@num\@empty\stepcounter{assignment}\else\setcounter{assignment}{\@@num}\fi% \setcounter{problem}{0}% \def\current@section@level{\document@hwexamtype}% \sref@label@id{\document@hwexamtype \thesection}% \begin{@assignment}} {\end{@assignment}} % \end{macrocode} % In the multi-assignment case we just use the |omdoc| environment for suitable % sectioning. % \begin{macrocode} \def\@@asstitle{\protect\document@hwexamtype~\arabic{assignment}% \assignment@title{}{\;(}{)\;} -- \given@due{}{}} \ifmultiple \newenvironment{@assignment}% {\ifx\assig@loadmodules\@true \begin{omgroup}[loadmodules]{\@@asstitle} \else \begin{omgroup}{\@@asstitle} \fi} {\end{omgroup}} % \end{macrocode} % for the single-page case we make a title block from the same components. % \begin{macrocode} \else \newenvironment{@assignment} {\begin{center}\bf \Large\@title\strut\\ \document@hwexamtype~\arabic{assignment}\assignment@title{\;}{:\;}{\\}% \large\given@due{--\;}{\;--} \end{center}} {} \fi% multiple % \end{macrocode} % \end{environment} % % \subsection{Including Assignments} % % \begin{macro}{\in*assignment} % This macro is essentially a glorified |\include| statement, it just sets some internal % macros first that overwrite the local points Importantly, it resets the |inclassig| % keys after the input. % \begin{macrocode} \addmetakey{inclassig}{number} \addmetakey*{inclassig}{title} \addmetakey{inclassig}{type} \addmetakey{inclassig}{given} \addmetakey{inclassig}{due} \addmetakey{inclassig}{mhrepos} \clear@inclassig@keys%initially \newcommand\includeassignment[2][]{\metasetkeys{inclassig}{#1}% \include{#2}\clear@inclassig@keys} \newcommand\inputassignment[2][]{\metasetkeys{inclassig}{#1}% \input{#2}\clear@inclassig@keys} % \end{macrocode} % \end{macro} % % \subsection{Typesetting Exams} % % \begin{macro}{\quizheading} % \begin{macrocode} \addmetakey{quizheading}{tas} \newcommand\quizheading[1]{\def\@tas{#1}% \large\noindent NAME: \hspace{8cm} MAILBOX:\\[2ex]% \ifx\@tas\@empty\else% \noindent TA: \@for\@I:=\@tas\do{{\Large$\Box$}\@I\hspace*{1em}}\\[2ex]\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\testheading} % \begin{macrocode} \addmetakey{testheading}{min} \addmetakey{testheading}{duration} \addmetakey{testheading}{reqpts} \newenvironment{testheading}[1][]{\metasetkeys{testheading}{#1} {\noindent\large{}Name: \hfill Matriculation Number:\hspace*{2cm}\strut\\[1ex] \begin{center}\Large\textbf{\@title}\\[1ex]\large\@date\\[3ex]\end{center} {\textbf{You have \ifx\testheading@duration\@empty\testheading@min minutes\else\testheading@duration\fi (sharp) for the test}};\\ Write the solutions to the sheet.}\par\noindent \newcount\check@time\check@time=\testheading@min \advance\check@time by -\theassignment@totalmin The estimated time for solving this exam is {\theassignment@totalmin} minutes, leaving you {\the\check@time} minutes for revising your exam. \newcount\bonus@pts\bonus@pts=\theassignment@totalpts \advance\bonus@pts by -\testheading@reqpts You can reach {\theassignment@totalpts} points if you solve all problems. You will only need {\testheading@reqpts} points for a perfect score, i.e.\ {\the\bonus@pts} points are bonus points. \vfill \begin{center} {\Large\em % You have ample time, so take it slow and avoid rushing to mistakes!\\[2ex] Different problems test different skills and knowledge, so do not get stuck on one problem.}\vfill\par\correction@table \\[3ex] \end{center}} {\newpage} % \end{macrocode} % \end{macro} % % \begin{macro}{\testspace} % \begin{macrocode} \newcommand\testspace[1]{\iftest\vspace*{#1}\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\testnewpage} % \begin{macrocode} \newcommand\testnewpage{\iftest\newpage\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\testemptypage} % \begin{macrocode} \newcommand\testemptypage[1][]{\iftest\begin{center}\hwexam@testemptypage@kw\end{center}\vfill\eject\else\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\@problem} % This macro acts on a problem's record in the |*.aux| file. Here we redefine it (it was % defined to do nothing in |problem.sty|) to generate the correction table. % \begin{macrocode} \renewcommand\@problem[3]{\stepcounter{assignment@probs} \def\@@pts{#2}\ifx\@@pts\@empty\else\addtocounter{assignment@totalpts}{#2}\fi \def\@@min{#3}\ifx\@@min\@empty\else\addtocounter{assignment@totalmin}{#3}\fi \xdef\correction@probs{\correction@probs & #1}% \xdef\correction@pts{\correction@pts & #2} \xdef\correction@reached{\correction@reached &}} % \end{macrocode} % \end{macro} % % \begin{macro}{\correction@table} % This macro generates the correction table % \begin{macrocode} \newcounter{assignment@probs} \newcounter{assignment@totalpts} \newcounter{assignment@totalmin} \def\correction@probs{\correction@probs@kw}% \def\correction@pts{\correction@pts@kw}% \def\correction@reached{\correction@reached@kw}% \def\after@correction@table{}% \stepcounter{assignment@probs} \newcommand\correction@table{\begin{tabular}{|l|*{\theassignment@probs}{c|}|l|}\hline% &\multicolumn{\theassignment@probs}{c||}%| {\footnotesize\correction@forgrading@kw} &\\\hline \correction@probs & \correction@sum@kw & \correction@grade@kw\\\hline \correction@pts &\theassignment@totalpts & \\\hline \correction@reached & & \\[.7cm]\hline \end{tabular} \ifx\after@correction@table\@empty\else\strut\par\noindent\after@correction@table\fi} % % \end{macrocode} % \end{macro} % % \subsection{Leftovers} % % at some point, we may want to reactivate the logos font, then we use % \begin{verbatim} % here we define the logos that characterize the assignment % \font\bierfont=../assignments/bierglas % \font\denkerfont=../assignments/denker % \font\uhrfont=../assignments/uhr % \font\warnschildfont=../assignments/achtung % % \newcommand\bierglas{{\bierfont\char65}} % \newcommand\denker{{\denkerfont\char65}} % \newcommand\uhr{{\uhrfont\char65}} % \newcommand\warnschild{{\warnschildfont\char 65}} % \newcommand\hardA{\warnschild} % \newcommand\longA{\uhr} % \newcommand\thinkA{\denker} % \newcommand\discussA{\bierglas} % \end{verbatim} % \Finale \endinput % \iffalse % LocalWords: GPL structuresharing STR iffalse cls NeedsTeXFormat hwexam hwexam.dtx sc %%% Local Variables: %%% mode: doctex %%% TeX-master: t %%% End: % \fi % LocalWords: texttt scsys sc latexml fileversion filedate maketitle setcounter newpage % LocalWords: tocdepth tableofcontents pts showmeta showmeta showignores omdoc extrefs % LocalWords: testspace testnewpage testemptypage testheading testheading reqpts reqpts % LocalWords: exfig makeatletter makeatother vspace hrule vspace vspace noindent textsf % LocalWords: includeassignment includeassignment HorIacJuc cscpnrr11 importmodule baz % LocalWords: includemhassignment includemhassignment importmhmodule foobar ldots sref % LocalWords: mhcurrentrepos mh-variants mh-variant compactenum printbibliography Cwd % LocalWords: langle rangle langle rangle ltxml.cls ltxml.sty respetively metakeys qw % LocalWords: cwd stex graphicx amssymb amstext amsmath newif iftest testfalse testtrue % LocalWords: ifsolutions solutionsfalse ifmultiple multiplefalse multipletrue keyval % LocalWords: ltxml assig srefaddidkey addmetakey ifx assignment@titleblock stepcounter % LocalWords: document@hwexamtype importmodules metasetkeys inclassig@title inclassig % LocalWords: inclassig@title inclassig@type inclassig@type inclassig@number xspace kv % LocalWords: inclassig@number inclassig@due inclassig@due inclassig@given ignorespaces % LocalWords: inclassig@given newenvironment currentsectionlevel OptionalKeyVals kvi % LocalWords: omgroup vals hwexamtype ednote textbackslash newcommand inputassignment % LocalWords: unlist quizheading tas hspace hfill textbf newcount vfill addtocounter % LocalWords: theassignment@totalmin theassignment@totalpts assignment@probs xdef hline % LocalWords: assignment@totalpts assignment@totalmin correction@probs correction@probs % LocalWords: newcounter theassignment@probs footnotesize mh@currentrepos endinput % LocalWords: inclassig@mhrepos inclassig@mhrepos doctex inputmhassignment