Mathematical Notation in Online R/exams
Overview
A popular use case of the R/exams package is the generation of dynamic exercises for online learning management systems in large-scale courses in mathematics, statistics, or physics. Often, these contain some mathematical notation using LaTeX markup. While LaTeX can be easily rendered into PDF for printing written exams, the options for rendering it into HTML for online exams are somewhat more diverse and the best strategies depend on a number of factors. As these involve a number of technical details this tutorial aims to give a brief overview and makes a few practical recommendations. Factors include the following:
- Original markup in exercise source files:
The R/exams exercises may employ either Markdown or LaTeX for formatting and structuring the text (see the First steps tutorial for more details). In either case LaTeX is used for the mathematical notation. Thus, also in Markdown the mathematical content is embedded as LaTeX code. - Math markup in HTML:
For display of the formatted text online in a browser, the original markup (Markdown/LaTeX) needs to be converted (see below) to HTML with some suitable formatting for the mathematical content. Either the LaTeX can be preserved or turned into MathML, a dedicated XML format for describing mathematical content. - Rendering of math markup:
The most widely-used way of rendering mathematical content in web pages is MathJax (see also the corresponding Wikipedia page), an open-source JavaScript library that works in all browsers without any setup by the user (except enabling JavaScript). It can render LaTeX directly but also MathML. Moreover, some browsers (mainly Firefox and Safari but not Chrome) have also native support for displaying MathML, i.e, without the need for an additional display engine such as MathJax. The advantage of employing the browser for MathML rendering is that it is faster and typically blends better into the regular text. The disadvantage is obviously that it is not supported by all browsers and does not support rendering of LaTeX directly. - Conversion to HTML:
The original markup from the exercises templates needs to be converted to HTML and the most powerful document converter for this is Pandoc (see also the corresponding Wikipedia page). It can convert both Markdown and LaTeX source files to HTML, either with LaTeX embedded for MathJax or with MathML (among various other options). Moreover, LaTeX (but not Markdown) exercises can be converted to HTML using the TeX-to-MathML converter TtM. (R/exams also provides a few further options which are typically of less interest due to lower quality, such as TtH or rendered images.) - Defaults in R/exams:
Allexams2xyz()
functions that produce HTML-based output offer aconverter =
argument. By default, this is configured to produce HTML with embedded MathML because this can be rendered both by MathJax in all browsers as well as by some browsers directly. The default is isconverter = "pandoc"
(equivalent to"pandoc-mathml"
) for R/Markdown exercises andconverter = "ttm"
for R/LaTeX exercises, respectively. Whether MathJax is enabled varies across output formats or might depend on the learning management system.
Why does all of this matter?
As a simple illustration of the strengths and weaknesses of the different approaches, the deriv exercise template (computation of a derivative using the product rule) is converted to HTML using exams2html()
. Here, the R/LaTeX version of the exercise is used ("deriv"
or equivelently "deriv.Rnw"
) but using the R/Markdown version ("deriv.Rmd"
) yields almost the same output.
The following examples and resulting screenshots contrast the output between Firefox and Chrome. By clicking on the screenshots you can also see what the HTML pages look like in your own browser.
MathML rendered by browser
By default, exams2html()
generates HTML with MathML embedded and uses a template that does not enable MathJax.
library("exams")
set.seed(1090)
exams2html("deriv")
The screenshots that the native MathML support in Firefox leads to output that renders fast and smoothly. However, the lack of native MathML support in Chrome means that the exercise cannot be displayed correctly.
MathML rendered by MathJax
To easily explore the effect of MathJax rendering exams2html()
supports the argument mathjax = TRUE
which inserts the MathJax <script>
into the template (loaded from RStudio’s content delivery network).
set.seed(1090)
exams2html("deriv", mathjax = TRUE)
Now the math output looks good in both browsers. However, for Firefox users the version without MathJax might still be preferable as it renders faster with somewhat smoother output.
LaTeX rendered by MathJax
To preserve the LaTeX equations, the argument converter = "pandoc-mathjax"
can be used. Then, Pandoc converts the LaTeX text to HTML but preserves the LaTeX equations (in minimal HTML markup).
set.seed(1090)
exams2html("deriv", converter = "pandoc-mathjax", mathjax = TRUE)
The output is very similar to the MathML rendered MathJax above. However, note that the alignment in the equations is changed (from left to right). This is caused by Pandoc replacing the LaTeX {eqnarray*}
environment employed in the "deriv"
exercise by {aligned}
environments.
Practical considerations
- Original markup in exercise source files:
Whether to use R/Markdown (.Rmd
) or R/LaTeX (.Rnw
) markup in the exercise source files is mostly a matter of taste. The former is probably somewhat easier to learn for beginners but generally differences are small if there is only moderate text formatting. It is also good practice to keep the formatting simple to be robust across the different output formats and more advanced math constructs should be checked carefully. - MathML as default math markup:
As of today (January 2019) it might seem more natural to use LaTeX rendered by MathJax asrmarkdown
does. However, when HTML conversion was added to R/exams in early 2012, MathML rendered by Firefox was the more robust choice. MathML has been preserved as the default since then because it can be rendered both by MathJax and some browsers. - Pandoc vs. TtM:
Pandoc is the default converter for all.Rmd
exercises while TtM is still used by default for.Rnw
exercises. The latter is mostly for backward compatibility but might change to Pandoc in the future. However, differences are not very large for most exercises anyway but some mathematical LaTeX constructs are just supported by one and not the other converter. - Enabling MathJax rendering:
Many modern learning management systems have MathJax enabled by default, e.g., in Moodle, Canvas, or OpenOlat. There are a couple of caveats, though: First, the default MathJax configuration in Moodle and OpenOlat switches off rendering of MathML. Second, some systems do not host their own copy of the MathJax library but employ a content delivery network (CDN). Thus, there is a small risk that the learning management system might be up and running but there are problems loading MathJax from the CDN. - Moodle:
As noted above the default configuration for Moodle has MathJax support (via a CDN) but switches off rendering of MathML. Asexams2moodle(...)
currently uses MathML markup by default, this necessitates Firefox or Safari for viewing the quizzes in Moodle. In contrast,exams2moodle(..., converter = "pandoc-mathjax")
would use LaTeX math markup and render it by MathJax (unless the Moodle configuration switched off MathJax support).
Request: Feedback from Moodle users would be appreciated on whether they prefer the current default orconverter = "pandoc-mathjax"
. It would be especially useful to find out whether the latter works in their Moodle installations. - Canvas:
We are currently working on a dedicatedexams2qti12()
-based functionexams2canvas()
for generating quizzes for Canvas. This will keep the MathML-based default for the math notation as this is rendered smoothly by Canvas’ own MathJax support. - OpenOlat:
A new dedicated interfaceexams2openolat()
for generating quizzes for OpenOlat has been added recently to R/exams (version 2.3-1). By default, this is a wrapper toexams2qti21(..., converter = "pandoc-mathjax")
because OpenOlat provides MathJax rendering of LaTeX math (but not MathML). Some additional tweaks are necessary, though, because OpenOlat expects the LaTeX to be embedded slightly differently from standard Pandoc output.
Further technical details
The mathematical equation in the random draw of the deriv exercise in LaTeX is: f(x) = x^{8} e^{3.4x}
. Here, we highlight that all converters yield almost equivalent output when rendered by MathJax:
"pandoc-mathjax" |
"ttm" |
"pandoc-mathml" |
---|---|---|
\(f(x) = x^{8} e^{3.4x}\) |
(Note: If you are viewing this on R-bloggers or another aggregator some or all of the equations will not display correctly. Refer to the R/exams site for a version with MathJax properly enabled.)
The underlying LaTeX code generated by converter = "pandoc-mathjax"
is simply the original LaTeX code with some minimal HTML markup:
<span class="math inline">\(f(x) = x^{8} e^{3.4x}\)</span>
The MathML code generated by converter = "ttm"
differs slightly from the of converter = "pandoc"
(or equivalently "pandoc-mathml"
). The former yields:
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo>
<msup><mrow><mi>x</mi></mrow><mrow><mn>8</mn></mrow>
</msup>
<msup><mrow><mi>e</mi></mrow><mrow><mn>3</mn><mo>.</mo><mn>4</mn><mi>x</mi></mrow>
</msup>
</mrow></math>
The Pandoc version is very similar but contains some more markup and annotation:
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics>
<mrow><mi>f</mi>
<mo stretchy="false" form="prefix">(</mo><mi>x</mi><mo stretchy="false" form="postfix">)</mo>
<mo>=</mo>
<msup><mi>x</mi><mn>8</mn></msup><msup><mi>e</mi><mrow><mn>3.4</mn><mi>x</mi></mrow></msup>
</mrow><annotation encoding="application/x-tex">f(x) = x^{8} e^{3.4x}</annotation>
</semantics></math>