React-markdown and react-syntax-highlighter

4.7k views Asked by At

I'm building a blog with ReactMarkdown, and I want to render a custom component for the code blocks:

<ReactMarkdown
   children={content}
   rehypePlugins={[rehypeRaw]}
   components={{
     code({ node, inline, children, className, ...props }) {
          return <PrismHighlighter children={children}  {...props} />;
          }
    }}
/>

My 'PrismHighlighter' file consists in the following:

import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { nightOwl } from 'react-syntax-highlighter/dist/cjs/styles/prism';

const SyntaxHighlight = ({ props, children }) => (
  <SyntaxHighlighter style={nightOwl} language="javascript" showLineNumbers {...props}>
    {children}
  </SyntaxHighlighter>
);

export default SyntaxHighlight;

The problem is the following: ReactMarkdown is receiving a string (what is okay), like this:

nucleus_dataset =
nucleus.create_dataset("PennFudan") DATASET_ID =
nucleus_dataset.info()['dataset_id'] # Save unique ID for future use

def format_img_data_for_upload(img_dir: str):   """Instantiates a
Nucleus DatasetItem for all images in the PennFudan dataset.

  Parameters   ----------   img_dir : str
      The filepath to the image directory

  Returns   -------   List[DatasetItem]
      A list of DatasetItem that can be uploaded via the Nucleus API   """   img_list = []   for img_filename in os.listdir(img_dir):
      img_id = img_filename.split('.')[0]
      item = DatasetItem(
          image_location=os.path.join(img_dir, img_filename), 
          reference_id=img_id,
      )
      img_list.append(item)   return img_list

img_list = format_img_data_for_upload(IMG_DIR)

response = nucleus_dataset.append(img_list)

But ReactMarkdown sends to PrismHighlighter an array of objects, like this: example of what ReactMarkdown sends

This results of PrismHighlighter avoiding several lines and showing only half or less of the code, like this: example

So, does anyone knows what happening here? I'm struggling with this for days now.

1

There are 1 answers

1
hannad rehman On

I was facing similar issue with latest version of react-markdown. I have written a detail blog on this problem here

you can create a new MarkdownRenderer component which does this

import React from 'react';
import Markdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import rehypeRaw from 'rehype-raw';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { dracula } from 'react-syntax-highlighter/dist/cjs/styles/prism';

type MarkdownRendererProps = {
  children: string;
};

export function MarkdownRenderer({ children: markdown }: MarkdownRendererProps) {
  return (
    <Markdown
      remarkPlugins={[remarkGfm]}
      rehypePlugins={[rehypeRaw]}
      components={{
        code({ node, inline, className, children, ...props }: any) {
          const match = /language-(\w+)/.exec(className || '');

          return !inline && match ? (
            <SyntaxHighlighter style={dracula} PreTag="div" language={match[1]} {...props}>
              {String(children).replace(/\n$/, '')}
            </SyntaxHighlighter>
          ) : (
            <code className={className} {...props}>
              {children}
            </code>
          );
        },
      }}
    >
      {markdown}
    </Markdown>
  );
}