summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/moodle/moodle.sty
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-02-08 21:58:24 +0000
committerKarl Berry <karl@freefriends.org>2021-02-08 21:58:24 +0000
commitb689b082c823fcce490e8231b4eff18837a5b2d3 (patch)
tree4c946e14963478600e21baf3a92b253dcb415e58 /Master/texmf-dist/tex/latex/moodle/moodle.sty
parent642941ac6911ff4f07f939e330eff1b4bf18e63a (diff)
moodle (8feb21)
git-svn-id: svn://tug.org/texlive/trunk@57683 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/moodle/moodle.sty')
-rw-r--r--Master/texmf-dist/tex/latex/moodle/moodle.sty460
1 files changed, 314 insertions, 146 deletions
diff --git a/Master/texmf-dist/tex/latex/moodle/moodle.sty b/Master/texmf-dist/tex/latex/moodle/moodle.sty
index 3061bd3299d..6a69f146152 100644
--- a/Master/texmf-dist/tex/latex/moodle/moodle.sty
+++ b/Master/texmf-dist/tex/latex/moodle/moodle.sty
@@ -21,7 +21,7 @@
%%
\NeedsTeXFormat{LaTeX2e}[1999/12/01]
\ProvidesPackage{moodle}
- [2021/01/04 v0.8 Moodle quiz XML generation]
+ [2021/02/07 v0.9 Moodle quiz XML generation]
\newif\ifmoodle@draftmode
\newif\ifmoodle@handout
\newif\ifmoodle@stampmode
@@ -58,12 +58,19 @@
\RequirePackage{environ} %To be able to take environment body as a macro argument
\RequirePackage{xkeyval} %For key-handling
\RequirePackage{amssymb} %For \checkmark symbol
-\RequirePackage{etex} %Expansion control, detokenization, etc.
+\@ifpackageloaded{iftex}{}{\RequirePackage{iftex}}
+\@ifundefined{ifeTeX}{% version of 'iftex' prior to November 2019.
+ \RequirePackage{etex}{}
+}{
+ \ifeTeX\else
+ \RequirePackage{etex}{} % Recent (2015+) TeX engines should be e-TeX.
+ %This is needed for expansion control, detokenization, etc.
+ \fi
+}
\RequirePackage{etoolbox}%List management
\RequirePackage{xpatch} %To patch commands easily in HTML mode
\RequirePackage{array} %For formatting tables in the LaTeX mode of Clozes
\RequirePackage{ifplatform} % To choose Ghostscript commands
-\@ifpackageloaded{iftex}{}{\RequirePackage{iftex}}
\@ifundefined{ifpdf}{\RequirePackage{ifpdf}}{}% old iftex would not define the conditional
\RequirePackage{shellesc} %Luatex-compatible way of getting system access
\RequirePackage{fancybox} %For fancy LaTeX tags
@@ -152,7 +159,7 @@
\fi
\writetomoodle{<!-- \moodle@stamp -->}%
\def\moodle@stamp{running on \platformname}%
- \g@addto@macro{\moodle@stamp}{ with the package moodle v0.8 }%
+ \g@addto@macro{\moodle@stamp}{ with the package moodle v0.9 }%
\writetomoodle{<!-- \moodle@stamp -->}%
\fi
\immediate\write\moodle@outfile{}%
@@ -200,13 +207,14 @@
}{}%
}}%
\newcommand*\@enumeratename{enumerate}%
+\newdimen\moodle@totalmarks \moodle@totalmarks=0pt%
\newenvironment{quiz}[2][]{%
\setkeys{moodle}{#1}%
\gdef\setcategory##1{%
% At first call (end of \begin{quiz}) enumerate is not started yet
\ifx\@currenvir\@enumeratename
% In case no question is defined between two calls of \setcategory
- \def\@noitemerr{\@latex@warning{Empty question list}}%
+ \def\@noitemerr{}%\@latex@warning{Empty question list}
\end{enumerate}%
\fi
\gdef\moodle@currentcategory{##1}%
@@ -227,7 +235,7 @@
\begin{enumerate}%
}%
\gdef\setsubcategory##1{%
- \def\@noitemerr{\@latex@warning{Empty question list}}%
+ \def\@noitemerr{}%\@latex@warning{Empty question list}
\end{enumerate}%
\moodle@write@category@xml{\moodle@currentcategory/##1}%
\ifmoodle@section
@@ -248,6 +256,7 @@
\setcategory{#2}%
}{%
\end{enumerate}%
+ \emph{Total of marks: \strip@pt\moodle@totalmarks}%
\let\setcategory\relax
\let\setsubcategory\relax
}%
@@ -327,21 +336,29 @@
}%
}%
-\def\generate@moodle@write@tags#1{%
- % #1 = NAME for \moodle@writeNAME
- % #3 = what, exactly, to write
- \xa\gdef\csname moodle@writetags\endcsname{%
- %\xa\xa\xdef\xa\xa\ds\xa\xa{Encountered '\string #1'}\show\ds
- \xa\xdef\xa\test@iii\xa{\moodle@tags}%
- \ifx\test@iii\@moodle@empty\relax\else
- \xa\converttohtmlmacro\xa\moodle@htmltowrite\xa{\moodle@tags}%
- \writetomoodle[2]{ <tags>}%
+\def\moodle@writetags{%
+ \xa\xdef\xa\test@iii\xa{\moodle@tags}%
+ \ifx\test@iii\@moodle@empty\relax\else
+ \writetomoodle[2]{ <tags>}%
+ \renewcommand*{\do}[1]{%
+ \def\moodle@tagtext{##1}%
+ \xa\converttohtmlmacro\xa\moodle@htmltowrite\xa{\moodle@tagtext}%
\writetomoodle[4]{ <tag><text><![CDATA[\moodle@htmltowrite]]></text></tag>}%
- \writetomoodle[2]{ </tags>}%
- \fi
- }%
+ }
+ \xa\docsvlist\xa{\moodle@tags}%
+ \writetomoodle[2]{ </tags>}%
+ \fi
+}%
+\newif\ifmoodle@firsttag
+\moodle@firsttagtrue
+\def\moodle@latex@writetags{%
+ \xa\xdef\xa\test@iii\xa{\moodle@tags}%
+ \ifx\test@iii\@moodle@empty\relax\else
+ \hfill tags: %
+ \renewcommand*{\do}[1]{\ifmoodle@firsttag\moodle@firsttagfalse\else, \fi\texttt{##1}}%
+ \xa\docsvlist\xa{\test@iii}%
+ \fi
}%
-
%% QUESTIONNAME
\define@cmdkey{moodle}[moodle@]{questionname}{}%
\generate@moodle@write@html@noptag{questionname}<name>{\moodle@questionname}%
@@ -407,8 +424,7 @@
%which defines a "tag" (i.e., keyword) for the question.
%Key calls like [tags={random}] set \moodle@tags.
\define@cmdkey{moodle}[moodle@]{tags}[]{}%
- \generate@moodle@write@tags{\csname moodle@tags\endcsname}%
- \moodleset{tags}%
+ \moodleset{tags={}}%
%% FRACTION -- how much this answer is worth out of 100 percent
\define@cmdkey{moodle}[moodle@]{fraction}[100]{}%
@@ -431,6 +447,10 @@
\generate@moodle@write@code*{shuffle}<shuffleanswers>{\ifmoodle@shuffle 1\else 0\fi}%
\moodleset{shuffle=true}%
+%% ALLORNOTHING -- for multichoice with multiple answers where all the points are given
+ \define@boolkey{moodle}[moodle@]{allornothing}[true]{}%
+ \moodleset{allornothing=false}%
+
%% TODO: CORRECTFEEDBACK
%% TODO: PARTIALLYCORRECTFEEDBACK
%% TODO: INCORRECTFEEDBACK
@@ -679,6 +699,7 @@
\NewEnviron{#1}[2][]{%
\bgroup
\setkeys{moodle}{##1,questionname={##2}}%
+ \global\advance\moodle@totalmarks by \csname moodle@default grade\endcsname pt
\expandafter\gatheritems\xa{\BODY}%
\let\moodle@questionheader=\gatheredheader
%First, the LaTeX processing
@@ -686,10 +707,7 @@
\ifmoodle@handout
\moodle@makelatextag@qtype{#1}
\else
- \xa\xdef\xa\test@iii\xa{\moodle@tags}%
- \ifx\test@iii\@moodle@empty\relax\else
- \hfill tags: \texttt{\moodle@tags}
- \fi
+ \moodle@latex@writetags
\par
\noindent
\moodle@makelatextag@qtype{#1}
@@ -718,47 +736,46 @@
\egroup
}%
}
-\let\description\relax% remove the meaning of existing \description and \enddescription
-\let\enddescription\relax
-\NewEnviron{description}[2][]{%
- \bgroup
- \setkeys{moodle}{#1,questionname={#2}}%
- \let\moodle@questiontext=\BODY
- \trim@spaces@in\moodle@questiontext
- \ifx\moodle@questiontext\@empty\relax\else%
- %First, the LaTeX processing.
- \item \textbf{\moodle@questionname}
- \ifmoodle@handout\else
- \xa\xdef\xa\test@iii\xa{\moodle@tags}%
- \ifx\test@iii\@moodle@empty\relax\else
- \hfill tags: \texttt{\moodle@tags}%
+\AfterEndPreamble{% in case something like \usepackage[french]{babel} is loaded
+ \let\description\relax% remove the meaning of existing \description and \enddescription
+ \let\enddescription\relax
+
+ \NewEnviron{description}[2][]{%
+ \bgroup
+ \setkeys{moodle}{#1,questionname={#2}}%
+ \let\moodle@questiontext=\BODY
+ \trim@spaces@in\moodle@questiontext
+ \ifx\moodle@questiontext\@empty\relax\else%
+ %First, the LaTeX processing.
+ \item \textbf{\moodle@questionname}
+ \ifmoodle@handout\else
+ \moodle@latex@writetags
+ \par
+ \noindent
\fi
- \par
+ \moodle@makelatextag@qtype{description}\par
\noindent
- \fi
- \moodle@makelatextag@qtype{description}\par
- \noindent
- \moodle@questiontext\par
- \ifmoodle@handout\else
- \ifx\moodle@feedback\@empty\relax\else
- \fbox{\parbox{\linewidth}{\emph{\moodle@feedback}}}%
+ \moodle@questiontext\par
+ \ifmoodle@handout\else
+ \ifx\moodle@feedback\@empty\relax\else
+ \fbox{\parbox{\linewidth}{\emph{\moodle@feedback}}}%
+ \fi
\fi
+ %Now, writing information to memory.
+ \@moodle@ifgeneratexml{%
+ \writetomoodle{<question type="description">}%
+ \moodle@writecommondata
+ \moodle@writetags%
+ \writetomoodle{</question>}%
+ }{}%
\fi
- %Now, writing information to memory.
- \@moodle@ifgeneratexml{%
- \writetomoodle{<question type="description">}%
- \moodle@writecommondata
- \moodle@writetags%
- \writetomoodle{</question>}%
- }{}%
- \fi
- \egroup
+ \egroup
+ }%
}%
\def\moodle@essay@latexprocessing{%
% Moodle cannot automatically grade an essay,
% but if the user puts \item's in, we can list them in an itemize as notes.
\par\noindent \emph{Notes for grader:}
- \moodle@questionheader
\ifnum\c@numgathereditems>0\relax
\begin{itemize} \setlength\itemsep{0pt}\setlength\parskip{0pt}%
\loopthroughitemswithcommand{\moodle@print@essay@answer}%
@@ -772,6 +789,8 @@
\NewEnviron{essay}[2][]{%
\bgroup
\setkeys{moodle}{#1,questionname={#2}}%
+ \global\advance\moodle@totalmarks by \csname moodle@default grade\endcsname pt
+ \moodle@checkresponsefieldlines
\expandafter\gatheritems\expandafter{\BODY}%
\let\moodle@questionheader=\gatheredheader
%First, the LaTeX processing.
@@ -779,10 +798,7 @@
\ifmoodle@handout
\moodle@makelatextag@qtype{essay}
\else
- \xa\xdef\xa\test@iii\xa{\moodle@tags}%
- \ifx\test@iii\@moodle@empty\relax\else
- \hfill tags: \texttt{\moodle@tags}
- \fi
+ \moodle@latex@writetags
\par
\noindent
\moodle@makelatextag@qtype{essay}
@@ -792,7 +808,9 @@
\fi
\par
\noindent
- \ifx\moodle@responsetemplate\@empty\relax\else%
+ \moodle@questionheader
+ \long\def\@lempty{}%
+ \ifx\moodle@responsetemplate\@lempty\else
\par\noindent \emph{Template:}
\par\fbox{\parbox{\linewidth}{\moodle@responsetemplate}}\par
\fi
@@ -831,6 +849,31 @@
\egroup
}%
+\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
+ \a=40%
+ \fi
+ \ifnum\the\a<5% 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
+ \else
+ \ifnum\csname moodle@response field lines\endcsname>5%
+ \ifnum\csname moodle@response field lines\endcsname<40%
+ \advance\a by\b% approximate with the next multiple of 5
+ \fi
+ \fi
+ \PackageWarning{moodle}{"response field lines" admits only multiples of 5 between 5 and 40
+ (You tried to set \csname moodle@response field lines\endcsname). The value
+ \the\a\space will be used.}%
+ \setkeys{moodle}{response field lines=\the\a}%
+ \fi
+}%
+
%%%% TODO
%%%% To make essay work will be tough.
%%%% Every line from \ifnum\c@numgathereditems=0\relax through its \else and \fi,
@@ -875,11 +918,11 @@
\moodle@writeattachmentsrequired%
}%
-\def\moodle@print@essay@answer#1{%
+\long\def\moodle@print@essay@answer#1{%
\item #1%
}%
-\def\moodle@savegraderinfo#1{%
+\long\def\moodle@savegraderinfo#1{%
%\def\ds{#1}\show\ds
\bgroup
\moodle@savegraderinfo@int#1\moodle@answer@rdelim
@@ -890,7 +933,7 @@
\setkeys{moodle}{fraction=0,#1}%
\moodle@savegraderinfo@int@int%
}%
-\def\moodle@savegraderinfo@int@int#1\moodle@answer@rdelim{%
+\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
@@ -962,7 +1005,8 @@
\trim@spaces@in\moodle@answertext
\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>}%
+ \xa\converttohtmlmacro\xa\moodle@answertext@html\xa{\moodle@answertext}%
+ \addto@xml[4]{\moodle@answers@xml}{ <text>\moodle@answertext@html</text>}%
\ifx\moodle@feedback\@empty\relax\else
\trim@spaces@in\moodle@feedback
\xa\converttohtmlmacro\xa\moodle@feedback@html\xa{\moodle@feedback}%
@@ -1065,10 +1109,19 @@
\def\moodle@makelatextag@multi{%
- \ifmoodle@multiple
- \moodle@makelatextagbox{Multiple}\relax%
+ \ifmoodle@allornothing
+ \ifx\endmulti\endclozemulti
+ \PackageError{moodle}{Unsupported option "allornothing" for a multichoice subquestion}
+ {Please set "allornothing=false"}%
+ \else
+ \moodle@makelatextagbox{All-or-nothing}%
+ \fi
\else
- \moodle@makelatextagbox{Single}\relax%
+ \ifmoodle@multiple
+ \moodle@makelatextagbox{Multiple}%
+ \else
+ \moodle@makelatextagbox{Single}%
+ \fi
\fi
\ifmoodle@handout\else
\ifmoodle@shuffle
@@ -1078,6 +1131,9 @@
}
\def\moodle@multi@latexprocessing{%
+ \ifmoodle@allornothing
+ \moodle@singletrue
+ \fi
\moodle@countcorrectanswers%
\ifmoodle@handout\NewList{answerlist}\fi
\begin{enumerate}\moodle@obeynumberingstyle%
@@ -1099,7 +1155,7 @@
\fi
\fi
}
- \def\moodle@print@multichoice@answer#1{%
+ \long\def\moodle@print@multichoice@answer#1{%
\let\moodle@feedback=\@empty%
\moodle@print@multichoice@answer@int#1 \@rdelim%
}%
@@ -1108,7 +1164,7 @@
\setkeys{moodle}{#1}%
\moodle@print@multichoice@answer@int@int%
}%
- \def\moodle@print@multichoice@answer@int@int#1#2\@rdelim{%
+ \long\def\moodle@print@multichoice@answer@int@int#1#2\@rdelim{%
\def\test@i{#1}%
\def\test@ii{#2}%
\def\moodle@answertext{\item }%
@@ -1129,11 +1185,11 @@
\ifx\moodle@fraction\@empty\relax%
\setkeys{moodle}{fraction=0}%
\fi
+ \moodle@checkfraction
\ifx\moodle@fraction\@hundred%
\trim@spaces@in\moodle@answertext%
\g@addto@macro\moodle@answertext{$~\checkmark$}%
\else
- \moodle@checkfraction
\ifdim0pt=\moodle@fraction pt\relax\else%
\g@addto@macro\moodle@answertext{$~(\moodle@fraction\%)$}%
\fi
@@ -1209,7 +1265,7 @@
\fi
\gdef\moodle@autosanctions{\strip@pt\moodle@pointsperincorrect}%
}
- \def\moodle@countcorrectanswers@a#1{%
+ \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
@@ -1222,7 +1278,7 @@
\moodle@countcorrectanswers@c%
%\fi
}%
- \def\moodle@countcorrectanswers@c#1#2\moodle@answer@rdelim{%
+ \long\def\moodle@countcorrectanswers@c#1#2\moodle@answer@rdelim{%
\def\test@i{#1}%
\ifx\test@i\@star
\stepcounter{moodle@numcorrectanswers}%
@@ -1258,7 +1314,15 @@
\fi
\fi
}
- \def\moodle@checkfraction{%
+ \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
@@ -1276,9 +1340,10 @@
\else
\setkeys{moodle}{fraction=\test@fractionmatched}%
\fi
- }
+ \fi
+ }
-\def\savemultianswer#1{%
+\long\def\savemultianswer#1{%
\bgroup
\savemultianswer@int#1 \moodle@answer@rdelim
\passvalueaftergroup{\moodle@answers@xml}%
@@ -1287,9 +1352,12 @@
\newcommand\savemultianswer@int[1][]{%
\let\moodle@fraction\@empty%
\setkeys{moodle}{#1}%
+ \ifmoodle@allornothing
+ \moodle@singletrue
+ \fi
\savemultianswer@int@int%
}%
- \def\savemultianswer@int@int#1#2\moodle@answer@rdelim{%
+ \long\def\savemultianswer@int@int#1#2\moodle@answer@rdelim{%
\def\test@i{#1}%
\ifx\test@i\@star
\ifmoodle@single
@@ -1323,9 +1391,12 @@
}%
\gdef\writemultiquestion{%
- \writetomoodle{<question type="multichoice">}%
+
+ \writetomoodle{<question type="multichoice\ifmoodle@allornothing set\fi">}%
\moodle@writecommondata%
- \moodle@writesingle%
+ \ifmoodle@allornothing\else
+ \moodle@writesingle%
+ \fi
\moodle@writeshuffle%
\moodle@writeanswernumbering%
}%
@@ -1334,6 +1405,7 @@
\NewEnviron{truefalse}[2][]{%
\bgroup
\setkeys{moodle}{#1,questionname={#2}}%
+ \global\advance\moodle@totalmarks by \csname moodle@default grade\endcsname pt
\expandafter\gatheritems\xa{\BODY}%
\let\moodle@questionheader=\gatheredheader
%First, the LaTeX processing
@@ -1341,10 +1413,7 @@
\ifmoodle@handout
\moodle@makelatextag@qtype{truefalse}
\else
- \xa\xdef\xa\test@iii\xa{\moodle@tags}%
- \ifx\test@iii\@moodle@empty\relax\else
- \hfill tags: \texttt{\moodle@tags}
- \fi
+ \moodle@latex@writetags
\par
\noindent
\moodle@makelatextag@qtype{truefalse}
@@ -1572,10 +1641,10 @@
\setcounter{moodle@numcorrectanswers}{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}
+ \PackageWarning{moodle}{Moodle expects at least three "answers" with matching type}%
\fi
\ifnum\c@moodle@numcorrectanswers<2%
- \PackageWarning{moodle}{Moodle expects at least two "questions" with the matching type}
+ \PackageWarning{moodle}{Moodle expects at least two "questions" with the matching type}%
\fi
\ifmoodle@handout
\ifmoodle@shuffle
@@ -1690,14 +1759,10 @@
\ifmoodle@handout
\moodle@makelatextag@qtype{cloze}
\else
- \xa\xdef\xa\test@iii\xa{\moodle@tags}%
- \ifx\test@iii\@moodle@empty\relax\else
- \hfill tags: \texttt{\moodle@tags}
- \fi
+ \moodle@latex@writetags
\par
\noindent
\moodle@makelatextag@qtype{cloze}
- \moodle@makelatextag@value{default grade}{\moodle@marks{\csname moodle@default grade\endcsname}}
\moodle@makelatextag@value{penalty}{penalty}
\fi
\par
@@ -1729,7 +1794,11 @@
\gdef\writeclozequestion{%
\writetomoodle{<question type="cloze">}%
- \moodle@writecommondata%
+ \moodle@writequestionname%
+ \moodle@writequestiontext%
+ \moodle@writegeneralfeedback%
+ \moodle@writepenalty%
+ \moodle@writehidden%
\moodle@writetags%
\writetomoodle{</question>}%
}%
@@ -1785,6 +1854,7 @@
\def\endclozemulti@code{\htmlize@patchendenvironment}%
\else
%LaTeX version
+ \global\advance\moodle@totalmarks by \csname moodle@default grade\endcsname pt
\moodle@questionheader% %Any introductory text just continues to be typeset.
\par
\noindent
@@ -1837,7 +1907,7 @@
\egroup%
}[\endclozemulti@code]%
-\def\moodle@print@clozemultichoice@answer#1{%
+\long\def\moodle@print@clozemultichoice@answer#1{%
\let\moodle@feedback=\@empty
\moodle@print@clozemultichoice@answer@int#1 \@rdelim%
}%
@@ -1845,7 +1915,7 @@
\setkeys{moodle}{fraction=0,#1}%
\moodle@print@clozemultichoice@answer@int@int%
}%
-\def\moodle@print@clozemultichoice@answer@int@int#1#2\@rdelim{%
+\long\def\moodle@print@clozemultichoice@answer@int@int#1#2\@rdelim{%
\def\moodle@answertext{}%
% Case 0: "(answer) \\ \hline"
% Case 1: "\item (answer)"
@@ -1904,7 +1974,7 @@
\fi
}%
-\def\saveclozemultichoiceanswer#1{%
+\long\def\saveclozemultichoiceanswer#1{%
\bgroup
\saveclozemultichoiceanswer@int#1 \moodle@answer@rdelim
\egroup
@@ -1913,7 +1983,7 @@
\setkeys{moodle}{fraction=0,#1}%
\saveclozemultichoiceanswer@int@int%
}%
-\def\saveclozemultichoiceanswer@int@int#1#2\moodle@answer@rdelim{%
+\long\def\saveclozemultichoiceanswer@int@int#1#2\moodle@answer@rdelim{%
\def\test@i{#1}%
\ifgatherbeginningofloop\else
\xa\gdef\xa\clozemulti@coding\xa{\clozemulti@coding\clozetilde}% separator between answers
@@ -1961,6 +2031,7 @@
\def\endclozenumerical@code{\htmlize@patchendenvironment}%
\else
%LaTeX version
+ \global\advance\moodle@totalmarks by \csname moodle@default grade\endcsname pt
\moodle@questionheader% %Any introductory text just continues to be typeset.
\par
\noindent
@@ -2082,6 +2153,7 @@
\def\endclozeshortanswer@code{\htmlize@patchendenvironment}%
\else
%LaTeX version
+ \global\advance\moodle@totalmarks by \csname moodle@default grade\endcsname pt
\moodle@questionheader% %Any introductory text just continues to be typeset.
\par
\noindent
@@ -2298,6 +2370,7 @@
\def\@lt{<}%
\def\@gt{>}%
+\def\@dash{-}%
\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).
@@ -2506,11 +2579,12 @@
\fi% \ifx\test@ii\@lsinglequote%
\else
\ifx\test@i\@rsinglequote%
- \ifx\test@ii\@rsinglequote%
- %Double right quote
- \g@addto@macro\htmlize@output{\otherampersand rdquo;}%
+ \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;}}%
+ {\g@addto@macro\htmlize@output{\otherampersand rdquo;}}%
\def\htmlize@next@i{\htmlize@recursive@i#3\htmlize@rdelim@i}%
- \else
+ \else% Single right quote
\g@addto@macro\htmlize@output{\otherampersand rsquo;}%
\def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}%
\fi% \ifx\test@ii\@rsinglequote%
@@ -2529,9 +2603,20 @@
{\g@addto@macro\htmlize@output{>}}%
\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}%
+ \ifx\test@i\@dash
+ \ifx\test@ii\@dash% en-dash (--)
+ \moodle@ifmathmode{\g@addto@macro\htmlize@output{--}}%
+ {\g@addto@macro\htmlize@output{\otherampersand ndash;}}%
+ \def\htmlize@next@i{\htmlize@recursive@i#3\htmlize@rdelim@i}%
+ \else
+ \g@addto@macro\htmlize@output{-}%
+ \def\htmlize@next@i{\htmlize@recursive@i#2#3\htmlize@rdelim@i}%
+ \fi
+ \else
+ % 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\@dash
\fi% \ifx\test@i\@gt
\fi% \ifx\test@i\@lt
\fi% \ifx\test@i\@doublequote
@@ -2785,6 +2870,7 @@
\htmlize@record@action{\endclozemode}%
\htmlize@record@action{\relax}%
+\html@action@def\%{\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}}%
@@ -2829,6 +2915,9 @@
\html@action@def\${%
\g@addto@macro\htmlize@output{\otherdollar}%
}%
+\html@action@def\@dquote{%
+ \g@addto@macro\htmlize@output{"}%
+ }%
\html@action@def\clozetilde{%
\xa\g@addto@macro\xa\htmlize@output\xa{\othertilde}%
}%
@@ -2989,20 +3078,42 @@
{\g@addto@macro\htmlize@output{\otherampersand#1caron\othersemicol}}%
{\xa\g@addto@macro\htmlize@output\xa{\string\v#1}}%
}%
-\html@def\underline#1{<SPAN STYLE=\&\#34;text-decoration: underline;\&\#34;>#1</SPAN>}
+
+{\catcode`|=3\relax
+ \gdef\htmlize@ogonek{A|E|I|U|a|e|i|u|}}
+\html@action@def\k#1{%
+ \ifinlist{#1}{\htmlize@ogonek}%
+ {\g@addto@macro\htmlize@output{\otherampersand#1ogon\othersemicol}}%
+ {
+ \bgroup
+ \def\test@i{#1}%
+ \ifx\test@i\@O
+ \def\toadd{\otherampersand\otherhash490\othersemicol}%
+ \else
+ \ifx\test@i\@o
+ \def\toadd{\otherampersand\otherhash491\othersemicol}%
+ \else
+ \def\toadd{\otherbackslash\otherlbrace#1\otherrbrace}%
+ \fi
+ \fi
+ \xa\g@addto@macro\xa\htmlize@output\xa{\toadd}%
+ \egroup
+ }%
+}%
+\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=\&\#34;font-variant: small-caps;\&\#34;>#1</SPAN>}
-\html@def\url#1{<A href=\&\#34;#1\&\#34;>#1</A>}%
-\html@def\href#1#2{<A href=\&\#34;#1\&\#34;>#2</A>}%
+\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>}%
\html@def\blank{____________}%
-\html@def\par{</P><P>}%
+\html@def\par{<BR/>}%
\html@def\aa{\&aring;}%
\html@def\AA{\&Aring;}%
\html@def\ae{\&aelig;}%
@@ -3022,6 +3133,15 @@
\html@def\guillemotleft{\&laquo;\&\#8239;}%
\html@def\fg{\&\#8239;\&raquo;}%
\html@def\guillemotright{\&\#8239;\&raquo;}%
+\html@def\glqq{\&bdquo;}%
+\html@def\grqq{\&ldquo;}%
+\html@def\glq{\&sbquo;}%
+\html@def\grq{\&lsquo;}%
+\html@def\flqq{\&laquo;\&\#8239;}%
+\html@def\frqq{\&\#8239;\&raquo;}%
+\html@def\flq{\&lsaquo;}%
+\html@def\frq{\&rsaquo;}%
+\html@def\dq{\&quot;}%
\html@def\,{\&\#8239;}%
\html@def\thinspace{\&\#8239;}%
\html@def\textbackslash{\&\#92;}%
@@ -3033,6 +3153,18 @@
\htmlize@record@action\inlinemathrightdelim
\htmlize@record@action\displaymathrightdelim
+\newcommand\htmlonly[2][]{#1}%
+\html@action@newcommand{htmlonly}[2][]{%
+ \g@addto@macro\htmlize@output{#2}%
+}%
+\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.}%
+ }%
+ }{}%
+}%
\def\moodle@media@find#1{%
\ifx\detokenize\@undefined\else
\edef\Gin@extensions{\detokenize\expandafter{\Gin@extensions}}%
@@ -3184,7 +3316,10 @@
}%
}%
\DeclareGraphicsAlien{.gif}{.png}{\htmlize@imagemagick@convert\otherspace '\SourceFile[0]' \OutputFile}%
- }{}%
+ }{
+ \newcommand\includegraphics[2][]{\PackageError{moodle}{"\string\includegraphics" is not defined}%
+ {Add "\string\usepackage{graphicx}" to you preamble.}}{}%}%
+ }%
}%
\define@cmdkeys{moodle@includegraphics}[moodle@graphics@]{ppi}
\define@cmdkey{moodle}[moodle@graphics@]{ppi}{}% This is so the ppi key can be set at the document, quiz, or question level.
@@ -3216,25 +3351,30 @@
\SVGtoPDF\otherspace '\SourceFile' -o '\OutputFile' 2>/dev/null}%
}%
\fi
-
-\ifmoodle@tikz
-\AfterEndPreamble{%
- %\htmlize@record@expand{\embedaspict}%
- \let\oldincludegraphics=\includegraphics
- % patching includegraphics to trigger externalization
- \renewcommand{\includegraphics}[2][]{%
- %\message{moodle.sty: Processing \string\includegraphics[#1]{#2} for HTML^^J}%
- \tikz{\node[inner sep=0pt]{\oldincludegraphics[#1]{#2}};}%
- }%
- % externalized images must be included with the regular command
- \pgfkeys{/pgf/images/include external/.code={\oldincludegraphics{#1}}}%
- \html@action@newcommand{includegraphics}[2][]{%
- \message{moodle.sty: Processing \string\includegraphics[#1]{#2} ^^J}
- \global\advance\numpicturesread by 1\relax
- \edef\htmlize@imagetag{<IMG SRC="data:\TikzExportMIME;base64,\csname picbaselxiv@\the\numpicturesread\endcsname">}%
- \xa\g@addto@macro\xa\htmlize@output\xa{\htmlize@imagetag}%
+\def\moodle@checkconversionsuccess#1#2{%
+ \IfFileExists{#1}{}{%
+ \PackageError{moodle}{#2 failed}%
+ {If the XML file is not of importance to you: use package option "draft"}%
}%
}%
+\ifmoodle@tikz
+ \AfterEndPreamble{%
+ %\htmlize@record@expand{\embedaspict}%
+ \let\oldincludegraphics=\includegraphics
+ % patching includegraphics to trigger externalization
+ \renewcommand{\includegraphics}[2][]{%
+ %\message{moodle.sty: Processing \string\includegraphics[#1]{#2} for HTML^^J}%
+ \tikz{\node[inner sep=0pt]{\oldincludegraphics[#1]{#2}};}%
+ }%
+ % externalized images must be included with the regular command
+ \pgfkeys{/pgf/images/include external/.code={\oldincludegraphics{#1}}}%
+ \html@action@newcommand{includegraphics}[2][]{%
+ \message{moodle.sty: Processing \string\includegraphics[#1]{#2} ^^J}
+ \global\advance\numpicturesread by 1\relax
+ \edef\htmlize@imagetag{<IMG SRC="data:\TikzExportMIME;base64,\csname picbaselxiv@\the\numpicturesread\endcsname">}%
+ \xa\g@addto@macro\xa\htmlize@output\xa{\htmlize@imagetag}%
+ }%
+ }%
\else
\html@action@newcommand{includegraphics}[2][]{%
\bgroup% The grouping is to localize the changes caused by \setkeys.
@@ -3284,6 +3424,7 @@
\edef\cmdline{\PDFtoSVG\otherspace "\moodle@media@base\moodle@media@ext" -o "\moodle@media@base\moodle@media@ext@current" 2>/dev/null}%
\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" >
@@ -3291,6 +3432,7 @@
"\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}%
@@ -3298,10 +3440,12 @@
\edef\cmdline{\htmlize@imagemagick@convert\otherspace "\moodle@media@base\moodle@media@ext" -resize \moodle@graphics@geometry\otherspace "\moodle@media@base\moodle@media@ext@current"}%
\message{moodle.sty: Converting '#2' to PNG...^^J}%
\xa\ShellEscape\xa{\cmdline}%
+ \moodle@checkconversionsuccess{\moodle@media@base\moodle@media@ext@current}{ImageMagick conversion}%
%Next, optimize inline
\edef\cmdline{\optipng\otherspace "\moodle@media@base\moodle@media@ext@current"}%
\message{moodle.sty: Optimizing '\moodle@media@base\moodle@media@ext@current'...^^J}%
\xa\ShellEscape\xa{\cmdline}%
+ \moodle@checkconversionsuccess{\moodle@media@base\moodle@media@ext@current}{PNG optimization}%
\fi
\fi
%Next, convert the file to base64 encoding
@@ -3325,27 +3469,25 @@
\egroup
}%
\fi
+\def\ConvertToBaseLXIV#1#2{%
+ \message{moodle.sty: Converting '#1#2' to base64...^^J}%
+ \ConvertToBaseLXIV@int{#1}{#2}
+ \xa\ShellEscape\xa{\cmdline}%
+ \moodle@checkconversionsuccess{#1.enc}{Base64 conversion}%
+}%
\ifwindows
- \def\ConvertToBaseLXIV#1#2{%
- \def\cmdline{\baselxiv\otherspace -encode "#1#2"\otherspace tmp.b64 && findstr /vbc:"---" tmp.b64 > "#1" && del tmp.b64"}%
- \message{moodle.sty: Converting '#1#2' to base64...^^J}%
- \xa\ShellEscape\xa{\cmdline}%
- % Starting from Windows 7, CertUtil is included by default. There should be no windows XP still running
- }%
+ \def\ConvertToBaseLXIV@int#1#2{%
+ \def\cmdline{\baselxiv\otherspace -encode "#1#2"\otherspace tmp.b64 && findstr /vbc:"---" tmp.b64 > "#1.enc" && del tmp.b64}%
+ }% Starting from Windows 7, CertUtil is included by default. There should be no windows XP still running
\else
\ifmacosx
- \def\ConvertToBaseLXIV#1#2{%
+ \def\ConvertToBaseLXIV@int#1#2{%
\def\cmdline{\baselxiv\otherspace -b 64 -i "#1#2"\otherspace -o "#1.enc"}%
- \message{moodle.sty: Converting '#1#2' to base64...^^J}%
- \xa\ShellEscape\xa{\cmdline}%
}%
\else % Linux, Cygwin
- \def\ConvertToBaseLXIV#1#2{%
+ \def\ConvertToBaseLXIV@int#1#2{%
\def\cmdline{\baselxiv\otherspace "#1#2"\otherspace > "#1.enc"}%
- \message{moodle.sty: Converting '#1#2' to base64...^^J}%
- \xa\ShellEscape\xa{\cmdline}%
- }%
- % base64 is part of coreutils, add "-w 64" to get exactly the previous behavior %
+ }% base64 is part of coreutils, add "-w 64" to get exactly the previous behavior %
\fi
\fi
\newread\baseLXIVdatafile
@@ -3385,32 +3527,44 @@
\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}%
- \xa\ShellEscape\xa{\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}}%
+ \xa\ShellEscape\xa{\cmdline}%
+ \moodle@checkconversionsuccess{\moodle@basename\TikzExportExtension}{PStoSVG conversion}%
+ }%
\fi
\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\TikzExportExtension" }%
- \xa\ShellEscape\xa{\cmdline}}%
+ \xa\ShellEscape\xa{\cmdline}%
+ \moodle@checkconversionsuccess{\moodle@basename\TikzExportExtension}{SVG optimization}%
+ }%
\else
\def\TikzExportExtension{.png}%
\def\TikzExportMIME{image/png}%
\ifpdfoutput% tex engines defaulting to PDF output (pdflatex, xelatex, lualatex)
\def\ExportTikz{ \message{moodle.sty: Converting picture '\moodle@basename.pdf' to PNG...^^J}%
\edef\gscmdline{\gs\otherspace -sOutputFile=\moodle@basename\TikzExportExtension\otherspace -r150 \moodle@basename.pdf}%
- \xa\ShellEscape\xa{\gscmdline}}%
+ \xa\ShellEscape\xa{\gscmdline}%
+ \moodle@checkconversionsuccess{\moodle@basename\TikzExportExtension}{Ghostscript conversion}%
+ }%
\else % latex
\def\ExportTikz{ \message{moodle.sty: Converting picture '\moodle@basename.ps' to PNG...^^J}%
\edef\gscmdline{\gs\otherspace -sOutputFile=\moodle@basename\TikzExportExtension\otherspace -r150 \\moodle@basename.ps}%
- \xa\ShellEscape\xa{\gscmdline}}%
+ \xa\ShellEscape\xa{\gscmdline}%
+ \moodle@checkconversionsuccess{\moodle@basename\TikzExportExtension}{Ghostscript conversion}%
+ }%
\fi
\def\OptimizeExport{ \message{moodle.sty: Optimizing '\moodle@basename.png'...^^J}%
\edef\cmdline{\optipng\otherspace \moodle@basename\TikzExportExtension}%
- \xa\ShellEscape\xa{\cmdline}}%
+ \xa\ShellEscape\xa{\cmdline}%
+ \moodle@checkconversionsuccess{\moodle@basename\TikzExportExtension}{PNG optimization}%
+ }%
\fi
\let\moodle@oldtikzpicture=\tikzpicture
%The following code lets us run things *before* the normal \begin{tikzpicture}.
@@ -3432,6 +3586,7 @@
\ExportTikz
\OptimizeExport
\ConvertToBaseLXIV{\moodle@basename}{\TikzExportExtension}%
+ \IfFileExists{\moodle@basename.enc}{}{\PackageError{moodle}{Conversion failed}{Check your base64 conversion utiliy}}%
\message{moodle.sty: Reading base64 file '\tikzexternalrealjob-tikztemp-\the\numconvertedpictures.enc'...^^J}%
\savebaselxivdata
\message{moodle.sty: base64 data saved.^^J}%
@@ -3829,6 +3984,19 @@
\xa\moodle@VerbatimInput\xa{\csname minted@infileHTML\the\c@moodle@pygmentizecounter\endcsname}%
}%
\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}'.}%