diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/webquiz/webquiz.cls')
-rw-r--r-- | Master/texmf-dist/tex/latex/webquiz/webquiz.cls | 391 |
1 files changed, 391 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/webquiz/webquiz.cls b/Master/texmf-dist/tex/latex/webquiz/webquiz.cls new file mode 100644 index 00000000000..29e6f22675e --- /dev/null +++ b/Master/texmf-dist/tex/latex/webquiz/webquiz.cls @@ -0,0 +1,391 @@ +% ----------------------------------------------------------------------- +% webquiz.cls | webquiz latex class file +% ----------------------------------------------------------------------- +% +% Copyright (C) Andrew Mathas, University of Sydney +% +% Distributed under the terms of the GNU General Public License (GPL) +% http://www.gnu.org/licenses/ +% +% This file is part of the WebQuiz system. +% +% <Andrew.Mathas@sydney.edu.au> +% ---------------------------------------------------------------------- + +\NeedsTeXFormat{LaTeX2e}[1996/12/01] + +% load webquiz-ini style +\input{webquiz-ini.code} + +% ---------------------------------------------------------------------- +\ProvidesClass{webquiz}[\webquiz{release date} Version \webquiz{version}] + +% initialise and then process document class options usng pgfopts +\RequirePackage{etoolbox} +\RequirePackage{pgfopts} +\def\unknown@options{}% unknown options are passed to article.cls +\def\WQ@HideSideMenu{DeFaUlT}% side menu visible by default +\newif\ifWQ@Tikz\WQ@Tikzfalse% true if tikz a document class option + +\newif\ifWQ@Debugging % for the debugging class option +% Process the documentclass options using pgfkeys and \ProcessPgfOptions +\pgfkeys{/WQ@ClassOptions/.is family, + /WQ@ClassOptions, + % turn debugging on + debugging/.code = {\WQ@Debuggingtrue}, + % pst2pdf + pst2pdf/.style = {pst2pdf value=true}, + pst2pdf value/.initial = false, + % languaage + language/.initial = DeFaUlT, + % one page + onepage/.style = {onepage value=true}, + separatepages/.style = {onepage value=false}, + onepage value/.initial = DeFaUlT, + % side menu + showsidemenu/.style = {hidesidemenu value=false}, + hidesidemenu/.style = {hidesidemenu value=true}, + hidesidemenu value/.initial= DeFaUlT, + % random order of quiz questions + randomorder/.style = {randomorder value=true}, + fixedorder/.style = {randomorder value=false}, + randomorder value/.initial = DeFaUlT, + % theme + theme/.initial = DeFaUlT, + % tikz + tikz/.code = {\global\WQ@Tikztrue}, + % unknown options => passed to article class + .unknown/.code={\edef\unknown@options{\unknown@options,\pgfkeyscurrentname}} +} +\newcommand\WQ@ClassOption[1]{\pgfkeysvalueof{/WQ@ClassOptions/#1}} + +% Use pgfkeys to check for valid options for the choice environment and the +% answer comparisons. As \ERROR is not defined an error message is +% generated by the unknown handlers below +\pgfkeys{/webquiz checker/.is family, /webquiz checker, + mode/.initial = single, + columns value/.initial = 1, + columns/.style = {columns value=#1}, + single/.style = {mode=single}, + multiple/.style = {mode=multiple}, + .unknown/.code = {\ERROR: invalid choice type: use single or multiple} + comparison/.is choice, + comparison/complex/.code = \relax, + comparison/integer/.code = \relax, + comparison/lowercase/.code = \relax, + comparison/number/.code = \relax, + comparison/string/.code = \relax, + comparison/.unknown/.code = {\ERROR: invalid input type: use integer, string or eval} +} + +% now process the options +\ProcessPgfOptions{/WQ@ClassOptions}% process options +\LoadClass[\unknown@options]{article}% load article class with options + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\RequirePackage{xparse} +\RequirePackage{pgffor} + +% load Michal Hoftich's new tikz driver for tex4ht +\ifWQ@Tikz + \ifdefined\HCode + \def\pgfsysdriver{pgfsys-dvisvgm4ht.def} + \fi +\fi + +\def\WQ@Error{\PackageError{webquiz}} +\def\WQ@Debugging#1{\ifWQ@Debugging\typeout{Debugging: #1}\fi} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\RequirePackage{amsfonts,amsmath} +\RequirePackage{bbding} +\setlength{\parindent}{0pt} +\setlength{\parskip}{10pt} + +% Macro to define a picture variant of \<command>. The latex version does +% nothing but the cfg version converts \<command> into an image + +\newcommand\DisplayAsImage[2][]{\relax} + +% Need to declare possible graphics extensions: see https://tex.stackexchange.com/questions/213461 +% This is just placeholder - the real definition is used in the cfg file +%\newcommand\DeclareGraphicsExtensions[1]{} + +% Macros for defining the university and department +\newcommand*{\DepartmentURL}[1]{\def\WQ@departmentURL{#1}} +\newcommand*{\Department}[1]{\def\WQ@department{#1}} + +% University/instution - university included for backwards compatibility +\newcommand*{\InstitutionURL}[1]{\def\WQ@institutionURL{#1}} +\newcommand*{\Institution}[1]{\def\WQ@institution{#1}} +\newcommand*{\UniversityURL}[1]{\def\WQ@institutionURL{#1}} +\newcommand*{\University}[1]{\def\WQ@institution{#1}} + +% Macros for defining the quiz web breadcrumbs using the unit code, name and +% URL. The names of these macros are chosen so as to be compatible with the +% in-house SMS package sms-uos.sty that specifies these for all units. +\newcommand*\UnitCode[1]{\def\uos@code{#1}} +\newcommand*\UnitName[1]{\def\uos@name{#1}} +\newcommand*\UnitURL[1]{\def\uos@url{#1}} +\newcommand*\QuizzesURL[1]{\def\WQ@quizzesUrl{#1}} +\newcommand*\BreadCrumb[1]{\def\WQ@breadcrumb{#1}} +\newcommand*\BreadCrumbs[1]{\def\WQ@breadcrumbs{#1}} + +% Default values - the university and department defaults can also be +% set in the webquizrc file. The main purpose of these defaults is +% to remind the user to set them. +\UnitCode{Unit code?} +\UnitName{Unit name?} +\UnitURL{} +\QuizzesURL{DeFaUlT} +\BreadCrumb{} +\BreadCrumbs{DeFaUlT} +\Department{DeFaUlT} +\DepartmentURL{DeFaUlT} +\University{DeFaUlT} +\UniversityURL{DeFaUlT} + +% Define page header and footer for the printable version of the quiz +% to show the unit code information. +\def\ps@quiz{\ps@empty + \def\@oddhead{\hbox to\textwidth{% + \uos@code\hss\textsc{\@title}\hss Page \thepage}}% + \let\@evenhead=\@oddhead +} +\def\ps@firstpage{\ps@empty} +\pagestyle{quiz} + + +\def\@title{} +\def\maketitle{\vspace*{10mm} + \begin{center} + {\large\textsc{\@title}}% + \end{center} +} +\AtBeginDocument{ + \maketitle% + \def\title{\WQ@Error{\noexpand\title can only be used in the preamble}\@ehc} + \thispagestyle{firstpage}% + \ifdefined\HCode\else + \textsc{WebQuiz} will process this quiz using \textbf{pst2pdf}. + \fi + \RequirePackage{tikz} +} + +% ----------------------------------------------------------------------- +% WebQuiz macros +% Define \WQ@XXXStart and \WQ@XXXEnd macros to avoid code duplication +% in webquiz.cfg. The following switches are used for syntax checking +% ----------------------------------------------------------------------- + +% These are all for error checking... +\newif\ifWQ@InFeedback +\newif\ifWQ@InAnswer +\newif\ifWQ@InChoice +\newif\ifWQ@InDiscussion +\newif\ifWQ@InItem +\newif\ifWQ@InQuestion +\newif\ifWQ@InQuizIndex +\newif\ifWQ@InWhenright +\newif\ifWQ@InWhenwrong + +% ----------------------------------------------------------------------- +% the quizindex environment and \quiz macro +% ----------------------------------------------------------------------- + +% the quiz counter keeps track of the question numbers in a quizindex environement +\newcounter{quiz} +\renewcommand\thequiz{\arabic{quiz}} +\def\WQ@QuizStart{% + \WQ@Debugging{Starting \noexpand\quiz...}% + \ifWQ@InQuizIndex\else\WQ@Error{\noexpand\quiz must appear inside a quizindex environment}\fi% + \refstepcounter{quiz}% increment the quiz counter for the URLs +} +\NewDocumentCommand\quiz{som}{% + \WQ@QuizStart% + \IfBooleanTF{#1}{\def\WQ@Quiz{}}{\def\WQ@Quiz{Quiz~\thequiz.\space}}% + \IfNoValueTF{#2}{\def\WQ@url{quiz\thequiz.html}}{\def\WQ@url{#2}}% + \leavevmode\medskip\newline% + \WQ@Quiz #3\newline% + \phantom{Quiz 10}\textit{URL}:\quad \WQ@url% +} + +\def\WQ@QuizIndexStart{% + \WQ@Debugging{Starting quizindex...}% + \ifWQ@InQuestion\WQ@Error{quizindex cannot appear in a question environment}\fi% + \ifWQ@InDiscussion\WQ@Error{quizindex environments cannot be inside a discussion environment}\fi + \ifWQ@InQuizIndex\WQ@Error{quizindex environments cannot be nested}\fi% + \global\WQ@InQuizIndextrue% here, and below, using \global is probably overkill... +} +\def\WQ@QuizIndexEnd{\global\WQ@InQuizIndexfalse\WQ@Debugging{Ending quizindex...}} +\newenvironment{quizindex}{\WQ@QuizIndexStart\bigskip}{\WQ@QuizIndexEnd} + +% ----------------------------------------------------------------------- +% discussion environment +% ----------------------------------------------------------------------- + +\newcounter{discussion} + +% \begin{dicussion}[short title][title -default-> Discussion] +\def\WQ@DiscussionStart{% + \WQ@Debugging{Starting discussion...}% + \ifWQ@InDiscussion\WQ@Error{discussion environments cannot be nested}\fi% + \ifWQ@InQuestion\WQ@Error{discussion environments cannot be inside a question environment}\fi% + \ifWQ@InQuizIndex\WQ@Error{discussion environments cannot be inside a quizindex environment}\fi% + \global\WQ@InDiscussiontrue% + \refstepcounter{discussion}% +} +\def\WQ@DiscussionEnd{\global\WQ@InDiscussionfalse\WQ@Debugging{Ending discussion...}} +\NewDocumentEnvironment{discussion}{O{Discussion}O{#1}} + {\WQ@DiscussionStart\textbf{#1} (#2)}{\WQ@DiscussionEnd\par\bigskip} + +% --------------------------------------------------------------------------- +% Cross referencing question and discussion environments +% --------------------------------------------------------------------------- + +% \WQ@Ref{+ or -}[optional *][optional text]{mandatory label} +\NewDocumentCommand\WQ@ref{ m s o m }{% +\fbox{\IfBooleanTF{#2}{link}{button} to \IfNoValueTF{#3}{to #1 \ref{#4}}{ to ``#3'' (#1 \ref{#4})}}% +} +\newcommand\dref{\WQ@ref{discussion}} +\newcommand\qref{\WQ@ref{question}} +\newcommand\Qref{\WQ@ref{question number}} + +% ----------------------------------------------------------------------- +% question environment +% ----------------------------------------------------------------------- + +% the question counter keeps track of the quiz question numbers +\newcounter{question} + +\def\WQ@QuestionStart{% + \WQ@Debugging{Starting question...}% + \ifWQ@InDiscussion\WQ@Error{question environments cannot be inside a discussion environment}\fi% + \ifWQ@InQuizIndex\WQ@Error{question environments cannot be inside a quizindex environment}\fi% + \ifWQ@InQuestion\WQ@Error{question environments cannot be nested!}\fi% + \global\WQ@InAnswerfalse% + \global\WQ@InChoicefalse% + \global\WQ@InChoicefalse% + \global\WQ@InItemfalse% + \global\WQ@InQuestiontrue% + \global\WQ@InFeedbackfalse% + \global\WQ@InWhenrightfalse% + \global\WQ@InWhenwrongfalse% + \refstepcounter{question}% +} + +\def\WQ@QuestionEnd{ + \ifWQ@InChoice\else\ifWQ@InAnswer\else% + \WQ@Error{Each question must contain a choice environment or an \noexpand\answer!}% + \fi\fi% + \global\WQ@InQuestionfalse% + \WQ@Debugging{Ending question...}% +} + +\newenvironment{question}{\WQ@QuestionStart\bigskip\textbf{Question \arabic{question}.\newline}} + {\par\bigskip\WQ@QuestionEnd} + +% ----------------------------------------------------------------------- +% choice environment, \correct and \incorrect choices and \feedback +% ----------------------------------------------------------------------- + +% the choice counter keeps track of the choices in a choice environment +\newcounter{choice} +\renewcommand\thechoice{(\alph{choice})} + +\def\WQ@ChoiceStart#1{% + \WQ@Debugging{Starting choice...}% + \ifWQ@InQuestion\relax% Give a warning if we are not inside a question + \else\WQ@Error{Choice environments must be contained in a question}% + \fi% + \ifWQ@InAnswer\WQ@Error{choice environments cannot contain an \noexpand\answer!}\fi% + \ifWQ@InChoice\WQ@Error{choice environments cannot be nested}\fi% + \global\WQ@InChoicetrue% + \global\WQ@InItemfalse% + \pgfkeys{/webquiz checker, #1}% + \setcounter{choice}{0}% reset choice counter +} + +\def\WQ@ChoiceEnd{% + \ifWQ@InItem\else\WQ@Error{Choice environment with no choices!}\fi% + \WQ@InChoicefalse% + \WQ@Debugging{Ending choice...}% +} + +% \begin{choice}[choice type, number of columns] ... \end{choice} The +% allowed choice types are "single" or "multiple". The type and number +% of columns is allowed to appear in either order, so most of the fun +% and games below is sanity checking of the argunments. +\NewDocumentEnvironment{choice}{O{single}}{% + \WQ@ChoiceStart{#1}% + \leavevmode\newline% +% (\textit{The choices will be printed in \pgfkeys{/webquiz checker/columns value} columns in the HTML version of the quiz})% + \par% + \setcounter{choice}{0}% +}{\WQ@ChoiceEnd} + +\def\WQ@ItemStart{% + \WQ@Debugging{Starting item...}% + \ifWQ@InChoice\relax% + \else\WQ@Error{\noexpand\correct and \noexpand\incorrect must be inside a choice environment}% + \fi% + \global\WQ@InItemtrue\global% + \WQ@InFeedbackfalse% + \refstepcounter{choice}% +} + +\def\WQ@Item#1{\WQ@ItemStart\par\bigskip #1\quad\textit{Option} \thequestion\thechoice:\qquad} +\def\correct{\WQ@Item\CheckmarkBold} +\def\incorrect{\WQ@Item\XSolidBrush} + +\def\WQ@FeedbackStart{% + \WQ@Debugging{Starting feedback...}% + \ifWQ@InItem\relax% + \else\WQ@Error{Missing \noexpand\correct or \noexpand\incorrect}% + \fi% + \ifWQ@InFeedback\WQ@Error{Only one feedback per option is allowed!}\fi% + \WQ@InFeedbacktrue% +} + +\def\feedback{\WQ@FeedbackStart\leavevmode\medskip\newline\textit{Feedback:}\space} + +% ----------------------------------------------------------------------- +% The \answer macro and the feedback macros \whenRight, \whenWrong +% ----------------------------------------------------------------------- + +% supported answer comparisons +\def\WQ@AnswerStart#1{% + \WQ@Debugging{Starting answer...}% + \ifWQ@InQuestion\relax% + \else\WQ@Error{\noexpand\answer\ must be contained in a question}% + \fi% + \ifWQ@InChoice\WQ@Error{You cannot have \noexpand\answer inside a choice environment}\fi% + \ifWQ@InAnswer\WQ@Error{Each question can contain only one \noexpand\answer command}\fi% + \pgfkeys{/webquiz checker/comparison/#1}% + \global\WQ@InAnswertrue% + \global\WQ@InWhenrightfalse% + \global\WQ@InWhenwrongfalse% +} + +\NewDocumentCommand\answer{s O{string} m}{% + \WQ@AnswerStart{#2}% + \leavevmode\bigskip\newline% + \IfBooleanTF{#1}{\fbox{\textit{(#2 comparison):}\quad#3}}% + {\fbox{\textit{Answer (#2 comparison):}\quad#3}}% +} + +\def\WQ@WhenStart#1{% + \WQ@Debugging{Starting when#1...}% + \ifWQ@InAnswer\relax\else\WQ@Error{missing \noexpand\answer}\fi% + \ifbool{WQ@InWhen#1}{% + \WQ@Error{Only one \noexpand\when#1 per question is allowed!}% + }{}% + \global\booltrue{WQ@InWhen#1}% +} + +\def\WQ@When#1{\WQ@WhenStart{#1}\leavevmode\medskip\newline\textit{Feedback when #1:}\space} +\def\whenRight{\WQ@When{right}} +\def\whenWrong{\WQ@When{wrong}} + +\endinput +%% End of file `webquiz.cls'. |