summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/moodle/moodle.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/moodle/moodle.dtx')
-rw-r--r--macros/latex/contrib/moodle/moodle.dtx5715
1 files changed, 3850 insertions, 1865 deletions
diff --git a/macros/latex/contrib/moodle/moodle.dtx b/macros/latex/contrib/moodle/moodle.dtx
index 9e932fb576..9f20c6c95a 100644
--- a/macros/latex/contrib/moodle/moodle.dtx
+++ b/macros/latex/contrib/moodle/moodle.dtx
@@ -1,8 +1,8 @@
% \iffalse meta-comment
%
% moodle.dtx
-% Copyright 2016 by Anders O.F. Hendrickson (anders.o.f.hendrickson AT gmail.com)
-% and 2019-2021 by Matthieu Guerquin-Kern (guerquin-kern AT crans.org).
+% 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
@@ -13,7 +13,7 @@
% 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
@@ -28,38 +28,45 @@
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{moodle}
%<*package>
- [2021/02/07 v0.9 Moodle quiz XML generation]
+ [2023/01/28 v1.0 Moodle quiz XML generation]
%</package>
%
%<*driver>
-\documentclass[a4paper]{ltxdoc}
+\documentclass[10pt,a4paper]{ltxdoc}
+%\usepackage[draft]{moodle}
\usepackage{iftex}
\ifPDFTeX
\usepackage[utf8]{inputenc} % necessary
\usepackage[T1]{fontenc} % necessary
- \usepackage[protrusion=true,expansion]{microtype}
- \usepackage[ttscale=.875]{libertine}
+ \usepackage{libertine}
+ \usepackage[scaled=0.83]{beramono}
\else % assuming LuaLaTeX or XeLaTeX
\usepackage{fontspec}
- \setmainfont[Mapping=tex-text]{Linux Libertine O}
+ \setmainfont{Linux Libertine O}
\fi
-%\usepackage{moodle}[2020/07/09]
-\usepackage{amssymb,metalogo,multirow,threeparttable,booktabs}
-\usepackage{hyperref,tikz,minted,changelog}
-\usetikzlibrary{arrows,positioning,decorations.text}
+\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
+\EnableCrossrefs
\CodelineIndex
\OnlyDescription
\RecordChanges
+\setcounter{IndexColumns}{2}
\begin{document}
\DocInput{moodle.dtx}
- %\PrintChanges
\end{document}
%</driver>
% \fi
%
-% \CheckSum{7729} ^^A Comment \OnlyDescription above to adjust
+% \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
@@ -81,170 +88,199 @@
% \GetFileInfo{\jobname.dtx}
%
% \DoNotIndex{\newcommand,\newenvironment,\def}
-%
%
-% \title{The \textsf{moodle} package: \\
-% generating Moodle quizzes via \LaTeX%
-% \thanks{This document
-% corresponds to \textsf{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.com} \and
-% Matthieu Guerquin-Kern\footnote{current maintainer, author of the updates (\texttt{v0.6}
-% to \texttt{v0.9}), partially funded in 2019 by \href{https://www.ensea.fr/en/}{ENSEA Graduate School}, France.}\\
-% \href{mailto:guerquin-kern AT crans.org}{guerquin-kern AT crans.org}}
-% \date{February 7, 2021}
-%
+% \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
%
-% \providecommand\TikZ{Ti\emph{k}Z}
+% \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{Motivation}
+% \section{Introduction}
+% \subsection{Motivation}
%
-% The acronym Moodle stands for ``Modular Object-Oriented Dynamic Learning Environment.''
-% It is an open source learning management system (LMS) employed by many universities,
+% 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.
+% \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
+% 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
+% 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
+%
+% 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
+% 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
+% 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
+%
+% 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
+% 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
+% (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
+%
+% 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
-% |\R| instead of |\mathbb{R}|
+% \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}|
+% 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
+% 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:
+%
+% \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.
+% 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 \textsf{moodle} package,
-% a quiz author can type a quiz using familiar \LaTeX\ syntax and document
+% 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 |.tex| file
+% \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 \textsf{moodle} package does not generate quizzes:
-% it generates question banks that can be imported in the LMS. The teacher
+%
+% 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:
+% 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 M and
-% roman font) while the \LaTeX\ package that is documented here is referred
-% to as \textsf{moodle} (all lower case and sans serif font).
-%
-% \section{Workflow}
-% The process of creating a quiz in Moodle using this package is depicted in
-% Figure~\ref{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\, \XeLaTeX\ or \LuaLaTeX.
-% This will also produce the file \meta{jobname}|-moodle.xml|.
-% \item Open Moodle, navigate to the desired course,
-% 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}
-% \begin{figure}[tbp]
+% 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
+% \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,-3.3)--++(-6.7,0)--++(-.25,1.725)--cycle;
-% \node[orange!80!black,above] (dev) at (7.5,-2.6) {\textit{Developpement}};
+% (-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,-3.4)--++(6.8,0)--++(0,-2)--++(-10.3,0)--cycle;
-% \node[green!80!black,below] (dev) at (7.5,-2.7) {\textit{Publishing}};
-% \node[box,text width=2cm] (tex) {\texttt{.tex} source file};
-% \node[rectangle,fill=white,draw,align=center,text
+% (-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};
-% \node[box,right=of compfinal,xshift=.5cm] (pdf) {\texttt{.pdf} file for proofreading};
-% \node[rectangle,fill=white,draw,align=center,text width=2cm,below=of compfinal] (extern)
+% \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) {\texttt{.xml} file\\\footnotesize(pictures embedded)};
+% \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] {\texttt{final}} (compfinal);
-% \draw (tex) edge [post,bend left=10] node[cmnt,pos=.5,below] {\texttt{draft}} (compdraft);
+% 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] (pdf);
-% \draw (compfinal) edge [post,bend left=10] (xml);
-% \draw (compfinal) edge [post,bend right=30] node[cmnt,black!40,pos=.5,text width=1cm,left]
-% {\texttt{tikz}, \texttt{.png}, \texttt{.jpg}} (extern);
-% \draw (extern) edge [post,green,bend right=30] node[cmnt,black!40,pos=.5,below,right]
-% {\texttt{base64}} (compfinal);
-% \draw (pdf) edge [post,red,bend right=15] node[sloped,cmnt,pos=.5,above] {improve} (tex);
+% \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 \textsf{moodle} package.}
+% \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/310/en/Question_types}.
+% 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 |xkeyval| package is used to provide a key-value interface.
+% The \pkg{xkeyval} package is used to provide a key-value interface.
%
% \subsection{Example Document}
%
@@ -256,6 +292,8 @@
% \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$?
@@ -277,103 +315,132 @@
% \end{document}
% \end{VerbatimOut}
% \inputminted[gobble=2,frame=lines]{latex}{minted.doc.out}
-% Key features to note in this first example are that a |quiz| environment
+% 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,
+% 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 |itemize| or |enumerate|, in that answers are set off by
-% |\item|'s, but the question itself is the text that occurs before
-% the first |\item|.
+% 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{\moodleregisternewcommands}\DescribeMacro{\htmlregister}
-%^^A Calling |\moodleregisternewcommands| tells the package to treat
+%^^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 |\newcommand|
+%^^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 |\htmlregister|\marg{macroname}, lets you declare a specific
+%^^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 |\def|.
-%
+%^^A macros defined using \TeX's primitive \cmd{\def}.
+%
% \subsection{Package Options}
-% \DescribeMacro{draft}
-% \DescribeMacro{final}
-% If the package option |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. The package option |final| might be useful if one wants
-% to avoid the option |draft| to be inherited from the |documentclass|.
-%
-% \DescribeMacro{handout}
-% If the package option |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
-% \texttt{matching} questions are shuffled and the option \texttt{shuffle}
-% triggers the shuffling of choices offered (\texttt{multi} and
-% \texttt{matching}). This is achieved thanks to the package
-% \texttt{randomlist}, loaded if the option is invoked.
-% The XML file is generated as usual.
-%
-% \DescribeMacro{nostamp}
+%
+% \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 operating system used and the package version. For instance:
+% file. This stamp contains information gathered about the \TeX\ engine,
+% the platform used and the package version. For instance:%
% \begin{quote}\small
-% |<!-- This file was generated on 2021-01-07 by LuaLaTeX -->|\\
-% |<!-- running on Linux with the package moodle |\texttt{\fileversion}| -->|
+% \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
+% |<!-- This XML file is a question bank made for Moodle. -->|\\
+% |<!-- It was generated on |\texttt{\today\space\the\hour:\the\minute}| by LuaLaTeX running -->|\\
+% |<!-- on Linux with the package moodle |\texttt{\fileversion}| (|\texttt{\filedate}|) -->|
% \end{quote}
-% The package option
-% |nostamp| prevents this stamp to be written in the XML file.
-%
-% \DescribeMacro{section}
-% \DescribeMacro{section*}
-% \DescribeMacro{subsection}
-% \DescribeMacro{subsection*}
-% If the package option |section| is invoked (|\usepackage[section]{moodle}|),
-% then each quiz is represented by a different \LaTeX\ section. Starred
-% variants correspond to unnumbered sections or subsections. To preserve
-% compatibility with Version 0.5 of this package, the default is |subsection*|.
-% Consequently, |\usepackage{moodle}| is equivalent to
-% |\usepackage[subsection*]{moodle}|.
-%
-% \DescribeMacro{tikz} The package option \texttt{tikz} is described in section
-% \ref{subsec:tikz}.
-%
-% \DescribeMacro{svg} The package option \texttt{svg} is described in section
-% \ref{subsec:svg}.
+% 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}
-%
-% \DescribeMacro{quiz}
-% A |.tex| document to generate Moodle quizzes contains one or more
-% |quiz| environments, within which various question environments are nested.
-% The required argument to the |quiz| environment names a category for Moodles
+%
+% 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.
-% \begin{center}
-% |\begin{quiz}|\oarg{options}\marg{category name}%
-% \end{center}
-% There are no |quiz|-specific options,
-% but any \meta{options} set with |\begin{quiz}|
-% will be inherited by all questions contained within that |quiz| environment.
-%
-% \DescribeMacro{\moodleset}
-% Options may also be set outside question environments with
-% |\moodleset|\marg{options}; these changes are local to \TeX-groups.
-%
-% \DescribeMacro{\setcategory}\DescribeMacro{\setsubcategory}
-% Although the |quiz| environment defines a category by its own, one can change
-% the current category inside the quiz environment and in between questions,
-% using the macro |\setcategory|\marg{category name}. A subcategory can also be
-% defined with |\setsubcategory|\marg{subcategory name}. The categories and
-% subcategories are reflected in the PDF file as sections, subsections, or
-% subsubsections, in accordance to the package setting |section|, |section*|,
-% |subsection|, or |subsection*|.
-%
+% 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} \\
@@ -386,28 +453,29 @@
% 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:
-%
-% \DescribeMacro{points}\DescribeMacro{default grade}
+%
+% \DescribeKey[quiz,question]{points}\DescribeDefault{1}
+% \DescribeKey[quiz,question]{default grade}
% By default, each question is worth 1 point on the quiz.
-% This may be changed with the |points| key or its synonym, |default grade|;
-% for example, |points=2| makes that question worth two points.
-%
-% \DescribeMacro{penalty}
-% The |penalty| is the fraction of points that is taken off for each wrong attempt;
+% 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.
-% The default is |penalty=0.10|.
-%
-% \DescribeMacro{fraction}
+%
+% \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 |fraction| key may be set to any of the values given in Table~\ref{tab:fraction},
-% from |0| (entirely wrong) to |100| (entirely correct).
-%
+% 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}{Valid positive options} for the \texttt{fraction} key: $100\cdot(p/q)$.}
+% \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}}
@@ -432,38 +500,41 @@
% \bottomrule
% \end{tabular}
% \end{table}
-% In questions where several choices can be selected (see |multi| with the option
-% |multiple|), positive fractions must sum up to exactly 100. It is also possible to set
+%
+% 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~\ref{tab:fraction}.
-%
-% \DescribeMacro{fractiontol}
-% The package tries to match the |fraction| key to one of the admissible values.
-% To this end, the tolerance is controlled by the |fractiontol| key. It defaults
-% to |0.01| but may be changed. When no admissible fraction value is matched, the
-% package throws an error.
-%
-% \DescribeMacro{feedback}
-% The |feedback| key sets text that will appear to the student after completing the quiz.
-% For example, one might set
+% 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.
-%
-% Two kinds of feedback can be given. If the |feedback| key is set for a
-% question, then that feedback will appear to each student regardless of the student's answer.
+%
+% \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 |feedback| key \emph{at the individual answer}.
+% may also be given by setting the \optn{feedback} key \emph{at the individual answer}.
%
-% \DescribeMacro{tags}
-% The |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.
+% \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
+% For example, one might set
% \begin{center}
% |tags={easy}|
% \end{center}
@@ -473,22 +544,27 @@
% |tags={tag1,tag2,{ leading whitespace},{including, comma}}|
% \end{center}
%
-% Tags can be assigned at two levels. If the |tags| key is set at the quiz level,
+% \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.
-% Question-specific tags can be assigned by setting the |tags| key \emph{at the question level}.
-% The question-level |tags| key overrides eventual quiz-level tags.
-%
+%
+% \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 rely on Moodle's category mechanism.
-%
+% 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 \textsf{moodle}
+%
+% 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}}
-%
-% \DescribeMacro{truefalse}
+%
+% \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} \\
@@ -497,7 +573,7 @@
% \rule{2em}{0pt}|\item| \meta{feedback when ``false" is chosen} \\
% |\end{truefalse}|
% \end{quote}
-% The correct answer is designated by the asterisk |*| after the |\item|;
+% 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
@@ -510,47 +586,67 @@
% \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/310/Multiple_Choice_question_type}{Multiple Choice}}
-%
-% \DescribeMacro{multi}
+% \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*| \meta{correct answer} \\
-% \rule{2em}{0pt}|\item|\oarg{options} \meta{wrong answer} \\
+% \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{options} \meta{wrong answer} \\
+% \rule{2em}{0pt}|\item|\oarg{answer options} \meta{wrong answer} \\
% |\end{multi}|
% \end{quote}
-% The correct answer is designated by the asterisk |*| after the |\item|;
+% The correct answer is designated by the asterisk \texttt{*} after the \cmd{\item};
% it need not appear first in the list.
-%
-%
-% \DescribeMacro{shuffle}
-% The boolean key |shuffle| determines whether Moodle will
+%
+%
+% \DescribeBoolean[multi]{shuffle}\DescribeDefault{true}
+% The Boolean key \optn{shuffle} determines whether \Moodle\ will
% rearrange the possible answers in a random order.
-% Setting |shuffle=false| will guarantee that the answer appear
-% in the order they were typed; the default is |shuffle=true|.
-%
-% \DescribeMacro{numbering}
-% Moodle offers different options for numbering the possible answers.
-% You may set the |numbering| key to any of the following values,
-% which mirror the usual \LaTeX\ syntax:
-% |alph|, |Alph|, |arabic|, |roman|, |Roman|, and |none|.
-% Calling |numbering=none| produces an unnumbered list of answers.
-% The Moodle syntax of |abc|, |ABCD|, |123|, |iii|, and |IIII| is also
-% acceptable,
-% but note that it requires \emph{four} capital letters to obtain
-% upper-case Roman or alphabetic numerals this way.
-%
-% \DescribeMacro{fraction}
-% The |fraction| key can be used to designate some wrong answers
-% as being worth partial credit. For example, a question might read thus:
+% 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$.
@@ -560,87 +656,116 @@
% \end{multi}
% \end{VerbatimOut}
% \inputminted[gobble=2,frame=lines]{latex}{minted.doc.out}
-% Thus the asterisk |*| is shorthand for |fraction=100|,
-% whereas a bare |\item| sets |fraction=0|.
-%
-% \DescribeMacro{single}
-% By default, the |multi| environment produces
-% a multiple choice question with only one correct answer;
-% this is called |single| mode, and on Moodle it appears with radio buttons.
-%
-% \DescribeMacro{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 |multiple|
-% or |single=false|.
-% The worth of each correct answers in |multiple| mode may be set by |fraction|,
-% but Moodle asks that all the fractions add up to \emph{exactly} 100.
-% If you simply designate each correct answer with |\item*|, then \textsf{moodle}
-% will divide equally among those answers the points lefts for a sum of 100\%.
-% Items that are not given a |fraction| are considered incorrect and selecting them
-% results in negative points such that the sum of all incorrect answers is -100\%.
+%
+% \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]{my question}
+% \begin{multi}[multiple]{Automatic Mode}
% Which numbers are prime?
-% \item[fraction=20] 2
+% \item 2
% \item* 5
% \item* 7
-% \item[fraction=-10] 1
+% \item 1
% \item 6
-% \item 8
% \end{multi}
-%
-% \begin{multi}[multiple]{my question}
+% \begin{multi}[multiple]{Advanced Mode}
% Which numbers are prime?
-% \item[fraction=20] 2
-% \item[fraction=40] 5
-% \item[fraction=40] 7
-% \item[fraction=-10] 1
-% \item[fraction=-45] 6
-% \item[fraction=-45] 8
+% \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 selecting all options to obtain a good grade with no merit.
-%
-% \DescribeMacro{allornothing}
+% 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
+% {``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
-% |allornothing| key.
-% The recommended way for designating correct answers is with |\item*|. If instead
-% the |fraction| is used, \textsf{moodle} moodle will consider that non-negative
+% \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 |allornothing| supersedes the options |multiple| and |single|.
-% To the best of our knowledge, Moodle does not offer the all-or-nothing behavior
-% for multiple choice questions embedded inside a cloze question.
-%
+% 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}}
%
-% A numerical question in Moodle requires the student
+% \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.
-% Its typical format is
+%
+% 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{options} \meta{correct answer} \\
+% \rule{2em}{0pt}|\item|\oarg{answer options} \meta{correct answer} \\
% |\end{numerical}|
% \end{quote}
-% If there is more than one correct answer, additional |\item|'s may be included.
+% 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 |fraction| key.
+% 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={You forgot to antidifferentiate!}]| \meta{incorrect answer}
+% |\item[fraction=0,feedback={Forgot to antidifferentiate?}]| \meta{incorrect answer}
% \end{quote}
%
-% \DescribeMacro{tolerance}
-% The |tolerance| key can be used to specify the validity of answers within some margin.
+% \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}
@@ -662,31 +787,34 @@
% \end{itemize}
%
% When feedback is to be given for any non-specified answer, one can add a \emph{last} answer
-% item containing the wilcard character |*| only. In this case, the |tolerance| key is irrelevant.
-%
-% Both answers and tolerance can be specified with the comma (|,|) as a decimal separator.
-% Exponent notation is accepted. After import, Moodle will recognize indifferently |0.000165|,
-% |0,000165|, |1.65E-4|, |1.65e-4|, |1,65E-4|, and |1,65e-4|.
+% item containing the wildcard character \texttt{*} only. In this case, the \optn{tolerance} key is irrelevant.
%
-% If the \textsf{siunitx} package is loaded, \textsf{moodle} will detect it and
-% numbers will be rendered nicely in the PDF output.
-%
-% Units, unit-handling and multipliers are currently unsupported.
+% 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}}
-% A short answer question resembles a numerical question: the student is to fill
-% in a text box with a missing word or phrase.
+%
+% \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{options} \meta{correct answer} \\
+% \rule{2em}{0pt}|\item|\oarg{answer options} \meta{correct answer} \\
% \rule{2em}{0pt}\quad$\vdots$ \\
-% \rule{2em}{0pt}|\item|\oarg{options} \meta{correct answer} \\
+% \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 |\blank|. For example,
-% your question might read
+% 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.
@@ -695,146 +823,176 @@
% \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,
+% 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.
-%
-% \DescribeMacro{case sensitive}\DescribeMacro{usecase}
-% The default setting when creating a Short Answer question in Moodle
+%
+% \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
-% \textsf{moodle}.
-% You can make a question case-sensitive with the key |case sensitive|
-% or its shorter synonym |usecase|.
+% \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 wildcard character |*| can used to grab answers that match
-% a specific pattern. For instance:
-% \begin{itemize}
-% \item ``\emph{Sir Isaac Newton}'', ``\emph{Isaac Newton}'' and
-% ``\emph{Newton}'' will match the pattern |*Newton|,
-% \item ``\emph{Gaston}'' and ``\emph{Wellington}'' will match the
-% pattern |*ton|,
-% \item ``\emph{Isaac}'' and ``\emph{Isaac Newton}'' will match the
-% pattern |Isaac*|,
-% \item any non empty answer will match the pattern |*| (wildcard alone).
+% 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}
-% 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
+%
+% \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|\oarg{options} \meta{notes for grader} \\
+% \rule{2em}{0pt}|\item| \meta{information 1 for grader} \\
% \rule{2em}{0pt}\quad$\vdots$ \\
-% \rule{2em}{0pt}|\item|\oarg{options} \meta{notes for grader} \\
+% \rule{2em}{0pt}|\item| \meta{information $n$ for grader} \\
% |\end{essay}|
% \end{quote}
-% Instead of containing answers, the |\item| tags for the |essay| question
-% contain notes that will appear to whoever is grading the question manually.
-%
-% \DescribeMacro{response required}
-% Although Moodle cannot grade the content of an essay question,
+% 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 |response required| key is set, Moodle will insist that the student
+% 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.
-%
-% \DescribeMacro{response format}
-% 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:
+%
+% \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}
-% \item[{\ttfamily html}] An editor with the ability to format HTML responses
+% \ItemDescribeOther[response format]{html} An editor with the ability to format \HTML\ responses
% including markup for italics, boldface, etc. This is the default.
-% \item[{\ttfamily file}] A file picker allowing the student to upload a
-% file, such as a PDF or DOC file, containing the essay.
-% \item[{\ttfamily 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
+% \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.
-% \item[{\ttfamily text}] This editor allows only for entering plain text
+% \ItemDescribeOther[response format]{text} This editor allows only for entering plain text
% without any markup.
-% \item[{\ttfamily monospaced}] This yields a plain text editor, without any
-% markup, and with a fixed-width font. This could be useful for
+% \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}
-%
-% \DescribeMacro{response field lines}
-% The key |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, \textsf{moodle} will approximate the value:
+%
+% \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}
-% The default is |response field lines=15|.
-%
-% \DescribeMacro{attachments allowed}
-% The |attachments allowed| key controls \emph{how many} attachments a student is
-% allowed to upload. Permissible values are |0|, |1|, |2|, |3|, or |unlimited|.
-%
-% \DescribeMacro{attachments required}
+%
+% \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 |attachments required| to |0|, |1|, |2|, or |3|.
-%
-% \DescribeMacro{template}
+% 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 |template=|\marg{template}.
+% 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}}
-%
-% A matching question offers a series of subquestions
-% and a set of possible answers from which to choose.
-% If there are $m$ questions and $n\geq m$ possible answers,
-% a matching question will look like this:
-%
+%
+% \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|\oarg{options} \meta{question 1} |\answer| \meta{answer 1}\\
-% \rule{2em}{0pt}|\item|\oarg{options} \meta{question 2} |\answer| \meta{answer 2}\\
+% \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|\oarg{options} \meta{question $m$} |\answer| \meta{answer $m$}\\
-% \rule{2em}{0pt}|\item|\oarg{options} |\answer| \meta{answer $m+1$}\\
+% \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|\oarg{options} |\answer| \meta{answer $n$}\\
+% \rule{2em}{0pt}|\item| |\answer| \meta{no match $n$}\\
% |\end{matching}|
% \end{quote}
-% Answers $1$ through $m$ correspond to questions $1$ through $m$;
-% answers $m+1$ through $n$ are ``decoy'' answers.
-% If multiple questions should have the same answer,
-% be sure your typed answer match exactly, so that Moodle will not
-% create duplicate copies of the same answer!
-%
-% \DescribeMacro{shuffle}
-% The |matching| question accepts the option of |shuffle| to randomly
-% permute the questions and answers; by default |shuffle=true|.
-%
-% \DescribeMacro{drag and drop}\DescribeMacro{dd}
-% The standard matching question offered by Moodle corresponds to
-% a dropdown box for choosing the answer to each question.
-% There also exists a \href{https://docs.moodle.org/310/en/Drag_and_drop_matching_question_type}
-% {``drag and drop matching''} plugin for Moodle that
-% shows all questions in one column,
-% all answers in a second column, and allows students to drag the correct
-% answer to the question using a mouse.
+% \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
-% `|drag and drop|' or `|dd|' for short. The default is |dd=false|.
-% If you choose the standard format, then due to the limitations of
-% dropdown boxes, no \LaTeX\ or HTML code can be used in the answers.
-%
+% \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}}
-%
-% A ``cloze question'' has one or more subquestions embedded within a passage of text.
+%
+% \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 |multi|, |shortanswer|, or |numerical| environments
-% within a |cloze| environment, as in the following example:
+% 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
@@ -855,44 +1013,84 @@
% \end{cloze}
% \end{VerbatimOut}
% \inputminted[gobble=2,frame=lines]{latex}{minted.doc.out}
-% Note that when used as a subquestion within a cloze question,
-% |\begin{multi}| is \emph{not} followed by name in braces;
-% the same is true for the |shortanswer| and |numerical|
-% environments.
-%
-% \DescribeMacro{single=true}\DescribeMacro{single=false}\DescribeMacro{multiple}
-% Before Moodle version 3.5, within a cloze question, a multiple choice question
-% was necessarily of type |single|, i.e. with a single good answer. If you intend
-% to export your quiz to Moodle 3.5+, the option |multiple| can be used, when
-% multiple good answers are to be found.
-%
-% \DescribeMacro{vertical}\DescribeMacro{horizontal}\DescribeMacro{inline}
-% Within a cloze question, by default, a multiple choice question is implemented
-% as an |inline| dropdown box. This is visually compact, but it also prevents
-% the use of mathematical or HTML formatting.
-% Adding the option |vertical| displays the subquestion as a vertical column
-% of radio buttons instead; likewise the option |horizontal| creates a horizontal
-% row of radio buttons.
-% The option |inline| is incompatible with |multiple| or |single=false|
+%
+% 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}
%
-% \DescribeMacro{shuffle}
-% Starting from Moodle version 3.0, within a cloze question, the items of a
-% multiple choice question can be shuffled. Setting |shuffle=false| will
+% \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 |shuffle=true|.
+% 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}.
%
-% \DescribeMacro{case sensitive}\DescribeMacro{usecase}
-% Within a cloze question, the short answer question can be made case sensitive.
-% This option, disabled by default, is selected with |case sensitive| or |usecase|.
-%
%\subsubsection{\href{https://docs.moodle.org/en/Description_question_type}{Description}}
-%
-% The Moodle description type is not really a question. It is more like a label.
-% One can set a |feedback| that the student gets when reviewing the submission.
+%
+% \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, \textsf{moodle} redefines the existing |description| environment.
+%
+% 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}
@@ -902,11 +1100,11 @@
% \end{quote}
%
% \subsection{Summary of the Key Options}
-%
-% Table~\ref{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~\ref{subsubsect:essay}.
-%
+%
+% 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.}
@@ -916,17 +1114,17 @@
% \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} &
+% 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}{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$ &
+% \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$ & & & &
@@ -935,12 +1133,12 @@
% 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$ & $\bullet$ & \\
+% & $\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}
+% \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%
@@ -953,322 +1151,779 @@
% & $\bullet$ & & & $\bullet$ & $\bullet$ \\
% \hspace{1em}Multi (inline) & $\bullet$ & & & & $\bullet$ & & &
% & & & & $\bullet$ & $\bullet$ \\
-% \hspace{1em}Multi (horizontal)& $\bullet$ & & & & $\bullet$ & & $\bullet$
+% \hspace{1em}Multi (horiz.) & $\bullet$ & & & & $\bullet$ & & $\bullet$
% & & & & & $\bullet$ & $\bullet$ \\
-% \hspace{1em}Multi (vertical)& $\bullet$ & & & & $\bullet$ & & $\bullet$
+% \hspace{1em}Multi (vert.) & $\bullet$ & & & & $\bullet$ & & $\bullet$
% & & & & & $\bullet$ & $\bullet$ \\
% \bottomrule
% \end{tabular}
% \end{table}
+%
+% \subsection{Automated Generation of Questions}
%
-% \section{Conversion to HTML}
+% \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.
%
-% Questions should be typed as usual for \LaTeX,
-% including |\$| to obtain dollar signs, |$|'s or |\(|...|\)| for math shifts,
-% |$$|'s or |\[|...|\]| for display math, et cetera.
-% The package \textsf{moodle.sty} automatically converts
-% this \LaTeX\ code into HTML for web display.
+% \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.
%
-% Table~\ref{tab:html} lists \LaTeX\ macros, commands, and environments that
-% are specifically converted to HTML.
+% \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{Conversion of \LaTeX\ material to HTML.}
-% \label{tab:html}
-% \begin{tabular}{llll}
+% \caption{Text mode diacritic macros undergoing a tailored conversion to \HTML.}
+% \label{tab:diacritics}
+% \begin{threeparttable}
+% \begin{tabular}{clll}
% \toprule
-% \multicolumn{2}{l}{Macros} & Commands & Environnments \\
-% \cmidrule(lr){1-2}\cmidrule(lr){3-3}\cmidrule(lr){4-4}
-% |\%| & |\#| &|\emph{}| & |\begin{center}|\\
-% |\$| & |\&| &|\textbf{}| & |\begin{enumerate}|\\
-% |\\| & |\par| &|\textit{}| & |\begin{itemize}|\\
-% |\&| & |\S| & |\texttt{}| & |\begin{tikzpicture}|\\
-% |\{| & |\}| & |\textsc{}| & \\
-% |\|\textvisiblespace & |\relax| & |\underline{}| &\\
-% |\,| & |\thinspace| & |\textsuperscript{}| & \\
-% |\dots| & |\ldots| & |\up{}| & \\
-% |\euro| & |\texteuro| & |\fup{}| & \\
-% |\TeX| & |\LaTeX|& |\textsubscript{}| & \\
-% |\_| & |\textbackslash| & |\url{}| & \\
-% |~| & & |\href{}{}| & \\
-% & & |\tikz[]{}| & \\
-% & & |\includegraphics[]{}| & \\
-% & & |\verbatiminput{}| & \\
-% & & |\VerbatimInput[]{}| & \\
-% & & |\LVerbatimInput[]{}| & \\
-% & & |\BVerbatimInput[]{}| & \\
-% & & |\inputminted[]{}{}| & \\
+% 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}
-% Single and double quotation marks (with german variants), french quotation marks,
-% inverted exclamation and question marks, and the diacritical
-% commands |\^|, |\'|, |\`|, |\"|, |\~|, |\c|, |\H|, |\k|, |\u| and |\v| are
-% also handled, as are the characters |\aa|, |\ae|, |\l|, |\oe|,
-% |\o|, |\ss|, and their capitalizations. See Tables~\ref{tab:diacritical},
-% \ref{tab:ligatures}, and \ref{tab:other} for more details.
-%
-% In addition, |<| and |>| will be converted to |&lt;| and |&gt;| \emph{within math mode only}.
-% If they should be typed outside of math mode, they will be passed as typed to
-% the HTML, and probably interpreted by students' browsers as HTML tags
-% or other unpredicated results.
-% A doubled dash will be converted to en-dash |&ndash;| \emph{outside math mode}.
%
-% Be aware that \emph{\textsf{moodle} 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.
+% In addition, |<| and |>| will be converted to their HTML equivalents |&lt;|
+% and |&gt;| in the \XML\ file. This prevents portions of the code to be
+% interpreted by \Moodle\ as \HTML\ tags.
%
-% \DescribeMacro{\htmlonly}The |\htmlonly|\oarg{Content for traditional output}
-% \marg{HTML content} command is 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
+% A doubled dash will be converted to en-dash |&ndash;| \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.
+% ignored for the \XML\ output.
% For instance, one can write code like this in a question environment
% \begin{quote}
% |\htmlonly[\fbox{PDF contents}]{|\\
-% |<div style="border: 1px solid green; display: inline-block;">|\\
+% |<div style="border: 1px solid; display: inline-block;">|\\
% \rule{10em}{0pt}|HTML contents</div>|\\
% |}|
% \end{quote}
%
-% \DescribeMacro{\htmlregister}The |\htmlregister| command lets you specify
-% the macros that must be expanded in the XML file. It works only when no
-% optional argument is used.
-%
-% \DescribeMacro{\moodleregisternewcommands}
-% When the list of macros is long, it becomes cumbersome to record them
-% individually for expansion.
-% Calling |\moodleregisternewcommands| triggers the automatic
-% expansion of macros defined subsequently using |\newcommand|,
-% |\renewcommand|, |\providecommand|, or their starred variants.
+% \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.
-%
-% If you think of another \LaTeX\ command that should be changed to an HTML
-% equivalent, please have a look at Section~\ref{sec:dev}.
-%
-% \section{Graphics}
-% The \textsf{moodle} package can handle two kinds of graphics seamlessly.
-% External graphics files may be included with the |\includegraphics| command
-% from the |graphicx| package, and graphics may be generated internally using \TikZ.
+% 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
+% 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.
-%
-% \subsection{Default \texttt{includegraphics}}
-% \DescribeMacro{\includegraphics}\DescribeMacro{height}\DescribeMacro{width}
-% When using |\includegraphics|, the only options currently supported
-% are |height| and |width|. Attempts to use other |\includegraphics| options,
-% such as |scale| or |angle|, will affect the PDF but not the XML output.
-% The dimensions set by |height| and |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
+%
+% \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
-% |<IMG HEIGHT=103 WIDTH=103 SRC="...">| showed up as almost exactly 1 inch
-% tall and 1 inch wide on several of this author's devices and browsers
+% number was selected because an image with
+% |<IMG HEIGHT=103 WIDTH=103 SRC="...">| 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.}
-% \DescribeMacro{ppi}
-% That value may be changed by setting the |ppi| key (e.g., |ppi=72|);
-% this is probably best done for the entire document with a |\moodleset| command,
+% \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{\graphicspath}
-% You can use |\graphicspath{{|\emph{path}|}}| to specify a directory where the
-% pictures to be included are located.
-%
-% A special rule was added for the inclusion of GIF pictures (|.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{\DeclareGraphicsAlien} Users may declare other graphic
-%^^A formats with the command |\DeclareGraphicsAlien|\marg{alien extension}
+%
+% \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}.
%
-% \subsection{\TikZ\ Pictures}
-% \TikZ\ is a user-friendly syntax layer for PGF, the macro \LaTeX\ package for creating
-% graphics. Users that are not familiar with TikZ\ can learn more here:
-% \url{https://ctan.org/pkg/pgf}.
-%
-% When \TikZ\ is loaded and used to define pictures, \textsf{moodle} invokes
-% the |external| \TikZ\ library, so that each |tikzpicture| environment is compiled
-% to a freestanding PDF file.
+% \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}.
%
-% \subsection{Package Option \texttt{tikz}}\label{subsec:tikz}
-% \DescribeMacro{tikz}
-% The \textsf{moodle} package admits a \texttt{tikz} option which has the following effects:
+% 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 \texttt{tikz} is loaded.
-% \item \texttt{includegraphics} is embedded in a \TikZ\ picture. Consequences are that
+% \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 \texttt{includegraphics} options is accessible,
-% e.g.~|scale=.5|, |angle=90|, or |width=.2\textwidth|.
+% \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{\embedaspict} a macro |\embedaspict{...}| is provided for the
-% inclusion of inline \LaTeX\ material as images. This can serve as a workaround to
-% overcome limitations of this package---like the conversion of tabulars to HTML---
-% or limitations of Moodle itself.
-% For the definition of this macro, the package \texttt{varwidth} is loaded.
-% \item optimizations of the \TikZ-external library are disabled. Compilation might get
+% \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}
%
-% \subsection{External Tools}
+
+% \subsubsection{External Tools}
% The mechanisms used for handling graphics are somewhat fragile and rely upon
% three free external programs.
% \begin{enumerate}
-% \item 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 |gswin64c.exe|
-% (if |\ifwindows| from the |ifplatform| package returns true)
-% or |gs| (if |\ifwindows| returns false).
-% If your system requires a different command line to invoke Ghostscript,
-% \DescribeMacro{\ghostscriptcommand}
+% \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 open-source ImageMagick software (\url{www.imagemagick.org})
-% converts each file to PNG format.
-% The command line for ImageMagick is the nondescript word |convert|,
-% \DescribeMacro{\imagemagickcommand}
-% but may be changed by invoking |\imagemagickcommand|\marg{executable filename}.
-% \item OptiPNG (\url{http://optipng.sourceforge.net/}) is used to optimize the PNG images.
-% The command line is presumed to be |optipng|, but can be changed with
-% \DescribeMacro{\optipngcommand} |\optipngcommand|\marg{executable filename}.
+% \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 |pdflatex|. Including PS graphics or using \TikZ\ with the DVI$\to$PS workflow is not
+% \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 Ghostscript and ImageMagick installed on your system
-% to fully use the graphics-handling capabilities of \textsf{moodle}.
-% \item If 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, |\write18| must be enabled.
-% For Mik\TeX, this means adding |--enable-write18| to the command line of |pdflatex|;
-% for \TeX Live, this means adding |--shell-escape=true|.
-% \item Due to security issues with old versions of Ghostcript, some systems default to a
-% policy that prevents the conversion of PDF and PS to PNG. Assuming that, as a user of
-% \textsf{moodle} which requires shell escape capabilities, you either use a sandboxed
+% \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-zelous security policy. For example,
+% over-zealous security policy. For example,
% \href{https://stackoverflow.com/a/52661288/14608059}{see this}.
-% \item Users of the |circuitikz| package (\url{https://www.ctan.org/pkg/circuitikz}) must
+% \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 |circuitikz| environment. That is required, as of \TikZ\ 2.1,
-% by the |external| library.
+% the historical \env{circuitikz} environment. That is required, as of \TikZ\ 2.1,
+% by the \pkg{external} library.
% \end{itemize}
%
-% \subsection{Package Option \texttt{svg}}\label{subsec:svg}
+% \subsubsection{Package Option \optn{svg}}\label{subsec:svg}
%
-% \paragraph{Important Notice} \emph{The \texttt{svg} option is an experimental feature
-% introduced in \textsf{moodle} v0.8. It has been tested exclusively under Linux, with
-% TeXLive 2020, Inkscape v1.0.1 and Scour 0.38.2.}
-%
-% \DescribeMacro{svg} The \textsf{moodle} package admits an experimental \texttt{svg}
-% option which has the following effects:
+% \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 |\includegraphics| can be used to import SVG graphic files directly
-% (extension |.svg| or |.SVG|). In this case, the SVG file is passed as-is to the
-% XML output and is converted using \href{https://inkscape.org/}
-% {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 beeing
-% rasterized. Before inclusion to the XML output, the SVG file is optimized using
+% \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 unoptimized SVG file will be passed to the XML output.
-% Two processes benefit from this PDF$\to$SVG conversion:
+% 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 |\includegraphics|, and
-% \item Tikz pictures that are externalized.
+% \item inclusion of \PDF\ graphics with \cmd{\includegraphics}, and
+% \item \TikZ\ pictures that are externalized.
% \end{itemize}
% \end{itemize}
%
-% \DescribeMacro{\PDFtoSVGcommand}\DescribeMacro{\SVGtoPDFcommand}
-% \DescribeMacro{\optiSVGcommand} The call of external tools can be changed using
-% the macros |\PDFtoSVGcommand| \marg{\dots}, |\SVGtoPDFcommand|\marg{\dots} and
-% |\optiSVGcommand|\marg{\dots}.
%
-% \section{Verbatim Code}
-% Because, for HTML translation, \textsf{moodle} parses the body of questions, the use of
+% 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|,
-% |\begin{verbatim}| and other standard utilities is not supported.
+% \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 \DescribeMacro{\verbatiminput}|\verbatiminput|\marg{filename} from the \textsf{verbatim}
-% package inserts verbatim code in both the PDF and the XML for moodle, without fancy additions.
-% \item \DescribeMacro{\VerbatimInput}The macro |\VerbatimInput|\marg{options}\marg{filename} from
-% \textsf{fancyvrb} or \textsf{fvextra} does more, with several options and settings offered
-% (see below).
-% The variants \DescribeMacro{\BVerbatimInput}|\VBerbatimInput| and
-% \DescribeMacro{\LVerbatimInput}|\LVerbatimInput| are also supported, with identical
-% effect on the XML output.
+% \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 \DescribeMacro{\inputminted}On top of that |\inputminted|\oarg{options}\marg{lang}
-% \marg{filename}from the \textsf{minted} package offers syntaxic highlighting tailored to the
-% specified language.
+% \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 \textsf{moodle} package handles these three commands to pass the code in the output XML.
-% With |\inputminted|, an external Python tool, \textsc{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 as-is to the XML. A drawback of this approach, is that characters |<|, |>|,
-% |&|, |'|, and |"| are likely to mislead the web browser rendering the question on Moodle.
+% 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 |\VerbatimInput| and |\inputminted|, the options that are taken care of for XML
-% generation are listed in Table~\ref{tab:verbatim-options}. Using |\fvset|\marg{key=value,...},
-% options can be set globally. Equivalently, with \textsf{minted},
-% |\setminted|\oarg{lang}\marg{key=value,...} is available.
+% 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 \texttt{VerbatimInput} and \texttt{inputminted}.}
+% \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\texttt{commentchar} & \meta{character}\\
-% \texttt{gobble} & \meta{integer}\\
-% \texttt{autogobble}\tnote{1} & \texttt{true} or \texttt{false}\\
-% \texttt{tabsize} & \meta{integer}\\
-% \texttt{numbers} & \texttt{none}, \texttt{left}, \texttt{right}, or \texttt{both}\tnote{2}\\
-% \texttt{firstnumber} & \texttt{auto}, \texttt{last}, or \meta{integer}\\
-% \texttt{firstline} & \meta{integer}\\
-% \texttt{lastline} & \meta{integer}\\
-% \texttt{numberblanklines} & \texttt{true} or \texttt{false}\\
-% \texttt{highlightlines}\tnote{2} & \marg{coma-separated list of integers or ranges}\\
-% \texttt{style}\tnote{1} & \meta{string}\\
+% ^^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] \texttt{autogobble}, \texttt{numbers=both}, and \texttt{style} are offered only by \textsf{minted}.
-%\item[2] line highlighting is offered only with \textsf{fvextra} or \textsf{minted} loaded.
+%\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 \textsf{moodle} questions, the environments |filecontents*| (from the
-% \textsf{filecontents} package or \LaTeX\ kernel itself since 2019) or |VerbatimOut|
-% (from the \textsf{fancyvrb} and \textsf{fvextra} packages).
-%
+% 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}
@@ -1294,12 +1949,9 @@
% \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={No. On line 3, there is only a comment.},
-% fraction=0] 3
-% \item[feedback={No. On line 5, the package \texttt{moodle} is loaded.},
-% fraction=0] 5
+% 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.\\
@@ -1315,117 +1967,184 @@
% \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, |\LVerbatimInput| or
-% |\BVerbatimInput| can be used. Instead, when \textsf{minted} is used, the ``left-right'' mode can be
+%
+% 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 \textsf{fancyvrb}, \textsf{fvextra}, or \textsf{minted}, \textsf{moodle}
-% sets framing options for the display of code in the output PDF:
+% 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 overidden using |\fvset| after the preamble.
+% These settings can be overridden using \cmd{\fvset} after the preamble.
%
-% \section{Calculated Questions}
-% Moodle's calculated questions are not supported by this package.
-%
-% However, as \href{https://github.com/avohns/python-latex-moodle-quiz}{demonstrated by A.
-% Vohns}, an advanced scripting language may be used to generate a series of questions sharing
-% the same prototype.
-%
-% We suggest to apply a specific tag to these questions. After import in Moodle, when creating
-% a quizz, this tag can be selected to narrow down a random selection of questions.
-% This would mimic the behavior of calculated questions while bringing the flexibility of your
-% favorite scripting language.
-%
-% Here are two examples inspired from the work of A. Vohns. The first one relies on the
-% native 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}
-% \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=4 else points=3 end
-% cloze_print({x,y},points)
-% end
-% end
-% end
-% \end{VerbatimOut}
-% \inputminted[]{lua}{minted.doc.out}
-% \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 \textsf{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}
-% \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=4
-% else:
-% points=3
-% cloze_print([x,y],points)
-% \end{VerbatimOut}
-% \inputminted[]{python}{minted.doc.out}
-% \begin{VerbatimOut}[gobble=1]{minted.doc.out}
-% \end{python}
-% \end{quiz}
-% \end{VerbatimOut}
-% \inputminted[gobble=2,frame=bottomline]{latex}{minted.doc.out}
-% These two codes yield the same XML content.
-%
-% \section{Known Limitations and Call for Bug Reports}
-% Table~\ref{tab:support-limitations} lists some features supported, limitations, and
-% bugs.
+% \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,
+%\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}
@@ -1433,23 +2152,23 @@
% & \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/35/en/Multiple_Choice_question_type}{Multichoice}
+% \href{https://docs.moodle.org/en/Multiple_Choice_question_type}{Multichoice}
%& yes & yes & yes \\
-% \href{https://docs.moodle.org/35/en/Numerical_question_type}{Numerical}
+% \href{https://docs.moodle.org/en/Numerical_question_type}{Numerical}
%& yes & no\tnote{1} & yes \\
-% \href{https://docs.moodle.org/35/en/Short-Answer_question_type}{Short Answer}
+% \href{https://docs.moodle.org/en/Short-Answer_question_type}{Short Answer}
% & yes & no\tnote{1} & yes \\
-% Matching (\href{https://docs.moodle.org/35/en/Matching_question_type}{std})
+% Matching (\href{https://docs.moodle.org/en/Matching_question_type}{std})
%& yes & no\tnote{2} & no\tnote{3} \\
-% Matching (\href{https://docs.moodle.org/35/en/Drag_and_drop_matching_question_type}{dd})
+% 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/35/en/Essay_question_type}{Essay}
+% \href{https://docs.moodle.org/en/Essay_question_type}{Essay}
%& yes & yes\tnote{5,6} & yes\tnote{5} \\
-% \href{https://docs.moodle.org/35/en/True/False_question_type}{True/False}
+% \href{https://docs.moodle.org/en/True/False_question_type}{True/False}
%& yes & no & yes \\
-% \href{https://docs.moodle.org/35/en/Description_question_type}{Description}
+% \href{https://docs.moodle.org/en/Description_question_type}{Description}
%& yes & $\varnothing$ & yes \\
-%\href{https://docs.moodle.org/35/en/Embedded_Answers_(Cloze)_question_type}{Cloze} &
+%\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} \\
@@ -1458,258 +2177,189 @@
%\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
+%\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
+%\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
+%\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 \textsf{dmlwriteexception} when
-%the field content exceeds few hundreds characters. This prevents the inclusion
+%\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
+%\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
+%\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
+%\item[7] \Moodle\ only reveals the feedback when hovering the checkmark or X
%mark with the mouse.
%\end{tablenotes}
%\end{threeparttable}
%\end{table}
-% Tables~\ref{tab:diacritical}, \ref{tab:ligatures}, and \ref{tab:other} describe the current
-% state of support special characters, accents and other diacritical marks.
-%\begin{table}[tbp]
-% \centering
-% \caption{Support for diacritical marks
-% in a UTF8-coded \TeX~document compiled with (pdf)\LaTeX\ (packages
-% \texttt{inputenc} with option \texttt{utf8} and \texttt{fontenc} with option \texttt{T1}),
-% \LuaLaTeX\ or \XeLaTeX\ (package \texttt{fontspec}).}
-% \label{tab:diacritical}
-% \begin{threeparttable}[t]
-% \begin{tabular}{*{6}{l}}
-% \toprule
-% \multicolumn{4}{l}{Input type} & \multicolumn{2}{l}{Engine support}\\
-% \cmidrule(lr){1-4}\cmidrule(lr){5-6}
-% \multicolumn{2}{l}{Unicode} & \multicolumn{2}{l}{\LaTeX} & \XeLaTeX\ or \LuaLaTeX & (pdf)\LaTeX \\
-% \cmidrule(lr){1-2}\cmidrule(lr){3-4}\cmidrule(lr){5-5}\cmidrule(lr){6-6}
-% \aa & \AA & \verb|\aa| & \verb|\AA| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \`a & \`A & \verb|\`a| & \verb|\`A| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \^a & \^A & \verb|\^a| & \verb|\^A| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \~a & \~A & \verb|\~a| & \verb|\~A| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \'e & \'E & \verb|\'e| & \verb|\'E| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \`e & \`E & \verb|\`e| & \verb|\`E| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \"e & \"E & \verb|\"e| & \verb|\"E| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \^e & \^E & \verb|\^e| & \verb|\^E| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \^i & \^I & \verb|\^i| & \verb|\^I| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \"i & \"I & \verb|\"i| & \verb|\"I| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \~n & \~N & \verb|\~n| & \verb|\~N| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \~o & \~O & \verb|\~o| & \verb|\~O| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \"o & \"O & \verb|\"o| & \verb|\"O| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \^o & \^O & \verb|\^o| & \verb|\^O| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \`u & \`U & \verb|\`u| & \verb|\`U| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \"u & \"U & \verb|\"u| & \verb|\"U| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \^u & \^U & \verb|\^u| & \verb|\^U| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \c{c} & \c{C} & \verb|\c{c}| & \verb|\c{C}| & Unicode and \LaTeX & Unicode and \LaTeX \\
-% \c{s} & \c{S} & \verb|\c{s}| & \verb|\c{S}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \c{t} & \c{T} & \verb|\c{t}| & \verb|\c{T}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \H{o} & \H{O} & \verb|\H{o}| & \verb|\H{O}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \H{u} & \H{U} & \verb|\H{u}| & \verb|\H{U}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \"y & \"Y & \verb|\"y| & \verb|\"Y| & Unicode and \LaTeX & \LaTeX only\\
-% \k{a} & \k{A} & \verb|\k{a}| & \verb|\k{A}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \k{e} & \k{E} & \verb|\k{e}| & \verb|\k{E}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \k{i} & \k{I} & \verb|\k{i}| & \verb|\k{I}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \k{o} & \k{O} & \verb|\k{o}| & \verb|\k{O}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \k{u} & \k{U} & \verb|\k{u}| & \verb|\k{U}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \u{a} & \u{A} & \verb|\u{a}| & \verb|\u{A}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \u{e} & \u{E} & \verb|\u{e}| & \verb|\u{E}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \u{g} & \u{G} & \verb|\u{g}| & \verb|\u{G}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \u{\i} & \u{I} & \verb|\u{\i}| & \verb|\u{I}| & Unicode and \LaTeX & \LaTeX\ only\tnote{1}\\
-% \u{o} & \u{O} & \verb|\u{o}| & \verb|\u{O}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \v{c} & \v{C} & \verb|\v{c}| & \verb|\v{C}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \v{d} & \v{D} & \verb|\v{d}| & \verb|\v{D}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \v{e} & \v{E} & \verb|\v{e}| & \verb|\v{E}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \v{l} & \v{L} & \verb|\v{l}| & \verb|\v{L}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \v{n} & \v{N} & \verb|\v{n}| & \verb|\v{N}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \v{r} & \v{R} & \verb|\v{r}| & \verb|\v{R}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \v{s} & \v{S} & \verb|\v{s}| & \verb|\v{S}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \v{t} & \v{T} & \verb|\v{t}| & \verb|\v{T}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \v{z} & \v{Z} & \verb|\v{z}| & \verb|\v{Z}| & Unicode and \LaTeX & \LaTeX\ only\\
-% \bottomrule
-% \end{tabular}
-% \begin{tablenotes}
-% \item[1] The rendering of |\u{i}| is flawed in (pdf)\LaTeX's traditional output.
-% ^^A \XeLaTeX\ renders correctly |\u{i}|, that is, without a superscript dot.
-% ^^A Instead, with (pdf)\LaTeX\ the rendering of |\u{i}| is flawed by the
-% ^^A superposition of the superscript dot and the breve diacritical mark.
-% ^^A Both engines render |\u{\i}| as expected.
-% \end{tablenotes}
-% \end{threeparttable}
-% \end{table}
%
-%\begin{table}[tbp]
-% \centering
-% \begin{threeparttable}[t]
-% \caption{Support for ligatures in a UTF8-coded \TeX~document compiled with (pdf)\LaTeX\ (packages
-% \texttt{inputenc} with option \texttt{utf8}, \texttt{fontenc} with option \texttt{T1}),
-% \LuaLaTeX\ or \XeLaTeX\ (package \texttt{fontspec}).}
-% \label{tab:ligatures}
-% \begin{tabular}{llllll}
-% \toprule
-% \multicolumn{4}{l}{Input type} & \multicolumn{2}{l}{Engine support}\\
-% \cmidrule(lr){1-4}\cmidrule(lr){5-6}
-% \multicolumn{2}{l}{Unicode} & \multicolumn{2}{l}{\LaTeX} & \XeLaTeX \ or \LuaLaTeX& (pdf)\LaTeX \\
-% \cmidrule(lr){1-2}\cmidrule(lr){3-4}\cmidrule(lr){5-6}\cmidrule(lr){6-6}
-% \ae & \AE & \verb|\ae| & \verb|\AE| & Unicode and \LaTeX & \LaTeX\ only\\
-% \oe & \OE & \verb|\oe| & \verb|\OE| & Unicode and \LaTeX & \LaTeX\ only\\
-% \ss & \SS & \verb|\ss| & \verb|\SS| & Unicode and \LaTeX\tnote{1} & \LaTeX\ only\tnote{2}\\
-% \bottomrule
-% \end{tabular}
-% \begin{tablenotes}[b]
-% \item[1] the Libertine font, used in this documentation and available for instance via the
-% package |libertine|, defines the glyph \SS. Most fonts do not define this glyph.
-% \item[2] \LaTeX\ defines the \verb|\SS| macro but (pdf)\LaTeX\ renders it as a doubled capital S.
-% \end{tablenotes}
-% \end{threeparttable}
-% \end{table}
-%
-%\begin{table}[tbp]
-% \centering
-% \begin{threeparttable}[b]
-% \caption{Support for other glyphs and punctuation marks in a UTF8-coded \TeX~document compiled
-% with (pdf)\LaTeX\ (packages \texttt{inputenc} with option \texttt{utf8}, \texttt{fontenc} with
-% option \texttt{T1}), \LuaLaTeX\ or \XeLaTeX\ (package \texttt{fontspec}).}
-% \label{tab:other}
-% \begin{tabular}{llllll}
-% \toprule
-% \multicolumn{4}{l}{Input type} & \multicolumn{2}{l}{Engine support}\\
-% \cmidrule(lr){1-4}\cmidrule(lr){5-6}
-% \multicolumn{2}{l}{Unicode} & \multicolumn{2}{l}{\LaTeX} & \XeLaTeX\ or \LuaLaTeX & (pdf)\LaTeX \\
-% \cmidrule(lr){1-2}\cmidrule(lr){3-4}\cmidrule(lr){5-5}\cmidrule(lr){6-6}
-% \l & \L & \verb|\l| & \verb|\L| & Unicode and \LaTeX & \LaTeX\ only\\
-% \o & \O & \verb|\o| & \verb|\O| & Unicode and \LaTeX & \LaTeX\ only\\
-% « & & \verb|\guillemotleft|\tnote{1} & & Unicode and \LaTeX & \LaTeX\ only\\
-% » & & \verb|\guillemotright|\tnote{1} & & Unicode and \LaTeX & \LaTeX\ only\\
-% ¿ & & \verb|\textquestiondown| & & Unicode and \LaTeX & \LaTeX\ only\\
-% ¡ & & \verb|\textexclamdown| & & Unicode and \LaTeX & \LaTeX\ only\\
-% \bottomrule
-% \end{tabular}
-% \begin{tablenotes}
-% \item[1] for the same symbols the package |babel| defines |\flqq| and |\frqq|, and
-% if loaded with option |french| defines |\og| and |\fg|. These commands
-% are also supported by \textsf{moodle}.
-% \end{tablenotes}
-% \end{threeparttable}
-% \end{table}
-%
-% Some features of Moodle quizzes have not yet been implemented in \textsf{moodle}.
+% 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,
+% \item \Moodle's feature of designating feedback for correct,
% partially correct, and incorrect answers.
-%^^A \item Calculated questions; that is, automatically generated numerical questions
+%^^A \item Calculated questions; that is, automatically generated \env{numerical} questions
%^^A using randomly chosen numbers.
% \item Hints
-% \item Units handling in numerical questions
+% \item Units handling in \env{numerical} questions
% \end{itemize}
-% 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. If you run into a problem, please have a look at Section~\ref{sec:dev}.
-%
-% \section{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.
-% Future versions of this package might include some support for
-% specifying your version of Moodle in the |.tex| file to help ensure compatibility.
-%
-% As the ultimate purpose of this package is the generation of XML files,
-% future versions of \textsf{moodle} will attempt to maintain backwards
-% compatibility with earlier versions regarding the XML output, apart from
+%
+% \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 |.tex| file with a future version
-% of \textsf{moodle} should produce the same XML file it does now
+% 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.
-%
-%
-% \section{Unrelated Tip: Quality of Moodle \TeX\ Images}
-% This has nothing to do with \textsf{moodle}, but is a Frequently Asked Question
+% \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
+% 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
+% 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.
-%
-% \clearpage
-% \section{Package Development}\label{sec:dev}
-% 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 \textsf{GitHub}, \textsf{Gitlab.com}, or
-% \textsf{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.
+% instead of \Moodle, producing much higher-quality results.
%
-% 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 |.tex| file shunk down
-% to the strict minimum (loaded packages, code, \dots) while still showing the
-% faulty behavior upon compilation.
-% \item Gather and send the |*.tex|, |*.log| and |*-moodle.xml| files together
-% with an explanation about
-% \begin{itemize}
-% \item your working environment (\TeX\ engine and distribution, operating
-% system, \dots),
-% \item the faulty behavior, and
-% \item what you expected instead.
-% \end{itemize}
-% \end{enumerate}
-%
% ^^A\clearpage
% \changes{v0.5}{2016/01/05}{Initial version}
-% \changes{v0.6}{2019/02/18}{Bux-fixing release}
+% \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}
-% \begin{changelog}[title={Version History},author={Matthieu Guerquin-Kern}]
+% \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/310/en/All_or_nothing_multiple_choice_question_type}
+% \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 |\k|\marg{\dots}.
-% \item Warn user of the \texttt{babel} package set for a German-related language
-% that using the character |"| will not play well with \textsf{moodle}.
-% \item Support for \textsf{babel} commands related to German quotes.
+% \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 |\%| in conversion to HTML.
-% \item Command |\htmlonly[]{}| to pass HTML contents directly to the XML file.
+% \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 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 |tags| key can now be used to specify a comma-separated list of tags.
+% \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 shortanswer questions is converted to HTML.
-% \item Paragraph breaks in multi and essay items no longer break compilation.
-% \item Question text in Essays was not shown in PDF file.
-% \item Commands |\textsc|, |\underline|, |\url|, and |\href| yielded HTML code with
+% \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
@@ -1717,64 +2367,64 @@
% \end{version}
% \begin{version}[version=0.8,date=2021-01-04]
% \added
-% \item Support for inclusion of GIF pictures.
-% \item Added package option |svg| to avoid the rasterization of vector graphics.
-% \item New macro |\setsubcategory| to define subcategories, reflected in PDF and XML.
-% \item Package option |handout| for sharing PDF with students.
+% \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 UTF8-coded sources).
+% \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 |fraction| key to values accepted by Moodle.
-% \item A |fractiontol| key to control the tolerance in this mechanism.
+% \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 |\_| and |\textbackslash|.
-% \item Support for the wildcard character as an answer in numerical questions.
+% \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 |\setcategory| is reflected by a new section in PDF.
-% \item In matching questions, warnings are raised if the number of items is insufficient.
-% \item Improved display of matching questions in PDF.
-% \item The package \textsf{iftex} is now required.
-% \item An error is thrown when |fraction| is set to an invalid value.
-% \item In numerical questions, the tolerance can be set in exponent form.
-% \item Nicer PDF rendering of numbers in numerical questions if \textsf{siunitx} is loaded.
-% \item Included PNG and JPEG files are now directly converted to base64.
+% \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 (|$...$|) can now contain escaped dollar signs (|\$|).
-% \item Closing braces escaped in cloze subquestions outside math environment.
-% \item The scope of the |tolerance| key is now respected.
+% \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 \texttt{tikz}.
-% \item Support for |\"Y| and |\"y|.
-% \item New commands converted to XML.
-% \item Adding a stamp comment in XML, package option offered to disable
+% \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 |\tikz| command.
+% \item Support for the \cmd{\tikz} command.
% \item A different directory can be specified for picture inclusion.
-% \item Warn user of the \texttt{babel} package set for french that autospacing
+% \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 multi with multiple answers allowed, choosing all options no longer
+% \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 \texttt{penalty} tag in cloze subquestions.
+% \item Irrelevant \optn{penalty} tag in \env{cloze} subquestions.
% \fixed
-% \item Non-integer fractions can now be specified in cloze subquestions.
-% \item Significantly squeeze PNG images size by skipping ancillary data.
+% \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.
+% 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 cloze subquestions. This allows \LaTeX\
+% \item Closing braces escaped in \env{cloze} subquestions. This allows \LaTeX\
% equations or images to be included.
% \item Image inclusion with macOS.
% \end{version}
@@ -1782,47 +2432,51 @@
% \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
+% \item \Moodle\ tags can now be specified for questions (and rendered in \PDF\
% as well).
-% \item In cloze questions, the \texttt{multiresponse} subquestion type is
+% \item In \env{cloze} questions, the multiresponse subquestion type is
% now supported.
% \removed
-% \item External dependency on \texttt{OpenSSL}.
-% \item Irrelevant tags were written in XML for matching questions.
+% \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 feedbacks can now contain backslashes.
+% \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
+% 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 UTF8-encoded sources (support
+% \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 \texttt{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 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 \texttt{final}.
+% \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\ equation and images.
+% 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}
-%
-% \StopEventually{}
+% \addcontentsline{toc}{section}{Version History}%
+% \PrintIndex
+% \addcontentsline{toc}{section}{Index}%
+% \StopEventually{%
+%^^A \PrintChanges
+% }
%
% \section{Implementation}
% \subsection{Packages, Options, and Utilities}
@@ -1836,18 +2490,36 @@
\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
-\DeclareOption{draft}{\moodle@draftmodetrue}
-\DeclareOption{handout}{\moodle@handouttrue}
-\DeclareOption{final}{\moodle@draftmodefalse}
-\DeclareOption{nostamp}{\moodle@stampmodefalse}
-\DeclareOption{tikz}{\moodle@tikztrue}
-\DeclareOption{svg}{\moodle@svgtrue}
-\DeclareOption{section}{\moodle@sectiontrue\moodle@numberedtrue}
-\DeclareOption{section*}{\moodle@sectiontrue\moodle@numberedfalse}
-\DeclareOption{subsection}{\moodle@sectionfalse\moodle@numberedtrue}
-\DeclareOption{subsection*}{\moodle@sectionfalse\moodle@numberedfalse}
+\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
@@ -1857,16 +2529,27 @@
\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
-\ProcessOptions
+\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{xkeyval} %For key-handling
\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),
+% 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.
@@ -1878,11 +2561,12 @@
\fi
}
\RequirePackage{etoolbox}%List management
-\RequirePackage{xpatch} %To patch commands easily in HTML mode
+\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
@@ -1892,6 +2576,10 @@
\RequirePackage{graphicx} %To include graphics
\fi
+\GetFileInfo{moodle.sty}%
+\edef\moodledate{\filedate}%
+\edef\moodleversion{\fileversion}%
+
\let\xa=\expandafter
\def\@star{*}%
\def\@hundred{100}%
@@ -1903,12 +2591,12 @@
% 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%
+ \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%
+\ifnum 0\ifTUTeX 1\fi\ifPDFTeX\ifpdf 1\fi\fi>0\relax
\pdfoutputtrue
\fi
% \end{macrocode}
@@ -1942,7 +2630,7 @@
\jobnamewithsuffixtomacro{\outputfilename}{-moodle.xml}
% \end{macrocode}
-% Next, we create macros to open and close the Moodle XML file
+% Next, we create macros to open and close the Moodle \XML\ file
% we will be writing.
% \begin{macrocode}
\newwrite\moodle@outfile
@@ -1959,7 +2647,17 @@
\fi
\fi
\ifmoodle@stampmode
- \def\moodle@stamp{This file was generated on \the\year-\two@digits\month-\two@digits\day}
+ \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{<!-- \moodle@stamp -->}%
+ \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 }%
@@ -1977,9 +2675,9 @@
\fi
\fi
\fi
- \writetomoodle{<!-- \moodle@stamp -->}%
- \def\moodle@stamp{running on \platformname}%
- \g@addto@macro{\moodle@stamp}{ with the package moodle v0.9 }%
+ \writetomoodle{<!-- \moodle@stamp running -->}%
+ \def\moodle@stamp{on \platformname}%
+ \g@addto@macro{\moodle@stamp}{ with the package moodle \moodleversion\space (\moodledate) }%
\writetomoodle{<!-- \moodle@stamp -->}%
\fi
\immediate\write\moodle@outfile{}%
@@ -1991,30 +2689,31 @@
\immediate\closeout\moodle@outfile
}%
% \end{macrocode}
-%
-% To both make this |.sty| file and the XML output more readable,
+%
+% 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
+% 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
- \count0=\number#1\relax
+ \moodle@indentnum=\number#1\relax
\gdef\moodle@indent{}%
\calculateindent@int
\egroup
}%
\def\calculateindent@int{%
- \ifnum\count0>0\relax
+ \ifnum\moodle@indentnum>0\relax
\g@addto@macro{\moodle@indent}{\otherspace}%
- \advance\count0 by -1\relax
+ \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
+% 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}
@@ -2029,7 +2728,7 @@
}%
% \end{macrocode}
% We now create the main |quiz| environment that will contain
-% the questions we write. It outputs to XML as a |<question type="category">| tag.
+% the questions we write. It outputs to \XML\ as a |<question type="category">| tag.
% \begin{macrocode}
{\catcode`\$=12\catcode`\ =12% in this context we cannot indent with spaces...
\gdef\moodle@write@category@xml#1{%
@@ -2044,7 +2743,8 @@
}{}%
}}%
\newcommand*\@enumeratename{enumerate}%
-\newdimen\moodle@totalmarks \moodle@totalmarks=0pt%
+\newdimen\moodle@totalmarks
+\gdef\moodle@currentcategory{}%
\newenvironment{quiz}[2][]{%
\setkeys{moodle}{#1}%
\gdef\setcategory##1{%
@@ -2069,7 +2769,7 @@
\subsection*{##1}%
\fi
\fi
- \begin{enumerate}%
+ \begin{enumerate}\renewcommand\labelenumi{(\theenumi)}%
}%
\gdef\setsubcategory##1{%
\def\@noitemerr{}%\@latex@warning{Empty question list}
@@ -2088,17 +2788,18 @@
\subsubsection*{##1}%
\fi
\fi
- \begin{enumerate}%
+ \begin{enumerate}\renewcommand\labelenumi{(\theenumi)}%
}%
\setcategory{#2}%
+ \moodle@totalmarks=0pt%
}{%
\end{enumerate}%
- \emph{Total of marks: \strip@pt\moodle@totalmarks}%
+ \emph{\GetTranslation{Total of marks}: \strip@pt\moodle@totalmarks}%
\let\setcategory\relax
\let\setsubcategory\relax
}%
-% \end{macrocode}
+% \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|.
@@ -2107,17 +2808,17 @@
\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}
+% \end{macrocode}
+%
+% \subsubsection{Main Switch: to create \XML\ or not}
%
-% \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.
+ % If we are generating \XML, do #1; otherwise do #2.
\tikzifexternalizing{%
- % This run of LaTeX is currently ONLY generating a Tikz image
+ % 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
+ % generating \XML, and moreover trying to do so would cause errors
% because of file dependencies.
#2%
}{%
@@ -2144,7 +2845,7 @@
% \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}}%
@@ -2153,13 +2854,13 @@
% 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}|>...</|\meta{HTML tag}|>|
-% to the output XML file.
-%
+% 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
+% through the HTMLizer, producing \HTML\ code, while the starred variant
% |\generate@moodle@write@code*| passes |#3| verbatim as text.
-%
-% For example,
+%
+% For example,
% |\generate@moodle@write@code{excuse}<EXC>{\theexcuse}|
% would expand to
% \begin{Verbatim}[gobble=4,frame=single]
@@ -2175,7 +2876,7 @@
% \fi
% }%
% \end{Verbatim}
-% but
+% but
% |\generate@moodle@write@code*{excuse}<EXC>{\theexcuse}|
% would expand only to
% \begin{Verbatim}[gobble=4,frame=single]
@@ -2190,7 +2891,7 @@
\def\generate@moodle@write@html#1<#2>#3{%
% #1 = NAME for \moodle@writeNAME
- % #2 = HTML tag
+ % #2 = \HTML\ tag
% #3 = what, exactly, to write
\xa\gdef\csname moodle@write#1\endcsname{%
\xa\def\xa\test@iii\xa{#3}%
@@ -2200,32 +2901,38 @@
\xa\converttohtmlmacro\xa\moodle@htmltowrite\xa{#3}%
\writetomoodle[2]{ <#2 format="html">}%
\writetomoodle[4]{ <text><![CDATA[<p>\moodle@htmltowrite</p>]]></text>}%
+ \ifmoodle@pluginfile
+ \writetomoodle[0]{\htmlize@embeddedfiletags}%
+ \fi
\writetomoodle[2]{ </#2>}%
\fi
}%
}%
\def\generate@moodle@write@html@noptag#1<#2>#3{%
- % No <P>..</P> 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"><text/></#2>}%
- \else
- \xa\converttohtmlmacro\xa\moodle@htmltowrite\xa{#3}%
- \writetomoodle[2]{ <#2 format="html">}%
- \writetomoodle[4]{ <text><![CDATA[\moodle@htmltowrite]]></text>}%
- \writetomoodle[2]{ </#2>}%
- \fi
- }%
+ % No <P>..</P> 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"><text/></#2>}%
+ \else
+ \xa\converttohtmlmacro\xa\moodle@htmltowrite\xa{#3}%
+ \writetomoodle[2]{ <#2 format="html">}%
+ \writetomoodle[4]{ <text><![CDATA[\moodle@htmltowrite]]></text>}%
+ \ifmoodle@pluginfile
+ \writetomoodle[0]{\htmlize@embeddedfiletags}%
+ \fi
+ \writetomoodle[2]{ </#2>}%
+ \fi
+ }%
}%
\def\generate@moodle@write@data*#1<#2>#3{%
% #1 = NAME for \moodle@writeNAME
- % #2 = HTML tag
+ % #2 = \HTML\ tag
% #3 = what, exactly, to write
\xa\gdef\csname moodle@write#1\endcsname{%
\writetomoodle[2]{ <#2>#3</#2>}%
@@ -2250,7 +2957,7 @@
\def\moodle@latex@writetags{%
\xa\xdef\xa\test@iii\xa{\moodle@tags}%
\ifx\test@iii\@moodle@empty\relax\else
- \hfill tags: %
+ \hfill \GetTranslation{tags}: %
\renewcommand*{\do}[1]{\ifmoodle@firsttag\moodle@firsttagfalse\else, \fi\texttt{##1}}%
\xa\docsvlist\xa{\test@iii}%
\fi
@@ -2291,8 +2998,8 @@
% 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 <generalfeedback>
+ % When it comes time to write them to \XML,
+ % \moodle@writegeneralfeedback uses the \HTML\ tag <generalfeedback>
% whereas \moodle@writefeedback uses the tag <feedback>.
% Note that the general feedback is NOT inherited by each answer!
\define@cmdkey{moodle}[moodle@]{feedback}[]{}%
@@ -2306,7 +3013,7 @@
%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}}
+ \define@key{moodle}{points}[1.0]{\xa\def\csname moodle@default grade\endcsname{#1}}%
\generate@moodle@write@code*{defaultgrade}<defaultgrade>{\csname moodle@default grade\endcsname}%
\moodleset{default grade=1.0} %This sets the default.
@@ -2337,7 +3044,7 @@
%% 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 <answer fraction="75">.
+ %the \XML\ within the answer tag, like <answer fraction="75">.
\moodleset{fraction=100} %This sets the default.
% \end{macrocode}
% \begin{macrocode}
@@ -2365,6 +3072,10 @@
\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
@@ -2392,18 +3103,18 @@
\def\moodle@numbering{IIII}\fi
}%
%'answer numbering' will be a synonym to 'numbering'
- \define@key{moodle}{answer numbering}[abc]{\setkeys{moodle}{numbering={#1}}}%
+ \define@key{moodle}{answer numbering}[abc]{\setkeys{moodle}{numbering={#1}}}%
\generate@moodle@write@code*{answernumbering}<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}%
-
+ \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@Roman{Roman}%
\def\@moodle@abc{abc}%
\def\@moodle@ABCD{ABCD}%
\def\@moodle@arabicnumbers{123}%
@@ -2411,6 +3122,7 @@
\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
@@ -2430,14 +3142,14 @@
\renewcommand\labelenumii{$\bullet$~}%
\fi
}
- %TODO: * In the PDF, how should 'none' in a multi look different from
+ %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{0}%
+ \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}}%
@@ -2447,7 +3159,7 @@
%% TOLERANCE
\define@cmdkey{moodle}[moodle@]{tolerance}[0]{}%
\moodleset{tolerance=0}%
- %There is no \moodle@writetolerance, because in the XML the
+ %There is no \moodle@writetolerance, because in the \XML\ the
%tolerance is given within the answer tag,
%like <answer fraction=100 tolerance=0.03>.
@@ -2456,17 +3168,17 @@
% \subsubsection{Keys for short answer questions}
% \begin{macrocode}
%% CASE SENSITIVE
- \define@boolkey{moodle}[moodle@]{case sensitive}[true]{}%
- \generate@moodle@write@code*{usecase}<usecase>{\csname ifmoodle@case sensitive\endcsname 1\else 0\fi}%
- % We make 'usecase' a synonym for 'case sensitive'.
- \define@boolkey{moodle}[moodle@]{usecase}[true]{\ifmoodle@usecase\csname moodle@case sensitivetrue\endcsname\else\csname moodle@case sensitivefalse\endcsname\fi}%
- \moodleset{case sensitive=false}%
+ \define@boolkey{moodle}[moodle@]{usecase}[true]{}%
+ \generate@moodle@write@code*{usecase}<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 'dragdrop' and 'drag and drop' synonyms for 'draganddrop'.
+ % 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{%
@@ -2492,11 +3204,11 @@
{html,html+file,text,monospaced,file}[html]%
{\def\test@i{#1}%
\ifx\test@i\@moodle@html
- % HTML Editor
- \def\moodle@responseformat{editor}%
+ % \HTML\ Editor
+ \def\moodle@responseformat{editor}%
\fi
\ifx\test@i\@moodle@htmlfile
- % HTML Editor with File Picker
+ % \HTML\ Editor with File Picker
\def\moodle@responseformat{editorfilepicker}%
\fi
\ifx\test@i\@moodle@text
@@ -2521,7 +3233,7 @@
\fi
}%
\generate@moodle@write@code*{responseformat}<responseformat>{\moodle@responseformat}%
- \moodleset{response format=html}%
+ \moodleset{response format=html}%
%N.B. if we did not set a default, then \moodle@responseformat would be undefined, causing problems.
%% RESPONSE REQUIRED
@@ -2584,12 +3296,12 @@
% \end{macrocode}
%
% \subsection{Answer handling}
-%
+%
% \begin{macrocode}
-%The Answers XML depends heavily on the question type.
+%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,
+%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.
@@ -2600,8 +3312,8 @@
\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)
+ % #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
@@ -2614,7 +3326,7 @@
% \end{macrocode}
%
% \subsubsection{Not yet implemented}
-%
+%
% \begin{macrocode}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -2623,32 +3335,43 @@
% 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
+% 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|:
+% \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|:
+% \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.
+% into the \XML\ file.
% \end{itemize}
% For example, to create the `shortanswer' question type,
-% we shall call
+% 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{%
@@ -2664,18 +3387,20 @@
}%
\def\moodle@makelatextag@qtype#1{%
- \doublebox{\tiny \textsc{#1}}
+ \doublebox{\tiny \textsc{\GetTranslation{#1}}}
}%
\def\moodle@makelatextag@value#1#2{%
- \moodle@makelatextagbox{\csname moodle@#1\endcsname~#2}
+ \moodle@makelatextagbox{\GetTranslation{#2}~\csname moodle@#1\endcsname}%
}%
\def\moodle@makelatextag@key#1{%
- \moodle@makelatextagbox{\csname moodle@#1\endcsname}
+ \moodle@makelatextagbox{\GetTranslation{#1}}
}%
-\def\moodle@marks#1{point\ifdim#1pt=1pt \else s\fi}
+\def\moodle@makelatextag@other#1{%
+ \moodle@makelatextagbox{\GetTranslation{#1}}
+}%
\def\moodle@makefrontend#1#2{%
\NewEnviron{#1}[2][]{%
@@ -2685,22 +3410,23 @@
\expandafter\gatheritems\xa{\BODY}%
\let\moodle@questionheader=\gatheredheader
%First, the LaTeX processing
- \item \textbf{\moodle@questionname}
+ \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}{\moodle@marks{\csname moodle@default grade\endcsname}}
- \moodle@makelatextag@value{penalty}{penalty}
+ \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.
@@ -2728,10 +3454,9 @@
% Description blocks can be empty. In this case, nothing is done.
%
% \begin{macrocode}
-\AfterEndPreamble{% in case something like \usepackage[french]{babel} is loaded
+\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}}%
@@ -2739,7 +3464,7 @@
\trim@spaces@in\moodle@questiontext
\ifx\moodle@questiontext\@empty\relax\else%
%First, the LaTeX processing.
- \item \textbf{\moodle@questionname}
+ \item \moodle@begin@samepage\textbf{\moodle@questionname}
\ifmoodle@handout\else
\moodle@latex@writetags
\par
@@ -2750,9 +3475,10 @@
\moodle@questiontext\par
\ifmoodle@handout\else
\ifx\moodle@feedback\@empty\relax\else
- \fbox{\parbox{\linewidth}{\emph{\moodle@feedback}}}%
+ \fbox{\parbox{.96\linewidth}{\emph{\moodle@feedback}}}%
\fi
\fi
+ \moodle@end@samepage
%Now, writing information to memory.
\@moodle@ifgeneratexml{%
\writetomoodle{<question type="description">}%
@@ -2769,31 +3495,31 @@
% \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,
+ % 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{Notes for grader:}
+ \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{\linewidth}{\emph{\moodle@generalfeedback}}}%
+ \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
+ \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 \textbf{\moodle@questionname}
+ \item \moodle@begin@samepage\textbf{\moodle@questionname}
\ifmoodle@handout
\moodle@makelatextag@qtype{essay}
\else
@@ -2801,22 +3527,26 @@
\par
\noindent
\moodle@makelatextag@qtype{essay}
- \moodle@makelatextag@value{default grade}{\moodle@marks{\csname moodle@default grade\endcsname}}
+ \moodle@makelatextag@value{default grade}{marked out of}
\moodle@makelatextag@value{penalty}{penalty}
- \moodle@makelatextag@key{responseformat}
+ \xa\moodle@makelatextag@key\xa{\moodle@responseformat}
\fi
\par
\noindent
\moodle@questionheader
\long\def\@lempty{}%
\ifx\moodle@responsetemplate\@lempty\else
- \par\noindent \emph{Template:}
- \par\fbox{\parbox{\linewidth}{\moodle@responsetemplate}}\par
+ \par\noindent\emph{\GetTranslation{Response template}:}
+ \par\noindent\fbox{\parbox{.96\linewidth}{\moodle@responsetemplate}}\par
\fi
\edef\moodle@generalfeedback{\expandonce\moodle@feedback}
- \ifmoodle@handout\else
+ \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.
@@ -2840,7 +3570,7 @@
%
\passvalueaftergroup{\moodle@answers@xml}%
\egroup
- \moodle@writeanswers% The 'answers' XML really contains the grader info.
+ \moodle@writeanswers% The 'answers' \XML\ really contains the grader info.
\moodle@writeresponsetemplate%
\moodle@writetags%
\writetomoodle{</question>}%
@@ -2851,18 +3581,18 @@
\def\moodle@checkresponsefieldlines{%
\newcount\a\a=\number\csname moodle@response field lines\endcsname
\newcount\b\b=5%
- \ifnum\the\a>40% if the value was more than 40
+ \ifnum\the\a>40\relax% if the value was more than 40
\a=40%
\fi
- \ifnum\the\a<5% if the value was less than 5
+ \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% equality holds if we had 5, 10, 15, 20, 25, 30, or 40
+ \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%
- \ifnum\csname moodle@response field lines\endcsname<40%
+ \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
@@ -2885,7 +3615,7 @@
%%%% 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
@@ -2904,7 +3634,7 @@
%%%% \egroup
%%%% \csname write#1question\endcsname
%%%% }{}%
-%%%% The \@ifundefined lines should automatically define the
+%%%% The \@ifundefined lines should automatically define the
%%%% \...@preamble \...@postamble macros to be \relax if they don't exist already.
\gdef\writeessayquestion{%
@@ -2921,19 +3651,7 @@
\item #1%
}%
-
\long\def\moodle@savegraderinfo#1{%
- %\def\ds{#1}\show\ds
- \bgroup
- \moodle@savegraderinfo@int#1\moodle@answer@rdelim
- \passvalueaftergroup{\moodle@answers@xml}%
- \egroup
-}%
-\newcommand\moodle@savegraderinfo@int[1][]{%
- \setkeys{moodle}{fraction=0,#1}%
- \moodle@savegraderinfo@int@int%
-}%
-\long\def\moodle@savegraderinfo@int@int#1\moodle@answer@rdelim{%
\def\moodle@answertext{#1}
\xa\converttohtmlmacro\xa\moodle@answertext@html\xa{\moodle@answertext}%
%\trim@spaces@in\moodle@answertext
@@ -2946,12 +3664,8 @@
% \end{macrocode}
%
% \subsubsection{Short Answer Question Front-End}
-%
+%
% \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.
-
%\NewEnviron{shortanswer}[2][]{%
% \bgroup
% \setkeys{moodle}{#1,questionname={#2}}%
@@ -2973,7 +3687,7 @@
% \bgroup
% \gdef\moodle@answers@xml{}%
% \setkeys{moodle}{feedback={}}%
-% \xa\loopthroughitemswithcommand\xa{\csname
+% \xa\loopthroughitemswithcommand\xa{\csname
% saveshortansweranswer\endcsname}%
% \passvalueaftergroup{\moodle@answers@xml}%
% \egroup
@@ -2987,10 +3701,10 @@
% LATEX PROCESSING
\def\moodle@makelatextag@shortanswer{%
- \csname ifmoodle@case sensitive\endcsname
- \moodle@makelatextagbox{Case-Sensitive}\relax
+ \ifmoodle@usecase
+ \moodle@makelatextag@other{Case-Sensitive}\relax
\else
- \moodle@makelatextagbox{Case-Insensitive}\relax
+ \moodle@makelatextag@other{Case-Insensitive}\relax
\fi
}
@@ -3002,7 +3716,7 @@
\loopthroughitemswithcommand{\moodle@print@shortanswer@answer}%
\end{itemize}%
\ifx\moodle@generalfeedback\@empty\relax\else%
- \fbox{\parbox{\linewidth}{\emph{\moodle@generalfeedback}}}%
+ \fbox{\parbox{.96\linewidth}{\emph{\moodle@generalfeedback}}}%
\fi
}
\fi
@@ -3023,7 +3737,7 @@
\item #1$~(\moodle@fraction\%)$%
\fi
\ifx\moodle@feedback\@empty\relax\else
- \hfill \emph{$\rightarrow$ \moodle@feedback}
+ \moodle@preFeedback \emph{$\rightarrow$ \moodle@feedback}
\fi
}%
@@ -3045,15 +3759,18 @@
\addto@xml[2]{\moodle@answers@xml}{<answer fraction="\moodle@fraction" format="plain_text">}%
\xa\converttohtmlmacro\xa\moodle@answertext@html\xa{\moodle@answertext}%
\addto@xml[4]{\moodle@answers@xml}{ <text>\moodle@answertext@html</text>}%
+ \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}{ <feedback format="html"><text><![CDATA[<p>\moodle@feedback@html</p>]]></text></feedback>}%
+ \addto@xml[4]{\moodle@answers@xml}{ <feedback format="html"><text><![CDATA[<p>\moodle@feedback@html</p>]]></text>\ifmoodle@pluginfile\htmlize@embeddedfiletags\fi</feedback>}%
\fi
\addto@xml[2]{\moodle@answers@xml}{</answer>}%
}%
-% WRITING QUESTION TO XML FILE
+% WRITING QUESTION TO \XML\ FILE
\gdef\writeshortanswerquestion{%
\writetomoodle{<question type="shortanswer">}%
\moodle@writecommondata%
@@ -3062,7 +3779,7 @@
% \end{macrocode}
%
% \subsubsection{Numerical Question Front-End}
-%
+%
% \begin{macrocode}
\moodle@makefrontend{numerical}{\moodle@makelatextag@numerical}%
@@ -3071,7 +3788,8 @@
\def\moodle@makelatextag@numerical{}
\AtEndPreamble{
- \@ifpackageloaded{siunitx}{\def\moodle@printnum{\num[omit-uncertainty,copy-decimal-marker]}}{\let\moodle@printnum\trim@spaces}%
+ \@ifpackageloaded{siunitx}{\def\moodle@printnum{\num[omit-uncertainty]}}%,copy-decimal-marker
+ {\let\moodle@printnum\trim@spaces}%
}
\ifmoodle@handout
@@ -3082,7 +3800,7 @@
\loopthroughitemswithcommand{\moodle@print@numerical@answer}%
\end{itemize}%
\ifx\moodle@generalfeedback\@empty\relax\else%
- \fbox{\parbox{\linewidth}{\emph{\moodle@generalfeedback}}}%
+ \fbox{\parbox{.96\linewidth}{\emph{\moodle@generalfeedback}}}%
\fi
}
\fi
@@ -3098,13 +3816,14 @@
\moodle@print@numerical@answer@int@int%
}%
\def\moodle@print@numerical@answer@int@int#1\@rdelim{%
- \xdef\test@i{\trim@spaces{#1}}%
+ \gdef\test@i{#1}%
+ \trim@spaces@in\test@i
\ifx\test@i\@star
\item \test@i
\else
\item \moodle@printnum{#1}%
- \ifnum\z@=\moodle@tolerance\else
- $\,\pm\,$\moodle@printnum{\moodle@tolerance}%
+ \ifx\moodle@tolerance\moodle@zero\else
+ $\,\pm\,$\moodle@printnum{\expandonce\moodle@tolerance}%
\fi
\fi
\ifx\moodle@fraction\@hundred
@@ -3114,7 +3833,7 @@
$~(\moodle@fraction\%)$%
\fi
\ifx\moodle@feedback\@empty\relax\else
- \hfill \emph{$\rightarrow$ \moodle@feedback}%
+ \moodle@preFeedback \emph{$\rightarrow$ \moodle@feedback}%
\fi
}%
@@ -3135,19 +3854,23 @@
\moodle@checkfraction
\addto@xml[2]{\moodle@answers@xml}{<answer fraction="\moodle@fraction" format="plain_text">}%
\addto@xml[4]{\moodle@answers@xml}{ <text>\moodle@answertext</text>}%
+
\ifx\moodle@answertext\@star\else
\addto@xml[4]{\moodle@answers@xml}{ <tolerance>\moodle@tolerance</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}{ <feedback format="html"><text><![CDATA[<p>\moodle@feedback@html</p>]]></text></feedback>}%
+ \addto@xml[4]{\moodle@answers@xml}{ <feedback format="html"><text><![CDATA[<p>\moodle@feedback@html</p>]]></text>\ifmoodle@pluginfile\htmlize@embeddedfiletags\fi</feedback>}%
\fi
\addto@xml[2]{\moodle@answers@xml}{</answer>}%
}%
-% WRITING QUESTION TO XML FILE
+% WRITING QUESTION TO \XML\ FILE
\gdef\writenumericalquestion{%
\writetomoodle{<question type="numerical">}%
\moodle@writecommondata%
@@ -3155,7 +3878,7 @@
% \end{macrocode}
%
% \subsubsection{Multiple Choice Question Front-End}
-%
+%
% \begin{macrocode}
%Multiple choice has the structure
% \begin{multi}[options]{name}%
@@ -3175,27 +3898,25 @@
\PackageError{moodle}{Unsupported option "allornothing" for a multichoice subquestion}
{Please set "allornothing=false"}%
\else
- \moodle@makelatextagbox{All-or-nothing}%
+ \moodle@makelatextag@other{All-or-nothing}%
\fi
\else
- \ifmoodle@multiple
- \moodle@makelatextagbox{Multiple}%
+ \ifmoodle@single
+ \moodle@makelatextag@other{Single}%
\else
- \moodle@makelatextagbox{Single}%
+ \moodle@makelatextag@other{Multiple}%
\fi
\fi
\ifmoodle@handout\else
\ifmoodle@shuffle
- \moodle@makelatextagbox{Shuffle}\relax%
+ \moodle@makelatextag@other{Shuffle}\relax%
\fi
\fi
}
\def\moodle@multi@latexprocessing{%
- \ifmoodle@allornothing
- \moodle@singletrue
- \fi
- \moodle@countcorrectanswers%
+ \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}}%
@@ -3212,7 +3933,7 @@
\end{enumerate}%
\ifmoodle@handout\else
\ifx\moodle@generalfeedback\@empty\relax\else%
- \fbox{\parbox{\linewidth}{\emph{\moodle@generalfeedback}}}%
+ \fbox{\parbox{.96\linewidth}{\emph{\moodle@generalfeedback}}}%
\fi
\fi
}
@@ -3234,7 +3955,7 @@
\ifmoodle@single%
\setkeys{moodle}{fraction=100}%
\else
- \setkeys{moodle}{fraction=\moodle@autopoints}%
+ \setkeys{moodle}{fraction=\moodle@AutoScore}%
\fi
\else
\g@addto@macro\moodle@answertext{#1#2}%
@@ -3244,7 +3965,11 @@
\ifmoodle@handout\else
\ifmoodle@single%
\ifx\moodle@fraction\@empty\relax%
- \setkeys{moodle}{fraction=0}%
+ \ifdim0pt<\moodle@sanction pt\relax
+ \setkeys{moodle}{fraction=-\moodle@sanction}%
+ \else
+ \setkeys{moodle}{fraction=0}%
+ \fi
\fi
\moodle@checkfraction
\ifx\moodle@fraction\@hundred%
@@ -3257,7 +3982,11 @@
\fi
\else% multiple
\ifx\moodle@fraction\@empty\relax%
- \setkeys{moodle}{fraction=\moodle@autosanctions}%
+ \ifmoodle@AdvancedScoreMode
+ \setkeys{moodle}{fraction=0}%
+ \else
+ \setkeys{moodle}{fraction=-\moodle@AutoScore}%
+ \fi
\fi
\moodle@checkfraction
\g@addto@macro\moodle@answertext{$~(\moodle@fraction\%)$}%
@@ -3268,142 +3997,142 @@
\xa\temp\xa{\moodle@answertext}%
\else
\ifx\moodle@feedback\@empty\relax\else%
- \g@addto@macro\moodle@answertext{\hfill \emph{$\rightarrow$ \moodle@feedback}}%
+ \g@addto@macro\moodle@answertext{\moodle@preFeedback \emph{$\rightarrow$ \moodle@feedback}}%
\fi
\moodle@answertext
\fi
}%
-% COMMON UTILITY: COUNTING CORRECT ANSWERS (AND A BIT MORE...)
- \newcounter{moodle@numcorrectanswers}% count the stars
- \newcounter{moodle@numincorrectanswers}% count the items without fraction key indicated
- \newlength{\moodle@pointspercorrect}%
- \newlength{\moodle@pointsperincorrect}%
- \newlength{\moodle@sumofpositivefractions}% sums user-set positive fractions
- \newlength{\moodle@sumofnegativefractions}% sums user-set negative fractions
- \def\moodle@countcorrectanswers{%
- \setcounter{moodle@numcorrectanswers}{0}%
- \setcounter{moodle@numincorrectanswers}{0}%
- \global\setlength{\moodle@pointspercorrect}{100pt}%
- \global\setlength{\moodle@pointsperincorrect}{-100pt}%
- \global\setlength{\moodle@sumofpositivefractions}{0pt}%
- \global\setlength{\moodle@sumofnegativefractions}{0pt}%
- \loopthroughitemswithcommand{\moodle@countcorrectanswers@a}%
- \global\advance\moodle@pointspercorrect by-\moodle@sumofpositivefractions\relax%
- \def\ds{\strip@pt\moodle@sumofpositivefractions}%
- \ifnum0=\c@moodle@numcorrectanswers\relax%
- % autopoints will never be used but we check if the sum of positive fractions is 100%
- \ifdim\moodle@pointspercorrect<-\moodle@fractiontol pt\relax%
- \PackageWarning{moodle}{Positive fractions sum up to more than 100 (here: \ds)}%
- \else
- \ifdim\moodle@pointspercorrect>\moodle@fractiontol pt\relax%
- \PackageError{moodle}{Positive fractions sum up to less than 100 (here: \ds)}%
- \fi
- \fi
- \else
- \ifdim0pt<\moodle@pointspercorrect\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 sum up to 100 or more (here: \ds):
- there is no positive points left to be given to starred items.}%
- \fi
- \global\divide\moodle@pointspercorrect by \c@moodle@numcorrectanswers\relax%
- \fi
- \gdef\moodle@autopoints{\strip@pt\moodle@pointspercorrect}%
- \global\advance\moodle@pointsperincorrect by-\moodle@sumofnegativefractions\relax%
- \def\ds{\strip@pt\moodle@sumofnegativefractions}%
- \ifnum0=\c@moodle@numincorrectanswers\relax%
- % autosanctions will never be used and
- % we do not care about the sum of negative fractions (might be less than -100)
- \else
- \ifdim0pt<\moodle@pointsperincorrect\relax%
- % we have items without fractions set: to prevent auto sanctions from becoming bonuses,
- % such items are neutralized.
- \PackageWarning{moodle}{Negative fractions sum up to -100 or less (here: \ds):
- items with no fraction key set will be considered as neutral.}%
- \global\setlength{\moodle@pointsperincorrect}{0pt}%
- \fi
- \global\divide\moodle@pointsperincorrect by \c@moodle@numincorrectanswers\relax%
- \fi
- \gdef\moodle@autosanctions{\strip@pt\moodle@pointsperincorrect}%
- }
- \long\def\moodle@countcorrectanswers@a#1{%
- %The grouping is to keep key answer-specific key changes local.
- \bgroup
- \moodle@countcorrectanswers@b#1\moodle@answer@rdelim
- \egroup
- }%
- \newcommand\moodle@countcorrectanswers@b[1][]{%
- %\ifx&#1&%
- \let\moodle@fraction\@empty%
- \setkeys{moodle}{#1}%
- \moodle@countcorrectanswers@c%
- %\fi
- }%
- \long\def\moodle@countcorrectanswers@c#1#2\moodle@answer@rdelim{%
- \def\test@i{#1}%
- \ifx\test@i\@star
- \stepcounter{moodle@numcorrectanswers}%
- \else
- \ifx\moodle@fraction\@empty\relax%
- \stepcounter{moodle@numincorrectanswers}%
- \else
- \ifdim0pt<\moodle@fraction pt\relax%
- \global\addtolength{\moodle@sumofpositivefractions}{\moodle@fraction pt}%
- \else
- \global\addtolength{\moodle@sumofnegativefractions}{\moodle@fraction pt}%
- \fi
- \fi
- \fi
- }%
- \newlength{\test@fraction}%
- \newlength{\test@lower}%
- \newlength{\test@upper}%
- \def\moodle@fractionerror{%
- \def\ds{\moodle@fraction}%
- \PackageError{moodle}{the current fraction is not a valid 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{%
- \setlength{\test@lower}{#1 pt}%
- \addtolength{\test@lower}{-\moodle@fractiontol pt}%
- \setlength{\test@upper}{#1 pt}%
- \addtolength{\test@upper}{\moodle@fractiontol pt}%
- \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%
- \setkeys{moodle}{fraction=100}%
- \fi
- \ifnum\moodle@fraction<0%
- \setkeys{moodle}{fraction=0}%
- \fi
- \else
- %\def\test@i{#1}%
- \setlength{\test@fraction}{\moodle@fraction pt}%
- % take the absolute value
- \ifdim0pt>\test@fraction\relax%
- \setlength{\test@fraction}{-\moodle@fraction pt}%
- \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%
- \setkeys{moodle}{fraction=-\test@fractionmatched}%
- \else
- \setkeys{moodle}{fraction=\test@fractionmatched}%
- \fi
- \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&#1&%
+ \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
@@ -3427,7 +4156,7 @@
\ifmoodle@single
\setkeys{moodle}{fraction=100}%
\else
- \setkeys{moodle}{fraction=\moodle@autopoints}%
+ \setkeys{moodle}{fraction=\moodle@AutoScore}%
\fi
\def\moodle@answertext{#2}%
\else
@@ -3435,9 +4164,17 @@
\fi
\ifx\moodle@fraction\@empty\relax%
\ifmoodle@single\relax
- \setkeys{moodle}{fraction=0}%
+ \ifdim0pt<\moodle@sanction pt\relax
+ \setkeys{moodle}{fraction=-\moodle@sanction}%
+ \else
+ \setkeys{moodle}{fraction=0}%
+ \fi
\else% multiple
- \setkeys{moodle}{fraction=\moodle@autosanctions}%
+ \ifmoodle@AdvancedScoreMode
+ \setkeys{moodle}{fraction=0}%
+ \else
+ \setkeys{moodle}{fraction=-\moodle@AutoScore}%
+ \fi
\fi
\fi
\trim@spaces@in\moodle@answertext
@@ -3446,17 +4183,19 @@
\addto@xml[2]{\moodle@answers@xml}{<answer fraction="\moodle@fraction" format="html">}%
\xa\converttohtmlmacro\xa\moodle@answertext@html\xa{\moodle@answertext}%
\addto@xml[4]{\moodle@answers@xml}{ <text><![CDATA[<p>\moodle@answertext@html</p>]]></text>}%
+ \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}{ <feedback format="html"><text><![CDATA[<p>\moodle@feedback@html</p>]]></text></feedback>}%
+ \addto@xml[4]{\moodle@answers@xml}{ <feedback format="html"><text><![CDATA[<p>\moodle@feedback@html</p>]]></text>\ifmoodle@pluginfile\htmlize@embeddedfiletags\fi</feedback>}%
\fi
\addto@xml[2]{\moodle@answers@xml}{</answer>}%
}%
-% WRITING QUESTION TO XML FILE
+% WRITING QUESTION TO \XML\ FILE
\gdef\writemultiquestion{%
-
\writetomoodle{<question type="multichoice\ifmoodle@allornothing set\fi">}%
\moodle@writecommondata%
\ifmoodle@allornothing\else
@@ -3468,7 +4207,7 @@
% \end{macrocode}
%
% \subsubsection{True/False Question Front-End}
-%
+%
% \begin{macrocode}
% True/False has structure
% \begin{truefalse}[options]{name}%
@@ -3486,7 +4225,7 @@
\expandafter\gatheritems\xa{\BODY}%
\let\moodle@questionheader=\gatheredheader
%First, the LaTeX processing
- \item \textbf{\moodle@questionname}
+ \item \moodle@begin@samepage\textbf{\moodle@questionname}
\ifmoodle@handout
\moodle@makelatextag@qtype{truefalse}
\else
@@ -3494,13 +4233,14 @@
\par
\noindent
\moodle@makelatextag@qtype{truefalse}
- \moodle@makelatextag@value{default grade}{\moodle@marks{\csname moodle@default grade\endcsname}}
+ \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}%
@@ -3510,7 +4250,7 @@
\gdef\moodle@answers@xml{}%
\setkeys{moodle}{feedback={}}%
\xa\loopthroughitemswithcommand\xa{\xa\savetruefalseanswer}%
- \ifnum\c@numgathereditems=1\relax%
+ \ifnum\c@numgathereditems=1\relax
\setcounter{currentitemnumber}{2}%
\savetruefalseanswer{}
\fi
@@ -3529,22 +4269,22 @@
% \ifnum\c@numgathereditems>2\relax%
% \PackageError{moodle}{Expecting at max two answers with truefalse type}
% \fi
- \setcounter{moodle@numcorrectanswers}{0}%
+ \setcounter{moodle@NumStarredAnswers}{0}%
\begin{itemize} \setlength\itemsep{0pt}\setlength\parskip{0pt}%
\loopthroughitemswithcommand{\moodle@print@truefalse@answer}%
- \ifnum\c@currentitemnumber=2%
- \item \textbf{False}%
+ \ifnum\c@currentitemnumber=2\relax
+ \item \textbf{\GetTranslation{False}}%
\fi
\end{itemize}
\ifmoodle@handout\else
\ifx\moodle@generalfeedback\@empty\relax\else%
- \fbox{\parbox{\linewidth}{\emph{\moodle@generalfeedback}}}%
+ \fbox{\parbox{.96\linewidth}{\emph{\moodle@generalfeedback}}}%
\fi
\fi
- \ifnum\c@moodle@numcorrectanswers=0\relax%
+ \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@numcorrectanswers>1\relax%
+ \ifnum\c@moodle@NumStarredAnswers>1\relax
\PackageError{moodle}{Two answers are explicitly marked as correct (*). Be sure only one answer leads to points.}%
\fi
}
@@ -3567,35 +4307,35 @@
\fi
}%
\def\moodle@print@truefalse@answer@int@int@empty{%
- \ifnum\c@currentitemnumber=1%
- \def\moodle@answertext{True}%
+ \ifnum\c@currentitemnumber=1\relax
+ \def\moodle@answertext{\GetTranslation{True}}%
\fi
- \ifnum\c@currentitemnumber=2%
- \def\moodle@answertext{False}%
+ \ifnum\c@currentitemnumber=2\relax
+ \def\moodle@answertext{\GetTranslation{False}}%
\fi
\item \textbf{\moodle@answertext}%
\ifmoodle@handout\else
\ifx\moodle@feedback\@empty\relax\else
- ~\hfill \emph{$\rightarrow$ \moodle@feedback}%
+ ~\moodle@preFeedback \emph{$\rightarrow$ \moodle@feedback}%
\fi
\fi
}%
\def\moodle@print@truefalse@answer@int@int@int#1#2\@rdelim{%
- \ifnum\c@currentitemnumber=1%
- \def\moodle@answertext{True}%
+ \ifnum\c@currentitemnumber=1\relax
+ \def\moodle@answertext{\GetTranslation{True}}%
\fi
- \ifnum\c@currentitemnumber=2%
- \def\moodle@answertext{False}%
+ \ifnum\c@currentitemnumber=2\relax
+ \def\moodle@answertext{\GetTranslation{False}}%
\fi
\item \textbf{\moodle@answertext}%
- \ifnum\c@currentitemnumber<3%
+ \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@numcorrectanswers}%
+ \stepcounter{moodle@NumStarredAnswers}%
\else
~%
\fi
@@ -3605,13 +4345,13 @@
\trim@spaces@in\test@ii
\ifx\test@ii\@empty\relax\else
\ifx\test@i\@star%
- \hfill \emph{$\rightarrow$ #2}%
+ \moodle@preFeedback \emph{$\rightarrow$ #2}%
\else%
- \hfill \emph{$\rightarrow$ #1#2}%
+ \moodle@preFeedback \emph{$\rightarrow$ #1#2}%
\fi
\fi
\else
- \hfill \emph{$\rightarrow$ \moodle@feedback}%
+ \moodle@preFeedback \emph{$\rightarrow$ \moodle@feedback}%
\fi
\fi
\fi
@@ -3639,19 +4379,22 @@
}%
\def\savetruefalseanswer@int@int@empty{%
\setkeys{moodle}{fraction=0}%
- \ifnum\c@currentitemnumber=1%
- \def\moodle@answertext{true}%
+ \ifnum\c@currentitemnumber=1\relax
+ \def\moodle@answertext{true}%
\fi
- \ifnum\c@currentitemnumber=2%
- \def\moodle@answertext{false}%
+ \ifnum\c@currentitemnumber=2\relax
+ \def\moodle@answertext{false}%
\fi
- \ifnum\c@currentitemnumber<3%
+ \ifnum\c@currentitemnumber<3\relax
\addto@xml[2]{\moodle@answers@xml}{<answer fraction="\moodle@fraction" format="plain_text">}%
\addto@xml[4]{\moodle@answers@xml}{ <text>\moodle@answertext</text>}%
+ \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}{ <feedback format="html"><text><![CDATA[<p>\moodle@feedback@html</p>]]></text></feedback>}%
+ \addto@xml[4]{\moodle@answers@xml}{ <feedback format="html"><text><![CDATA[<p>\moodle@feedback@html</p>]]></text>\ifmoodle@pluginfile\htmlize@embeddedfiletags\fi</feedback>}%
\fi
\addto@xml[2]{\moodle@answers@xml}{</answer>}%
\fi
@@ -3663,15 +4406,18 @@
\else
\setkeys{moodle}{fraction=0}%
\fi
- \ifnum\c@currentitemnumber=1%
- \def\moodle@answertext{true}%
+ \ifnum\c@currentitemnumber=1\relax
+ \def\moodle@answertext{true}%
\fi
- \ifnum\c@currentitemnumber=2%
- \def\moodle@answertext{false}%
+ \ifnum\c@currentitemnumber=2\relax
+ \def\moodle@answertext{false}%
\fi
- \ifnum\c@currentitemnumber<3%
+ \ifnum\c@currentitemnumber<3\relax
\addto@xml[2]{\moodle@answers@xml}{<answer fraction="\moodle@fraction" format="plain_text">}%
\addto@xml[4]{\moodle@answers@xml}{ <text>\moodle@answertext</text>}%
+ \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
@@ -3680,18 +4426,18 @@
\else%
\xa\converttohtmlmacro\xa\moodle@feedback@html\xa{#1#2}%
\fi%
- \addto@xml[4]{\moodle@answers@xml}{ <feedback format="html"><text><![CDATA[<p>\moodle@feedback@html</p>]]></text></feedback>}%
+ \addto@xml[4]{\moodle@answers@xml}{ <feedback format="html"><text><![CDATA[<p>\moodle@feedback@html</p>]]></text>\ifmoodle@pluginfile\htmlize@embeddedfiletags\fi</feedback>}%
\fi
\else
\trim@spaces@in\moodle@feedback
\xa\converttohtmlmacro\xa\moodle@feedback@html\xa{\moodle@feedback}%
- \addto@xml[4]{\moodle@answers@xml}{ <feedback format="html"><text><![CDATA[<p>\moodle@feedback@html</p>]]></text></feedback>}%
+ \addto@xml[4]{\moodle@answers@xml}{ <feedback format="html"><text><![CDATA[<p>\moodle@feedback@html</p>]]></text>\ifmoodle@pluginfile\htmlize@embeddedfiletags\fi</feedback>}%
\fi
\addto@xml[2]{\moodle@answers@xml}{</answer>}%
\fi
}%
-% WRITING QUESTION TO XML FILE
+% WRITING QUESTION TO \XML\ FILE
\gdef\writetruefalsequestion{%
\writetomoodle{<question type="truefalse">}%
\moodle@writecommondata%
@@ -3699,7 +4445,7 @@
% \end{macrocode}
%
% \subsubsection{Matching Question Front-End}
-%
+%
% \begin{macrocode}
%\let\answer=\hfill
@@ -3710,33 +4456,37 @@
\def\moodle@makelatextag@matching{%
\ifmoodle@handout\else
\ifmoodle@draganddrop
- \moodle@makelatextagbox{Drag and drop}\relax%
+ \moodle@makelatextag@other{Drag and drop}\relax%
\fi
\ifmoodle@shuffle
- \moodle@makelatextagbox{Shuffle}\relax%
+ \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
+ \par\noindent
\ifmoodle@handout
- \NewList{questionlist}
- \NewList{answerlist}
+ \NewList{questionlist}%
+ \gdef\matcheslist{}%
+ \NewList{answerlist}%
+ \else
+ \long\def\matching@table@text{}%
\fi
- \def\matching@table@text{}%
- % \ifnum\c@numgathereditems>2\relax%
-% \PackageError{moodle}{Expecting at max two answers with truefalse type}
-% \fi
- \setcounter{moodle@numcorrectanswers}{0}% Here this counter is for "questions" (items on the left column)
+ \setcounter{moodle@NumStarredAnswers}{0}% Here this counter is for "questions" (items on the left column)
\loopthroughitemswithcommand{\moodle@print@matching@answer}%
- \ifnum\c@numgathereditems<3%
- \PackageWarning{moodle}{Moodle expects at least three "answers" with matching type}%
+ \ifnum\c@numgathereditems<3\relax
+ \PackageWarning{moodle}{Moodle expects at least three proposed matches in matching questions}%
\fi
- \ifnum\c@moodle@numcorrectanswers<2%
- \PackageWarning{moodle}{Moodle expects at least two "questions" with the matching type}%
+ \ifnum\c@moodle@NumStarredAnswers<2\relax
+ \PackageWarning{moodle}{Moodle expects at least two items in matching questions}%
\fi
\ifmoodle@handout
\ifmoodle@shuffle
@@ -3744,23 +4494,25 @@
\else
\let\moodle@matching@loop=\ForEachFirstItem
\fi
- \moodle@matching@loop{questionlist}{Question}{
- \xdef\test@i{\Question}%
- \ExtractRandomItem{answerlist}{Answer}%
- \ifx\test@i\@empty
- \xdef\matching@table@text{\expandonce\matching@table@text & & $\bullet$~\expandonce\Answer\\}%
- \else
- \xdef\matching@table@text{\expandonce\matching@table@text\expandonce\Question~$\bullet$ & & $\bullet$~\expandonce\Answer\\}%
- \fi
+ \begin{minipage}{.43\linewidth}%
+ \moodle@matching@loop{questionlist}{Question}{%
+ \moodle@matching@left{\Question}%
+ \vskip 4pt\relax
}%
- \fi
- \begin{tabular}{@{}>{\raggedleft}p{.45\linewidth}p{.1\linewidth}p{.45\linewidth}@{}}%
- \matching@table@text
- \end{tabular}%
- \par
- \ifmoodle@handout\else
+ \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{\linewidth}{\emph{\moodle@generalfeedback}}}%
+ \fbox{\parbox{.96\linewidth}{\emph{\moodle@generalfeedback}}}%
\fi
\fi
\egroup
@@ -3777,18 +4529,30 @@
\def\test@i{#1}%
\trim@spaces@in\test@i
\ifmoodle@handout
- \ifx\test@i\@empty
- \InsertLastItem{questionlist}{\@empty}%
- \else
+ \ifx\test@i\@empty\else
+ \stepcounter{moodle@NumStarredAnswers}%
\InsertLastItem{questionlist}{#1}%
\fi
- \InsertLastItem{answerlist}{#2}%
+ \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
- \g@addto@macro\matching@table@text{&&$\bullet$~#2\\}%
+ \xa\g@addto@macro\xa\matching@table@text\xa{%
+ &&\moodle@matching@right{#2}\\\\\relax%
+ }%
\else
- \stepcounter{moodle@numcorrectanswers}%
- \xa\g@addto@macro\xa\matching@table@text\xa{\test@i~$\bullet$&\leavevmode\cleaders\hb@xt@.44em{\hss$\cdot$\hss}\hfill\kern\z@&$\bullet$~#2\\}%
+ \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
}%
@@ -3812,33 +4576,34 @@
\def\moodle@subanswertext{#2}%
\trim@spaces@in\moodle@subquestiontext
\xa\converttohtmlmacro\xa\moodle@subquestiontext@htmlized\xa{\moodle@subquestiontext}%
- \trim@spaces@in\moodle@subanswertext
- \ifmoodle@draganddrop
- \xa\converttohtmlmacro\xa\moodle@subanswertext@htmlized\xa{\moodle@subanswertext}%
- \fi
\addto@xml[2]{\moodle@answers@xml}{<subquestion format="html">}%
\ifx\moodle@subquestiontext\@empty
\addto@xml[4]{\moodle@answers@xml}{ <text></text>}%
\else
- \addto@xml[4]{\moodle@answers@xml}{ <text><![CDATA[<p>\moodle@subquestiontext@htmlized</p>]]></text>}%
+ \addto@xml[4]{\moodle@answers@xml}{ <text><![CDATA[<p>\moodle@subquestiontext@htmlized</p>]]></text>\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}{ <answer format="html"><text><![CDATA[<p>\moodle@subanswertext@htmlized</p>]]></text></answer>}%
+ \addto@xml[4]{\moodle@answers@xml}{ <answer format="html"><text><![CDATA[<p>\moodle@subanswertext@htmlized</p>]]></text>\ifmoodle@pluginfile\htmlize@embeddedfiletags\fi</answer>}%
\else
-% \show\moodle@subanswertext
- \addto@xml[4]{\moodle@answers@xml}{ <answer><text>\moodle@subanswertext</text></answer>}%
+% \show\moodle@subanswertext@htmlized
+ \addto@xml[4]{\moodle@answers@xml}{ <answer format="html"><text><![CDATA[\moodle@subanswertext@htmlized]]></text></answer>}%
\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}{ <feedback
+% \addto@xml[4]{\moodle@answers@xml}{ <feedback
%format="html"><text><![CDATA[<p>\moodle@feedback@html</p>]]></text></feedback>}%
% \fi
\addto@xml[2]{\moodle@answers@xml}{</subquestion>}%
}%
-% WRITING QUESTION TO XML FILE
+% WRITING QUESTION TO \XML\ FILE
\gdef\writematchingquestion{%
\ifmoodle@draganddrop
\writetomoodle{<question type="ddmatch">}%
@@ -3855,17 +4620,17 @@
% \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:
+% 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.
+% \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.
+% cloze code as part of the \XML\ questiontext.
% \end{enumerate}
% \begin{macrocode}
% LATEX PROCESSING
@@ -3880,7 +4645,7 @@
% A cloze question won't have any \item's in it, so we just use \BODY.
\moodle@enableclozeenvironments
%First, the LaTeX processing.
- \item \textbf{\moodle@questionname}
+ \item \moodle@begin@samepage\textbf{\moodle@questionname}
\ifmoodle@handout
\moodle@makelatextag@qtype{cloze}
\else
@@ -3897,12 +4662,13 @@
%\csname moodle@cloze@latexprocessing\endcsname
\ifmoodle@handout\else
\ifx\moodle@generalfeedback\@empty\relax\else%
- \fbox{\parbox{\linewidth}{\emph{\moodle@generalfeedback}}}%
+ \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.
+ \xa\questiontext\xa{\BODY}% Save the question text as \HTML.
\writeclozequestion
}{}%
\egroup%
@@ -3917,7 +4683,7 @@
\let\endshortanswer=\endclozeshortanswer
}
-% WRITING QUESTION TO XML FILE
+% WRITING QUESTION TO \XML\ FILE
\gdef\writeclozequestion{%
\writetomoodle{<question type="cloze">}%
\moodle@writequestionname%
@@ -3930,14 +4696,53 @@
}%
% \end{macrocode}
%
-% \subsubsection{Cloze Multiple Choice Questions}
-%
+% 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}{default grade=1}%
\setkeys{moodle}{#1}%
+ \moodle@checkclozegrade
\expandafter\gatheritems\xa{\BODY}%
\let\moodle@questionheader=\gatheredheader
\ifhtmlizer@active
@@ -3946,30 +4751,35 @@
\xa\g@addto@macro\xa\moodle@clozemulti@output\xa{\moodle@questionheader}%
\def\clozemulti@coding{}%
\edef\clozemulti@coding{\csname moodle@default grade\endcsname:}%
- \ifmoodle@multiple
- \PackageWarning{moodle}{Cloze Multiresponse only supported by Moodle 3.5+}
- \g@addto@macro{\clozemulti@coding}{MULTIRESPONSE}%
- \else
+ \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@shuffle
- \g@addto@macro{\clozemulti@coding}{_}%
- \fi
+ \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@multiple
- \PackageError{moodle}{Vertical mode (dropdown box) incompatible with multiresponse.}
- \else
+ \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
- \PackageWarning{moodle}{Cloze Multi Shuffling only supported by Moodle 3.0+}
+ \moodle@WarningOrError{3}{0}{Cloze Multi Shuffling}
\g@addto@macro{\clozemulti@coding}{S:}%
\else
\g@addto@macro{\clozemulti@coding}{:}%
@@ -3991,10 +4801,11 @@
\noindent
\moodle@makelatextag@qtype{multi}
\ifmoodle@handout\else
- \moodle@makelatextag@value{default grade}{\moodle@marks{\csname moodle@default grade\endcsname}}
+ \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}%
@@ -4013,7 +4824,7 @@
\par\noindent
\ifmoodle@handout
\begin{tabular}[t]{|p{.45\linewidth}|}
- \else
+ \else
\begin{tabular}[t]{|p{.45\linewidth}|p{.45\linewidth}|}
% answer & feedback \\\hline\hline
\fi
@@ -4039,13 +4850,15 @@
\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][]{%
- \setkeys{moodle}{fraction=0,#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{%
@@ -4070,13 +4883,43 @@
\trim@spaces@in\moodle@answertext
\trim@spaces@in\moodle@answertext
\ifmoodle@handout\else
- \ifx\moodle@fraction\@hundred
- \g@addto@macro\moodle@answertext{$~\checkmark$}%
- \else
- \moodle@checkfraction
- \ifdim0pt=\moodle@fraction pt\relax\else
- \xdef\moodle@answertext{\expandonce\moodle@answertext$~(\moodle@fraction\%)$}%
+ \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
@@ -4088,7 +4931,7 @@
\or % Case 1
\ifmoodle@handout\else
\ifx\moodle@feedback\@empty\relax\else
- \xdef\moodle@answertext{\expandonce\moodle@answertext \hfill \expandonce\emph{$\rightarrow$ \expandonce\moodle@feedback}}%
+ \xdef\moodle@answertext{\expandonce\moodle@answertext \moodle@preFeedback \expandonce\emph{$\rightarrow$ \expandonce\moodle@feedback}}%
\fi
\fi
\else % otherwise
@@ -4130,9 +4973,9 @@
\trim@spaces@in\moodle@answertext
\trim@spaces@in\moodle@answertext
\ifx\moodle@fraction\@hundred
- \g@addto@macro\clozemulti@coding{=}%
+ \g@addto@macro\clozemulti@coding{\clozecorrect}%
\else
- \moodle@checkfraction
+ \moodle@checkclozefraction
\ifdim0pt=\moodle@fraction pt\relax\else
\xdef\clozemulti@coding{\expandonce\clozemulti@coding\otherpercent\moodle@fraction\otherpercent}%
\fi
@@ -4145,14 +4988,14 @@
% \end{macrocode}
%
% \subsubsection{Cloze Numerical Questions}
-%
+%
% \begin{macrocode}
\NewEnviron{clozenumerical}[1][]{%
\bgroup
\expandafter\gatheritems\expandafter{\BODY}%
\let\moodle@questionheader=\gatheredheader
- \setkeys{moodle}{default grade=1}%
\setkeys{moodle}{#1}%
+ \moodle@checkclozegrade
\ifhtmlizer@active
%HTML version
\def\moodle@clozenumerical@output{}%
@@ -4175,7 +5018,7 @@
\noindent
\moodle@makelatextag@qtype{numerical}
\ifmoodle@handout\else
- \moodle@makelatextag@value{default grade}{\moodle@marks{\csname moodle@default grade\endcsname}}
+ \moodle@makelatextag@value{default grade}{marked out of}
\moodle@makelatextag@numerical
\par
\noindent
@@ -4205,29 +5048,29 @@
\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@checkfraction
+ \moodle@checkclozefraction
\edef\moodle@clozenumericalprint@fraction{$(~\moodle@fraction\%)$}%
\fi
- \ifnum\z@=\moodle@tolerance
+ \ifx\moodle@zero\moodle@tolerance%
\def\moodle@clozenumericalprint@tolerance{}%
\else
- \edef\moodle@clozenumericalprint@tolerance{$\,\pm\,$\moodle@printnum{\moodle@tolerance}}%
+ \edef\moodle@clozenumericalprint@tolerance{$\,\pm\,$\moodle@printnum{\expandonce\moodle@tolerance}}%
\fi
- \xdef\test@i{\trim@spaces{#1}}%
+ \gdef\test@i{#1}%
+ \trim@spaces@in\test@i
\ifx\test@i\@star
- \xdef\moodle@clozenumericalprint@line{#1~\moodle@clozenumericalprint@fraction & \expandonce\emph{\expandonce\moodle@feedback}}%
+ \xdef\moodle@clozenumericalprint@line{\expandonce\test@i~\moodle@clozenumericalprint@fraction & \expandonce\emph{\expandonce\moodle@feedback}}%
\else
- \xdef\moodle@clozenumericalprint@line{\moodle@printnum{#1}\moodle@clozenumericalprint@tolerance~\moodle@clozenumericalprint@fraction & \expandonce\emph{\expandonce\moodle@feedback}}%
+ \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
@@ -4244,9 +5087,9 @@
\def\moodle@answertext{#1}%
\trim@spaces@in\moodle@answertext
\ifx\moodle@fraction\@hundred
- \g@addto@macro\clozenumerical@coding{=}%
+ \g@addto@macro\clozenumerical@coding{\clozecorrect}%
\else
- \moodle@checkfraction
+ \moodle@checkclozefraction
\ifdim0pt=\moodle@fraction pt\relax\else
\xdef\clozenumerical@coding{\expandonce\clozenumerical@coding\otherpercent\moodle@fraction\otherpercent}%
\fi
@@ -4264,27 +5107,20 @@
% \end{macrocode}
%
% \subsubsection{Cloze Short Answer Questions}
-%
+%
% \begin{macrocode}
\NewEnviron{clozeshortanswer}[1][]{%
\bgroup
\expandafter\gatheritems\expandafter{\BODY}%
\let\moodle@questionheader=\gatheredheader
- \setkeys{moodle}{default grade=1}%
\setkeys{moodle}{#1}%
- %Because nesting conditionals built by \csname doesn't work well,
- %we'll test '\ifmoodle@case sensitive' now and save the result in \count0.
- \csname ifmoodle@case sensitive\endcsname
- \count0=1\relax
- \else
- \count0=0\relax
- \fi
+ \moodle@checkclozegrade
\ifhtmlizer@active
%HTML version
\def\moodle@clozeshortanswer@output{}%
\xa\g@addto@macro\xa\moodle@clozeshortanswer@output\xa{\moodle@questionheader}%
\def\clozeshortanswer@coding{}%
- \ifnum\count0=1\relax
+ \ifmoodle@usecase
\edef\clozeshortanswer@coding{\csname moodle@default grade\endcsname:SHORTANSWER_C:}%
\else
\edef\clozeshortanswer@coding{\csname moodle@default grade\endcsname:SHORTANSWER:}%
@@ -4305,7 +5141,7 @@
\noindent
\moodle@makelatextag@qtype{shortanswer}
\ifmoodle@handout\else
- \moodle@makelatextag@value{default grade}{\moodle@marks{\csname moodle@default grade\endcsname}}
+ \moodle@makelatextag@value{default grade}{marked out of}
\moodle@makelatextag@shortanswer
\par
\noindent
@@ -4339,15 +5175,13 @@
\ifx\moodle@fraction\@hundred
\def\moodle@clozeshortanswerprint@fraction{$~\checkmark$}%
\else
- \moodle@checkfraction
+ \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
@@ -4364,9 +5198,9 @@
\def\moodle@answertext{#1}%
\trim@spaces@in\moodle@answertext
\ifx\moodle@fraction\@hundred
- \g@addto@macro\clozeshortanswer@coding{=}%
+ \g@addto@macro\clozeshortanswer@coding{\clozecorrect}%
\else
- \moodle@checkfraction
+ \moodle@checkclozefraction
\ifdim0pt=\moodle@fraction pt\relax\else
\xdef\clozeshortanswer@coding{\expandonce\clozeshortanswer@coding\otherpercent\moodle@fraction\otherpercent}%
\fi
@@ -4379,9 +5213,9 @@
% \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.
-%
+% 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}
@@ -4391,8 +5225,9 @@
\catcode`\^=12\gdef\othercaret{^}%
\catcode`\$=12\gdef\otherdollar{$}%
\catcode`\%=12\gdef\otherpercent{%}
- \catcode`\%=12\gdef\otherlbracket{[}
- \catcode`\%=12\gdef\otherrbracket{]}}%
+ \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%
@@ -4407,11 +5242,12 @@
\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
@@ -4459,17 +5295,17 @@
% \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
+% 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}
@@ -4486,7 +5322,7 @@
\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%
+ \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,
@@ -4537,9 +5373,9 @@
% \end{macrocode}
%
% \subsection{Separation}
-%
+%
% This code separates a string of tokens into two parts.
-% Its parameters, |#1#2|, consist of tokenized text,
+% 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 ``|{...}|'',
@@ -4560,16 +5396,16 @@
% \end{macrocode}
%
% The next line creates the macro |\htmlize@remove@stopcode|,
-% which removes the characters ``|\@htmlize@stop |'' from the end of a
+% 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
@@ -4583,6 +5419,9 @@
\long\def\converttohtmlmacro#1#2{%
\grouplevel=0\relax
\def\htmlize@output{}%
+ \ifmoodle@pluginfile
+ \gdef\htmlize@embeddedfiletags{}%
+ \fi
\htmlizer@activetrue%
\converttohtml@int{#2}%
\htmlizer@activefalse%
@@ -4601,6 +5440,7 @@
\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).
@@ -4612,24 +5452,28 @@
\let\htmlize@next@i=\relax
\else
\ifx\test@i\@otherlbrace%
- \xa\g@addto@macro\xa\htmlize@output\xa{\otherlbrace}%
- \bgroup
- \normalcatcodes
+ \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%
+ {\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}%
+ \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%
+ \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}%
- %
+ \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}%
@@ -4637,22 +5481,23 @@
% \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}}%
+ \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}%
+ \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
+ \egroup
+ \let\htmlize@next@i=\htmlize@scrap
+ \fi
\else
\ifx\test@i\@otherdollar%
% Math shift character.
@@ -4669,7 +5514,7 @@
\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,
+ % 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
@@ -4687,9 +5532,9 @@
% 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
+ % 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
+ % 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!
@@ -4701,10 +5546,10 @@
% Environments: \begin{array}
%
% #2 is only for items on a specific list.
- % #1 is anything that runs in TeX's mouth.
+ % #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}}%
@@ -4744,7 +5589,7 @@
%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.
+ %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}%
}%
@@ -4787,7 +5632,7 @@
\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.
+ % 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}%
@@ -4796,8 +5641,9 @@
\fi% \ifx\@htmlize@cs\@@begin@cs
\else%
\ifx\test@i\@othertilde%
- % The ~ becomes non-breaking space &nbsp;
- \g@addto@macro\htmlize@output{\otherampersand nbsp;}%
+ % The ~ becomes non-breaking space &nbsp; 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%
@@ -4813,26 +5659,25 @@
\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{\otherampersand rsquo;\otherampersand rsquo;}}%
+ \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
- \g@addto@macro\htmlize@output{\otherampersand rsquo;}%
+ \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 rdquo;}%
+ \g@addto@macro\htmlize@output{\otherampersand quot;}%
\def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}%
\else
\ifx\test@i\@lt
- \moodle@ifmathmode{\g@addto@macro\htmlize@output{\otherampersand lt;}}%
- {\g@addto@macro\htmlize@output{<}}%
+ \g@addto@macro\htmlize@output{\otherampersand lt;}
\def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}%
\else
\ifx\test@i\@gt
- \moodle@ifmathmode{\g@addto@macro\htmlize@output{\otherampersand gt;}}%
- {\g@addto@macro\htmlize@output{>}}%
+ \g@addto@macro\htmlize@output{\otherampersand gt;}%
\def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}%
\else
\ifx\test@i\@dash
@@ -4845,9 +5690,19 @@
\def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}%
\fi
\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}%
+ \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
@@ -4866,9 +5721,9 @@
\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...|"
@@ -4877,9 +5732,9 @@
\edef\inlinemathleftdelim{\otherbackslash(}%
\def\inlinemathrightdelim#1{\advancemathmodecounter{-1}%
\g@addto@macro\htmlize@output{\otherbackslash)}}%
-\edef\displaymathleftdelim{\otherbackslash[}%
+\edef\displaymathleftdelim{<CENTER>\otherbackslash[}%
\def\displaymathrightdelim#1{\advancemathmodecounter{-1}%
- \g@addto@macro\htmlize@output{\otherbackslash]}}%
+ \g@addto@macro\htmlize@output{\otherbackslash]</CENTER>}}%
\long\def\htmlize@inlinemath@recursive@i#1#2#3\htmlize@rdelim@i{%
% inspired by \htmlize@recursive@i
\def\test@i{#1}%
@@ -4926,20 +5781,20 @@
}
% \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,
+ \bgroup %The corresponding \egroup is given in \htmlize@proceedwiththerest,
%to localize the changes to the environment definitions.
\htmlize@activate@environments
\gdef\htmlize@afteraction@hook{}%
@@ -4950,7 +5805,6 @@
\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}%
}
@@ -4965,14 +5819,13 @@
}%
}
-
\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.
+% 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}
@@ -4980,7 +5833,7 @@
\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,
+ % 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
@@ -5012,7 +5865,7 @@
%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%
+ \xa\htmlize@recursive@i\htmlize@remainder@detokenized\@htmlize@stop\@htmlize@stop\@htmlize@stop\htmlize@rdelim@i%
}
\long\def\htmlize@record@action#1{%
@@ -5020,7 +5873,7 @@
}
\def\htmlize@activate@css{}%
-\def\html@action@def#1{%
+\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}%
@@ -5032,7 +5885,7 @@
\else
\xa\html@action@def\csname #1\endcsname{\csname moodle@#1@int\endcsname}%
\fi
- % Note that \htmlize@do@actioncs will 'patch' this by putting
+ % 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.
@@ -5046,18 +5899,18 @@
}%
}
% \end{macrocode}
-%
+%
% \subsubsection{Engine for expansion control sequences}
-%
+%
% Calling |\htmlize@redefine@expansionmacros| will redefine
% the macros for us. It starts out empty.
% \begin{macrocode}
-\def\htmlize@redefine@expansionmacros{}%
+\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.
+% 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}
@@ -5073,7 +5926,7 @@
% |\renewcommand|, |\providecommand| or their starred variants.
% \begin{macrocode}
\def\moodleregisternewcommands{%
- %% INSPIRED FROM
+ %% INSPIRED FROM
%https://tex.stackexchange.com/questions/73271/how-to-redefine-or-patch-the-newcommand-command
\newcommand*{\saved@ifdefinable}{}
\let\saved@ifdefinable\@ifdefinable
@@ -5084,8 +5937,8 @@
\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
+% 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
@@ -5098,15 +5951,15 @@
\xa\def\csname html@\string#1\endcsname%
}
% \end{macrocode}
-% Note that when |\html@def| expands out, it ends with |\def\html@\oldcsname|
+% 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
+% we define specific environments, action control sequences, and macros to
% expand to accomplish our purposes.
-%
+%
% \subsubsection{Action Environments}
% \begin{macrocode}
\htmlize@record@environment{clozemulti}
@@ -5116,7 +5969,11 @@
\htmlize@record@environment{clozeshortanswer}
\htmlize@record@environment{shortanswer}
-\html@newenvironment{center}{\xdef\htmlize@afteraction@hook{<CENTER>\expandonce\BODY</CENTER>}}%
+\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}%
@@ -5129,13 +5986,13 @@
\moodle@restoreitems{\thenumgathereditems}%
}%
\def\moodle@saveitems#1{%
- \ifnum#1>0%
+ \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%
+ \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}%
@@ -5146,9 +6003,9 @@
\advance\moodle@listdepth by 1\relax
\moodle@save@getitems@state%
\xa\gatheritems\xa{\BODY}%
- \gdef\htmlize@afteraction@hook{<#2>}%
+ \gdef\htmlize@afteraction@hook{\HTMLtag{#2}}%
\loopthroughitemswithcommand{\moodle@itemtoLI}%
- \g@addto@macro\htmlize@afteraction@hook{</#2>}%
+ \g@addto@macro\htmlize@afteraction@hook{\HTMLtag{/#2}}%
\moodle@restore@getitems@state%
\advance\moodle@listdepth by -1\relax
}%
@@ -5158,15 +6015,15 @@
\moodle@makelistenv{itemize}{UL}%
\def\moodle@itemtoLI#1{%
- \g@addto@macro\htmlize@afteraction@hook{<LI>#1}%
+ \g@addto@macro\htmlize@afteraction@hook{\HTMLtag{LI}#1}%
\trim@spaces@in\htmlize@afteraction@hook%
- \g@addto@macro\htmlize@afteraction@hook{</LI>}%
+ \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
@@ -5182,26 +6039,34 @@
\htmlize@record@action{\endclozemode}%
\htmlize@record@action{\relax}%
-\html@action@def\%{\g@addto@macro\htmlize@output{\otherpercent}}%
+\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{<BR/>}}}%
+\html@action@def\\{%
+ \moodle@ifmathmode{\g@addto@macro\htmlize@output{\otherbackslash\otherbackslash}}%
+ {\g@addto@macro\htmlize@output{<BR/>}}
+ }%
\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}\fi
- \g@addto@macro\htmlize@output{\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}%
+ \g@addto@macro\htmlize@output{<CENTER>\otherbackslash\otherlbracket}%
}%
\html@action@def\]{%
- \g@addto@macro\htmlize@output{\otherbackslash\otherrbracket}%
+ \g@addto@macro\htmlize@output{\otherbackslash\otherrbracket</CENTER>}%
\advancemathmodecounter{-1}
}%
\html@action@def\({%
@@ -5224,15 +6089,64 @@
\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}%
@@ -5242,17 +6156,17 @@
\endclozemode
}%
\html@action@def\TeX{%
- \g@addto@macro\htmlize@output{\otherbackslash(\otherbackslash rm\otherbackslash TeX\otherbackslash)}
+ \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)}
+ \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|}}
+ \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{%
@@ -5269,7 +6183,7 @@
%Diaeresis/Tréma/Umlaut
{\catcode`|=3\relax
- \gdef\htmlize@diaeresis{a|e|i|o|u|y|A|E|I|O|U|Y|}}
+ \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}}%
@@ -5293,7 +6207,7 @@
\ifx\test@i\@u
\def\toadd{\otherampersand\otherhash369\othersemicol}%
\else
- \def\toadd{\otherbackslash\otherlbrace#1\otherrbrace}%
+ \def\toadd{\otherbackslash H\otherlbrace#1\otherrbrace}%
\fi
\fi
\fi
@@ -5305,40 +6219,40 @@
%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\otherlbrace#1\otherrbrace}%
- \fi
- \fi
- \fi
- \fi
- \fi
- \fi
- \xa\g@addto@macro\xa\htmlize@output\xa{\toadd}%
- \egroup
+ \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|}}
+ \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}}%
@@ -5347,12 +6261,12 @@
% breve diacritics
{\catcode`|=3\relax
- \gdef\htmlize@breve{A|G|U|a|g|u|}}
+ \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
@@ -5376,7 +6290,7 @@
\ifx\test@i\@o
\def\toadd{\otherampersand\otherhash335\othersemicol}%
\else
- \def\toadd{\otherbackslash\otherlbrace#1\otherrbrace}%
+ \def\toadd{\otherbackslash u\otherlbrace#1\otherrbrace}%
\fi
\fi
\fi
@@ -5391,7 +6305,7 @@
% 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|}}
+ \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}}%
@@ -5400,11 +6314,11 @@
% Ogonek diacritics
{\catcode`|=3\relax
- \gdef\htmlize@ogonek{A|E|I|U|a|e|i|u|}}
+ \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
@@ -5413,84 +6327,292 @@
\ifx\test@i\@o
\def\toadd{\otherampersand\otherhash491\othersemicol}%
\else
- \def\toadd{\otherbackslash\otherlbrace#1\otherrbrace}%
+ \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}
-%
-% \begin{macrocode}
-\html@def\underline#1{<SPAN STYLE=\@dquote text-decoration: underline;\@dquote>#1</SPAN>}%
-\html@def\emph#1{<EM>#1</EM>}%
-\html@def\textit#1{<I>#1</I>}%
-\html@def\textbf#1{<B>#1</B>}%
-\html@def\texttt#1{<CODE>#1</CODE>}%
-\html@def\textsc#1{<SPAN STYLE=\@dquote font-variant: small-caps;\@dquote>#1</SPAN>}%
-\html@def\url#1{<A href=\@dquote #1\@dquote>#1</A>}%
-\html@def\href#1#2{<A href=\@dquote #1\@dquote>#2</A>}%
-\html@def\textsuperscript#1{<SUP>#1</SUP>}%
-\html@def\up#1{<SUP>#1</SUP>}%
-\html@def\fup#1{<SUP>#1</SUP>}%
-\html@def\textsubscript#1{<SUB>#1</SUB>}%
+%
+% 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{____________}%
-\html@def\par{<BR/>}%
+\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{<SPAN STYLE="text-decoration: underline;">#1</SPAN>}}%
+}%
+% \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{\&aring;}%
\html@def\AA{\&Aring;}%
\html@def\ae{\&aelig;}%
\html@def\AE{\&AElig;}%
-\html@def\oe{\&oelig;}%
-\html@def\OE{\&OElig;}%
-\html@def\S{\&sect;}%
-\html@def\euro{\&euro;}%
-\html@def\texteuro{\&euro;}%
+\html@def\dh{\&eth;}%
+\html@def\DH{\&ETH;}%
+\html@def\dj{\&dstrok;}%
+\html@def\DJ{\&Dstrok;}%
+\html@def\i{\&imath;}%
+\html@def\ij{\&ijlig;}%
+\html@def\IJ{\&IJlig;}%
+\html@def\j{\&jmath;}%
+\html@def\l{\&lstrok;}%
+\html@def\L{\&Lstrok;}%
+\html@def\ng{\&eng;}%
+\html@def\NG{\&ENG;}%
\html@def\o{\&oslash;}%
\html@def\O{\&Oslash;}%
+\html@def\oe{\&oelig;}%
+\html@def\OE{\&OElig;}%
\html@def\ss{\&szlig;}%
\html@def\SS{\&\#7838;}%
-\html@def\l{\&lstrok;}%
-\html@def\L{\&Lstrok;}%
+\html@def\th{\&thorn;}%
+\html@def\TH{\&THORN;}%
+% \end{macrocode}
+% Fifth, \LaTeX\ commands for horizontal spacing and line breaks.
+% In a number of situations, paragraph breaks translated into
+% |</p><p>| 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{\&blank;}%
+\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{\&iquest;}%
+\html@def\textexclamdown{\&iexcl;}%
+\html@def\euro{\&euro;}%
+\html@def\texteuro{\&euro;}%
+\html@def\S{\&sect;}%
+% \end{macrocode}
+% Seventh, \LaTeX\ commands for various quotation marks.
+% \begin{macrocode}
+\html@def\textquoteleft{\&lsquo;}%
+\html@def\textquoteright{\&rsquo;}%
+\html@def\textquotedblleft{\&ldquo;}%
+\html@def\textquotedblright{\&rdquo;}%
+\html@def\guilsinglleft{\&lsaquo;}%
+\html@def\guilsinglright{\&rsaquo;}%
+\html@def\guillemotleft{\&laquo;}%
+\html@def\guillemotright{\&raquo;}%
+\html@def\quotesinglbase{\&sbquo;}%
+\html@def\quotedblbase{\&bdquo;}%
+\html@def\flq{\&lsaquo;}%
+\html@def\frq{\&rsaquo;}%
+\html@def\flqq{\&laquo;}%
+\html@def\frqq{\&raquo;}%
\html@def\og{\&laquo;\&\#8239;}%
-\html@def\guillemotleft{\&laquo;\&\#8239;}%
\html@def\fg{\&\#8239;\&raquo;}%
-\html@def\guillemotright{\&\#8239;\&raquo;}%
-\html@def\glqq{\&bdquo;}%
-\html@def\grqq{\&ldquo;}%
\html@def\glq{\&sbquo;}%
\html@def\grq{\&lsquo;}%
-\html@def\flqq{\&laquo;\&\#8239;}%
-\html@def\frqq{\&\#8239;\&raquo;}%
-\html@def\flq{\&lsaquo;}%
-\html@def\frq{\&rsaquo;}%
+\html@def\glqq{\&bdquo;}%
+\html@def\grqq{\&ldquo;}%
\html@def\dq{\&quot;}%
-\html@def\,{\&\#8239;}%
-\html@def\thinspace{\&\#8239;}%
-\html@def\textbackslash{\&\#92;}%
-\html@def\_{\&\#95;}%
-\html@def\textquestiondown{\&iquest;}%
-\html@def\textexclamdown{\&iexcl;}%
-
-% AH CUSTOM MACROS TO EXPAND --- remove these before publishing!
-%\htmlize@record@expand{\inv}%
-%\htmlize@record@expand{\rec}%
-
-\htmlize@record@action\inlinemathrightdelim
-\htmlize@record@action\displaymathrightdelim
-
% \end{macrocode}
%
-% \subsubsection{Passing Code to XML Only}
-% Users may want to include pieces of HTML code to the XML file only.
+% \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.
+% 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}%
@@ -5498,10 +6620,10 @@
% \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 |graphics.sty|.
+% 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{}|.
@@ -5513,10 +6635,10 @@
% \begin{macrocode}
\AtEndPreamble{%
\@ifpackageloaded{graphics}{%
- \@ifpackagelater{graphics}{2019/10/08}{}{%
- \PackageError{moodle}{`moodle' is made to interact with the `graphics'
- package not older than 2019/10/08.}%
- }%
+ \@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{%
@@ -5574,7 +6696,7 @@
% begin modified part
\xdef\moodle@media@base{\detokenize\xa{\Gin@base}}%
\xdef\moodle@media@ext{\detokenize\xa{\Gin@ext}}%
- % end modfied part
+ % end modified part
\fi
\endgroup
}
@@ -5635,7 +6757,7 @@
\htmlize@setexecutable@int
}
\def\htmlize@setexecutable@int#1{%
- \egroup
+ \egroup
\expandafter\def\htmlize@executable@macro{#1}%
}
@@ -5647,30 +6769,41 @@
\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%
-
-\imagemagickcommand{convert -colorspace RGB}%
\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}%
-\optiSVGcommand{scour -q --enable-id-stripping --enable-comment-stripping
- --shorten-ids --indent=none --remove-descriptive-elements}%
% \end{macrocode}
-%
+%
% \subsubsection{Conversion and inclusion of non-native formats}
% \begin{macrocode}
\AtEndPreamble{%
- \@ifpackageloaded{graphicx}{%
+ \@ifpackageloaded{graphics}{%
\def\@firstofthree#1#2#3{#1}%
\def\@secondofthree#1#2#3{#2}%
\newcommand{\DeclareGraphicsAlien}[3]{%
@@ -5690,11 +6823,11 @@
\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.
+% 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]' \OutputFile}%
+ \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.}}{}%}%
@@ -5727,7 +6860,7 @@
}
\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.
@@ -5738,16 +6871,16 @@
% \begin{macrocode}
\ifmoodle@svg
\AtEndPreamble{%
-% Declaring SVG to PDF conversion rule for includegraphics
+% 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' -o '\OutputFile' 2>/dev/null}%
+ \SVGtoPDF\otherspace \SourceFile\otherspace -o \otherspace\OutputFile\otherspace 2>\DevNull}%
\DeclareGraphicsAlien{.SVG}{.pdf}{%
- \SVGtoPDF\otherspace '\SourceFile' -o '\OutputFile' 2>/dev/null}%
+ \SVGtoPDF\otherspace \SourceFile\otherspace -o \otherspace\OutputFile\otherspace 2>\DevNull}%
}%
\fi
\def\moodle@checkconversionsuccess#1#2{%
@@ -5780,8 +6913,8 @@
\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
+ % 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
@@ -5817,24 +6950,24 @@
% 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% PDF file and SVG option active
- \def\moodle@media@ext@current{.svg}%
+ \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>/dev/null}%
+ \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" && mv "\moodle@media@base.tmp.svg"
+ "\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{.png}%
+ \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}%
@@ -5852,17 +6985,42 @@
%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"
+ \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
- \ShellEscape{\DeleteFiles\otherspace "\moodle@media@base.enc"}%
+ \ifwindows
+ \ShellEscape{powershell.exe "del ""\moodle@media@base.enc"""}%
+ \else
+ \ShellEscape{\DeleteFiles\otherspace "\moodle@media@base.enc"}%
+ \fi
\else
- \ShellEscape{\DeleteFiles\otherspace "\moodle@media@base.enc" "\moodle@media@base\moodle@media@ext@current"}%
+ \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%
- \edef\htmlize@imagetag{<IMG \moodle@graphics@htmlgeometry\otherspace SRC="data:\moodle@media@mime@current;base64,\csname picbaselxiv@graphics@#2\endcsname">}%
+ \ifmoodle@pluginfile
+ \edef\htmlize@imagetag{<IMG \moodle@graphics@htmlgeometry\otherspace SRC="@@PLUGINFILE@@/\moodle@media@base\moodle@media@ext@current">}%
+ \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{<file name="\moodle@media@base}%
+ \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{\moodle@media@ext@current"}
+ \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{ path="/\moodle@media@path" encoding="base64">}%
+ \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{\csname picbaselxiv@graphics@#2\endcsname</file>}%
+ \else
+ \edef\htmlize@imagetag{<IMG \moodle@graphics@htmlgeometry\otherspace SRC="data:\moodle@media@mime@current;base64,\csname picbaselxiv@graphics@#2\endcsname">}%
+ \fi
\xa\g@addto@macro\xa\htmlize@output\xa{\htmlize@imagetag}%
\message{moodle.sty: <IMG> tag inserted.^^J}%
\egroup
@@ -5879,7 +7037,7 @@
}%
\ifwindows
\def\ConvertToBaseLXIV@int#1#2{%
- \def\cmdline{\baselxiv\otherspace -encode "#1#2"\otherspace tmp.b64 && findstr /vbc:"---" tmp.b64 > "#1.enc" && del tmp.b64}%
+ \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
@@ -5893,7 +7051,7 @@
\fi
\fi
% \end{macrocode}
-% The following code accomplishes the reading of an |.enc| file into memory.
+% 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
@@ -5914,12 +7072,12 @@
\baselxiv@next
}
% \end{macrocode}
-%
+%
% \subsection{\TikZ\ Picture Handling}
-% If the user is not using the \TikZ\ package, there is no need to waste time
+% 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
+% 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}
@@ -5943,24 +7101,38 @@
\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>/dev/null}%
+ \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>/dev/null}%
- \xa\ShellEscape\xa{\cmdline}%
+ \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
- \def\OptimizeExport{ \message{moodle.sty: Optimizing '\moodle@basename.svg'...^^J}%
+ \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" && mv "\moodle@basename.tmp.svg"
+ "\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}%
@@ -5993,7 +7165,7 @@
\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
+ % 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
@@ -6027,20 +7199,38 @@
\fi
%
% The HTMLizer version of the tikzpicture environment,
- % which writes an <IMG> tag to the XML file.
+ % which writes an <IMG> 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
- \edef\htmlize@imagetag{<IMG SRC="data:\TikzExportMIME;base64,\csname picbaselxiv@\the\numpicturesread\endcsname">}%
+ \ifmoodle@pluginfile
+ \edef\htmlize@imagetag{<IMG SRC="@@PLUGINFILE@@/tikz/\tikzexternalrealjob-tikztemp-\the\numpicturesread\TikzExportExtension">}%
+ \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{<file name="\tikzexternalrealjob-tikztemp-}%
+ \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{\the\numpicturesread}%
+ \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{\TikzExportExtension"}
+ \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{ path="/tikz/" encoding="base64">}%
+ \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{\csname picbaselxiv@\the\numpicturesread\endcsname</file>}%
+ \else
+ \edef\htmlize@imagetag{<IMG SRC="data:\TikzExportMIME;base64,\csname picbaselxiv@\the\numpicturesread\endcsname">}%
+ \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
- \edef\htmlize@imagetag{<IMG SRC="data:\TikzExportMIME;base64,\csname picbaselxiv@\the\numpicturesread\endcsname">}%
+ \ifmoodle@pluginfile
+ \edef\htmlize@imagetag{<IMG SRC="@@PLUGINFILE@@/tikz/\tikzexternalrealjob-tikztemp-\the\numpicturesread\TikzExportExtension">}%
+ \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{<file name="\tikzexternalrealjob-tikztemp-}%
+ \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{\the\numpicturesread}%
+ \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{\TikzExportExtension"}
+ \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{ path="/tikz/" encoding="base64">}%
+ \xa\g@addto@macro\xa\htmlize@embeddedfiletags\xa{\csname picbaselxiv@\the\numpicturesread\endcsname</file>}%
+ \else
+ \edef\htmlize@imagetag{<IMG SRC="data:\TikzExportMIME;base64,\csname picbaselxiv@\the\numpicturesread\endcsname">}%
+ \fi
\xa\g@addto@macro\xa\htmlize@output\xa{\htmlize@imagetag}%
}%
\else
@@ -6063,7 +7253,12 @@
\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%
}
@@ -6076,7 +7271,7 @@
\RequirePackage{varwidth}% for the command |embedaspict|
\fi
% \end{macrocode}
-% Finally, we clean up our mess by deleting the temporary PDF, PNG, and ENC
+% 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.
@@ -6087,12 +7282,16 @@
\ifXeTeX
% we must keep picture pdf's for subsequent linking (xdvipdfmx)
\ifwindows
- \ShellEscape{powershell.exe -noexit "del * -include \tikzexternalrealjob-tikztemp-*.* -exclude *.pdf}%
+ \ShellEscape{powershell.exe "del * -include \tikzexternalrealjob-tikztemp-*.* -exclude *.pdf"}%
\else
\ShellEscape{find . -type f -name "\tikzexternalrealjob-tikztemp-*.*" -not -name "*.pdf" -delete}%
\fi
\else
- \ShellEscape{\DeleteFiles\otherspace \tikzexternalrealjob-tikztemp-*.*}%
+ \ifwindows
+ \ShellEscape{powershell.exe "del \tikzexternalrealjob-tikztemp-*.*"}%
+ \else
+ \ShellEscape{\DeleteFiles\otherspace \tikzexternalrealjob-tikztemp-*.*}%
+ \fi
\fi
}{}%
\fi
@@ -6105,6 +7304,7 @@
% \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
@@ -6229,13 +7429,36 @@
% }%
}{}%
}%
+% \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{%
@@ -6245,6 +7468,7 @@
\@bsphack
\let\do\@makeother\dospecials
\catcode`\^^M\active
+ \moodle@HackTML
\def\verbatim@processline{\xa\g@addto@macro\xa\htmlize@output\xa{\the\verbatim@line<BR/>}}
\verbatim@readfile{#1}%
\@esphack
@@ -6261,30 +7485,33 @@
\@ifpackageloaded{fancyvrb}{\PackageError{moodle}{'moodle' should be loaded before 'fancyvrb'.}%
{'moodle' loads 'fancybox' which, unfortunately, redefines verbatim commands.}}{\relax}%
-\html@action@newcommand{VerbatimInput}[2][]{%
- \message{moodle.sty: Processing \string\VerbatimInput[#1]{#2} for HTML ^^J}%
- \def\FV@KeyValues{#1}%
- \FV@UseKeyValues% import options defined in #1
- \moodle@VerbatimInput{#2}%
-}%
-\html@action@newcommand{LVerbatimInput}[2][]{%
- \message{moodle.sty: Processing \string\LVerbatimInput[#1]{#2} for HTML ^^J}%
- \def\FV@KeyValues{#1}%
- \FV@UseKeyValues% import options defined in #1
- \moodle@VerbatimInput{#2}%
-}%
-\html@action@newcommand{BVerbatimInput}[2][]{%
- \message{moodle.sty: Processing \string\BVerbatimInput[#1]{#2} for HTML ^^J}%
- \def\FV@KeyValues{#1}%
- \FV@UseKeyValues% import options defined in #1
- \moodle@VerbatimInput{#2}%
-}%
+\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{<PRE style="\xmlDisplayVerbatimBox"><CODE>}%
%%%%%%%% using material from fancyvrb and fvextra %%%%%%%%
%\begingroup
\def\moodle@verbatim@addlinenumber##1{%
- \g@addto@macro\htmlize@output{<span style="font-size: 80\otherpercent;
+ \g@addto@macro\htmlize@output{<span style="font-size: 80\otherpercent;
background-color: \otherhash f0f0f0; padding: 0 5px 0 5px; display:
inline-block; width: 16pt; ##1">}%
\if@FV@NumberBlankLines
@@ -6294,10 +7521,10 @@
\xa\g@addto@macro\xa\htmlize@output\xa{\otherampersand nbsp;</span>}%
\else
\xa\g@addto@macro\xa\htmlize@output\xa{\the\c@FancyVerbLine</span>}%
- \fi
+ \fi
\fi
}
- % redefine the ProcessLine routine ('fancyvrb' and 'fvextra') for XML output
+ % 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{<mark>}% fvextra triggered highlighting for this line
@@ -6309,7 +7536,7 @@
\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
@@ -6341,13 +7568,16 @@
}{\relax}%
}
% \end{macrocode}
-% Third, we patch `minted' so that it also calls pygmentize to generate HTML code.
+% 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@checkstyle{\minted@get@opt{style}{default}}%
+ \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}}%
@@ -6360,7 +7590,7 @@
\def\minted@cmdtemplate##1##2{%
\ifminted@kpsewhich
\ifwindows
- \detokenize{for /f "usebackq tokens=*"}\space\@percentchar\detokenize{a
+ \detokenize{for /f "usebackq tokens=*"}\space\@percentchar\detokenize{a
in (`kpsewhich}\space\minted@codefile\detokenize{`) do}\space
\fi
\fi
@@ -6380,14 +7610,14 @@
\fi}%
\def\minted@cmd{\minted@cmdtemplate{latex -P commandprefix=PYG}{\minted@infile}}
% For debugging, uncomment: %%%%
- \immediate\typeout{\minted@cmd}%
+ %\immediate\typeout{\minted@cmd}%
% %%%%
- \def\minted@cmdHTML{\minted@cmdtemplate{html -P noclasses -P
+ \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
+ \def\minted@cmdPNG{\minted@cmdtemplate{png -P
line_numbers=True}{\minted@infilePNG}}%
- \def\minted@cmdSVG{\minted@cmdtemplate{svg -P
+ \def\minted@cmdSVG{\minted@cmdtemplate{svg -P
linenos=True}{\minted@infileSVG}}%
\ifthenelse{\boolean{minted@cache}}%
{%
@@ -6396,8 +7626,8 @@
\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@
+ \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}}}%
@@ -6407,7 +7637,7 @@
\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\FancyVerbStartNum\fi-\ifx\FancyVerbStopNum\z@
0\else\FancyVerbStopNum\fi)}}{}%
\immediate\closeout\minted@code
\edef\minted@argone@esc{#1}%
@@ -6421,22 +7651,22 @@
\def\minted@hashcmd{%
\detokenize{python -c "import hashlib; import os;
hasher = hashlib.sha1();
- f =
+ f =
open(os.path.expanduser(os.path.expandvars(\"}\minted@tmpfname@esc.mintedcmd\detokenize{\")),
\"rb\");
hasher.update(f.read());
f.close();
- f =
+ f =
open(os.path.expanduser(os.path.expandvars(\"}\minted@argone@esc\detokenize{\")),
\"rb\");
hasher.update(f.read());
f.close();
- f =
+ f =
open(os.path.expanduser(os.path.expandvars(\"}\minted@tmpfname@esc.mintedmd5\detokenize{\")),
\"w\");
- macro = \"\\edef\\minted@hash\" + chr(123) + hasher.hexdigest()
+ macro = \"\\edef\\minted@hash\" + chr(123) + hasher.hexdigest()
+ chr(125) + \"\";
- f.write(\"\\makeatletter\" + macro +
+ f.write(\"\\makeatletter\" + macro +
\"\\makeatother\\endinput\n\");
f.close();"}}%
\ShellEscape{\minted@hashcmd}%
@@ -6444,8 +7674,8 @@
\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@
+ \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}}}%
@@ -6472,10 +7702,10 @@
\ifwindows
\StrSubstitute{\minted@infile}{/}{\@backslashchar}[\minted@infile@windows]
\StrSubstitute{\minted@actualinfile}{/}{\@backslashchar}[\minted@actualinfile@windows]
- \ShellEscape{move /y
+ \ShellEscape{move /y
\minted@outputdir\minted@infile@windows\space\minted@outputdir\minted@actualinfile@windows}%
\else
- \ShellEscape{mv -f
+ \ShellEscape{mv -f
\minted@outputdir\minted@infile\space\minted@outputdir\minted@actualinfile}%
\fi
\let\minted@infile\minted@actualinfile
@@ -6507,38 +7737,793 @@
% 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
+ \minted@fvset% import options
\stepcounter{moodle@pygmentizecounter}
\xa\moodle@VerbatimInput\xa{\csname minted@infileHTML\the\c@moodle@pygmentizecounter\endcsname}%
}%
% \end{macrocode}
%
-% \subsection{Warning users of \texttt{babel}}
-% Users of the |babel| package loaded with the 'french' option may experience problems
-% related to autospacing when using |pdfLaTeX|. We shall warn them.
+% \subsection{Internationalization}
+% Here is an attempt to internationalize the PDF typesetting, relying on
+% the package 'translations'.
% \begin{macrocode}
-\AtBeginDocument{%
- \def\moodle@babel@german@warn{\PackageWarning{moodle}{Be careful when using moodle
- and German-related babel package options. The symbol " is made active and your umlauts
- will confuse moodle. You can either 1) compile with xelatex/lualatex with UTF-8 coded
- characters or 2) avoid the babel option.}
- }
- \@ifpackagewith{babel}{german}{\moodle@babel@german@warn}{\relax}%
- \@ifpackagewith{babel}{austrian}{\moodle@babel@german@warn}{\relax}%
- \@ifpackagewith{babel}{swissgerman}{\moodle@babel@german@warn}{\relax}%
- \@ifpackagewith{babel}{swissgerman.toss}{\moodle@babel@german@warn}{\relax}%
- \@ifpackagewith{babel}{ngerman}{\moodle@babel@german@warn}{\relax}%
- \@ifpackagewith{babel}{naustrian}{\moodle@babel@german@warn}{\relax}%
- \@ifpackagewith{babel}{nswissgerman}{\moodle@babel@german@warn}{\relax}%
- \@ifpackagewith{babel}{nswissgerman.toss}{\moodle@babel@german@warn}{\relax}%
- \ifPDFTeX % pdflatex or latex
- \@ifpackagewith{babel}{french}{%
- \PackageWarning{moodle}{Be careful when using LaTeX, moodle, and the babel package with option 'french'. Autospacing produces in undesired symbols in the XML. You can either 1) compile with xelatex/lualatex or 2) add '\NoAutoSpacing' after '\begin{quiz}'.}%
- }{\relax}%
+\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