React中渲染Markdown
最近使用React渲染Markdown,进行了一些简单的探索,和大家分享下相关经验。
基本的Markdown能力
当下有许多成熟的Markdown库,如 marked、react-markdown等,这里我采用的是react-markdown。因其与React有更好的结合。
react-markdown地址:https://www.npmjs.com/package/react-markdown
其用法也比较简单:
1import React from 'react' 2import Markdown from 'react-markdown' 3 4export default props => ( 5 <Markdown 6 source={props.content} 7 /> 8)
代码语法高亮
如果不做任何配置,React-Markdown会使用 <pre>
包裹Markdown中的代码块。
这样虽然也能正常显示,但是没有了语法高亮的功能,不够美观。
好在React-Markdown中提供了自定义renderer的功能,可以自定义渲染逻辑。
首先,在React-Markdown中配置下使用自定义渲染引擎:
1import React from 'react' 2import Markdown from 'react-markdown' 3 4const CodeBlock = ({ language, value }) => <pre>{value}</pre> 5 6export default props => ( 7 <Markdown 8 source={props.content} 9 renderers={{ code: CodeBlock }} 10 /> 11)
这里我们配置了使用CodeBlock
来渲染代码块,目前还是在使用pre进行渲染。
然后,再在CodeBlock
中加上语法高亮的支持。
1import React from 'react' 2import Markdown from 'react-markdown' 3import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' 4import { solarizedlight as codeStyle } from 'react-syntax-highlighter/dist/cjs/styles/prism' 5 6const CodeBlock = ({ language, value }) => ( 7 <SyntaxHighlighter language={language} style={codeStyle}> 8 {value} 9 </SyntaxHighlighter> 10) 11 12export default props => ( 13 <Markdown 14 source={props.content} 15 renderers={{ code: CodeBlock }} 16 /> 17)
这里使用了react-syntax-highlighter
库来做语法高亮支持。
它支持多套主题,具体可配置项参考其官方文档。
React Syntax Highlighter地址: https://www.npmjs.com/package/react-syntax-highlighter
流程图支持
有一套名为Mermaid的流程图库,可在Markdown中直接使用,但是目前在各平台的支持度不同步,React-Markdown中也没有默认支持它。
使用Mermaid可以在Markdown中使用指令画出流程图、类图、甘特图、状态图等多种图表,方便好用,具体用法可参考其官方网站。
Mermaid官方网站:https://mermaid-js.github.io/mermaid/#/
Mermaid是一套JS库,可以在网页中直接加载使用,我们可以稍微修改下CodeBlock
组件,对其进行支持。
首先,在页面中加载mermaid.min.js,并启用自动渲染功能。
可直接将其写入 html 文件中:
1<script src="//unpkg.com/mermaid@8.4.8/dist/mermaid.min.js"></script> 2<script>mermaid.initialize({startOnLoad:true});</script>
如果写在React中,则需要处理下{}字符:
1<script src='//unpkg.com/mermaid@8.4.8/dist/mermaid.min.js' /> 2<script>mermaid.initialize({'{startOnLoad: true}'});</script>
在开启startOnLoad: true
之后,Mermaid会自动处理className中带有mermaid
的tag。
因此,CodeBlock
中可以做如下的修改:
1import React from 'react' 2import Markdown from 'react-markdown' 3import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' 4import { solarizedlight as codeStyle } from 'react-syntax-highlighter/dist/cjs/styles/prism' 5 6const CodeBlock = ({ language, value }) => ( 7 language === 'mermaid' 8 ? return <div className='mermaid'>{value}</div> 9 : <SyntaxHighlighter language={language} style={codeStyle}> 10 {value} 11 </SyntaxHighlighter> 12) 13 14export default props => ( 15 <Markdown 16 source={props.content} 17 renderers={{ code: CodeBlock }} 18 /> 19)
至此,大功告成。
最后,放个示例mermaid,大家看看效果:
1graph TB 2 c1-->a2 3 subgraph one 4 a1-->a2 5 end 6 subgraph two 7 b1-->b2 8 end 9 subgraph three 10 c1-->c2 11 end