diff --git a/frontend/package.json b/frontend/package.json index 8b7fe0e7..fb3bc20f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,6 +16,7 @@ "highlight.js": "^9.12.0", "markdown-it": "^8.4.0", "markdown-it-task-lists": "^2.1.0", + "mermaid": "^7.1.2", "monaco-editor": "^0.10.1", "normalize.css": "^7.0.0", "vue": "^2.5.2", diff --git a/frontend/src/components/MermaidPlugin.js b/frontend/src/components/MermaidPlugin.js new file mode 100644 index 00000000..a4514daf --- /dev/null +++ b/frontend/src/components/MermaidPlugin.js @@ -0,0 +1,56 @@ +import mermaid from 'mermaid' + +const mermaidChart = (code) => { + try { + mermaid.parse(code) + return `
${code}
` + } catch ({ str, hash }) { + return `
${str}
` + } +} + +const MermaidPlugin = (md) => { + md.mermaid = mermaid + mermaid.loadPreferences = (preferenceStore) => { + let mermaidTheme = preferenceStore.get('mermaid-theme') + if (mermaidTheme === undefined) { + mermaidTheme = 'default' + } + let ganttAxisFormat = preferenceStore.get('gantt-axis-format') + if (ganttAxisFormat === undefined) { + ganttAxisFormat = '%Y-%m-%d' + } + mermaid.initialize({ + theme: mermaidTheme, + gantt: { axisFormatter: [ + [ganttAxisFormat, (d) => { + return d.getDay() === 1 + }] + ]} + }) + return { + 'mermaid-theme': mermaidTheme, + 'gantt-axis-format': ganttAxisFormat + } + } + + const temp = md.renderer.rules.fence.bind(md.renderer.rules) + md.renderer.rules.fence = (tokens, idx, options, env, slf) => { + const token = tokens[idx] + const code = token.content.trim() + if (token.info === 'mermaid') { + return mermaidChart(code) + } + const firstLine = code.split(/\n/)[0].trim() + if (firstLine === 'gantt' || firstLine === 'sequenceDiagram' || firstLine.match(/^graph (?:TB|BT|RL|LR|TD);?$/)) { + return mermaidChart(code) + } + return temp(tokens, idx, options, env, slf) + } +} + +MermaidPlugin.update = () => { + mermaid.init() +} + +export default MermaidPlugin diff --git a/frontend/src/components/View.vue b/frontend/src/components/View.vue index d5aaa6ed..a0a2d186 100644 --- a/frontend/src/components/View.vue +++ b/frontend/src/components/View.vue @@ -8,6 +8,7 @@ import 'highlight.js/styles/github-gist.css' import Markdown from 'markdown-it' import TaskLists from 'markdown-it-task-lists' import Highlight from 'highlight.js' +import MermaidPlugin from './MermaidPlugin' export default { name: 'xview', @@ -28,7 +29,7 @@ export default { return '' } - }).use(TaskLists) + }).use(TaskLists).use(MermaidPlugin) } }, mounted () { @@ -37,6 +38,7 @@ export default { methods: { render (val) { this.$refs.view.innerHTML = this.markdown.render(val) + MermaidPlugin.update() } }, watch: { diff --git a/frontend/yarn.lock b/frontend/yarn.lock index e9d4614c..13afd6fa 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -1737,12 +1737,32 @@ cyclist@~0.2.2: version "0.2.2" resolved "http://registry.npm.taobao.org/cyclist/download/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" +d3@3.5.17: + version "3.5.17" + resolved "http://registry.npm.taobao.org/d3/download/d3-3.5.17.tgz#bc46748004378b21a360c9fc7cf5231790762fb8" + d@1: version "1.0.0" resolved "http://registry.npm.taobao.org/d/download/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" dependencies: es5-ext "^0.10.9" +dagre-d3-renderer@^0.4.25: + version "0.4.26" + resolved "http://registry.npm.taobao.org/dagre-d3-renderer/download/dagre-d3-renderer-0.4.26.tgz#648a491209b853ae96ddf3fea41a1f104479a5a1" + dependencies: + d3 "3.5.17" + dagre-layout "^0.8.0" + graphlib "^2.1.1" + lodash "^4.17.4" + +dagre-layout@^0.8.0: + version "0.8.4" + resolved "http://registry.npm.taobao.org/dagre-layout/download/dagre-layout-0.8.4.tgz#ec436c01a5a2c1e6709fcf31860aa4e026a2f5e9" + dependencies: + graphlib "^2.1.5" + lodash "^4.17.5" + dashdash@^1.12.0: version "1.14.1" resolved "http://registry.npm.taobao.org/dashdash/download/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -2819,6 +2839,12 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2: version "4.1.11" resolved "http://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" +graphlib@^2.1.1, graphlib@^2.1.5: + version "2.1.5" + resolved "http://registry.npm.taobao.org/graphlib/download/graphlib-2.1.5.tgz#6afe1afcc5148555ec799e499056795bd6938c87" + dependencies: + lodash "^4.11.1" + growly@^1.3.0: version "1.3.0" resolved "http://registry.npm.taobao.org/growly/download/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -2928,7 +2954,7 @@ hawk@3.1.3, hawk@~3.1.3: hoek "2.x.x" sntp "1.x.x" -he@1.1.x, he@^1.1.0: +he@1.1.x, he@^1.1.0, he@^1.1.1: version "1.1.1" resolved "http://registry.npm.taobao.org/he/download/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" @@ -3638,6 +3664,10 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "http://registry.npm.taobao.org/lodash.uniq/download/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" +lodash@^4.11.1, lodash@^4.17.5: + version "4.17.5" + resolved "http://registry.npm.taobao.org/lodash/download/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" + lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0: version "4.17.4" resolved "http://registry.npm.taobao.org/lodash/download/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -3769,6 +3799,17 @@ merge-descriptors@1.0.1: version "1.0.1" resolved "http://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" +mermaid@^7.1.2: + version "7.1.2" + resolved "http://registry.npm.taobao.org/mermaid/download/mermaid-7.1.2.tgz#6265728156c2e0891e004cba60a44022174487ad" + dependencies: + d3 "3.5.17" + dagre-d3-renderer "^0.4.25" + dagre-layout "^0.8.0" + he "^1.1.1" + lodash "^4.17.4" + moment "^2.20.1" + methods@~1.1.2: version "1.1.2" resolved "http://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -3896,6 +3937,10 @@ mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdi dependencies: minimist "0.0.8" +moment@^2.20.1: + version "2.20.1" + resolved "http://registry.npm.taobao.org/moment/download/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd" + monaco-editor@^0.10.1: version "0.10.1" resolved "http://registry.npm.taobao.org/monaco-editor/download/monaco-editor-0.10.1.tgz#8c96c4f15b6b5258bf92cbde93cad8a7e3007e14"