3

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.

5 Answers 5

5

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.

1
  • Thanks a lot, Marijn! Now it works with \graphicspath Commented Apr 21, 2020 at 20:40
1

Moodle's pipeline to convert graphics to base64 for the XML file is the following: Input graphics -> Imagemagick -> openssl -> base64 Output

Marijn's solution seems to work under the assumption that one deals with PNG graphics and uses \includegraphics without writing the graphics file extension (.png). The imagemagick step fails (which might be a good thing if you don't want to resize unnecessarily the original PNG file) without compromising the rest of the process.

ASarkar's adaptation is made to work under the assumption that one deals with PDF graphics and uses \includegraphics without writing the graphics file extension (.pdf). The imagemagick step succeeds (provided your system's policy allows Ghostscript to convert PDFs to PNGs).

Both Marijn's and ASarkar's solutions will fail if the command \graphicspath is not called.

Here is a solution made for people dealing with different graphics file formats. The price to pay is to always specify the file extension in the \includegraphics call:

\documentclass{article}
\usepackage{graphicx,moodle}
\makeatletter
\def\moodle@graphicspath{\@ifundefined{Ginput@path}{}{\xa\@firstofone\Ginput@path}}
\xpatchcmd{\moodle@includegraphics@int@int}%
{#2 -resize}%
{\moodle@graphicspath#2 -resize}%
{\typeout{patch ok}}%
{\typeout{patch failed}}
\makeatother
\begin{document}
\begin{quiz}{Newton laws}
  \begin{multi}[shuffle=true, points=1]{Newton laws - 1}
    blablabla
    \includegraphics{folder1/fig3.png} % the path is specified here
  \item* 1
  \item 2 
  \end{multi}
\graphicspath{{folder2/}} % path specified with \graphicspath
  \begin{multi}[shuffle=true, points=1]{Newton laws - 1}
    blablabla
    \includegraphics{fig4.pdf}
  \item* 1
  \item 2 
  \end{multi}
\end{quiz}
\end{document}

Note that it is superfluous to load the package xpatch as moodle requires it anyway.

A version of the moodle package under development uses this approach. See this fixed issue

0

It seems that moodle.sty requires the image files to be in the same directory as the latex source file. I copied all the image files to the directory where the latex source was and now the xml file has embedded the decoded base64 files. So it seems that \graphicspath cannot be used with moodle.sty

0

@Marijn's answer is excellent. However, I also found that even convert command fails to convert pdf to png unless the \includegraphics command has the extension .pdf, i.e.

% Works, but the output png file is named spinning_top1.pdf.png
\includegraphics[width=0.4\textwidth]{spinning_top1.pdf}

and not

% Fails to convert
\includegraphics[width=0.4\textwidth]{spinning_top1}

To account for that here is my modified code. (This assumes that all your image files are .pdf files and not .jpg or .gif)

\usepackage{xpatch}
\makeatletter
\def\graphicspath#1{\def\Ginput@path{#1}\edef\moodleimgpath{\@firstofone#1}}

\xpatchcmd{\moodle@includegraphics@int@int}%
{\htmlize@imagemagick@convert\otherspace #2 -resize \moodle@graphics@geometry\otherspace #2.png}%
{\htmlize@imagemagick@convert\otherspace \moodleimgpath#2.pdf -resize \moodle@graphics@geometry\otherspace +profile 'icc' \moodleimgpath#2.png}%
{\typeout{patch ok}}%
{\typeout{patch failed}}

\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
-1

All the files are in the same folder. It has a problem of configuring external programs and it is not what to do.

magick' is not recognized as an internal or external command, operable program or batch file. moodle.sty: Converting './robot.png.png' to base64... 'openssl' is not recognized as an internal or external command, operable program or batch file. moodle.sty:

1
  • Franklin, did you run pdflatex with the --shell-escape switch? This allows pdflatex to run external programms from inside the tex file Commented Jun 8, 2020 at 23:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .