diff options
author | Norbert Preining <norbert@preining.info> | 2023-01-29 03:01:53 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2023-01-29 03:01:53 +0000 |
commit | dab4e7c261c34234f9d9f1ac92923d6f903046ef (patch) | |
tree | 63b6eec067a9ff0bcd62088dd8b708ce880ece58 /macros/latex/contrib/moodle | |
parent | 261f52e7813eade06f278eda62023fda3d266980 (diff) |
CTAN sync 202301290301
Diffstat (limited to 'macros/latex/contrib/moodle')
-rw-r--r-- | macros/latex/contrib/moodle/README.md | 37 | ||||
-rw-r--r-- | macros/latex/contrib/moodle/moodle.dtx | 5715 | ||||
-rw-r--r-- | macros/latex/contrib/moodle/moodle.ins | 4 | ||||
-rw-r--r-- | macros/latex/contrib/moodle/moodle.pdf | bin | 260933 -> 369655 bytes |
4 files changed, 3877 insertions, 1879 deletions
diff --git a/macros/latex/contrib/moodle/README.md b/macros/latex/contrib/moodle/README.md index 30e1b4a976..f6d06f6f5f 100644 --- a/macros/latex/contrib/moodle/README.md +++ b/macros/latex/contrib/moodle/README.md @@ -10,11 +10,11 @@ part of all distributions of LaTeX version 2005/12/01 or later. Original contents (2016): [Anders O.F. Hendrickson](/author/hendrickson) ([contact](mailto:anders.o.f.hendricksonATgmail.com)) -2019-2021: [Matthieu Guerquin-Kern](/author/guerquin-kern) ([contact](mailto:guerquin-kernATcrans.org)) +2019-2023: [Matthieu Guerquin-Kern](/author/guerquin-kern) ([contact](mailto:guerquin-kernATcrans.org)) # Contents -This work, under version number 0.8, consists of the files +This work, under version number 1.0, consists of the files [`moodle.dtx`](/tex-archive/macros/latex/contrib/moodle/moodle.dtx), [`moodle.ins`](/tex-archive/macros/latex/contrib/moodle/moodle.ins), and the derived documentation file [`moodle.pdf`](/tex-archive/macros/latex/contrib/moodle/moodle.pdf). @@ -24,7 +24,7 @@ Details on how to generate derived files from the sources are given in Section " A TDS archive [moodle.tds.zip](http://mirrors.ctan.org/install/macros/latex/contrib/moodle.tds.zip) is also available to be conveniently expanded in your local texmf directory. -It contains the derived file `moodle.sty` and a set of test files. +It contains the derived files `moodle.sty`, `moodle.pdf` and a set of test files. # Requirements @@ -38,25 +38,35 @@ This package (`moodle.sty`) requires the following packages: - [`xpatch`](pkg/xpatch), - [`array`](pkg/array), - [`ifplatform`](/pkg/ifplatform), +- [`shellesc`](pkg/shellesc), +- [`readprov`](pkg/readprov), - [`fancybox`](pkg/fancybox), and - [`getitems`](pkg/getitems). -In order to manipulate images, the package relies on the following external tools: +The package option `handout` requires: +- [`randomlist`](pkg/randomlist). + +In order to manipulate images, the package relies on the following tools: +- [`graphics`](pkg/graphics), - [GhostScript](www.ghostscript.com), - [ImageMagick](www.imagemagick.org), and - [optipng](http://optipng.sourceforge.net/). -In addition, to compile the documentation, the following LaTeX packages are +Instead, to compile the documentation, the following LaTeX packages are necessary: - [`amssymb`](pkg/amssymb), -- [`metalogo`](pkg/metalogo), -- [`multirow`](pkg/multirow), -- [`threeparttable`](pkg/threeparttable), +- [`babel`](pkg/babel), - [`booktabs`](pkg/booktabs), +- [`changelog`](pkg/changelog), +- [`dtxdescribe`](pkg/dtxdescribe), +- [`eurosym`](pkg/eurosym), - [`hyperref`](pkg/hyperref), +- [`longtable`](pkg/longtable), +- [`minted`](pkg/minted), +- [`microtype`](pkg/microtype), - [`tikz`](pkg/tikz), -- [`minted`](pkg/minted), and -- [`microtype`](pkg/microtype). +- [`threeparttable`](pkg/threeparttable), and +- [`varioref`](pkg/varioref). # Building @@ -64,8 +74,11 @@ The file `moodle.sty` can be generated using the command ```bash latex moodle.ins ```` -The documentation file `moodle.pdf` can be generated by running twice the command +The documentation file `moodle.pdf` can be generated by running +successively the three commands: ```bash -lualatex -shell-escape moodle.dtx +lualatex -halt-on-error -shell-escape moodle.dtx +makeindex -s gglo.ist -o moodle.gls moodle.glo +lualatex -halt-on-error -shell-escape moodle.dtx ``` (n.b. the requirements in the previous section) 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 |<| and |>| \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 |–| \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 |<| +% and |>| 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 |–| \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&% - \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&% + \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 - \g@addto@macro\htmlize@output{\otherampersand nbsp;}% + % The ~ becomes non-breaking space outside of math mode + \moodle@ifmathmode{\g@addto@macro\htmlize@output{\@othertilde}}% + {\g@addto@macro\htmlize@output{\otherampersand nbsp;}}% \def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}% \else \ifx\test@i\@lsinglequote% @@ -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{\å}% \html@def\AA{\Å}% \html@def\ae{\æ}% \html@def\AE{\Æ}% -\html@def\oe{\œ}% -\html@def\OE{\Œ}% -\html@def\S{\§}% -\html@def\euro{\€}% -\html@def\texteuro{\€}% +\html@def\dh{\ð}% +\html@def\DH{\Ð}% +\html@def\dj{\đ}% +\html@def\DJ{\Đ}% +\html@def\i{\ı}% +\html@def\ij{\ij}% +\html@def\IJ{\IJ}% +\html@def\j{\ȷ}% +\html@def\l{\ł}% +\html@def\L{\Ł}% +\html@def\ng{\ŋ}% +\html@def\NG{\Ŋ}% \html@def\o{\ø}% \html@def\O{\Ø}% +\html@def\oe{\œ}% +\html@def\OE{\Œ}% \html@def\ss{\ß}% \html@def\SS{\&\#7838;}% -\html@def\l{\ł}% -\html@def\L{\Ł}% +\html@def\th{\þ}% +\html@def\TH{\Þ}% +% \end{macrocode} +% Fifth, \LaTeX\ commands for horizontal spacing and line breaks. +% In a number of situations, paragraph breaks translated into +% |</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{\␣}% +\html@def\newline{\HTMLtag{BR/}}% +\html@def\par{\HTMLtag{BR/}}% +% \end{macrocode} +% Sixth, \LaTeX\ commands for various symbols. +% \begin{macrocode} +\html@def\textbackslash{\&\#92;}% +\html@def\_{\&\#95;}% +\html@def\textquestiondown{\¿}% +\html@def\textexclamdown{\¡}% +\html@def\euro{\€}% +\html@def\texteuro{\€}% +\html@def\S{\§}% +% \end{macrocode} +% Seventh, \LaTeX\ commands for various quotation marks. +% \begin{macrocode} +\html@def\textquoteleft{\‘}% +\html@def\textquoteright{\’}% +\html@def\textquotedblleft{\“}% +\html@def\textquotedblright{\”}% +\html@def\guilsinglleft{\‹}% +\html@def\guilsinglright{\›}% +\html@def\guillemotleft{\«}% +\html@def\guillemotright{\»}% +\html@def\quotesinglbase{\‚}% +\html@def\quotedblbase{\„}% +\html@def\flq{\‹}% +\html@def\frq{\›}% +\html@def\flqq{\«}% +\html@def\frqq{\»}% \html@def\og{\«\&\#8239;}% -\html@def\guillemotleft{\«\&\#8239;}% \html@def\fg{\&\#8239;\»}% -\html@def\guillemotright{\&\#8239;\»}% -\html@def\glqq{\„}% -\html@def\grqq{\“}% \html@def\glq{\‚}% \html@def\grq{\‘}% -\html@def\flqq{\«\&\#8239;}% -\html@def\frqq{\&\#8239;\»}% -\html@def\flq{\‹}% -\html@def\frq{\›}% +\html@def\glqq{\„}% +\html@def\grqq{\“}% \html@def\dq{\"}% -\html@def\,{\&\#8239;}% -\html@def\thinspace{\&\#8239;}% -\html@def\textbackslash{\&\#92;}% -\html@def\_{\&\#95;}% -\html@def\textquestiondown{\¿}% -\html@def\textexclamdown{\¡}% - -% 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 diff --git a/macros/latex/contrib/moodle/moodle.ins b/macros/latex/contrib/moodle/moodle.ins index b118c1beab..9a367ff71d 100644 --- a/macros/latex/contrib/moodle/moodle.ins +++ b/macros/latex/contrib/moodle/moodle.ins @@ -26,8 +26,8 @@ This is a generated file. -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 diff --git a/macros/latex/contrib/moodle/moodle.pdf b/macros/latex/contrib/moodle/moodle.pdf Binary files differindex 47a4c2ecca..4c67dab223 100644 --- a/macros/latex/contrib/moodle/moodle.pdf +++ b/macros/latex/contrib/moodle/moodle.pdf |