fast-reflexes / better-react-mathjax

MIT License
132 stars 16 forks source link

Getting Typesetting failed: e[g.fn] is not a function with better-react-mathjax #53

Closed lancejpollard closed 9 months ago

lancejpollard commented 9 months ago

It appears using tex2svg or tex2svgPromise at least throw that error and are unusable. Any ideas?

fast-reflexes commented 9 months ago

Hello there!

I can make both of those work perfectly fine. Since Code Sandbox is no longer offering free umlimited usage, I'm posting the full code here:

NOTE: The below is a complicated and non-standard way of accomplishing manual typesetting with tex2svg and tex2svgPromise. See the follow-up post which shows the idiomatic way of doing it in this library. I will let the below stay as a proof of concept for advanced use-cases only

import "./App.css"
import {MathJax, MathJaxBaseContext, MathJaxContext} from "better-react-mathjax";
import {useContext, useEffect} from "react";

const App = () => {

    const config = {
        loader: { load: ["input/tex", "output/svg"] },
        tex: {
            inlineMath: [["$", "$"], ["\\(", "\\)"]],
            displayMath: [["$$", "$$"], ["\\[", "\\]"]]
        }
    }
    return (
      <MathJaxContext config={config} src={"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"} >
          <MathJax>
              {"This is typeset automatically: $\\frac{\\sqrt{1}}{2}$"}
          </MathJax>
          <Consumer />
      </MathJaxContext>
    )
}

const Consumer = () => {

    const mjContext = useContext(MathJaxBaseContext);

    useEffect(() => {
        if (mjContext) {
            mjContext.promise.then((mathJax => {
                if("startup" in mathJax) {
                    mathJax.startup.promise.then(() => {
                        const tex = "\\dfrac{225}{500}";
                        let html = mathJax.tex2svg(tex, {display: false,});
                        document.getElementById("math")?.replaceChildren(html);
                        mathJax.tex2svgPromise(tex, {display: false}).then((html: HTMLElement) => {
                            document.getElementById("math2")?.replaceChildren(html);
                        })
                    });
                }
            }));
        }
    });

    return (
        <div>
            <p>
                {"This is typeset manually with tex2svg: "}
                <span id={"math"} />
                <br />
                {"And this is typeset manually with svg2Promise:"}
                <span id={"math2"} />
            </p>
        </div>
    );
}

export default App;

And here is the result:

Skärmavbild 2024-02-07 kl  21 09 16

All of these three are svgs:

Skärmavbild 2024-02-07 kl  21 09 55

Maybe you forgot to download the correct source file for svg to work? You can study a previous similar question here: https://github.com/fast-reflexes/better-react-mathjax/issues/26

Hope this answers your question!

fast-reflexes commented 9 months ago

This is actually how you're supposed to do this in the library... ignore the above complicated way of doing the same:

<MathJaxContext config={config} src={"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"} >
    <MathJax>
        {"This is typeset automatically: $\\frac{\\sqrt{1}}{2}$"}
    </MathJax>
    <span>{"This is typeset manually with tex2svg: "}</span>
    <MathJax
        inline
        renderMode={"pre"}
        typesettingOptions={{ fn: "tex2svg" }}
        text={"\\dfrac{225}{500}"}
    />
    <br/>
    <span>{"This is typeset manually with tex2svgPromise: "}</span>
    <MathJax
        inline
        renderMode={"pre"}
        typesettingOptions={{ fn: "tex2svgPromise" }}
        text={"\\dfrac{225}{500}"}
    />
</MathJaxContext>

Note that you still have to import the particular source which includes the SVG output Jax.

lancejpollard commented 9 months ago

Got it, I was probably missing src={"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"}.

johncheong1234 commented 8 months ago

Anyway to do the same thing with ascii math to svg?

johncheong1234 commented 8 months ago

Anyway to do the same thing with ascii math to svg? Found out a few seconds later: Just replace typesettingOptions={{ fn: "tex2svgPromise" }} with typesettingOptions={{ fn: "asciimath2svg" }}