marked.js结合mermaid.js实现markdown支持甘特图等显示

zmisgod 发布于 2019-1-13 19:48:01 阅读 130 评论 0

起因

上周马哥给我们介绍了evernote中甘特图,十分强大,不仅仅有甘特图,还有流程图,序列图。

有道云笔记也支持这种功能(必须是markdown模式才会有下面的按钮)

image

通过简简单单的markdown代码就可以实现了图形化。于是我在github上搜了一下,发现真的有js实现了类似的功能,这个js就是:mermaid.js 我找到后,发现mermaid.js也可以实现上述三种图。立即给一个star,太牛了。

因为本站使用的markdown转HTML采用的是marked.js。所以只要实现在marked.js中添加相应的hook,当markdown中有甘特图这类的标识出现,就直接用mermaid.js进行渲染即可。

寻找解决办法

看了mermaid的文档,官方已经给了解决办法,也就是如果在``` ``` 中发现有mermaid可以渲染的图形代码,就将其渲染成<div class="mermaid"></div>即可,否则就渲染成<pre><code></code></pre>

代码(涉及到nuxt.js中ssr的渲染)

import marked from 'marked'
export default {
  data() {
    return {
      content:
        '## zmisgod \n\n```\ngraph LR\nA-->B\nB-->C\nC-->A\nD-->C\n```\n正常情况下,我们不建议使用嵌套的 Dialog,如果需要在页面上同时显示多个 Dialog,可以将它们平级放置。对于确实需要嵌套 Dialog 的场景,我们提供了append-to-body属性。将内层 Dialog 的该属性设置为 true,它就会插入至 body 元素上,从而保证内外层 Dialog 和遮罩层级关系的正确。\n\n正常情况下,我们不建议使用嵌套的 Dialog,如果需要在页面上同时显示多个 Dialog,可以将它们平级放置。对于确实需要嵌套 Dialog 的场景,我们提供了append-to-body属性。将内层 Dialog 的该属性设置为 true,它就会插入至 body 元素上,从而保证内外层 Dialog 和遮罩层级关系的正确。\n\n'
    }
  },
  created() {
    if (process.client) {
      let mermaid = require('mermaid')
      mermaid.initialize({ startOnLoad: true, theme: 'forest' })
    }
    var renderer = new marked.Renderer()
    renderer.code = function(code, language) {
      if (code.match(/^sequenceDiagram/) || code.match(/^graph/)) {
        return '<div class="mermaid">' + code + '</div>'
      } else {
        return '<pre><code>' + code + '</code></pre>'
      }
    }
    this.content = marked(this.content, { renderer: renderer })
  }
}

效果:

markdown

image

## zmisgod \n\n```\ngraph LR\nA-->B\nB-->C\nC-->A\nD-->C\n```\n正常情况下,我们不建议使用嵌套的 Dialog,如果需要在页面上同时显示多个 Dialog,可以将它们平级放置。对于确实需要嵌套 Dialog 的场景,我们提供了append-to-body属性。将内层 Dialog 的该属性设置为 true,它就会插入至 body 元素上,从而保证内外层 Dialog 和遮罩层级关系的正确。\n\n正常情况下,我们不建议使用嵌套的 Dialog,如果需要在页面上同时显示多个 Dialog,可以将它们平级放置。对于确实需要嵌套 Dialog 的场景,我们提供了append-to-body属性。将内层 Dialog 的该属性设置为 true,它就会插入至 body 元素上,从而保证内外层 Dialog 和遮罩层级关系的正确。\n\n

渲染结果

image