Skip to content

Initial MathJax renderer implementation#39

Draft
grimsteel wants to merge 15 commits intomasterfrom
docs-client-mathjax
Draft

Initial MathJax renderer implementation#39
grimsteel wants to merge 15 commits intomasterfrom
docs-client-mathjax

Conversation

@grimsteel
Copy link
Collaborator

@grimsteel grimsteel commented Jun 4, 2025

This is an initial implementation of a client-side MathJax renderer (for Docs right now).

I've currently only implemented the renderer, but this was the bulk of the work. Everything else should be significantly easier.

image

Comparison: (CodeCogs is left, MathJax is right)
image

As far as I know, adding support for the mobile/workspace addon isn't possible as this renderer relies on a Canvas to convert the MathJax SVG to a PNG.

Todo:

  • Renderer
  • Derenderer
  • Colored equations (Docs actually has no support for this at all right now)
  • MathJax error handling
  • Further equation tests
I also cleaned up some of the render code
  • use enum and defined interface type instead of tuple/magic numbers
  • move all render options into a single interface
  • remove redundant params (start/end for range where the RangeElement is
    already passed in, rendererType + renderer[5])
  • remove quality param
  • improve readability of Docs replaceEquations return value (use object
    instead of numerical flag)

grimsteel added 4 commits May 24, 2025 13:20
- use enum and defined interface type instead of tuple/magic numbers
- move all render options into a single interface
- move most options into a single interface
- remove redundant params (start/end for range where the RangeElement is
already passed in, rendererType + renderer[5])
- remove quality param
- improve readability of Docs replaceEquations return value (use object
instead of numerical flag)
- add client rendering option to render code
@Divide-By-0
Copy link
Owner

Divide-By-0 commented Jun 4, 2025 via email

@grimsteel
Copy link
Collaborator Author

Can we make sure the MathJax is the same height as Codecogs?

Yes - I've done some scaling already just based on the image heights, but I should be able to make it more accurate. (I'll also see if I can reduce the thickness of the MathJax equations)

For some parts of equations, MathJax is actually bigger for some reason: (TexRendr is left; I'm not sure what happened to the first part of the equation)
image

It seems like most renderers scale down the fractions, while MathJax does not.

Can we have mobile fallback to the other renderers then I guess
so it still works?

Right now, we only use MathJax when the checkbox enabling it is checked. I'll eventually remove the check and make it the default, but the code for the other renderers is all still there. Mobile should keep using them.

@grimsteel grimsteel force-pushed the docs-client-mathjax branch from 8363811 to 1b4cdb3 Compare July 15, 2025 22:12
@Divide-By-0
Copy link
Owner

Put it under advanced settings?

- previously, we were iterating over the indices of elements. if a shape
was removed because it only had an equation, there was a chance we could
skip the next shape - this changes the code to iterate over an array of
elements that is fetched once, before the iteration happens
@Divide-By-0
Copy link
Owner

From grimsteel:

Also, I was doing some more tests with the MathJax renderer, and it fails when there are multiple equations in the same TextElement.

Right now, the renderer does an initial pass of the entire document and finds all of the equations without actually rendering them. It stores each equation as a RangeElement with a custom start/end offset, and saves each one as a named range (as the actual RangeElement object can't be sent to the client). It then sends all the information to the client, which renders each equation and sends the rendered blob back with the named range ID. It then inserts these blobs using the same placeImage function like the other renderers.

As far as I can tell, placeImage/repairImage actually delete the rest of the TextElement the equation is contained in and append a new one that has the current equation removed. This makes the MathJax renderer fail when it tries to do stuff with the named range for any subsequent equations in the same TextElement, as it doesn't actually exist anymore.

Do you have any ideas for solving this? I suppose I could "group" equations by TextElement, and process each TextElement at once, but that would pretty much require new rendering code.

@Divide-By-0
Copy link
Owner

Reply from me:

What if you went backwards through the document, replacing equations at the end of each paragraph first? So that way when you replace the rest of the paragraph, it doesn't actually change the earlier equations... I don't really know if this will work or not

You could also maybe rescan the document after each image replacement or something? I think scanning is pretty quick or maybe even go to the previous text element in the next text each time or something to recalculate it instead of having to re-scan the entire document even, I'm not sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments