SimonDanisch/Bonito.jl

Using MathJax for rendering LaTeX

timoleistner opened this issue · 4 comments

Hi,
As there is a way of wrapping JS libraries it should be possible to use MathJax somehow.
I would like to use LaTeX like this for example:

DOM.p(L"$log(x_t)=A+C\cdot e^{−e^{(−B\cdot (t−M))}}$")

While the documentation gives one example, I am not sure how to make MathJax work.

MathJax states that:
If you write your own HTML (directly or via a template/theme engine), you can include MathJax by adding this snippet to your page:

<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>

Franklin.jl made it work too somehow

Any pointers would be appreciated.

Did you try by adding that snipped to the page with DOM.script?

I tried different things but to no avail.

App() do session
	jsmodule = ES6Module("https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js")::Asset

	DOM.script(src=jsmodule, type="module")
	return DOM.p(raw"$log(x_t)=A+C\cdot e^{−e^{(−B\cdot (t−M))}}$")
end
App() do session

	DOM.script("""
	<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
	<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
	"""
	)
	return DOM.p(raw"$log(x_t)=A+C\cdot e^{−e^{(−B\cdot (t−M))}}$")
end
App() do session
	jsmodule = ES6Module("https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js")::Asset
	
	return DOM.p(js"$(jsmodule).then(jsmodule=> {
			$log(x_t)=A+C\cdot e^{−e^{(−B\cdot (t−M))}}$
	})")
end

I am also not sure if I should use a raw"" string or a latex string L"" or js"". I'm probably missing some fundamental thing 🤔

Edit: There is also a CDN https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_SVG but the CDNSource() from the Docs Assets part isnt working anymore.

This should work:

App() do 
    polyfill = DOM.script(src="https://polyfill.io/v3/polyfill.min.js?features=es6")
    mthjax = DOM.script(id="MathJax-script", src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js", async=true)
    mathtex = raw"When \(a \ne 0\), there are two solutions to 
        \(ax^2 + bx + c = 0\) and they are
        \[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\]"
    return DOM.div(polyfill, mthjax, DOM.p_unesc(mathtex))
end

It only works on first display though... It should work on static sites like that, or when you serve the app via a server - just not with browser-display.

I guess it's because of: https://docs.mathjax.org/en/latest/advanced/typeset.html
But doing mathjax.typeset() runs into:
mathjax/MathJax#3079

Very nice! I think it would be cool to have an example like this in the docs in the Wrapping JS libraries section.
Like you said, it works when serving the app via server and doesn't work in Pluto (browser-display).

It would be nice to have a more accessible/intuitive way of doing this, like overloaded LatexStrings so that one could also use string interpolation or is this possible already somehow? I tried the following to no avail:

App() do 
    polyfill = DOM.script(src="https://polyfill.io/v3/polyfill.min.js?features=es6")
    mthjax = DOM.script(id="MathJax-script", src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js", async=true)
    mathtex = Observable(raw"When \(a \ne 0\), there are two solutions to 
        \(ax^2 + bx + c = 0\) and they are
        \[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\]")
    s_a = Bonito.Slider(range(1, 10, step=0.5), value=5)
    function texstring(var)
        mathtex[] = raw"When \(" * "$var" * raw"\)"
    end
    map(texstring, s_a.value)
    return DOM.div(polyfill, mthjax, DOM.p_unesc(mathtex))
end

Is there any information on DOM.p_unesc()? Because I couldn't find anything on this (Neither in the docs of Bonito.jl nor in its code or in Hyperscript.jl's code) but it seems to work without wrapping the mathtex string in it.

How did you try to use mathjax.typeset()? Just including it in the example like this

App() do 
    polyfill = DOM.script(src="https://polyfill.io/v3/polyfill.min.js?features=es6")
    mathjax = DOM.script(id="MathJax-script", src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js", async=true)
    mathtex = raw"When \(a \ne 0\), there are two solutions to 
        \(ax^2 + bx + c = 0\) and they are
        \[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\]"
    mathjax.typeset()
    return DOM.div(polyfill, mthjax, DOM.p_unesc(mathtex))
end

won't throw the mentioned error for me (but won't render latex in Pluto either).

Anyway it's cool that this functionality is basically there already. Thank you for this cool package!