[Tex/LaTex] moodle.sty does not insert graphics in xml output file

graphicsmoodle;xml

I neet to generate quizes to be imported within the moodle platform . The quizes include figures.

I tried the moodle package from texlive version 2018.20190227-2. When I run pdflatex the .pdf and .xml files are generated without any error message, but the base64 encoded image is not included in the xml output file. All the required commands required by moodle.sty are installed (ghostscript, openssl and imagemagick). Here is an example file.tex

\documentclass[12pt]{article}
\usepackage{moodle}
\usepackage{graphicx}

\graphicspath{{../figures/}}

\begin{document}

\begin{quiz}{Newton laws}
  \begin{multi}[shuffle=true, points=1]{Newton laws - 1}
    blablabla

    \includegraphics{fig3}

  \item* 1
  \item 2
\end{multi}
\end{quiz}

\end{document}

I run pdflatex --shell-escape=true file.tex
The relevant (I think) output from pdflatex is,

...
(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd)
moodle.sty: Processing \includegraphics[]{fig3} for HTML...
moodle.sty: Converting 'fig3' to PNG...
moodle.sty: Converting 'fig3.png' to base64...
moodle.sty: Reading base64 file 'fig3.enc'...
moodle.sty: <IMG> tag inserted.
[1{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map} <./fig3.png (PNG copy)>]
...

But in the xml output file the decoded base64 image is not included, I only get the following where the image should be inserted:

... <IMG  SRC="data:image/png;base64,"> ...

I ended pasting the base64 decoded image by hand after the comma in the previous line but that would be tedious because I have to generate a question bank with a lot of images.

Thanks in advance.

Best Answer

Indeed moodle.sty does not use \graphicspath for the conversion to base64 internally. The conversion command is defined as follows:

\openssl\otherspace enc -base64 -in #2.png -out #2.enc

with \openssl defined as the command that runs openssl and \otherspace is empty by default. However, you can modify this command on the fly using the xpatch package.

Assume you define a command \moodleimgpath that contains the path. The conversion command is used within the macro \moodle@includegraphics@int@int so that is the macro that needs to be patched.

Because there is an @ symbol in the name, which is normally only used in package source code, you need to specify that you want to use @ as a normal symbol within your document using \makeatletter before the patch, and \makeatother after.

Patching needs five arguments: first the macro that is patched, then the string that needs to be modified, then the replacement string, then code that is run when the patch is succesfull, and then code that is run when the patch failed. In this case:

\makeatletter
\xpatchcmd{\moodle@includegraphics@int@int}%
{\openssl\otherspace enc -base64 -in #2.png -out #2.enc}%
{\openssl\otherspace enc -base64 -in \moodleimgpath#2.png -out #2.enc}%
{\typeout{patch ok}}%
{\typeout{patch failed}}
\makeatother

Then it would be nice to derive \moodleimgpath from \graphicspath. The \graphicspath macro has a very simple definition, it is a wrapper around the internal macro \Ginput@path. Therefore, we can use a full redefinition to define the original internal macro but also define our new macro for Moodle. However, because the graphics path can be given with extra braces (\graphicspath{{mypath}}) these should be stripped when setting the new macro. Stripping braces can be done using \@firstofone.

Full MWE:

\documentclass[12pt]{article}
\usepackage{moodle}
\usepackage{graphicx}
\usepackage{xpatch}
\makeatletter
\def\graphicspath#1{\def\Ginput@path{#1}\edef\moodleimgpath{\@firstofone#1}}

\xpatchcmd{\moodle@includegraphics@int@int}%
{\openssl\otherspace enc -base64 -in #2.png -out #2.enc}%
{\openssl\otherspace enc -base64 -in \moodleimgpath#2.png -out #2.enc}%
{\typeout{patch ok}}%
{\typeout{patch failed}}
\makeatother

\graphicspath{{./newton/}}

\begin{document}

\begin{quiz}{Newton laws}
  \begin{multi}[shuffle=true, points=1]{Newton laws - 1}
    blablabla

    \includegraphics[width=6cm]{newtons-law}

  \item* 1
  \item 2
\end{multi}
\end{quiz}

\end{document}

XML output:

<IMG width=243 SRC="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAwQAAAE5CAIAAACh4nDvAACAAElEQVR42uydBXQU etc">

On Moodle:

enter image description here

Note that this requires all images to be in that folder, or, alternatively, that you re-patch the command somewhere within the document in case you want to modify the path. Also this could interfere with processing of TikZ images, most likely some extra adjustments are needed in that case.

Related Question