Render subscript in using react-markdown

84 Views Asked by At

I am unable to render subscript the markdown notation (~this is subscript~but not this) using react-markdown.

There are three ways I could easily find to render a do this: remark-supersub, remark-sub-super and something like this:

components={{ 
    em: ({ node, ...props }) => { 
            if ( props.children[0] && typeof props.children[0] === 'string' && props.children[0].startsWith('^')) { 
                    return <sup>{props.children[0].substring(1)}</sup> 
                } 
            if ( props.children[0] && typeof props.children[0] === 'string' && props.children[0].startsWith('~')) { 
                    return <sub>{props.children[0].substring(1)}</sub> 
                } 
            return <i {...props} /> 
            },
}}

... none of them works for me (they either do nothing or throw an error while rendering). Any other ideas? Thanks in advance.

1

There are 1 best solutions below

3
moonstar-x On BEST ANSWER

One of the packages you mentioned, remark-supersub works pretty well without much configuration.

You should pass this plugin as a remarkPlugins prop in the Markdown component:

import Markdown from "react-markdown";
import supersub from "remark-supersub";
import remarkGfm from "remark-gfm";
import remarkMath from "remark-math";

const markdown = `
# Markdown

21^st^ Century

H~2~O

~this is subscript~but not this

Something in ~~strikethrough~~
`;

export default function App() {
  return (
    <Markdown
      remarkPlugins={[
        [remarkGfm, { singleTilde: false }],
        remarkMath,
        supersub,
      ]}
    >
      {markdown}
    </Markdown>
  );
}

This will render your markdown like this:

Output image.

Edit React Markdown - Super/Sub


Update: As seen in your comment, the issue lies with remark-gfm because this plugin will interpret by default ~text~ as strikethrough. The solution would be to pass { singleTilde: false } to remarkGfm, that way you can keep a single ~text~ as subtext instead and ~~text~~ as strikethrough.