reactjs - 如何在 react 中应用 markdown-to-jsx 包中的代码高亮?
问题描述
我正在使用 markdown-to-jsx 包来在我的 react 项目中呈现文档内容。这个包提供了一个 Markdown 组件,它接受一个 options 属性来覆盖 HTML 元素的默认样式等等。
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>
现在,Markdown 组件接受了一个 markdown,所以我将一个按照 markdown规则格式化的字符串传递给它。
它包含一些代码块,如下所示,我想将颜色添加到:
我使用“react-syntax-highlighter”包创建了一个组件,它如下所示:
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;
问题来了——我怎样才能将两者结合起来?我在想如果选项对象接受这样的配置是有意义的,但是通过他们的 GitHub 页面查看“markdown-to-jsx”文档,显示没有选项。
我已经看到一个名为“react-markdown”的包,它能够接受我的 SyntaxHighligher 组件和任务,但我想使用“markdown-to-jsx”包应用相同的功能。
解决方案
markdown-to-jsx
将代码块生成为<pre><code>...</code></pre>
,但我们不能简单地覆盖code
标记,因为内联代码也使用它。来自的自述文件markdown-to-jsx
建议我们可以pre > code
以某种方式覆盖:
一些元素映射与其他库有点不同,特别是:
span
: 用于内嵌文本。
code
: 用于内联代码。
pre > code
: 代码块是一个以 pre 为直接祖先的代码元素。
但根据我的实验和对源代码的阅读,我认为唯一的方法是覆盖pre
并检查code
其children
. 例如:
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>
);
};
不幸的是,如果您想同时覆盖内联代码和代码块,我没有一个好的解决方案。当同时覆盖pre
和code
标签时,code
生成的标签SyntaxHighlighter
也会被覆盖,因此内联代码和代码块的呈现方式相同。
推荐阅读
- graphql - 如何为graphql-client设置超时
- php - 从 MySQL 获取大量数据时超时?
- android - 如何获取在 editText 上输入的信息?
- python - 如何让这个程序无限循环,直到输入特定的整数 4?
- php - Laravel 多个 where 子句通过变量检查空值
- java - Hibernate with H2 在建立实体管理器时出现错误(Eclipse/Java)
- java - Windows 上多线程 Java 应用程序的 CPU 使用率过低
- c# - 为什么自签名 PFX X509Certificate2 私钥会引发 NotSupportedException?
- node.js - Node.js PGAdmin 谷歌云连接
- oracle-sqldeveloper - 在 oracle 中与新用户建立连接时出错