remark-math
remark-math copied to clipboard
rehype-mathjax: CHTML not rendering
Initial checklist
- [X] I read the support docs
- [X] I read the contributing guide
- [X] I agree to follow the code of conduct
- [X] I searched issues and couldn’t find anything (or linked relevant results below)
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/[email protected]/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
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
Also cross linking a recent discussion in react-markdown
running into the same issue https://github.com/remarkjs/react-markdown/issues/745
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.
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.
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.
Thanks for the reply. I just reposted your summary https://github.com/vercel/next.js/discussions/54852
@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.
yep, you are right. Just test it out with React, and everything works fine in react for #81 .
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.
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.