diff options
author | Karl Berry <karl@freefriends.org> | 2021-02-08 21:58:24 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-02-08 21:58:24 +0000 |
commit | b689b082c823fcce490e8231b4eff18837a5b2d3 (patch) | |
tree | 4c946e14963478600e21baf3a92b253dcb415e58 /Master/texmf-dist/tex/latex/moodle | |
parent | 642941ac6911ff4f07f939e330eff1b4bf18e63a (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')
-rw-r--r-- | Master/texmf-dist/tex/latex/moodle/moodle.sty | 460 |
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{\å}% \html@def\AA{\Å}% \html@def\ae{\æ}% @@ -3022,6 +3133,15 @@ \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\dq{\"}% \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}'.}% |