DEV Community

Pavel Belokon
Pavel Belokon

Posted on

Code Reading (Docusaurus)

For my study week I was tasked with reaviwing on of the For my study week, I was tasked with reviewing one of the Docusaurus features in order to implement it in my own project.

The feature I found to be very cool is Syntax Highlighting for code blocks if we go to Docusaurus official page linked above we can see that it uses Prism React Renderer with custome themes.

Here is a small example of how this would work with Markdown:

function HelloCodeTitle(props) {
  return <h1>Hello, {props.name}</h1>;
}
Enter fullscreen mode Exit fullscreen mode

We can do this by encapsulating the code block in triple backticks (

) followed by a language identifier at the beginning, like so (

jsx).

The implementation is done by the library, so there is not much to explore, but we can still see how Docusaurus uses/configures Prism.

If we go to lines 24 - 25, we can see custom themes for Prism that can be found in the utilities folder. For example, we can see in both light and dark themes that they always extend the base theme that goes with Prism. You can see it here

Also, as explained, as can be seen in the example website, Docusaurus has whenever Fenced Code Blocks are parsed in Markdown, you can see that as per Prism documentation, Docusaurus first creates a "pre" tag with the language class and then adds a container with code lines inside.

example:

Image description

Now, lastly, let's see how Docusaurus parses Markdown Code Blocks, which can be seen here.

export function unwrapMdxCodeBlocks(content: string): string {
  // We only support 3/4 backticks on purpose, should be good enough
  const regexp3 =
    /(?<begin>^|\n)```
{% endraw %}
mdx-code-block\n(?<children>.*?)\n
{% raw %}
```(?<end>\n|$)/gs;
  const regexp4 =
    /(?<begin>^|\n)```
{% endraw %}
{% raw %}`mdx-code-block\n(?<children>.*?)\n`{% endraw %}
{% raw %}
```(?<end>\n|$)/gs;

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const replacer = (substring: string, ...args: any[]) => {
    const groups = args.at(-1);
    return `${groups.begin}${groups.children}${groups.end}`;
  };

  return content.replaceAll(regexp3, replacer).replaceAll(regexp4, replacer);
}

Enter fullscreen mode Exit fullscreen mode

The approach is, in fact, what you would expect: 2 regexes for 3/4 backticks to cover most of the scenarios.

I believe this covers all the information I needed to create an implementation of this feature for my project.

Finally, let's talk about the strategies I used to read the code. It was a typical process that I think everyone has used, which is isolating the area that you want to review. In my example, it was Code Block highlighting, so I went using GitHub Code Search to find all related files. Since it was pretty much what I needed, I started going through the files and found that Docusaurus passes parsed Markdown to Prism, and that was it. I also found searching for issues related to your topic helpful because more knowledgeable people leave a lot of explanations and discussions of the feature.

To the question "Did you need to use AI to help?" I say no, as in order to use it on such a big project, I would have to spend a lot of time providing it with the context. I could better invest myself to get a better understanding of the feature rather than an overview. Yes, it can be helpful when you want a quick answer to a general question, but it fails to provide a detailed overview. So using AI is better left for helping in understanding smaller questions, such as code blocks.

Top comments (0)