timlrx / rehype-prism-plus

rehype plugin to highlight code blocks in HTML with Prism (via refractor) with line highlighting and line numbers
MIT License
177 stars 19 forks source link

Line numbers not working when using rehype-raw #54

Closed virgilio-redradix closed 2 years ago

virgilio-redradix commented 2 years ago

Using rehype-prism-plus in a project with react-markdown and rehype-raw plugin. It works fine if rehype-prism-plus is defined first in the plugins array but line numbers are not displayed (and related attributes are unset in DOM) if placing rehype-raw first.

Dependencies versions:

"react-markdown": "^8.0.3",
"rehype-prism-plus": "^1.5.0",
"rehype-raw": "^6.1.1"

Sample code:

import ReactMarkdown from "react-markdown";
import rehypeRaw from "rehype-raw";
import rehypePrismPlus from "rehype-prism-plus";

import "./styles.css";

const markdown = `
Code block:

~~~js showLineNumbers
const test = 'Show line numbers'
~~~
`;

export default function App() {
  return (
    <div className="App">
      <ReactMarkdown rehypePlugins={[rehypePrismPlus, rehypeRaw]} >
        {markdown}
      </ReactMarkdown>
    </div>
  );
}

CodeSandbox: https://codesandbox.io/s/thirsty-williams-us0vg1?file=/src/App.js

timlrx commented 2 years ago

Thanks for the example. Yes, this behaviour is intended - rehypePrismPlus should come first as it goes beyond the standard markdown specs in parsing a code block by detecting optional arguments such as showLineNumbers and converting it to a valid HTML syntax tree.

As described in rehype-raw:

This plugin passes each node and embedded raw HTML through an HTML parser (parse5), to recreate a tree exactly as how a browser would parse it

If it runs first, it will discard the non-standard meta information field in the code block. If it runs later, it takes the already modified syntax tree with the correct attributes and the line numbers are thus preserved.

Any reason you might need to run rehype-raw first? If you are looking to combine html blocks together with markdown, perhaps consider using MDX?

Another possible approach might be to setshowLineNumbers to true at the plugin level rather than as a meta property at the code block level - this would apply line numbers to all code blocks.

virgilio-redradix commented 2 years ago

Thank you very much for your response @timlrx! I don't need to run rehype-raw first at all, just noticed this behaviour and thought it might be a bug but with your explanation I understand everything is working as it should. Thanks again!