React中渲染Markdown

最近使用React渲染Markdown,进行了一些简单的探索,和大家分享下相关经验。

基本的Markdown能力

当下有许多成熟的Markdown库,如 marked、react-markdown等,这里我采用的是react-markdown。因其与React有更好的结合。

react-markdown地址:https://www.npmjs.com/package/react-markdown

其用法也比较简单:

import React from 'react'
import Markdown from 'react-markdown'

export default props => (
  <Markdown
    source={props.content}
  />
)

代码语法高亮

如果不做任何配置,React-Markdown会使用 <pre>包裹Markdown中的代码块。

这样虽然也能正常显示,但是没有了语法高亮的功能,不够美观。

好在React-Markdown中提供了自定义renderer的功能,可以自定义渲染逻辑。

首先,在React-Markdown中配置下使用自定义渲染引擎:

import React from 'react'
import Markdown from 'react-markdown'

const CodeBlock = ({ language, value }) => <pre>{value}</pre>

export default props => (
  <Markdown
    source={props.content}
    renderers={{ code: CodeBlock }}
  />
)

这里我们配置了使用CodeBlock来渲染代码块,目前还是在使用pre进行渲染。

然后,再在CodeBlock中加上语法高亮的支持。

import React from 'react'
import Markdown from 'react-markdown'
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
import { solarizedlight as codeStyle } from 'react-syntax-highlighter/dist/cjs/styles/prism'

const CodeBlock = ({ language, value }) => (
  <SyntaxHighlighter language={language} style={codeStyle}>
    {value}
  </SyntaxHighlighter>
)

export default props => (
  <Markdown
    source={props.content}
    renderers={{ code: CodeBlock }}
  />
)

这里使用了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 文件中:

<script src="//unpkg.com/mermaid@8.4.8/dist/mermaid.min.js"></script>
<script>mermaid.initialize({startOnLoad:true});</script>

如果写在React中,则需要处理下{}字符:

<script src='//unpkg.com/mermaid@8.4.8/dist/mermaid.min.js' />
<script>mermaid.initialize({'{startOnLoad: true}'});</script>

在开启startOnLoad: true之后,Mermaid会自动处理className中带有mermaid的tag。

因此,CodeBlock中可以做如下的修改:

import React from 'react'
import Markdown from 'react-markdown'
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
import { solarizedlight as codeStyle } from 'react-syntax-highlighter/dist/cjs/styles/prism'

const CodeBlock = ({ language, value }) => (
  language === 'mermaid'
    ? return <div className='mermaid'>{value}</div>
    : <SyntaxHighlighter language={language} style={codeStyle}>
      {value}
    </SyntaxHighlighter>
)

export default props => (
  <Markdown
    source={props.content}
    renderers={{ code: CodeBlock }}
  />
)

至此,大功告成。

最后,放个示例mermaid,大家看看效果:

graph TB c1-->a2 subgraph one a1-->a2 end subgraph two b1-->b2 end subgraph three c1-->c2 end

0条评论