Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rehype-mathjax: CHTML not rendering #85

Open
4 tasks done
FunkMonkey opened this issue Jul 24, 2023 · 10 comments
Open
4 tasks done

rehype-mathjax: CHTML not rendering #85

FunkMonkey opened this issue Jul 24, 2023 · 10 comments
Labels
🤞 phase/open Post is being triaged manually

Comments

@FunkMonkey
Copy link

Initial checklist

Affected packages and versions

4.0.3

Link to runnable example

No response

Steps to reproduce

import React from 'react';
import ReactMarkdown from 'react-markdown';
import rehypeMathjaxChtml from 'rehype-mathjax/chtml';
import remarkMath from 'remark-math';

export interface IExpressionProps {
  expression: string;
  inline?: boolean;
}

export function Expression({ expression, inline }: IExpressionProps): React.ReactElement {
  const text = inline ? `$${expression}$` : `$$${expression}$$`;
  return (
    <ReactMarkdown
      remarkPlugins={[remarkMath]}
      rehypePlugins={[
        [
          rehypeMathjaxChtml,
          {
            scale: 4,
            chtml: {
              fontURL: 'https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/output/chtml/fonts/woff-v2',
            },
          },
        ],
      ]}
    >
      {text}
    </ReactMarkdown>
  );
}

Runtime: Building via Vite for the browser on Node18.

Expected behavior

Equations should be rendered

Actual behavior

Equations are not rendered with rehypeMathjaxChtml, but are rendered when using the default SVG renderer instead.

The problem is most likely that the generated HTML-code contains classname instead of class, e.g.:

<mjx-container classname="MathJax" jax="CHTML">
  <mjx-math classname="MJX-TEX">
    <mjx-mo classname="mjx-n">
      <mjx-c classname="mjx-c3D"></mjx-c>
    </mjx-mo>
    <mjx-mfrac space="4">
      <mjx-frac>
        <mjx-num>
          <mjx-nstrut></mjx-nstrut>
          <mjx-mstyle size="s" style="color: rgb(76, 175, 80);">
            <mjx-mtext classname="mjx-n">
              <mjx-c classname="mjx-c41"></mjx-c>
              <mjx-c classname="mjx-c6E"></mjx-c>
              <mjx-c classname="mjx-c7A"></mjx-c>
              <mjx-c classname="mjx-c61"></mjx-c>
              <mjx-c classname="mjx-c68"></mjx-c>
              <mjx-c classname="mjx-c6C"></mjx-c>
              <mjx-c classname="mjx-c20"></mjx-c>
              <mjx-c classname="mjx-c64"></mjx-c>
              <mjx-c classname="mjx-c65"></mjx-c>
              <mjx-c classname="mjx-c72"></mjx-c>
              <mjx-c classname="mjx-c20"></mjx-c>
              <mjx-c classname="mjx-c45"></mjx-c>
              <mjx-c classname="mjx-c6C"></mjx-c>
              <mjx-c classname="mjx-c65"></mjx-c>
              <mjx-c classname="mjx-c6D"></mjx-c>
              <mjx-c classname="mjx-c65"></mjx-c>
              <mjx-c classname="mjx-c6E"></mjx-c>
              <mjx-c classname="mjx-c74"></mjx-c>
              <mjx-c classname="mjx-c65"></mjx-c>
              <mjx-c classname="mjx-c20"></mjx-c>
              <mjx-c classname="mjx-c69"></mjx-c>
              <mjx-c classname="mjx-c6E"></mjx-c>
              <mjx-c classname="mjx-cA0"></mjx-c>
            </mjx-mtext>
            <mjx-mi classname="mjx-i">
              <mjx-c classname="mjx-c1D43E TEX-I"></mjx-c>
            </mjx-mi>
            <mjx-mo classname="mjx-n">
              <mjx-c classname="mjx-c2229"></mjx-c>
            </mjx-mo>
            <mjx-mi classname="mjx-i">
              <mjx-c classname="mjx-c1D445 TEX-I"></mjx-c>
            </mjx-mi>
          </mjx-mstyle>
        </mjx-num>
        <mjx-dbox>
          <mjx-dtable>
            <mjx-line></mjx-line>
            <mjx-row>
              <mjx-den>
                <mjx-dstrut></mjx-dstrut>
                <mjx-mstyle size="s" style="color: rgb(63, 81, 181);">
                  <mjx-mtext classname="mjx-n">
                    <mjx-c classname="mjx-c41"></mjx-c>
                    <mjx-c classname="mjx-c6E"></mjx-c>
                    <mjx-c classname="mjx-c7A"></mjx-c>
                    <mjx-c classname="mjx-c61"></mjx-c>
                    <mjx-c classname="mjx-c68"></mjx-c>
                    <mjx-c classname="mjx-c6C"></mjx-c>
                    <mjx-c classname="mjx-c20"></mjx-c>
                    <mjx-c classname="mjx-c64"></mjx-c>
                    <mjx-c classname="mjx-c65"></mjx-c>
                    <mjx-c classname="mjx-c72"></mjx-c>
                    <mjx-c classname="mjx-c20"></mjx-c>
                    <mjx-c classname="mjx-c45"></mjx-c>
                    <mjx-c classname="mjx-c6C"></mjx-c>
                    <mjx-c classname="mjx-c65"></mjx-c>
                    <mjx-c classname="mjx-c6D"></mjx-c>
                    <mjx-c classname="mjx-c65"></mjx-c>
                    <mjx-c classname="mjx-c6E"></mjx-c>
                    <mjx-c classname="mjx-c74"></mjx-c>
                    <mjx-c classname="mjx-c65"></mjx-c>
                    <mjx-c classname="mjx-c20"></mjx-c>
                    <mjx-c classname="mjx-c69"></mjx-c>
                    <mjx-c classname="mjx-c6E"></mjx-c>
                    <mjx-c classname="mjx-cA0"></mjx-c>
                  </mjx-mtext>
                  <mjx-mi classname="mjx-i">
                    <mjx-c classname="mjx-c1D445 TEX-I"></mjx-c>
                  </mjx-mi>
                </mjx-mstyle>
              </mjx-den>
            </mjx-row>
          </mjx-dtable>
        </mjx-dbox>
      </mjx-frac>
    </mjx-mfrac>
  </mjx-math>
