benrbray / prosemirror-math

Schema and plugins for "first-class" math support in ProseMirror!
https://benrbray.com/prosemirror-math/
MIT License
249 stars 35 forks source link

Support for async KaTeX #22

Open gzuidhof opened 3 years ago

gzuidhof commented 3 years ago

Hi benrbray,

Thank you for this library, I have integrated it into Starboard Notebook (you can try it here). Before the NPM package was released I vendored all the code (read: copy pasted), but now that it's out I would love to get rid of my own version.

I was only able to remove about half of the code: in Starboard Notebook I load as much stuff asynchronously as possible to keep the initial load and render time fast, KaTeX included.

Basically the only change I made is this in NodeView:

katexLoader.then((katex) => {
    if (!this._mathRenderElt) return;
    // render katex, but fail gracefully
    try {
        katex.render(texString, this._mathRenderElt, this._katexOptions);
        this._mathRenderElt.classList.remove("parse-error");
        this.dom.setAttribute("title", "");
    } catch (err) {
        if (err instanceof ParseError) {
            console.error(err);
            this._mathRenderElt.classList.add("parse-error");
            this.dom.setAttribute("title", err.toString());
        } else {
            throw err;
        }
    }
});

I don't know the best way to fit this into the library.

Perhaps instead of importing katex directly one could pass an object with this signature:

interface MathRenderer {
  render(value: string, element: HTMLElement, rendererOptions: any): Promise<{ok: true} | {ok: false, error: Error}>
}

I saw in another issue that you wanted to support Mathjax as well, this would be a step towards supporting that too.

benrbray commented 3 years ago

fyi I'm actively working on this (outside of my day job), trying to put some care into how options might be passed to/from NodeViews.

In addition to your async KaTeX use case, I want to support MathJax with the next release. Right now some of the KaTeX-specific design decisions are tangled up with the NodeView code. MathJax is a bit of a behemoth, so I'm trying to understand the various ways that MathJax (as well as KaTeX or other math renderers) might be included in an application.