% \iffalse meta-comment % % moodle.dtx % Copyright 2016 by Anders O.F. Hendrickson (anders.o.f.hendrickson AT gmail DOT com) % and 2019-2021 by Matthieu Guerquin-Kern (guerquin-kern AT crans DOT org). % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Matthieu Guerquin-Kern. % % This work consists of the files moodle.dtx and moodle.ins % and the derived file moodle.sty. % % \fi % % \iffalse %<*driver> \ProvidesFile{moodle.dtx} % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{moodle} %<*package> [2023/01/28 v1.0 Moodle quiz XML generation] % % %<*driver> \documentclass[10pt,a4paper]{ltxdoc} %\usepackage[draft]{moodle} \usepackage{iftex} \ifPDFTeX \usepackage[utf8]{inputenc} % necessary \usepackage[T1]{fontenc} % necessary \usepackage{libertine} \usepackage[scaled=0.83]{beramono} \else % assuming LuaLaTeX or XeLaTeX \usepackage{fontspec} \setmainfont{Linux Libertine O} \fi \usepackage{microtype} \usepackage{dtxdescribe,varioref} \addtolength\marginparwidth{30pt} \addtolength\oddsidemargin{20pt} \addtolength\evensidemargin{20pt} \usepackage[main=english,french,german]{babel} \usepackage{amssymb,threeparttable,booktabs} \usepackage{eurosym,longtable,tikz,minted,changelog} %\usepackage[pdfpagelabels]{hyperref}% now loaded by ltxdoc \usetikzlibrary{arrows,positioning,decorations.text,calc} %\usemintedstyle{Wombat} \EnableCrossrefs \CodelineIndex \OnlyDescription \RecordChanges \setcounter{IndexColumns}{2} \begin{document} \DocInput{moodle.dtx} \end{document} % % \fi % % \CheckSum{10269} ^^A Comment \OnlyDescription above to adjust % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % % \GetFileInfo{\jobname.dtx} % % \DoNotIndex{\newcommand,\newenvironment,\def} % % \providecommand\TikZ{\mbox{Ti\emph{k}Z}}% % \providecommand\Moodle{\mbox{\brand{Moodle}}}% % \providecommand\LMS{\mbox{\acro{LMS}}}% % \providecommand\XML{\mbox{\acro{XML}}}% % % \title{% % The \pkg{moodle} package: \\ % generating \Moodle\ quizzes via \LaTeX% % \thanks{This document corresponds to \pkg{moodle.sty}~\fileversion, dated \filedate.} % }% % % \author{% % Anders Hendrickson\footnote{original author of the package (\texttt{v0.5}), inactive.}\\ % \texttt{anders.o.f.hendrickson AT gmail DOT com} \and % Matthieu Guerquin-Kern\footnote{current maintainer, % % author of the updates (\texttt{v0.6} to \texttt{\fileversion}).}\\ % \href{mailto:guerquin-kernATcransDOTorg}{\texttt{guerquin-kern AT crans DOT org}}% % }% % % \date{\today} % % \maketitle % % \begin{abstract} % This document describes the \pkg{moodle} package, made for writing \Moodle\ % quizzes in \LaTeX. In addition to typesetting the quizzes for proofreading or % giving to students as handout, the package generates an \XML\ file to be uploaded % to a \Moodle\ server. % \end{abstract} % % \tableofcontents % % \section{Introduction} % \subsection{Motivation} % % The acronym \acro{Moodle} stands for ``Modular Object-Oriented Dynamic Learning Environment.'' % It is an open source learning management system (\LMS) employed by many universities, % colleges, and high schools to provide digital access to course materials, such as % notes, video lectures, forums, and the like; see % \url{https://moodle.com/moodle-lms/} for more information. % One of the many useful % features of \Moodle\ is that mathematical and scientific notation can be entered in % \LaTeX\ or \TeX\ code, which will be typeset either through a built-in \TeX\ filter % or by invoking MathJax. % % For instructors who want to give students frequent feedback, % but lack the time to do so, a particularly valuable module in \Moodle\ % is the \emph{quiz}. A \Moodle\ quiz can consist of several different types of % questions---not only multiple choice or true/false questions, but also % questions requiring a short phrase or numerical answer, and even essay % questions. All but the essay questions are automatically graded by the % system, and the instructor has full control over how often the quiz may be % attempted, its duration, and so forth. Feedback can be tailored to specific % mistakes the student makes. % % All these features make \Moodle\ quizzes very useful tools for instructors % who have access to them. % Unfortunately, the primary way to create or edit a \Moodle\ quiz % is through a web-based interface that can be slow to operate. % To users of \LaTeX, accustomed to the speed of typing source code on % a keyboard alone, the agonizing slowness of switching between mouse and keyboard % to navigate a web form with its myriad dropdown boxes, radio buttons, % compounded with a perceptible time lag as one's \Moodle\ server responds to requests, % can produce a very frustrating experience. Moreover, editing is entirely % impossible without network access. % % Once the quiz is written, there is no easy way to view and proofread all the % information of which it is made. Each question is edited on a separate webpage, % which is so full of options that it cannot be viewed on a single screen. % An instructor has to spend much time checking over the newly created quiz in % order to be confident there are no errors. % % Added to all this is the frustration of managing graphics. % If a question requires an image---say, asking a calculus student to interpret % the graph of a function---the image must first be produced as a standalone file % (e.g., in \JPG\ or \PNG\ format), uploaded to \Moodle, and then chosen in a web-based % \HTML\ editor. Great is the vexation of the instructor who decided to alter a % question, as there are more and more possibilities of error whenever multiple % files must be kept synchronized. % % Users of \LaTeX\ are also accustomed to the speed and flexibility that % comes from defining their own macros, which may be as brief as writing % \cmd{\R} instead of |\mathbb{R}| % or as complex as macros that generate entire paragraphs of text. % The \Moodle\ editor, by contrast, requires you to type |\mathbb{R}| % every single time you want $\mathbb{R}$. % % Finally, there is the question of archiving and reusing one's work. % Much, much work goes into creating \Moodle\ quizzes, which then reside % on a \Moodle\ server somewhere in the cloud in a format neither easily browsable % nor easily modifiable. % % \LaTeX\ itself has the power to solve all these difficulties: % it is swift to edit and swifter to compile a \LaTeX\ document, % and the \PDF\ may be previewed onscreen or printed out for ease of proofreading. % Mathematical graphics can be integrated within the main file through \TikZ, % and of course \LaTeX\ macros can be customized. % Using the present \pkg{moodle} package, % a quiz author can type a quiz using familiar \LaTeX\ syntax and document % structure. Upon compilation, \LaTeX\ will generate both a well-organized % \PDF\ that is easy to proofread and an \XML\ file that can be uploaded directly % to \Moodle. The entire process is far faster than using \Moodle's own % web-based editor, makes it easier to catch one's mistakes, % and the ultimate source code of one's work is a human-readable \filenm{.tex} file % that can be archived, versioned, browsed, and edited offline. % % Strictly speaking, the \pkg{moodle} package does not generate quizzes: % it generates question banks that can be imported in the \LMS. The teacher % still needs to compose manually a quiz from the question banks. Hopefully, % two \Moodle\ features supported by the package make this task easier: % categories and tags. % % In this documentation the \LMS\ is referred to as \Moodle\ % (uppercase letters and roman font) while the \LaTeX\ package % is referred to as \pkg{moodle} (lower case and sans serif font). % % \subsection{Workflow} % %% \begin{figure}[bp] % \centering % \begin{tikzpicture}[node distance=1,auto,bend % angle=45,box/.style={rectangle,draw=blue!50,rounded corners=3,top % color=white,bottom color=black!20,thick,align=center,text % width=2.5cm},elmt/.style={font=\itshape,align=left}, % cmnt/.style={font=\footnotesize,align=center}, % bigcmnt/.style={font=\normalsize,align=center},pre/.style={<-,>=stealth',thick}, % post/.style={->,>=stealth',thick}, prepost/.style={<->,>=stealth',thick}] % \draw[white,fill=orange!20,rounded corners=10] % (-1.5,-.7)--++(0,1.4)--++(10.3,0)--++(0,-2.3)--++(-6.7,0)--++(-.25,.725)--cycle; % \node[orange!80!black,above] (dev) at (7.5,-1.6) {\textit{Development}}; % \fill[green,fill opacity=.2,rounded corners=10] % (-1.5,.7)--++(3,0)--++(0.5,-2.4)--++(6.8,0)--++(0,-3)--++(-10.3,0)--cycle; % \node[green!80!black,below] (dev) at (7.5,-1.7) {\textit{Publishing}}; % \node[box,text width=2cm] (tex) {\filenm{.tex} source file}; % \node[rectangle,fill=white,draw,align=center,text % width=1.5cm,below=of tex] (compfinal) {\LaTeX{}\\ engine}; % \node[rectangle,fill=white,draw,align=center,text width=1.5cm,right=of tex,xshift=4.5cm] % (compdraft) {\LaTeX{}\\ engine}; % \draw ($(tex)!.5!(compdraft)+(0,-.7)$) node[box] (pdf) {\filenm{.pdf} file for proofreading}; % \node[box,below=of pdf,yshift=.1cm] (pdfhandout) {\filenm{.pdf} file for students}; % \node[rectangle,fill=white,draw,align=center,text width=2cm,below=of compfinal] (extern) % {Picture\\processing}; % \draw (pdf|-extern) node[box,anchor=center] (xml) {\filenm{.xml} file\\\footnotesize(pictures embedded)}; % \draw (compdraft|-pdfhandout) % node[rectangle,fill=white,draw,align=center,text width=1.5cm,anchor=center] (students) % {Students}; % \draw (compdraft|-xml) % node[rectangle,fill=white,draw,align=center,text width=1.5cm,anchor=center] (moodle) % {\Moodle\ \\Server}; % \draw (tex) edge [post,bend right=10] node[cmnt,pos=.5,left] {\optn{final}} % node[cmnt,pos=.5,right] {\optn{handout}} (compfinal); % \draw (tex) edge [post,bend left=10] node[cmnt,pos=.5,below] {\optn{draft}} (compdraft); % \draw (compdraft) edge [post,bend left=10] (pdf); % \draw (compfinal) edge [post] node[cmnt,pos=.5,above,sloped] % {\footnotesize(\optn{handout})} (pdfhandout); % \draw[dashed] (compfinal) edge [post] (pdf); % \draw (compfinal) edge [post,bend left=0] node[cmnt,pos=.55,below,sloped] % {\footnotesize(\optn{final})} (xml); % \draw (compfinal) edge [post,bend right=15] node[cmnt,black!40,pos=.5,text width=1cm,left] % {\optn{tikz}, \filenm{.png}, \filenm{.jpg}} (extern); % \draw (extern) edge [post,green,bend right=15] node[cmnt,black!40,pos=.5,below,right] % {\prog{base64}} (compfinal); % \draw (pdf) edge [post,red,bend left=15] node[sloped,cmnt,pos=.5,above] {improve} (tex); % \draw (pdfhandout) edge [post,red] node[cmnt,pos=.5,below] {distribute} (students); % \draw (xml) edge [post,red] node[cmnt,pos=.5,below] {import} (moodle); % \end{tikzpicture} % \caption{Block diagram describing a typical workflow using the \pkg{moodle} package.} % \label{fig:workflow} % \end{figure} % % The process of creating a quiz in \Moodle\ using this package is depicted in % Figure~\vref{fig:workflow}. It follows a few % steps: % \begin{enumerate} % \item Write a \LaTeX\ document using |\usepackage{moodle}| as described % below. % \item Compile the document to \PDF\ using pdf\LaTeX\ (\acro{ASCII} characters only), % \XeLaTeX, or \LuaLaTeX. % This will also produce the file \meta{jobname}\filenm{-moodle.xml}. % \item navigate to your course on \Moodle\ and, under ``Question bank'', select ``Import.'' % \item Select ``Moodle \XML\ format,'' choose the \XML\ file to upload, and press ``Import.'' % \item After \Moodle\ verifies that the questions have been imported correctly, % you may add them to your quizzes. % \end{enumerate} % % \section{Usage}\label{sect:usage} % The following pages presume the reader already has some familiarity with creating % and editing \Moodle\ quizzes through the web interface. % Users that are not familiar with \Moodle\ quizzes can learn more in the \Moodle\ % documentation. For instance, \url{https://docs.moodle.org/en/Question_types}. % % The \pkg{xkeyval} package is used to provide a key-value interface. % % \subsection{Example Document} % % Here is a simple example document: % \begin{VerbatimOut}[gobble=1]{minted.doc.out} % \documentclass[12pt]{article} % \usepackage[section]{moodle} % \moodleregisternewcommands % \newcommand\monomial[1]{x^{#1}} % \newcommand\sillyanswer{What!?} % \begin{document} % Quiz generated \LaTeX's \textsf{moodle} (\moodleversion, \moodledate). % Import the derived file \texttt{\jobname-moodle.xml} on Moodle. % \begin{quiz}{My first quiz} % \begin{numerical}[points=2]{Basic addition} % What is $8+3$? % \item 11 % \end{numerical} % \begin{shortanswer}[usecase]{Newton's name} % What was Newton's first name? % \item Isaac % \item[fraction=0, feedback={\sillyanswer}] Fig % \item[fraction=0] Sir % \end{shortanswer} % \begin{multi}[points=3]{A first derivative} % What is the first derivative of $\monomial{3}$? % \item $\frac{1}{4}\monomial{4}+C$ % \item[feedback={yes!}]* $3\monomial{2}$ % \item[feedback={\sillyanswer}] $51$ % \end{multi} % \end{quiz} % \end{document} % \end{VerbatimOut} % \inputminted[gobble=2,frame=lines]{latex}{minted.doc.out} % Key features to note in this first example are that a \env{quiz} environment % contains several question environments. % Each question takes a name as a mandatory argument, % and it may also take optional key-value arguments within brackets. % The question environments resemble list environments % such as \env{itemize} or \env{enumerate}, in that answers are set off by % \cmd{\item}'s, but the question itself is the text that occurs before % the first \cmd{\item}. % %^^A \DescribeMacro[moodle]{\moodleregisternewcommands} %^^A \DescribeMacro[moodle]{\htmlregister} %^^A Calling \cmb{\moodleregisternewcommands} tells the package to treat %^^A specifically the macros defined subsequently. %^^A This way, the macros that \Moodle's \LaTeX\ renderer does not know %^^A about can be properly expanded in the \XML\ file. %^^A This mechanism applies only to the macros defined using \cmd{\newcommand} %^^A and \emph{without} optional argument. %^^A Using \cmd{\htmlregister}\marg{macroname}, lets you declare a specific %^^A macro for expansion. This mechanism, instead, also applies to the %^^A macros defined using \TeX's primitive \cmd{\def}. % % \subsection{Package Options} % % \DescribeOption[moodle]{draft} If the package option \optn{draft} is invoked, % by calling |\usepackage[draft]{moodle}| or |\documentclass[draft]{...}|, % then no \XML\ file will be generated. This is especially useful while % editing a quiz containing graphics, so as to avoid the time spent % converting image files. % \DescribeOption[moodle]{final} The package option \optn{final} might be % useful if one wants to avoid the option \optn{draft} to be inherited from % the \cmd{\documentclass}. % % \DescribeOption[moodle]{handout} % If the package option \optn{handout} is invoked (|\usepackage[handout]{moodle}|), % the \PDF\ file is generated clean from teacher-only information (answers, % points, penalty, feedback, tags) and, hence, can be given to students % for classroom work. In particular, as would \Moodle\ do, answers in % \env{matching} questions are shuffled and the option \optn{shuffle} % triggers the shuffling of choices offered (\env{multi} and % \env{matching}). This is achieved thanks to the package % \pkg{randomlist}, loaded if the option is invoked. The seed of its % random generator is controlled by the macro \cmd{\RLsetrandomseed}\marg{integer} % \DescribeMacro[randomlist]{\RLsetrandomseed}. % This option does not interfere with the generation of the \XML\ file. % % \DescribeOption[moodle]{samepage}^^A\watchout[experimental] % If the package option \optn{samepage} is invoked, preferably used together % with \optn{handout} (|\usepackage[handout,samepage]{moodle}|), the package % will try to keep every question on the same page. Very bad spacing % can result from this. % This option is experimental. Subquestions inside a \env{cloze} question % are protected but the \env{cloze} question itself is not protected. % % \DescribeOption[moodle]{nostamp} % By default, the package will output a stamp as a comment in the XML % file. This stamp contains information gathered about the \TeX\ engine, % the platform used and the package version. For instance:% % \begin{quote}\small % \makeatletter\def\today{\the\year-\two@digits\month-\two@digits\day}\makeatother % \newcount\hour\hour=\time % \divide\hour by 60\relax % \newcount\minute\minute=\hour % \multiply\minute by -60\relax % \advance\minute by \time\relax % ||\\ % ||\\ % || % \end{quote} % The package option |nostamp| prevents this % stamp from being written in the \XML\ file. % % \DescribeOption[moodle]{section}\DescribeOption[moodle]{subsection} % \DescribeOption[moodle]{section*}\DescribeOption[moodle]{subsection*} % The package options \optn{section} and \optn{subsection} place each quiz as a % new section or subsection, respectively. Starred variants % correspond to unnumbered sections or subsections. To preserve % compatibility with Version 0.5 of this package, the default is % \optn{subsection*}. Consequently, |\usepackage[subsection*]{moodle}| is equivalent % to |\usepackage{moodle}| . % % \DescribeOption[moodle]{tikz} % The package option \optn{tikz} is described in Section~\vref{subsec:tikz}. % % \DescribeOption[moodle]{svg}^^A\watchout[experimental] % The package option \optn{svg} is described in Section~\vref{subsec:svg}. % % \DescribeOption[moodle]{LMS}\texttt{=}\meta{\texttt{X.Y}} % \DescribeDefault{warn only} lets you specify version numbers % for the target \Moodle\ LMS instance (\texttt{X} and \texttt{Y} are % major and minor version integers). When version numbers are provided, % the use of recent quiz features is secured by a compatibility % check and \pkg{moodle} raises relevant errors. The XML stamp % (see \optn{nostamp} above) also mentions \Moodle's target version. % By default, \pkg{moodle} will just issue warnings when recent quiz % features are used. % % \subsection{Quiz and Question Environments} % % A \filenm{.tex} document to generate \Moodle\ quizzes contains one or more % \env{quiz} environments. % % \DescribeEnv[moodle]{quiz}\oarg{common options}\marg{category name} % defines a quiz, within which various question environments are nested. % The mandatory argument, \meta{category name}, names a category for \Moodle's % ``question bank'': after import, the questions defined in this environment % will be gathered in this category. % Using the optional argument, options can be set at the quiz level. % Although there are no \env{quiz}-specific options, any \meta{common options} set % with the quiz will be inherited by all questions contained within that environment. % % \DescribeMacro[moodle]{\moodleset}\marg{options} % is to be used to set options outside question environments; the option % settings are local to \TeX-groups. % % \DescribeMacro[moodle]{\setcategory}\marg{category name} % is to be used to change the current category inside a quiz environment and % in between questions. Note that the \env{quiz} environment defines a category % by its own. % % \DescribeMacro[moodle]{\setsubcategory}\marg{subcategory name} % does the same with subcategories. % The categories and subcategories are reflected in the \PDF\ file as sections, subsections, or % subsubsections, in accordance to the package setting \optn{section}, \optn{section*}, % \optn{subsection}, or \optn{subsection*}. % % The syntax for each question environment is % \begin{quote} % |\begin|\marg{question type}\oarg{question options}\marg{question name} \\ % \rule{2em}{0pt}\meta{question text} \\ % \rule{2em}{0pt}|\item|\oarg{item options} \meta{item} \\ % \rule{2em}{0pt}\quad$\vdots$ \\ % \rule{2em}{0pt}|\item|\oarg{item options} \meta{item} \\ % |\end|\marg{question type} % \end{quote} % The meaning of the \meta{item}s varies depending on the question type, % but they usually are answers to the question. % Details will be given below. % % The following key-value options may be set for all questions: % % \DescribeKey[quiz,question]{points}\DescribeDefault{1} % \DescribeKey[quiz,question]{default grade} % By default, each question is worth 1 point on the quiz. % This setting may be changed with the \optn{points} key or its synonym, \optn{default grade}. % For example, \optn{points=2} makes that question worth two points. % % \DescribeKey[quiz,question]{penalty}\DescribeDefault{0.1} % The \optn{penalty} is the fraction of points that is taken off for each wrong attempt; % it may be set to any value between 0 and 1. % % \DescribeKey[answer]{fraction}^^A\DescribeDefault{0} % In most question types, it is possible to designate some answers as being % worth partial credit---that is, some fraction of a completely correct answer. % The \optn{fraction} key may be set to any of the values given in Table~\vref{tab:fraction}, % from \texttt{0} (entirely wrong) to \texttt{100} (entirely correct). % % \begin{table}[tbp] % \centering % \caption{\href{https://github.com/moodle/moodle/blob/MOODLE\_310\_STABLE/question/engine/bank.php\#L339} % {Admissible positive values} for the \optn{fraction} key outside \env{cloze} environments: $100\cdot(p/q)$.} % \label{tab:fraction} % \footnotesize % \begin{tabular}{l*{10}{l}} % \toprule % Denominator $q$ & \multicolumn{10}{c}{Numerator $p$}\\ % \cmidrule{2-11} % & 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9\\ % \cmidrule(lr){1-1}\cmidrule(lr){2-2}\cmidrule(lr){3-3}\cmidrule(lr){4-4} % \cmidrule(lr){5-5}\cmidrule(lr){6-6}\cmidrule(lr){7-7}\cmidrule(lr){8-8} % \cmidrule(lr){9-9}\cmidrule(lr){10-10}\cmidrule(lr){11-11} % 20 & 0&5&&&&&&&&\\\cmidrule(lr){1-1} % 10 & &10&20&30&40&50&60&70&80&90\\\cmidrule(lr){1-1} % 9 & &11.11111&&&&&&&&100\\\cmidrule(lr){1-1} % 8 & &12.5&&&&&&&100&\\\cmidrule(lr){1-1} % 7 & &14.28571&&&&&&100&&\\\cmidrule(lr){1-1} % 6 & &16.66667&&&&83.33333&100&&&\\\cmidrule(lr){1-1} % 5 & &20&&&80&100&&&&\\\cmidrule(lr){1-1} % 4 & &25&&75&100&&&&&\\\cmidrule(lr){1-1} % 3 & &33.33333&66.66667&100&&&&&&\\\cmidrule(lr){1-1} % 2 & &50&100&&&&&&&\\\cmidrule(lr){1-1} % 1 & 0&100&&&&&&&&\\\cmidrule(lr){1-1} % \bottomrule % \end{tabular} % \end{table} % % In questions where several choices can be selected (see \env{multi} with option % \optn{multiple}), positive fractions must add up to exactly 100. It is also possible to set % negative fractions (from -100 to 0) for wrong choices, in order to prevent the % selection of all choices from leading to a good grade. % In this case, the value ranging from -100 to 0 must be the opposite of one of the % values listed in Table~\vref{tab:fraction}. % % \DescribeKey[answer]{fractiontol}\DescribeDefault{0.01} % The package tries to match the \optn{fraction} key to one of the admissible values. % To this end, the tolerance is controlled by the \optn{fractiontol} key. The default % value, \texttt{0.01}, may be changed. When no admissible fraction value is matched, the % package raises an error. % % \DescribeKey{feedback} % The \optn{feedback} key sets text that will appear to the student after completing the quiz. % For example, one might set % \begin{center} % |feedback={This question might show up in the final exam.}| % \end{center} % The desired feedback should be included in braces. % % \DescribeKey[question]{feedback}If the \optn{feedback} key is set for a question, % then that feedback will appear to each student regardless of the student's answer. % % \DescribeKey[answer]{feedback} % Answer-specific feedback (perhaps explaining a common mistake) % may also be given by setting the \optn{feedback} key \emph{at the individual answer}. % % \DescribeKey{tags} % The \optn{tags} key sets a list of keywords for the question that will be taken into account % by \Moodle\ for filtering purposes or classification of questions inside the question bank. % It is possible for instance to build a quiz with questions cherry-picked among the set of % questions holding a particular tag. % For example, one might set % \begin{center} % |tags={easy}| % \end{center} % The desired tag should be specified in between braces. Multiple tags can be set as a % comma-separated list: % \begin{center} % |tags={tag1,tag2,{ leading whitespace},{including, comma}}| % \end{center} % % \DescribeKey[quiz]{tags} % If the \optn{tags} key is set at the quiz level, % then that tag list will serve as a default for each question of the quiz. % % \DescribeKey[question]{tags} % Question-specific tags can be assigned by setting the \optn{tags} key \emph{at the question level}. % The question-level \optn{tags} key overrides eventual quiz-level tags. % % Users willing to specify a same tag for all questions of the quiz could % also consider relying on \Moodle's category mechanism. % % \subsection{\href{https://docs.moodle.org/en/Question_types}{Question Types}} % % We next discuss the various question types supported by \pkg{moodle} % and the options that may be set. % %\subsubsection{\href{https://docs.moodle.org/en/True/False_question_type}{True/False}} % % \DescribeEnv[quiz]{truefalse}\oarg{question options}\marg{question name} % is an environment that defines a \emph{True/False} question. % % The syntax for a True/False question is as follows: % \begin{quote} % |\begin{truefalse}|\oarg{question options}\marg{question name} \\ % \rule{2em}{0pt}\meta{question text} \\ % \rule{2em}{0pt}|\item*| \meta{feedback when ``true" is chosen} \\ % \rule{2em}{0pt}|\item| \meta{feedback when ``false" is chosen} \\ % |\end{truefalse}| % \end{quote} % The correct answer is designated by the asterisk \texttt{*} after the \cmd{\item}; % it need not appear first in the list. % % Answer-specific feedback can also be defined as an item option, similarly to % other types. % \begin{quote} % |\begin{truefalse}|\oarg{question options}\marg{question name} \\ % \rule{2em}{0pt}\meta{question text} \\ % \rule{2em}{0pt}|\item[feedback={|\meta{When ``true" is chosen}|}]*| \\ % |\end{truefalse}| % \end{quote} % Note that, in this example, no feedback is defined for the incorrect answer % ``False": the corresponding item can be omitted. % % With the True/False question type, the |penalty| key has no effect. % % \subsubsection{\href{https://docs.moodle.org/en/Multiple_Choice_question_type}{Multiple Choice}} % \label{subsec:multi} % % \DescribeEnv[quiz]{multi}\oarg{question options}\marg{question name} % is an environment that defines a \emph{Multiple Choice} question. % % The syntax for a classic multiple choice question, % with only one correct answer, is as follows: % \begin{quote} % |\begin{multi}|\oarg{question options}\marg{question name} \\ % \rule{2em}{0pt}\meta{question text} \\ % \rule{2em}{0pt}|\item|\oarg{answer options}|*| \meta{correct answer} \\ % \rule{2em}{0pt}|\item|\oarg{answer options} \meta{wrong answer} \\ % \rule{2em}{0pt}\quad$\vdots$ \\ % \rule{2em}{0pt}|\item|\oarg{answer options} \meta{wrong answer} \\ % |\end{multi}| % \end{quote} % The correct answer is designated by the asterisk \texttt{*} after the \cmd{\item}; % it need not appear first in the list. % % % \DescribeBoolean[multi]{shuffle}\DescribeDefault{true} % The Boolean key \optn{shuffle} determines whether \Moodle\ will % rearrange the possible answers in a random order. % Setting \optn{shuffle=false} will guarantee that the answers will % be presented to the student in the order they were typed. % % \DescribeKey[multi]{numbering}\DescribeDefault{abc} % \Moodle\ offers different options for numbering the possible answers. % You may set the \optn{numbering} key to any of the values listed in % Table~\vref{tab:numbering_options}. % \begin{table}[tbp] % \centering % \caption{Numbering modalities offered for \env{multi} questions.} % \label{tab:numbering_options} % \begin{tabular}{rllllll} % \toprule % Sample & a., b., \dots & A., B., \dots & 1., 2., \dots & i., ii., \dots & % I., II., \dots & $\bullet$ \\ % \cmidrule(lr){2-2}\cmidrule(lr){3-3}\cmidrule(lr){4-4}\cmidrule(lr){5-5}\cmidrule(lr){6-6} % \cmidrule(lr){7-7} % \LaTeX\ syntax & \optn{alph} & \optn{Alph} & \optn{arabic} & \optn{roman} & \optn{Roman} & \optn{none}\\ % \Moodle\ syntax & \optn{abc} & \optn{ABCD} & \optn{123} & \optn{iii} & \optn{IIII} & \optn{none} \\ % \bottomrule % \end{tabular} % \end{table} % \optn{numbering=none} produces an unnumbered list of answers. % Note the \emph{four} capital letters required by \Moodle's syntax % to obtain upper-case Roman or alphabetic numerals. % % \DescribeKey[item]{fraction}\DescribeDefault{0} % \DescribeKey[item*]{fraction}\DescribeDefault{100} % The \optn{fraction} key may be automatically set depending on the % presence of an asterisk \texttt{*} right after the \cmd{\item}. By default, % Starred items designate correct answers (\optn{fraction=100}) while % bare items designate incorrect answers (\optn{fraction=0}). % The key can be used to designate some wrong answers as being worth % partial credit or sanction. For example, a question might read % \begin{VerbatimOut}[gobble=1]{minted.doc.out} % \begin{multi}{my question} % Compute $\int 4x^3\,dx$. % \item* $x^4+C$ % \item[fraction=50] $x^4$ % \item $12x^2$ % \end{multi} % \end{VerbatimOut} % \inputminted[gobble=2,frame=lines]{latex}{minted.doc.out} % % \DescribeBoolean[multi]{single}\DescribeDefault{true} % By default, the \env{multi} environment produces a multiple choice % question where only one answer can be selected. This is called % \optn{single} mode. %^^A On \Moodle, the choices are displayed with radio %^^A buttons and only one of them can be selected by the student. % % In \optn{single} mode, the teacher can set negative fractions for % incorrect choices. This way, the expected grade of a student % picking up choices randomly across a quiz is lowered. % By default, incorrect answers that do not have a fraction % specified correspond to \optn{fraction=0}. % \DescribeKey[quiz,multi]{sanction}\DescribeDefault{0} However, % if the \optn{sanction} key is set to a positive value, at quiz or % question levels, such incorrect answers are sanctioned as if % \optn{fraction=-}\meta{sanction value} was set for each of them. % % \DescribeKey[multi]{multiple} % It is also possible to write questions with possibly more than % one correct answer, asking the user to check all correct answers. % To do this, use the key \optn{multiple} or \optn{single=false}. % For this kind of question, the student gets a grade that % corresponds to the total of the weights of the answers selected. % Users may rely on two modalities to set the weights of the answers: % \begin{enumerate} % \item the \emph{advanced mode} applies whenever a \optn{fraction} key % is set among the proposed answers. In this case, it is recommended % that the user sets manually everything. Answers that are left with % no fraction set are considered as neutral, selecting them will % not change the grade. If \cmd{\item*} is used to designate some correct % answers, \pkg{moodle} will distribute equally among those answers % the points that are left for a total of 100\% (only positive % fractions count here). Note that doing so will easily yield % situations where the weights are inadmissible (see % Table~\vref{tab:fraction}). % \item the \emph{automatic mode} applies when correct answers are % designated using \cmd{\item*} and no answer has a \optn{fraction} key set. % In this case, each correct answer is weighted to bring the same % fraction of the maximum grade and each incorrect answer is % weighted to cancel the benefits of the selection of one correct % answer. % \end{enumerate} % For example, the following two examples are equivalent: % \begin{VerbatimOut}[gobble=1]{minted.doc.out} % \begin{multi}[multiple]{Automatic Mode} % Which numbers are prime? % \item 2 % \item* 5 % \item* 7 % \item 1 % \item 6 % \end{multi} % \begin{multi}[multiple]{Advanced Mode} % Which numbers are prime? % \item[fraction=-50] 2 % \item[fraction=50] 5 % \item[fraction=50] 7 % \item[fraction=-50] 1 % \item[fraction=-50] 6 % \end{multi} % \end{VerbatimOut} % \inputminted[gobble=2,frame=lines]{latex}{minted.doc.out} % Note that, in this example, negative fractions are set for wrong % choices. This prevents students from obtaining a good grade with % no merit if they select all answers. % % Contrarily to the \optn{single} mode where questions with negative fractions may % lead to a overall negative grade, when multiple choices can be selected, the % lowest grade \Moodle\ will take into account for the question is 0. % % \DescribeKey[multi]{allornothing} % There also exists a \href{https://moodle.org/plugins/qtype_multichoiceset} % {``All-or-Nothing Multiple Choice''} plugin for \Moodle\ that introduces a % question type similar to a multiple choice with multiple correct answers, % with the specificity that the points are given if and only if the student % selects all correct answers. This kind of question is set up using the % \optn{allornothing} key. % The recommended way for designating correct answers is with \cmd{\item*}. If instead % the \optn{fraction} is used, \pkg{moodle} will consider that non-negative % fractions ($>0$) designate correct answers and negative fractions ($\leq 0$) % designate incorrect choices. % The option \optn{allornothing} supersedes the options \optn{multiple} and \optn{single}. % To the best of our knowledge, \Moodle\ does not offer the all-or-nothing behavior % for multiple choice questions embedded inside a \env{cloze} question. % % \subsubsection{\href{https://docs.moodle.org/en/Numerical_question_type}{Numerical}} % % \DescribeEnv[quiz]{numerical}\oarg{question options}\marg{question name} % is an environment that defines a \emph{Numerical} question which, in \Moodle, requires the student % to input a real number in decimal form. % % The typical format for this question type is: % \begin{quote} % |\begin{numerical}|\oarg{question options}\marg{question name} \\ % \rule{2em}{0pt}\meta{question text} \\ % \rule{2em}{0pt}|\item|\oarg{answer options} \meta{correct answer} \\ % |\end{numerical}| % \end{quote} % If there is more than one correct answer, additional \cmd{\item}'s may be included. % Because this is not a multiple choice question, there is no need to provide % incorrect answers. There may nevertheless be reasons to include incorrect answers. % For example, partially correct answers may be specified by setting the \optn{fraction} key. % Feedback for a common mistake may be given by including the incorrect answer like this: % \begin{quote}\footnotesize % |\item[fraction=0,feedback={Forgot to antidifferentiate?}]| \meta{incorrect answer} % \end{quote} % % \DescribeKey[numerical]{tolerance}\DescribeDefault{0} % The \optn{tolerance} key can be used to specify the validity of answers within some margin. % This key can be set at different levels: quiz, question, item. % For example, with the question % \begin{VerbatimOut}[gobble=1]{minted.doc.out} % \begin{numerical}[tolerance=0.01]{my question} % Approximate value of $\sqrt{2}$? % \item[tolerance={1e-1}] 1.4142 % \item[fraction=20,feedback={twice this!}] 7.0711e-1 % \item[fraction=0,feedback={Wrong!}] * % \end{numerical} % \end{VerbatimOut} % \inputminted[gobble=2,frame=lines]{latex}{minted.doc.out} % In this example, % \begin{itemize} % \item any answer in the range $[1.4042,1.4242]$ will be validated, % \item any answer in the range $[0.69711,0.71711]$ will get the specific feedback % \emph{twice this!} and 20\% of points, % \item any other answer is incorrect and will get the specific feedback % \emph{Wrong!}. % \end{itemize} % % When feedback is to be given for any non-specified answer, one can add a \emph{last} answer % item containing the wildcard character \texttt{*} only. In this case, the \optn{tolerance} key is irrelevant. % % Both answers and tolerance can be specified with the comma (\texttt{,}) as a decimal separator. % Exponent notation is accepted. After import, \Moodle\ will recognize indifferently \texttt{0.000165}, % \texttt{0,000165}, \texttt{1.65E-4}, \texttt{1.65e-4}, \texttt{1,65E-4}, and \texttt{1,65e-4}. % % If the \pkg{siunitx} package is loaded, \pkg{moodle} will detect it and % numbers will be rendered nicely in the \PDF\ output. % % Units, unit-handling and multipliers are currently unsupported.\watchout % % \subsubsection{\href{https://docs.moodle.org/en/Short-Answer_question_type}{Short Answer}} % % \DescribeEnv[quiz]{shortanswer}\oarg{question options}\marg{question name} % is an environment that defines a \emph{Short Answer} question. It resembles % a \env{numerical} question: the student is to fill in a text box with a % missing word or phrase. % \begin{quote} % |\begin{shortanswer}|\oarg{question options}\marg{question name} \\ % \rule{2em}{0pt}\meta{question text} \\ % \rule{2em}{0pt}|\item|\oarg{answer options} \meta{correct answer} \\ % \rule{2em}{0pt}\quad$\vdots$ \\ % \rule{2em}{0pt}|\item|\oarg{answer options} \meta{correct answer} \\ % |\end{shortanswer}| % \end{quote} % You can make the text box appear as part of the question with the % control sequence \cmd{\blank}. For example, % your question might read % \begin{VerbatimOut}[gobble=1]{minted.doc.out} % \begin{shortanswer}{Leibniz} % Newton's rival was Gottfried Wilhelm \blank. % \item Leibniz % \item Leibniz. % \end{shortanswer} % \end{VerbatimOut} % \inputminted[gobble=2,frame=lines]{latex}{minted.doc.out} % Note that as the blank occurred at the end of a sentence, % we included two answers, % lest students get the question wrong merely by % including or omitting a period. % % \DescribeBoolean[shortanswer]{case sensitive}\DescribeDefault{false} % The default setting when creating a Short Answer question in \Moodle\ % is to ignore the distinction between upper- and lower-case letters % when grading a short answer question. This default is preserved by % \pkg{moodle}. % You can make a question case-sensitive with the Boolean key % \optn{case sensitive} or its shorter synonym \optn{usecase}\DescribeBoolean[shortanswer]{usecase}. % % The \href{https://docs.moodle.org/en/Short-Answer_question_type#Wildcard_usage}% % {wildcard character} \texttt{*} can used to grab answers that match % a specific pattern. Following the order of answers, the first match will lead % to the corresponding score and eventual feedback. As an example, take the % following question % \begin{VerbatimOut}[gobble=1]{minted.doc.out} % \begin{shortanswer}[usecase]{Newton's name} % What was Newton's first name? % \item Isaac % \item[fraction=0,feedback={Simply Isaac!}] Isaa* % \item[fraction=0,feedback={This one is Leibniz!}] *Gottfried* % \item[fraction=0,feedback={First name, not title!}] Sir* % \item[fraction=0,feedback={No\dots}] * % \end{shortanswer} % \end{VerbatimOut} % \inputminted[gobble=2,frame=lines]{latex}{minted.doc.out} % \begin{itemize}\def\answ#1{\framebox{\texttt{#1}}}% % \item the answer \answ{Isaac} is the only one that gets rewarded, % \item answers \answ{Isaac Leibniz}, \answ{Isaac Newton}, and \answ{Isaak} yield % the feedback \emph{Simply Isaac!}, % \item answers \answ{Sir Gottfried Wilhelm}, \answ{Sir Gottfried}, % \answ{Gottfried Wilhem}, and \answ{Gottfried} yield % the feedback \emph{This one is Leibniz!}, % \item answers \answ{Sir Isaac}, and \answ{Sir} yield % the feedback \emph{First name, not title!}, % \item any answer that does not match the previous patterns % yields the feedback \emph{No\dots}. % \end{itemize} % % \subsubsection{\href{https://docs.moodle.org/en/Essay_question_type}{Essay}}\label{subsubsect:essay} % % \DescribeEnv[quiz]{essay}\oarg{question options}\marg{question name} % is an environment that defines an \emph{Essay} question. % % Instructors may ask essay questions on a \Moodle\ quiz, % although \Moodle's software is not up to the task of grading them! % Instead, each essay question answer must be graded manually by the % instructor or a teaching assistant. % \begin{quote} % |\begin{essay}|\oarg{question options}\marg{question name} \\ % \rule{2em}{0pt}\meta{question text} \\ % \rule{2em}{0pt}|\item| \meta{information 1 for grader} \\ % \rule{2em}{0pt}\quad$\vdots$ \\ % \rule{2em}{0pt}|\item| \meta{information $n$ for grader} \\ % |\end{essay}| % \end{quote} % Instead of containing answers, the \cmd{\item} entries included in the \env{essay} % question contain notes that will appear to whoever is grading the question manually. % Contrarily to other question types, \cmd{\item} in \env{essay} questions % do not take options. % % \DescribeBoolean[essay]{response required}\DescribeDefault{false} % Although \Moodle\ cannot grade the content of an essay question, % it can at least determine whether the question has been left blank. % If the \optn{response required} key is set, \Moodle\ will insist that the student % enter something in the blank before accepting the quiz as completed. % % \DescribeKey[essay]{response format}\DescribeDefault{html} % \Moodle\ offers five different ways for students to enter and/or upload their % answers to an essay question. You may choose one of these five options: % \begin{description} % \ItemDescribeOther[response format]{html} An editor with the ability to format \HTML\ responses % including markup for italics, boldface, etc. This is the default. % \ItemDescribeOther[response format]{file} A file picker allowing the student to upload a % file, such as a \PDF\ or DOC file, containing the essay. % \ItemDescribeOther[response format]{html+file} The same \HTML\ editor as above, but with the % ability to upload files as well. This permits some students to type % answers directly into the web form, and others to compose their % essays in another program first. % \ItemDescribeOther[response format]{text} This editor allows only for entering plain text % without any markup. % \ItemDescribeOther[response format]{monospaced} This yields a plain text editor, without any % markup, and with a fixed-width font. This could be useful for % entering code snippets, for example. % \end{description} % % \DescribeKey[essay]{response field lines}\DescribeDefault{15} % The key \optn{response field lines} controls the height of the input box. % For \Moodle, the admissible values are: 5, 10, 15, 20, 25, 30, 35, and 40. % If the value set is not admissible, \pkg{moodle} will approximate the value: % \begin{itemize} % \item with either 5 or 40 if the value set was out of range, or % \item with the next multiple of 5 otherwise. % \end{itemize} % % \DescribeKey[essay]{attachments allowed}\DescribeDefault{0} % The \optn{attachments allowed} key controls \emph{how many} attachments a student is % allowed to upload. Admissible values are \texttt{0}, \texttt{1}, \texttt{2}, % \texttt{3}, or \texttt{unlimited}. % % \DescribeKey[essay]{attachments required}\DescribeDefault{0} % You may also require the student to upload a certain number of attachments % by setting \optn{attachments required} to \texttt{0}, \texttt{1}, \texttt{2}, or \texttt{3}. % % \DescribeKey[essay]{template} % Finally, you may preload the essay question with a template that the student % will edit and/or type over, with the key \optn{template=}\marg{template}. % The \meta{template} should be enclosed in braces. % % \subsubsection{\href{https://docs.moodle.org/en/Matching_question_type}{Matching}} % % \DescribeEnv[quiz]{matching}\oarg{question options}\marg{question name} % is an environment that defines a \emph{Matching} question. It typically % looks like this: % \begin{quote} % |\begin{matching}|\oarg{question options}\marg{question name} \\ % \rule{2em}{0pt}\meta{question text} \\ % \rule{2em}{0pt}|\item| \meta{item 1} |\answer| \meta{match 1}\\ % \rule{2em}{0pt}|\item| \meta{item 2} |\answer| \meta{match 2}\\ % \rule{2em}{0pt}\quad$\vdots$ \\ % \rule{2em}{0pt}|\item| \meta{item $m$} |\answer| \meta{match $m$}\\ % \rule{2em}{0pt}|\item| |\answer| \meta{no match $1$}\\ % \rule{2em}{0pt}\quad$\vdots$ \\ % \rule{2em}{0pt}|\item| |\answer| \meta{no match $n$}\\ % |\end{matching}| % \end{quote} % \meta{match}es $1$ through $m$ are separated from their corresponding % \meta{item}s by the command \cmd{\answer}\DescribeMacro[matching]{\answer}. % Answers that match no item can be proposed at the end of the list, % preceded by an empty item. % % After import, \Moodle\ will recognize matches that are \emph{exact} % duplicates. If you intend multiple questions to have the same match, % make sure that they are entered identically. % % \DescribeBoolean[matching]{shuffle}\DescribeDefault{true} % When students take a matching question, \Moodle\ always displays % the proposed matches in random order. % The \env{matching} question accepts the option |shuffle| to also % randomly permute the items. % % \DescribeBoolean[matching]{drag and drop}\DescribeDefault{false} % The standard matching question offered by \Moodle\ corresponds to % a dropdown box for choosing the match for each item. % There also exists a \href{https://docs.moodle.org/en/Drag_and_drop_matching_question_type} % {``drag and drop matching''} plugin for \Moodle\ that % shows all items in a column (left), all proposed matches in a second column % (right), and asks students to drag the correct % match to each item with the mouse. % In this package, to enable drag-and-drop matching, use the key % \optn{drag and drop} or \optn{dd}\DescribeKey[matching]{dd}\ for short. % Beware that, with the standard format (\optn{drag and drop=false}), due % to the limitations of dropdown boxes, \Moodle\ will not render \LaTeX\ % or \HTML\ code passed in the answers. % % \subsubsection{\href{https://docs.moodle.org/en/Embedded_Answers_(Cloze)_question_type} % {Cloze Questions and Subquestions}} % % \DescribeEnv[quiz]{cloze}\oarg{question options}\marg{question name} % is an environment that defines a \emph{Cloze} question. % % A ``cloze question'' has one or more subquestions embedded within a passage of text. % For example, you might ask students to fill in several missing words within % a sentence, or calculate several coefficients of a polynomial. % To encode cloze questions in \LaTeX\ using this package is easy: % you simply nest one or more \env{multi}, \env{numerical}, or \env{shortanswer} environments % within a \env{cloze} environment, as in the following example: % \begin{VerbatimOut}[gobble=1]{minted.doc.out} % \begin{cloze}{my cloze question} % Thanks to calculus, invented by Isaac % \begin{shortanswer}[usecase] % \item Newton % \end{shortanswer}, % we know that the derivative of $x^2$ is % \begin{multi}[horizontal] % \item $2x$ % \item* $\frac{1}{3} x^3 + C$ % \item $0$ % \end{multi} % and that $\int_0^2 x^2\,dx$ equals % \begin{numerical} % \item[tolerance={4e-4}] 2.667 % \end{numerical}. % Thanks, Isaac! % \end{cloze} % \end{VerbatimOut} % \inputminted[gobble=2,frame=lines]{latex}{minted.doc.out} % % Note that, when used as a subquestion within a \env{cloze} question, % the question environments are \emph{not} followed by a question % name in braces. % \begin{description} % \ItemDescribeEnv[cloze]{multi}\oarg{subquestion options} defines a % Multiple Choice question inside a Cloze question, % \ItemDescribeEnv[cloze]{numerical}\oarg{subquestion options} defines a % Numerical question inside a Cloze question, and % \ItemDescribeEnv[cloze]{shortanswer}\oarg{subquestion options} defines a % Shortanswer question inside a Cloze question, % \end{description} % % \DescribeKey[cloze]{points}\DescribeDefault{1} % \DescribeKey[cloze]{default grade} % Inside \env{cloze} environments, the \optn{points} or \optn{default grade} % keys can be used to weight the worth of each subquestion. A specific % constraint applies: the values should be positive integers. % % \DescribeKey[cloze]{fraction} % Inside \env{cloze} environments, the \optn{fraction} key can be used to give % partial credit or sanction for certain answers. The values % specified must be integers and are independent of the admissible % values listed in Table~\vref{tab:fraction}. % % \DescribeBoolean[cloze]{single}\DescribeDefault{true} % \DescribeKey[cloze]{multiple} % Prior to \Moodle\ version 3.5, within a \env{cloze} question, a multiple choice question % was necessarily of type \optn{single}, i.e. with a single good answer. If you intend % to export your quiz to \Moodle\ 3.5+, the option \optn{multiple} can be used for % questions where students must be able to select several answers. % The modalities described in Section~\vref{subsec:multi} for setting the % weight of answers apply. The only difference occurs in \emph{advanced mode}: % the sum of positive fractions may not be 100\%. In this case, after % importing the \XML\ file, \Moodle\ will automatically scale the positive % fractions for a total of 100\% and leave intact the negative fractions. % ^^A\footnote{\url{https://tracker.moodle.org/browse/MDL-3782?focusedCommentId=421564\#comment-421564}}. % % ^^A\DescribeKey[cloze]{vertical}\DescribeKey[cloze]{horizontal}\DescribeKey[cloze]{inline} % ^^A\DescribeDefault{inline} % Within a \env{cloze} question, a multiple choice question may be displayed in three % different modes: % \begin{description} % \ItemDescribeKey[cloze]{inline} The inline dropdown box is the default choice % when only one answer is to be selected (option \optn{single}). The dropdown box % is visually compact, but also prevents the use of mathematical or \HTML\ formatting. % This option is incompatible\watchout\ with \optn{multiple} or \optn{single=false} % (dropdown boxes don't let you pick up several answers!). % \ItemDescribeKey[cloze]{vertical} displays the subquestion as a vertical column % of radio buttons instead. This is the default when several items can % be selected (options \optn{multiple} or \optn{single=false}). % \ItemDescribeKey[cloze]{horizontal} creates a horizontal row of radio buttons. % This option works well when the possible answers are short. The result is more % compact than what \optn{vertical} gives. % \end{description} % % \DescribeBoolean[cloze]{shuffle} % Starting from \Moodle\ version 3.0, within a \env{cloze} question, the items of a % multiple choice question can be shuffled. Setting \optn{shuffle=false} will % guarantee that the answer appear in the order they were typed; the % default is \optn{shuffle=true}. % % \DescribeBoolean[cloze]{case sensitive}\DescribeDefault{false} % \DescribeBoolean[cloze]{usecase} % Within a \env{cloze} question, the \env{shortanswer} question can be made case sensitive. % This option, disabled by default, is selected with \optn{case sensitive} or \optn{usecase}. % %\subsubsection{\href{https://docs.moodle.org/en/Description_question_type}{Description}} % % \DescribeEnv[quiz]{description}\oarg{question options}\marg{question name} % is an environment that defines a so-called \emph{Description} question. % % The \Moodle\ description type is not really a question. It is more like a label. % One can set a \optn{feedback} that the student gets when reviewing the submission. % Tags can be set as well. % % For descriptions, \pkg{moodle} redefines \LaTeX's \env{description} environment. % The scope of this redefinition is limited to the \env{quiz} environment. % % The syntax for a Description question is as follows: % \begin{quote} % |\begin{description}|\oarg{question options}\marg{question name} \\ % \rule{2em}{0pt}\meta{question text} \\ % |\end{description}| % \end{quote} % % \subsection{Summary of the Key Options} % % Table~\vref{tab:key-options}, summarizes % the key options available at the question and answer levels depending on the % question type. For the essay questions, please refer to Section~\vref{subsubsect:essay}. % % \begin{table}[tbp] % \centering % \caption{Options offered at the question and answer levels for each question type.} % \label{tab:key-options} % \small % \begin{tabular}{*{15}{l}} % \toprule % & \multicolumn{11}{l}{Question} & \multicolumn{3}{l}{Answer}\\ % \cmidrule(lr){2-12}\cmidrule(lr){13-15} % Question type & \rotatebox{90}{points} & % \rotatebox{90}{penalty} & \rotatebox{90}{feedback} & \rotatebox{90}{tags} & % \rotatebox{90}{shuffle} & \rotatebox{90}{numbering} & \rotatebox{90}{multiple} & % \rotatebox{90}{allornothing} &\rotatebox{90}{usecase} & \rotatebox{90}{tolerance} & % \rotatebox{90}{dd} & \rotatebox{90}{fraction} & \rotatebox{90}{feedback} & % \rotatebox{90}{tolerance}\\\cmidrule(lr){1-1}\cmidrule(lr){2-2}\cmidrule(lr){3-3} % \cmidrule(lr){4-4}\cmidrule(lr){5-5}\cmidrule(lr){6-6}\cmidrule(lr){7-7} % \cmidrule(lr){8-8}\cmidrule(lr){9-9}\cmidrule(lr){10-10}\cmidrule(lr){11-11} % \cmidrule(lr){12-12}\cmidrule(lr){13-13}\cmidrule(lr){14-14}\cmidrule(lr){15-15} % \href{https://docs.moodle.org/35/en/Multiple_Choice_question_type} % {Multichoice} & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ & % $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ & & & & $\bullet$ & $\bullet$ \\ % \href{https://docs.moodle.org/35/en/Numerical_question_type}{Numerical} % & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ & & & & % & & $\bullet$ & & $\bullet$ & $\bullet$ & $\bullet$ \\ % \href{https://docs.moodle.org/35/en/Short-Answer_question_type}{Short % Answer} & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ & & & & % & $\bullet$ & & & $\bullet$ & $\bullet$ \\ % \href{https://docs.moodle.org/35/en/Matching_question_type}{Matching} % & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ & $\bullet$ & & & % & & & $\bullet$ & & \\ % \href{https://docs.moodle.org/35/en/True/False_question_type} % {True/False} & $\bullet$ & & $\bullet$ & $\bullet$ & & & & % & & & & & $\bullet$ \\ % \href{https://docs.moodle.org/35/en/Description_question_type} % {Description} & & & $\bullet$ & $\bullet$ & & & & % & & & & & \\ % ^^A\href{https://docs.moodle.org/35/en/Essay_question_type}{Essay} & \\\hline% % \href{https://docs.moodle.org/35/en/Embedded_Answers_(Cloze)_question_type}{Cloze} % & & $\bullet$ & $\bullet$ & $\bullet$ & & & & % & & & & & \\\cmidrule(lr){1-1} % \hspace{1em}Numerical & $\bullet$ & & & & & & & % & &$\bullet$ & & $\bullet$ & $\bullet$ & $\bullet$ \\ % \hspace{1em}Short Answer & $\bullet$ & & & & & & & % & $\bullet$ & & & $\bullet$ & $\bullet$ \\ % \hspace{1em}Multi (inline) & $\bullet$ & & & & $\bullet$ & & & % & & & & $\bullet$ & $\bullet$ \\ % \hspace{1em}Multi (horiz.) & $\bullet$ & & & & $\bullet$ & & $\bullet$ % & & & & & $\bullet$ & $\bullet$ \\ % \hspace{1em}Multi (vert.) & $\bullet$ & & & & $\bullet$ & & $\bullet$ % & & & & & $\bullet$ & $\bullet$ \\ % \bottomrule % \end{tabular} % \end{table} % % \subsection{Automated Generation of Questions} % % \Moodle's \href{https://docs.moodle.org/en/Calculated_question_type} % {Calculated Questions} types are not supported by this package. % % However, much more flexibly, a scripting language can be used in % combination with \pkg{moodle} to generate a large set of questions, % based on a prototype. % % In this case, the teacher building a quiz often wants one of the questions % to be randomly picked up and presented to the student. To achieve this, % we suggest to apply a specific tag to the questions sharing the same prototype. % After import in \Moodle, when creating a quiz, this tag can be selected to % narrow down a random selection of questions. % % This way, the feature of calculated questions can be reproduced, while % benefiting from the flexibility given by your favorite scripting language. % % In this Section, two possible approaches are presented. % % \subsubsection{Script Generating \TeX\ Code} % % Here are two examples inspired from the work of % \href{https://github.com/avohns/python-latex-moodle-quiz}{A. Vohns}. % The first one relies on the % native \prog{Lua} capabilities of \LuaLaTeX. % \begin{VerbatimOut}[gobble=1]{minted.doc.out} % \begin{quiz}[tags={calculated}]{Example Quiz} % \directlua{ % \end{VerbatimOut} % \inputminted[gobble=2,frame=topline]{latex}{minted.doc.out} % \vspace{-.7cm} % \begin{VerbatimOut}[gobble=1]{minted.doc.out} % function clozenum_print(pair,op,result) % tex.print("\\begin{numerical}$"..pair[1].." "..op.." "..pair[2].." % =$".."\\item ",result,"\\end{numerical}") % end % function cloze_print(pair,points) % tex.print("\\begin{cloze}[points="..points.."]{Arithmetic Quiz % ("..pair[1]..", "..pair[2]..")}Solve the following tasks!\\\\") % clozenum_print(pair,"+",pair[1]+pair[2]) % clozenum_print(pair,"-",pair[1]-pair[2]) % clozenum_print(pair,"*",pair[1]*pair[2]) % if pair[1]/pair[2]==math.floor(pair[1]/pair[2]) then % clozenum_print(pair,":",math.floor(pair[1]/pair[2])) % end % tex.print("\\end{cloze}") % end % for x = 2,4 do % for y = 2,4 do % if x>y then % if x/y==math.floor(x/y) then points=1 else points=2 end % cloze_print({x,y},points) % end % end % end % \end{VerbatimOut} % \inputminted[]{lua}{minted.doc.out} % \vspace{-.7cm} % \begin{VerbatimOut}[gobble=1]{minted.doc.out} % } % \end{quiz} % \end{VerbatimOut} % \inputminted[gobble=2,frame=bottomline]{latex}{minted.doc.out} % The second example makes use of the \pkg{python} package (|\usepackage{python}|). % \begin{VerbatimOut}[gobble=1]{minted.doc.out} % \begin{quiz}[tags={calculated}]{Example Quiz} % \begin{python} % \end{VerbatimOut} % \inputminted[gobble=2,frame=topline]{latex}{minted.doc.out} % \vspace{-.7cm} % \begin{VerbatimOut}[gobble=1]{minted.doc.out} % def clozenum_print(pair,op,result): % print(rf"""\begin{{numerical}} % ${pair[0]} {op} {pair[1]} =$\item {result} % \end{{numerical}}""") % def cloze_print(pair,points): % print(rf"""\begin{{cloze}}[points={points}]{{Arithmetic Quiz % {(pair[0],pair[1])}}}Solve the following tasks!\\""") % clozenum_print([x,y],"+",x+y) % clozenum_print([x,y],"-",x-y) % clozenum_print([x,y],"*",x*y) % if pair[0]/pair[1] == pair[0]//pair[1]: % clozenum_print([x,y],":",x//y) % print("\end{cloze}") % for x in range(2,5): % for y in range(2,5): % if x > y: % if x/y == x//y: % points=1 % else: % points=2 % cloze_print([x,y],points) % \end{VerbatimOut} % \inputminted[]{python}{minted.doc.out} % \vspace{-.7cm} % \begin{VerbatimOut}[gobble=1]{minted.doc.out} % \end{python} % \end{quiz} % \end{VerbatimOut} % \inputminted[gobble=2,frame=bottomline]{latex}{minted.doc.out} % These two example codes yield the same \XML\ content. % % \subsubsection{\TeX\ Code As a Template} % % Instead of mixing \TeX\ and scripting code into the same file, it is probably % a better practice to write a |.tex| template file with predefined variables and % manipulate the latter using an external script. % % The \pkg{moodle} package facilitates the development of question templates. % Specific control sequences (e.g.~\TeX\ commands) can be used in place of answers % or other parameters to the questions. In \optn{draft} mode, this should be % possible even where \pkg{moodle} expects numerical values (e.g.~answers of % numerical questions). % After drafting and question development, the control sequences can then be % substituted, by means of a scripting language, with instances of the variables % pulled from a database (e.g. |*.csv| file). % This way, complex quizzes, with parameterized TikZ pictures for instance, can be produced. % % This approach, briefly presented in the rest of this section, is demonstrated by % C. Caprani in \href{https://github.com/ccaprani/genquiz}{genquiz}, % with Python for scripting and Jinja as a templating engine. % % The specific control sequence of the template is the \TeX\ command |\VAR|, taking % the variable name to be substituted from the database as an argument. In order to % highlight the fields for template development, in \optn{draft} mode, this command is % defined to typeset the variable name in bold red font. When generating the \XML\ % question bank, in \optn{final} mode, the variable values are substituted for the % specific control sequence. Variables can be used to define numerical answers, % tolerances, and even parameterize TikZ pictures. % % \begin{VerbatimOut}[gobble=1]{minted.doc.out} % \documentclass{article} % \usepackage[draft]{moodle} % \usepackage{tikz} % \newcommand*{\VAR}[1]{\textcolor{red}{\textbf{#1}}} % \begin{document} % \begin{quiz}{Disk or Square} % \begin{cloze}[tags={disk area}] % {Area of the Disk QID00\VAR{qidx}} % \begin{tikzpicture} % \draw[fill=black!20] circle[radius=1]; % \draw[<->] (0,0)--(1,0)node[above,midway]{\VAR{radius}}; % \end{tikzpicture} % A disk has radius \VAR{radius}, what is its area? % \begin{numerical}[points=1,penalty=0] % \item[tolerance = \VAR{areatol}] \VAR{area} % \item[fraction=0,feedback={Note the units.}] * % incorrect % \end{numerical} % Provide your answers to 3 significant digits. % \end{cloze} % \end{quiz} % \end{document} % \end{VerbatimOut} % \inputminted[gobble=1,frame=lines]{latex}{minted.doc.out} % % A small python code that reads the template and renders the actual |*.tex| file % is shown below. In this example, the template file is called |quiz_template.tex| and % the variables are hard-coded as a list of Python dictionaries. But nothing prevents % you from generating them on-the-fly or picking them from a database. % It is worth noting that \prog{jinja2} will process all |\VAR{|\meta{name}|}| occurrences, % regardless of \TeX\ comments. % % \begin{VerbatimOut}[gobble=1]{minted.doc.out} % import os % import jinja2 % % # Tell jinja what to look for in the template % # (from web.archive.org/web/20121024021221/http://e6h.de/post/11/) % latex_jinja_env = jinja2.Environment( % variable_start_string=r"\VAR{", % variable_end_string=r"}", % comment_start_string=r"\#{", % comment_end_string="}", % loader=jinja2.FileSystemLoader(os.path.abspath(".")), % ) % % # Load the template % template = latex_jinja_env.get_template("quiz_template.tex") % % # Prepare the variables or read from a database % database = [ % {"qidx": 1, "radius": 2, "areatol": 0.1, "area": 12.57}, % {"qidx": 2, "radius": 3, "areatol": 0.2, "area": 28.27}, % {"qidx": 3, "radius": 4, "areatol": 0.4, "area": 50.26}, % ] % % for row in database: % # combine template and variables % document = template.render(**row) % % # XML files are generated by moodle.sty in "final" mode % document = document.replace(r"\usepackage[draft]{moodle}", % r"\usepackage{moodle}") % % # write document % with open(f"{row['qidx']}.tex","w",encoding="utf-8") as outfile: % outfile.write(document) % \end{VerbatimOut} % \inputminted[gobble=1,frame=lines]{python}{minted.doc.out} % % Executing this Python code will result in three new |.tex| files in the current directory. % These can then be compiled with a \TeX\ engine to produce the individual \XML\ files. % Of course, for a large number of quizzes it is preferable to automate this compilation, % and to combine the large number of resulting \XML\ files into a single \XML\ file for upload % to Moodle. See \href{https://github.com/ccaprani/genquiz}{genquiz} for more details. % % Naturally, the concept of templating, demonstrated here with Python, may be orchestrated % using other scripting languages. % % \section{Conversion to HTML} % % \subsection{Level of Support} % % The package \pkg{moodle.sty} tries to automatically % convert the \LaTeX\ code included in the questions % into \HTML\ for web display. % % With this aim, a number of \TeX\ and \LaTeX\ macros, % commands, and environments undergo a tailored treatment % when \pkg{moodle} generates the \XML\ file. A few tables % describe the current level of support: % \begin{enumerate} % \item text mode diacritic macros (e.g.~|\"u|) in Table~\vref{tab:diacritics}, % \item text mode macros for ligatures (e.g.~\cmd{\oe}) and other glyphs (e.g.~\cmd{\aa}) in % Table~\vref{tab:ligatures_and_glyphs}, % \item horizontal spacing (e.g.~\cmd{\quad}) and line breaking (e.g.~\cmd{\\}) macros in % Table~\vref{tab:spacing}, % \item text mode symbols (e.g.~\cmd{\$}) and punctuation (e.g.~\cmd{\textexclamdown}) macros in % Table~\vref{tab:symbols_and_punctuation}, and finally % \item other \LaTeX\ commands (e.g.~\cmd{\emph}) and environments (e.g.~\env{center}) % in Table~\vref{tab:commands_and_environments}. % \end{enumerate} %^^A \pagebreak % %^^A Inspired by https://tex.stackexchange.com/a/163717/228515 % \begin{table}[tbp] % \centering % \caption{Text mode diacritic macros undergoing a tailored conversion to \HTML.} % \label{tab:diacritics} % \begin{threeparttable} % \begin{tabular}{clll} % \toprule % Definition & Letter List\tnote{1} & Description & Samples\\ % \cmidrule(lr){1-1}\cmidrule(lr){2-2}\cmidrule(lr){3-3}\cmidrule(lr){4-4} % \cmd{\"}\marg{letter} & a, e, i, o, u, y & % \href{https://en.wikipedia.org/wiki/Diaeresis_(diacritic)}{umlaut or diaeresis} % & \"{a} \"{A} \"{e} \"{E} \"{i} \"{I} \"{o} \"{O} \dots\ \"{Y}\\ % \cmd{\'}\marg{letter} & a, e, i, o, u & % \href{https://en.wikipedia.org/wiki/Acute\_accent}{acute accent} % & \'{a} \'{A} \'{e} \'{E} \'{i} \'{I} \'{o} \'{O} \'{u} \'{U}\\ % \cmd{\.}\marg{letter} & c, e, g, i, z & % \href{https://en.wikipedia.org/wiki/Dot_(diacritic)#Overdot}{overdot} % & \.{c} \.{C} \.{e} \.{E} \.{g} \.{G} \.{i} \.{I} \.{z} \.{Z}\\ % \cmd{\=}\marg{letter} & a, e, g, i, o, u, y & % \href{https://en.wikipedia.org/wiki/Macron_(diacritic)}{macron} % & \={a} \={A} \={e} \={E} \={g} \={G} \={i} \={I} \dots\ \={Y}\\ % \cmd{\^}\marg{letter} & a, e, i, o, u & % \href{https://en.wikipedia.org/wiki/Circumflex}{circumflex} & % \^{a} \^{A} \^{e} \^{E} \^{i} \^{I} \^{o} \^{O} \^{u} \^{U}\\ % \cmd{\`}\marg{letter} & a, e, i, o, u & % \href{https://en.wikipedia.org/wiki/Grave\_accent}{grave accent} % & \`{a} \`{A} \`{e} \`{E} \`{i} \`{I} \`{o} \`{O} \`{u} \`{U}\\ % \cmd{\~}\marg{letter} & a, n, o & % \href{https://en.wikipedia.org/wiki/Tilde}{tilde} % & \~{a} \~{A} \~{n} \~{N} \~{o} \~{O}\\ % \cmd{\b}\marg{letter} & b, d, k, l, n, t, z & % \href{https://en.wikipedia.org/wiki/Macron_below}{macron below} % & \b{b} \b{B} \b{d} \b{D} \b{k} \b{K} \b{l} \dots\ \b{Z}\\ % \cmd{\c}\marg{letter} & c, s, t & % \href{https://en.wikipedia.org/wiki/Cedilla}{cedilla} % & \c{c} \c{C} \c{s} \c{S} \c{t} \c{T}\\ % \cmd{\d}\marg{letter} & a, b & % \href{https://en.wikipedia.org/wiki/Dot_(diacritic)#Underdot}{underdot} % & \d{a} \d{A} \d{b} \d{B}\\ % \cmd{\H}\marg{letter} & o, u & % \href{https://en.wikipedia.org/wiki/Double\_acute\_accent}{double acute accent} % & \H{o} \H{O} \H{u} \H{U}\\ % \cmd{\k}\marg{letter} & a, e, i, o, u & % \href{https://en.wikipedia.org/wiki/Ogonek}{ogonek} % & \k{a} \k{A} \k{e} \k{E} \k{i} \k{I} \k{o} \k{O} \k{u} \k{U}\\ % \cmd{\r}\marg{letter} & a, u & % \href{https://en.wikipedia.org/wiki/Ring_(diacritic)#Overring}{overring} % & \r{a} \r{A} \r{u} \r{U} \\ %^^A \cmd{\t}\marg{letter} & a, b, c & tie-after accent & \t{oo}\\ % \cmd{\u}\marg{letter} & a, e, g, i\tnote{2}, \i, o, u & % \href{https://en.wikipedia.org/wiki/Breve}{breve} % & \u{a} \u{A} \u{e} \u{E} \u{i} \u{\i} \u{I} \u{o} \u{O} \u{u} \u{U}\\ % \cmd{\v}\marg{letter} & c, d, e, l, n, r, s, t, z & % \href{https://en.wikipedia.org/wiki/Caron}{caron or h\'a\v{c}ek} % & \v{c} \v{C} \v{d} \v{D} \v{e} \v{E} \v{l} \dots\ \v{Z}\\ % \bottomrule % \end{tabular} % \begin{tablenotes} % \item[1] The lowercase letters listed also stand for their uppercase % equivalent. % \item[2] pdf\TeX\ v3.14159265 typesets |\u{i}| with an objectionable tittle. % Use |\u{\i}|. % \end{tablenotes} % \end{threeparttable} % \end{table} % % \begin{table}[tbp] % \centering % \caption{Text mode ligature and glyph macros undergoing a tailored conversion % to \HTML.} % \label{tab:ligatures_and_glyphs} % \begin{threeparttable} % \begin{tabular}{cccc} % \toprule % \multicolumn{2}{c}{Lowercase} & \multicolumn{2}{c}{Uppercase} \\ % \cmidrule(lr){1-2}\cmidrule(lr){3-4} % Definition & Sample & Definition & Sample \\ % \cmidrule(lr){1-1}\cmidrule(lr){2-2}\cmidrule(lr){3-3}\cmidrule(lr){4-4} % \cmd{\aa} & \aa & \cmd{\AA} & \AA \\ % \cmd{\ae} & \ae & \cmd{\AE} & \AE \\ % \cmd{\dh} & \dh & \cmd{\DH} & \DH \\ % \cmd{\dj} & \dj & \cmd{\DJ} & \DJ \\ % \cmd{\i} & \i & & \\ % \cmd{\ij} & \ij & \cmd{\IJ} & \IJ \\ % \cmd{\j} & \j & & \\ % \cmd{\l} & \l & \cmd{\L} & \L \\ % \cmd{\ng} & \ng & \cmd{\NG} & \NG \\ % \cmd{\o} & \o & \cmd{\O} & \O \\ % \cmd{\oe} & \oe & \cmd{\OE} & \OE \\ % \cmd{\ss} & \ss & \cmd{\SS}\tnote{1} & \SS\tnote{2} \\ % \cmd{\th} & \th & \cmd{\TH} & \TH \\ % \bottomrule % \end{tabular} % \begin{tablenotes} % \item[1] Contrarily to most fonts, Libertine, used in this documentation and % available for instance via the package \pkg{libertine}, defines the glyph % \SS. % \item[2] \LaTeX\ defines the \cmd{\SS} macro but pdf\TeX\ renders it as a % doubled capital S. % \end{tablenotes} % \end{threeparttable} % \end{table} % % \begin{table}[tbp] % \centering % \caption{Text mode horizontal spacing and line breaking macros undergoing a % tailored conversion to \HTML.} % \label{tab:spacing} %^^A Inspired by https://tex.stackexchange.com/a/74354/228515 % \begin{threeparttable} % \begin{tabular}{ll} % \toprule % Definition & Description \\ % \cmidrule(lr){1-1}\cmidrule(lr){2-2} % \cmd{\,} or \cmd{\thinspace} & narrow non-breaking space \\ % |~| or \texttt{\textbackslash\textvisiblespace} & non-breaking space \\ % \cmd{\>}\tnote{1},{ } \cmd{\:}{}\tnote{2}{ } or \cmd{\medspace}\tnote{2} & mid space \\ % \cmd{\;}\tnote{2}{ } or \cmd{\thickspace}\tnote{2} & thick space \\ % \cmd{\enspace} & nut (1en wide space)\\ % \cmd{\quad} & mutton (1em wide space)\\ % \cmd{\qquad} & doubled mutton (2em wide space)\\ % \cmd{\textvisiblespace} & sample: \textvisiblespace \\ % \cmd{\\} or \cmd{\newline} & start a new line \\ % |\par| or \meta{blank line} & start a new paragraph \\ % \bottomrule % \end{tabular} % \begin{tablenotes} % \item[1] \cmd{\>} is defined in math-mode only. % \item[2] \cmd{\:}, \cmd{\medspace}, \cmd{\;}, and \cmd{\thickspace} require the package % \pkg{amsmath}. % \end{tablenotes} % \end{threeparttable} % \end{table} % % \begin{table}[tbp] % \centering % \caption{Text mode punctuation marks and symbol macros undergoing a tailored % conversion to \HTML. A baseline is represented in the samples of quotations % marks, in order to draw attention to their vertical positioning.} % \label{tab:symbols_and_punctuation} % \newsavebox\textbox % \newcommand\showbaseline[1]{\leavevmode\sbox\textbox{#1} % \rlap{\rule{\wd\textbox}{.1pt}}\usebox\textbox} % \begin{threeparttable} % \begin{tabular}{llc} % \toprule % Package & Definition & Sample \\ % \cmidrule(lr){1-1}\cmidrule(lr){2-2}\cmidrule(lr){3-3} % \LaTeX\ base & \cmd{\%} & \% \\ % & \cmd{\#} & \# \\ % & \cmd{\_} & \_ \\ % & \cmd{\textbackslash} & \textbackslash \\ % & \cmd{\$} & \$ \\ % & \cmd{\&} & \& \\ % & \cmd{\S} & \S \\ % & |\{| & \{ \\ % & |\}| & \} \\ % & \cmd{\texteuro} & \texteuro \\ % & \cmd{\dots} or \cmd{\ldots} & \dots \\ % & \cmd{\textexclamdown} & \textexclamdown \\ % & \cmd{\textquestiondown} & \textquestiondown \\ % & |--| & -- \\ % & |=| & = \\ % & |`| and |'|\tnote{1} & \showbaseline{` '} \\ % & \cmd{\textquoteleft} and \cmd{\textquoteright} % & \showbaseline{\textquoteleft\ \textquoteright} \\ % & |``| and |''|\tnote{1,2} & \showbaseline{`` ''} \\ % & \cmd{\textquotedblleft} and \cmd{\textquotedblright} % & \showbaseline{\textquotedblleft\ \textquotedblright} \\ % & \cmd{\textquotesingle} & \showbaseline{\textquotesingle\ } \\ % & |"| & \showbaseline{" }\tnote{2} \\ % & \cmd{\textquotedbl} & \showbaseline{\textquotedbl\ }\\ % & \cmd{\guilsinglleft} and \cmd{\guilsinglright} % & \showbaseline{\guilsinglleft\ \guilsinglright} \\ % & \cmd{\guillemotleft} and \cmd{\guillemotright} % & \showbaseline{\guillemotleft\ \guillemotright}\\ % & \cmd{\quotesinglbase} & \showbaseline{\quotesinglbase\ }\\ % & \cmd{\quotedblbase} & \showbaseline{\quotedblbase\ } \\ % \cmidrule(lr){1-1} % \pkg{eurosym} & \cmd{\euro} & \euro\\ % \cmidrule(lr){1-1} % \pkg{babel} & \cmd{\flq} and \cmd{\frq} & \showbaseline{\flq\ \frq} \\ % & \cmd{\flqq} and \cmd{\frqq} & \showbaseline{\flqq\ \frqq} \\ % \cmidrule(lr){1-1} % \pkg{babel}, opt. \optn{french} & \cmd{\og} and \cmd{\fg}\tnote{3} % & \showbaseline{\flqq\ \frqq} \\ % \cmidrule(lr){1-1} % \pkg{babel}, opt. \optn{german} & \cmd{\glq} and \cmd{\grq} % & \showbaseline{\glq\ \grq} \\ % & \cmd{\dq} & \showbaseline{\dq\ }\tnote{2} \\ % & \cmd{\glqq} and \cmd{\grqq} & \showbaseline{\glqq\ \grqq} \\ % \bottomrule % \end{tabular} % \begin{tablenotes} % \item[1] When placed in math mode, the single straight quote (\texttt{'}) is % passed as-is to the \XML, even when doubled (double prime symbol). % \item[2] In roman type, \LuaLaTeX\ and \XeLaTeX\ typeset the double straight % quote symbol (\texttt{"}) and the command \cmd{\dq} as a double right quote % (\textquotedblright). Instead, \pkg{moodle} follows pdf\LaTeX: whatever % the \TeX\ engine used, the double straight quote (\texttt{"}) is passed to the \XML. % \item[3] The way \cmd{\og} and \cmd{\fg} are typeset in the \PDF\ depends on the % current babel language. Regardless, \pkg{moodle} passes the symbols % \texttt{\guillemotleft} and \texttt{\guillemotright} to the \XML. % \end{tablenotes} % \end{threeparttable} % \end{table} % % \begin{table}[tbp] % \centering % \caption{\LaTeX\ commands and environments undergoing a tailored conversion % to \HTML.} % \label{tab:commands_and_environments} % \begin{tabular}{lll} % \toprule % Package & Commands & Environments \\ % \cmidrule(lr){1-1}\cmidrule(lr){2-2}\cmidrule(lr){3-3} % \LaTeX\ base & |{}|& |$|$\cdots$|$| (inline math) \\ % & \cmd{\relax} & |\(|$\cdots$|\)| (inline math) \\ % & \cmd{\LaTeX} & |$$|$\cdots$|$$| (display math) \\ % & \cmd{\TeX} & \cmd{\[}$\cdots$\cmd{\]} (display math) \\ % & \cmd{\emph}\marg{\dots} & \env{center} \\ % & \cmd{\textbf}\marg{\dots} & \env{enumerate} \\ % & \cmd{\textit}\marg{\dots} & \env{itemize} \\ % & \cmd{\textsc}\marg{\dots} & \env{quote} \\ % & \cmd{\textsuperscript}\marg{\dots} & \env{quotation}\\ % & \cmd{\textsubscript}\marg{\dots} &\\ % & \cmd{\texttt}\marg{\dots} &\\ % & \cmd{\underline}\marg{\dots} &\\ % \cmidrule(lr){1-1} % \pkg{hyperref} & \cmd{\href}\marg{\dots}\marg{\dots} &\\ % \pkg{url} or \pkg{hyperref} & \cmd{\url}\marg{\dots} &\\ % \cmidrule(lr){1-1} % \pkg{babel}, opt. \optn{french} & \cmd{\fup}\marg{\dots} &\\ % & \cmd{\up}\marg{\dots} &\\ % \cmidrule(lr){1-1} % \pkg{graphics} or \pkg{graphicx} & % \cmd{\includegraphics}\oarg{\dots}\marg{\dots} \\ % \cmidrule(lr){1-1} % \pkg{tikz} & \cmd{\tikz}\oarg{\dots}\marg{\dots} & \env{tikzpicture}\oarg{\dots} \\ % \cmidrule(lr){1-1} % \pkg{verbatim} & \cmd{\verbatiminput}\marg{\dots} &\\ % \cmidrule(lr){1-1} % \pkg{fancyverb} or % \pkg{fvextra}& \cmd{\VerbatimInput}\oarg{\dots}\marg{\dots} &\\ % & \cmd{\LVerbatimInput}\oarg{\dots}\marg{\dots} &\\ % & \cmd{\BVerbatimInput}\oarg{\dots}\marg{\dots}& \\ % \cmidrule(lr){1-1} % \pkg{minted} & \cmd{\inputminted}\oarg{\dots}\marg{\dots}\marg{\dots} &\\ % \bottomrule % \end{tabular} % \end{table} % % In addition, |<| and |>| will be converted to their HTML equivalents |<| % and |>| in the \XML\ file. This prevents portions of the code to be % interpreted by \Moodle\ as \HTML\ tags. % % A doubled dash will be converted to en-dash |–| \emph{outside math mode}. % Empty groups |{}| will be passed to the XML only \emph{in math mode}. % % Be aware that, apart what is described previously, \pkg{moodle} \emph{does % not know how to convert any other \TeX\ or \LaTeX\ commands to \HTML.} % If other sequences are used, they may be passed verbatim to the \XML\ file % or may cause unpredicted results. % % If you think of another \LaTeX\ command that should be changed to an HTML % equivalent, please have a look at Section~\vref{sec:dev}. % % \DescribeMacro[question,answer,feedback]{\htmlonly}\oarg{Content for traditional output} % \marg{HTML content} is a command to be used inside question environments (text, % answers, or feedback). It lets you pass directly code to the \XML\ file while being % ignored for the traditional output (\PDF). The \HTML\ content passed as an argument % is subject to no particular processing and users should not expect to be able to % pass dangerous characters like |\|, |%|, or |#|. An optional argument allows to % pass contents to be processed for the traditional output. This argument is % ignored for the \XML\ output. % For instance, one can write code like this in a question environment % \begin{quote} % |\htmlonly[\fbox{PDF contents}]{|\\ % |
|\\ % \rule{10em}{0pt}|HTML contents
|\\ % |}| % \end{quote} % % \DescribeMacro[moodle]{\htmlregister}\marg{command} is a command that lets you % specify a macro that must be expanded in the \XML\ file. It works only when % the macro is defined without optional argument.\watchout % % \DescribeMacro[moodle]{\moodleregisternewcommands} % When the list of user-defined macros is long, it becomes cumbersome to % record them individually for expansion. Calling \cmd{\moodleregisternewcommands} % watches for subsequent calls to \cmd{\newcommand}, \cmd{\renewcommand}, % \cmd{\providecommand}, and their starred variants such that the corresponding % commands are automatically expanded by \pkg{moodle}. % Again, this works only if the macros are defined \emph{without} optional % argument.\watchout % % \subsection{Graphics} % The \pkg{moodle} package can handle two kinds of graphics seamlessly. % External graphics files may be included with the \cmd{\includegraphics} command % from the \pkg{graphicx} package, and graphics may be generated internally using \TikZ. % In either case, the graphics will be embedded in base-64 encoding directly within % the \Moodle\ \XML\ produced. This prevents the hassle of managing separate % graphics files on the \Moodle\ server, as \Moodle\ will store the picture % within the question in the question bank. % % \subsubsection{Default \texttt{includegraphics}} % % \DescribeMacro[graphics,graphicx]{\includegraphics}\oarg{options}\marg{file} can be used to % include graphic files in both \PDF\ and the \XML\ outputs. % The only options currently supported are \optn{height}\DescribeKey[includegraphics]{height}\ % and \optn{width}\DescribeKey[includegraphics]{width}. Attempts to use other % \cmd{\includegraphics} options, such as \optn{scale} or \optn{angle}, will affect the \PDF\ % but not the \XML\ output. % The dimensions set by \optn{height} and \optn{width} are \TeX\ dimensions such as % \texttt{4\,in} or \texttt{2.3\,cm}. % In order to prepare the image for web viewing, this package converts those % dimensions to pixels using a default of % 103 pixels per inch.\footnote{This % number was selected because an image with % || showed up as almost exactly 1 inch % tall and 1 inch wide on several of this author's devices and browsers % as of January 2016.} % \DescribeKey[includegraphics]{ppi} % That value may be changed by setting the \optn{ppi} key (e.g., \texttt{ppi=72}); % this is probably best done for the entire document with a \cmd{\moodleset} command, % rather than image-by-image. % % \DescribeMacro[graphics,graphicx]{\graphicspath}|{{|\meta{path1}|},{|\meta{path2}|},...}| can be % used to specify the locations of the pictures to be included. % % A special rule was added for the inclusion of \GIF\ pictures (\filenm{.gif} extension). % These files are passed as-is to the \XML, preserving potential animations. % However, as pdf\TeX\ engines do not support the \GIF\ format, the picture is % passed to the \PDF\ output after a conversion to the \PNG\ format. When the \GIF\ % file is animated, only its first frame is passed to the \PDF. % %^^A \DescribeMacro[moodle]{\DeclareGraphicsAlien} Users may declare other graphic %^^A formats with the command \cmd{\DeclareGraphicsAlien}\marg{alien extension} %^^A \marg{native extension}\marg{command line for conversion}. % % \subsubsection{\TikZ\ Pictures} % \TikZ\ is a user-friendly syntax layer for \acro{PGF}, the macro \LaTeX\ package for creating % graphics. More information on \TikZ\ can be found at \url{https://ctan.org/pkg/pgf}. % % When \TikZ\ is loaded and used to define pictures, \pkg{moodle} invokes % the \pkg{external} \TikZ\ library, so that each \env{tikzpicture} environment is compiled % to a freestanding \PDF\ file. % % \subsubsection{Package Option \optn{tikz}}\label{subsec:tikz} % \DescribeOption[moodle]{tikz} % The \pkg{moodle} package admits a \optn{tikz} option which has the following effects: % \begin{itemize} % \item the package \pkg{tikz} is loaded. % \item \DescribeMacro[tikz]{\includegraphics}\cmd{\includegraphics} embeds graphics in a \TikZ\ picture. Consequences are that % \begin{itemize} % \item the pictures encoded in the \XML\ file are resampled. This prevents encoding % images at a higher resolution than rendered by \Moodle. % \item the full set of \cmd{\includegraphics} options is accessible, % e.g.~\optn{scale=.5}, \optn{angle=90}, or |width=.2\textwidth|. % \end{itemize} % \item \DescribeMacro[tikz]{\embedaspict} a macro \cmd{\embedaspict}\marg{\LaTeX\ contents} % is provided for the conversion of inline \LaTeX\ material as images. This can serve % as a workaround to overcome limitations of this package---like the conversion of % \emph{tabular}s to HTML--- or limitations of \Moodle\ itself. % For the definition of this macro, the package \pkg{varwidth} is loaded. % \item optimizations of the \TikZ-external library are disabled: compilation might get % sensibly slower. % \end{itemize} % % \subsubsection{External Tools} % The mechanisms used for handling graphics are somewhat fragile and rely upon % three free external programs. % \begin{enumerate} % \item \prog{GhostScript} (\url{www.ghostscript.com}) is used to convert the \PDF\ output % from \TikZ\ into a \PNG\ raster graphics file. % The default command line is presumed to be \prog{gswin64c.exe} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % (if |\ifwindows| from the \pkg{ifplatform} package returns true) % or \prog{gs} (if |\ifwindows| returns false). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % If your system requires a different command line to invoke \prog{Ghostscript}, % \DescribeMacro[moodle]{\ghostscriptcommand} % you may change it by invoking: % \begin{quote} % |\ghostscriptcommand|\marg{executable filename} % \end{quote} % \item When external graphics files such as \PDF\ are included, % the \prog{ImageMagick} software (\url{www.imagemagick.org}) % converts each file to \PNG\ format. % The command line for \prog{ImageMagick} is the nondescript word \progcode{convert}, % \DescribeMacro[moodle]{\imagemagickcommand} % but may be changed by invoking \cmd{\imagemagickcommand}\marg{executable filename}. % \item \prog{OptiPNG} (\url{http://optipng.sourceforge.net/}) is used to optimize the \PNG\ images. % The command line is presumed to be \prog{optipng}, but can be changed with % \DescribeMacro[moodle]{\optipngcommand}\cmd{\optipngcommand}\marg{executable filename}. % \end{enumerate} % % Please note the following vital points to make the graphics handling work: % \begin{itemize} % \item As of now, graphics are only supported when compiling directly to a \PDF\ % with (\prog{pdf}$\mid$\prog{xe}$\mid$\prog{lua})\prog{latex}. Including \acro{PS} graphics or using \TikZ\ with the \DVI$\to$\acro{PS} workflow is not % yet supported. %^^A \item Filenames should not contains spaces or, under windows, special characters like |_| or |\|. % \item You must have \prog{Ghostscript} and \prog{ImageMagick} installed on your system % to fully use the graphics-handling capabilities of \pkg{moodle}. % \item If \prog{OptiPNG} is not installed, the corresponding system calls will fail with otherwise no % impact on the compilation process: \PNG\ files are passed unoptimized to the \XML\ output. % \item \LaTeX\ must be able to call system commands; that is, \cmd{\write18} must be enabled. % For Mik\TeX, this means adding \progcode{--enable-write18} to the command line of % (\prog{pdf}$\mid$\prog{xe}$\mid$\prog{lua})\prog{latex}; for \TeX\ Live, this means adding \progcode{--shell-escape=true}. % \item Due to security issues with old versions of \prog{Ghostcript}, some systems default to a % policy that prevents the conversion of \PDF\ and \acro{PS} to \PNG. Assuming that, as a user of % \pkg{moodle} which requires shell escape capabilities, you either use a sandboxed % environment or trust the files handled at the system-level, you may want to disable this % over-zealous security policy. For example, % \href{https://stackoverflow.com/a/52661288/14608059}{see this}. % \item Users of the \pkg{circuitikz} package (\url{https://www.ctan.org/pkg/circuitikz}) must % enclose their circuits' \TikZ\ code in the |tikzpicture| environment instead of % the historical \env{circuitikz} environment. That is required, as of \TikZ\ 2.1, % by the \pkg{external} library. % \end{itemize} % % \subsubsection{Package Option \optn{svg}}\label{subsec:svg} % % \paragraph{Important Notice}\watchout[experimental] \emph{The \optn{svg} option is % an experimental feature introduced in \pkg{moodle} v0.8. It has been tested only % under Linux and Windows, with TeX Live 2020, Inkscape v1.0.1 and Scour 0.38.2.} % % \DescribeOption[moodle]{svg} The \pkg{moodle} package admits an experimental % \optn{svg} option which has the following effects: % \begin{itemize} % \item \DescribeMacro[svg]{\includegraphics}\cmd{\includegraphics} can be used to import % \SVG\ graphic files directly (extension \filenm{.svg} or \filenm{.SVG}). In this case, the \SVG\ file % is passed as-is to the \XML\ output and is converted using \href{https://inkscape.org/} % {\prog{Inkscape}} (must be installed) for inclusion in the \PDF\ output. % \item the graphic files in \PDF\ format are converted to the \SVG\ format using % \href{https://inkscape.org/}{Inkscape} (must be installed), rather than being % rasterized. Before inclusion to the \XML\ output, the \SVG\ file is optimized using % the \href{https://github.com/scour-project/scour}{Scour} utility. This % optimization step is optional in the sense that, if the Scour call fails, % the un-optimized \SVG\ file will be passed to the \XML\ output. % Two processes benefit from this \PDF$\to$\SVG\ conversion: % \begin{itemize} % \item inclusion of \PDF\ graphics with \cmd{\includegraphics}, and % \item \TikZ\ pictures that are externalized. % \end{itemize} % \end{itemize} % % % The call of external \SVG\ manipulation utilities can be modified using the macros: % \begin{description} % \item \ItemDescribeMacro[svg]{\PDFtoSVGcommand}\ for conversion % from \PDF\ to \SVG, % \item \ItemDescribeMacro[svg]{\SVGtoPDFcommand}\ for conversion % from \SVG\ to \PDF, and % \item \ItemDescribeMacro[svg]{\optiSVGcommand}\ for the % optimization of \SVG\ files. % \end{description} % % \subsection{Verbatim Code} % % Because, for \HTML\ translation, \pkg{moodle} parses the body of questions, the use of % verbatim code results in compilation errors. This is why the use of |\verb|, % \env{verbatim} and other standard utilities is not supported. % % However, using the following three utilities, verbatim code can be imported from an external file: % \begin{enumerate} % \item \cmd{\verbatiminput}\marg{filename}\DescribeMacro[verbatim]{\verbatiminput}\ % from the \pkg{verbatim} package inserts verbatim code in both the \PDF\ and the % \acro{XML} for \Moodle, without fancy additions. % \item The macro \cmd{\VerbatimInput}\marg{options}\marg{filename} % \DescribeMacro[fancyvrb,fvextra]{\VerbatimInput}\ from % \pkg{fancyvrb} or \pkg{fvextra} does more, with several options and settings % offered (see below). % The variants \DescribeMacro[fancyvrb,fvextra]{\BVerbatimInput}\cmd{\VBerbatimInput} and % \DescribeMacro[fancyvrb,fvextra]{\LVerbatimInput}\cmd{\LVerbatimInput} are also supported, % with no difference on the \XML\ output. % The variants with a star are unsupported and result in errors when used. % \item On top of that \cmd{\inputminted}\oarg{options}\marg{lang}\marg{filename}\ % \DescribeMacro[minted]{\inputminted} from the \pkg{minted} package offers syntax % highlighting tailored to the specified language. % \end{enumerate} % The \pkg{moodle} package handles these three commands to pass the code in the output \XML. % With \cmd{\inputminted}, an external Python tool, \prog{pygmentize}, performs syntax analysis and % its \HTML\ formatter is used to populate the \XML. With the other commands, the contents of the % file is passed almost as-is to the XML: in order to survive \Moodle\ import and \HTML\ rendering, % characters |<|, |>|, |&|, |'|, and |"| are converted to \HTML\ equivalents. % % With \cmd{\VerbatimInput} and \cmd{\inputminted}, the options that are taken care of for XML % generation are listed in Table~\vref{tab:verbatim-options}. % Using \cmd{\fvset}\marg{key=value,\dots}, options can be set globally. Equivalently, with \pkg{minted}, % \cmd{\setminted}\oarg{lang}\marg{key=value,\dots} is available. % % \begin{table}[tbp] % \centering % \begin{threeparttable}[b] % \caption{Options and corresponding values considered for \XML\ generation of verbatim material % with \cmd{\VerbatimInput} and \cmd{\inputminted}.} % \label{tab:verbatim-options} % \begin{tabular}{ll} % \toprule % Option keys & Possible values\\\cmidrule(lr){1-1}\cmidrule(lr){2-2} % ^^A\optn{commentchar} & \meta{character}\\ % \optn{gobble} & \meta{integer}\\ % \optn{autogobble}\tnote{1} & \texttt{true} or \texttt{false}\\ % \optn{tabsize} & \meta{integer}\\ % \optn{numbers} & \texttt{none}, \texttt{left}, \texttt{right}, or \texttt{both}\tnote{2}\\ % \optn{firstnumber} & \texttt{auto}, \texttt{last}, or \meta{integer}\\ % \optn{firstline} & \meta{integer}\\ % \optn{lastline} & \meta{integer}\\ % \optn{numberblanklines} & \texttt{true} or \texttt{false}\\ % \optn{highlightlines}\tnote{2} & \marg{coma-separated list of integers or ranges}\\ % \optn{style}\tnote{1} & \meta{string}\\ % \bottomrule % \end{tabular} %\begin{tablenotes} %\item[1] \optn{autogobble}, \optn{numbers=both}, and \optn{style} are from \pkg{minted}. %\item[2] line highlighting is offered only with \pkg{fvextra} or \pkg{minted} loaded. %\end{tablenotes} %\end{threeparttable} %\end{table} % % In order to define the verbatim code from the \LaTeX\ document itself, it is still possible % to use, outside the scope of the \pkg{moodle} questions, the environments \env{filecontents*} % (from the \pkg{filecontents} package or \LaTeX\ kernel itself since 2019) or \env{VerbatimOut} % (from the \pkg{fancyvrb} and \pkg{fvextra} packages). % % Here is an example: % \begin{VerbatimOut}[gobble=2]{minted.doc.out} % \documentclass[12pt,a4paper]{article} % \usepackage[section]{moodle} % \usepackage{minted} % \begin{document} % \begin{quiz}[tags={minted}]{LaTeX Quiz} % \begin{filecontents*}{excerpt.tex} % % !TeX encoding = UTF-8 % % !TeX spellcheck = en_US % % !TEX TS-program = lualatex % \documentclass{article} % \usepackage[nostamp]{moodle} % \ifPDFTeX % FOR LATEX and PDFLATEX % \usepackage[utf8]{inputenc} % necessary % \usepackage[T1]{fontenc} % necessary % \else % assuming XELATEX or LUALATEX % \usepackage{fontspec} % \fi % \end{filecontents*} % \begin{numerical}[tolerance=0]{Loading a Class} % Consider the following \LaTeX\ code excerpt.\\ % \inputminted[numbers=left]{latex}{excerpt.tex} % On which line is the class loaded? % \item[feedback={ % yes! \inputminted[highlightlines={4}]{latex}{excerpt.tex} }] 4 % \item[feedback={Line 3 is just a comment.},fraction=0] 3 % \item[feedback={Line 5 loads the package \texttt{moodle}},fraction=0] 5 % \end{numerical} % \begin{multi}[single]{IDE} % Consider the following \LaTeX\ code excerpt.\\ % \inputminted[numbers=left]{latex}{excerpt.tex} % Which \TeX\ engine will be used by the IDE for compilation. % \item[feedback={Have a closer look at line 3}] \texttt{tex} % \item[feedback={Have a closer look at line 3}] \texttt{latex} % \item[feedback={Have a closer look at line 3}] \texttt{pdflatex} % \item[feedback={Have a closer look at line 3}] \texttt{xelatex} % \item* \texttt{lualatex} % \end{multi} % \end{quiz} % \end{document} % \end{VerbatimOut} % \inputminted[gobble=2,frame=lines]{latex}{minted.doc.out} % % When code decorated with left-side line numbers is placed in question items, the output \PDF\ could % show a collision between numbers of the item and the first line. To avoid this, \cmd{\LVerbatimInput} or % \cmd{\BVerbatimInput} can be used. Instead, when \pkg{minted} is used, the ``left-right'' mode can be % enforced with the \LaTeX\ command: % \begin{quote} % |\RecustomVerbatimEnvironment{Verbatim}{LVerbatim}{}| % \end{quote} % % When using utilities from \pkg{fancyvrb}, \pkg{fvextra}, or \pkg{minted}, \pkg{moodle} % sets framing options for the display of code in the output \PDF: % \begin{quote} % |\fvset{frame=lines,label={[Beginning of code]End of code},|\\ % | framesep=3mm,numbersep=9pt}| % \end{quote} % These settings can be overridden using \cmd{\fvset} after the preamble. % % \section{Internationalization} % % This section is intended for authors of \Moodle\ quizzes writing in one or several % languages other than English. It seems reasonable to assume that those users have heard % of the packages \pkg{babel} or \pkg{polyglossia} (\XeTeX\ or \LuaTeX\ only), that % both aim at enforcing language-related rules to \LaTeX\ documents. % % The contents of the \XML\ file that is generated by \pkg{moodle} depends entirely % on the user input and \Moodle's \XML\ syntax: there is little room for \pkg{moodle} to % internationalize something here. Instead, the focus of this section is the \PDF\ % typesetting that is determined by \pkg{moodle}, where some internalization % efforts can be of help. % % Both \pkg{babel} and \pkg{polyglossia} provide ways of specifiying a language for % the document or a part of it. If one of these packages is loaded in the preamble, % \pkg{moodle} will automatically load the package \pkg{translator} and rely on it % to provide translations of its keys (see Table~\vref{tab:language_keys}) in % different languages, with some knowledge on aliases. The package % \pkg{translations} does a very similar job and can be loaded in the preamble % to serve, if desired, as a replacement for \pkg{translator}. % % Currently, full-support is provided for English, French, German, Italian, and % Spanish. Very limited support is provided for Catalan, Croatian, Czech, Danish, Dutch, % Estonian, Finnish, Hungarian, Icelandic, Lithuanian, Norsk, Polish, Portuguese, % Romanian, Swedish, and Turkish. % % Users may define their own translations in the preamble. For instance % \begin{quote} % |\AfterEndPreamble{|\\ % | \DeclareTranslation|\marg{babel language name}|{True}{Foo}%|\\ % | \DeclareTranslation|\marg{babel language name}|{False}{Bar}%|\\ % |}| % \end{quote} % Note that, when the package \pkg{translations} is loaded, % \cmd{\AfterEndPreamble} must not be used. % % Contributions to improve or broaden the linguistic support are very welcome. % % \begin{center} % \begin{longtable}{ l p{.55\textwidth} } % \caption{\pkg{moodle}'s language keys for internationalization of the \PDF\ typesetting.} % \label{tab:language_keys}\\ % \toprule % Key & Context\\ % \cmidrule(lr){1-1}\cmidrule(lr){2-2} % \endfirsthead % \multicolumn{2}{c}% % {\tablename\ \thetable\ -- \textit{Continued from previous page}} \\ % \hline % Key & Context\\ % \cmidrule(lr){1-1}\cmidrule(lr){2-2} % \endhead % \hline\multicolumn{2}{r}{\textit{Continued on next page}} \\ % \endfoot % \bottomrule % \endlastfoot % \optn{True} & indicates option ``True'' in a True/False question.\\ % \optn{False} & indicates option ``False'' in a True/False question.\\ % \optn{cloze} & tag indicating a ``cloze'' question.\\ % \optn{description} & tag indicating a ``description'' question.\\ % \optn{essay} & tag indicating an ``essay'' question.\\ % \optn{matching} & tag indicating a ``matching'' question.\\ % \optn{multi} & tag indicating a ``multichoice'' question.\\ % \optn{numerical} & tag indicating a ``numerical'' question.\\ % \optn{shortanswer} & tag indicating a ``shortanswer'' question.\\ % \optn{truefalse} & tag indicating a ``true/false'' question.\\ % \optn{Shuffle} & tag indicating that options offered will be shuffled in a % ``multichoice'' or ``matching'' question.\\ % \optn{Single} & tag indicating that only one option can be selected in a % ``multichoice'' question.\\ % \optn{Multiple} & tag indicating that several options can be selected in a % ``multichoice'' question.\\ % \optn{marked out of} & tag indicating the weight of the question (maximum % number of points), followed by a number.\\ % \optn{penalty} & tag indicating the penalty factor applied for each wrong % attempt in adaptive mode.\\ % \optn{tags} & indicates the beginning of a tag list characterizing the % question.\\ % \optn{All-or-nothing} & tag indicating that all correct options must be % selected to get credited a good answer.\\ % \optn{Case-Sensitive} & tag indicating that the case of characters matters % for a ``Shortanswer'' question.\\ % \optn{Case-Insensitive} & tag indicating that the case of characters % does not matter for a ``Shortanswer'' question.\\ % \optn{Drag and drop} & tag indicating that a ``matching'' question relies % on the Drag-and-drop plugin.\\ % \optn{Information for graders} & indicates the beginning of a paragraph % where instructions for the graders of an ``essay'' question are given.\\ % \optn{Response template} & indicates the beginning of a paragraph where % the answer template of an ``essay'' question is represented.\\ % \optn{editor} & tag indicating that, for answering an essay question, an % editor with \HTML\ support will be proposed.\\ % \optn{editorfilepicker} & tag indicating that, for answering an essay question, % an editor with \HTML\ support and a file picker will be proposed.\\ % \optn{plain} & tag indicating that, for answering an essay question, an % editor with no markup support will be proposed.\\ % \optn{monospaced} & tag indicating that, for answering an essay question, % an editor with fixed-width font and no markup support will be proposed.\\ % \optn{noinline} & tag indicating that, for answering an essay question, a file % picker will be proposed.\\ % \optn{Total of marks} & at the end of the quiz, indicates the sum of the % weights of all questions, followed by a colon and a number. \\ % \end{longtable} % \end{center} % % \section{Package Development}\label{sec:dev} % % \subsection{Feature Requests, Bug Reports, and Contributions} % % This package is developed as a collaborative project, currently hosted % on the Gitlab server instance \url{https://framagit.org/mattgk/moodle}. % The project's activity can be monitored there: reported issues, last % modifications, \dots % % Contributions, either bug reports or fixes, are welcome. Users willing to % help can either sign-in with an existing \brand{GitHub}, \brand{Gitlab.com}, or % \brand{Bitbucket} account or register a new account. % % Of course, getting in touch with the package maintainer by % \href{mailto:guerquin-kernATcrans.org}{email} works as well. % % The authors have used this package together with a limited number of colleagues % for a few semesters of teaching. If other users adopt this package, we fully expect them % to find bugs. % % When experiencing a problem and before reporting it, please check whether % or not something similar has already been filed as an issue % \href{https://framagit.org/mattgk/moodle/-/issues?scope=all&state=all}{here}. % If the problem appears to be new, please report it by following these steps: % \begin{enumerate} % \item Prepare a \emph{minimal} working example, i.e. a \filenm{.tex} file shrunk down % to the strict minimum (loaded packages, code, \dots) while still showing the % faulty behavior upon compilation. % \item Gather and send the \filenm{*.tex}, \filenm{*.log} and \filenm{*-moodle.xml} files together % with an explanation about % \begin{itemize} % \item your local working environment (\TeX\ engine and distribution, platform, % external tools used, \dots), % \item the version of the \Moodle\ instance you are using % (for instance see the file |https://|\meta{server-domain}|/lib/upgrade.txt| ) % \item the faulty behavior, and % \item what you expected instead. % \end{itemize} % \end{enumerate} % % \subsection{Known Limitations} % % When using with pdf\TeX\ for compilation, \pkg{moodle} supports % question contents with \acro{ASCII} characters only. The use of % non-\acro{ASCII} characters may work in some cases but will most % probably yield compilation errors or undesired \XML\ contents. % % Instead, \pkg{moodle} will work flawlessly when \XeTeX\ and % \LuaTeX\ are used to compile \UTF-8 encoded documents. % % Table~\vref{tab:support-limitations} lists % some features supported, limitations, and bugs. %\begin{table}[tbp] %\centering %\begin{threeparttable}[b] %\caption{Content enrichment (pictures, equations) support after \XML\ import in \Moodle\ v3.5.7, % depending on the question type.} %\label{tab:support-limitations} %\begin{tabular}{lccc} % \toprule % & \multicolumn{3}{l}{XML rendering in\dots}\\\cmidrule(lr){2-4} %Question type & Question & Answer & Feedback\\\cmidrule(lr){1-1}\cmidrule(lr){2-2} %\cmidrule(lr){3-3}\cmidrule(lr){4-4} % \href{https://docs.moodle.org/en/Multiple_Choice_question_type}{Multichoice} %& yes & yes & yes \\ % \href{https://docs.moodle.org/en/Numerical_question_type}{Numerical} %& yes & no\tnote{1} & yes \\ % \href{https://docs.moodle.org/en/Short-Answer_question_type}{Short Answer} % & yes & no\tnote{1} & yes \\ % Matching (\href{https://docs.moodle.org/en/Matching_question_type}{std}) %& yes & no\tnote{2} & no\tnote{3} \\ % Matching (\href{https://docs.moodle.org/en/Drag_and_drop_matching_question_type}{dd}) % & yes & yes\tnote{4} & no\tnote{3} \\ % \href{https://docs.moodle.org/en/Essay_question_type}{Essay} %& yes & yes\tnote{5,6} & yes\tnote{5} \\ % \href{https://docs.moodle.org/en/True/False_question_type}{True/False} %& yes & no & yes \\ % \href{https://docs.moodle.org/en/Description_question_type}{Description} %& yes & $\varnothing$ & yes \\ %\href{https://docs.moodle.org/en/Embedded_Answers_(Cloze)_question_type}{Cloze} & %yes & $\varnothing$& $\varnothing$ \\\cmidrule(lr){1-1} %\hspace{1em}Numerical & yes & no\tnote{1} & yes \\ %\hspace{1em}Short Answer & yes & no\tnote{1} & yes\tnote{7} \\ %\hspace{1em}Multi (inline) & yes & no\tnote{2} & yes\tnote{7} \\ %\hspace{1em}Multi (horizontal) & yes & yes & yes \\ %\hspace{1em}Multi (vertical) & yes & yes & yes \\\bottomrule %\end{tabular} %\begin{tablenotes} %\item[1] \Moodle\ prompts the student for an answer and then compares it to the %solutions provided. This is text-only. %\item[2] \Moodle\ uses a dropdown list to let one choose among the possible %answers. This forbids either picture inclusion and \LaTeX\ rendering. %\item[3] Not supported by \Moodle\ (in this context, answer-specific feedback %represents lots of possible combinations). %\item[4] The drag-and-drop-matching plugin seems broken before version 1.6 %20190409. \Moodle's \XML\ import fails with a \texttt{dmlwriteexception} when %the field content exceeds few hundreds characters. This prevents the inclusion %of most base64 images and maybe some complicated equations. %\item[5] For this question type and in the context of \XML\ generation, the %Answer column represents the ``template" while the Feedback column represents %the ``notes for the grader". Obviously, the grading process is not automatic %and there is no answer-specific feedback. %\item[6] Picture and \LaTeX\ rendering could be done, but only after %submission and only if the keyval ``response format" is set to ``html". %\item[7] \Moodle\ only reveals the feedback when hovering the checkmark or X %mark with the mouse. %\end{tablenotes} %\end{threeparttable} %\end{table} % % Some features of \Moodle\ quizzes have not yet been implemented in \pkg{moodle}. % Here is a non-exhaustive list. % \begin{itemize} % \item \Moodle's feature of designating feedback for correct, % partially correct, and incorrect answers. %^^A \item Calculated questions; that is, automatically generated \env{numerical} questions %^^A using randomly chosen numbers. % \item Hints % \item Units handling in \env{numerical} questions % \end{itemize} % % \subsection{Compatibility} % This package has been originally written for and tested with the implementation of % \Moodle\ 2.9 run by Moodlerooms for St.~Norbert College in January 2016. % Since then, it has been successfully combined with \Moodle\ 3.5. % % The package option \optn{LMS} lets you specify the targeted \Moodle\ version % and helps ensuring compatibility. % % As the ultimate purpose of this package is the generation of \XML\ files, % future versions of \pkg{moodle} will attempt to maintain backwards % compatibility with earlier versions regarding the \XML\ output, apart from % bug fixes. % Backwards compatibility of the \PDF\ output is not yet guaranteed, however, % in case the author or users discover better ways for the \PDF\ to display % the underlying \XML\ data to be proofread. % % In other words, compiling your current \filenm{.tex} file with a future version % of \pkg{moodle} should produce the same \XML\ file it does now % (apart from bug fixes), % but it might produce a more informative, and hence different, % \PDF\ output. % % \subsection{Unrelated Tip: Quality of \Moodle\ \TeX\ Images} % This has nothing to do with \pkg{moodle}, but is a Frequently Asked Question % in is own right. % On some servers, at least, \Moodle's default ``\TeX\ Filter'' for % displaying mathematical notation is of abysmally poor quality, rending mathematics % as low-resolution \PNG's. One solution that has worked for me is to go % to ``Course Administration $\to$ Filters,'' turn ``\TeX\ Notation'' \emph{off}, % but turn ``MathJax'' \emph{on}. This forces \TeX\ code to be rendered by MathJax % instead of \Moodle, producing much higher-quality results. % % ^^A\clearpage % \changes{v0.5}{2016/01/05}{Initial version} % \changes{v0.6}{2019/02/18}{Bug-fixing release} % \changes{v0.7}{2020/07/09}{Feature extensions} % \changes{v0.8}{2021/01/04}{Bug fixes and feature extensions} % \changes{v0.9}{2021/02/07}{Bug fixes and feature extensions} % \changes{v1.0}{2023/01/28}{Bug fixes and feature extensions} % \begin{changelog}[title={Version History},sectioncmd=\section*,author={Matthieu Guerquin-Kern}] % ^^A \begin{version}[version=\fileversion,]^^Adate=] % ^^A \end{version} % \begin{version}[version=1.0,date=2023-01-28] % \added % ^^A \item A section describing the use of templates for generating large number % ^^A of quizzes has been added (courtesy of Colin Caprani). % \item For templating purposes, in \optn{draft} mode, general TeX code can % now be used in items and |tolerance| key of numerical questions % (courtesy of Colin Caprani). % \item Support for the \env{quote} and \env{quotation} environments in the HTML % conversion process (courtesy of Gerald Teschl). % \item Experimental package option \optn{pluginfile} mimics the way % \Moodle\ embeds pictures in the \XML. % \item Answer box for Essay questions with \optn{handout}. % \item Key-value package option \optn{LMS} to target a specific version % of \Moodle. % \item Support for more text mode diacritic and horizontal spacing % commands. % \item Macros \cmd{\moodleversion} and \cmd{\moodledate} are defined. % \item Experimental package option \optn{samepage} to avoid splitting % questions across multiple pages. % \item \optn{sanction} key to set default mark for incorrect answers. % \item Started the internationalization of the package based on % \pkg{translator} (optionally \pkg{translations}). English, % French, German, Italian, and Spanish % are fully supported (with help from J\"urgen Vollmer for German % and Romano Giannetti for Italian and Spanish). Contributions are welcome. % \item Warn user of the \pkg{babel} package set for Turkish % that using the shorthands will not play well with \pkg{moodle}. % \item Support for \cmd{\i} in conversion to \HTML. % \item \SVG\ option support for Windows (courtesy of Wolf M\"uller). % \changed % \item In Cloze \env{multi} subquestions, the default mode is % \optn{inline} when only one answer is to be selected and % \optn{vertical} when several answers can be selected. % \item Single straight quotes (apostrophe) in math mode are passed as-is % to the \XML\ (with help from Keno Wehr). % \item Empty groups |{}| in math-mode are passed as-is to the \XML\ % (with help from Keno Wehr). % \item Inside \env{cloze} subquestions, \optn{points} are forced to the % nearest positive integer. ^^AA warning is issued when the user setting % ^^Ais modified. % \item \XML\ stamp exposes compilation time. % \item Labels of proposed answers now following \Moodle's convention % (\emph{1., 2., \dots}) in the \PDF\ typesetting of \env{multi} questions. % \item Automatic sanction mechanism for incorrect choices in \env{multi} % questions with multiple answers allowed. Now applies also inside % \env{cloze} questions. % \item In \env{cloze} subquestions, non-integer fractions are rounded. % \item Rewording of some indications in the \PDF, related to internationalization. % \item The answers of \env{matching} questions are now converted to \HTML\ % (accents and \cmd{\htmlonly} in mind). % \removed % \item Support for non-\acro{ASCII} characters abandoned when compiling % with \prog{pdflatex}. % \fixed % \item In math-mode, \cmd{\underline} is no longer translated to \HTML. % \item Preexisting pictures no longer get deleted when including graphics % without specifying the extension (courtesy of Colin Caprani). % \item In answers of \env{matching} questions, some \TeX\ macros will not % break compilation. A problem with curly braces persists. % \item The cloze subquestions now inherit \optn{points} set at % the higher levels. % \item Option \optn{single=false} now works in Cloze \env{multi} questions. % \item Undesired trailing spaces are removed from offered answers in % \env{matching} question. % \item Compatibility with \pkg{siunitx} version 3. % \item Compatibility with \pkg{minted} starting from 2021/12/24 v2.6. % \item Different issues with graphics handling on Windows (\prog{magick}, % \prog{del}, \prog{move},\dots). % \item Symbols |<| and |>| are translated to \HTML\ equivalents, also in % text-mode. % \item Warning german-writing and (Xe$\mid$Lua)\TeX\ users about troubles % caused by text-mode umlauts. % \item In \env{cloze} subquestions items and outside math environments, % the equal symbol (|=|) no longer interferes with the Cloze syntax. % \item A pagebreak occuring inside cloze shortanswers would reset page numbers. % \item The redefinition of the \env{description} environment is limited to % the scope of the \env{quiz}. % \item PDF typesetting of matching answers (line breaks, repeated matches). % \item Symbols \cmd{\%} found inside math mode are escaped for \HTML. % \item The \optn{fraction} keys specified inside \env{cloze} questions are % forced to integer values as required by \Moodle's \XML\ format. % \item True/False no longer broken when \pkg{hyperref} is loaded. % \item Tolerances in \env{numerical} answers now correctly displayed in \PDF. % \item Warning for users running a too old version of \pkg{graphics}. % \item In the code included with \pkg{verbatim}, \pkg{fancyvrb}, or % \pkg{fvextra}, characters that matter for \HTML\ are escaped. % \end{version} % \begin{version}[version=0.9,date=2021-02-07] % \added % \item Support for \href{https://docs.moodle.org/en/All_or_nothing_multiple_choice_question_type} % {all-or-nothing multiple choice} questions. % \item Support for the ogonek diacritical mark via \cmd{\k}\marg{\dots}. % \item Warn user of the \pkg{babel} package set for a German-related language % that using the character |"| will not play well with \pkg{moodle}. % \item Support for \pkg{babel} commands related to German quotes. % \item Support for en-dash (--) outside of math mode. % \item Support for \cmd{\%} in conversion to \HTML. % \item Command |\htmlonly[]{}| to pass \HTML\ contents directly to the \XML\ file. % \changed % \item An error is issued when a graphics conversion step fails. % \item Irrelevant points are no longer written at the \env{cloze} question level in \PDF\ and \XML. % \item The total number of marks is shown in the \PDF\ at the end of each quiz. % \item The \optn{tags} key can now be used to specify a comma-separated list of tags. % \fixed % \item Answer text of \env{shortanswer} questions is converted to \HTML. % \item Paragraph breaks in \env{multi} and \env{essay} items no longer break compilation. % \item Question text in Essays was not shown in \PDF\ file. % \item Commands \cmd{\textsc}, \cmd{\underline}, \cmd{\url}, and \cmd{\href} yielded \HTML\ code with % inadequate double quotation marks. % \item Broken base64-encoding pipeline for images under Windows (thanks to Andreas Vohns). % \item Repeated single right quotation marks no longer merged in math mode % (thanks to Alberto Albano). % \end{version} % \begin{version}[version=0.8,date=2021-01-04] % \added % \item Support for inclusion of \GIF\ pictures. % \item Added package option \optn{svg} to avoid the rasterization of vector graphics. % \item New macro \cmd{\setsubcategory} to define subcategories, reflected in \PDF\ and \XML. % \item Package option \optn{handout} for sharing \PDF\ with students. % \item Extensions can be omitted when including pictures. % \item Description question type. % \item \LuaLaTeX\ is now supported (and recommended for \UTF-8 coded sources). % \item Examples of ways to reproduce the behavior of calculated questions. % \item Command to trigger the automatic recording of new commands. % \item Mechanism to match \optn{fraction} key to values accepted by \Moodle. % \item A \optn{fractiontol} key to control the tolerance in this mechanism. % \item Support for inverted punctuation marks |¿| and |¡|. % \item Support for \cmd{\_} and \cmd{\textbackslash}. % \item Support for the wildcard character as an answer in \env{numerical} questions. % \changed % \item Template of Essay questions is now shown in \PDF. % \item The macro \cmd{\setcategory} is reflected by a new section in \PDF. % \item In \env{matching} questions, warnings are raised if the number of items is insufficient. % \item Improved display of \env{matching} questions in \PDF. % \item The package \pkg{iftex} is now required. % \item An error is thrown when \optn{fraction} is set to an invalid value. % \item In \env{numerical} questions, the tolerance can be set in exponent form. % \item Nicer \PDF\ rendering of numbers in \env{numerical} questions if \pkg{siunitx} is loaded. % \item Included \PNG\ and \acro{JPEG} files are now directly converted to base64. % \fixed % \item TeX's inline math (\texttt{$...$}) can now contain escaped dollar signs (\cmd{\$}). % \item Closing braces escaped in \env{cloze} subquestions outside math environment. % \item The scope of the \optn{tolerance} key is now respected. % \end{version} % \begin{version}[version=0.7,date=2020-09-06] % \added % \item Support for inclusion of verbatim code. % \item Package option \optn{tikz}. % \item Support for \cmd{\"Y} and \cmd{\"y}. % \item New commands converted to \XML. % \item Adding a stamp comment in \XML, package option offered to disable % this behavior. % \item Support for the \cmd{\tikz} command. % \item A different directory can be specified for picture inclusion. % \item Warn user of the \pkg{babel} package set for French that autospacing % must be deactivated. % \item Square bracket math delimiters are recognized and converted properly. % \item Support of breve and caron diacritical marks. % \changed % \item In \env{multi} with multiple answers allowed, choosing all options no longer % results in a good grade. An automatic penalty mechanism is introduced. % Can be overridden by manually setting fractions. % \removed % \item Irrelevant \optn{penalty} tag in \env{cloze} subquestions. % \fixed % \item Non-integer fractions can now be specified in \env{cloze} subquestions. % \item Significantly squeeze \PNG\ images size by skipping ancillary data. % \item Enumerate or itemize environment can now be nested in question items. % \item Several pictures can be included in a question without being mixed % in the \XML\ file. % \item Management and rendering of fraction in questions. % \item Correctly handling a \LaTeX\ command starting the last item of a question. % \item Closing braces escaped in \env{cloze} subquestions. This allows \LaTeX\ % equations or images to be included. % \item Image inclusion with macOS. % \end{version} % \begin{version}[version=0.6b,date=2019-11-27] % \added % \item New package options to set section or subsection at the quiz level. % \item True/False question type is now supported. % \item \Moodle\ tags can now be specified for questions (and rendered in \PDF\ % as well). % \item In \env{cloze} questions, the multiresponse subquestion type is % now supported. % \removed % \item External dependency on \prog{OpenSSL}. % \item Irrelevant tags were written in \XML\ for \env{matching} questions. % \fixed % \item \TikZ\ externalization now works when using \XeLaTeX. % \item It is now possible to set points manually among several correct % answers in multichoice questions. % \item General feedback can now contain backslashes. % \item Several quizzes can now be defined in a single source file, each % specifying a category for \Moodle's question bank. % \item Correct encoding information is now written in \XML\ depending on % the \LaTeX\ compiler used. % \end{version} % \begin{version}[version=0.6a,date=2019-06-21] % \added % \item \XeLaTeX\ is now recommended when using \UTF-8 encoded sources (support % of accents). % \item Feedbacks are now displayed in the \PDF\ file produced. % \item The \prog{OptiPNG} utility is used to reduce the size % of images embedded in the \XML\ file. % \item Question options and settings are now displayed in the \PDF\ file % \item Supporting more \LaTeX\ macros for symbols and accents (mostly % diacritical marks and ligatures). % \item Introduce shuffle options in cloze-multi subquestions. % \item Package option \optn{final}. % \changed % \item In draft mode, \TikZ\ externalization is no longer triggered. % \fixed % \item In the different question types, the feedback fields are now converted % for \HTML\ allowing \LaTeX\ equations and images. % \item Documentation improvements (limitations and previously undocumented % features). % \end{version} % \shortversion{version=0.5,date=2016-01-05,simple,changes=Initial version,author={Anders O.F. Hendrickson}} % \end{changelog} % \addcontentsline{toc}{section}{Version History}% % \PrintIndex % \addcontentsline{toc}{section}{Index}% % \StopEventually{% %^^A \PrintChanges % } % % \section{Implementation} % \subsection{Packages, Options, and Utilities} % \begin{macrocode} \newif\ifmoodle@draftmode \newif\ifmoodle@handout \newif\ifmoodle@stampmode \newif\ifmoodle@tikz \newif\ifmoodle@tikzloaded \newif\ifmoodle@svg \newif\ifmoodle@section \newif\ifmoodle@subsection \newif\ifmoodle@numbered \newif\ifmoodle@international \newif\ifmoodle@feedbackLeft% contribution of Juergen Vollmer, 2021-03-05 \newif\ifmoodle@samepage% contribution of Romano Giannetti, 2021-03-07 \newif\ifmoodle@pluginfile% %% Moodle version \RequirePackage{xkeyval}%For key-handling \newcount\moodle@LMSmajor% major version number of the LMS targeted \newcount\moodle@LMSminor% minor version number of the LMS targeted %%DECLARATION OF OPTIONS \DeclareOptionX{draft}{\moodle@draftmodetrue}% \DeclareOptionX{handout}{\moodle@handouttrue}% \DeclareOptionX{final}{\moodle@draftmodefalse}% \DeclareOptionX{nostamp}{\moodle@stampmodefalse}% \DeclareOptionX{tikz}{\moodle@tikztrue}% \DeclareOptionX{svg}{\moodle@svgtrue}% \DeclareOptionX{section}{\moodle@sectiontrue\moodle@numberedtrue}% \DeclareOptionX{section*}{\moodle@sectiontrue\moodle@numberedfalse}% \DeclareOptionX{subsection}{\moodle@sectionfalse\moodle@numberedtrue}% \DeclareOptionX{subsection*}{\moodle@sectionfalse\moodle@numberedfalse}% \DeclareOptionX{feedbackleft}{\moodle@feedbackLefttrue}% contribution of Juergen Vollmer, 2021-03-05 \DeclareOptionX{feedbackright}{\moodle@feedbackLeftfalse}% default \DeclareOptionX{samepage}{\moodle@samepagetrue}% contribution of Romano Giannetti, 2021-03-07 \DeclareOptionX{LMS}[0.0]{% \filename@parse{#1}% \moodle@LMSmajor=\filename@base \moodle@LMSminor=\filename@ext }% \DeclareOptionX{pluginfile}{\moodle@pluginfiletrue}% \moodle@draftmodefalse \moodle@handoutfalse \moodle@stampmodetrue \moodle@tikzfalse \moodle@tikzloadedfalse \moodle@svgfalse \moodle@subsectiontrue \moodle@numberedfalse \moodle@feedbackLeftfalse% contribution of Juergen Vollmer, 2021-03-05 \moodle@samepagefalse% contribution of Romano Giannetti, 2021-03-07 \moodle@pluginfilefalse \ProcessOptionsX*% the star allows to inherit 'draft' and 'final' from the class \ifmoodle@samepage \def\moodle@begin@samepage{\minipage[t]{\linewidth}} \def\moodle@end@samepage{\endminipage\vskip 0pt plus 50pt\relax} \else % defining to relax is safer versus adding spurious spaces \def\moodle@begin@samepage{\relax} \def\moodle@end@samepage{\relax} \fi \RequirePackage{environ} %To be able to take environment body as a macro argument \RequirePackage{amssymb} %For \checkmark symbol %\RequirePackage{trimspaces} %To remove extra spaces from strings (loaded by environ) \@ifpackageloaded{iftex}{}{\RequirePackage{iftex}} % iftex already required by recent versions of ifplatform. Needed to know: % 1) whether we can convert output from PDF to \PNG\ (ifpdf), % 2) when output pdf is latin1-encoded (ifpdf) % 3) when output xml is utf8-encoded (if?tex) \@ifundefined{ifeTeX}{% version of 'iftex' prior to November 2019. \RequirePackage{etex}{} }{ \ifeTeX\else \RequirePackage{etex}{} % Recent (2015+) TeX engines should be e-TeX. %This is needed for expansion control, detokenization, etc. \fi } \RequirePackage{etoolbox}%List management \RequirePackage{xpatch} %To patch commands easily in \HTML\ mode \RequirePackage{array} %For formatting tables in the LaTeX mode of Clozes \RequirePackage{ifplatform} % To choose Ghostscript commands \@ifundefined{ifpdf}{\RequirePackage{ifpdf}}{}% old iftex would not define the conditional \RequirePackage{shellesc} %Luatex-compatible way of getting system access \RequirePackage{readprov} %To gather information on the package (version, date, ...) \RequirePackage{fancybox} %For fancy LaTeX tags \RequirePackage{getitems} %To gather the header and items \ifmoodle@handout \RequirePackage[seed=42]{randomlist} %To randomize answers in matching questions \fi \ifmoodle@svg \RequirePackage{graphicx} %To include graphics \fi \GetFileInfo{moodle.sty}% \edef\moodledate{\filedate}% \edef\moodleversion{\fileversion}% \let\xa=\expandafter \def\@star{*}% \def\@hundred{100}% \def\@fifty{50}% \def\@moodle@empty{}% \def\@relax{\relax}% \def\@moodle@par{\par}% % Taken from https://tex.stackexchange.com/questions/47576/combining-ifxetex-and-ifluatex-with-the-logical-or-operation \@ifundefined{ifTUTeX}{ \newif\ifTUTeX % a new conditional starts as false \ifnum 0\ifXeTeX 1\fi\ifLuaTeX 1\fi>0\relax \TUTeXtrue \fi }{}% \newif\ifpdfoutput % a new conditional starts as false \ifnum 0\ifTUTeX 1\fi\ifPDFTeX\ifpdf 1\fi\fi>0\relax \pdfoutputtrue \fi % \end{macrocode} % As the package involves a fair bit of file processing, % we automate the naming of auxiliary files. % \begin{macrocode} \def\jobnamewithsuffixtomacro#1#2{% \filenamewithsuffixtomacro{#1}{\jobname}{#2}% } \def\@jn@quote{"}% \def\filenamewithsuffixtomacro#1#2#3{% % #1 = macro to create % #2 = filename to add suffix to % #3 = suffix to add \edef\jn@suffix{#3}% \def\jn@macro{#1}% \xa\testforquote#2\@jn@rdelim } \def\testforquote#1#2\@jn@rdelim{% \def\jn@test@i{#1}% \ifx\jn@test@i\@jn@quote % Involves quotes \edef\jn@next{"\jn@stripquotes#1#2\jn@suffix"}% \else \edef\jn@next{#1#2\jn@suffix}% \fi \xa\xdef\jn@macro{\jn@next}% } \def\jn@stripquotes"#1"{#1}% \jobnamewithsuffixtomacro{\outputfilename}{-moodle.xml} % \end{macrocode} % Next, we create macros to open and close the Moodle \XML\ file % we will be writing. % \begin{macrocode} \newwrite\moodle@outfile \def\openmoodleout{% \immediate\openout\moodle@outfile=\outputfilename\relax \ifPDFTeX % latin1-based engines (pdflatex or latex) \writetomoodle{}% \else \ifTUTeX % UTF8-based engines (XeTeX or LuaTeX) \writetomoodle{}% \else % what shall we do? \writetomoodle{}% %\stop \fi \fi \ifmoodle@stampmode \def\moodle@stamp{This is a question bank made for Moodle } \ifnum\the\moodle@LMSmajor\the\moodle@LMSminor=\z@\else \g@addto@macro{\moodle@stamp}{\the\moodle@LMSmajor.\the\moodle@LMSminor.\space} \fi \writetomoodle{}% \newcount\hour\hour=\time \divide\hour by 60\relax \newcount\minute\minute=\hour \multiply\minute by -60\relax \advance\minute by \time\relax \def\moodle@stamp{It was generated on \the\year-\two@digits\month-\two@digits\day\space \the\hour:\the\minute} \ifPDFTeX % pdflatex or latex \ifpdf % pdflatex \g@addto@macro{\moodle@stamp}{ by pdfLaTeX }% \else % latex \g@addto@macro{\moodle@stamp}{ by LaTeX }% \fi \else \ifXeTeX % xetex \g@addto@macro{\moodle@stamp}{ by XeLaTeX }% \else \ifLuaTeX % luatex \g@addto@macro{\moodle@stamp}{ by LuaLaTeX }% \else \g@addto@macro{\moodle@stamp}{ a TeX engine }% \fi \fi \fi \writetomoodle{}% \def\moodle@stamp{on \platformname}% \g@addto@macro{\moodle@stamp}{ with the package moodle \moodleversion\space (\moodledate) }% \writetomoodle{}% \fi \immediate\write\moodle@outfile{}% \writetomoodle{}% }% \def\closemoodleout{% \writetomoodle{ }% \writetomoodle{}% \immediate\closeout\moodle@outfile }% % \end{macrocode} % % To both make this \filenm{.sty} file and the \XML\ output more readable, % we create a mechanism for writing to the output file with indents. % The macro |\calculateindent|\marg{$n$} globally defines % |\moodle@indent| to be a string of \meta{$n$} |\otherspace|'s. % \begin{macrocode} \newcount\moodle@indentnum \def\calculateindent#1{% \bgroup \moodle@indentnum=\number#1\relax \gdef\moodle@indent{}% \calculateindent@int \egroup }% \def\calculateindent@int{% \ifnum\moodle@indentnum>0\relax \g@addto@macro{\moodle@indent}{\otherspace}% \advance\moodle@indentnum by -1\relax \expandafter \calculateindent@int \fi }% % \end{macrocode} % Now the command |\writetomoodle|\oarg{n}\marg{stuff} adds the line % ``\meta{stuff}'' to the \XML\ file % preceded by an indent of \meta{n} spaces. % Note that this command |\edef|'s its second argument. % \begin{macrocode} \newcommand\writetomoodle[2][0]{% \edef\test@ii{#2}% \ifnum#1=0\relax \immediate\write\moodle@outfile{\test@ii}% \else \calculateindent{#1}% \immediate\write\moodle@outfile{\moodle@indent\trim@pre@space{\test@ii}}% \fi }% % \end{macrocode} % We now create the main |quiz| environment that will contain % the questions we write. It outputs to \XML\ as a || tag. % \begin{macrocode} {\catcode`\$=12\catcode`\ =12% in this context we cannot indent with spaces... \gdef\moodle@write@category@xml#1{% \@moodle@ifgeneratexml{% \writetomoodle{ }% \writetomoodle{}% \writetomoodle{ }% \writetomoodle{ $course$/top/#1}% \writetomoodle{ }% \writetomoodle{}% \writetomoodle{ }% }{}% }}% \newcommand*\@enumeratename{enumerate}% \newdimen\moodle@totalmarks \gdef\moodle@currentcategory{}% \newenvironment{quiz}[2][]{% \setkeys{moodle}{#1}% \gdef\setcategory##1{% % At first call (end of \begin{quiz}) enumerate is not started yet \ifx\@currenvir\@enumeratename % In case no question is defined between two calls of \setcategory \def\@noitemerr{}%\@latex@warning{Empty question list} \end{enumerate}% \fi \gdef\moodle@currentcategory{##1}% \moodle@write@category@xml{##1}% \ifmoodle@section \ifmoodle@numbered \section{##1}% \else \section*{##1}% \fi \else \ifmoodle@numbered \subsection{##1}% \else \subsection*{##1}% \fi \fi \begin{enumerate}\renewcommand\labelenumi{(\theenumi)}% }% \gdef\setsubcategory##1{% \def\@noitemerr{}%\@latex@warning{Empty question list} \end{enumerate}% \moodle@write@category@xml{\moodle@currentcategory/##1}% \ifmoodle@section \ifmoodle@numbered \subsection{##1}% \else \subsection*{##1}% \fi \else \ifmoodle@numbered \subsubsection{##1}% \else \subsubsection*{##1}% \fi \fi \begin{enumerate}\renewcommand\labelenumi{(\theenumi)}% }% \setcategory{#2}% \moodle@totalmarks=0pt% }{% \end{enumerate}% \emph{\GetTranslation{Total of marks}: \strip@pt\moodle@totalmarks}% \let\setcategory\relax \let\setsubcategory\relax }% % \end{macrocode} % The next utility takes a single macro control sequence |#1|, % and allows that macro's current value to persist % after the next |\egroup|, |}|, or |\endgroup|. % \begin{macrocode} \def\passvalueaftergroup#1{% \xa\xa\xa\gdef\xa\xa\csname moodle@remember@\string#1\endcsname\xa{\xa\def\xa#1\xa{#1}}% \xa\aftergroup\csname moodle@remember@\string#1\endcsname } % \end{macrocode} % % \subsubsection{Main Switch: to create \XML\ or not} % % \begin{macrocode} \long\def\@moodle@ifgeneratexml#1#2{% % If we are generating \XML, do #1; otherwise do #2. \tikzifexternalizing{% % This run of LaTeX is currently ONLY generating a TikZ image % to be saved in an external file. We do NOT want to waste time % generating \XML, and moreover trying to do so would cause errors % because of file dependencies. #2% }{% \ifmoodle@draftmode #2% \else #1% \fi }% } % \end{macrocode} % Now the macros |openmoodleout| and |closemoodleout| are triggered at Begin and End Document, respectively % \begin{macrocode} \AfterEndPreamble{ \@moodle@ifgeneratexml{% \openmoodleout% }{}% } \AtEndDocument{ \@moodle@ifgeneratexml{% \closemoodleout% }{}% } % \end{macrocode} % % \subsection{Key-Value Pairs for Quiz Questions} % % The various options are set using key-value syntax of |xkeyval|. % \begin{macrocode} \def\moodleset#1{\setkeys{moodle}{#1}}% % \end{macrocode} % We first define some macros that will help us write other macros. % Calling |\generate@moodle@write@code|\marg{name}|<|\meta{HTML tag}|>|\marg{text to write} % creates a macro |\moodle@write|\meta{name}, taking no parameters, % which writes the code |<|\meta{HTML tag}|>...| % to the output \XML\ file. % % The ordinary version |\generate@moodle@write@code| passes its output text |#3| % through the HTMLizer, producing \HTML\ code, while the starred variant % |\generate@moodle@write@code*| passes |#3| verbatim as text. % % For example, % |\generate@moodle@write@code{excuse}{\theexcuse}| % would expand to % \begin{Verbatim}[gobble=4,frame=single] % \gdef\moodle@writeexcuse{% % \xa\def\xa\test@iii\xa{\theexcuse}% % \ifx\test@iii\@moodle@empty % \writetomoodle[2]{ }% % \else % \xa\converttohtmlmacro\xa\moodle@htmltowrite\xa{\theexcuse}% % \writetomoodle[2]{ }% % \writetomoodle[4]{ \moodle@htmltowrite

]]>
}% % \writetomoodle[2]{
}% % \fi % }% % \end{Verbatim} % but % |\generate@moodle@write@code*{excuse}{\theexcuse}| % would expand only to % \begin{Verbatim}[gobble=4,frame=single] % \gdef\moodle@writeexcuse{% % \writetomoodle[2]{ \theexcuse}% % } % \end{Verbatim} % \begin{macrocode} \def\generate@moodle@write@code{% \@ifnextchar*\generate@moodle@write@data\generate@moodle@write@html }% \def\generate@moodle@write@html#1<#2>#3{% % #1 = NAME for \moodle@writeNAME % #2 = \HTML\ tag % #3 = what, exactly, to write \xa\gdef\csname moodle@write#1\endcsname{% \xa\def\xa\test@iii\xa{#3}% \ifx\test@iii\@moodle@empty \writetomoodle[2]{ <#2 format="html">}% \else \xa\converttohtmlmacro\xa\moodle@htmltowrite\xa{#3}% \writetomoodle[2]{ <#2 format="html">}% \writetomoodle[4]{ \moodle@htmltowrite

]]>
}% \ifmoodle@pluginfile \writetomoodle[0]{\htmlize@embeddedfiletags}% \fi \writetomoodle[2]{ }% \fi }% }% \def\generate@moodle@write@html@noptag#1<#2>#3{% % No

..

introduced % #1 = NAME for \moodle@writeNAME % #2 = \HTML\ tag % #3 = what, exactly, to write \xa\gdef\csname moodle@write#1\endcsname{% \xa\def\xa\test@iii\xa{#3}% \ifx\test@iii\@moodle@empty \writetomoodle[2]{ <#2 format="html">}% \else \xa\converttohtmlmacro\xa\moodle@htmltowrite\xa{#3}% \writetomoodle[2]{ <#2 format="html">}% \writetomoodle[4]{ }% \ifmoodle@pluginfile \writetomoodle[0]{\htmlize@embeddedfiletags}% \fi \writetomoodle[2]{ }% \fi }% }% \def\generate@moodle@write@data*#1<#2>#3{% % #1 = NAME for \moodle@writeNAME % #2 = \HTML\ tag % #3 = what, exactly, to write \xa\gdef\csname moodle@write#1\endcsname{% \writetomoodle[2]{ <#2>#3}% }% }% \def\moodle@writetags{% \xa\xdef\xa\test@iii\xa{\moodle@tags}% \ifx\test@iii\@moodle@empty\relax\else \writetomoodle[2]{ }% \renewcommand*{\do}[1]{% \def\moodle@tagtext{##1}% \xa\converttohtmlmacro\xa\moodle@htmltowrite\xa{\moodle@tagtext}% \writetomoodle[4]{ }% } \xa\docsvlist\xa{\moodle@tags}% \writetomoodle[2]{ }% \fi }% \newif\ifmoodle@firsttag \moodle@firsttagtrue \def\moodle@latex@writetags{% \xa\xdef\xa\test@iii\xa{\moodle@tags}% \ifx\test@iii\@moodle@empty\relax\else \hfill \GetTranslation{tags}: % \renewcommand*{\do}[1]{\ifmoodle@firsttag\moodle@firsttagfalse\else, \fi\texttt{##1}}% \xa\docsvlist\xa{\test@iii}% \fi }% % \end{macrocode} % \subsubsection{Keys for all question types} % \begin{macrocode} %% QUESTIONNAME \define@cmdkey{moodle}[moodle@]{questionname}{}% % \gdef\moodle@writequestionname{% % \writetomoodle[2]{}% % \writetomoodle[4]{ \moodle@questionname}% % \writetomoodle[2]{}% % }% %\generate@moodle@write@code{questionname}{\moodle@questionname}% \generate@moodle@write@html@noptag{questionname}{\moodle@questionname}% %% QUESTIONTEXT %I tried to use questiontext as a key, but it doesn't seem to work. %The trouble is that xkeyval has trouble parsing a key with a \par token followed by a comma within brackets, %like \setkeys{moodle}{questiontext={ABC\par [D,E]}} %It's not worth trying to fix. \long\def\questiontext#1{% %\converttohtmlmacro\myoutput{#1}% %\let\moodle@questiontext=\myoutput% \def\moodle@questiontext{#1}% }% \generate@moodle@write@code{questiontext}{\moodle@questiontext}%{% %% PENALTY FOR WRONG ATTEMPT \define@cmdkey{moodle}[moodle@]{penalty}[0.10]{}% \generate@moodle@write@code*{penalty}{\moodle@penalty}% \moodleset{penalty=0.10}% %% FEEDBACK % Moodle allows for feedback tailored to each question, % and feedback tailored to each right or wrong answer. % We shall use the key 'feedback' to record both kinds of feedback, % relying on TeX's grouping mechanism to keep them apart. % When it comes time to write them to \XML, % \moodle@writegeneralfeedback uses the \HTML\ tag % whereas \moodle@writefeedback uses the tag . % Note that the general feedback is NOT inherited by each answer! \define@cmdkey{moodle}[moodle@]{feedback}[]{}% \generate@moodle@write@code{generalfeedback}{\moodle@feedback}% \generate@moodle@write@code{feedback}{\moodle@feedback}% \moodleset{feedback={}}% %% DEFAULT GRADE %The next line creates \moodle@defaultgrade, %which is how many points the quiz question is worth. %Key calls like [default grade=7] set \moodle@defaultgrade. \define@cmdkey{moodle}[moodle@]{default grade}[1.0]{}% %Next, makes 'points' a synonym for 'default grade' \define@key{moodle}{points}[1.0]{\xa\def\csname moodle@default grade\endcsname{#1}}% \generate@moodle@write@code*{defaultgrade}{\csname moodle@default grade\endcsname}% \moodleset{default grade=1.0} %This sets the default. %% HIDDEN \define@boolkey{moodle}[moodle@]{hidden}[true]{}% \generate@moodle@write@code*{hidden}{\ifmoodle@hidden 1\else 0\fi}% \moodleset{hidden=false}% \def\moodle@writecommondata{% \moodle@writequestionname% \moodle@writequestiontext% \moodle@writedefaultgrade% \moodle@writegeneralfeedback% \moodle@writepenalty% \moodle@writehidden% }% %% TAGS %The next line creates \moodle@tags, %which defines a "tag" (i.e., keyword) for the question. %Key calls like [tags={random}] set \moodle@tags. \define@cmdkey{moodle}[moodle@]{tags}[]{}% \moodleset{tags={}}% % \end{macrocode} % \subsubsection{Keys for all answers} % \begin{macrocode} %% FRACTION -- how much this answer is worth out of 100 percent \define@cmdkey{moodle}[moodle@]{fraction}[100]{}% %We do not create \moodle@writefraction, because the fraction occurs in %the \XML\ within the answer tag, like . \moodleset{fraction=100} %This sets the default. % \end{macrocode} % \begin{macrocode} %% FRACTIONTOL -- the tolerance for fractions with respect to valid values \define@cmdkey{moodle}[moodle@]{fractiontol}[0.1]{}% \moodleset{fractiontol=0.1} %This sets the default. % \end{macrocode} % \subsubsection{Keys for multiple choice questions} % \begin{macrocode} %% SINGLE and MULTIPLE -- for multichoice, is there 1 right answer or more than 1? \define@boolkey{moodle}[moodle@]{single}[true]{}% \generate@moodle@write@code*{single}{\ifmoodle@single true\else false\fi}% \moodleset{single=true}% %The key 'multiple' is an antonym to 'single'. \define@boolkey{moodle}[moodle@]{multiple}[true]{\ifmoodle@multiple\moodle@singlefalse\else\moodle@singletrue\fi}% %% SHUFFLE ANSWERS \define@boolkey{moodle}[moodle@]{shuffle}[true]{}% \generate@moodle@write@code*{shuffle}{\ifmoodle@shuffle 1\else 0\fi}% \moodleset{shuffle=true}% %% ALLORNOTHING -- for multichoice with multiple answers where all the points are given % if and only if all the correct answers are selected. \define@boolkey{moodle}[moodle@]{allornothing}[true]{}% \moodleset{allornothing=false}% %% SANCTION -- how much shall incorrect choices by sanctioned in multichoice questions (single) \define@cmdkey{moodle}[moodle@]{sanction}[]{}% \moodleset{sanction=0} %This sets the default. %% TODO: CORRECTFEEDBACK %% TODO: PARTIALLYCORRECTFEEDBACK %% TODO: INCORRECTFEEDBACK %% TODO: NUMCORRECT key %% NUMBERING -- for numbering of multichoice questions \define@choicekey{moodle}{numbering}% {alpha,alph,Alpha,Alph,arabic,roman,Roman,% abc,ABCD,123,iii,IIII,none}[abc]{% \def\moodle@numbering{#1}% \def\test@@i{#1}% \ifx\test@@i\@moodle@alpha \def\moodle@numbering{abc}\fi \ifx\test@@i\@moodle@alph \def\moodle@numbering{abc}\fi \ifx\test@@i\@moodle@Alpha \def\moodle@numbering{ABCD}\fi \ifx\test@@i\@moodle@Alph \def\moodle@numbering{ABCD}\fi \ifx\test@@i\@moodle@arabic \def\moodle@numbering{123}\fi \ifx\test@@i\@moodle@roman \def\moodle@numbering{iii}\fi \ifx\test@@i\@moodle@Roman \def\moodle@numbering{IIII}\fi }% %'answer numbering' will be a synonym to 'numbering' \define@key{moodle}{answer numbering}[abc]{\setkeys{moodle}{numbering={#1}}}% \generate@moodle@write@code*{answernumbering}{\moodle@numbering}% %N.B. if we did not set the default here, then \moodle@numbering would be undefined, causing problems. \moodleset{answer numbering=abc}% \def\@moodle@alpha{alpha}% \def\@moodle@Alpha{Alpha}% \def\@moodle@alph{alph}% \def\@moodle@Alph{Alph}% \def\@moodle@arabic{arabic}% \def\@moodle@roman{roman}% \def\@moodle@Roman{Roman}% \def\@moodle@abc{abc}% \def\@moodle@ABCD{ABCD}% \def\@moodle@arabicnumbers{123}% \def\@moodle@iii{iii}% \def\@moodle@IIII{IIII}% \def\@moodle@none{none}% \def\moodle@obeynumberingstyle{% \renewcommand\labelenumii{\theenumii.}% follow Moodle's labeling convention \ifx\moodle@numbering\@moodle@abc \renewcommand\theenumii{\alph{enumii}}% \fi \ifx\moodle@numbering\@moodle@ABCD \renewcommand\theenumii{\Alph{enumii}}% \fi \ifx\moodle@numbering\@moodle@arabicnumbers \renewcommand\theenumii{\arabic{enumii}}% \fi \ifx\moodle@numbering\@moodle@iii \renewcommand\theenumii{\roman{enumii}}% \fi \ifx\moodle@numbering\@moodle@IIII \renewcommand\theenumii{\Roman{enumii}}% \fi \ifx\moodle@numbering\@moodle@none \renewcommand\labelenumii{$\bullet$~}% \fi } %TODO: * In the PDF, how should 'none' in a multi look different from % short answer or numerical options? % * Instead of \theenumi and \labelenumi, % use \@enumdepth to automatically set the correct depth. %% DISPLAY MODE -- affects Cloze multiple choice questions only. % 0 = inline, 1 = vertical, 2 = horizontal \def\moodle@multi@mode{\ifmoodle@single 0\else 1\fi}% \define@key{moodle}{inline}[]{\def\moodle@multi@mode{0}}% \define@key{moodle}{vertical}[]{\def\moodle@multi@mode{1}}% \define@key{moodle}{horizontal}[]{\def\moodle@multi@mode{2}}% % \end{macrocode} % \subsubsection{Keys for numerical questions} % \begin{macrocode} %% TOLERANCE \define@cmdkey{moodle}[moodle@]{tolerance}[0]{}% \moodleset{tolerance=0}% %There is no \moodle@writetolerance, because in the \XML\ the %tolerance is given within the answer tag, %like . % TODO: implement unit-handling for numerical questions! % \end{macrocode} % \subsubsection{Keys for short answer questions} % \begin{macrocode} %% CASE SENSITIVE \define@boolkey{moodle}[moodle@]{usecase}[true]{}% \generate@moodle@write@code*{usecase}{\ifmoodle@usecase 1\else 0\fi}% % We make 'case sensitive' a synonym for 'usecase'. \define@boolkey{moodle}[moodle@]{case sensitive}[true]{\ifcsname moodle@case sensitive\endcsname \moodle@usecasetrue\else\moodle@usecasefalse\fi}% \moodleset{usecase=false}% % \end{macrocode} % \subsubsection{Keys for matching questions} % \begin{macrocode} %% DRAG-AND-DROP FORMAT \define@boolkey{moodle}[moodle@]{draganddrop}[true]{}% % We make 'dd' and 'draganddrop' and 'drag and drop' synonyms for 'draganddrop'. \define@boolkey{moodle}[moodle@]{dd}[true]{\ifmoodle@dd\moodle@draganddroptrue\else\moodle@draganddropfalse\fi}% \define@boolkey{moodle}[moodle@]{drag and drop}[true]{\moodle@ddsynonym}% \def\moodle@ddsynonym{% \csname ifmoodle@drag and drop\endcsname \moodle@draganddroptrue \else \moodle@draganddropfalse \fi } \moodleset{draganddrop=false}% % \end{macrocode} % \subsubsection{Keys for essay questions} % \begin{macrocode} %% EDITOR \def\@moodle@html{html}% \def\@moodle@htmlfile{html+file}% \def\@moodle@text{text}% \def\@moodle@plain{plain}% \def\@moodle@monospaced{monospaced}% \def\@moodle@file{file}% \def\@moodle@noinline{noinline}% \define@choicekey{moodle}{response format}% {html,html+file,text,monospaced,file}[html]% {\def\test@i{#1}% \ifx\test@i\@moodle@html % \HTML\ Editor \def\moodle@responseformat{editor}% \fi \ifx\test@i\@moodle@htmlfile % \HTML\ Editor with File Picker \def\moodle@responseformat{editorfilepicker}% \fi \ifx\test@i\@moodle@text % Plain text \def\moodle@responseformat{plain}% \fi \ifx\test@i\@moodle@plain % Plain text \def\moodle@responseformat{plain}% \fi \ifx\test@i\@moodle@monospaced % Plain text, monospaced font \def\moodle@responseformat{monospaced}% \fi \ifx\test@i\@moodle@file % No inline text (i.e., attachments only) \def\moodle@responseformat{noinline}% \fi \ifx\test@i\@moodle@noinline % No inline text (i.e., attachments only) \def\moodle@responseformat{noinline}% \fi }% \generate@moodle@write@code*{responseformat}{\moodle@responseformat}% \moodleset{response format=html}% %N.B. if we did not set a default, then \moodle@responseformat would be undefined, causing problems. %% RESPONSE REQUIRED \define@boolkey{moodle}[moodle@]{response required}[true]{}% % TODO: Make synonym 'required' \generate@moodle@write@code*{responserequired}{\csname ifmoodle@response required\endcsname 1\else 0\fi}% \moodleset{response required=false}% %% RESPONSEFIELDLINES \define@cmdkey{moodle}[moodle@]{response field lines}[15]{}% \generate@moodle@write@code*{responsefieldlines}{\csname moodle@response field lines\endcsname}% %Make synonyms 'input box size' or 'height' or 'lines'? \moodleset{response field lines=15}% N.B. if we do not set a default, then \moodle@responseformat will be undefined, causing problems. %% ATTACHMENTS ALLOWED \def\@moodle@unlimited{unlimited}% \define@choicekey{moodle}{attachments allowed}{0,1,2,3,unlimited}[1]{% \def\test@i{#1}% \ifx\test@i\@moodle@unlimited \def\moodle@attachmentsallowed{-1}% \else \def\moodle@attachmentsallowed{#1}% \fi } \generate@moodle@write@code*{attachmentsallowed}{\moodle@attachmentsallowed} \moodleset{attachments allowed=0}% %% ATTACHMENTS REQUIRED \define@choicekey{moodle}{attachments required}{0,1,2,3}[1]{\def\moodle@attachmentsrequired{#1}}% \generate@moodle@write@code*{attachmentsrequired}{\moodle@attachmentsrequired} \moodleset{attachments required=0}% %% RESPONSE TEMPLATE \define@key{moodle}{template}{\long\def\moodle@responsetemplate{#1}}% \generate@moodle@write@html@noptag{responsetemplate}{\moodle@responsetemplate} \moodleset{template={}}% % \end{macrocode} % \subsubsection{Hint tags} % The following are not yet fully implemented. % \begin{macrocode} %% SHOWNUMCORRECT \define@boolkey{moodle}[moodle@]{shownumcorrect}[true]{}% \gdef\moodle@writeshownumcorrect{% \if\moodle@shownumcorrect \writetomoodle[4]{ }% \fi }% \moodleset{shownumcorrect=false}% %% CLEARWRONG \define@boolkey{moodle}[moodle@]{clearwrong}[true]{}% \gdef\moodle@writeclearwrong{% \if\moodle@clearwrong \writetomoodle[4]{ }% \fi }% \moodleset{clearwrong=false}% % TODO: Implement hints % \end{macrocode} % % \subsection{Answer handling} % % \begin{macrocode} %The Answers \XML\ depends heavily on the question type. %Each type of question defines how it obtains answers from the LaTeX input, %how it typesets those in a \PDF\ or \DVI, and how it writes them as \XML\ code. %It will write that \XML\ to the macro \moodle@answers@xml, %which them gets written to the file when \moodle@writeanswers %is invoked. \def\moodle@answers@xml{}% \gdef\moodle@writeanswers{% \writetomoodle{\moodle@answers@xml}% }% \newcommand\addto@xml[3][0]{% % #1 = spaces to indent (default=0) % #2 = macro containing \XML\ code (possibly empty) % #3 = \XML\ text to be appended to that macro (will be \edef'd) \calculateindent{#1}% \edef\xml@to@add{\moodle@indent\trim@pre@space{#3}}% \ifx#2\@moodle@empty \edef\newxml{\noexpand#2\xml@to@add}% \else \edef\newxml{\noexpand#2^^J\xml@to@add}% \fi \xa\xa\xa\def\xa\xa\xa#2\xa\xa\xa{\newxml}% }% % \end{macrocode} % % \subsubsection{Not yet implemented} % % \begin{macrocode} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% CALCULATED %%%%%%%%%%%%%%%%%%%%%%%%%% % TODO: I don't think I really want to handle this. Not now. % \end{macrocode} % % \subsection{Typesetting options} % This section provides the tools to allow on to control how the quiz gets typeset % in the resulting PDF file. % \begin{macrocode} \ifmoodle@feedbackLeft% contribution of Juergen Vollmer, 2021-03-05 \newcommand{\moodle@preFeedback}{\\}% \else% \newcommand{\moodle@preFeedback}{\hfill}% \fi % \end{macrocode} % % \subsection{Front Ends} % This section creates the user interface for the various question types. % First, we define a generic command to create % a front-end environment for a Moodle question type. % In order to function, the following macros must be hard-coded: % \begin{itemize} % \item |\moodle@|\meta{type}|@latexprocessing|: % Loops through the saved |\item|'s to typeset them in LaTeX, % usually inside an itemize or enumerate environment. % \item |\save|\meta{type}|answer#1|: % Processes the text of a single |\item| to save the information to memory, % usually inside |\moodle@answers@xml|. % \item |\write|\meta{type}|question|: % Writes the information, hitherto saved only in macros, % into the \XML\ file. % \end{itemize} % For example, to create the `shortanswer' question type, % we shall call % \begin{Verbatim}[gobble=5,frame=single] % \moodle@makefrontend{shortanswer} % \def\moodle@shortanswer@latexprocessing{...} % \def\saveshortansweranswer#1{...} % \def\writeshortanswerquestion{...} % \end{Verbatim} % % \begin{macrocode} \def\moodle@makelatextagbox#1{% % \ifmoodle@tikzloaded % \tikzset{external/export next=false} % \tikz[baseline]{\node[draw,minimum height=1.2em,rounded corners,fill=black!20] {\tiny #1};} % % Fancy but interferes with the tikzexternalize counter % \else \Ovalbox{\tiny #1} %\ovalbox{\tiny #1} %\shadowbox{\tiny #1} % \fi }% \def\moodle@makelatextag@qtype#1{% \doublebox{\tiny \textsc{\GetTranslation{#1}}} }% \def\moodle@makelatextag@value#1#2{% \moodle@makelatextagbox{\GetTranslation{#2}~\csname moodle@#1\endcsname}% }% \def\moodle@makelatextag@key#1{% \moodle@makelatextagbox{\GetTranslation{#1}} }% \def\moodle@makelatextag@other#1{% \moodle@makelatextagbox{\GetTranslation{#1}} }% \def\moodle@makefrontend#1#2{% \NewEnviron{#1}[2][]{% \bgroup \setkeys{moodle}{##1,questionname={##2}}% \global\advance\moodle@totalmarks by \csname moodle@default grade\endcsname pt \expandafter\gatheritems\xa{\BODY}% \let\moodle@questionheader=\gatheredheader %First, the LaTeX processing \item \moodle@begin@samepage \textbf{\moodle@questionname} \ifmoodle@handout \moodle@makelatextag@qtype{#1} \else \moodle@latex@writetags \par \noindent \moodle@makelatextag@qtype{#1}% \moodle@makelatextag@value{default grade}{marked out of} \moodle@makelatextag@value{penalty}{penalty}% \fi #2\par \noindent \moodle@questionheader \edef\moodle@generalfeedback{\expandonce\moodle@feedback} \csname moodle@#1@latexprocessing\endcsname \moodle@end@samepage %Now, writing information to XML \@moodle@ifgeneratexml{% \xa\questiontext\xa{\moodle@questionheader}% Save the question text. \csname write#1question\endcsname \bgroup \gdef\moodle@answers@xml{}% \setkeys{moodle}{feedback={}}% \xa\loopthroughitemswithcommand\xa{\csname save#1answer\endcsname}% \passvalueaftergroup{\moodle@answers@xml}% \egroup \moodle@writeanswers% \moodle@writetags% \writetomoodle{
}% }{}% \egroup }% } % \end{macrocode} % % \subsubsection{Description Question Front-End} % Description and essay questions are the only question types whose front end % is not yet created by |\moodle@makefrontend|. % This is because of what need to be done with their contents. % % Description blocks can be empty. In this case, nothing is done. % % \begin{macrocode} \AtBeginEnvironment{quiz}{% protect existing description outside of quiz \let\description\relax% remove the meaning of existing \description and \enddescription \let\enddescription\relax \NewEnviron{description}[2][]{% \bgroup \setkeys{moodle}{#1,questionname={#2}}% \let\moodle@questiontext=\BODY \trim@spaces@in\moodle@questiontext \ifx\moodle@questiontext\@empty\relax\else% %First, the LaTeX processing. \item \moodle@begin@samepage\textbf{\moodle@questionname} \ifmoodle@handout\else \moodle@latex@writetags \par \noindent \fi \moodle@makelatextag@qtype{description}\par \noindent \moodle@questiontext\par \ifmoodle@handout\else \ifx\moodle@feedback\@empty\relax\else \fbox{\parbox{.96\linewidth}{\emph{\moodle@feedback}}}% \fi \fi \moodle@end@samepage %Now, writing information to memory. \@moodle@ifgeneratexml{% \writetomoodle{}% \moodle@writecommondata \moodle@writetags% \writetomoodle{}% }{}% \fi \egroup }% }% % \end{macrocode} % % \subsubsection{Essay Question Front-End} % The front end is not yet created by |\moodle@makefrontend| because of % what must must be done with the |\item|'s. % % \begin{macrocode} \def\moodle@essay@latexprocessing{% % Moodle cannot automatically grade an essay, % but if the user puts \item's in, we can list them in an itemize as notes. \par\noindent \emph{\GetTranslation{Information for graders}:} \ifnum\c@numgathereditems>0\relax \begin{itemize} \setlength\itemsep{0pt}\setlength\parskip{0pt}% \loopthroughitemswithcommand{\moodle@print@essay@answer}% \end{itemize}% \fi \ifx\moodle@generalfeedback\@empty\relax\else% \fbox{\parbox{.96\linewidth}{\emph{\moodle@generalfeedback}}}% \fi } \NewEnviron{essay}[2][]{% \bgroup \setkeys{moodle}{#1,questionname={#2}}% \global\advance\moodle@totalmarks by \csname moodle@default grade\endcsname pt% \moodle@checkresponsefieldlines \expandafter\gatheritems\expandafter{\BODY}% \let\moodle@questionheader=\gatheredheader %First, the LaTeX processing. \item \moodle@begin@samepage\textbf{\moodle@questionname} \ifmoodle@handout \moodle@makelatextag@qtype{essay} \else \moodle@latex@writetags \par \noindent \moodle@makelatextag@qtype{essay} \moodle@makelatextag@value{default grade}{marked out of} \moodle@makelatextag@value{penalty}{penalty} \xa\moodle@makelatextag@key\xa{\moodle@responseformat} \fi \par \noindent \moodle@questionheader \long\def\@lempty{}% \ifx\moodle@responsetemplate\@lempty\else \par\noindent\emph{\GetTranslation{Response template}:} \par\noindent\fbox{\parbox{.96\linewidth}{\moodle@responsetemplate}}\par \fi \edef\moodle@generalfeedback{\expandonce\moodle@feedback} \ifmoodle@handout \par\noindent \fbox{\parbox[t][\csname moodle@response field lines\endcsname\baselineskip]{.96\linewidth}{\phantom{Moodle}}}% \else \csname moodle@essay@latexprocessing\endcsname \fi \moodle@end@samepage %Now, writing information to memory. \@moodle@ifgeneratexml{% \xa\questiontext\xa{\moodle@questionheader}% Save the question text. \writeessayquestion \bgroup \gdef\moodle@answers@xml{}% % \ifnum\c@numgathereditems=0\relax \addto@xml[2]\moodle@answers@xml{}% \else \addto@xml[2]\moodle@answers@xml{1\relax \addto@xml[4]\moodle@answers@xml{
    }% \fi \loopthroughitemswithcommand{\moodle@savegraderinfo}% \ifnum\c@numgathereditems>1\relax \addto@xml[4]\moodle@answers@xml{
}% \fi \addto@xml[2]\moodle@answers@xml{]]>
}% \fi % \passvalueaftergroup{\moodle@answers@xml}% \egroup \moodle@writeanswers% The 'answers' \XML\ really contains the grader info. \moodle@writeresponsetemplate% \moodle@writetags% \writetomoodle{}% }{}% \egroup }% \def\moodle@checkresponsefieldlines{% \newcount\a\a=\number\csname moodle@response field lines\endcsname \newcount\b\b=5% \ifnum\the\a>40\relax% if the value was more than 40 \a=40% \fi \ifnum\the\a<5\relax% if the value was less than 5 \a=5% \fi \divide\a by\b% integer division by 5 \multiply\a by\b% multiply by 5 \ifnum\a=\csname moodle@response field lines\endcsname\relax% equality holds if we had 5, 10, 15, 20, 25, 30, or 40 \else \ifnum\csname moodle@response field lines\endcsname>5\relax% \ifnum\csname moodle@response field lines\endcsname<40\relax% \advance\a by\b% approximate with the next multiple of 5 \fi \fi \PackageWarning{moodle}{"response field lines" admits only multiples of 5 between 5 and 40 (You tried to set \csname moodle@response field lines\endcsname). The value \the\a\space will be used.}% \setkeys{moodle}{response field lines=\the\a}% \fi }% %%%% TODO %%%% To make essay work will be tough. %%%% Every line from \ifnum\c@numgathereditems=0\relax through its \else and \fi, %%%% with the exception of %%%% \xa\loopthroughitemswithcommand\xa{\csname save#1answer\endcsname}% %%%% , does not exist in our current \moodle@makefrontend code. %%%% How can we cope? %%%% %%%% Idea: change \moodle@makefrontend so that %%%% 1. if \c@numgathereditems=0, we don't do anything. %%%% 2. it calls a preamble and postamble around the \loopthroughitemswithcommand. %%%% Like this: %%%% %%%% \@moodle@ifgeneratexml{% %%%% \xa\questiontext\xa{\moodle@questionheader}% Save the question text. %%%% \bgroup %%%% \gdef\moodle@answers@xml{}% %%%% \setkeys{moodle}{feedback={}}% %%%% \@ifundefined{moodle@#1@answers@preamble}{}{}% %%%% \csname moodle@#1@answers@preamble\endcsname %%%% \ifnum\c@numgathereditems=0\relax %%%% \relax %%%% \else %%%% \xa\loopthroughitemswithcommand\xa{\csname save#1answer\endcsname}% %%%% \fi %%%% \@ifundefined{moodle@#1@answers@postamble}{}{}% %%%% \csname moodle@#1@answers@postamble\endcsname %%%% \passvalueaftergroup{\moodle@answers@xml}% %%%% \egroup %%%% \csname write#1question\endcsname %%%% }{}% %%%% The \@ifundefined lines should automatically define the %%%% \...@preamble \...@postamble macros to be \relax if they don't exist already. \gdef\writeessayquestion{% \writetomoodle{}% \moodle@writecommondata% \moodle@writeresponserequired% \moodle@writeresponseformat% \moodle@writeresponsefieldlines% \moodle@writeattachmentsallowed% \moodle@writeattachmentsrequired% }% \long\def\moodle@print@essay@answer#1{% \item #1% }% \long\def\moodle@savegraderinfo#1{% \def\moodle@answertext{#1} \xa\converttohtmlmacro\xa\moodle@answertext@html\xa{\moodle@answertext}% %\trim@spaces@in\moodle@answertext \ifnum\c@numgathereditems>1\relax \addto@xml[6]{\moodle@answers@xml}{
  • \moodle@answertext@html
  • }% \else \addto@xml[4]{\moodle@answers@xml}{\moodle@answertext@html}% \fi }% % \end{macrocode} % % \subsubsection{Short Answer Question Front-End} % % \begin{macrocode} %\NewEnviron{shortanswer}[2][]{% % \bgroup % \setkeys{moodle}{#1,questionname={#2}}% % \expandafter\gatheritems\xa{\BODY}% % \let\moodle@questionheader=\gatheredheader % %First, the LaTeX processing. % \item \textbf{\moodle@questionname} % \csname ifmoodle@case sensitive\endcsname % \framebox{\tiny Case-Sensitive}\relax % \fi % \framebox{\tiny\csname moodle@default grade\endcsname~points} % \framebox{\tiny\csname moodle@penalty\endcsname~penalty}\par % \noindent % \moodle@questionheader % \csname moodle@shortanswer@latexprocessing\endcsname % %Now, writing information to memory. % \@moodle@ifgeneratexml{% % \xa\questiontext\xa{\moodle@questionheader}% Save the question text. % \bgroup % \gdef\moodle@answers@xml{}% % \setkeys{moodle}{feedback={}}% % \xa\loopthroughitemswithcommand\xa{\csname % saveshortansweranswer\endcsname}% % \passvalueaftergroup{\moodle@answers@xml}% % \egroup % \csname writeshortanswerquestion\endcsname % }{}% % \egroup % }% \moodle@makefrontend{shortanswer}{\moodle@makelatextag@shortanswer}% % LATEX PROCESSING \def\moodle@makelatextag@shortanswer{% \ifmoodle@usecase \moodle@makelatextag@other{Case-Sensitive}\relax \else \moodle@makelatextag@other{Case-Insensitive}\relax \fi } \ifmoodle@handout \let\moodle@shortanswer@latexprocessing\relax \else \def\moodle@shortanswer@latexprocessing{% \begin{itemize} \setlength\itemsep{0pt}\setlength\parskip{0pt}% \loopthroughitemswithcommand{\moodle@print@shortanswer@answer}% \end{itemize}% \ifx\moodle@generalfeedback\@empty\relax\else% \fbox{\parbox{.96\linewidth}{\emph{\moodle@generalfeedback}}}% \fi } \fi \def\moodle@print@shortanswer@answer#1{% \let\moodle@feedback=\@empty \moodle@print@shortanswer@answer@int#1\@rdelim }% \newcommand\moodle@print@shortanswer@answer@int[1][]{% \setkeys{moodle}{#1}% \moodle@print@shortanswer@answer@int@int% }% \def\moodle@print@shortanswer@answer@int@int#1\@rdelim{% \ifx\moodle@fraction\@hundred \item #1$~\checkmark$% \else \moodle@checkfraction \item #1$~(\moodle@fraction\%)$% \fi \ifx\moodle@feedback\@empty\relax\else \moodle@preFeedback \emph{$\rightarrow$ \moodle@feedback} \fi }% % SAVING ANSWERS TO MEMORY \def\saveshortansweranswer#1{% \bgroup \saveshortansweranswer@int#1\moodle@answer@rdelim \passvalueaftergroup{\moodle@answers@xml}% \egroup }% \newcommand\saveshortansweranswer@int[1][]{% \setkeys{moodle}{fraction=100,#1}% %%%%%% DEFAULT VALUE IS 100% \saveshortansweranswer@int@int% }% \def\saveshortansweranswer@int@int#1\moodle@answer@rdelim{% \def\moodle@answertext{#1}% \trim@spaces@in\moodle@answertext \moodle@checkfraction \addto@xml[2]{\moodle@answers@xml}{}% \xa\converttohtmlmacro\xa\moodle@answertext@html\xa{\moodle@answertext}% \addto@xml[4]{\moodle@answers@xml}{ \moodle@answertext@html}% \ifmoodle@pluginfile \writetomoodle[0]{\htmlize@embeddedfiletags}% \fi \ifx\moodle@feedback\@empty\relax\else \trim@spaces@in\moodle@feedback \xa\converttohtmlmacro\xa\moodle@feedback@html\xa{\moodle@feedback}% \addto@xml[4]{\moodle@answers@xml}{ \moodle@feedback@html

    ]]>
    \ifmoodle@pluginfile\htmlize@embeddedfiletags\fi
    }% \fi \addto@xml[2]{\moodle@answers@xml}{
    }% }% % WRITING QUESTION TO \XML\ FILE \gdef\writeshortanswerquestion{% \writetomoodle{}% \moodle@writecommondata% \moodle@writeusecase% }% % \end{macrocode} % % \subsubsection{Numerical Question Front-End} % % \begin{macrocode} \moodle@makefrontend{numerical}{\moodle@makelatextag@numerical}% % LATEX PROCESSING \def\moodle@makelatextag@numerical{} \AtEndPreamble{ \@ifpackageloaded{siunitx}{\def\moodle@printnum{\num[omit-uncertainty]}}%,copy-decimal-marker {\let\moodle@printnum\trim@spaces}% } \ifmoodle@handout \let\moodle@numerical@latexprocessing\relax \else \def\moodle@numerical@latexprocessing{% \begin{itemize} \setlength\itemsep{0pt}\setlength\parskip{0pt}% \loopthroughitemswithcommand{\moodle@print@numerical@answer}% \end{itemize}% \ifx\moodle@generalfeedback\@empty\relax\else% \fbox{\parbox{.96\linewidth}{\emph{\moodle@generalfeedback}}}% \fi } \fi \def\moodle@print@numerical@answer#1{% \let\moodle@feedback=\@empty \bgroup \moodle@print@numerical@answer@int#1\@rdelim \egroup }% \newcommand\moodle@print@numerical@answer@int[1][]{% \setkeys{moodle}{#1}% \moodle@print@numerical@answer@int@int% }% \def\moodle@print@numerical@answer@int@int#1\@rdelim{% \gdef\test@i{#1}% \trim@spaces@in\test@i \ifx\test@i\@star \item \test@i \else \item \moodle@printnum{#1}% \ifx\moodle@tolerance\moodle@zero\else $\,\pm\,$\moodle@printnum{\expandonce\moodle@tolerance}% \fi \fi \ifx\moodle@fraction\@hundred $~\checkmark$% \else \moodle@checkfraction $~(\moodle@fraction\%)$% \fi \ifx\moodle@feedback\@empty\relax\else \moodle@preFeedback \emph{$\rightarrow$ \moodle@feedback}% \fi }% % SAVING ANSWERS TO MEMORY \def\savenumericalanswer#1{% \bgroup \savenumericalanswer@int#1\moodle@answer@rdelim \passvalueaftergroup{\moodle@answers@xml}% \egroup }% \newcommand\savenumericalanswer@int[1][]{% \setkeys{moodle}{fraction=100,#1}% %%%%%% DEFAULT VALUE IS 100% \savenumericalanswer@int@int% }% \def\savenumericalanswer@int@int#1\moodle@answer@rdelim{% \def\moodle@answertext{#1}% \trim@spaces@in\moodle@answertext \moodle@checkfraction \addto@xml[2]{\moodle@answers@xml}{}% \addto@xml[4]{\moodle@answers@xml}{ \moodle@answertext}% \ifx\moodle@answertext\@star\else \addto@xml[4]{\moodle@answers@xml}{ \moodle@tolerance}% \fi \ifmoodle@pluginfile \writetomoodle[0]{\htmlize@embeddedfiletags}% \fi \ifx\moodle@feedback\@empty\relax\else \trim@spaces@in\moodle@feedback \xa\converttohtmlmacro\xa\moodle@feedback@html\xa{\moodle@feedback}% \addto@xml[4]{\moodle@answers@xml}{ \moodle@feedback@html

    ]]>
    \ifmoodle@pluginfile\htmlize@embeddedfiletags\fi
    }% \fi \addto@xml[2]{\moodle@answers@xml}{
    }% }% % WRITING QUESTION TO \XML\ FILE \gdef\writenumericalquestion{% \writetomoodle{}% \moodle@writecommondata% }% % \end{macrocode} % % \subsubsection{Multiple Choice Question Front-End} % % \begin{macrocode} %Multiple choice has the structure % \begin{multi}[options]{name}% % What is 5+7? % \item 13 % \item* 12 % \item 11 % \end{multi}% \moodle@makefrontend{multi}{\moodle@makelatextag@multi}% % LATEX PROCESSING \def\moodle@makelatextag@multi{% \ifmoodle@allornothing \ifx\endmulti\endclozemulti \PackageError{moodle}{Unsupported option "allornothing" for a multichoice subquestion} {Please set "allornothing=false"}% \else \moodle@makelatextag@other{All-or-nothing}% \fi \else \ifmoodle@single \moodle@makelatextag@other{Single}% \else \moodle@makelatextag@other{Multiple}% \fi \fi \ifmoodle@handout\else \ifmoodle@shuffle \moodle@makelatextag@other{Shuffle}\relax% \fi \fi } \def\moodle@multi@latexprocessing{% \ifmoodle@allornothing\moodle@singletrue\fi \ifmoodle@single\relax\else\moodle@InspectMultipleAnswers\fi \ifmoodle@handout\NewList{answerlist}\fi \begin{enumerate}\moodle@obeynumberingstyle% %\renewcommand{\theenumi}{\alph{enumi}}% \setlength\itemsep{0pt}\setlength\parskip{0pt}% \loopthroughitemswithcommand{\moodle@print@multichoice@answer}% \ifmoodle@handout \ifmoodle@shuffle \let\moodle@multi@loop=\ForEachRandomItem \else \let\moodle@multi@loop=\ForEachFirstItem \fi \moodle@multi@loop{answerlist}{Answer}{\Answer}% \fi \end{enumerate}% \ifmoodle@handout\else \ifx\moodle@generalfeedback\@empty\relax\else% \fbox{\parbox{.96\linewidth}{\emph{\moodle@generalfeedback}}}% \fi \fi } \long\def\moodle@print@multichoice@answer#1{% \let\moodle@feedback=\@empty% \moodle@print@multichoice@answer@int#1 \@rdelim% }% \newcommand\moodle@print@multichoice@answer@int[1][]{% \let\moodle@fraction\@empty% \setkeys{moodle}{#1}% \moodle@print@multichoice@answer@int@int% }% \long\def\moodle@print@multichoice@answer@int@int#1#2\@rdelim{% \def\test@i{#1}% \def\test@ii{#2}% \def\moodle@answertext{\item }% \ifx\test@i\@star% \g@addto@macro\moodle@answertext{#2}% \ifmoodle@single% \setkeys{moodle}{fraction=100}% \else \setkeys{moodle}{fraction=\moodle@AutoScore}% \fi \else \g@addto@macro\moodle@answertext{#1#2}% \fi \trim@spaces@in\moodle@answertext% \trim@spaces@in\moodle@answertext% \ifmoodle@handout\else \ifmoodle@single% \ifx\moodle@fraction\@empty\relax% \ifdim0pt<\moodle@sanction pt\relax \setkeys{moodle}{fraction=-\moodle@sanction}% \else \setkeys{moodle}{fraction=0}% \fi \fi \moodle@checkfraction \ifx\moodle@fraction\@hundred% \trim@spaces@in\moodle@answertext% \g@addto@macro\moodle@answertext{$~\checkmark$}% \else \ifdim0pt=\moodle@fraction pt\relax\else% \g@addto@macro\moodle@answertext{$~(\moodle@fraction\%)$}% \fi \fi \else% multiple \ifx\moodle@fraction\@empty\relax% \ifmoodle@AdvancedScoreMode \setkeys{moodle}{fraction=0}% \else \setkeys{moodle}{fraction=-\moodle@AutoScore}% \fi \fi \moodle@checkfraction \g@addto@macro\moodle@answertext{$~(\moodle@fraction\%)$}% \fi \fi \ifmoodle@handout \def\temp{\InsertLastItem{answerlist}}% \xa\temp\xa{\moodle@answertext}% \else \ifx\moodle@feedback\@empty\relax\else% \g@addto@macro\moodle@answertext{\moodle@preFeedback \emph{$\rightarrow$ \moodle@feedback}}% \fi \moodle@answertext \fi }% % COMMON UTILITY: Inspecting answers of multiple choice questions (for option 'multiple') \newcounter{moodle@NumStarredAnswers}% count the stars \newdimen\moodle@autoscore@tmp% \newdimen\moodle@TotalPositiveFractions% Total of user-set positive fractions \newdimen\moodle@PositiveScoreFactor% scaling factor to impose the fractions of %correct answers to add up to 100% \newif\ifmoodle@AdvancedScoreMode% \def\moodle@InspectMultipleAnswers{% \setcounter{moodle@NumStarredAnswers}{0}% \moodle@autoscore@tmp=100pt\relax% temporary variable \moodle@TotalPositiveFractions=0pt\relax% \moodle@PositiveScoreFactor=1pt\relax \moodle@AdvancedScoreModefalse \loopthroughitemswithcommand{\moodle@InspectMultipleAnswers@a}% \ifmoodle@AdvancedScoreMode% advanced mode \ifx\endmulti\endclozemulti% inside cloze \divide\moodle@TotalPositiveFractions by 100\relax \advance\moodle@TotalPositiveFractions by \c@moodle@NumStarredAnswers pt\relax \moodle@PositiveScoreFactor=1 pt\relax \moodle@PositiveScoreFactor=\dimexpr 1 pt * \moodle@PositiveScoreFactor / \moodle@TotalPositiveFractions\relax% \global\def\moodle@OtherScore{% for multianswer questions in cloze, with advanced mode \ifdim0pt<\moodle@fraction pt\relax \moodle@fraction \else \moodle@autoscore@tmp=\moodle@PositiveScoreFactor\relax% \multiply\moodle@autoscore@tmp by \moodle@fraction\relax% \strip@pt\moodle@autoscore@tmp \fi }% \else% outside cloze \advance\moodle@autoscore@tmp by-\moodle@TotalPositiveFractions\relax% \def\ds{\strip@pt\moodle@TotalPositiveFractions}% \ifnum0=\c@moodle@NumStarredAnswers\relax% % autopoints will never be used but we check if the sum of positive fractions is 100% \ifdim\moodle@autoscore@tmp<-\moodle@fractiontol pt\relax% \PackageWarning{moodle}{Positive fractions add up to more than 100 (here: \ds)}% % Here we issue only a warning because Moodle accepts the \XML\ without error. \else \ifdim\moodle@autoscore@tmp>\moodle@fractiontol pt\relax% \PackageError{moodle}{Positive fractions add up to less than 100 (here: \ds)}% \fi \fi \else% there are starred items \ifdim0pt<\moodle@autoscore@tmp\relax\else% % we have starred items so the sum of user-set positive fractions must be less than 100% % otherwise, starred items would lead to penalties \PackageError{moodle}{Positive fractions add up to 100 or more (here: \ds): there is no positive points left to be given to starred items.}% \fi \divide\moodle@autoscore@tmp by \c@moodle@NumStarredAnswers\relax% \fi \fi \else% automatic score (not in advanced score mode) \global\divide\moodle@autoscore@tmp by \c@moodle@NumStarredAnswers\relax% \fi \xdef\moodle@AutoScore{\strip@pt\moodle@autoscore@tmp}% } \long\def\moodle@InspectMultipleAnswers@a#1{% %The grouping is to keep key answer-specific key changes local. \bgroup \moodle@InspectMultipleAnswers@b#1\moodle@answer@rdelim \egroup }% \newcommand\moodle@InspectMultipleAnswers@b[1][]{% %\ifx&% \let\moodle@fraction\@empty% \setkeys{moodle}{#1}% \moodle@InspectMultipleAnswers@c% %\fi }% \long\def\moodle@InspectMultipleAnswers@c#1#2\moodle@answer@rdelim{% \def\test@i{#1}% \ifx\test@i\@star \stepcounter{moodle@NumStarredAnswers}% \else \ifx\moodle@fraction\@empty\else \global\moodle@AdvancedScoreModetrue \ifdim0pt<\moodle@fraction pt\relax% \global\advance\moodle@TotalPositiveFractions by \moodle@fraction pt\relax% \fi \fi \fi }% \newdimen\test@fraction% \newdimen\test@lower% \newdimen\test@upper% \def\moodle@fractionerror{% \def\ds{\moodle@fraction}% \PackageError{moodle}{the current fraction is not an admissible value (here: \ds)}% } {\catcode`|=3\relax \gdef\moodle@validfractionlist{0|5|10|11.11111|12.5|14.28571|16.66667|20|25|30|33.33333|40|50|60|66.66667|70|75|80|83.33333|90|100}}% \def\moodle@isfractionnear#1{% \test@lower=\dimexpr #1 pt - \moodle@fractiontol pt\relax% \test@upper=\dimexpr #1 pt + \moodle@fractiontol pt\relax% \ifdim\test@upper>\test@fraction\relax \ifdim\test@lower<\test@fraction\relax \gdef\test@fractionmatched{#1}% \fi \fi } \def\moodle@checkfraction{% \ifmoodle@allornothing \ifnum\moodle@fraction>0\relax \setkeys{moodle}{fraction=100}% \fi \ifnum\moodle@fraction<0\relax \setkeys{moodle}{fraction=0}% \fi \else %\def\test@i{#1}% \test@fraction=\moodle@fraction pt\relax% % take the absolute value \ifdim0pt>\test@fraction\relax% \test@fraction=-\moodle@fraction pt\relax% \fi % test if the fraction is an admissible value \let\test@fractionmatched\@empty \forlistloop{\moodle@isfractionnear}{\moodle@validfractionlist}% \ifx\test@fractionmatched\@empty\relax \moodle@fractionerror% \fi \ifdim\moodle@fraction pt<-\moodle@fractiontol pt\relax% \xdef\moodle@fraction{-\test@fractionmatched}% \else \xdef\moodle@fraction{\test@fractionmatched}% \fi \fi } % TODO: Put these macros in same order as other sections'. % SAVING ANSWERS TO MEMORY \long\def\savemultianswer#1{% \bgroup \savemultianswer@int#1 \moodle@answer@rdelim \passvalueaftergroup{\moodle@answers@xml}% \egroup }% \newcommand\savemultianswer@int[1][]{% \let\moodle@fraction\@empty% \setkeys{moodle}{#1}% \ifmoodle@allornothing \moodle@singletrue \fi \savemultianswer@int@int% }% \long\def\savemultianswer@int@int#1#2\moodle@answer@rdelim{% \def\test@i{#1}% \ifx\test@i\@star \ifmoodle@single \setkeys{moodle}{fraction=100}% \else \setkeys{moodle}{fraction=\moodle@AutoScore}% \fi \def\moodle@answertext{#2}% \else \def\moodle@answertext{#1#2}% \fi \ifx\moodle@fraction\@empty\relax% \ifmoodle@single\relax \ifdim0pt<\moodle@sanction pt\relax \setkeys{moodle}{fraction=-\moodle@sanction}% \else \setkeys{moodle}{fraction=0}% \fi \else% multiple \ifmoodle@AdvancedScoreMode \setkeys{moodle}{fraction=0}% \else \setkeys{moodle}{fraction=-\moodle@AutoScore}% \fi \fi \fi \trim@spaces@in\moodle@answertext \trim@spaces@in\moodle@answertext \moodle@checkfraction \addto@xml[2]{\moodle@answers@xml}{}% \xa\converttohtmlmacro\xa\moodle@answertext@html\xa{\moodle@answertext}% \addto@xml[4]{\moodle@answers@xml}{ \moodle@answertext@html

    ]]>
    }% \ifmoodle@pluginfile \addto@xml[4]{\moodle@answers@xml}{\htmlize@embeddedfiletags}% \fi \ifx\moodle@feedback\@empty\relax\else \trim@spaces@in\moodle@feedback \xa\converttohtmlmacro\xa\moodle@feedback@html\xa{\moodle@feedback}% \addto@xml[4]{\moodle@answers@xml}{ \moodle@feedback@html

    ]]>
    \ifmoodle@pluginfile\htmlize@embeddedfiletags\fi
    }% \fi \addto@xml[2]{\moodle@answers@xml}{
    }% }% % WRITING QUESTION TO \XML\ FILE \gdef\writemultiquestion{% \writetomoodle{}% \moodle@writecommondata% \ifmoodle@allornothing\else \moodle@writesingle% \fi \moodle@writeshuffle% \moodle@writeanswernumbering% }% % \end{macrocode} % % \subsubsection{True/False Question Front-End} % % \begin{macrocode} % True/False has structure % \begin{truefalse}[options]{name}% % This is a matching question. % \item[feedback={feedback for student answering incorrectly "true"}] % first item is for true % \item* this is an other way of specifying answer-specific feedback % \end{truefalse}% %\moodle@makefrontend{truefalse}{}% We dont use the generic frontend because truefalse has no tunable penalty \NewEnviron{truefalse}[2][]{% \bgroup \setkeys{moodle}{#1,questionname={#2}}% \global\advance\moodle@totalmarks by \csname moodle@default grade\endcsname pt \expandafter\gatheritems\xa{\BODY}% \let\moodle@questionheader=\gatheredheader %First, the LaTeX processing \item \moodle@begin@samepage\textbf{\moodle@questionname} \ifmoodle@handout \moodle@makelatextag@qtype{truefalse} \else \moodle@latex@writetags \par \noindent \moodle@makelatextag@qtype{truefalse} \moodle@makelatextag@value{default grade}{marked out of} \fi \par \noindent \moodle@questionheader \edef\moodle@generalfeedback{\expandonce\moodle@feedback} \moodle@truefalse@latexprocessing \moodle@end@samepage %Now, writing information to XML \@moodle@ifgeneratexml{% \setkeys{moodle}{penalty=1}% \xa\questiontext\xa{\moodle@questionheader}% Save the question text. \csname writetruefalsequestion\endcsname \bgroup \gdef\moodle@answers@xml{}% \setkeys{moodle}{feedback={}}% \xa\loopthroughitemswithcommand\xa{\xa\savetruefalseanswer}% \ifnum\c@numgathereditems=1\relax \setcounter{currentitemnumber}{2}% \savetruefalseanswer{} \fi \passvalueaftergroup{\moodle@answers@xml}% \egroup \moodle@writeanswers% \moodle@writetags% \writetomoodle{}% }{}% \egroup }% % LATEX PROCESSING \def\moodle@truefalse@latexprocessing{% % \ifnum\c@numgathereditems>2\relax% % \PackageError{moodle}{Expecting at max two answers with truefalse type} % \fi \setcounter{moodle@NumStarredAnswers}{0}% \begin{itemize} \setlength\itemsep{0pt}\setlength\parskip{0pt}% \loopthroughitemswithcommand{\moodle@print@truefalse@answer}% \ifnum\c@currentitemnumber=2\relax \item \textbf{\GetTranslation{False}}% \fi \end{itemize} \ifmoodle@handout\else \ifx\moodle@generalfeedback\@empty\relax\else% \fbox{\parbox{.96\linewidth}{\emph{\moodle@generalfeedback}}}% \fi \fi \ifnum\c@moodle@NumStarredAnswers=0\relax \PackageError{moodle}{No answer is explicitly marked as correct (*). Be sure one answer leads to points.}% \fi \ifnum\c@moodle@NumStarredAnswers>1\relax \PackageError{moodle}{Two answers are explicitly marked as correct (*). Be sure only one answer leads to points.}% \fi } \def\moodle@print@truefalse@answer#1{% here # is all what comes after "\item", that is "[options]* text" \let\moodle@feedback=\@empty \moodle@print@truefalse@answer@int#1\@rdelim % add an end delimiter: }% \newcommand\moodle@print@truefalse@answer@int[1][]{% with the optional argument, catch options and set them as keys \setkeys{moodle}{#1}% \moodle@print@truefalse@answer@int@int% applies to the rest: "* text\@rdelim" }% \def\moodle@print@truefalse@answer@int@int#1\@rdelim{% this is just to treat appart the case where nothing follows \def\test@i{#1} \trim@spaces@in\test@i \ifx\test@i\@empty\relax \moodle@print@truefalse@answer@int@int@empty \else \moodle@print@truefalse@answer@int@int@int#1\@rdelim \fi }% \def\moodle@print@truefalse@answer@int@int@empty{% \ifnum\c@currentitemnumber=1\relax \def\moodle@answertext{\GetTranslation{True}}% \fi \ifnum\c@currentitemnumber=2\relax \def\moodle@answertext{\GetTranslation{False}}% \fi \item \textbf{\moodle@answertext}% \ifmoodle@handout\else \ifx\moodle@feedback\@empty\relax\else ~\moodle@preFeedback \emph{$\rightarrow$ \moodle@feedback}% \fi \fi }% \def\moodle@print@truefalse@answer@int@int@int#1#2\@rdelim{% \ifnum\c@currentitemnumber=1\relax \def\moodle@answertext{\GetTranslation{True}}% \fi \ifnum\c@currentitemnumber=2\relax \def\moodle@answertext{\GetTranslation{False}}% \fi \item \textbf{\moodle@answertext}% \ifnum\c@currentitemnumber<3\relax \def\test@i{#1}% %\trim@spaces@in\test@i \ifx\test@i\@star \ifmoodle@handout\else ~$\checkmark$% \fi \stepcounter{moodle@NumStarredAnswers}% \else ~% \fi \ifmoodle@handout\else \ifx\moodle@feedback\@empty\relax \def\test@ii{#2}% \trim@spaces@in\test@ii \ifx\test@ii\@empty\relax\else \ifx\test@i\@star% \moodle@preFeedback \emph{$\rightarrow$ #2}% \else% \moodle@preFeedback \emph{$\rightarrow$ #1#2}% \fi \fi \else \moodle@preFeedback \emph{$\rightarrow$ \moodle@feedback}% \fi \fi \fi }% % SAVING ANSWERS TO MEMORY \def\savetruefalseanswer#1{% \bgroup \savetruefalseanswer@int#1\moodle@answer@rdelim \passvalueaftergroup{\moodle@answers@xml}% \egroup }% \newcommand\savetruefalseanswer@int[1][]{% \setkeys{moodle}{#1}% \savetruefalseanswer@int@int% }% \def\savetruefalseanswer@int@int#1\moodle@answer@rdelim{% \def\test@i{#1} \trim@spaces@in\test@i \ifx\test@i\@empty\relax \savetruefalseanswer@int@int@empty \else \savetruefalseanswer@int@int@int#1\moodle@answer@rdelim \fi }% \def\savetruefalseanswer@int@int@empty{% \setkeys{moodle}{fraction=0}% \ifnum\c@currentitemnumber=1\relax \def\moodle@answertext{true}% \fi \ifnum\c@currentitemnumber=2\relax \def\moodle@answertext{false}% \fi \ifnum\c@currentitemnumber<3\relax \addto@xml[2]{\moodle@answers@xml}{}% \addto@xml[4]{\moodle@answers@xml}{ \moodle@answertext}% \ifmoodle@pluginfile \addto@xml[4]{\moodle@answers@xml}{\htmlize@embeddedfiletags}% \fi \ifx\moodle@feedback\@empty\relax\else \trim@spaces@in\moodle@feedback \xa\converttohtmlmacro\xa\moodle@feedback@html\xa{\moodle@feedback}% \addto@xml[4]{\moodle@answers@xml}{ \moodle@feedback@html

    ]]>
    \ifmoodle@pluginfile\htmlize@embeddedfiletags\fi
    }% \fi \addto@xml[2]{\moodle@answers@xml}{
    }% \fi }% \def\savetruefalseanswer@int@int@int#1#2\moodle@answer@rdelim{% \def\test@i{#1}% \ifx\test@i\@star \setkeys{moodle}{fraction=100}% \else \setkeys{moodle}{fraction=0}% \fi \ifnum\c@currentitemnumber=1\relax \def\moodle@answertext{true}% \fi \ifnum\c@currentitemnumber=2\relax \def\moodle@answertext{false}% \fi \ifnum\c@currentitemnumber<3\relax \addto@xml[2]{\moodle@answers@xml}{}% \addto@xml[4]{\moodle@answers@xml}{ \moodle@answertext}% \ifmoodle@pluginfile \addto@xml[4]{\moodle@answers@xml}{\htmlize@embeddedfiletags}% \fi \ifx\moodle@feedback\@empty\relax \def\test@ii{#2} \ifx\test@ii\@empty\relax\else \ifx\test@i\@star \xa\converttohtmlmacro\xa\moodle@feedback@html\xa{#2}% \else% \xa\converttohtmlmacro\xa\moodle@feedback@html\xa{#1#2}% \fi% \addto@xml[4]{\moodle@answers@xml}{ \moodle@feedback@html

    ]]>
    \ifmoodle@pluginfile\htmlize@embeddedfiletags\fi
    }% \fi \else \trim@spaces@in\moodle@feedback \xa\converttohtmlmacro\xa\moodle@feedback@html\xa{\moodle@feedback}% \addto@xml[4]{\moodle@answers@xml}{ \moodle@feedback@html

    ]]>
    \ifmoodle@pluginfile\htmlize@embeddedfiletags\fi
    }% \fi \addto@xml[2]{\moodle@answers@xml}{
    }% \fi }% % WRITING QUESTION TO \XML\ FILE \gdef\writetruefalsequestion{% \writetomoodle{}% \moodle@writecommondata% }% % \end{macrocode} % % \subsubsection{Matching Question Front-End} % % \begin{macrocode} %\let\answer=\hfill \moodle@makefrontend{matching}{\moodle@makelatextag@matching}% % LATEX PROCESSING \def\moodle@makelatextag@matching{% \ifmoodle@handout\else \ifmoodle@draganddrop \moodle@makelatextag@other{Drag and drop}\relax% \fi \ifmoodle@shuffle \moodle@makelatextag@other{Shuffle}\relax% \fi \fi } \long\def\moodle@matching@left#1{% \parbox[c]{.9\linewidth}{\raggedleft #1}\hfil\vrule width .5pt$\bullet$% }% \long\def\moodle@matching@right#1{% $\bullet$\vrule width .5pt\hfil\parbox[c]{.9\linewidth}{#1}% }% \def\moodle@matching@latexprocessing{% \bgroup %\let\answer=\hfill \par\noindent \ifmoodle@handout \NewList{questionlist}% \gdef\matcheslist{}% \NewList{answerlist}% \else \long\def\matching@table@text{}% \fi \setcounter{moodle@NumStarredAnswers}{0}% Here this counter is for "questions" (items on the left column) \loopthroughitemswithcommand{\moodle@print@matching@answer}% \ifnum\c@numgathereditems<3\relax \PackageWarning{moodle}{Moodle expects at least three proposed matches in matching questions}% \fi \ifnum\c@moodle@NumStarredAnswers<2\relax \PackageWarning{moodle}{Moodle expects at least two items in matching questions}% \fi \ifmoodle@handout \ifmoodle@shuffle \let\moodle@matching@loop=\ForEachRandomItem \else \let\moodle@matching@loop=\ForEachFirstItem \fi \begin{minipage}{.43\linewidth}% \moodle@matching@loop{questionlist}{Question}{% \moodle@matching@left{\Question}% \vskip 4pt\relax }% \end{minipage}% \hfill \begin{minipage}{.43\linewidth}% \ForEachFirstItem{answerlist}{Answer}{% \moodle@matching@right{\Answer}% \vskip 4pt\relax }% \end{minipage}% \else \begin{tabular}{@{}p{.43\linewidth}@{}p{.1\linewidth}@{}p{.43\linewidth}@{}}% \matching@table@text \end{tabular}% \ifx\moodle@generalfeedback\@empty\relax\else% \fbox{\parbox{.96\linewidth}{\emph{\moodle@generalfeedback}}}% \fi \fi \egroup } \long\def\moodle@print@matching@answer#1{% \moodle@print@matching@answer@int#1 \@rdelim }% \newcommand\moodle@print@matching@answer@int[1][]{% \moodle@print@matching@answer@int@int }% \long\def\moodle@print@matching@answer@int@int#1\answer#2\@rdelim{% %\typeout{\string#1 \answer \string#2}% \def\test@i{#1}% \trim@spaces@in\test@i \ifmoodle@handout \ifx\test@i\@empty\else \stepcounter{moodle@NumStarredAnswers}% \InsertLastItem{questionlist}{#1}% \fi \edef\test@ii{\detokenize{#2}}% \trim@spaces@in\test@ii \trim@spaces@in\test@ii% don't know why the 2nd call is required % add proposed match only if not already in the list \xifinlist{\expandonce\test@ii}{\matcheslist}{}{% \listeadd\matcheslist{\expandonce\test@ii}% % matches are always proposed shuffled \InsertRandomItem{answerlist}{#2}% }% \else \ifx\test@i\@empty \xa\g@addto@macro\xa\matching@table@text\xa{% &&\moodle@matching@right{#2}\\\\\relax% }% \else \stepcounter{moodle@NumStarredAnswers}% \xa\g@addto@macro\xa\matching@table@text\xa{% \moodle@matching@left{#1}&\leavevmode\leaders\hb@xt@.44em{\hss$\cdot$\hss}\hfill\kern\z@% &\moodle@matching@right{#2}\\\\\relax }% \fi \fi }% % SAVING ANSWERS TO MEMORY \long\def\savematchinganswer#1{% \bgroup \savematchinganswer@int#1 \moodle@answer@rdelim% \passvalueaftergroup{\moodle@answers@xml}% \egroup }% \newcommand\savematchinganswer@int[1][]{% \setkeys{moodle}{#1}% \savematchinganswer@int@int%\space }% \long\def\savematchinganswer@int@int#1\answer#2\moodle@answer@rdelim{% %\typeout{\string#1 \answer \string#2}% % Note that #1 may simply be \relax. \def\moodle@subquestiontext{#1}% \def\moodle@subanswertext{#2}% \trim@spaces@in\moodle@subquestiontext \xa\converttohtmlmacro\xa\moodle@subquestiontext@htmlized\xa{\moodle@subquestiontext}% \addto@xml[2]{\moodle@answers@xml}{}% \ifx\moodle@subquestiontext\@empty \addto@xml[4]{\moodle@answers@xml}{ }% \else \addto@xml[4]{\moodle@answers@xml}{ \moodle@subquestiontext@htmlized

    ]]>
    \ifmoodle@pluginfile\htmlize@embeddedfiletags\fi}% \fi \trim@spaces@in\moodle@subanswertext \trim@spaces@in\moodle@subanswertext% don't know why but a second call seems required... %\ifmoodle@draganddrop \xa\converttohtmlmacro\xa\moodle@subanswertext@htmlized\xa{\moodle@subanswertext}% %\fi \ifmoodle@draganddrop % \show\moodle@subanswertext@htmlized \addto@xml[4]{\moodle@answers@xml}{ \moodle@subanswertext@htmlized

    ]]>
    \ifmoodle@pluginfile\htmlize@embeddedfiletags\fi
    }% \else % \show\moodle@subanswertext@htmlized \addto@xml[4]{\moodle@answers@xml}{ }% \fi % \ifx\moodle@feedback\@empty\relax\else % \trim@spaces@in\moodle@feedback % \xa\converttohtmlmacro\xa\moodle@feedback@html\xa{\moodle@feedback}% % \addto@xml[4]{\moodle@answers@xml}{ \moodle@feedback@html

    ]]>
    }% % \fi \addto@xml[2]{\moodle@answers@xml}{
    }% }% % WRITING QUESTION TO \XML\ FILE \gdef\writematchingquestion{% \ifmoodle@draganddrop \writetomoodle{}% \else \writetomoodle{}% \fi \moodle@writecommondata% % \moodle@writesingle% %irrelevant for the matching type \moodle@writeshuffle% % \moodle@writeanswernumbering% %irrelevant for the matching type }% % \end{macrocode} % % \subsection{Cloze Questions} % Because cloze questions are so complicated, they get their own section of code. % The cloze strategy is as follows. % % All subquestions show up as part of the question body text. % For each type of subquestion, we have a cloze-version environment % that actually has 2 versions, depending on whether we are doing LaTeX or \XML\ processing. % So the main environment is quite typical: % \begin{enumerate} % \item Process the body as LaTeX. % During this run, a |\begin{multi}| etc.~will be processed for display onscreen. % \item Then save the body as the questiontext for \XML. % During this run, a |\begin{multi}| etc.~will be parsed and turned into % cloze code as part of the \XML\ questiontext. % \end{enumerate} % \begin{macrocode} % LATEX PROCESSING % SAVING ANSWERS TO MEMORY \newif\ifmoodle@clozemode \moodle@clozemodefalse \NewEnviron{cloze}[2][]{% \bgroup \setkeys{moodle}{default grade=1}% \setkeys{moodle}{#1,questionname={#2}}% % A cloze question won't have any \item's in it, so we just use \BODY. \moodle@enableclozeenvironments %First, the LaTeX processing. \item \moodle@begin@samepage\textbf{\moodle@questionname} \ifmoodle@handout \moodle@makelatextag@qtype{cloze} \else \moodle@latex@writetags \par \noindent \moodle@makelatextag@qtype{cloze} \moodle@makelatextag@value{penalty}{penalty} \fi \par \noindent \BODY \edef\moodle@generalfeedback{\expandonce\moodle@feedback} %\csname moodle@cloze@latexprocessing\endcsname \ifmoodle@handout\else \ifx\moodle@generalfeedback\@empty\relax\else% \fbox{\parbox{.96\linewidth}{\emph{\moodle@generalfeedback}}}% \fi \fi \moodle@end@samepage %Now, writing information to memory. \@moodle@ifgeneratexml{% \xa\questiontext\xa{\BODY}% Save the question text as \HTML. \writeclozequestion }{}% \egroup% } \def\moodle@enableclozeenvironments{% \let\multi=\clozemulti \let\endmulti=\endclozemulti \let\numerical=\clozenumerical \let\endnumerical=\endclozenumerical \let\shortanswer=\clozeshortanswer \let\endshortanswer=\endclozeshortanswer } % WRITING QUESTION TO \XML\ FILE \gdef\writeclozequestion{% \writetomoodle{}% \moodle@writequestionname% \moodle@writequestiontext% \moodle@writegeneralfeedback% \moodle@writepenalty% \moodle@writehidden% \moodle@writetags% \writetomoodle{}% }% % \end{macrocode} % % Utility to check the validity of fractions and points inside cloze subquestions. % \begin{macrocode} \newdimen\moodle@tmpdim \def\moodle@checkclozefraction{% \moodle@tmpdim=\moodle@fraction pt\relax % Rounding is performed in three steps: % 1) round(x)=floor(x+1/2) \advance\moodle@tmpdim by .5pt\relax % 2) floor(x)=trunc(x) if x>0, and floor(x)=trunc(x-1) if x<0 \ifdim\moodle@tmpdim<0pt\relax\advance\moodle@tmpdim by -1pt\fi % 3) Truncation because the quantum of TeX dimensions is 1/65536-th of a point. \divide\moodle@tmpdim by 65536\relax\multiply\moodle@tmpdim by 65536\relax \def\moodle@tmpval{\strip@pt\moodle@tmpdim}% \ifdim\moodle@tmpdim=\moodle@fraction pt\else \PackageWarning{moodle}{in cloze questions, fractions must be integers. Rounding \moodle@fraction\space to \moodle@tmpval}% \fi \xdef\moodle@fraction{\moodle@tmpval}% in any case, take eventual decimals out (e.g. change 10.0 for 10) }% \def\moodle@checkclozegrade{% \moodle@tmpdim=\csname moodle@default grade\endcsname pt\relax \ifdim\moodle@tmpdim<1 pt\relax \PackageWarning{moodle}{for cloze questions, the default grade must be a positive integer. Changing the default grade from \csname moodle@default grade\endcsname\space to 1}% \csdef{moodle@default grade}{1}% \else % Rounding is performed in three steps: % 1) round(x)=floor(x+1/2) \advance\moodle@tmpdim by .5pt\relax % 2) floor(x)=trunc(x) if x>0, and floor(x)=trunc(x-1) if x<0 \ifdim\moodle@tmpdim<0pt\relax\advance\moodle@tmpdim by -1pt\fi % 3) Truncation because the quantum of TeX dimensions is 1/65536-th of a point. \divide\moodle@tmpdim by 65536\relax\multiply\moodle@tmpdim by 65536\relax \def\moodle@tmpval{\strip@pt\moodle@tmpdim}% \ifdim\moodle@tmpdim=\csname moodle@default grade\endcsname pt\else \PackageWarning{moodle}{for cloze questions, the default grade must be a positive integer. Rounding \csname moodle@default grade\endcsname\space to \moodle@tmpval}% \fi \csedef{moodle@default grade}{\moodle@tmpval}% in any case, take eventual decimals out (e.g. change 10.0 for 10) \fi }% % \end{macrocode} % % \subsubsection{Cloze Multiple Choice Questions} % % \begin{macrocode} \NewEnviron{clozemulti}[1][]{% \bgroup \setkeys{moodle}{#1}% \moodle@checkclozegrade \expandafter\gatheritems\xa{\BODY}% \let\moodle@questionheader=\gatheredheader \ifhtmlizer@active %HTML version \def\moodle@clozemulti@output{}% \xa\g@addto@macro\xa\moodle@clozemulti@output\xa{\moodle@questionheader}% \def\clozemulti@coding{}% \edef\clozemulti@coding{\csname moodle@default grade\endcsname:}% \ifmoodle@single \g@addto@macro{\clozemulti@coding}{MULTICHOICE}% \else \moodle@WarningOrError{3}{5}{Cloze Multiresponse}% \g@addto@macro{\clozemulti@coding}{MULTIRESPONSE}% \fi \ifcase\moodle@multi@mode\relax % Case 0: dropdown box style \ifmoodle@single\else \PackageError{moodle}{Inline mode (dropdown box) incompatible with multiresponse.} \fi \ifmoodle@shuffle \g@addto@macro{\clozemulti@coding}{_}% \fi \or % Case 1: vertical style \ifmoodle@single \g@addto@macro{\clozemulti@coding}{_V}% \else \ifmoodle@shuffle \g@addto@macro{\clozemulti@coding}{_}% \fi \fi \else % Case 2: horizontal radio buttons \g@addto@macro{\clozemulti@coding}{_H}% \fi \ifmoodle@shuffle \moodle@WarningOrError{3}{0}{Cloze Multi Shuffling} \g@addto@macro{\clozemulti@coding}{S:}% \else \g@addto@macro{\clozemulti@coding}{:}% \fi \bgroup \setkeys{moodle}{feedback={}}% \loopthroughitemswithcommand{\saveclozemultichoiceanswer}% \egroup %\xa\g@addto@macro\xa\clozemulti@coding\xa{\clozerbrace}% \xa\g@addto@macro\xa\moodle@clozemulti@output\xa{\xa\clozelbrace\clozemulti@coding\clozerbrace}% %\show\moodle@clozemulti@output \xa\gdef\xa\htmlize@afteraction@hook\xa{\moodle@clozemulti@output}% \def\endclozemulti@code{\htmlize@patchendenvironment}% \else %LaTeX version \global\advance\moodle@totalmarks by \csname moodle@default grade\endcsname pt \moodle@questionheader% %Any introductory text just continues to be typeset. \par \noindent \moodle@makelatextag@qtype{multi} \ifmoodle@handout\else \moodle@makelatextag@value{default grade}{marked out of} \moodle@makelatextag@multi \fi \def\cloze@multichoice@table@text{}% \ifmoodle@single\relax\else\moodle@InspectMultipleAnswers\fi \ifmoodle@handout\NewList{answerlist}\fi %\let\moodle@feedback=\@empty \loopthroughitemswithcommand{\moodle@print@clozemultichoice@answer}% \ifmoodle@handout \ifmoodle@shuffle \let\moodle@clozemult@loop=\ForEachRandomItem \else \let\moodle@clozemult@loop=\ForEachFirstItem \fi \moodle@clozemult@loop{answerlist}{Answer}{ \xdef\cloze@multichoice@table@text{\expandonce\cloze@multichoice@table@text\expandonce\Answer}% }% \fi \ifcase\moodle@multi@mode\relax %Case 0: dropdown box style \par\noindent \ifmoodle@handout \begin{tabular}[t]{|p{.45\linewidth}|} \else \begin{tabular}[t]{|p{.45\linewidth}|p{.45\linewidth}|} % answer & feedback \\\hline\hline \fi \firsthline% (\firsthline is from the array package.) \cloze@multichoice@table@text% \end{tabular}% \par% \or %Case 1: vertical style \par\noindent \begin{itemize}\setlength\itemsep{0pt}\setlength\parskip{0pt}% \cloze@multichoice@table@text% \end{itemize}% \par% \else %Case 2: horizontal radio buttons \par{\cloze@multichoice@table@text}\par% \fi \def\endclozemulti@code{\relax}% \fi \passvalueaftergroup\endclozemulti@code% \passvalueaftergroup\htmlize@afteraction@hook% \egroup% }[\endclozemulti@code]% \long\def\moodle@print@clozemultichoice@answer#1{% %\bgroup \let\moodle@feedback=\@empty \moodle@print@clozemultichoice@answer@int#1 \@rdelim% %\egroup }% \newcommand\moodle@print@clozemultichoice@answer@int[1][]{% \let\moodle@fraction\@empty% \setkeys{moodle}{#1}% \moodle@print@clozemultichoice@answer@int@int% }% \long\def\moodle@print@clozemultichoice@answer@int@int#1#2\@rdelim{% \def\moodle@answertext{}% % Case 0: "(answer) \\ \hline" % Case 1: "\item (answer)" % Case 2: "$\bullet~$(answer)\hfill" \ifcase\moodle@multi@mode\relax \relax% Case 0 \or \g@addto@macro\moodle@answertext{\item}% Case 1 \else \g@addto@macro\moodle@answertext{$\bullet~$}% Case 2 \fi \def\test@i{#1}% \ifx\test@i\@star \setkeys{moodle}{fraction=100}% \g@addto@macro\moodle@answertext{#2}% \else \g@addto@macro\moodle@answertext{#1#2}% \fi \trim@spaces@in\moodle@answertext \trim@spaces@in\moodle@answertext \ifmoodle@handout\else \ifmoodle@single% \ifx\moodle@fraction\@empty\relax% \ifdim0pt<\moodle@sanction pt\relax \setkeys{moodle}{fraction=-\moodle@sanction}% \else \setkeys{moodle}{fraction=0}% \fi \fi \moodle@checkclozefraction \ifx\moodle@fraction\@hundred% \trim@spaces@in\moodle@answertext% \g@addto@macro\moodle@answertext{$~\checkmark$}% \else \ifdim0pt=\moodle@fraction pt\relax\else% \xdef\moodle@answertext{\expandonce\moodle@answertext$~(\moodle@fraction\%)$}% \fi \fi \else% multiple \ifx\moodle@fraction\@empty\relax% \ifmoodle@AdvancedScoreMode \setkeys{moodle}{fraction=0}% \else \setkeys{moodle}{fraction=-\moodle@AutoScore}% \fi \else \ifmoodle@AdvancedScoreMode \moodle@checkclozefraction \ifdim0pt<\moodle@fraction pt\relax \moodle@autoscore@tmp=\moodle@PositiveScoreFactor\relax% \multiply\moodle@autoscore@tmp by \moodle@fraction\relax% \xdef\moodle@fraction{\strip@pt\moodle@autoscore@tmp}% \fi \else \setkeys{moodle}{fraction=\moodle@AutoScore}% \fi \fi \xdef\moodle@answertext{\expandonce\moodle@answertext$~(\moodle@fraction\%)$}% \fi \fi \ifcase\moodle@multi@mode\relax % Case 0 \ifmoodle@handout\else \xdef\moodle@answertext{\expandonce\moodle@answertext &\expandonce\emph{\expandonce\moodle@feedback}}% \fi \g@addto@macro\moodle@answertext{\\\hline} \or % Case 1 \ifmoodle@handout\else \ifx\moodle@feedback\@empty\relax\else \xdef\moodle@answertext{\expandonce\moodle@answertext \moodle@preFeedback \expandonce\emph{$\rightarrow$ \expandonce\moodle@feedback}}% \fi \fi \else % otherwise \ifmoodle@handout\else \ifx\moodle@feedback\@empty\relax\else \xdef\moodle@answertext{\expandonce\moodle@answertext\,\expandonce\emph{$\rightarrow$ \expandonce\moodle@feedback}}% \fi \fi \g@addto@macro\moodle@answertext{\hfill}% Case 2 \fi \ifmoodle@handout \def\temp{\InsertLastItem{answerlist}}% \xa\temp\xa{\moodle@answertext}% \else \xdef\cloze@multichoice@table@text{\expandonce\cloze@multichoice@table@text\expandonce\moodle@answertext}% \fi }% \long\def\saveclozemultichoiceanswer#1{% \bgroup \saveclozemultichoiceanswer@int#1 \moodle@answer@rdelim \egroup }% \newcommand\saveclozemultichoiceanswer@int[1][]{% \setkeys{moodle}{fraction=0,#1}% \saveclozemultichoiceanswer@int@int% }% \long\def\saveclozemultichoiceanswer@int@int#1#2\moodle@answer@rdelim{% \def\test@i{#1}% \ifgatherbeginningofloop\else \xa\gdef\xa\clozemulti@coding\xa{\clozemulti@coding\clozetilde}% separator between answers \fi \ifx\test@i\@star \setkeys{moodle}{fraction=100}% \def\moodle@answertext{#2}% \else \def\moodle@answertext{#1#2}% \fi \trim@spaces@in\moodle@answertext \trim@spaces@in\moodle@answertext \ifx\moodle@fraction\@hundred \g@addto@macro\clozemulti@coding{\clozecorrect}% \else \moodle@checkclozefraction \ifdim0pt=\moodle@fraction pt\relax\else \xdef\clozemulti@coding{\expandonce\clozemulti@coding\otherpercent\moodle@fraction\otherpercent}% \fi \fi \xdef\clozemulti@coding{\expandonce\clozemulti@coding\expandonce\moodle@answertext}% \ifx\moodle@feedback\@empty\else \xdef\clozemulti@coding{\expandonce\clozemulti@coding\otherbackslash\otherhash\expandonce\moodle@feedback}% \fi }% % \end{macrocode} % % \subsubsection{Cloze Numerical Questions} % % \begin{macrocode} \NewEnviron{clozenumerical}[1][]{% \bgroup \expandafter\gatheritems\expandafter{\BODY}% \let\moodle@questionheader=\gatheredheader \setkeys{moodle}{#1}% \moodle@checkclozegrade \ifhtmlizer@active %HTML version \def\moodle@clozenumerical@output{}% \xa\g@addto@macro\xa\moodle@clozenumerical@output\xa{\moodle@questionheader}% \def\clozenumerical@coding{}% \edef\clozenumerical@coding{\csname moodle@default grade\endcsname:NUMERICAL:}% \bgroup \setkeys{moodle}{feedback={}}% \loopthroughitemswithcommand{\saveclozenumericalanswer}% \egroup %\xa\g@addto@macro\xa\clozenumerical@coding\xa{\otherrbrace}% \xa\g@addto@macro\xa\moodle@clozenumerical@output\xa{\xa\clozelbrace\clozenumerical@coding\clozerbrace}% \xa\gdef\xa\htmlize@afteraction@hook\xa{\moodle@clozenumerical@output}% \def\endclozenumerical@code{\htmlize@patchendenvironment}% \else %LaTeX version \global\advance\moodle@totalmarks by \csname moodle@default grade\endcsname pt \moodle@questionheader% %Any introductory text just continues to be typeset. \par \noindent \moodle@makelatextag@qtype{numerical} \ifmoodle@handout\else \moodle@makelatextag@value{default grade}{marked out of} \moodle@makelatextag@numerical \par \noindent \def\cloze@numerical@table@text{}% \loopthroughitemswithcommand{\moodle@print@clozenumerical@answer}% \begin{tabular}[t]{|p{.45\linewidth}|p{.45\linewidth}|} \firsthline% (\firsthline is from the array package.) % answer & feedback \\\hline\hline \cloze@numerical@table@text% \end{tabular}% \par% \fi \def\endclozenumerical@code{\relax}% \fi \passvalueaftergroup\endclozenumerical@code% \passvalueaftergroup\htmlize@afteraction@hook% \egroup }[\endclozenumerical@code]% \def\moodle@print@clozenumerical@answer#1{% \let\moodle@feedback=\@empty \bgroup \moodle@print@clozenumerical@answer@int#1\@rdelim \egroup }% \newcommand\moodle@print@clozenumerical@answer@int[1][]{% \setkeys{moodle}{#1}% \moodle@print@clozenumerical@answer@int@int% }% \def\moodle@zero{0}% \def\moodle@print@clozenumerical@answer@int@int#1\@rdelim{% \ifx\moodle@fraction\@hundred \def\moodle@clozenumericalprint@fraction{$~\checkmark$}% \else \moodle@checkclozefraction \edef\moodle@clozenumericalprint@fraction{$(~\moodle@fraction\%)$}% \fi \ifx\moodle@zero\moodle@tolerance% \def\moodle@clozenumericalprint@tolerance{}% \else \edef\moodle@clozenumericalprint@tolerance{$\,\pm\,$\moodle@printnum{\expandonce\moodle@tolerance}}% \fi \gdef\test@i{#1}% \trim@spaces@in\test@i \ifx\test@i\@star \xdef\moodle@clozenumericalprint@line{\expandonce\test@i~\moodle@clozenumericalprint@fraction & \expandonce\emph{\expandonce\moodle@feedback}}% \else \xdef\moodle@clozenumericalprint@line{\moodle@printnum{\expandonce\test@i}\expandonce\moodle@clozenumericalprint@tolerance~\moodle@clozenumericalprint@fraction & \expandonce\emph{\expandonce\moodle@feedback}}% \fi \xa\g@addto@macro\xa\cloze@numerical@table@text\xa{\moodle@clozenumericalprint@line \\\hline}% }% \def\saveclozenumericalanswer#1{% \bgroup \saveclozenumericalanswer@int#1\moodle@answer@rdelim \egroup }% \newcommand\saveclozenumericalanswer@int[1][]{% \setkeys{moodle}{fraction=100,#1}% %%%%%% DEFAULT VALUE IS 100% \saveclozenumericalanswer@int@int% }% \def\saveclozenumericalanswer@int@int#1\moodle@answer@rdelim{% \ifgatherbeginningofloop\else \xa\gdef\xa\clozenumerical@coding\xa{\clozenumerical@coding\clozetilde}% separator between answers \fi \def\moodle@answertext{#1}% \trim@spaces@in\moodle@answertext \ifx\moodle@fraction\@hundred \g@addto@macro\clozenumerical@coding{\clozecorrect}% \else \moodle@checkclozefraction \ifdim0pt=\moodle@fraction pt\relax\else \xdef\clozenumerical@coding{\expandonce\clozenumerical@coding\otherpercent\moodle@fraction\otherpercent}% \fi \fi \ifx\moodle@answertext\@star \xdef\clozenumerical@coding{\expandonce\clozenumerical@coding\moodle@answertext}% \else \xdef\clozenumerical@coding{\expandonce\clozenumerical@coding\moodle@answertext:\moodle@tolerance}% \fi \ifx\moodle@feedback\@empty\else %\trim@spaces@in\moodle@feedback \xdef\clozenumerical@coding{\expandonce\clozenumerical@coding\otherbackslash\otherhash\expandonce\moodle@feedback}% \fi }% % \end{macrocode} % % \subsubsection{Cloze Short Answer Questions} % % \begin{macrocode} \NewEnviron{clozeshortanswer}[1][]{% \bgroup \expandafter\gatheritems\expandafter{\BODY}% \let\moodle@questionheader=\gatheredheader \setkeys{moodle}{#1}% \moodle@checkclozegrade \ifhtmlizer@active %HTML version \def\moodle@clozeshortanswer@output{}% \xa\g@addto@macro\xa\moodle@clozeshortanswer@output\xa{\moodle@questionheader}% \def\clozeshortanswer@coding{}% \ifmoodle@usecase \edef\clozeshortanswer@coding{\csname moodle@default grade\endcsname:SHORTANSWER_C:}% \else \edef\clozeshortanswer@coding{\csname moodle@default grade\endcsname:SHORTANSWER:}% \fi \bgroup \setkeys{moodle}{feedback={}}% \loopthroughitemswithcommand{\saveclozeshortansweranswer}% \egroup %\xa\g@addto@macro\xa\clozeshortanswer@coding\xa{\otherrbrace}% \xa\g@addto@macro\xa\moodle@clozeshortanswer@output\xa{\xa\clozelbrace\clozeshortanswer@coding\clozerbrace}% \xa\gdef\xa\htmlize@afteraction@hook\xa{\moodle@clozeshortanswer@output}% \def\endclozeshortanswer@code{\htmlize@patchendenvironment}% \else %LaTeX version \global\advance\moodle@totalmarks by \csname moodle@default grade\endcsname pt \moodle@questionheader% %Any introductory text just continues to be typeset. \par \noindent \moodle@makelatextag@qtype{shortanswer} \ifmoodle@handout\else \moodle@makelatextag@value{default grade}{marked out of} \moodle@makelatextag@shortanswer \par \noindent \def\cloze@shortanswer@table@text{}% \loopthroughitemswithcommand{\moodle@print@clozeshortanswer@answer}% \begin{tabular}[t]{|p{.45\linewidth}|p{.45\linewidth}|} \firsthline% (\firsthline is from the array package.) % answer & feedback \\\hline\hline \cloze@shortanswer@table@text% \end{tabular}% \par% \fi \def\endclozeshortanswer@code{\relax}% \fi \passvalueaftergroup\endclozeshortanswer@code% \passvalueaftergroup\htmlize@afteraction@hook% \egroup }[\endclozeshortanswer@code]% \def\moodle@print@clozeshortanswer@answer#1{% \let\moodle@feedback=\@empty \bgroup \moodle@print@clozeshortanswer@answer@int#1\@rdelim \egroup }% \newcommand\moodle@print@clozeshortanswer@answer@int[1][]{% \setkeys{moodle}{#1}% \moodle@print@clozeshortanswer@answer@int@int% }% \def\moodle@print@clozeshortanswer@answer@int@int#1\@rdelim{% \ifx\moodle@fraction\@hundred \def\moodle@clozeshortanswerprint@fraction{$~\checkmark$}% \else \moodle@checkclozefraction \edef\moodle@clozeshortanswerprint@fraction{$~(\moodle@fraction\%)$}% \fi \xdef\moodle@clozeshortanswerprint@line{#1~\moodle@clozeshortanswerprint@fraction & \expandonce\emph{\expandonce\moodle@feedback}}% \xa\g@addto@macro\xa\cloze@shortanswer@table@text\xa{\moodle@clozeshortanswerprint@line \\\hline}% }% \def\saveclozeshortansweranswer#1{% \bgroup \saveclozeshortansweranswer@int#1\moodle@answer@rdelim \egroup }% \newcommand\saveclozeshortansweranswer@int[1][]{% \setkeys{moodle}{fraction=100,#1}% %%%%%% DEFAULT VALUE IS 100% \saveclozeshortansweranswer@int@int% }% \def\saveclozeshortansweranswer@int@int#1\moodle@answer@rdelim{% \ifgatherbeginningofloop\else \xa\gdef\xa\clozeshortanswer@coding\xa{\clozeshortanswer@coding\clozetilde}% separator between answers \fi \def\moodle@answertext{#1}% \trim@spaces@in\moodle@answertext \ifx\moodle@fraction\@hundred \g@addto@macro\clozeshortanswer@coding{\clozecorrect}% \else \moodle@checkclozefraction \ifdim0pt=\moodle@fraction pt\relax\else \xdef\clozeshortanswer@coding{\expandonce\clozeshortanswer@coding\otherpercent\moodle@fraction\otherpercent}% \fi \fi \xdef\clozeshortanswer@coding{\expandonce\clozeshortanswer@coding\moodle@answertext}% \ifx\moodle@feedback\@empty\else \xdef\clozeshortanswer@coding{\expandonce\clozeshortanswer@coding\otherbackslash\otherhash\expandonce\moodle@feedback}% \fi }% % \end{macrocode} % % \section{Converting \LaTeX\ to HTML} % A lot of work must now be done to convert the \LaTeX\ code % of a question or answer into \HTML\ code with embedded \TeX\ for math. % % \subsection{Catcode Setup} % First, we create versions of the special characters with catcode 12, ``other.'' % \begin{macrocode} {\catcode`\#=12\gdef\otherhash{#}% \catcode`\~=12\gdef\othertilde{~}% \catcode`\&=12\gdef\otherampersand{&}% \catcode`\^=12\gdef\othercaret{^}% \catcode`\$=12\gdef\otherdollar{$}% \catcode`\%=12\gdef\otherpercent{%} \catcode`\[=12\gdef\otherlbracket{[} \catcode`\]=12\gdef\otherrbracket{]}}% {\catcode`\=\string=12\gdef\otherequal{=}}% {\catcode`\ =12\gdef\otherspace{ }}% {\ttfamily\catcode`\|=0\catcode`\\=12\relax|gdef|otherbackslash{\}}% {\catcode`\[=1\catcode`\]=2\catcode`\{=12\catcode`\}=12% \gdef\otherlbrace[{]\gdef\otherrbrace[}]\gdef\clozelbrace[{]\gdef\clozerbrace[}]]% \edef\@otherlbrace{\otherlbrace}% \edef\@otherrbrace{\otherrbrace}% \edef\@otherlbracket{\otherlbracket}% \edef\@otherrbracket{\otherrbracket}% \edef\@clozelbrace{\clozelbrace}% \edef\@clozerbrace{\clozerbrace}% \edef\@otherdollar{\otherdollar}% \edef\@otherbackslash{\otherbackslash}% \edef\@othertilde{\othertilde}% \edef\@otherequal{\otherequal}% % \end{macrocode} % % Next, we define commands to change catcodes to a suitable verbatim mode % for transcription. % % \begin{macrocode} { \catcode`\[=1\relax \catcode`\]=2\relax \catcode`\|=0\relax |gdef|verbcatcodesweirdest[ |catcode`\{=12|relax |catcode`\}=12|relax |catcode`\\=12|relax ]% }% \def\verbcatcodes{% \catcode`\$=12\relax \catcode`\&=12\relax \catcode`\#=12\relax \catcode`\^=12\relax \catcode`\_=12\relax \catcode`\~=12\relax \makeatletter \catcode`\%=12\relax \catcode`\ =12\relax\catcode\newlinechar=12\verbcatcodesweirdest}% \def\normalcatcodes{% \catcode`\\=0\relax \catcode`\{=1\relax \catcode`\}=2\relax \catcode`\$=3\relax \catcode`\&=4\relax \catcode\endlinechar=5\relax \catcode`\#=6\relax \catcode`\^=7\relax \catcode`\_=8\relax \catcode`\ =10\relax \makeatletter% We will be detokenizing and retokenizing internal control sequences, so we need this. \catcode`\~=13\relax \catcode`\%=14\relax}% \def\retokenizingcatcodes{% %For rescanning previously scanned text, all true comments will already be gone, %but % signs may have been inserted by Cloze questions, so we want to treat them as 'other.' % % TODO: #'s are more worrisome. \normalcatcodes \catcode`\%=12\relax } % \end{macrocode} % % \subsection{Detokenization and Retokenization} % % We will be processing a \TeX\ token list. % Based on its content, sometimes we will want it to be detokenized to % individual characters, but other times we want it retokenized so that % \TeX's own parsing mechanism can gather up the parameters of macros. % We use the e\TeX\ primitive command |\scantokens| to do this. % % The following code (catcodes, groupings and all) defines a |\scantokens@to@macro| macro. % That will assemble and disassemble strings of tokens % using any changing schemes of catcodes we desire. % % We define |^^A| to be |\gdef\stm@saved|, while |^^B| and |^^C| are substitutes for |{| and |}|, respectively. % This permits us to define |\scantokens@to@macro| in a peculiar catcode regime. % \begin{macrocode} \begingroup \catcode`\^^A=13\gdef^^A{\gdef\stm@saved}% \catcode`\^^B=1\catcode`\^^C=2\relax \long\gdef\scantokens@to@macro#1#2#3{% % #1 = control sequence to be defined % #2 = command to change catcodes, e.g. \verbcatcodes, % and define any command sequences % #3 = text to be retokenized and saved into #1. \bgroup \def\texttorescan{#3}% \catcode`\^^A=13\catcode`\^^B=1\catcode`\^^C=2\relax \xa\def\xa\arg\xa{\xa^^A\xa^^B\texttorescan^^C}% #2% \catcode\endlinechar=9\relax% %\scantokens always sees an end-of-line character at its end and converts it to a space. %The catcode change sets \scantokens to ignore end-of-line chars. %In practice, we're always calling \scantokens on previously scanned text anyway, %so we won't miss any real end-of-line chars, since they were already converted to spaces. \xa\scantokens\xa{\arg}% \egroup \xa\def\xa#1\xa{\stm@saved}% }% \endgroup% \long\def\ultradetokenize@to@macro#1#2{% \scantokens@to@macro#1{\verbcatcodes}{#2}% }% \def\retokenizenormal@to@macro#1#2{% \scantokens@to@macro#1{\retokenizingcatcodes}{#2}% }% % \end{macrocode} % % \subsection{Level-Tracking} % % \subsubsection{TeX groups} % While parsing, we'll need to keep track of how deeply nested in \TeX\ groups we are. % \begin{macrocode} \newcount\grouplevel % \end{macrocode} % % \subsubsection{Math mode} % While parsing, we'll need to keep track of whether % we are in math mode (and how many levels deep the math mode might be nested). % \begin{macrocode} \newcount\moodle@mathmodedepth \moodle@mathmodedepth=0\relax \def\moodle@ifmathmode#1#2{% \ifnum\moodle@mathmodedepth>0\relax #1% \else #2% \fi }% % \end{macrocode} % % \subsubsection{Nested Lists} % While parsing, we'll need to keep track levels of nested list. % \begin{macrocode} \newcount\moodle@listdepth \moodle@listdepth=0\relax % \end{macrocode} % % \subsection{Separation} % % This code separates a string of tokens into two parts. % Its parameters, |#1#2|, consist of tokenized text, % plus one terminal |\@htmlize@stop|. % We are trying to break up the text into its first group and the remainder. % This |\@htmlize@stop| is needed in case |#2| has the form ``|{...}|'', % since we don't want \TeX\ to strip the braces off. % Thus |\@htmlize@remainder| will definitely end in ``|\@htmlize@stop|''. % \begin{macrocode} \long\def\htmlize@grabblock#1#2\htmlize@rdelim@ii{% \long\def\htmlize@blockinbraces{#1}% \long\def\htmlize@remainder{#2}% }% % \end{macrocode} % % The next line defines the macro |\@htmlize@stop@detokenized| to contain % the string of tokens |\@htmlize@stop|, all of category code 12 (other) or 10 (letter). % We'll need this for comparison purposes later. % \begin{macrocode} \ultradetokenize@to@macro\@htmlize@stop@detokenized{\@htmlize@stop}% % \end{macrocode} % % The next line creates the macro |\htmlize@remove@stopcode|, % which removes the characters ``|\@htmlize@stop |'' from the end of a % detokenized sequence. % Its syntax when called is simply |\htmlize@remove@stopcode |\meta{material}, % with no delimiters, since the ``|\@htmlize@stop |'' is itself the delimiter. % \begin{macrocode} \xa\def\xa\htmlize@remove@stopcode\xa#\xa1\@htmlize@stop@detokenized{#1}% % \end{macrocode} % % \subsection{Main Code: the HTMLizer} % % \begin{macrocode} \newif\ifhtmlizer@active \htmlizer@activefalse \newif\ifhtmlize@actioncs \newif\ifhtmlize@expandcs \newif\ifhtmlize@passcs \long\def\@@begin@cs{\begin}% \def\@@htmlize@stop{\@htmlize@stop}% \long\def\converttohtmlmacro#1#2{% \grouplevel=0\relax \def\htmlize@output{}% \ifmoodle@pluginfile \gdef\htmlize@embeddedfiletags{}% \fi \htmlizer@activetrue% \converttohtml@int{#2}% \htmlizer@activefalse% \let#1=\htmlize@output\relax } \long\def\converttohtml@int#1{% \advance\grouplevel by 1\relax \bgroup \ultradetokenize@to@macro\htmlize@texttoscan{#1}% \xa\htmlize@recursive@i\htmlize@texttoscan\@htmlize@stop\@htmlize@stop\@htmlize@stop\htmlize@rdelim@i% \egroup \advance\grouplevel by -1\relax }% \def\@lt{<}% \def\@gt{>}% \def\@dash{-}% \def\@dq{"}% \long\def\htmlize@recursive@i#1#2#3\htmlize@rdelim@i{% % #1#2#3 is a sequence of tokens. All should be categories 11 (letter) or 12 (other). % It terminates with the control sequences \@htmlize@stop\@htmlize@stop\@htmlize@stop. %\long\def\ds{(#1|#2|#3)}\show\ds \def\test@i{#1}% \def\test@ii{#2}% \ifx\test@i\@@htmlize@stop \let\htmlize@next@i=\relax \else \ifx\test@i\@otherlbrace% \ifx\test@ii\@otherrbrace% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\otherlbrace\otherrbrace}}{}% \def\htmlize@next@i{\htmlize@recursive@i#3\htmlize@rdelim@i}% \else \xa\g@addto@macro\xa\htmlize@output\xa{\otherlbrace}% \bgroup \normalcatcodes %We need to rescan the input as TeX code, % so TeX can automatically pull off the first group in braces. % First, let's get rid of the terminal \@htmlize@stop codes. {\def\@htmlize@stop{}\xdef\htmlize@scrap{#1#2#3}}% \let\htmlize@text@to@rescan=\htmlize@scrap% % Next, we retokenize the code. \xa\retokenizenormal@to@macro\xa\htmlize@rescanned\xa{\htmlize@text@to@rescan}% % Now break it up into two pieces. \xa\htmlize@grabblock\htmlize@rescanned\@htmlize@stop\htmlize@rdelim@ii% % The first piece, \htmlize@blockinbraces, will be passed as a unit to \converttohtml@int. % The second part, \htmlize@remainder, will continue at this depth of grouping. % Therefore we'll detokenize \htmlize@remainder here. \xa\ultradetokenize@to@macro\xa\htmlize@remainder@detokenized\xa{\htmlize@remainder}% \edef\htmlize@remainder@detokenized{\xa\htmlize@remove@stopcode\htmlize@remainder@detokenized}% % % Now build \htmlize@next@i. % When done, should look like % \converttohtml@int{\htmlize@blockinbraces}% % \g@addto@macro\htmlize@output{\otherrbrace}% % \htmlize@recursive@i\htmlize@remainder@detokenized\@htmlize@stop\@htmlize@stop\@htmlize@stop\htmlize@rdelim@i% % but with all three arguments expanded. % Note that we are running \gdef\htmlize@scrap{\converttohtml@int}% \xa\g@addto@macro\xa\htmlize@scrap\xa{\xa{\htmlize@blockinbraces}}% \g@addto@macro\htmlize@scrap{\g@addto@macro\htmlize@output}% \ifmoodle@clozemode \xa\g@addto@macro\xa\htmlize@scrap\xa{\xa{\otherbackslash\otherrbrace}}% % \moodle@ifmathmode{\xa\g@addto@macro\xa\htmlize@scrap\xa{\xa{\otherbackslash}}}% % {}% \else \xa\g@addto@macro\xa\htmlize@scrap\xa{\xa{\otherrbrace}}% \fi \g@addto@macro\htmlize@scrap{\htmlize@recursive@i}% \xa\g@addto@macro\xa\htmlize@scrap\xa{\htmlize@remainder@detokenized\@htmlize@stop\@htmlize@stop\@htmlize@stop\htmlize@rdelim@i}% % Okay, that's done. It's stored in a global macro. % Now we get it out of this group. \egroup \let\htmlize@next@i=\htmlize@scrap \fi \else \ifx\test@i\@otherdollar% % Math shift character. \ifx\test@ii\@otherdollar % Double dollar sign, so we're entering display math mode. % We grab everything between $$...$$, sanitize it, and add it verbatim to % our output. \htmlize@displaymathshift@replace#1#2#3\htmlize@rdelim@iii% \else % Single dollar sign, so we're entering inline math mode. % We grab everything between $...$, sanitize it, and add it verbatim to % our output. \htmlize@inlinemathshift@replace#1#2#3\htmlize@rdelim@iii% \fi% \ifx\test@ii\@otherdollar % Now we resume work. % The \htmlize@xxxxxxmathshift@replace macro stored the remaining text in \htmlize@remaining@text. % Note that since we never detokenized and retokenized #1#2#3, % \htmlize@remaining@text still includes the terminating \@htmlize@stop\@htmlize@stop\@htmlize@stop. \def\htmlize@next@i{\xa\htmlize@recursive@i\htmlize@remaining@text\htmlize@rdelim@i}% \else \ifx\test@i\@otherbackslash% % Control sequence. Oh boy. % There are three possible things to do: % 1. Retokenize everything, so we get a token list. % Expand this control sequence, the first one in the list, % to obtain a new token list. Then resume processing that list. % Examples: \def\emph#1{#1}, \def\rec#1{\frac{1}{#1}}, \def\inv{^{-1}} % \& --> & \# --> #; etc. % Environments: \begin{center}...\end{center} -->
    ...
    % 2. Retokenize everything, so we get a token list. % Let this first command (with its parameters) ACT. % This may involve work in TeX's stomach (e.g., with counters) % or with external files (e.g., image processing). % The command may directly add material to \htmlize@output, % but it should not typeset anything and should vanish from the % input stream when it is done. % When it's done, we somehow need to detokenize and resume % processing the remainder of the input stream. % Only commands explicitly crafted (or modified) to work % with moodle.sty can possibly do all this! % Examples: (modified) \includegraphics % Environments: \begin{clozemulti}, \begin{enumerate} % 3. Ignore that it's a command. Pass it right on as a character % sequence to \htmlize@output. % Examples: \alpha, \frac % Environments: \begin{array} % % #2 is only for items on a specific list. % #1 is anything that runs in TeX's mouth. % We could keep a list and give users a way to add to it. % I could also try expanding macros, using \ifcsmacro from etoolbox.sty % % The first step is to figure out what control sequence we're dealing with. % First, let's get rid of the terminal \@htmlize@stop codes. {\def\@htmlize@stop{}\xdef\htmlize@scrap{#1#2#3}}% \let\htmlize@text@to@rescan=\htmlize@scrap% % Next, we retokenize the code. \xa\retokenizenormal@to@macro\xa\htmlize@rescanned\xa{\htmlize@text@to@rescan}% % Now break it up into two pieces. \xa\htmlize@grabblock\htmlize@rescanned\@htmlize@stop\htmlize@rdelim@ii% \let\@htmlize@cs\htmlize@blockinbraces% \edef\htmlize@cs@string{\xa\string\@htmlize@cs}% % The first piece, \htmlize@blockinbraces, will contain the single token in \@htmlize@cs. % We'll need to keep the second part, \htmlize@remainder, since it probably % contains arguments to the cs in \@htmlize@cs. %\edef\ds{Encountered '\xa\string\@htmlize@cs'}\show\ds % % N.B. that \@htmlize@cs is a macro *containing* a single control sequence. % This is good for testing with \ifx. % \htmlize@cs@string contains the cs as a string, e.g., the characters "\emph". % \ifx\@htmlize@cs\@@begin@cs %This is a \begin. Begin environment-handling routine. % % Grab the first {...} from \htmlize@remainder, which is the argument % to \begin. \xa\htmlize@grabblock\htmlize@remainder\@htmlize@stop\htmlize@rdelim@ii% \let\htmlize@envname=\htmlize@blockinbraces% %We do not need the rest, so we won't pay any attention to the new %content of \htmlize@remainder. % %Now environments are non-expandable, %so there are only two possibilities: action or pass. \xa\ifinlist\xa{\htmlize@envname}{\htmlize@env@actionlist}% {% Action environment! %\bgroup %\def\ds{Encountered active environment \string\begin\{{\htmlize@envname}\}}\show\ds \def\htmlize@next@i{\xa\htmlize@do@actionenv\htmlize@rescanned\@htmlize@stop\htmlize@actionsequence@rdelim}% %The \bgroup is to active the environments. %The matching \egroup is found in \htmlize@do@actionenv. }{%An environment to pass to the HTML %We just pass the backslash from "\begin" and move on. \g@addto@macro\htmlize@output{#1}% \def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}% }% \else% %This is not an environment. Begin macro-handling routine. \htmlize@actioncsfalse \htmlize@expandcsfalse \htmlize@passcsfalse \xa\ifinlist\xa{\htmlize@cs@string}{\htmlize@cs@actionlist}% {%Action sequence! \htmlize@actioncstrue}% {% Not action sequence! \xa\ifinlist\xa{\htmlize@cs@string}{\htmlize@cs@expandlist}% {%CS to be expanded! \htmlize@expandcstrue% }% {%CS to be transcribed to XML \htmlize@passcstrue% }% }% %Now exactly one of \ifhtmlize@actioncs, \ifhtmlize@expandcs, and \ifhtmlize@passcs is true. \ifhtmlize@actioncs % It's an action-sequence. %\edef\ds{Must let \xa\string\@htmlize@cs\ act!}\show\ds %\show\htmlize@rescanned \def\htmlize@next@i{\xa\htmlize@do@actioncs\htmlize@rescanned\@htmlize@stop\htmlize@actionsequence@rdelim}% %\show\htmlize@rescanned % Note that \htmlize@do@actioncs should patch the command to have it % restart the scanning in time. \else \ifhtmlize@expandcs % control sequence to be expanded %\edef\ds{Must expand \xa\string\@htmlize@cs}\show\ds \bgroup \htmlize@redefine@expansionmacros %The \expandafters first expand \htmlize@rescanned, %and then expand its first token just once. \xa\xa\xa\gdef\xa\xa\xa\htmlize@scrap\xa\xa\xa{\htmlize@rescanned}% \egroup \xa\ultradetokenize@to@macro\xa\htmlize@remaining@text\xa{\htmlize@scrap}% \def\htmlize@next@i{\xa\htmlize@recursive@i\htmlize@remaining@text\@htmlize@stop\@htmlize@stop\@htmlize@stop\htmlize@rdelim@i}% \else % control sequence to be transcribed to \XML. %\edef\ds{Must pass on \xa\string\@htmlize@cs}\show\ds \g@addto@macro\htmlize@output{#1}% \def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}% \fi% \ifhtmlize@expandcs \fi% \ifhtmlize@actioncs \fi% \ifx\@htmlize@cs\@@begin@cs \else% \ifx\test@i\@othertilde% % The ~ becomes non-breaking space   outside of math mode \moodle@ifmathmode{\g@addto@macro\htmlize@output{\@othertilde}}% {\g@addto@macro\htmlize@output{\otherampersand nbsp;}}% \def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}% \else \ifx\test@i\@lsinglequote% \ifx\test@ii\@lsinglequote% % Double left quote \g@addto@macro\htmlize@output{\otherampersand ldquo;}% \def\htmlize@next@i{\htmlize@recursive@i#3\htmlize@rdelim@i}% \else \g@addto@macro\htmlize@output{\otherampersand lsquo;}% \def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}% \fi% \ifx\test@ii\@lsinglequote% \else \ifx\test@i\@rsinglequote% \ifx\test@ii\@rsinglequote% Double right quote %AAedit 2021.01.06: in math mode, you should write 2 single right quotes, for second derivatives \moodle@ifmathmode{\g@addto@macro\htmlize@output{''}}% {\g@addto@macro\htmlize@output{\otherampersand rdquo;}}% \def\htmlize@next@i{\htmlize@recursive@i#3\htmlize@rdelim@i}% \else% Single right quote \moodle@ifmathmode{\g@addto@macro\htmlize@output{'}}% {\g@addto@macro\htmlize@output{\otherampersand rsquo;}}% \def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}% \fi% \ifx\test@ii\@rsinglequote% \else \ifx\test@i\@doublequote \g@addto@macro\htmlize@output{\otherampersand quot;}% \def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}% \else \ifx\test@i\@lt \g@addto@macro\htmlize@output{\otherampersand lt;} \def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}% \else \ifx\test@i\@gt \g@addto@macro\htmlize@output{\otherampersand gt;}% \def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}% \else \ifx\test@i\@dash \ifx\test@ii\@dash% en-dash (--) \moodle@ifmathmode{\g@addto@macro\htmlize@output{--}}% {\g@addto@macro\htmlize@output{\otherampersand ndash;}}% \def\htmlize@next@i{\htmlize@recursive@i#3\htmlize@rdelim@i}% \else \g@addto@macro\htmlize@output{-}% \def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}% \fi \else \ifx\test@i\@otherequal \ifmoodle@clozemode \moodle@ifmathmode{\g@addto@macro\htmlize@output{=}}% {\g@addto@macro\htmlize@output{\otherampersand\otherhash 61;}}% \else \g@addto@macro\htmlize@output{=}% \fi \def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}% \else % Default case: write first token to output, call self on remaining tokens. \g@addto@macro\htmlize@output{#1}% \def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}% \fi% \ifx\test@i\@otherequal \fi% \ifx\test@i\@dash \fi% \ifx\test@i\@gt \fi% \ifx\test@i\@lt \fi% \ifx\test@i\@doublequote \fi% \ifx\test@i\@rsinglequote% \fi% \ifx\test@i\@lsinglequote% \fi% \ifx\test@i\@othertilde% \fi% \ifx\test@i\@otherbackslash% \fi% \ifx\test@i\@otherdollar% \fi% \ifx\test@i\@otherlbrace% \fi% \ifx\test@i\@@htmlize@stop \htmlize@next@i }% \def\@lsinglequote{`}% \def\@rsinglequote{'}% \def\@doublequote{"}% % \end{macrocode} % % \subsection{Math Mode handling} % % In the following, note that the |\|\meta{*}|mathrightdelim|'s gobble an argument. % This is so ``|$a$ is...|" can turn into % ``\ldots |a\|\meta{*}|mathrightdelim{} is...|" % and preserve a trailing space. % \begin{macrocode} \edef\inlinemathleftdelim{\otherbackslash(}% \def\inlinemathrightdelim#1{\advancemathmodecounter{-1}% \g@addto@macro\htmlize@output{\otherbackslash)}}% \edef\displaymathleftdelim{
    \otherbackslash[}% \def\displaymathrightdelim#1{\advancemathmodecounter{-1}% \g@addto@macro\htmlize@output{\otherbackslash]
    }}% \long\def\htmlize@inlinemath@recursive@i#1#2#3\htmlize@rdelim@i{% % inspired by \htmlize@recursive@i \def\test@i{#1}% \ifx\test@i\@@htmlize@stop \let\htmlize@next@i=\relax \else \ifx\test@i\@otherbackslash \g@addto@macro\mathtext{#1#2}% \def\htmlize@next@i{\xa\htmlize@inlinemath@recursive@i#3\htmlize@rdelim@i}% \else \ifx\test@i\@otherdollar \let\htmlize@next@i=\relax \g@addto@macro\aftertext{#2#3}% \else \g@addto@macro\mathtext{#1}% \def\htmlize@next@i{\xa\htmlize@inlinemath@recursive@i#2#3\htmlize@rdelim@i}% \fi \fi \fi \htmlize@next@i } {\catcode`\$=12\relax% \gdef\htmlize@inlinemathshift@replace#1#2\htmlize@rdelim@iii{% %\def\ds{inline math shift has '#1' and '#2'}\show\ds \xa\g@addto@macro\xa\htmlize@output\xa{\inlinemathleftdelim}% \advancemathmodecounter{1}% \gdef\mathtext{}% \gdef\aftertext{}% \htmlize@inlinemath@recursive@i#2\htmlize@rdelim@i% \xdef\htmlize@remaining@text{\expandonce\mathtext% \otherbackslash inlinemathrightdelim{}% \expandonce\aftertext}% %\show\htmlize@remaining@text }% \gdef\htmlize@displaymathshift@replace$$#1$$#2\htmlize@rdelim@iii{% \xa\g@addto@macro\xa\htmlize@output\xa{\displaymathleftdelim}% \advancemathmodecounter{1}% \def\mathtext{#1}% \def\aftertext{#2}% \xdef\htmlize@remaining@text{\expandonce\mathtext% \otherbackslash displaymathrightdelim{}% \expandonce\aftertext}% }% } % \end{macrocode} % % \subsection{Engines for Control Sequences} % % There are three kinds of control sequences that need special handling: % \begin{enumerate} % \item Action environments % \item Action command sequences % \item Expansion macros % \end{enumerate} % % \subsubsection{Engine for running action environments} % \begin{macrocode} \long\def\htmlize@do@actionenv#1#2\@htmlize@stop\htmlize@actionsequence@rdelim{% \bgroup %The corresponding \egroup is given in \htmlize@proceedwiththerest, %to localize the changes to the environment definitions. \htmlize@activate@environments \gdef\htmlize@afteraction@hook{}% #1#2\@htmlize@stop\htmlize@actionsequence@rdelim% } \def\htmlize@patchendenvironment{\swaptotrueendenvironment{\xa\htmlize@proceedwiththerest\htmlize@afteraction@hook}}% \def\swaptotrueendenvironment#1#2\if@ignore\@ignorefalse\ignorespaces\fi{#2\if@ignore\@ignorefalse\ignorespaces\fi#1}% \long\def\htmlize@record@environment#1{% \listadd{\htmlize@env@actionlist}{#1}% } \long\def\html@newenvironment#1#2{% \listadd{\htmlize@env@actionlist}{#1}% \g@addto@macro\htmlize@activate@environments{% \xa\let\csname #1\endcsname\relax% \xa\let\csname end#1\endcsname\relax% \NewEnviron{#1}{% #2% }[\htmlize@patchendenvironment]% }% } \def\htmlize@activate@environments{}% % \end{macrocode} % % \subsubsection{Engine for running action command sequences} % % The following automatically adds the ``engine'' to do the command % and then resume processing the \LaTeX\ into \HTML. % It uses the |xpatch| package, which says it works with anything % defined using |\newcommand| etc. and |\newenvironment| etc. % \begin{macrocode} \gdef\htmlize@afteraction@hook{}% \long\def\htmlize@do@actioncs#1#2\htmlize@actionsequence@rdelim{% % #1#2 contains the current string to be rendered into HTML; % N.B. it has been tokenized at this point, % so TeX can process it directly. % #1 = the command sequence we need to execute % #2 = the rest of the string % % First, we patch the desired command so that, when it is over, % it calls \htmlize@proceedwiththerest. % We do this within the group, so as not to permanently change the command. \bgroup % The matching \egroup is issued in \htmlize@proceedwiththerest, % so that the changes made by \htmlize@activate@css are localized to just the command itself. \gdef\htmlize@afteraction@hook{}% \htmlize@activate@css% \def\test@i{#1}% \ifx\test@i\@relax \def#1{\xa\htmlize@proceedwiththerest\htmlize@afteraction@hook}% \else \xapptocmd#1{\xa\htmlize@proceedwiththerest\htmlize@afteraction@hook}{}{\PackageError{Could not patch the command \string#1!}}% \fi % Now we call that patched command. #1#2\htmlize@actionsequence@rdelim% %The matching \egroup now is built into the command #1. } \long\def\htmlize@proceedwiththerest#1\htmlize@actionsequence@rdelim{% % The action cs has done its work. % Now we gather up the remaining tokens, detokenize them, % remove the \@htmlize@stop, and get back to work transcribing it. \egroup %This \egroup matches the \bgroup that was issued either in \htmlize@do@actioncs or in \htmlize@do@actionenv \ultradetokenize@to@macro\htmlize@remainder@detokenized{#1}% %This will contain an extra \@htmlize@stop, so we remove it. \xa\xa\xa\def\xa\xa\xa\htmlize@remainder@detokenized\xa\xa\xa{\xa\htmlize@remove@stopcode\htmlize@remainder@detokenized}% %Now we get back to work transcribing the remainder. \xa\htmlize@recursive@i\htmlize@remainder@detokenized\@htmlize@stop\@htmlize@stop\@htmlize@stop\htmlize@rdelim@i% } \long\def\htmlize@record@action#1{% \xa\listadd\xa\htmlize@cs@actionlist\xa{\string#1}% } \def\htmlize@activate@css{}% \long\def\html@action@def#1{% \htmlize@record@action{#1}% \xa\def\xa\htmlize@scrap\xa{\xa\let\xa#1\csname html@\string#1\endcsname}% \xa\g@addto@macro\xa\htmlize@activate@css\xa{\htmlize@scrap}% \xa\def\csname html@\string#1\endcsname% %And this \def\html@\oldcsname is follows by the remainder of the definition. } \def\html@action@newcommand#1[#2][#3]#4{% %\message{>>> Defining #1[#2][#3]{...} ^^J} \ifmoodle@draftmode \else \xa\html@action@def\csname #1\endcsname{\csname moodle@#1@int\endcsname}% \fi % Note that \htmlize@do@actioncs will 'patch' this by putting % '\xa\htmlize@proceedwiththerest\htmlize@afteraction@hook' % at the end. We want those 3 tokens to occur instead after % the graphics filename. \xa\csdef{moodle@#1@int}##1##2##3{\csname moodle@#1@int@int\endcsname}% % This gobbles up those three spurious tokens, % which we will re-insert after our work is done. \xa\newcommand\csname moodle@#1@int@int\endcsname[#2][#3]{% #4% % Now we re-insert the code to get the HTMLizing going again. \xa\htmlize@proceedwiththerest\htmlize@afteraction@hook }% } % \end{macrocode} % % \subsubsection{Engine for expansion control sequences} % % Calling |\htmlize@redefine@expansionmacros| will redefine % the macros for us. It starts out empty. % \begin{macrocode} \long\def\htmlize@redefine@expansionmacros{}% % \end{macrocode} % If |\mymacro| needs no changes to be suited for expansion, % you can simply call |\htmlize@record@expand{\mymacro}| % or |\htmlregister{\mymacro}| % to record that it should be expanded on its way to the \HTML. % Examples would be user-built macros such as |\inv|$\to$|^{-1}| % or |\N|$\to$|\mathbb{N}|. % \begin{macrocode} \long\def\htmlize@record@expand#1{% \xa\listadd\xa\htmlize@cs@expandlist\xa{\string#1}% } \let\htmlregister=\htmlize@record@expand % \end{macrocode} % Often users define a list of macros at the end of the preamble. % It can be cumbersome to record individually these macros for expansion. % By calling |\moodleregisternewcommands| they trigger the automatic % expansion of macros defined subsequently using |\newcommand|, % |\renewcommand|, |\providecommand| or their starred variants. % \begin{macrocode} \def\moodleregisternewcommands{% %% INSPIRED FROM %https://tex.stackexchange.com/questions/73271/how-to-redefine-or-patch-the-newcommand-command \newcommand*{\saved@ifdefinable}{} \let\saved@ifdefinable\@ifdefinable \renewcommand{\@ifdefinable}[2]{% \saved@ifdefinable{##1}{##2}% \htmlregister{##1} }% \let\@@ifdefinable\@ifdefinable }% % \end{macrocode} % On the other hand, if an alternate version of the macro is % needed for \HTML\ purposes, you can define its \HTML\ version with % |\html@def\mymacro...| % Parameters are okay. % An example would be % |\html@def\emph#1{#1}|. % \begin{macrocode} \long\def\html@def#1{% \htmlize@record@expand{#1}% \xa\def\xa\htmlize@scrap\xa{\xa\let\xa#1\csname html@\string#1\endcsname}% \xa\g@addto@macro\xa\htmlize@redefine@expansionmacros\xa{\htmlize@scrap}% \xa\def\csname html@\string#1\endcsname% } % \end{macrocode} % Note that when |\html@def| expands out, it ends with |\def\html@\oldcsname| % which abuts directly on the remainder of the definition. % % \subsection{Specific Control Sequences for Action and Expansion} % % Now that we have that machinery in place, % we define specific environments, action control sequences, and macros to % expand to accomplish our purposes. % % \subsubsection{Action Environments} % \begin{macrocode} \htmlize@record@environment{clozemulti} \htmlize@record@environment{multi} \htmlize@record@environment{clozenumerical} \htmlize@record@environment{numerical} \htmlize@record@environment{clozeshortanswer} \htmlize@record@environment{shortanswer} \html@newenvironment{center}{\xdef\htmlize@afteraction@hook{\noexpand\HTMLtag{CENTER}\expandonce\BODY\noexpand\HTMLtag{/CENTER}}}% \html@newenvironment{quote}{\xdef\htmlize@afteraction@hook{\noexpand\HTMLtag{BLOCKQUOTE}\expandonce\BODY\noexpand\HTMLtag{/BLOCKQUOTE}}}% \html@newenvironment{quotation}{\xdef\htmlize@afteraction@hook{\noexpand\HTMLtag{BLOCKQUOTE}\expandonce\BODY\noexpand\HTMLtag{/BLOCKQUOTE}}}% \def\moodle@save@getitems@state{% \global\xa\xdef\csname moodle@currentitemnumber@level@\the\moodle@listdepth\xa\endcsname\xa{\thecurrentitemnumber}% \global\xa\xdef\csname moodle@numgathereditems@level@\the\moodle@listdepth\xa\endcsname\xa{\thenumgathereditems}% \moodle@saveitems{\thenumgathereditems}% }% \def\moodle@restore@getitems@state{% \setcounter{numgathereditems}{\csname moodle@numgathereditems@level@\the\moodle@listdepth\endcsname}% \setcounter{currentitemnumber}{\csname moodle@currentitemnumber@level@\the\moodle@listdepth\endcsname}% \moodle@restoreitems{\thenumgathereditems}% }% \def\moodle@saveitems#1{% \ifnum#1>0\relax \global\csletcs{moodle@level@\the\moodle@listdepth @item@#1}{getitems@item@#1}% \xa\moodle@saveitems\xa{\number\numexpr#1-1\expandafter}% \fi }% \def\moodle@restoreitems#1{% \ifnum#1>0\relax \global\csletcs{getitems@item@#1}{moodle@level@\the\moodle@listdepth @item@#1}% \global\xa\let\csname moodle@level@\the\moodle@listdepth @item@#1\endcsname=\@undefined \xa\moodle@restoreitems\xa{\number\numexpr#1-1\expandafter}% \fi }% \def\moodle@makelistenv#1#2{% \html@newenvironment{#1}{% \advance\moodle@listdepth by 1\relax \moodle@save@getitems@state% \xa\gatheritems\xa{\BODY}% \gdef\htmlize@afteraction@hook{\HTMLtag{#2}}% \loopthroughitemswithcommand{\moodle@itemtoLI}% \g@addto@macro\htmlize@afteraction@hook{\HTMLtag{/#2}}% \moodle@restore@getitems@state% \advance\moodle@listdepth by -1\relax }% }% \moodle@makelistenv{enumerate}{OL}% \moodle@makelistenv{itemize}{UL}% \def\moodle@itemtoLI#1{% \g@addto@macro\htmlize@afteraction@hook{\HTMLtag{LI}#1}% \trim@spaces@in\htmlize@afteraction@hook% \g@addto@macro\htmlize@afteraction@hook{\HTMLtag{/LI}}% }% % \end{macrocode} % % \subsubsection{Action Control Sequences} % % \begin{macrocode} \def\advancemathmodecounter#1{% \global\advance\moodle@mathmodedepth by #1\relax } \def\openclozemode{% \global\moodle@clozemodetrue\relax } \def\endclozemode{% \global\moodle@clozemodefalse\relax } \htmlize@record@action{\advancemathmodecounter}% \htmlize@record@action{\openclozemode}% \htmlize@record@action{\endclozemode}% \htmlize@record@action{\relax}% \html@action@def\HTMLtag#1{% \xa\g@addto@macro\xa\htmlize@output\xa{<#1>}% }% \html@action@def\%{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\otherbackslash\otherpercent}}% {\g@addto@macro\htmlize@output{\otherpercent}}% }% \html@action@def\#{\g@addto@macro\htmlize@output{\otherhash}}% \html@action@def\&{\g@addto@macro\htmlize@output{\otherampersand}}% \html@action@def\\{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\otherbackslash\otherbackslash}}% {\g@addto@macro\htmlize@output{
    }} }% \html@action@def\{{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\otherbackslash\otherlbrace}}% {\g@addto@macro\htmlize@output{\otherlbrace}}% }% \html@action@def\}{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\otherbackslash\otherrbrace}}% {\ifmoodle@clozemode\g@addto@macro\htmlize@output{\otherbackslash\otherrbrace}% \else\g@addto@macro\htmlize@output{\otherrbrace}\fi}% }% \html@action@def\[{% \advancemathmodecounter{1} \g@addto@macro\htmlize@output{
    \otherbackslash\otherlbracket}% }% \html@action@def\]{% \g@addto@macro\htmlize@output{\otherbackslash\otherrbracket
    }% \advancemathmodecounter{-1} }% \html@action@def\({% \advancemathmodecounter{1} \g@addto@macro\htmlize@output{\otherbackslash(}% }% \html@action@def\){% \g@addto@macro\htmlize@output{\otherbackslash)}% \advancemathmodecounter{-1} }% \html@action@def\ldots{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\string\ldots}}% {\g@addto@macro\htmlize@output{\otherampersand hellip\othersemicol}}% }% \html@action@def\dots{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\string\dots}}% {\g@addto@macro\htmlize@output{\otherampersand hellip\othersemicol}}% }% \html@action@def\ {% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\otherbackslash\otherspace}}% {\g@addto@macro\htmlize@output{\otherspace}}% }% \html@action@def\,{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\string\,}}% {\g@addto@macro\htmlize@output{\otherampersand\otherhash 8239\othersemicol}}% }% \html@action@def\thinspace{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\string\thinspace\otherspace}}% {\g@addto@macro\htmlize@output{\otherampersand\otherhash 8239\othersemicol}}% }% \html@action@def\>{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\otherbackslash\otherampersand gt;}}% {\g@addto@macro\htmlize@output{\otherampersand emsp14\othersemicol}}% }% \html@action@def\:{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\string\:}}% {\g@addto@macro\htmlize@output{\otherampersand emsp14\othersemicol}}% }% \html@action@def\medspace{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\string\:}}% {\g@addto@macro\htmlize@output{\otherampersand emsp14\othersemicol}}% }% \html@action@def\;{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\otherbackslash\othersemicol}}% {\g@addto@macro\htmlize@output{\otherampersand emsp13\othersemicol}}% }% \html@action@def\thickspace{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\otherbackslash\othersemicol}}% {\g@addto@macro\htmlize@output{\otherampersand emsp13\othersemicol}}% }% \html@action@def\enspace{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\string\enspace\otherspace}}% {\g@addto@macro\htmlize@output{\otherampersand ensp\othersemicol}}% }% \html@action@def\quad{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\string\quad\otherspace}}% {\g@addto@macro\htmlize@output{\otherampersand emsp\othersemicol}}% }% \html@action@def\qquad{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\string\qquad\otherspace}}% {\g@addto@macro\htmlize@output{\otherampersand emsp\othersemicol\otherampersand emsp\othersemicol}}% }% \html@action@def\${% \g@addto@macro\htmlize@output{\otherdollar}% }% \html@action@def\textquotesingle{% \g@addto@macro\htmlize@output{'}% }% \html@action@def\@dquote{% \g@addto@macro\htmlize@output{"}% }% \html@action@def\textquotedbl{% \g@addto@macro\htmlize@output{"}% }% \html@action@def\clozetilde{% \xa\g@addto@macro\xa\htmlize@output\xa{\othertilde}% }% \html@action@def\clozecorrect{% \xa\g@addto@macro\xa\htmlize@output\xa{\otherequal}% }% \html@action@def\clozelbrace{% \openclozemode \xa\g@addto@macro\xa\htmlize@output\xa{\otherlbrace}% }% \html@action@def\clozerbrace{% \xa\g@addto@macro\xa\htmlize@output\xa{\otherrbrace}% \endclozemode }% \html@action@def\TeX{% \g@addto@macro\htmlize@output{\otherbackslash(\otherbackslash rm\otherbackslash TeX\otherbackslash)}% }% \html@action@def\LaTeX{% \g@addto@macro\htmlize@output{\otherbackslash(\otherbackslash rm\otherbackslash LaTeX\otherbackslash)}% }% {\catcode`;=12\relax\gdef\othersemicol{;}} %Diacritical marks over vowels {\catcode`|=3\relax \gdef\htmlize@vowels{a|e|i|o|u|A|E|I|O|U|}}% \def\htmlize@define@diacritic#1#2{% \htmlize@record@action{#1}% \g@addto@macro\htmlize@activate@css{% \def#1##1{% \ifinlist{##1}{\htmlize@vowels}% {\g@addto@macro\htmlize@output{\otherampersand##1#2\othersemicol}}% {\xa\g@addto@macro\htmlize@output\xa{\string#1##1}}% }% }% } \htmlize@define@diacritic{\^}{circ}% \htmlize@define@diacritic{\'}{acute}% \htmlize@define@diacritic{\`}{grave}% %Diaeresis/Tréma/Umlaut {\catcode`|=3\relax \gdef\htmlize@diaeresis{a|e|i|o|u|y|A|E|I|O|U|Y|}}% \html@action@def\"#1{% \ifinlist{#1}{\htmlize@diaeresis}% {\g@addto@macro\htmlize@output{\otherampersand#1uml\othersemicol}}% {\xa\g@addto@macro\htmlize@output\xa{\string\"#1}}% }% %Hungarian long-umlaut diacritics \def\@o{o}\def\@O{O}\def\@u{u}\def\@U{U}% \html@action@def\H#1{% \bgroup \def\test@i{#1}% \ifx\test@i\@O \def\toadd{\otherampersand\otherhash336\othersemicol}% \else \ifx\test@i\@o \def\toadd{\otherampersand\otherhash337\othersemicol}% \else \ifx\test@i\@U \def\toadd{\otherampersand\otherhash368\othersemicol}% \else \ifx\test@i\@u \def\toadd{\otherampersand\otherhash369\othersemicol}% \else \def\toadd{\otherbackslash H\otherlbrace#1\otherrbrace}% \fi \fi \fi \fi \xa\g@addto@macro\xa\htmlize@output\xa{\toadd}% \egroup }% %Cedilla \def\@c{c}\def\@C{C}\def\@s{s}\def\@S{S}\def\@t{t}\def\@T{T}% \html@action@def\c#1{% \bgroup \def\test@i{#1}% \ifx\test@i\@c \def\toadd{\otherampersand ccedil\othersemicol}% \else \ifx\test@i\@C \def\toadd{\otherampersand Ccedil\othersemicol}% \else \ifx\test@i\@s \def\toadd{\otherampersand\otherhash351\othersemicol}% \else \ifx\test@i\@S \def\toadd{\otherampersand\otherhash350\othersemicol}% \else \ifx\test@i\@t \def\toadd{\otherampersand\otherhash355\othersemicol}% \else \ifx\test@i\@T \def\toadd{\otherampersand\otherhash354\othersemicol}% \else \def\toadd{\otherbackslash c\otherlbrace#1\otherrbrace}% \fi \fi \fi \fi \fi \fi \xa\g@addto@macro\xa\htmlize@output\xa{\toadd}% \egroup }% %Tilde over a, n, o {\catcode`|=3\relax \gdef\htmlize@tilde{A|N|O|a|n|o|}}% \html@action@def\~#1{% \ifinlist{#1}{\htmlize@tilde}% {\g@addto@macro\htmlize@output{\otherampersand#1tilde\othersemicol}}% {\xa\g@addto@macro\htmlize@output\xa{\string\~#1}}% }% % breve diacritics {\catcode`|=3\relax \gdef\htmlize@breve{A|G|U|a|g|u|}}% \def\@e{e}\def\@E{E}\def\@i{i}\def\@ii{\i}\def\@I{I}\def\@o{o}\def\@O{O}% \html@action@def\u#1{% \ifinlist{#1}{\htmlize@breve}% {\g@addto@macro\htmlize@output{\otherampersand#1breve\othersemicol}}% {% \bgroup \def\test@i{#1}% \ifx\test@i\@E \def\toadd{\otherampersand\otherhash276\othersemicol}% \else \ifx\test@i\@e \def\toadd{\otherampersand\otherhash277\othersemicol}% \else \ifx\test@i\@I \def\toadd{\otherampersand\otherhash300\othersemicol}% \else \ifx\test@i\@i \def\toadd{\otherampersand\otherhash301\othersemicol}% \else \ifx\test@i\@ii \def\toadd{\otherampersand\otherhash301\othersemicol}% \else \ifx\test@i\@O \def\toadd{\otherampersand\otherhash334\othersemicol}% \else \ifx\test@i\@o \def\toadd{\otherampersand\otherhash335\othersemicol}% \else \def\toadd{\otherbackslash u\otherlbrace#1\otherrbrace}% \fi \fi \fi \fi \fi \fi \fi \xa\g@addto@macro\xa\htmlize@output\xa{\toadd}% \egroup }% }% % caron diacritics {\catcode`|=3\relax \gdef\htmlize@caron{C|D|E|L|N|R|S|T|Z|c|d|e|l|n|r|s|t|z|}}% \html@action@def\v#1{% \ifinlist{#1}{\htmlize@caron}% {\g@addto@macro\htmlize@output{\otherampersand#1caron\othersemicol}}% {\xa\g@addto@macro\htmlize@output\xa{\string\v#1}}% }% % Ogonek diacritics {\catcode`|=3\relax \gdef\htmlize@ogonek{A|E|I|U|a|e|i|u|}}% \html@action@def\k#1{% \ifinlist{#1}{\htmlize@ogonek}% {\g@addto@macro\htmlize@output{\otherampersand#1ogon\othersemicol}}% {% \bgroup \def\test@i{#1}% \ifx\test@i\@O \def\toadd{\otherampersand\otherhash490\othersemicol}% \else \ifx\test@i\@o \def\toadd{\otherampersand\otherhash491\othersemicol}% \else \def\toadd{\otherbackslash k\otherlbrace#1\otherrbrace}% \fi \fi \xa\g@addto@macro\xa\htmlize@output\xa{\toadd}% \egroup }% }% % macron diacritics {\catcode`|=3\relax \gdef\htmlize@macron{A|E|I|O|U|a|e|i|o|u|}}% \def\@g{g}\def\@G{G}\def\@y{y}\def\@Y{Y}% \html@action@def\=#1{% \ifinlist{#1}{\htmlize@macron}% {\g@addto@macro\htmlize@output{\otherampersand#1macr\othersemicol}}% {% \bgroup \def\test@i{#1}% \ifx\test@i\@g \def\toadd{\otherampersand\otherhash7713\othersemicol}% \else \ifx\test@i\@G \def\toadd{\otherampersand\otherhash7712\othersemicol}% \else \ifx\test@i\@y \def\toadd{\otherampersand\otherhash563\othersemicol}% \else \ifx\test@i\@Y \def\toadd{\otherampersand\otherhash562\othersemicol}% \else \def\toadd{\otherbackslash =\otherlbrace#1\otherrbrace}% \fi \fi \fi \fi \xa\g@addto@macro\xa\htmlize@output\xa{\toadd}% \egroup }% }% % macron below diacritics \def\@b{b}\def\@B{B}\def\@d{d}\def\@D{D}\def\@k{k}\def\@K{K}\def\@l{l}% \def\@L{L}\def\@n{n}\def\@N{N}\def\@t{t}\def\@T{T}\def\@z{z}\def\@Z{Z}% \html@action@def\b#1{% \bgroup \def\test@i{#1}% \ifx\test@i\@b \def\toadd{\otherampersand\otherhash7687\othersemicol}% \else \ifx\test@i\@B \def\toadd{\otherampersand\otherhash7686\othersemicol}% \else \ifx\test@i\@d \def\toadd{\otherampersand\otherhash7695\othersemicol}% \else \ifx\test@i\@D \def\toadd{\otherampersand\otherhash7694\othersemicol}% \else \ifx\test@i\@k \def\toadd{\otherampersand\otherhash7733\othersemicol}% \else \ifx\test@i\@K \def\toadd{\otherampersand\otherhash7732\othersemicol}% \else \ifx\test@i\@l \def\toadd{\otherampersand\otherhash7739\othersemicol}% \else \ifx\test@i\@L \def\toadd{\otherampersand\otherhash7738\othersemicol}% \else \ifx\test@i\@n \def\toadd{\otherampersand\otherhash7753\othersemicol}% \else \ifx\test@i\@N \def\toadd{\otherampersand\otherhash7752\othersemicol}% \else \ifx\test@i\@r \def\toadd{\otherampersand\otherhash7775\othersemicol}% \else \ifx\test@i\@R \def\toadd{\otherampersand\otherhash7774\othersemicol}% \else \ifx\test@i\@t \def\toadd{\otherampersand\otherhash7791\othersemicol}% \else \ifx\test@i\@T \def\toadd{\otherampersand\otherhash7790\othersemicol}% \else \ifx\test@i\@z \def\toadd{\otherampersand\otherhash7829\othersemicol}% \else \ifx\test@i\@Z \def\toadd{\otherampersand\otherhash7828\othersemicol}% \else \def\toadd{\otherbackslash b\otherlbrace#1\otherrbrace}% \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \xa\g@addto@macro\xa\htmlize@output\xa{\toadd}% \egroup }% % Overdot diacritics {\catcode`|=3\relax \gdef\htmlize@dotabove{C|E|G|I|Z|c|e|g|z|}}% \def\@i{i}% \html@action@def\.#1{% \ifinlist{#1}{\htmlize@dotabove}% {\g@addto@macro\htmlize@output{\otherampersand#1dot\othersemicol}}% { \bgroup \def\test@i{#1}% \ifx\test@i\@i \def\toadd{i}% \else \def\toadd{\otherbackslash .\otherlbrace#1\otherrbrace}% \fi \xa\g@addto@macro\xa\htmlize@output\xa{\toadd}% \egroup }% }% % Underdot diacritics \def\@A{A}\def\@a{a}\def\@B{B}\def\@b{b}% \html@action@def\d#1{% \bgroup \def\test@i{#1}% \ifx\test@i\@a \def\toadd{\otherampersand\otherhash7841\othersemicol}% \else \ifx\test@i\@A \def\toadd{\otherampersand\otherhash7840\othersemicol}% \else \ifx\test@i\@b \def\toadd{\otherampersand\otherhash7685\othersemicol}% \else \ifx\test@i\@B \def\toadd{\otherampersand\otherhash7684\othersemicol}% \else \def\toadd{\otherbackslash d\otherlbrace#1\otherrbrace}% \fi \fi \fi \fi \xa\g@addto@macro\xa\htmlize@output\xa{\toadd}% \egroup }% % Overring {\catcode`|=3\relax \gdef\htmlize@ring{A|U|a|u|}}% \html@action@def\r#1{% \ifinlist{#1}{\htmlize@ring}% {\g@addto@macro\htmlize@output{\otherampersand#1ring\othersemicol}}% {\xa\g@addto@macro\htmlize@output\xa{\string\r#1}}% }% % \end{macrocode} % % \subsubsection{Command sequences for Expansion} % % First, commands defined by this package. % \begin{macrocode} \def\blank{\rule{1in}{0.5pt}}% % TODO: Make an optional argument for width? This wouldn't affect Moodle, % only the appearance in the PDF. It doesn't seem worth it. \html@def\blank{____________}% \htmlize@record@action\inlinemathrightdelim \htmlize@record@action\displaymathrightdelim % \end{macrocode} % Second, native \LaTeX\ commands. % \begin{macrocode} \html@def\emph#1{\HTMLtag{EM}#1\HTMLtag{/EM}}% \html@def\textbf#1{\HTMLtag{B}#1\HTMLtag{/B}}% \html@def\textit#1{\HTMLtag{I}#1\HTMLtag{/I}}% \html@def\textsc#1{\HTMLtag{SPAN STYLE="font-variant: small-caps;"}#1\HTMLtag{/SPAN}}% \html@def\textsuperscript#1{\HTMLtag{SUP}#1\HTMLtag{/SUP}}% \html@def\textsubscript#1{\HTMLtag{SUB}#1\HTMLtag{/SUB}}% \html@def\texttt#1{\HTMLtag{CODE}#1\HTMLtag{/CODE}}% \html@action@def\underline#1{% \moodle@ifmathmode{\g@addto@macro\htmlize@output{\string\underline{#1}}}% {\g@addto@macro\htmlize@output{#1}}% }% % \end{macrocode} % Third, popular \LaTeX\ commands from packages. % \begin{macrocode} \html@def\url#1{\HTMLtag{A href=\@dq #1\@dq}#1\HTMLtag{/A}}% url or hyperref \html@def\href#1#2{\HTMLtag{A href=\@dq #1\@dq}#2\HTMLtag{/A}}% hyperref \html@def\up#1{\HTMLtag{SUP}#1\HTMLtag{/SUP}}% \pkg{babel}, option \optn{french} \html@def\fup#1{\HTMLtag{SUP}#1\HTMLtag{/SUP}}% \pkg{babel}, option \optn{french} % \end{macrocode} % Fourth, \LaTeX\ commands for ligature and other glyphs. % \begin{macrocode} \html@def\aa{\å}% \html@def\AA{\Å}% \html@def\ae{\æ}% \html@def\AE{\Æ}% \html@def\dh{\ð}% \html@def\DH{\Ð}% \html@def\dj{\đ}% \html@def\DJ{\Đ}% \html@def\i{\ı}% \html@def\ij{\ij}% \html@def\IJ{\IJ}% \html@def\j{\ȷ}% \html@def\l{\ł}% \html@def\L{\Ł}% \html@def\ng{\ŋ}% \html@def\NG{\Ŋ}% \html@def\o{\ø}% \html@def\O{\Ø}% \html@def\oe{\œ}% \html@def\OE{\Œ}% \html@def\ss{\ß}% \html@def\SS{\&\#7838;}% \html@def\th{\þ}% \html@def\TH{\Þ}% % \end{macrocode} % Fifth, \LaTeX\ commands for horizontal spacing and line breaks. % In a number of situations, paragraph breaks translated into % |

    | would bring trouble in the \HTML\ code. Examples: % \begin{itemize} % \item fields of cloze subquestions % \item inside environments like |center|, |itemize|, or |enumerate|. % \end{itemize} % \begin{macrocode} \html@def\space{ }% \html@def\textvisiblespace{\␣}% \html@def\newline{\HTMLtag{BR/}}% \html@def\par{\HTMLtag{BR/}}% % \end{macrocode} % Sixth, \LaTeX\ commands for various symbols. % \begin{macrocode} \html@def\textbackslash{\&\#92;}% \html@def\_{\&\#95;}% \html@def\textquestiondown{\¿}% \html@def\textexclamdown{\¡}% \html@def\euro{\€}% \html@def\texteuro{\€}% \html@def\S{\§}% % \end{macrocode} % Seventh, \LaTeX\ commands for various quotation marks. % \begin{macrocode} \html@def\textquoteleft{\‘}% \html@def\textquoteright{\’}% \html@def\textquotedblleft{\“}% \html@def\textquotedblright{\”}% \html@def\guilsinglleft{\‹}% \html@def\guilsinglright{\›}% \html@def\guillemotleft{\«}% \html@def\guillemotright{\»}% \html@def\quotesinglbase{\‚}% \html@def\quotedblbase{\„}% \html@def\flq{\‹}% \html@def\frq{\›}% \html@def\flqq{\«}% \html@def\frqq{\»}% \html@def\og{\«\&\#8239;}% \html@def\fg{\&\#8239;\»}% \html@def\glq{\‚}% \html@def\grq{\‘}% \html@def\glqq{\„}% \html@def\grqq{\“}% \html@def\dq{\"}% % \end{macrocode} % % \subsubsection{Passing Code to \XML\ Only} % Users may want to include pieces of \HTML\ code to the \XML\ file only. % When producing the traditional output, the optional argument, empty % by default, is used. % \begin{macrocode} \newcommand\htmlonly[2][]{#1}% % \end{macrocode} % When producing the \XML\ file, the mandatory argument is passed as-is. % \begin{macrocode} \html@action@newcommand{htmlonly}[2][]{% \g@addto@macro\htmlize@output{#2}% }% % \end{macrocode} % % \subsection{Graphics via {\ttfamily\string\includegraphics}} % % \subsubsection{Finding Media Files} % The following code is adapted from the command |\Ginclude@graphics| as % found in \filenm{graphics.sty}. % Calling |\moodle@media@find|\marg{filename} looks for the file the % same way |\includegraphics| does, with or without extension provided, % in the current folder and in folders specified with |\graphicspath{}|. % The allowed extensions and their relative priorities can be set % via |\DeclareGraphicsExtensions{}|. % The outcome is that the macros |\moodle@media@base| and |\moodle@media@ext| % are set with the basename, including path, and extension, respectively. % % \begin{macrocode} \AtEndPreamble{% \@ifpackageloaded{graphics}{% \@ifpackagelater{graphics}{2019/10/08 v1.3c}{}% {\PackageError{moodle}{`moodle' is made to interact with the `graphics'\MessageBreak package not older than 2019/10/08.}\@eha\endinput}% }{}% }% \def\moodle@media@find#1{% \ifx\detokenize\@undefined\else \edef\Gin@extensions{\detokenize\expandafter{\Gin@extensions}}% \fi \begingroup \let\input@path\Ginput@path \set@curr@file{#1}% \expandafter\filename@parse\expandafter{\@curr@file}% \ifx\filename@ext\Gin@gzext \expandafter\filename@parse\expandafter{\filename@base}% \ifx\filename@ext\relax \let\filename@ext\Gin@gzext \else \edef\Gin@ext{\Gin@ext\Gin@sepdefault\Gin@gzext}% \fi \fi \ifx\filename@ext\relax \@for\Gin@temp:=\Gin@extensions\do{% \ifx\Gin@ext\relax \Gin@getbase\Gin@temp \fi}% \else \Gin@getbase{\Gin@sepdefault\filename@ext}% \ifnum0% \ifx\Gin@ext\relax 1% \else \@ifundefined{Gin@rule@\Gin@ext}{1}{0}% \fi >0 \let\Gin@ext\relax \let\Gin@savedbase\filename@base \let\Gin@savedext\filename@ext \edef\filename@base{\filename@base\Gin@sepdefault\filename@ext}% \let\filename@ext\relax \@for\Gin@temp:=\Gin@extensions\do{% \ifx\Gin@ext\relax \Gin@getbase\Gin@temp \fi}% \ifx\Gin@ext\relax \let\filename@base\Gin@savedbase \let\filename@ext\Gin@savedext \fi \fi \ifx\Gin@ext\relax \@warning{File `#1' not found}% \def\Gin@base{\filename@area\filename@base}% \edef\Gin@ext{\Gin@sepdefault\filename@ext}% \fi \fi \ifx\Gin@ext\relax \@latex@error{File `#1' not found}% {I could not locate the file with any of these extensions:^^J% \Gin@extensions^^J\@ehc}% \else % begin modified part \xdef\moodle@media@base{\detokenize\xa{\Gin@base}}% \xdef\moodle@media@ext{\detokenize\xa{\Gin@ext}}% % end modified part \fi \endgroup } % \end{macrocode} % \begin{macrocode} %See % * https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types % * https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Containers \def\moodle@media@formats{} \newcommand{\DeclareMediaFormat}[3]{% \xdef\moodle@media@formats{\ifx\moodle@media@formats\empty\else\moodle@media@formats,\fi#1}% \csgdef{moodle@media@#1list}{#2}% \csgdef{moodle@media@#1mime}{#3}% }% % Image Formats \DeclareMediaFormat{PNG}{.png,.PNG}{image/png}% \DeclareMediaFormat{JPEG}{.jpg,.JPG,.jpeg,.JPEG}{image/jpeg}% \DeclareMediaFormat{SVG}{.svg,.SVG}{image/svg+xml}% \DeclareMediaFormat{GIF}{.gif}{image/gif}% % Audio Formats \DeclareMediaFormat{WAV}{.wav,.WAV}{audio/wave}% \DeclareMediaFormat{MP3}{.mp3,.MP3}{audio/mpeg}% \DeclareMediaFormat{OGG}{.ogg,.opus,.og&}{audio/ogg}% %\DeclareMediaFormat{FLAC}{.flac,.FLAC}{audio/flac}% % Video Formats \DeclareMediaFormat{WEBM}{.webm,.webm}{video/webm}% \DeclareMediaFormat{MP4}{.mp4,.MP4,.m4v,.M4V}{video/mp4}% \DeclareMediaFormat{OGV}{.ogv,.OGV}{video/ogg}% % \end{macrocode} % \begin{macrocode} \def\moodle@media@mime@identify#1{% \edef\test@i{\detokenize\xa{#1}}% \let\moodle@media@mime@current\relax \edef\moodle@media@formats{\detokenize\xa{\moodle@media@formats}}% \@for\@format:=\moodle@media@formats\do{% \edef\@templist{\csname moodle@media@\@format list\endcsname}% \@for\@ext:=\@templist\do{% \ifx\moodle@media@mime@current\relax \edef\@ext{\detokenize\xa{\@ext}}% \ifx\test@i\@ext \message{<>^^J}% \xdef\moodle@media@mime@current{\csname moodle@media@\@format mime\endcsname}% \xdef\moodle@media@ext@current{#1}% \fi \fi }% }% } % \end{macrocode} % % \subsubsection{External program command lines} % We first set up commands for the external programs. % \begin{macrocode} \def\htmlize@setexecutable#1{% % Defines macro #1 to be #2 in a verbatim mode suitable for filenames \def\htmlize@executable@macro{#1}% \bgroup\catcode`\|=0\catcode`\\=12\relax% \htmlize@setexecutable@int } \def\htmlize@setexecutable@int#1{% \egroup \expandafter\def\htmlize@executable@macro{#1}% } \def\ghostscriptcommand{\htmlize@setexecutable\gs}% \def\baselxivcommand{\htmlize@setexecutable\baselxiv}% \def\imagemagickcommand{\htmlize@setexecutable\htmlize@imagemagick@convert}% \def\optipngcommand{\htmlize@setexecutable\optipng}% \def\PDFtoSVGcommand{\htmlize@setexecutable\PDFtoSVG}% \def\SVGtoPDFcommand{\htmlize@setexecutable\SVGtoPDF}% \def\optiSVGcommand{\htmlize@setexecutable\optiSVG}% \def\DeleteFilecommand{\htmlize@setexecutable\DeleteFiles}% \def\MoveFilecommand{\htmlize@setexecutable\MoveFiles}% \def\DevNullcommand{\htmlize@setexecutable\DevNull}% \ifwindows% \ghostscriptcommand{gswin64c.exe -dBATCH -dNOPAUSE -sDEVICE=pngalpha}% \baselxivcommand{certutil}% % Uses scour from inkscape default installation % The \Inkscape\bin directory has to be in the users path and provides both: % {inkscape,python}.exe the scour-Package which is found by python in Inkscape\lib\python3.x\site-packages\ \optiSVGcommand{python -m scour.scour -q --enable-id-stripping --enable-comment-stripping --shorten-ids --indent=none --remove-descriptive-elements}% \DeleteFilecommand{del}% \MoveFilecommand{move}% \DevNullcommand{NUL}% \imagemagickcommand{magick -colorspace RGB}% \else% \ghostscriptcommand{gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha}% \baselxivcommand{base64}% \optiSVGcommand{scour -q --enable-id-stripping --enable-comment-stripping --shorten-ids --indent=none --remove-descriptive-elements}% \DeleteFilecommand{rm -f}% \MoveFilecommand{mv}% \DevNullcommand{/dev/null}% \imagemagickcommand{convert -colorspace RGB}% \fi% \optipngcommand{optipng -clobber -strip all -quiet}% \PDFtoSVGcommand{inkscape --export-type=svg --export-area-page --vacuum-defs}%--pdf-poppler % remove the "--pdf-poppler" import option if you want to preserve text (avoid conversion to path) \SVGtoPDFcommand{inkscape --export-type=pdf --export-area-page}% % \end{macrocode} % % \subsubsection{Conversion and inclusion of non-native formats} % \begin{macrocode} \AtEndPreamble{% \@ifpackageloaded{graphics}{% \def\@firstofthree#1#2#3{#1}% \def\@secondofthree#1#2#3{#2}% \newcommand{\DeclareGraphicsAlien}[3]{% \edef\Gin@extensions{\Gin@extensions,#1}% \DeclareGraphicsRule{#1}{\@gobble#1}{#1}{}% \csdef{Gread@\@gobble#1}##1{% \edef\SourceFile{\Gin@base\Gin@ext}% \edef\Gin@base{\Gin@base-\@gobble#1-converted-to}% \edef\Gin@ext{#2}% \edef\OutputFile{\Gin@base\Gin@ext}% \edef\targetfmt{\expandafter\expandafter\expandafter \@firstofthree\csname Gin@rule@\Gin@ext\endcsname\relax}% \edef\targetext{\expandafter\expandafter\expandafter \@secondofthree\csname Gin@rule@\Gin@ext\endcsname\relax}% \IfFileExists{\OutputFile}{}{\ShellEscape{#3}}% \csletcs{Ginclude@\@gobble#1}{Ginclude@\targetfmt}% \csname Gread@\targetfmt\endcsname{\Gin@base\targetext}% }% }% % Support for \GIF\ files: passed as-is in \XML\ but converted in \PNG\ for PDF output. % In case the \GIF\ is animated, we pick up the first frame in this conversion. % While the picture will be animated after Moodle import, it will not be in the PDF % output, whatever the viewer is. \DeclareGraphicsAlien{.gif}{.png}{\htmlize@imagemagick@convert\otherspace \SourceFile[0]\otherspace \OutputFile}% }{ \newcommand\includegraphics[2][]{\PackageError{moodle}{"\string\includegraphics" is not defined}% {Add "\string\usepackage{graphicx}" to you preamble.}}{}%}% }% }% % \end{macrocode} % \subsubsection{Graphics key-handling} % Next, we get ready to handle keys like |height=4cm| or |width=3cm| or |ppi=72|. % \begin{macrocode} \define@cmdkeys{moodle@includegraphics}[moodle@graphics@]{ppi} \define@cmdkey{moodle}[moodle@graphics@]{ppi}{}% This is so the ppi key can be set at the document, quiz, or question level. \define@cmdkeys{Gin}{ppi}% This is so the original \includegraphics will not object to a key of ppi. \setkeys{moodle@includegraphics}{ppi=103} \newdimen\moodle@graphics@temp@dimen \newcount\moodle@graphics@height@pixels \newcount\moodle@graphics@width@pixels \def\moodle@graphics@dimentopixels#1#2{% \moodle@graphics@temp@dimen=#2\relax \moodle@graphics@temp@dimen=0.013837\moodle@graphics@temp@dimen \xa\moodle@graphics@temp@dimen\xa=\moodle@graphics@ppi\moodle@graphics@temp@dimen #1=\moodle@graphics@temp@dimen \divide #1 by 65536\relax } \define@key{moodle@includegraphics}{height}[]{% \moodle@graphics@dimentopixels{\moodle@graphics@height@pixels}{#1}% } \define@key{moodle@includegraphics}{width}[]{% \moodle@graphics@dimentopixels{\moodle@graphics@width@pixels}{#1}% } \setkeys{moodle@includegraphics}{height=0pt,width=0pt} % \end{macrocode} % % \subsubsection{Graphics conversion to HTML} % If the |tikz| option is loaded, we define the |embedaspict| command. % Furthermore, |includegraphics| is packed into a TikZ node. % This allows externalization with regular options for |includegraphics|. % Otherwise, |includegraphics| is redefined with a limited set of options supported. % % Option SVG % \begin{macrocode} \ifmoodle@svg \AtEndPreamble{% % Declaring \SVG\ to PDF conversion rule for includegraphics % \edef\Gin@extensions{\Gin@extensions,.svg,.SVG}% % \DeclareGraphicsRule{.svg}{pdf}{.pdf}{% % `\SVGtoPDF\otherspace '#1' \noexpand\Gin@base-svg-converted-to.pdf}% % \DeclareGraphicsRule{.SVG}{pdf}{.pdf}{% % `\SVGtoPDF\otherspace '#1' \noexpand\Gin@base-SVG-converted-to.pdf}% \DeclareGraphicsAlien{.svg}{.pdf}{% \SVGtoPDF\otherspace \SourceFile\otherspace -o \otherspace\OutputFile\otherspace 2>\DevNull}% \DeclareGraphicsAlien{.SVG}{.pdf}{% \SVGtoPDF\otherspace \SourceFile\otherspace -o \otherspace\OutputFile\otherspace 2>\DevNull}% }% \fi \def\moodle@checkconversionsuccess#1#2{% \IfFileExists{#1}{}{% \PackageError{moodle}{#2 failed}% {If the XML file is not of importance to you: use package option "draft"}% }% }% \ifmoodle@tikz \AfterEndPreamble{% %\htmlize@record@expand{\embedaspict}% \let\oldincludegraphics=\includegraphics % patching includegraphics to trigger externalization \renewcommand{\includegraphics}[2][]{% %\message{moodle.sty: Processing \string\includegraphics[#1]{#2} for HTML^^J}% \tikz{\node[inner sep=0pt]{\oldincludegraphics[#1]{#2}};}% }% % externalized images must be included with the regular command \pgfkeys{/pgf/images/include external/.code={\oldincludegraphics{#1}}}% \html@action@newcommand{includegraphics}[2][]{% \message{moodle.sty: Processing \string\includegraphics[#1]{#2} ^^J} \global\advance\numpicturesread by 1\relax \edef\htmlize@imagetag{}% \xa\g@addto@macro\xa\htmlize@output\xa{\htmlize@imagetag}% }% }% \else \html@action@newcommand{includegraphics}[2][]{% \bgroup% The grouping is to localize the changes caused by \setkeys. \message{moodle.sty: Processing \string\includegraphics[#1]{#2} for HTML...^^J} \setkeys*{moodle@includegraphics}{#1}% % Height or width should be given in TeX dimensions like cm or pt or in, % and are converted to pixels for web use using the ppi key. % TODO: Can we modify \includegraphics to accept height or width in % pixels? % TODO: What about \includegraphics[scale=0.7] ? % Other keys: keepaspectratio=true|false, angle (rotation), clip & trim % -> the package option 'tikz' offers a workaround for this \ifnum\moodle@graphics@height@pixels=0\relax \ifnum\moodle@graphics@width@pixels=0\relax % No size specified. Default to height of 200 pixels. \def\moodle@graphics@geometry{x200}% \def\moodle@graphics@htmlgeometry{}% \else % Width only specified. \edef\moodle@graphics@geometry{\number\moodle@graphics@width@pixels}% \edef\moodle@graphics@htmlgeometry{width=\number\moodle@graphics@width@pixels}% \fi \else \ifnum\moodle@graphics@width@pixels=0\relax % Height only specified. The `x' is part of the syntax. \edef\moodle@graphics@geometry{x\number\moodle@graphics@height@pixels}% \edef\moodle@graphics@htmlgeometry{height=\number\moodle@graphics@height@pixels}% \else % Height and width both specified. The `!' is part of the syntax. \edef\moodle@graphics@geometry{\number\moodle@graphics@width@pixels x\number\moodle@graphics@height@pixels!}% \edef\moodle@graphics@htmlgeometry{width=\number\moodle@graphics@width@pixels\otherspace height=\number\moodle@graphics@height@pixels}% \fi \fi %Look for the file, even if no extension is provided \moodle@media@find{#2}% %\message{<<\moodle@media@base>>^^J} %\message{<<\moodle@media@ext>>^^J} %Try to identify corresponding MIME-type \moodle@media@mime@identify{\moodle@media@ext}% \ifx\moodle@media@mime@current\relax % conversion needed \edef\moodle@media@pdf{\detokenize{.pdf}}% \edef\moodle@media@ext{\detokenize\xa{\moodle@media@ext}}% \ifnum0\ifx\moodle@media@ext\moodle@media@pdf1\fi\ifmoodle@svg1\fi=11\relax% PDF file and \SVG\ option active \def\moodle@media@ext@current{-moodle.svg}% \edef\moodle@media@mime@current{\moodle@media@SVGmime}% \edef\cmdline{\PDFtoSVG\otherspace "\moodle@media@base\moodle@media@ext" -o "\moodle@media@base\moodle@media@ext@current" 2>\DevNull}% \message{moodle.sty: Converting '#2' to SVG...^^J}% \xa\ShellEscape\xa{\cmdline}% \moodle@checkconversionsuccess{\moodle@media@base\moodle@media@ext@current}{PDFtoSVG conversion}% %Next, optimize inline \ifwindows\else \edef\cmdline{\optiSVG < "\moodle@media@base\moodle@media@ext@current" > "\moodle@media@base.tmp.svg" && \MoveFiles\otherspace "\moodle@media@base.tmp.svg" "\moodle@media@base\moodle@media@ext@current"}% \message{moodle.sty: Optimizing '\moodle@media@base\moodle@media@ext@current'...^^J}% \xa\ShellEscape\xa{\cmdline}% \moodle@checkconversionsuccess{\moodle@media@base\moodle@media@ext@current}{SVG optimization}% \fi \else% call ImageMagick \def\moodle@media@ext@current{-moodle.png}% \def\moodle@media@mime@current{image/png}% \edef\cmdline{\htmlize@imagemagick@convert\otherspace "\moodle@media@base\moodle@media@ext" -resize \moodle@graphics@geometry\otherspace "\moodle@media@base\moodle@media@ext@current"}% \message{moodle.sty: Converting '#2' to PNG...^^J}% \xa\ShellEscape\xa{\cmdline}% \moodle@checkconversionsuccess{\moodle@media@base\moodle@media@ext@current}{ImageMagick conversion}% %Next, optimize inline \edef\cmdline{\optipng\otherspace "\moodle@media@base\moodle@media@ext@current"}% \message{moodle.sty: Optimizing '\moodle@media@base\moodle@media@ext@current'...^^J}% \xa\ShellEscape\xa{\cmdline}% \moodle@checkconversionsuccess{\moodle@media@base\moodle@media@ext@current}{PNG optimization}% \fi \fi %Next, convert the file to base64 encoding \ConvertToBaseLXIV{\moodle@media@base}{\moodle@media@ext@current}% %Now, save that base64 encoding in a TeX macro \def\moodle@newpic@baselxiv{}% \message{moodle.sty: Reading base64 file '\moodle@media@base.enc'...^^J}% \openin\baseLXIVdatafile="\moodle@media@base.enc"\relax \ifeof\baseLXIVdatafile \PackageError{moodle}{reading '\moodle@media@base.enc' failed}% {If the XML file is not of importance to you: use package option "draft"}% \else \savebaselxivdata@recursive \fi \closein\baseLXIVdatafile %Clean up files \ifx\moodle@media@ext@current\moodle@media@ext \ifwindows \ShellEscape{powershell.exe "del ""\moodle@media@base.enc"""}% \else \ShellEscape{\DeleteFiles\otherspace "\moodle@media@base.enc"}% \fi \else \ifwindows \ShellEscape{powershell.exe "del ""\moodle@media@base.enc"""}% \ShellEscape{powershell.exe "del ""\moodle@media@base\moodle@media@ext@current"""}% \else \ShellEscape{\DeleteFiles\otherspace "\moodle@media@base.enc" "\moodle@media@base\moodle@media@ext@current"}% \fi \fi \xa\global\xa\let\csname picbaselxiv@graphics@#2\endcsname=\moodle@newpic@baselxiv% \ifmoodle@pluginfile \edef\htmlize@imagetag{}% \xa\filename@parse\xa{\moodle@media@base}% \xdef\moodle@media@path{\filename@area}% \xdef\moodle@media@base{\filename@base}% \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{}% \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{\csname picbaselxiv@graphics@#2\endcsname}% \else \edef\htmlize@imagetag{}% \fi \xa\g@addto@macro\xa\htmlize@output\xa{\htmlize@imagetag}% \message{moodle.sty: tag inserted.^^J}% \egroup }% \fi % \end{macrocode} % This macro is in charge of throwing a system call to convert local files to base64. % \begin{macrocode} \def\ConvertToBaseLXIV#1#2{% \message{moodle.sty: Converting '#1#2' to base64...^^J}% \ConvertToBaseLXIV@int{#1}{#2} \xa\ShellEscape\xa{\cmdline}% \moodle@checkconversionsuccess{#1.enc}{Base64 conversion}% }% \ifwindows \def\ConvertToBaseLXIV@int#1#2{% \def\cmdline{\baselxiv\otherspace -encode "#1#2"\otherspace tmp.b64 && findstr /vbc:"---" tmp.b64 > "#1.enc" && powershell.exe "del tmp.b64"}% }% Starting from Windows 7, CertUtil is included by default. There should be no windows XP still running \else \ifmacosx \def\ConvertToBaseLXIV@int#1#2{% \def\cmdline{\baselxiv\otherspace -b 64 -i "#1#2"\otherspace -o "#1.enc"}% }% \else % Linux, Cygwin \def\ConvertToBaseLXIV@int#1#2{% \def\cmdline{\baselxiv\otherspace "#1#2"\otherspace > "#1.enc"}% }% base64 is part of coreutils, add "-w 64" to get exactly the previous behavior % \fi \fi % \end{macrocode} % The following code accomplishes the reading of an \filenm{.enc} file into memory. % It is also used by the \TikZ\ code below. % \begin{macrocode} \newread\baseLXIVdatafile \def\savebaselxivdata@recursive{% \ifeof\baseLXIVdatafile \let\baselxiv@next=\relax \else \read\baseLXIVdatafile to \datalinein %\message{<<\datalinein>>^^J} \ifx\datalinein\@moodle@par \let\baselxiv@next=\relax \else %We add tokens manually, rather than with \g@addto@macro, to save time. \xa\xa\xa\gdef\xa\xa\xa\moodle@newpic@baselxiv\xa\xa\xa{\xa\moodle@newpic@baselxiv\datalinein^^J}% \let\baselxiv@next=\savebaselxivdata@recursive \fi \fi \baselxiv@next } % \end{macrocode} % % \subsection{\TikZ\ Picture Handling} % If the user is not using the \TikZ\ package, there is no need to waste time % loading it. Without \TikZ\ loaded, however, many of the following commands % are undefined. % Our solution is to wait until |\AtBeginDocument| and then test whether % \TikZ\ is loaded. If so, we make the appropriate definitions. % \begin{macro}{TikZ} % \changes{v0.7}{2020/07/14}{Support \emph{tikz}\ command} % \begin{macrocode} \AtBeginDocument{ \ifx\tikzpicture\@undefined \moodle@tikzloadedfalse \else \moodle@tikzloadedtrue \fi \ifmoodle@draftmode \long\def\tikzifexternalizing#1#2{#2}% \else \ifmoodle@tikzloaded \usetikzlibrary{external}% \tikzexternalize% \tikzset{external/force remake}% \def\moodle@basename{\tikzexternalrealjob-tikztemp-\the\numconvertedpictures}% \ifmoodle@svg \def\TikzExportExtension{.svg}% \def\TikzExportMIME{image/svg+xml}% \ifpdfoutput% tex engines defaulting to PDF output (pdflatex, xelatex, lualatex) \def\ExportTikz{ \message{moodle.sty: Converting picture '\moodle@basename.pdf' to SVG...^^J}% \edef\cmdline{\PDFtoSVG\otherspace "\moodle@basename.pdf" -o "\moodle@basename\TikzExportExtension" 2>\DevNull}% \message{\cmdline} \xa\ShellEscape\xa{\cmdline}% \moodle@checkconversionsuccess{\moodle@basename\TikzExportExtension}{PDFtoSVG conversion}% }% \else % latex \def\ExportTikz{ \message{moodle.sty: Converting picture '\moodle@basename.ps' to SVG...^^J}% \edef\cmdline{\PDFtoSVG\otherspace "\moodle@basename.ps" -o "\moodle@basename\TikzExportExtension" 2>\DevNull}% \message{\cmdline} \xa\ShellEscape\xa{\cmdline}% \moodle@checkconversionsuccess{\moodle@basename\TikzExportExtension}{PStoSVG conversion}% }% \fi \ifwindows \def\OptimizeExport{ \message{moodle.sty: Optimizing '\moodle@basename.svg'...^^J}% \edef\cmdline{\optiSVG\otherspace < "\moodle@basename\TikzExportExtension" > "\moodle@basename.tmp.svg" && powershell.exe "move ""\moodle@basename.tmp.svg""" % """\moodle@basename\TikzExportExtension"""}% \message{\cmdline} \xa\ShellEscape\xa{\cmdline}% \moodle@checkconversionsuccess{\moodle@basename\TikzExportExtension}{SVG optimization}% }% \else \def\OptimizeExport{ \message{moodle.sty: Optimizing '\moodle@basename.svg'...^^J}% \edef\cmdline{\optiSVG\otherspace < "\moodle@basename\TikzExportExtension" > "\moodle@basename.tmp.svg" && \MoveFiles\otherspace "\moodle@basename.tmp.svg" "\moodle@basename\TikzExportExtension" }% \message{\cmdline} \xa\ShellEscape\xa{\cmdline}% \moodle@checkconversionsuccess{\moodle@basename\TikzExportExtension}{SVG optimization}% }% \fi \else \def\TikzExportExtension{.png}% \def\TikzExportMIME{image/png}% \ifpdfoutput% tex engines defaulting to PDF output (pdflatex, xelatex, lualatex) \def\ExportTikz{ \message{moodle.sty: Converting picture '\moodle@basename.pdf' to PNG...^^J}% \edef\gscmdline{\gs\otherspace -sOutputFile=\moodle@basename\TikzExportExtension\otherspace -r150 \moodle@basename.pdf}% \xa\ShellEscape\xa{\gscmdline}% \moodle@checkconversionsuccess{\moodle@basename\TikzExportExtension}{Ghostscript conversion}% }% \else % latex \def\ExportTikz{ \message{moodle.sty: Converting picture '\moodle@basename.ps' to PNG...^^J}% \edef\gscmdline{\gs\otherspace -sOutputFile=\moodle@basename\TikzExportExtension\otherspace -r150 \\moodle@basename.ps}% \xa\ShellEscape\xa{\gscmdline}% \moodle@checkconversionsuccess{\moodle@basename\TikzExportExtension}{Ghostscript conversion}% }% \fi \def\OptimizeExport{ \message{moodle.sty: Optimizing '\moodle@basename.png'...^^J}% \edef\cmdline{\optipng\otherspace \moodle@basename\TikzExportExtension}% \xa\ShellEscape\xa{\cmdline}% \moodle@checkconversionsuccess{\moodle@basename\TikzExportExtension}{PNG optimization}% }% \fi \let\moodle@oldtikzpicture=\tikzpicture %The following code lets us run things *before* the normal \begin{tikzpicture}. \renewenvironment{tikzpicture}{% \global\advance\numconvertedpictures by 1\relax %\jobnamewithsuffixtomacro{\htmlize@picbasename}{-tikztemp-\the\numconvertedpictures}% %\xa\tikzsetnextfilename\xa{\htmlize@picbasename}% \tikzsetnextfilename{\tikzexternalrealjob-tikztemp-\the\numconvertedpictures}% \moodle@oldtikzpicture% }{}% % However, the tikz externalize library does *not* run \end{tikzpicture}. % In order to run commands after the tikz picture is done compiling, we need to % use a hook into \tikzexternal@closeenvironments. \g@addto@macro{\tikzexternal@closeenvironments}{% \moodle@endtikzpicture@hook } % The following could replace calls to \pdftopng, \pngoptim and \pngtobaselxiv % \tikzset{external/system call/.add={}{; % gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha -sOutputFile="\image.png" -r150 "\image.pdf"; % optipng -clobber -strip all -quiet "\image.png"; % base64 "\image.png" > "\image.enc" % } % } % With the following mechanism, we could trigger something when the externalized images are included back. % \pgfkeys{/pgf/images/include external/.code={\pgfimage{#1}\@moodle@ifgeneratexml{\savebaselxivdata}{}}} % \def\moodle@endtikzpicture@hook{% \@moodle@ifgeneratexml{% \ExportTikz \OptimizeExport \ConvertToBaseLXIV{\moodle@basename}{\TikzExportExtension}% \IfFileExists{\moodle@basename.enc}{}{\PackageError{moodle}{Conversion failed}{Check your base64 conversion utiliy}}% \message{moodle.sty: Reading base64 file '\tikzexternalrealjob-tikztemp-\the\numconvertedpictures.enc'...^^J}% \savebaselxivdata \message{moodle.sty: base64 data saved.^^J}% }{}% } \ifmoodle@tikz \tikzset{external/optimize=false}% due to redefinition, includegraphics must not be optimized away \else \tikzset{external/optimize=true}% \tikzset{external/optimize command away={\VerbatimInput}{1}}% \fi % % The HTMLizer version of the tikzpicture environment, % which writes an tag to the \XML\ file. \htmlize@record@environment{tikzpicture}% \g@addto@macro\htmlize@activate@environments{% \let\tikzpicture\relax\let\endtikzpicture\relax \NewEnviron{tikzpicture}[1][]{% \global\advance\numpicturesread by 1\relax \ifmoodle@pluginfile \edef\htmlize@imagetag{}% \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{}% \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{\csname picbaselxiv@\the\numpicturesread\endcsname}% \else \edef\htmlize@imagetag{}% \fi \xa\g@addto@macro\xa\htmlize@output\xa{\htmlize@imagetag}% }[\htmlize@patchendenvironment]% }% \html@action@newcommand{tikz}[2][]{% % \message{>>> Processing \string\tikz[#1]{...} ^^J} \global\advance\numpicturesread by 1\relax \ifmoodle@pluginfile \edef\htmlize@imagetag{}% \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{}% \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{\csname picbaselxiv@\the\numpicturesread\endcsname}% \else \edef\htmlize@imagetag{}% \fi \xa\g@addto@macro\xa\htmlize@output\xa{\htmlize@imagetag}% }% \else %TikZ not loaded. Provide dummy definitions for commands. \long\def\tikzifexternalizing#1#2{#2}% \fi \fi \ifmoodle@tikz \tikzstyle{moodlepict}=[minimum height=1em,inner sep=0pt,execute at begin node={\begin{varwidth}{\linewidth}},execute at end node={\end{varwidth}}] \newcommand\embedaspict[1]{\tikz[baseline=-\the\dimexpr\fontdimen22\textfont2\relax]{\node[moodlepict]{\mbox{#1}};}} \htmlize@record@expand{\embedaspict} \fi } \newcount\numconvertedpictures \numconvertedpictures=0\relax \newcount\numpicturesread \numpicturesread=0\relax \def\savebaselxivdata{% \def\moodle@newpic@baselxiv{}% \openin\baseLXIVdatafile=\tikzexternalrealjob-tikztemp-\the\numconvertedpictures.enc\relax \ifeof\baseLXIVdatafile \PackageError{moodle}{reading '\moodle@media@base.enc' failed}% {If the XML file is not of importance to you: use package option "draft"}% \else \savebaselxivdata@recursive \fi \closein\baseLXIVdatafile \xa\global\xa\let\csname picbaselxiv@\the\numconvertedpictures\endcsname=\moodle@newpic@baselxiv% } \ifmoodle@tikz \ifmoodle@tikzloaded \PackageWarning{moodle}{With package option 'tikz', you should not load TikZ manually.}% \fi \RequirePackage{tikz}% \RequirePackage{varwidth}% for the command |embedaspict| \fi % \end{macrocode} % Finally, we clean up our mess by deleting the temporary PDF, \PNG, and ENC % files we created. % With XeTeX, we cannot clean pictures pdf's because they are actually included in the final pdf afterwards, by xdvipdfmx. % With LuaTeX, it looks like |\AtEndDocument| is too early to for this cleaning step. % \begin{macrocode} \AfterEndDocument{% \ifmoodle@tikzloaded \@moodle@ifgeneratexml{% \ifXeTeX % we must keep picture pdf's for subsequent linking (xdvipdfmx) \ifwindows \ShellEscape{powershell.exe "del * -include \tikzexternalrealjob-tikztemp-*.* -exclude *.pdf"}% \else \ShellEscape{find . -type f -name "\tikzexternalrealjob-tikztemp-*.*" -not -name "*.pdf" -delete}% \fi \else \ifwindows \ShellEscape{powershell.exe "del \tikzexternalrealjob-tikztemp-*.*"}% \else \ShellEscape{\DeleteFiles\otherspace \tikzexternalrealjob-tikztemp-*.*}% \fi \fi }{}% \fi } % \end{macrocode} % TODO: % * sizing options for TikZ pictures? %\end{macro} % % \subsection{Other Media} % Support for other media comes through the |\url|\marg{link} and |\href|\marg{link}\marg{text} % commands. % \begin{macrocode} \AtEndPreamble{% \@ifpackageloaded{hyperref}{% \let\oldhref\href \let\oldurl\url \def\moodle@hyper@readexternallink#1#2#3#4:#5:#6\\#7{% % 1) The link type (the string "link" in the cases I observed) % 2) The URL fragment (i.e. what comes after # in the end), % 3) the text replacement, % 4) the URL scheme (http, https, mailto, file, run etc), % 5) the URL details (in general, that is whole authority + path + query). % If the URL contains a column (specification of a password in userinfo or a % port in authority), we get here whatever comes before the first column (:) % 6) empty is URL contains no column. Otherwise, filled with whatever follows % a first column (:) after the scheme, % 7) the whole URL again (fragment removed). \def\filename@ext{}% \def\filename@area{}% \def\filename@base{}% \ifx\\#6\\% if ##6 is empty (the URL contains no column -> no scheme -> local) %\@hyper@linkfile file:#7\\{#3}{#2}{#7}% local file %Local file (##1|##2|##3|##4|##5|##6): ##7\par \filename@parse{#4}% \ConvertToBaseLXIV{\filename@area\filename@base}{.\filename@ext}% \else \ifx\\#4\\%if ##4 is empty (no scheme was specified -> local file) % %\@hyper@linkfile file:#7\\{#3}{#2}{#7}% Mac filename ? % Local file (Mac? ##1|##2|##3|##4|##5|##6): ##7\par \filename@parse{#4}% \ConvertToBaseLXIV{\filename@area\filename@base}{.\filename@ext}% \else \def\@pdftempa{#4}% \ifx\@pdftempa\@pdftempwordfile% scheme is "file:" % %\@hyper@linkfile#7\\{#3}{#2}{#7}% file % Local file (no column ##1|##2|##3|##4|##5|##6): ##7\par \filename@parse{#5}% \ConvertToBaseLXIV{\filename@area\filename@base}{.\filename@ext}% \else \ifx\@pdftempa\@pdftempwordrun% scheme is "run:" \ifHy@pdfa \Hy@Error{% PDF/A: Launch action is prohibited% }\@ehc \begingroup \leavevmode % ##2% \endgroup \else% not in PDF/A mode -> run is allowed %\@hyper@launch#7\\{#3}{#2}% run local file % Run local file (##1|##2|##3|##4|##5|##6): ##7\par \filename@parse{#5}% \ConvertToBaseLXIV{\filename@area\filename@base}{.\filename@ext}% \fi \else% scheme is neither "file" nor "run", assuming it is a web protocol %\hyper@linkurl{#3}{#7\ifx\\#2\\\else\hyper@hash#2\fi}% URL % URL (##1|##2|##3|##4|##5|##6): ##7\par \filename@parse{#7}% \fi \fi \fi \fi \xdef\moodle@media@ext{.\filename@ext}% \xdef\moodle@media@base{\filename@area\filename@base}% }% % \html@action@newcommand{href}[3][]{% % \bgroup% The grouping is to localize the changes caused by \setkeys. % \message{moodle.sty: Processing \string\href[#1]{#2}{#3} for HTML...^^J}% % the following macro is a modified version of hyperref's |\hyper@readexternallink| % \let\@hyper@readexternallink\moodle@hyper@readexternallink % \oldhref[#1]{#2}{#3}% %\message{<<\moodle@media@base>>^^J} %\message{<<\moodle@media@ext>>^^J} %Try to identify corresponding MIME-type % \moodle@media@mime@identify{\moodle@media@ext}% %\edef\moodle@media@mime@current{\detokenize\xa{\moodle@media@mime@current}}% % \xa\message\xa{moodle.sty: \moodle@media@mime@current^^J}% % \ifx\moodle@media@mime@current\relax % \xa\g@addto@macro\xa\htmlize@output\xa{#3}% % \message{moodle.sty: tag inserted.^^J}% % \else % \filename@parse{\moodle@media@mime@current}% % \def\@tmp{audio/} % \ifx\filename@area\@tmp % \IfFileExists{\moodle@media@base.enc}{% % \def\moodle@newpic@baselxiv{}% % \openin\baseLXIVdatafile=\moodle@media@base.enc\relax % \savebaselxivdata@recursive % \closein\baseLXIVdatafile % \xa\g@addto@macro\xa\htmlize@output\xa{}% % }{% % \xa\g@addto@macro\xa\htmlize@output\xa{}% % }% % \message{moodle.sty: #1}% % \message{moodle.sty: tag inserted.^^J}% % \egroup % }% }{}% }% % \end{macrocode} % % \subsection{Verbatim Code} % % We start by defining a macro to parameter a style for code box display in Moodle % \begin{macrocode} \def\xmlDisplayVerbatimBox{border-top: thin solid; border-bottom: thin solid}% % \end{macrocode} % Then we set a macro to escape some characters that would not play well with \HTML. % \begin{macrocode} \begingroup \catcode`\<=\active\relax \catcode`\>=\active\relax \catcode`\"=\active\relax \catcode`\'=\active\relax \catcode`\&=\active\relax \gdef\moodle@HackTML{% \catcode`\<=\active\relax \catcode`\>=\active\relax \catcode`\"=\active\relax \catcode`\'=\active\relax \catcode`\&=\active\relax \gdef<{\otherampersand lt;}% \gdef>{\otherampersand gt;}% \gdef"{\otherampersand quot;}% \gdef'{\otherampersand apos;}% \gdef&{\otherampersand amp;}% }% \endgroup % \end{macrocode} % First, let us handle |\verbatiminput| from the `verbatim' package % \begin{macrocode} \html@action@def\verbatiminput#1{% \message{moodle.sty: Processing \string\verbatiminput{#1} for HTML ^^J}% \g@addto@macro\htmlize@output{

    }%
      %%%%%%%%%%%%%% from verbatim %%%%%%%%%%%%%%%%%
      \@bsphack
      \let\do\@makeother\dospecials
      \catcode`\^^M\active
      \moodle@HackTML
      \def\verbatim@processline{\xa\g@addto@macro\xa\htmlize@output\xa{\the\verbatim@line
    }} \verbatim@readfile{#1}% \@esphack %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \g@addto@macro\htmlize@output{
    }% }% % \end{macrocode} % Second, we deal with |\VerbatimInput| from `fancyvrb' or `fvextra' % \begin{macrocode} \@ifpackageloaded{minted}{\PackageError{moodle}{'moodle' should be loaded before 'minted'.}% {'moodle' loads 'fancybox' which, unfortunately, redefines verbatim commands.}}{\relax}% \@ifpackageloaded{fvextra}{\PackageError{moodle}{'moodle' should be loaded before 'fvextra'.}% {'moodle' loads 'fancybox' which, unfortunately, redefines verbatim commands.}}{\relax}% \@ifpackageloaded{fancyvrb}{\PackageError{moodle}{'moodle' should be loaded before 'fancyvrb'.}% {'moodle' loads 'fancybox' which, unfortunately, redefines verbatim commands.}}{\relax}% \def\moodle@FV#1{% \html@action@newcommand{#1}[2][]{% \message{moodle.sty: Processing \@backslashchar#1[##1]{##2} for HTML ^^J}% \def\FV@KeyValues{##1}% \FV@UseKeyValues% import options defined in #1 \def\FV@Input####1{ \immediate\openin\FV@InFile ####1\relax \ifeof\FV@InFile \FV@Error{No verbatim file ####1}\FV@eha \immediate\closein\FV@InFile \else \FV@CatCodes \moodle@HackTML \expandafter\FV@@Input \fi}% \moodle@VerbatimInput{##2}% }% } \moodle@FV{VerbatimInput}% \moodle@FV{LVerbatimInput}% \moodle@FV{BVerbatimInput}% \def\moodle@VerbatimInput#1{% \g@addto@macro\htmlize@output{
    }%
      %%%%%%%% using material from fancyvrb and fvextra  %%%%%%%%
      %\begingroup
      \def\moodle@verbatim@addlinenumber##1{%
        \g@addto@macro\htmlize@output{}%
        \if@FV@NumberBlankLines
          \xa\g@addto@macro\xa\htmlize@output\xa{\the\c@FancyVerbLine}%
        \else
          \ifx\FV@Line\empty
            \xa\g@addto@macro\xa\htmlize@output\xa{\otherampersand nbsp;}%
          \else
            \xa\g@addto@macro\xa\htmlize@output\xa{\the\c@FancyVerbLine}%
          \fi
        \fi
      }
      % redefine the ProcessLine routine ('fancyvrb' and 'fvextra') for \XML\ output
      \def\FV@ProcessLine##1{%
        \ifcsname FV@HighlightLine:\number\c@FancyVerbLine\endcsname
          \xdef\moodle@FV@tagB{}% fvextra triggered highlighting for this line
          \xdef\moodle@FV@tagE{}%
        \else
          \xdef\moodle@FV@tagB{}% no highlighting
          \xdef\moodle@FV@tagE{}%
        \fi
        \catcode`\`=12%
        \def\FV@Line{##1}%
        \ifx\FV@LeftListNumber\relax
    
        \else% line numbers displayed on the left side
          \moodle@verbatim@addlinenumber{text-align: right}%
        \fi
        \xa\g@addto@macro\xa\htmlize@output\xa{\moodle@FV@tagB}%
        \xa\g@addto@macro\xa\htmlize@output\xa{\FV@Line}%
        \xa\g@addto@macro\xa\htmlize@output\xa{\moodle@FV@tagE}%
        \ifx\FV@RightListNumber\relax\else% line numbers on the right side
          \moodle@verbatim@addlinenumber{text-align: left; float: right}%
        \fi
        \g@addto@macro\htmlize@output{
    }%linebreak } \global\FV@CodeLineNo\z@% reset codeline counter \frenchspacing% Cancels special punctuation spacing. \FV@DefineWhiteSpace \def\FV@Space{\space} \FV@DefineTabOut% replace tabs with a series a whitespaces \ifdefined\FV@HighlightLinesPrep \FV@HighlightLinesPrep% prepare highlighting if 'fvextra' is loaded \fi \FV@Input{#1}% %\endgroup %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \g@addto@macro\htmlize@output{
    }% }% \AtEndPreamble{% \@ifpackageloaded{fancyvrb}{% % custom settings for display \fvset{frame=lines,label={[Beginning of code]End of code},framesep=3mm,numbersep=9pt}% }{\relax}% } % \end{macrocode} % Third, we patch `minted' so that it also calls pygmentize to generate \HTML\ code. % \begin{macrocode} \AtEndPreamble{% this definition should prevail because `minted' gets loaded after `moodle' \@ifpackageloaded{minted}{% \newcounter{moodle@pygmentizecounter}% \@ifundefined{minted@defstyle}{% compatibility with minted prior to 2021/12/24 v2.6 \let\minted@defstyle=\minted@checkstyle% }{}% \renewcommand{\minted@pygmentize}[2][\minted@outputdir\minted@jobname.pyg]{% \minted@defstyle{\minted@get@opt{style}{default}}% \stepcounter{minted@pygmentizecounter}% \ifthenelse{\equal{\minted@get@opt{autogobble}{false}}{true}}% {\def\minted@codefile{\minted@outputdir\minted@jobname.pyg}}% {\def\minted@codefile{#1}}% \ifthenelse{\boolean{minted@isinline}}% {\def\minted@optlistcl@inlines{% \minted@optlistcl@g@i \csname minted@optlistcl@lang\minted@lang @i\endcsname}}% {\let\minted@optlistcl@inlines\@empty}% \def\minted@cmdtemplate##1##2{% \ifminted@kpsewhich \ifwindows \detokenize{for /f "usebackq tokens=*"}\space\@percentchar\detokenize{a in (`kpsewhich}\space\minted@codefile\detokenize{`) do}\space \fi \fi \MintedPygmentize\space -l #2 -f ##1 -F tokenmerge \minted@optlistcl@g \csname minted@optlistcl@lang\minted@lang\endcsname \minted@optlistcl@inlines \minted@optlistcl@cmd -o \minted@outputdir##2\space \ifminted@kpsewhich \ifwindows \@percentchar\detokenize{a}% \else \detokenize{`}kpsewhich \minted@codefile\space \detokenize{||} \minted@codefile\detokenize{`}% \fi \else \minted@codefile \fi}% \def\minted@cmd{\minted@cmdtemplate{latex -P commandprefix=PYG}{\minted@infile}} % For debugging, uncomment: %%%% %\immediate\typeout{\minted@cmd}% % %%%% \def\minted@cmdHTML{\minted@cmdtemplate{html -P noclasses -P nowrap -P hl_lines="\FV@HighlightLinesList" -P style="\minted@get@opt{style}{default}"}{\csname minted@infileHTML\the\c@minted@pygmentizecounter\endcsname}}% \def\minted@cmdPNG{\minted@cmdtemplate{png -P line_numbers=True}{\minted@infilePNG}}% \def\minted@cmdSVG{\minted@cmdtemplate{svg -P linenos=True}{\minted@infileSVG}}% \ifthenelse{\boolean{minted@cache}}% {% \ifminted@frozencache \else \ifx\XeTeXinterchartoks\minted@undefined \ifthenelse{\equal{\minted@get@opt{autogobble}{false}}{true}}% {\edef\minted@hash{\pdf@filemdfivesum{#1}% \pdf@mdfivesum{\minted@cmd autogobble(\ifx\FancyVerbStartNum\z@ 0\else\FancyVerbStartNum\fi-\ifx\FancyVerbStopNum\z@ 0\else\FancyVerbStopNum\fi)}}}% {\edef\minted@hash{\pdf@filemdfivesum{#1}% \pdf@mdfivesum{\minted@cmd}}}% \else \ifx\mdfivesum\minted@undefined \immediate\openout\minted@code\minted@jobname.mintedcmd\relax \immediate\write\minted@code{\minted@cmd}% \ifthenelse{\equal{\minted@get@opt{autogobble}{false}}{true}}% {\immediate\write\minted@code{autogobble(\ifx\FancyVerbStartNum\z@ 0\else\FancyVerbStartNum\fi-\ifx\FancyVerbStopNum\z@ 0\else\FancyVerbStopNum\fi)}}{}% \immediate\closeout\minted@code \edef\minted@argone@esc{#1}% \StrSubstitute{\minted@argone@esc}{\@backslashchar}{\@backslashchar\@backslashchar}[\minted@argone@esc]% \StrSubstitute{\minted@argone@esc}{"}{\@backslashchar"}[\minted@argone@esc]% \edef\minted@tmpfname@esc{\minted@outputdir\minted@jobname}% \StrSubstitute{\minted@tmpfname@esc}{\@backslashchar}{\@backslashchar\@backslashchar}[\minted@tmpfname@esc]% \StrSubstitute{\minted@tmpfname@esc}{"}{\@backslashchar"}[\minted@tmpfname@esc]% %Cheating a little here by using ASCII codes to write `{` and `}` %in the Python code \def\minted@hashcmd{% \detokenize{python -c "import hashlib; import os; hasher = hashlib.sha1(); f = open(os.path.expanduser(os.path.expandvars(\"}\minted@tmpfname@esc.mintedcmd\detokenize{\")), \"rb\"); hasher.update(f.read()); f.close(); f = open(os.path.expanduser(os.path.expandvars(\"}\minted@argone@esc\detokenize{\")), \"rb\"); hasher.update(f.read()); f.close(); f = open(os.path.expanduser(os.path.expandvars(\"}\minted@tmpfname@esc.mintedmd5\detokenize{\")), \"w\"); macro = \"\\edef\\minted@hash\" + chr(123) + hasher.hexdigest() + chr(125) + \"\"; f.write(\"\\makeatletter\" + macro + \"\\makeatother\\endinput\n\"); f.close();"}}% \ShellEscape{\minted@hashcmd}% \minted@input{\minted@outputdir\minted@jobname.mintedmd5}% \else \ifthenelse{\equal{\minted@get@opt{autogobble}{false}}{true}}% {\edef\minted@hash{\mdfivesum file {#1}% \mdfivesum{\minted@cmd autogobble(\ifx\FancyVerbStartNum\z@ 0\else\FancyVerbStartNum\fi-\ifx\FancyVerbStopNum\z@ 0\else\FancyVerbStopNum\fi)}}}% {\edef\minted@hash{\mdfivesum file {#1}% \mdfivesum{\minted@cmd}}}% \fi \fi \edef\minted@infile{\minted@cachedir/\minted@hash.pygtex}% \edef\minted@temp@infileHTML{\minted@cachedir/\minted@hash.html}% \global\cslet{minted@infileHTML\the\c@minted@pygmentizecounter}{\minted@temp@infileHTML}% %\global\edef\minted@infilePNG{\minted@cachedir/\minted@hash.png}% %\global\edef\minted@infileSVG{\minted@cachedir/\minted@hash.svg}% \IfFileExists{\minted@infile}{}{% \ifthenelse{\equal{\minted@get@opt{autogobble}{false}}{true}}{% \minted@autogobble{#1}}{}% \ShellEscape{\minted@cmd}% \ShellEscape{\minted@cmdHTML}% %\ShellEscape{\minted@cmdPNG}% %\ShellEscape{\minted@cmdSVG}% }% \fi \ifthenelse{\boolean{minted@finalizecache}}% {% \edef\minted@cachefilename{listing\arabic{minted@pygmentizecounter}.pygtex}% \edef\minted@actualinfile{\minted@cachedir/\minted@cachefilename}% \ifwindows \StrSubstitute{\minted@infile}{/}{\@backslashchar}[\minted@infile@windows] \StrSubstitute{\minted@actualinfile}{/}{\@backslashchar}[\minted@actualinfile@windows] \ShellEscape{move /y \minted@outputdir\minted@infile@windows\space\minted@outputdir\minted@actualinfile@windows}% \else \ShellEscape{mv -f \minted@outputdir\minted@infile\space\minted@outputdir\minted@actualinfile}% \fi \let\minted@infile\minted@actualinfile \expandafter\minted@addcachefile\expandafter{\minted@cachefilename}% }% {\ifthenelse{\boolean{minted@frozencache}}% {% \edef\minted@cachefilename{listing\arabic{minted@pygmentizecounter}.pygtex}% \edef\minted@infile{\minted@cachedir/\minted@cachefilename}% \expandafter\minted@addcachefile\expandafter{\minted@cachefilename}}% {\expandafter\minted@addcachefile\expandafter{\minted@hash.pygtex}}% }% \minted@inputpyg}% {% \ifthenelse{\equal{\minted@get@opt{autogobble}{false}}{true}}{% \minted@autogobble{#1}}{}% \ShellEscape{\minted@cmd}% \ShellEscape{\minted@cmdHTML}% %\ShellEscape{\minted@cmdPNG}% %\ShellEscape{\minted@cmdSVG}% \minted@inputpyg}% }% }{}% }% \html@action@newcommand{inputminted}[3][]{% \message{moodle.sty: Processing \string\inputminted[#1]{#2}{#3} for HTML ^^J}% % arguments #2 and #3 are thrown away: the job is done previously by minted when % calling pygmentize. The file |\minted@infileHTML| generated with our hack will be used. % Since minted is based upon `fvextra' the macro |\moodle@VerbatimInput| works here. \minted@configlang{#2}% grab options set for this specific language \setkeys{minted@opt@cmd}{#1}% grab options in #1 \minted@fvset% import options \stepcounter{moodle@pygmentizecounter} \xa\moodle@VerbatimInput\xa{\csname minted@infileHTML\the\c@moodle@pygmentizecounter\endcsname}% }% % \end{macrocode} % % \subsection{Internationalization} % Here is an attempt to internationalize the PDF typesetting, relying on % the package 'translations'. % \begin{macrocode} \AtEndPreamble{% \@ifpackageloaded{translator}{\moodle@internationaltrue}{}% \@ifpackageloaded{translations}{\moodle@internationaltrue}{}% % polyglossia "fakes" babel \@ifpackageloaded{polyglossia}{% \moodle@internationaltrue % The following is commented because \xpg@bloaded is set very late and must be expanded %\PassOptionsToPackage{\xpg@bloaded}{translator} }{ \@ifpackageloaded{babel}{% \moodle@internationaltrue % The following is commented because some languages of babel, % like lithuanian, are unknown to translator. Instead we % copied the aliases below. %\PassOptionsToPackage{\bbl@loaded}{translator}% }{}% }% \ifmoodle@international % By default, we load and rely on "translator". % The package is simple and has limited dependencies. % Since we borrow the syntax of "translations", % the switch is easy: just "\usepackage{translations}" % in the preamble. %\RequirePackage{translations}% \@ifpackageloaded{translations}{}{% \RequirePackage{translator}% % Borrow the syntax from 'translations' \newcommand\DeclareTranslation[3]{\deftranslation[to=#1]{#2}{#3}}% \newcommand\DeclareTranslationFallback[2]{\deftranslation[to=fallback]{#1}{#2}}% \let\GetTranslation=\translate % Set a fall-back if a translation is unknown (usually English, see below) \languagepath{\languagename,fallback}% % Set aliases (most of them taken directly from translator.sty) \languagealias{afrikaans} {Afrikaans,Dutch}% \languagealias{american} {AmericanEnglish,English}% \languagealias{austrian} {Austrian1997,Austrian,German1997,German}% \languagealias{brazil} {Brazilian,Portuguese}% \languagealias{brazilian} {Brazilian,Portuguese}% \languagealias{british} {BritishEnglish,English}% \languagealias{catalan} {Catalan}% unknown to translator \languagealias{canadian} {Canadian,English}% \languagealias{canadien} {Canadien,French}% \languagealias{croatian} {Croatian}% \languagealias{czech} {Czech}% \languagealias{danish} {Danish}% \languagealias{dutch} {Dutch}% \languagealias{english} {English}% \languagealias{estonian} {Estonian}% \languagealias{finnish} {Finnish}% \languagealias{french} {French}% \languagealias{german} {German1997,German}% \languagealias{hungarian} {Hungarian}% \languagealias{icelandic} {Icelandic}% \languagealias{italian} {Italian}% \languagealias{lithuanian}{Lithuanian}% unknown to translator \languagealias{magyar} {Magyar,Hungarian}% added Hungarian \languagealias{naustrian} {Austrian,German}% \languagealias{ngerman} {German}% \languagealias{norsk} {Norsk}% \languagealias{norwegian} {Norsk}% for polyglossia \languagealias{nynorsk} {Nynorsk,Norsk}% \languagealias{polish} {Polish}% \languagealias{portuges} {Portuguese}% \languagealias{portuguese}{Portuguese}% \languagealias{romanian} {Romanian}% \languagealias{slovak} {Slovak,Czech}% added Czech \languagealias{spanish} {Spanish}% \languagealias{swedish} {Swedish}% \languagealias{turkish} {Turkish}% \languagealias{UKenglish} {BritishEnglish,English}% \languagealias{USenglish} {AmericanEnglish,English}% }% \DeclareTranslation{Catalan}{True}{Vertader}% \DeclareTranslation{Catalan}{False}{Fals}% %\DeclareTranslation{Catalan}{cloze}{}% %\DeclareTranslation{Catalan}{description}{}% %\DeclareTranslation{Catalan}{essay}{}% %\DeclareTranslation{Catalan}{matching}{}% %\DeclareTranslation{Catalan}{multi}{}% %\DeclareTranslation{Catalan}{numerical}{}% %\DeclareTranslation{Catalan}{shortanswer}{}% %\DeclareTranslation{Catalan}{truefalse}{}% %\DeclareTranslation{Catalan}{Shuffle}{}% %\DeclareTranslation{Catalan}{Single}{}% %\DeclareTranslation{Catalan}{marked out of}{}% %\DeclareTranslation{Catalan}{penalty}{}% %\DeclareTranslation{Catalan}{tags}{}% %\DeclareTranslation{Catalan}{All-or-nothing}{}% %\DeclareTranslation{Catalan}{Case-Sensitive}{}% %\DeclareTranslation{Catalan}{Case-Insensitive}{}% %\DeclareTranslation{Catalan}{Drag and drop}{}% %\DeclareTranslation{Catalan}{Information for graders}{}% %\DeclareTranslation{Catalan}{Response template}{}% %\DeclareTranslation{Catalan}{editor}{}% %\DeclareTranslation{Catalan}{editorfilepicker}{}% %\DeclareTranslation{Catalan}{plain}{}% %\DeclareTranslation{Catalan}{monospaced}{}% %\DeclareTranslation{Catalan}{noinline}{}% %\DeclareTranslation{Catalan}{Total of marks}{}% \DeclareTranslation{Croatian}{True}{To\v{c}no}% \DeclareTranslation{Croatian}{False}{Neto\v{c}no}% %\DeclareTranslation{Croatian}{cloze}{}% %\DeclareTranslation{Croatian}{description}{}% %\DeclareTranslation{Croatian}{essay}{}% %\DeclareTranslation{Croatian}{matching}{}% %\DeclareTranslation{Croatian}{multi}{}% %\DeclareTranslation{Croatian}{numerical}{}% %\DeclareTranslation{Croatian}{shortanswer}{}% %\DeclareTranslation{Croatian}{truefalse}{}% %\DeclareTranslation{Croatian}{Shuffle}{}% %\DeclareTranslation{Croatian}{Single}{}% %\DeclareTranslation{Croatian}{Multiple}{}% %\DeclareTranslation{Croatian}{marked out of}{}% %\DeclareTranslation{Croatian}{penalty}{}% %\DeclareTranslation{Croatian}{tags}{}% %\DeclareTranslation{Croatian}{All-or-nothing}{}% %\DeclareTranslation{Croatian}{Case-Sensitive}{}% %\DeclareTranslation{Croatian}{Case-Insensitive}{}% %\DeclareTranslation{Croatian}{Drag and drop}{}% %\DeclareTranslation{Croatian}{Information for graders}{}% %\DeclareTranslation{Croatian}{Response template}{}% %\DeclareTranslation{Croatian}{editor}{}% %\DeclareTranslation{Croatian}{editorfilepicker}{}% %\DeclareTranslation{Croatian}{plain}{}% %\DeclareTranslation{Croatian}{monospaced}{}% %\DeclareTranslation{Croatian}{noinline}{}% %\DeclareTranslation{Croatian}{Total of marks}{}% \DeclareTranslation{Czech}{True}{Pravda}% \DeclareTranslation{Czech}{False}{Nepravda}% %\DeclareTranslation{Czech}{cloze}{}% %\DeclareTranslation{Czech}{description}{}% %\DeclareTranslation{Czech}{essay}{}% %\DeclareTranslation{Czech}{matching}{}% %\DeclareTranslation{Czech}{multi}{}% %\DeclareTranslation{Czech}{numerical}{}% %\DeclareTranslation{Czech}{shortanswer}{}% %\DeclareTranslation{Czech}{truefalse}{}% %\DeclareTranslation{Czech}{Shuffle}{}% %\DeclareTranslation{Czech}{Single}{}% %\DeclareTranslation{Czech}{Multiple}{}% %\DeclareTranslation{Czech}{marked out of}{}% %\DeclareTranslation{Czech}{penalty}{}% %\DeclareTranslation{Czech}{tags}{}% %\DeclareTranslation{Czech}{All-or-nothing}{}% %\DeclareTranslation{Czech}{Case-Sensitive}{}% %\DeclareTranslation{Czech}{Case-Insensitive}{}% %\DeclareTranslation{Czech}{Drag and drop}{}% %\DeclareTranslation{Czech}{Information for graders}{}% %\DeclareTranslation{Czech}{Response template}{}% %\DeclareTranslation{Czech}{editor}{}% %\DeclareTranslation{Czech}{editorfilepicker}{}% %\DeclareTranslation{Czech}{plain}{}% %\DeclareTranslation{Czech}{monospaced}{}% %\DeclareTranslation{Czech}{noinline}{}% %\DeclareTranslation{Czech}{Total of marks}{}% \DeclareTranslation{Danish}{True}{Sandt}% \DeclareTranslation{Danish}{False}{Falsk}% %\DeclareTranslation{Danish}{cloze}{}% %\DeclareTranslation{Danish}{description}{}% %\DeclareTranslation{Danish}{essay}{}% %\DeclareTranslation{Danish}{matching}{}% %\DeclareTranslation{Danish}{multi}{}% %\DeclareTranslation{Danish}{numerical}{}% %\DeclareTranslation{Danish}{shortanswer}{}% %\DeclareTranslation{Danish}{truefalse}{}% %\DeclareTranslation{Danish}{Shuffle}{}% %\DeclareTranslation{Danish}{Single}{}% %\DeclareTranslation{Danish}{Multiple}{}% %\DeclareTranslation{Danish}{marked out of}{}% %\DeclareTranslation{Danish}{penalty}{}% %\DeclareTranslation{Danish}{tags}{}% %\DeclareTranslation{Danish}{All-or-nothing}{}% %\DeclareTranslation{Danish}{Case-Sensitive}{}% %\DeclareTranslation{Danish}{Case-Insensitive}{}% %\DeclareTranslation{Danish}{Drag and drop}{}% %\DeclareTranslation{Danish}{Information for graders}{}% %\DeclareTranslation{Danish}{Response template}{}% %\DeclareTranslation{Danish}{editor}{}% %\DeclareTranslation{Danish}{editorfilepicker}{}% %\DeclareTranslation{Danish}{plain}{}% %\DeclareTranslation{Danish}{monospaced}{}% %\DeclareTranslation{Danish}{noinline}{}% %\DeclareTranslation{Danish}{Total of marks}{}% \DeclareTranslation{Dutch}{True}{Waar}% \DeclareTranslation{Dutch}{False}{Niet waar}% %\DeclareTranslation{Dutch}{cloze}{}% %\DeclareTranslation{Dutch}{description}{}% %\DeclareTranslation{Dutch}{essay}{}% %\DeclareTranslation{Dutch}{matching}{}% %\DeclareTranslation{Dutch}{multi}{}% %\DeclareTranslation{Dutch}{numerical}{}% %\DeclareTranslation{Dutch}{shortanswer}{}% %\DeclareTranslation{Dutch}{truefalse}{}% %\DeclareTranslation{Dutch}{Shuffle}{}% %\DeclareTranslation{Dutch}{Single}{}% %\DeclareTranslation{Dutch}{Multiple}{}% %\DeclareTranslation{Dutch}{marked out of}{}% %\DeclareTranslation{Dutch}{penalty}{}% %\DeclareTranslation{Dutch}{tags}{}% %\DeclareTranslation{Dutch}{All-or-nothing}{}% %\DeclareTranslation{Dutch}{Case-Sensitive}{}% %\DeclareTranslation{Dutch}{Case-Insensitive}{}% %\DeclareTranslation{Dutch}{Drag and drop}{}% %\DeclareTranslation{Dutch}{Information for graders}{}% %\DeclareTranslation{Dutch}{Response template}{}% %\DeclareTranslation{Dutch}{editor}{}% %\DeclareTranslation{Dutch}{editorfilepicker}{}% %\DeclareTranslation{Dutch}{plain}{}% %\DeclareTranslation{Dutch}{monospaced}{}% %\DeclareTranslation{Dutch}{noinline}{}% %\DeclareTranslation{Dutch}{Total of marks}{}% \DeclareTranslation{English}{True}{True}% \DeclareTranslation{English}{False}{False}% \DeclareTranslation{English}{cloze}{Embedded answers}% \DeclareTranslation{English}{description}{Description}% \DeclareTranslation{English}{essay}{Essay}% \DeclareTranslation{English}{matching}{Matching}% \DeclareTranslation{English}{multi}{Multiple choice}% \DeclareTranslation{English}{numerical}{Numerical}% \DeclareTranslation{English}{shortanswer}{Short answer}% \DeclareTranslation{English}{truefalse}{True/False}% \DeclareTranslation{English}{Shuffle}{Shuffle}% \DeclareTranslation{English}{Single}{One answer only}% \DeclareTranslation{English}{Multiple}{Multiple answers allowed}% \DeclareTranslation{English}{marked out of}{marked out of}% \DeclareTranslation{English}{penalty}{penalty}% \DeclareTranslation{English}{tags}{tags}% \DeclareTranslation{English}{All-or-nothing}{All-or-nothing}% \DeclareTranslation{English}{Case-Sensitive}{Case-Sensitive}% \DeclareTranslation{English}{Case-Insensitive}{Case-Insensitive}% \DeclareTranslation{English}{Drag and drop}{Drag and drop}% \DeclareTranslation{English}{Information for graders}{Information for graders}% \DeclareTranslation{English}{Response template}{Response template}% \DeclareTranslation{English}{editor}{HTML editor}% \DeclareTranslation{English}{editorfilepicker}{HTML editor + file picker}% \DeclareTranslation{English}{plain}{Plain text}% \DeclareTranslation{English}{monospaced}{Plain text, monospaced font}% \DeclareTranslation{English}{noinline}{File picker}% \DeclareTranslation{English}{Total of marks}{Total of marks}% \DeclareTranslation{Estonian}{True}{T\~oene}% \DeclareTranslation{Estonian}{False}{V\"a\"ar}% %\DeclareTranslation{Estonian}{cloze}{}% %\DeclareTranslation{Estonian}{description}{}% %\DeclareTranslation{Estonian}{essay}{}% %\DeclareTranslation{Estonian}{matching}{}% %\DeclareTranslation{Estonian}{multi}{}% %\DeclareTranslation{Estonian}{numerical}{}% %\DeclareTranslation{Estonian}{shortanswer}{}% %\DeclareTranslation{Estonian}{truefalse}{}% %\DeclareTranslation{Estonian}{Shuffle}{}% %\DeclareTranslation{Estonian}{Single}{}% %\DeclareTranslation{Estonian}{Multiple}{}% %\DeclareTranslation{Estonian}{marked out of}{}% %\DeclareTranslation{Estonian}{penalty}{}% %\DeclareTranslation{Estonian}{tags}{}% %\DeclareTranslation{Estonian}{All-or-nothing}{}% %\DeclareTranslation{Estonian}{Case-Sensitive}{}% %\DeclareTranslation{Estonian}{Case-Insensitive}{}% %\DeclareTranslation{Estonian}{Drag and drop}{}% %\DeclareTranslation{Estonian}{Information for graders}{}% %\DeclareTranslation{Estonian}{Response template}{}% %\DeclareTranslation{Estonian}{editor}{}% %\DeclareTranslation{Estonian}{editorfilepicker}{}% %\DeclareTranslation{Estonian}{plain}{}% %\DeclareTranslation{Estonian}{monospaced}{}% %\DeclareTranslation{Estonian}{noinline}{}% %\DeclareTranslation{Estonian}{Total of marks}{}% \DeclareTranslation{Finnish}{True}{Tosi}% \DeclareTranslation{Finnish}{False}{Ep\"atosi}% %\DeclareTranslation{Finnish}{cloze}{}% %\DeclareTranslation{Finnish}{description}{}% %\DeclareTranslation{Finnish}{essay}{}% %\DeclareTranslation{Finnish}{matching}{}% %\DeclareTranslation{Finnish}{multi}{}% %\DeclareTranslation{Finnish}{numerical}{}% %\DeclareTranslation{Finnish}{shortanswer}{}% %\DeclareTranslation{Finnish}{truefalse}{}% %\DeclareTranslation{Finnish}{Shuffle}{}% %\DeclareTranslation{Finnish}{Single}{}% %\DeclareTranslation{Finnish}{Multiple}{}% %\DeclareTranslation{Finnish}{marked out of}{}% %\DeclareTranslation{Finnish}{penalty}{}% %\DeclareTranslation{Finnish}{tags}{}% %\DeclareTranslation{Finnish}{All-or-nothing}{}% %\DeclareTranslation{Finnish}{Case-Sensitive}{}% %\DeclareTranslation{Finnish}{Case-Insensitive}{}% %\DeclareTranslation{Finnish}{Drag and drop}{}% %\DeclareTranslation{Finnish}{Information for graders}{}% %\DeclareTranslation{Finnish}{Response template}{}% %\DeclareTranslation{Finnish}{editor}{}% %\DeclareTranslation{Finnish}{editorfilepicker}{}% %\DeclareTranslation{Finnish}{plain}{}% %\DeclareTranslation{Finnish}{monospaced}{}% %\DeclareTranslation{Finnish}{noinline}{}% %\DeclareTranslation{Finnish}{Total of marks}{}% \DeclareTranslation{French}{True}{Vrai}% \DeclareTranslation{French}{False}{Faux}% \DeclareTranslation{French}{cloze}{R\'eponses int\'egr\'ees}% \DeclareTranslation{French}{description}{Description}% \DeclareTranslation{French}{essay}{Composition}% \DeclareTranslation{French}{matching}{Appariement}% \DeclareTranslation{French}{multi}{QCM}% \DeclareTranslation{French}{numerical}{Num\'erique}% \DeclareTranslation{French}{shortanswer}{R\'eponse courte}% \DeclareTranslation{French}{truefalse}{Vrai/Faux}% \DeclareTranslation{French}{Shuffle}{M\'elanger}% \DeclareTranslation{French}{Single}{R\'eponse unique}% \DeclareTranslation{French}{Multiple}{Plusieurs r\'eponses possibles}% \DeclareTranslation{French}{marked out of}{not\'e sur}% \DeclareTranslation{French}{penalty}{p\'enalit\'e}% \DeclareTranslation{French}{tags}{\'etiquettes}% \DeclareTranslation{French}{All-or-nothing}{Tout ou rien}% \DeclareTranslation{French}{Case-Sensitive}{Sensible \`a la casse}% \DeclareTranslation{French}{Case-Insensitive}{Insensible \`a la casse}% \DeclareTranslation{French}{Drag and drop}{Glisser-d\'eposer}% \DeclareTranslation{French}{Information for graders}{Information pour les évaluateurs}% \DeclareTranslation{French}{Response template}{Mod\`ele de r\'eponse}% \DeclareTranslation{French}{editor}{\'Editeur HTML}% \DeclareTranslation{French}{editorfilepicker}{\'Editeur \HTML\ + s\'electeur de fichier}% \DeclareTranslation{French}{plain}{\'Editeur texte}% \DeclareTranslation{French}{monospaced}{\'Editeur texte, police \`a chasse fixe}% \DeclareTranslation{French}{noinline}{S\'electeur de fichier}% \DeclareTranslation{French}{Total of marks}{Total des points}% \DeclareTranslation{German}{True}{Wahr}% \DeclareTranslation{German}{False}{Falsch}% \DeclareTranslation{German}{cloze}{L\"uckentext}% \DeclareTranslation{German}{description}{Beschreibung}% \DeclareTranslation{German}{essay}{Freitext}% \DeclareTranslation{German}{matching}{Zuordnung}% \DeclareTranslation{German}{multi}{Multiple-Choice}% \DeclareTranslation{German}{numerical}{Numerisch}% \DeclareTranslation{German}{shortanswer}{Kurzantwort}% \DeclareTranslation{German}{truefalse}{Wahr/Falsch}% \DeclareTranslation{German}{Shuffle}{Mischen}% \DeclareTranslation{German}{Single}{Nur eine Antwort erlaubt}% \DeclareTranslation{German}{Multiple}{Mehrere Antworten erlaubt}% \DeclareTranslation{German}{marked out of}{Punkte:}% \DeclareTranslation{German}{penalty}{Abzug}% \DeclareTranslation{German}{tags}{Tags}% \DeclareTranslation{German}{All-or-nothing}{Alles-oder-nichts}% \DeclareTranslation{German}{Case-Sensitive}{Gro\ss-/Kleinschreibung muss stimmen}% \DeclareTranslation{German}{Case-Insensitive}{Gro\ss-/Kleinschreibung unwichtig}% \DeclareTranslation{German}{Drag and drop}{Drag-and-Drop}% \DeclareTranslation{German}{Information for graders}{Information zur Bewertung}% \DeclareTranslation{German}{Response template}{Antwortvorlage}% \DeclareTranslation{German}{editor}{HTML Editor}% \DeclareTranslation{German}{editorfilepicker}{HTML Editor mit Dateiauswahl}% \DeclareTranslation{German}{plain}{Unformatierter Text}% \DeclareTranslation{German}{monospaced}{Unformatierter Text, Schriftart mit fester Laufweite}% \DeclareTranslation{German}{noinline}{Kein Textfeld}% \DeclareTranslation{German}{Total of marks}{Gesamtsumme der Punkte}% \DeclareTranslation{Hungarian}{True}{Igaz}% \DeclareTranslation{Hungarian}{False}{Hamis}% %\DeclareTranslation{Hungarian}{cloze}{}% %\DeclareTranslation{Hungarian}{description}{}% %\DeclareTranslation{Hungarian}{essay}{}% %\DeclareTranslation{Hungarian}{matching}{}% %\DeclareTranslation{Hungarian}{multi}{}% %\DeclareTranslation{Hungarian}{numerical}{}% %\DeclareTranslation{Hungarian}{shortanswer}{}% %\DeclareTranslation{Hungarian}{truefalse}{}% %\DeclareTranslation{Hungarian}{Shuffle}{}% %\DeclareTranslation{Hungarian}{Single}{}% %\DeclareTranslation{Hungarian}{Multiple}{}% %\DeclareTranslation{Hungarian}{marked out of}{}% %\DeclareTranslation{Hungarian}{penalty}{}% %\DeclareTranslation{Hungarian}{tags}{}% %\DeclareTranslation{Hungarian}{All-or-nothing}{}% %\DeclareTranslation{Hungarian}{Case-Sensitive}{}% %\DeclareTranslation{Hungarian}{Case-Insensitive}{}% %\DeclareTranslation{Hungarian}{Drag and drop}{}% %\DeclareTranslation{Hungarian}{Information for graders}{}% %\DeclareTranslation{Hungarian}{Response template}{}% %\DeclareTranslation{Hungarian}{editor}{}% %\DeclareTranslation{Hungarian}{editorfilepicker}{}% %\DeclareTranslation{Hungarian}{plain}{}% %\DeclareTranslation{Hungarian}{monospaced}{}% %\DeclareTranslation{Hungarian}{noinline}{}% %\DeclareTranslation{Hungarian}{Total of marks}{}% \DeclareTranslation{Icelandic}{True}{R\'ett}% \DeclareTranslation{Icelandic}{False}{Rangt}% %\DeclareTranslation{Icelandic}{cloze}{}% %\DeclareTranslation{Icelandic}{description}{}% %\DeclareTranslation{Icelandic}{essay}{}% %\DeclareTranslation{Icelandic}{matching}{}% %\DeclareTranslation{Icelandic}{multi}{}% %\DeclareTranslation{Icelandic}{numerical}{}% %\DeclareTranslation{Icelandic}{shortanswer}{}% %\DeclareTranslation{Icelandic}{truefalse}{}% %\DeclareTranslation{Icelandic}{Shuffle}{}% %\DeclareTranslation{Icelandic}{Single}{}% %\DeclareTranslation{Icelandic}{Multiple}{}% %\DeclareTranslation{Icelandic}{marked out of}{}% %\DeclareTranslation{Icelandic}{penalty}{}% %\DeclareTranslation{Icelandic}{tags}{}% %\DeclareTranslation{Icelandic}{All-or-nothing}{}% %\DeclareTranslation{Icelandic}{Case-Sensitive}{}% %\DeclareTranslation{Icelandic}{Case-Insensitive}{}% %\DeclareTranslation{Icelandic}{Drag and drop}{}% %\DeclareTranslation{Icelandic}{Information for graders}{}% %\DeclareTranslation{Icelandic}{Response template}{}% %\DeclareTranslation{Icelandic}{editor}{}% %\DeclareTranslation{Icelandic}{editorfilepicker}{}% %\DeclareTranslation{Icelandic}{plain}{}% %\DeclareTranslation{Icelandic}{monospaced}{}% %\DeclareTranslation{Icelandic}{noinline}{}% %\DeclareTranslation{Icelandic}{Total of marks}{}% \DeclareTranslation{Italian}{True}{Vero}% \DeclareTranslation{Italian}{False}{Falso}% \DeclareTranslation{Italian}{cloze}{Risposte inglobate}% \DeclareTranslation{Italian}{description}{Descrizione}% \DeclareTranslation{Italian}{essay}{Tema libero}% \DeclareTranslation{Italian}{matching}{Corrispondenza}% \DeclareTranslation{Italian}{multi}{Risposta multipla}% \DeclareTranslation{Italian}{numerical}{Numerica}% \DeclareTranslation{Italian}{shortanswer}{Risposta breve}% \DeclareTranslation{Italian}{truefalse}{Vero/Falso}% \DeclareTranslation{Italian}{Shuffle}{Ordine casuale}% \DeclareTranslation{Italian}{Single}{Una sola alternativa}% \DeclareTranslation{Italian}{Multiple}{Pi\`u alternative}% \DeclareTranslation{Italian}{marked out of}{punteggio max.}% \DeclareTranslation{Italian}{penalty}{penalit\`a}% \DeclareTranslation{Italian}{tags}{etichette}% \DeclareTranslation{Italian}{All-or-nothing}{Tutto o niente}% \DeclareTranslation{Italian}{Case-Sensitive}{Sensibile alle maiuscole}% \DeclareTranslation{Italian}{Case-Insensitive}{Maiuscolo/minuscolo indifferente}% \DeclareTranslation{Italian}{Drag and drop}{Drag and drop}% \DeclareTranslation{Italian}{Information for graders}{Informazioni per i valutatori}% \DeclareTranslation{Italian}{Response template}{Modello di risposta}% \DeclareTranslation{Italian}{editor}{Editor HTML}% \DeclareTranslation{Italian}{editorfilepicker}{Editor \HTML\ con file picker}% \DeclareTranslation{Italian}{plain}{Testo semplice}% \DeclareTranslation{Italian}{monospaced}{Testo semplice, caratteri a spaziatura fissa}% \DeclareTranslation{Italian}{noinline}{Solo file picker}% \DeclareTranslation{Italian}{Total of marks}{Punteggio complessivo}% \DeclareTranslation{Lithuanian}{True}{Tiesa}% \DeclareTranslation{Lithuanian}{False}{Netiesa}% %\DeclareTranslation{Lithuanian}{cloze}{}% %\DeclareTranslation{Lithuanian}{description}{}% %\DeclareTranslation{Lithuanian}{essay}{}% %\DeclareTranslation{Lithuanian}{matching}{}% %\DeclareTranslation{Lithuanian}{multi}{}% %\DeclareTranslation{Lithuanian}{numerical}{}% %\DeclareTranslation{Lithuanian}{shortanswer}{}% %\DeclareTranslation{Lithuanian}{truefalse}{}% %\DeclareTranslation{Lithuanian}{Shuffle}{}% %\DeclareTranslation{Lithuanian}{Single}{}% %\DeclareTranslation{Lithuanian}{Multiple}{}% %\DeclareTranslation{Lithuanian}{marked out of}{}% %\DeclareTranslation{Lithuanian}{penalty}{}% %\DeclareTranslation{Lithuanian}{tags}{}% %\DeclareTranslation{Lithuanian}{All-or-nothing}{}% %\DeclareTranslation{Lithuanian}{Case-Sensitive}{}% %\DeclareTranslation{Lithuanian}{Case-Insensitive}{}% %\DeclareTranslation{Lithuanian}{Drag and drop}{}% %\DeclareTranslation{Lithuanian}{Information for graders}{}% %\DeclareTranslation{Lithuanian}{Response template}{}% %\DeclareTranslation{Lithuanian}{editor}{}% %\DeclareTranslation{Lithuanian}{editorfilepicker}{}% %\DeclareTranslation{Lithuanian}{plain}{}% %\DeclareTranslation{Lithuanian}{monospaced}{}% %\DeclareTranslation{Lithuanian}{noinline}{}% %\DeclareTranslation{Lithuanian}{Total of marks}{}% \DeclareTranslation{Norsk}{True}{Riktig}% \DeclareTranslation{Norsk}{False}{Feil}% %\DeclareTranslation{Norsk}{cloze}{}% %\DeclareTranslation{Norsk}{description}{}% %\DeclareTranslation{Norsk}{essay}{}% %\DeclareTranslation{Norsk}{matching}{}% %\DeclareTranslation{Norsk}{multi}{}% %\DeclareTranslation{Norsk}{numerical}{}% %\DeclareTranslation{Norsk}{shortanswer}{}% %\DeclareTranslation{Norsk}{truefalse}{}% %\DeclareTranslation{Norsk}{Shuffle}{}% %\DeclareTranslation{Norsk}{Single}{}% %\DeclareTranslation{Norsk}{Multiple}{}% %\DeclareTranslation{Norsk}{marked out of}{}% %\DeclareTranslation{Norsk}{penalty}{}% %\DeclareTranslation{Norsk}{tags}{}% %\DeclareTranslation{Norsk}{All-or-nothing}{}% %\DeclareTranslation{Norsk}{Case-Sensitive}{}% %\DeclareTranslation{Norsk}{Case-Insensitive}{}% %\DeclareTranslation{Norsk}{Drag and drop}{}% %\DeclareTranslation{Norsk}{Information for graders}{}% %\DeclareTranslation{Norsk}{Response template}{}% %\DeclareTranslation{Norsk}{editor}{}% %\DeclareTranslation{Norsk}{editorfilepicker}{}% %\DeclareTranslation{Norsk}{plain}{}% %\DeclareTranslation{Norsk}{monospaced}{}% %\DeclareTranslation{Norsk}{noinline}{}% %\DeclareTranslation{Norsk}{Total of marks}{}% \DeclareTranslation{Polish}{True}{Prawda}% \DeclareTranslation{Polish}{False}{Fa\l sz}% %\DeclareTranslation{Polish}{cloze}{}% %\DeclareTranslation{Polish}{description}{}% %\DeclareTranslation{Polish}{essay}{}% %\DeclareTranslation{Polish}{matching}{}% %\DeclareTranslation{Polish}{multi}{}% %\DeclareTranslation{Polish}{numerical}{}% %\DeclareTranslation{Polish}{shortanswer}{}% %\DeclareTranslation{Polish}{truefalse}{}% %\DeclareTranslation{Polish}{Shuffle}{}% %\DeclareTranslation{Polish}{Single}{}% %\DeclareTranslation{Polish}{Multiple}{}% %\DeclareTranslation{Polish}{marked out of}{}% %\DeclareTranslation{Polish}{penalty}{}% %\DeclareTranslation{Polish}{tags}{}% %\DeclareTranslation{Polish}{All-or-nothing}{}% %\DeclareTranslation{Polish}{Case-Sensitive}{}% %\DeclareTranslation{Polish}{Case-Insensitive}{}% %\DeclareTranslation{Polish}{Drag and drop}{}% %\DeclareTranslation{Polish}{Information for graders}{}% %\DeclareTranslation{Polish}{Response template}{}% %\DeclareTranslation{Polish}{editor}{}% %\DeclareTranslation{Polish}{editorfilepicker}{}% %\DeclareTranslation{Polish}{plain}{}% %\DeclareTranslation{Polish}{monospaced}{}% %\DeclareTranslation{Polish}{noinline}{}% %\DeclareTranslation{Polish}{Total of marks}{}% \DeclareTranslation{Portuguese}{True}{Verdadeiro}% \DeclareTranslation{Portuguese}{False}{Falso}% %\DeclareTranslation{Portuguese}{cloze}{}% %\DeclareTranslation{Portuguese}{description}{}% %\DeclareTranslation{Portuguese}{essay}{}% %\DeclareTranslation{Portuguese}{matching}{}% %\DeclareTranslation{Portuguese}{multi}{}% %\DeclareTranslation{Portuguese}{numerical}{}% %\DeclareTranslation{Portuguese}{shortanswer}{}% %\DeclareTranslation{Portuguese}{truefalse}{}% %\DeclareTranslation{Portuguese}{Shuffle}{}% %\DeclareTranslation{Portuguese}{Single}{}% %\DeclareTranslation{Portuguese}{Multiple}{}% %\DeclareTranslation{Portuguese}{marked out of}{}% %\DeclareTranslation{Portuguese}{penalty}{}% %\DeclareTranslation{Portuguese}{tags}{}% %\DeclareTranslation{Portuguese}{All-or-nothing}{}% %\DeclareTranslation{Portuguese}{Case-Sensitive}{}% %\DeclareTranslation{Portuguese}{Case-Insensitive}{}% %\DeclareTranslation{Portuguese}{Drag and drop}{}% %\DeclareTranslation{Portuguese}{Information for graders}{}% %\DeclareTranslation{Portuguese}{Response template}{}% %\DeclareTranslation{Portuguese}{editor}{}% %\DeclareTranslation{Portuguese}{editorfilepicker}{}% %\DeclareTranslation{Portuguese}{plain}{}% %\DeclareTranslation{Portuguese}{monospaced}{}% %\DeclareTranslation{Portuguese}{noinline}{}% %\DeclareTranslation{Portuguese}{Total of marks}{}% \DeclareTranslation{Romanian}{True}{Adev\u{a}rat}% \DeclareTranslation{Romanian}{False}{Fals}% %\DeclareTranslation{Romanian}{cloze}{}% %\DeclareTranslation{Romanian}{description}{}% %\DeclareTranslation{Romanian}{essay}{}% %\DeclareTranslation{Romanian}{matching}{}% %\DeclareTranslation{Romanian}{multi}{}% %\DeclareTranslation{Romanian}{numerical}{}% %\DeclareTranslation{Romanian}{shortanswer}{}% %\DeclareTranslation{Romanian}{truefalse}{}% %\DeclareTranslation{Romanian}{Shuffle}{}% %\DeclareTranslation{Romanian}{Single}{}% %\DeclareTranslation{Romanian}{Multiple}{}% %\DeclareTranslation{Romanian}{marked out of}{}% %\DeclareTranslation{Romanian}{penalty}{}% %\DeclareTranslation{Romanian}{tags}{}% %\DeclareTranslation{Romanian}{All-or-nothing}{}% %\DeclareTranslation{Romanian}{Case-Sensitive}{}% %\DeclareTranslation{Romanian}{Case-Insensitive}{}% %\DeclareTranslation{Romanian}{Drag and drop}{}% %\DeclareTranslation{Romanian}{Information for graders}{}% %\DeclareTranslation{Romanian}{Response template}{}% %\DeclareTranslation{Romanian}{editor}{}% %\DeclareTranslation{Romanian}{editorfilepicker}{}% %\DeclareTranslation{Romanian}{plain}{}% %\DeclareTranslation{Romanian}{monospaced}{}% %\DeclareTranslation{Romanian}{noinline}{}% %\DeclareTranslation{Romanian}{Total of marks}{}% \DeclareTranslation{Spanish}{True}{Verdadero}% \DeclareTranslation{Spanish}{False}{Falso}% \DeclareTranslation{Spanish}{cloze}{Respuestas anidadas}% \DeclareTranslation{Spanish}{description}{Descripci\'on}% \DeclareTranslation{Spanish}{essay}{Ensayo}% \DeclareTranslation{Spanish}{matching}{Emparejamiento}% \DeclareTranslation{Spanish}{multi}{Opci\'on m\'ultiple}% \DeclareTranslation{Spanish}{numerical}{Num\'erica}% \DeclareTranslation{Spanish}{shortanswer}{Respuesta corta}% \DeclareTranslation{Spanish}{truefalse}{Verdadero/Falso}% \DeclareTranslation{Spanish}{Shuffle}{Barajar al azar}% \DeclareTranslation{Spanish}{Single}{S\'olo una respuesta}% \DeclareTranslation{Spanish}{Multiple}{Se permiten varias respuestas}% \DeclareTranslation{Spanish}{marked out of}{Punt\'ua como}% \DeclareTranslation{Spanish}{penalty}{penalizaci\'on}% \DeclareTranslation{Spanish}{tags}{marcas}% \DeclareTranslation{Spanish}{All-or-nothing}{Todo o nada}% \DeclareTranslation{Spanish}{Case-Sensitive}{May\'usculas y min\'usculas deben coincidir}% \DeclareTranslation{Spanish}{Case-Insensitive}{Igual may\'usculas que min\'usculas}% \DeclareTranslation{Spanish}{Drag and drop}{Arrastrar y soltar}% \DeclareTranslation{Spanish}{Information for graders}{Informaci\'on para evaluadores}% \DeclareTranslation{Spanish}{Response template}{Plantilla de respuesta}% \DeclareTranslation{Spanish}{editor}{Editor HTML}% \DeclareTranslation{Spanish}{editorfilepicker}{Editor \HTML\ con selector de archivos}% \DeclareTranslation{Spanish}{plain}{Texto sin formato}% \DeclareTranslation{Spanish}{monospaced}{Texto sin formato, tipografía monoespaciada}% \DeclareTranslation{Spanish}{noinline}{Sin texto}% \DeclareTranslation{Spanish}{Total of marks}{Total de puntos}% \DeclareTranslation{Swedish}{True}{Sant}% \DeclareTranslation{Swedish}{False}{Falskt}% %\DeclareTranslation{Swedish}{cloze}{}% %\DeclareTranslation{Swedish}{description}{}% %\DeclareTranslation{Swedish}{essay}{}% %\DeclareTranslation{Swedish}{matching}{}% %\DeclareTranslation{Swedish}{multi}{}% %\DeclareTranslation{Swedish}{numerical}{}% %\DeclareTranslation{Swedish}{shortanswer}{}% %\DeclareTranslation{Swedish}{truefalse}{}% %\DeclareTranslation{Swedish}{Shuffle}{}% %\DeclareTranslation{Swedish}{Single}{}% %\DeclareTranslation{Swedish}{Multiple}{}% %\DeclareTranslation{Swedish}{marked out of}{}% %\DeclareTranslation{Swedish}{penalty}{}% %\DeclareTranslation{Swedish}{tags}{}% %\DeclareTranslation{Swedish}{All-or-nothing}{}% %\DeclareTranslation{Swedish}{Case-Sensitive}{}% %\DeclareTranslation{Swedish}{Case-Insensitive}{}% %\DeclareTranslation{Swedish}{Drag and drop}{}% %\DeclareTranslation{Swedish}{Information for graders}{}% %\DeclareTranslation{Swedish}{Response template}{}% %\DeclareTranslation{Swedish}{editor}{}% %\DeclareTranslation{Swedish}{editorfilepicker}{}% %\DeclareTranslation{Swedish}{plain}{}% %\DeclareTranslation{Swedish}{monospaced}{}% %\DeclareTranslation{Swedish}{noinline}{}% %\DeclareTranslation{Swedish}{Total of marks}{}% \DeclareTranslation{Turkish}{True}{Do\u{g}ru}% \DeclareTranslation{Turkish}{False}{Yanl\i \c{s}}% %\DeclareTranslation{Turkish}{cloze}{}% %\DeclareTranslation{Turkish}{description}{}% %\DeclareTranslation{Turkish}{essay}{}% %\DeclareTranslation{Turkish}{matching}{}% %\DeclareTranslation{Turkish}{multi}{}% %\DeclareTranslation{Turkish}{numerical}{}% %\DeclareTranslation{Turkish}{shortanswer}{}% %\DeclareTranslation{Turkish}{truefalse}{}% %\DeclareTranslation{Turkish}{Shuffle}{}% %\DeclareTranslation{Turkish}{Single}{}% %\DeclareTranslation{Turkish}{Multiple}{}% %\DeclareTranslation{Turkish}{marked out of}{}% %\DeclareTranslation{Turkish}{penalty}{}% %\DeclareTranslation{Turkish}{tags}{}% %\DeclareTranslation{Turkish}{All-or-nothing}{}% %\DeclareTranslation{Turkish}{Case-Sensitive}{}% %\DeclareTranslation{Turkish}{Case-Insensitive}{}% %\DeclareTranslation{Turkish}{Drag and drop}{}% %\DeclareTranslation{Turkish}{Information for graders}{}% %\DeclareTranslation{Turkish}{Response template}{}% %\DeclareTranslation{Turkish}{editor}{}% %\DeclareTranslation{Turkish}{editorfilepicker}{}% %\DeclareTranslation{Turkish}{plain}{}% %\DeclareTranslation{Turkish}{monospaced}{}% %\DeclareTranslation{Turkish}{noinline}{}% %\DeclareTranslation{Turkish}{Total of marks}{}% \else% neither babel nor polyglossia loaded \newcommand\DeclareTranslationFallback[2]{\csdef{moodle@fallback@#1}{#2}}% Save fallback keys \def\GetTranslation#1{\csuse{moodle@fallback@#1}}% Use fallback keys \fi \DeclareTranslationFallback{True}{True}% \DeclareTranslationFallback{False}{False}% \DeclareTranslationFallback{cloze}{Embedded answers}% \DeclareTranslationFallback{description}{Description}% \DeclareTranslationFallback{essay}{Essay}% \DeclareTranslationFallback{matching}{Matching}% \DeclareTranslationFallback{multi}{Multiple choice}% \DeclareTranslationFallback{numerical}{Numerical}% \DeclareTranslationFallback{shortanswer}{Short answer}% \DeclareTranslationFallback{truefalse}{True/False}% \DeclareTranslationFallback{Shuffle}{Shuffle}% \DeclareTranslationFallback{Single}{One answer only}% \DeclareTranslationFallback{Multiple}{Multiple answers allowed}% \DeclareTranslationFallback{marked out of}{marked out of}% \DeclareTranslationFallback{penalty}{penalty}% \DeclareTranslationFallback{tags}{tags}% \DeclareTranslationFallback{All-or-nothing}{All-or-nothing}% \DeclareTranslationFallback{Case-Sensitive}{Case-Sensitive}% \DeclareTranslationFallback{Case-Insensitive}{Case-Insensitive}% \DeclareTranslationFallback{Drag and drop}{Drag and drop}% \DeclareTranslationFallback{Information for graders}{Information for graders}% \DeclareTranslationFallback{Response template}{Response template}% \DeclareTranslationFallback{editor}{HTML editor}% \DeclareTranslationFallback{editorfilepicker}{HTML editor + file picker}% \DeclareTranslationFallback{plain}{Plain text}% \DeclareTranslationFallback{monospaced}{Plain text, monospaced font}% \DeclareTranslationFallback{noinline}{File picker}% \DeclareTranslationFallback{Total of marks}{Total of marks}% }% % \end{macrocode} % % Users of the |babel| package loaded with specific options may experience problems % related to active characters and shorthands. We tell the problems and solutions we know. % \begin{macrocode} \AtBeginDocument{% \@ifpackageloaded{babel}{% \@ifundefined{bbl@loaded}{}{% polyglossia fakes babel \forcsvlist{\listadd\moodle@babel@german@list}{german,austrian,swissgerman,swissgerman.toss,ngerman,naustrian,nswissgerman,nswissgerman.toss}% \forcsvlist{\listadd\moodle@babel@french@list}{acadian,french,frenchb,francais}% \ifPDFTeX \def\moodle@babel@french@warn{% \PackageWarning{moodle}{Be careful when using pdflatex, moodle, and the babel package loaded with a French-related option. Autospacing yields undesired symbols in the XML. Here are three workarounds: \MessageBreak 1) compile with xelatex/lualatex,\MessageBreak 2) add `\NoAutoSpacing' after `\begin{quiz}', or\MessageBreak 3) avoid the babel option.^^J}}% \def\moodle@babel@german@warn{% \PackageWarning{moodle}{Be careful when using pdflatex, moodle, and the babel package loaded with a German-related option. The symbol `"' is made active and your umlauts will confuse moodle. Here are three workarounds:\MessageBreak 1) compile with xelatex/lualatex, \MessageBreak 2) add `\string\shorthandoff{"}' after `\begin{quiz}', or\MessageBreak 3) avoid the babel option.^^J}}% \fi \def\moodle@babel@turkish@warn{% \PackageWarning{moodle}{Be careful when using moodle and the babel package loaded with option `turkish'. Shorthands are likely to break compilation. Here are three workarounds:\MessageBreak 1) rely on `polyglossia' (XeTeX or LuaTeX),\MessageBreak 2) add `\shorthandoff{=:!}' after `\begin{quiz}', or\MessageBreak 3) avoid the babel option.^^J}}% \def\do#1{% \ifstrequal{#1}{turkish}{\moodle@babel@turkish@warn}{% \ifinlist{#1}{\moodle@babel@french@list}% {\ifPDFTeX\moodle@babel@french@warn\fi}{% \ifinlist{#1}{\moodle@babel@german@list}{% \ifPDFTeX\moodle@babel@german@warn\else \gdef\moodle@babel@german@warn{% \PackageWarning{moodle}{Be careful when using moodle and the babel package loaded with a German-related option that make the symbol `"' active. We recommend typing umlauts with UTF-8 characters. By default, `\string\"a' is poorly translated in the XML file. This is fixed if you define `\string\shorthandoff{"}' after `\begin{quiz}'. But then `"a` will no longer work as expected.^^J}% }% \gdef\moodle@babel@german@warn@single{% \moodle@babel@german@warn \gdef\moodle@babel@german@warn@single{}%\relax }% \pretocmd{\"}% {\moodle@babel@german@warn@single}% {}% { \PackageWarning{moodle}{Umlaut patch failed.}% \moodle@babel@german@warn@single }% \fi }{}% } } } \expandafter\docsvlist\expandafter{\bbl@loaded}% }% }{}% }% % \end{macrocode} % % \subsection{Warning and Error Management} % % \begin{macrocode} \def\moodle@WarningOrError#1#2#3{% % #1 : major version % #2 : minor version % #3 : feature \ifnum\the\moodle@LMSmajor\the\moodle@LMSminor=\z@\relax \PackageWarning{moodle}{#3 is only supported by Moodle #1.#2+}% \else \ifnum\numexpr 1000*\the\moodle@LMSmajor+\the\moodle@LMSminor\relax<\numexpr 1000*#1+#2\relax \PackageError{moodle}{#3 is only supported by Moodle #1.#2+ (you declared Moodle \the\moodle@LMSmajor.\the\moodle@LMSminor)}% \fi \fi }% % \end{macrocode} % \Finale \endinput