Reputation: 69
I'm using the markdown-to-jsx package in order to render documentation content inside my react project. This package provides a Markdown component, which accepts an options prop to override HTML elements's default style, and more.
const markdownOptions = {
wrapper: DocsContentWrapper,
forceWrapper: true,
overrides: {
h1: LeadTitle,
h2: SecondaryTitle,
h3: ThirdTitle,
p: Paragraph,
pre: CodeWrapper,
ol: ListWrapper,
li: ListItem,
},
};
<Markdown
options={MarkdownOptions}
>
{MockDoc}
</Markdown>
Now, the Markdown component accept a markdown, so I pass it a string which is formatted accoring to markdown rules.
It contains some code blocks, like the following, which I want to add colors to:
I have created a component using 'react-syntax-highlighter' package, and it looks like the following:
import React from 'react';
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"
import { tomorrow } from "react-syntax-highlighter/dist/esm/styles/prism"
const SyntaxHighligher = ({ language, markdown }) => {
return (
<SyntaxHighlighter
language={language}
style={tomorrow}
>
{markdown}
</SyntaxHighlighter>
);
};
export default SyntaxHighligher;
And here comes the question - how can I integrate the two? I was thinking that it would have made sense if the options object would accept such configuration, but looking at 'markdown-to-jsx' docs via their GitHub page, shows no option.
I have seen a package called 'react-markdown' that is able to accept my SyntaxHighligher component and to the task, but I want to apply the same functionality with 'markdown-to-jsx' package.
Upvotes: 6
Views: 4758
Reputation: 3
I had the same problem with the OP. Here is my approach for it
import { PrismLight as SyntaxHighlighter } from "react-syntax-highlighter";
import { materialDark } from "react-syntax-highlighter/dist/esm/styles/prism";
import Markdown from "markdown-to-jsx";
function Code({ className, children }) {
const language = className.replace("lang-", "");
return (
<div className="codeBlock">
<SyntaxHighlighter language={language.toLowerCase()} style={materialDark}>
{children}
</SyntaxHighlighter>
</div>
);
}
function JsxFromMarkdown() {
return (
<div className="markdownContainer">
<Markdown
options={{
overrides: {
code: {
component: Code,
},
},
}}
>
{markdownContent}
</Markdown>
</div>
);
}
I use language={language.toLowerCase()}
inside Code component as my code block in markdown file is written as ```PYTHON a = 1 + 2 ```. If your code is written as ```python a = 1 + 2 ``` inside markdown file, you should use language={language}
inside Code component.
Upvotes: 0
Reputation: 51
markdown-to-jsx
generates code blocks as <pre><code>...</code></pre>
, but we can't simply override code
tag since inline code uses it as well. The README from markdown-to-jsx
suggests that we can override pre > code
somehow:
Some element mappings are a bit different from other libraries, in particular:
span
: Used for inline text.
code
: Used for inline code.
pre > code
: Code blocks are a code element with a pre as its direct ancestor.
But based on my experiments and reading of the source code, I think the only way is to override pre
and check for code
in its children
. For example:
import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter';
import {materialDark as CodeStyle} from 'react-syntax-highlighter/dist/esm/styles/prism';
const CodeBlock = ({className, children}) => {
let lang = 'text'; // default monospaced text
if (className && className.startsWith('lang-')) {
lang = className.replace('lang-', '');
}
return (
<SyntaxHighlighter language={lang} style={CodeStyle}>
{children}
</SyntaxHighlighter>
);
}
// markdown-to-jsx uses <pre><code/></pre> for code blocks.
const PreBlock = ({children, ...rest}) => {
if ('type' in children && children ['type'] === 'code') {
return CodeBlock(children['props']);
}
return <pre {...rest}>{children}</pre>;
};
const YourComponent = () => {
return (
<Markdown
options={{
overrides: {
pre: PreBlock,
},
}}
>
{yourMarkdown}
</Markdown>
);
};
Unfortunately, I don't have a good solution if you want to override BOTH inline code and code blocks. When overriding both pre
and code
tags, the code
tag generated by SyntaxHighlighter
also gets overridden, so the inline code and code blocks are rendered identically.
Upvotes: 4