最近有一个需求要把 markdown 文件解析并展示到页面中,要求有目录有样式。
先看一眼实现效果:
样式用的是 github 风格的 markdown 样式:github-markdown-css
markdown 解析 + 目录用的是:
代码实现
先说一下 react-markdown 这个插件,用它来解析 markdown 并不能完全解析,还要用 remark-gfm 辅助解析表格,删除线,脚注等,官方给出的解释如下:
用于启用 GitHub 添加的 Markdown 扩展:自动链接文字(
www.x.com
)、脚注([^1]
)、删除线(~~stuff~~
)、表格(| cell |…
)和任务列表(* [x]
)。您可以使用此插件添加对解析和序列化它们的支持。GitHub 对 CommonMark 的这些扩展称为GFM(GitHub Flavored Markdown)。
这两个插件作者相同,另外还有其他的辅助插件,有需要可以去官方文档看一下。
目录是用 markdown-navbar 这个插件生成的,个人觉得效果非常完美,但是据观察此插件只能用在 react 项目中。
vue 项目可以用vue-markdown 试一下,我实验过,这个插件可以实现解析,样式和目录,但是目录细节不完善,没有点击,滚动追随等高亮效果,选项有很多,可以自行了解。
另外:github-markdown-css 插件我是直接放的css外链,当然也可以使用npm的方式添加。
主要代码:
import React, { Component } from 'react';
import ReactMarkdown from 'react-markdown'; // 解析 markdown
import remarkGfm from 'remark-gfm'; // markdown 对表格/删除线/脚注等的支持
import MarkNav from 'markdown-navbar'; // markdown 目录
import 'markdown-navbar/dist/navbar.css';
class App extends Component {
constructor(props) {
super(props)
this.state = {
SourceData: ''
}
}
componentDidMount() {
var $this = this;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
$this.setState({
SourceData: xmlhttp.responseText
})
}
}
// 文件目录在 public/static/test.md 这里不需要写 public 因为打包之后没有此目录。
xmlhttp.open("GET", "/static/test.md", true);
xmlhttp.send();
}
render() {
return (
<div className="App">
<div className="leftSide">
<MarkNav
className="toc-list"
source={this.state.SourceData}
ordered={true}
/>
</div>
<div
className="markdown-body content">
<ReactMarkdown
children={this.state.SourceData}
remarkPlugins={[remarkGfm]}
/>
</div>
</div>
);
}
}
export default App;
结语
总结一下,github-markdown-css 是作为单独的样式用的,markdown-navbar 只用在react中生成 markdown 目录,至于解析 markdown 文件,其实有很多轮子,比如:marked,react-markdown,vue-markdown等。
如果需要目录,react 中 markdown-navbar 的目录功能能全面。vue 中 vue-markdown 这一个插件就足够了,目录和样式他都有,只是目前来看细节的地方不是那么完善,但是也够用了。
以上这些插件和实现效果是我尝试过的,当然还有其他插件可以实现同等的效果,欢迎探讨。