Added flowchart diagrams (#510)

Co-authored-by: Tilman Vatteroth <tilman.vatteroth@tu-dortmund.de>
Co-authored-by: mrdrogdrog <mr.drogdrog@gmail.com>
Co-authored-by: Erik Michelson <github@erik.michelson.eu>
This commit is contained in:
Philip Molares 2020-08-29 23:56:27 +02:00 committed by GitHub
parent d482065d72
commit 33648f1645
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 118 additions and 0 deletions

View file

@ -41,6 +41,7 @@
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "4.2.1",
"eslint-plugin-standard": "4.0.1",
"flowchart.js": "1.14.0",
"fork-awesome": "1.1.7",
"github-markdown-css": "4.0.0",
"highlight.js": "10.1.2",

View file

@ -3,6 +3,11 @@
"slogan": "The best platform to write and share markdown.",
"title": "Collaborative markdown notes"
},
"renderer": {
"flowchart": {
"invalidSyntax": "Invalid flowchart.js syntax!"
}
},
"landing": {
"intro": {
"exploreFeatures": "Explore all features",

View file

@ -9,6 +9,20 @@ opengraph:
# Embedding demo
[TOC]
## Flowchart
\`\`\`flow
st=>start: Start
e=>end: End
op=>operation: My Operation
op2=>operation: lalala
cond=>condition: Yes or No?
st->op->op2->cond
cond(yes)->e
cond(no)->op2
\`\`\`
## CSV
\`\`\`csv delimiter=; header

View file

@ -57,6 +57,7 @@ import { replaceYouTubeLink } from './regex-plugins/replace-youtube-link'
import { AsciinemaReplacer } from './replace-components/asciinema/asciinema-replacer'
import { ComponentReplacer, SubNodeConverter } from './replace-components/ComponentReplacer'
import { CsvReplacer } from './replace-components/csv/csv-replacer'
import { FlowchartReplacer } from './replace-components/flow/flowchart-replacer'
import { GistReplacer } from './replace-components/gist/gist-replacer'
import { HighlightedCodeReplacer } from './replace-components/highlighted-fence/highlighted-fence-replacer'
import { ImageReplacer } from './replace-components/image/image-replacer'
@ -311,6 +312,7 @@ export const MarkdownRenderer: React.FC<MarkdownRendererProps> = ({ content, onM
new ImageReplacer(),
new TocReplacer(),
new CsvReplacer(),
new FlowchartReplacer(),
new HighlightedCodeReplacer(),
new QuoteOptionsReplacer(),
new KatexReplacer()

View file

@ -0,0 +1,16 @@
import { DomElement } from 'domhandler'
import React from 'react'
import { ComponentReplacer } from '../ComponentReplacer'
import { FlowChart } from './flowchart/flowchart'
export class FlowchartReplacer implements ComponentReplacer {
getReplacement (codeNode: DomElement, index: number): React.ReactElement | undefined {
if (codeNode.name !== 'code' || !codeNode.attribs || !codeNode.attribs['data-highlight-language'] || codeNode.attribs['data-highlight-language'] !== 'flow' || !codeNode.children || !codeNode.children[0]) {
return
}
const code = codeNode.children[0].data as string
return <FlowChart key={`flowchart-${index}`} code={code}/>
}
}

View file

@ -0,0 +1,48 @@
import { parse } from 'flowchart.js'
import React, { useEffect, useRef, useState } from 'react'
import { Alert } from 'react-bootstrap'
import { Trans, useTranslation } from 'react-i18next'
export interface FlowChartProps {
code: string
}
export const FlowChart: React.FC<FlowChartProps> = ({ code }) => {
const diagramRef = useRef<HTMLDivElement>(null)
const [error, setError] = useState(false)
useTranslation()
useEffect(() => {
if (diagramRef.current === null) {
return
}
const parserOutput = parse(code)
try {
parserOutput.drawSVG(diagramRef.current, {
'line-width': 2,
fill: 'none',
'font-size': '16px',
'font-family': 'Source Code Pro, twemoji, monospace'
})
setError(false)
} catch (error) {
setError(true)
}
const currentDiagramRef = diagramRef.current
return () => {
Array.from(currentDiagramRef.children).forEach(value => value.remove())
}
}, [code])
if (error) {
return (
<Alert variant={'danger'}>
<Trans i18nKey={'renderer.flowchart.invalidSyntax'}/>
</Alert>
)
}
return <div ref={diagramRef} className={'text-center'}/>
}

View file

@ -0,0 +1,13 @@
declare module 'flowchart.js' {
type Options = {
'line-width': number,
'fill': string,
'font-size': string,
'font-family': string
}
type ParseOutput = {
clean: () => void,
drawSVG: (container: HTMLElement, options: Options) => void,
}
export const parse: (code: string) => ParseOutput
}

View file

@ -5225,6 +5225,11 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
eve-raphael@0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/eve-raphael/-/eve-raphael-0.5.0.tgz#17c754b792beef3fa6684d79cf5a47c63c4cda30"
integrity sha1-F8dUt5K+7z+maE15z1pHxjxM2jA=
eventemitter2@^6.4.2:
version "6.4.3"
resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.3.tgz#35c563619b13f3681e7eb05cbdaf50f56ba58820"
@ -5659,6 +5664,13 @@ flatten@^1.0.2:
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b"
integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==
flowchart.js@1.14.0:
version "1.14.0"
resolved "https://registry.yarnpkg.com/flowchart.js/-/flowchart.js-1.14.0.tgz#b468501be54aa279bada8ec5da222e9eec542492"
integrity sha512-XpXh6v2EUWJ1FyHdwFX1aZKLRpZXZmkMNcqVAV3dbIAmWGW++Oop31SpZRA/cJ8yaFjM16GZl/tb768fG8mBmg==
dependencies:
raphael "2.3.0"
flush-write-stream@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8"
@ -10367,6 +10379,13 @@ range-parser@^1.2.1, range-parser@~1.2.1:
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
raphael@2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/raphael/-/raphael-2.3.0.tgz#eabeb09dba861a1d4cee077eaafb8c53f3131f89"
integrity sha512-w2yIenZAQnp257XUWGni4bLMVxpUpcIl7qgxEgDIXtmSypYtlNxfXWpOBxs7LBTps5sDwhRnrToJrMUrivqNTQ==
dependencies:
eve-raphael "0.5.0"
raw-body@2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332"