</mjx-container>

I am not quite sure if this is a bug of rehype-mathjax or mathjax itself. Or does CHTML only work with rehype-sanitize, e.g. see README?

Thanks!

Runtime

Other (please specify in steps to reproduce)

Package manager

yarn 2

OS

Windows

Build and bundle tools

Vite

@github-actions github-actions bot added 👋 phase/new Post is being triaged automatically 🤞 phase/open Post is being triaged manually and removed 👋 phase/new Post is being triaged automatically labels Jul 24, 2023
@ChristianMurphy
Copy link
Member

Thanks for reaching out @FunkMonkey! 👋

Or does CHTML only work with rehype-sanitize

While it is a good idea to use rehype-sanitize, it is not required for this project.

I am not quite sure if this is a bug of rehype-mathjax or mathjax itself.

Given that the SVG renderer works fine, but the CHTML one does not.
Runnable demo: https://codesandbox.io/s/eloquent-moore-kc84ny?file=/src/app.tsx

And that the code between SVG: https://github.com/remarkjs/remark-math/blob/main/packages/rehype-mathjax/svg.js
and CHTML https://github.com/remarkjs/remark-math/blob/main/packages/rehype-mathjax/chtml.js
is nearly identical except which mathjax function they use, and validation for a required option.
I tend to think this is a bug in MathJax itself.

/cc @tani in case you have any additional ideas on what may be happening in the chtml

@ChristianMurphy
Copy link
Member

Also cross linking a recent discussion in react-markdown running into the same issue remarkjs/react-markdown#745

@wooorm
Copy link
Member

wooorm commented Jul 29, 2023

I think this has to do with React supporting properties (className) on HTML/SVG elements, but not on MathML (or custom, or unknown) elements.
We support className everywhere.

Googling MathML + React gives many bugs, e.g., https://stackoverflow.com/questions/51319758/react-16-html-attributes-with-mathml-tags.

MathML was mostly abandoned for years, but recently got updates and implementations. Hopefully React will add/improve MathML support.

@edward1127
Copy link

edward1127 commented Aug 31, 2023

Do you have any updates on how to solve it? I've encountered the issue where the rendered SVG is not inline. I suspect it might be related to the same className issue.
image

@ChristianMurphy
Copy link
Member

Welcome @edward1127! 👋
Did you get a chance to read @wooorm's comment right before yours?
In particular:

MathML was mostly abandoned for years, but recently got updates and implementations. Hopefully React will add/improve MathML support.

We don't have an update on the remark side, because remark isn't causing the issue.
You could file an issue with React (https://github.com/facebook/react/issues) or reach out to one of the React communities (https://react.dev/community) for more specific ideas.
Consider sharing a link to the discussion you start in the react community here, so others can find it and use it as reference.

@edward1127
Copy link

Thanks for the reply. I just reposted your summary vercel/next.js#54852

@ChristianMurphy
Copy link
Member

@edward1127 that link looks to be the question from #81?
Do you believe this and #81 are the same issue? I tend to think they are separate, one in React in one in Next, but happy to hear other perspectives.

@edward1127
Copy link

edward1127 commented Aug 31, 2023

yep, you are right.
Just test it out with React, and everything works fine in react for #81 .

@GeorgeNabilPro
Copy link

I countered this issue, and I think it can be worked around by making a custom rehype plugin to replace each 'classname' property in the hast with 'class'. However, it may not be an efficient method. But if you really want to solve the issue I think this solution deserves a try.

@wooorm
Copy link
Member

wooorm commented Sep 6, 2023

I don‘t think that works. Whether it works or not it would break lots of things.

If you really want to solve this issue, see the existing comments on this discussion and solve the root cause, or use a working alternative: do not use the CHTML rendered, or use rehype-katex.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤞 phase/open Post is being triaged manually
Development

No branches or pull requests

5 participants