diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.spec.js b/packages/mermaid/src/diagrams/flowchart/flowDb.spec.ts similarity index 89% rename from packages/mermaid/src/diagrams/flowchart/flowDb.spec.js rename to packages/mermaid/src/diagrams/flowchart/flowDb.spec.ts index 6f04ca70a..68c03bdeb 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowDb.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/flowDb.spec.ts @@ -1,14 +1,15 @@ import flowDb from './flowDb.js'; +import type { FlowSubGraph } from './types.js'; describe('flow db subgraphs', () => { - let subgraphs; + let subgraphs: FlowSubGraph[]; beforeEach(() => { subgraphs = [ { nodes: ['a', 'b', 'c', 'e'] }, { nodes: ['f', 'g', 'h'] }, { nodes: ['i', 'j'] }, { nodes: ['k'] }, - ]; + ] as FlowSubGraph[]; }); describe('exist', () => { it('should return true when the is exists in a subgraph', () => { @@ -25,17 +26,17 @@ describe('flow db subgraphs', () => { describe('makeUniq', () => { it('should remove ids from sungraph that already exists in another subgraph even if it gets empty', () => { - const subgraph = flowDb.makeUniq({ nodes: ['i', 'j'] }, subgraphs); + const subgraph = flowDb.makeUniq({ nodes: ['i', 'j'] } as FlowSubGraph, subgraphs); expect(subgraph.nodes).toEqual([]); }); it('should remove ids from sungraph that already exists in another subgraph', () => { - const subgraph = flowDb.makeUniq({ nodes: ['i', 'j', 'o'] }, subgraphs); + const subgraph = flowDb.makeUniq({ nodes: ['i', 'j', 'o'] } as FlowSubGraph, subgraphs); expect(subgraph.nodes).toEqual(['o']); }); it('should not remove ids from subgraph if they are unique', () => { - const subgraph = flowDb.makeUniq({ nodes: ['q', 'r', 's'] }, subgraphs); + const subgraph = flowDb.makeUniq({ nodes: ['q', 'r', 's'] } as FlowSubGraph, subgraphs); expect(subgraph.nodes).toEqual(['q', 'r', 's']); }); diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.js b/packages/mermaid/src/diagrams/flowchart/flowDb.ts similarity index 74% rename from packages/mermaid/src/diagrams/flowchart/flowDb.js rename to packages/mermaid/src/diagrams/flowchart/flowDb.ts index 899345b6e..f7ee54ab1 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowDb.js +++ b/packages/mermaid/src/diagrams/flowchart/flowDb.ts @@ -12,38 +12,38 @@ import { setDiagramTitle, getDiagramTitle, } from '../common/commonDb.js'; +import type { FlowVertex, FlowClass, FlowSubGraph, FlowText, FlowEdge, FlowLink } from './types.js'; const MERMAID_DOM_ID_PREFIX = 'flowchart-'; let vertexCounter = 0; let config = getConfig(); -let vertices = {}; -let edges = []; -let classes = {}; -let subGraphs = []; -let subGraphLookup = {}; -let tooltips = {}; +let vertices: Record = {}; +let edges: FlowEdge[] & { defaultInterpolate?: string; defaultStyle?: string[] } = []; +let classes: Record = {}; +let subGraphs: FlowSubGraph[] = []; +let subGraphLookup: Record = {}; +let tooltips: Record = {}; let subCount = 0; let firstGraphFlag = true; -let direction; +let direction: string; -let version; // As in graph +let version: string; // As in graph // Functions to be run after graph rendering -let funs = []; +let funs: ((element: Element) => void)[] = []; -const sanitizeText = (txt) => common.sanitizeText(txt, config); +const sanitizeText = (txt: string) => common.sanitizeText(txt, config); /** * Function to lookup domId from id in the graph definition. * - * @param id - * @public + * @param id - id of the node */ -export const lookUpDomId = function (id) { - const veritceKeys = Object.keys(vertices); - for (const veritceKey of veritceKeys) { - if (vertices[veritceKey].id === id) { - return vertices[veritceKey].domId; +export const lookUpDomId = function (id: string) { + const vertexKeys = Object.keys(vertices); + for (const vertexKey of vertexKeys) { + if (vertices[vertexKey].id === id) { + return vertices[vertexKey].domId; } } return id; @@ -52,30 +52,24 @@ export const lookUpDomId = function (id) { /** * Function called by parser when a node definition has been found * - * @param _id - * @param text - * @param textObj - * @param type - * @param style - * @param classes - * @param dir - * @param props */ -export const addVertex = function (_id, textObj, type, style, classes, dir, props = {}) { +export const addVertex = function ( + id: string, + textObj: FlowText, + type: 'group', + style: string[], + classes: string[], + dir: string, + props = {} +) { + if (!id || id.trim().length === 0) { + return; + } let txt; - let id = _id; - if (id === undefined) { - return; - } - if (id.trim().length === 0) { - return; - } - - // if (id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id; if (vertices[id] === undefined) { vertices[id] = { - id: id, + id, labelType: 'text', domId: MERMAID_DOM_ID_PREFIX + id + '-' + vertexCounter, styles: [], @@ -94,7 +88,7 @@ export const addVertex = function (_id, textObj, type, style, classes, dir, prop vertices[id].text = txt; } else { if (vertices[id].text === undefined) { - vertices[id].text = _id; + vertices[id].text = id; } } if (type !== undefined) { @@ -123,20 +117,12 @@ export const addVertex = function (_id, textObj, type, style, classes, dir, prop /** * Function called by parser when a link/edge definition has been found * - * @param _start - * @param _end - * @param type - * @param linkText - * @param linkTextObj */ -export const addSingleLink = function (_start, _end, type) { - let start = _start; - let end = _end; - // if (start[0].match(/\d/)) start = MERMAID_DOM_ID_PREFIX + start; - // if (end[0].match(/\d/)) end = MERMAID_DOM_ID_PREFIX + end; - // log.info('Got edge...', start, end); +export const addSingleLink = function (_start: string, _end: string, type: any) { + const start = _start; + const end = _end; - const edge = { start: start, end: end, type: undefined, text: '', labelType: 'text' }; + const edge: FlowEdge = { start: start, end: end, type: undefined, text: '', labelType: 'text' }; log.info('abc78 Got edge...', edge); const linkTextObj = type.text; @@ -153,13 +139,11 @@ export const addSingleLink = function (_start, _end, type) { if (type !== undefined) { edge.type = type.type; edge.stroke = type.stroke; - edge.length = type.length; - } - if (edge?.length > 10) { - edge.length = 10; + edge.length = type.length > 10 ? 10 : type.length; } + if (edges.length < (config.maxEdges ?? 500)) { - log.info('abc78 pushing edge...'); + log.info('Pushing edge...'); edges.push(edge); } else { throw new Error( @@ -171,12 +155,12 @@ You have to call mermaid.initialize.` ); } }; -export const addLink = function (_start, _end, type) { - log.info('addLink (abc78)', _start, _end, type); - let i, j; - for (i = 0; i < _start.length; i++) { - for (j = 0; j < _end.length; j++) { - addSingleLink(_start[i], _end[j], type); + +export const addLink = function (_start: string[], _end: string[], type: unknown) { + log.info('addLink', _start, _end, type); + for (const start of _start) { + for (const end of _end) { + addSingleLink(start, end, type); } } }; @@ -184,15 +168,16 @@ export const addLink = function (_start, _end, type) { /** * Updates a link's line interpolation algorithm * - * @param positions - * @param interp */ -export const updateLinkInterpolate = function (positions, interp) { +export const updateLinkInterpolate = function ( + positions: ('default' | number)[], + interpolate: string +) { positions.forEach(function (pos) { if (pos === 'default') { - edges.defaultInterpolate = interp; + edges.defaultInterpolate = interpolate; } else { - edges[pos].interpolate = interp; + edges[pos].interpolate = interpolate; } }); }; @@ -200,12 +185,10 @@ export const updateLinkInterpolate = function (positions, interp) { /** * Updates a link with a style * - * @param positions - * @param style */ -export const updateLink = function (positions, style) { +export const updateLink = function (positions: ('default' | number)[], style: string[]) { positions.forEach(function (pos) { - if (pos >= edges.length) { + if (typeof pos === 'number' && pos >= edges.length) { throw new Error( `The index ${pos} for linkStyle is out of bounds. Valid indices for linkStyle are between 0 and ${ edges.length - 1 @@ -223,7 +206,7 @@ export const updateLink = function (positions, style) { }); }; -export const addClass = function (ids, style) { +export const addClass = function (ids: string, style: string[]) { ids.split(',').forEach(function (id) { if (classes[id] === undefined) { classes[id] = { id, styles: [], textStyles: [] }; @@ -244,9 +227,8 @@ export const addClass = function (ids, style) { /** * Called by parser when a graph definition is found, stores the direction of the chart. * - * @param dir */ -export const setDirection = function (dir) { +export const setDirection = function (dir: string) { direction = dir; if (direction.match(/.* { + +export const setGen = (ver: string) => { version = ver || 'gen-2'; }; -/** @returns {string} */ + export const defaultStyle = function () { return 'fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;'; }; -/** - * Clears the internal graph db so that a new graph can be parsed. - * - * @param _id - * @param list - * @param _title - */ -export const addSubGraph = function (_id, list, _title) { - let id = _id.text.trim(); +export const addSubGraph = function ( + _id: { text: string }, + list: string[], + _title: { text: string; type: string } +) { + let id: string | undefined = _id.text.trim(); let title = _title.text; if (_id === _title && _title.text.match(/\s/)) { id = undefined; } - /** @param a */ - function uniq(a) { - const prims = { boolean: {}, number: {}, string: {} }; - const objs = []; + + function uniq(a: any[]) { + const prims: any = { boolean: {}, number: {}, string: {} }; + const objs: any[] = []; let dir; // = undefined; direction.trim(); const nodeList = a.filter(function (item) { @@ -512,10 +491,7 @@ export const addSubGraph = function (_id, list, _title) { return { nodeList, dir }; } - let nodeList = []; - - const { nodeList: nl, dir } = uniq(nodeList.concat.apply(nodeList, list)); - nodeList = nl; + const { nodeList, dir } = uniq(list.flat()); if (version === 'gen-1') { for (let i = 0; i < nodeList.length; i++) { nodeList[i] = lookUpDomId(nodeList[i]); @@ -523,7 +499,6 @@ export const addSubGraph = function (_id, list, _title) { } id = id || 'subGraph' + subCount; - // if (id[0].match(/\d/)) id = lookUpDomId(id); title = title || ''; title = sanitizeText(title); subCount = subCount + 1; @@ -538,19 +513,6 @@ export const addSubGraph = function (_id, list, _title) { log.info('Adding', subGraph.id, subGraph.nodes, subGraph.dir); - /** Deletes an id from all subgraphs */ - // const del = _id => { - // subGraphs.forEach(sg => { - // const pos = sg.nodes.indexOf(_id); - // if (pos >= 0) { - // sg.nodes.splice(pos, 1); - // } - // }); - // }; - - // // Removes the members of this subgraph from any other subgraphs, a node only belong to one subgraph - // subGraph.nodes.forEach(_id => del(_id)); - // Remove the members in the new subgraph if they already belong to another subgraph subGraph.nodes = makeUniq(subGraph, subGraphs).nodes; subGraphs.push(subGraph); @@ -558,7 +520,7 @@ export const addSubGraph = function (_id, list, _title) { return id; }; -const getPosForId = function (id) { +const getPosForId = function (id: string) { for (const [i, subGraph] of subGraphs.entries()) { if (subGraph.id === id) { return i; @@ -567,12 +529,15 @@ const getPosForId = function (id) { return -1; }; let secCount = -1; -const posCrossRef = []; -const indexNodes2 = function (id, pos) { +const posCrossRef: number[] = []; +const indexNodes2 = function (id: string, pos: number): { result: boolean; count: number } { const nodes = subGraphs[pos].nodes; secCount = secCount + 1; if (secCount > 2000) { - return; + return { + result: false, + count: 0, + }; } posCrossRef[secCount] = pos; // Check if match @@ -608,13 +573,13 @@ const indexNodes2 = function (id, pos) { }; }; -export const getDepthFirstPos = function (pos) { +export const getDepthFirstPos = function (pos: number) { return posCrossRef[pos]; }; export const indexNodes = function () { secCount = -1; if (subGraphs.length > 0) { - indexNodes2('none', subGraphs.length - 1, 0); + indexNodes2('none', subGraphs.length - 1); } }; @@ -630,7 +595,7 @@ export const firstGraph = () => { return false; }; -const destructStartLink = (_str) => { +const destructStartLink = (_str: string): FlowLink => { let str = _str.trim(); let type = 'arrow_open'; @@ -662,7 +627,7 @@ const destructStartLink = (_str) => { return { type, stroke }; }; -const countChar = (char, str) => { +const countChar = (char: string, str: string) => { const length = str.length; let count = 0; for (let i = 0; i < length; ++i) { @@ -673,7 +638,7 @@ const countChar = (char, str) => { return count; }; -const destructEndLink = (_str) => { +const destructEndLink = (_str: string) => { const str = _str.trim(); let line = str.slice(0, -1); let type = 'arrow_open'; @@ -713,7 +678,7 @@ const destructEndLink = (_str) => { stroke = 'invisible'; } - let dots = countChar('.', line); + const dots = countChar('.', line); if (dots) { stroke = 'dotted'; @@ -723,7 +688,7 @@ const destructEndLink = (_str) => { return { type, stroke, length }; }; -export const destructLink = (_str, _startStr) => { +export const destructLink = (_str: string, _startStr: string) => { const info = destructEndLink(_str); let startInfo; if (_startStr) { @@ -757,7 +722,7 @@ export const destructLink = (_str, _startStr) => { }; // Todo optimizer this by caching existing nodes -const exists = (allSgs, _id) => { +const exists = (allSgs: FlowSubGraph[], _id: string) => { let res = false; allSgs.forEach((sg) => { const pos = sg.nodes.indexOf(_id); @@ -770,11 +735,9 @@ const exists = (allSgs, _id) => { /** * Deletes an id from all subgraphs * - * @param sg - * @param allSubgraphs */ -const makeUniq = (sg, allSubgraphs) => { - const res = []; +const makeUniq = (sg: FlowSubGraph, allSubgraphs: FlowSubGraph[]) => { + const res: string[] = []; sg.nodes.forEach((_id, pos) => { if (!exists(allSubgraphs, _id)) { res.push(sg.nodes[pos]); @@ -786,6 +749,7 @@ const makeUniq = (sg, allSubgraphs) => { export const lex = { firstGraph, }; + export default { defaultConfig: () => defaultConfig.flowchart, setAccTitle, diff --git a/packages/mermaid/src/diagrams/flowchart/parser/backup b/packages/mermaid/src/diagrams/flowchart/parser/backup deleted file mode 100644 index 2248ea2ac..000000000 --- a/packages/mermaid/src/diagrams/flowchart/parser/backup +++ /dev/null @@ -1,503 +0,0 @@ -/** mermaid - * https://mermaidjs.github.io/ - * (c) 2015 Knut Sveidqvist - * MIT license. - */ - -/* lexical grammar */ -%lex -%x string - -%% -\%\%[^\n]* /* do nothing */ -["] this.begin("string"); -["] this.popState(); -[^"]* return "STR"; -"style" return 'STYLE'; -"default" return 'DEFAULT'; -"linkStyle" return 'LINKSTYLE'; -"interpolate" return 'INTERPOLATE'; -"classDef" return 'CLASSDEF'; -"class" return 'CLASS'; -"click" return 'CLICK'; -"graph" return 'GRAPH'; -"subgraph" return 'subgraph'; -"end"\b\s* return 'end'; -"LR" return 'DIR'; -"RL" return 'DIR'; -"TB" return 'DIR'; -"BT" return 'DIR'; -"TD" return 'DIR'; -"BR" return 'DIR'; -[0-9]+ return 'NUM'; -\# return 'BRKT'; -":" return 'COLON'; -";" return 'SEMI'; -"," return 'COMMA'; -"*" return 'MULT'; -\s*\-\-[x]\s* return 'ARROW_CROSS'; -\s*[x]\-\-[x]\s* return 'DOUBLE_ARROW_CROSS'; -\s*\-\-\>\s* return 'ARROW_POINT'; -\s*\<\-\-\>\s* return 'DOUBLE_ARROW_POINT'; -\s*\-\-[o]\s* return 'ARROW_CIRCLE'; -\s*[o]\-\-[o]\s* return 'DOUBLE_ARROW_CIRCLE'; -\s*\-\-\-\s* return 'ARROW_OPEN'; -\s*\-\.\-[x]\s* return 'DOTTED_ARROW_CROSS'; -\s*[x]\-\.\-[x]\s* return 'DOUBLE_DOTTED_ARROW_CROSS'; -\s*\-\.\-\>\s* return 'DOTTED_ARROW_POINT'; -\s*\<\-\.\-\>\s* return 'DOUBLE_DOTTED_ARROW_POINT'; -\s*\-\.\-[o]\s* return 'DOTTED_ARROW_CIRCLE'; -\s*[o]\-\.\-[o]\s* return 'DOUBLE_DOTTED_ARROW_CIRCLE'; -\s*\-\.\-\s* return 'DOTTED_ARROW_OPEN'; -\s*.\-[x]\s* return 'DOTTED_ARROW_CROSS'; -\s*[x].\-[x]\s* return 'DOUBLE_DOTTED_ARROW_CROSS'; -\s*\.\-\>\s* return 'DOTTED_ARROW_POINT'; -\s*\<\.\-\>\s* return 'DOUBLE_DOTTED_ARROW_POINT'; -\s*\.\-[o]\s* return 'DOTTED_ARROW_CIRCLE'; -\s*[o]\.\-[o]\s* return 'DOUBLE_DOTTED_ARROW_CIRCLE'; -\s*\.\-\s* return 'DOTTED_ARROW_OPEN'; -\s*\=\=[x]\s* return 'THICK_ARROW_CROSS'; -\s*[x]\=\=[x]\s* return 'DOUBLE_THICK_ARROW_CROSS'; -\s*\=\=\>\s* return 'THICK_ARROW_POINT'; -\s*\<\=\=\>\s* return 'DOUBLE_THICK_ARROW_POINT'; -\s*\=\=[o]\s* return 'THICK_ARROW_CIRCLE'; -\s*[o]\=\=[o]\s* return 'DOUBLE_THICK_ARROW_CIRCLE'; -\s*\=\=[\=]\s* return 'THICK_ARROW_OPEN'; -\s*\-\-\s* return '--'; -\s*\-\.\s* return '-.'; -\s*\=\=\s* return '=='; -%\s*\<\-\-\s* return 'START_DOUBLE_ARROW_POINT'; -%\s*\[x]\-\-\s* return 'START_DOUBLE_ARROW_CROSS'; -%\s*\[o]\-\-\s* return 'START_DOUBLE_ARROW_CIRCLE'; -%\s*\<\-\.\s* return 'START_DOUBLE_DOTTED_ARROW_POINT'; -%\s*\[x]\-\.\s* return 'START_DOUBLE_DOTTED_ARROW_CROSS'; -%\s*\[o]\-\.\s* return 'START_DOUBLE_DOTTED_ARROW_CIRCLE'; -%\s*\<\=\=\s* return 'START_DOUBLE_THICK_ARROW_POINT'; -%\s*\[x]\=\=\s* return 'START_DOUBLE_THICK_ARROW_CROSS'; -%\s*\[o]\=\=\s* return 'START_DOUBLE_THICK_ARROW_CIRCLE'; -"(-" return '(-'; -"-)" return '-)'; -\- return 'MINUS'; -"." return 'DOT'; -\+ return 'PLUS'; -\% return 'PCT'; -"=" return 'EQUALS'; -\= return 'EQUALS'; -"<" return 'TAGSTART'; -">" return 'TAGEND'; -"^" return 'UP'; -"v" return 'DOWN'; -[A-Za-z]+ return 'ALPHA'; -[!"#$%&'*+,-.`?\\_/] return 'PUNCTUATION'; -[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]| -[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]| -[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]| -[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]| -[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]| -[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]| -[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]| -[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]| -[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]| -[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]| -[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]| -[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]| -[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]| -[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]| -[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]| -[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]| -[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]| -[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]| -[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]| -[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]| -[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]| -[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]| -[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]| -[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]| -[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]| -[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]| -[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]| -[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]| -[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]| -[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]| -[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]| -[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]| -[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]| -[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]| -[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]| -[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]| -[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]| -[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]| -[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]| -[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]| -[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]| -[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]| -[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]| -[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]| -[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]| -[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]| -[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]| -[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]| -[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]| -[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]| -[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]| -[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]| -[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]| -[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]| -[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]| -[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]| -[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]| -[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]| -[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]| -[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]| -[\uFFD2-\uFFD7\uFFDA-\uFFDC] - return 'UNICODE_TEXT'; -"|" return 'PIPE'; -"(" return 'PS'; -")" return 'PE'; -"[" return 'SQS'; -"]" return 'SQE'; -"{" return 'DIAMOND_START' -"}" return 'DIAMOND_STOP' -"\"" return 'QUOTE'; -\n+ return 'NEWLINE'; -\s return 'SPACE'; -<> return 'EOF'; - -/lex - -/* operator associations and precedence */ - -%left '^' - -%start mermaidDoc - -%% /* language grammar */ - -mermaidDoc: graphConfig document; - -document - : /* empty */ - { $$ = [];} - | document line - { - if($2 !== []){ - $1.push($2); - } - $$=$1;} - ; - -line - : statement - {$$=$1;} - | SEMI - | NEWLINE - | SPACE - | EOF - ; - -graphConfig - : SPACE graphConfig - | NEWLINE graphConfig - | GRAPH SPACE DIR FirstStmtSeperator - { yy.setDirection($3);$$ = $3;} - | GRAPH SPACE TAGEND FirstStmtSeperator - { yy.setDirection("LR");$$ = $3;} - | GRAPH SPACE TAGSTART FirstStmtSeperator - { yy.setDirection("RL");$$ = $3;} - | GRAPH SPACE UP FirstStmtSeperator - { yy.setDirection("BT");$$ = $3;} - | GRAPH SPACE DOWN FirstStmtSeperator - { yy.setDirection("TB");$$ = $3;} - ; - -ending: endToken ending - | endToken - ; - -endToken: NEWLINE | SPACE | EOF; - -FirstStmtSeperator - : SEMI | NEWLINE | spaceList NEWLINE ; - - -spaceListNewline - : SPACE spaceListNewline - | NEWLINE spaceListNewline - | NEWLINE - | SPACE - ; - - -spaceList - : SPACE spaceList - | SPACE - ; - -statement - : verticeStatement separator - {$$=$1} - | styleStatement separator - {$$=[];} - | linkStyleStatement separator - {$$=[];} - | classDefStatement separator - {$$=[];} - | classStatement separator - {$$=[];} - | clickStatement separator - {$$=[];} - | subgraph SPACE alphaNum SQS text SQE separator document end - {$$=yy.addSubGraph($3,$8,$5);} - | subgraph SPACE STR separator document end - {$$=yy.addSubGraph(undefined,$5,$3);} - | subgraph SPACE alphaNum separator document end - {$$=yy.addSubGraph($3,$5,$3);} - | subgraph separator document end - {$$=yy.addSubGraph(undefined,$3,undefined);} - ; - -separator: NEWLINE | SEMI | EOF ; - -verticeStatement: - vertex link vertex - { yy.addLink($1,$3,$2);$$ = [$1,$3];} - | vertex - {$$ = [$1];} - ; - -vertex: alphaNum SQS text SQE - {$$ = $1;yy.addVertex($1,$3,'square');} - | alphaNum SQS text SQE spaceList - {$$ = $1;yy.addVertex($1,$3,'square');} - | alphaNum PS PS text PE PE - {$$ = $1;yy.addVertex($1,$4,'circle');} - | alphaNum PS PS text PE PE spaceList - {$$ = $1;yy.addVertex($1,$4,'circle');} - | alphaNum '(-' text '-)' - {$$ = $1;yy.addVertex($1,$3,'ellipse');} - | alphaNum '(-' text '-)' spaceList - {$$ = $1;yy.addVertex($1,$3,'ellipse');} - | alphaNum PS text PE - {$$ = $1;yy.addVertex($1,$3,'round');} - | alphaNum PS text PE spaceList - {$$ = $1;yy.addVertex($1,$3,'round');} - | alphaNum DIAMOND_START text DIAMOND_STOP - {$$ = $1;yy.addVertex($1,$3,'diamond');} - | alphaNum DIAMOND_START text DIAMOND_STOP spaceList - {$$ = $1;yy.addVertex($1,$3,'diamond');} - | alphaNum TAGEND text SQE - {$$ = $1;yy.addVertex($1,$3,'odd');} - | alphaNum TAGEND text SQE spaceList - {$$ = $1;yy.addVertex($1,$3,'odd');} -/* | alphaNum SQS text TAGSTART - {$$ = $1;yy.addVertex($1,$3,'odd_right');} - | alphaNum SQS text TAGSTART spaceList - {$$ = $1;yy.addVertex($1,$3,'odd_right');} */ - | alphaNum - {$$ = $1;yy.addVertex($1);} - | alphaNum spaceList - {$$ = $1;yy.addVertex($1);} - ; - -alphaNum - : alphaNumStatement - {$$=$1;} - | alphaNum alphaNumStatement - {$$=$1+''+$2;} - ; - -alphaNumStatement - : DIR - {$$=$1;} - | alphaNumToken - {$$=$1;} - | DOWN - {$$='v';} - | MINUS - {$$='-';} - ; - -link: linkStatement arrowText - {$1.text = $2;$$ = $1;} - | linkStatement TESTSTR SPACE - {$1.text = $2;$$ = $1;} - | linkStatement arrowText SPACE - {$1.text = $2;$$ = $1;} - | linkStatement - {$$ = $1;} - | '--' text ARROW_POINT - {$$ = {"type":"arrow","stroke":"normal","text":$2};} - | 'START_DOUBLE_ARROW_POINT' text ARROW_POINT - {$$ = {"type":"double_arrow_point","stroke":"normal","text":$2};} - | '--' text ARROW_CIRCLE - {$$ = {"type":"arrow_circle","stroke":"normal","text":$2};} - | '--' text ARROW_CROSS - {$$ = {"type":"arrow_cross","stroke":"normal","text":$2};} - | '--' text ARROW_OPEN - {$$ = {"type":"arrow_open","stroke":"normal","text":$2};} - | '-.' text DOTTED_ARROW_POINT - {$$ = {"type":"arrow","stroke":"dotted","text":$2};} - | '-.' text DOTTED_ARROW_CIRCLE - {$$ = {"type":"arrow_circle","stroke":"dotted","text":$2};} - | '-.' text DOTTED_ARROW_CROSS - {$$ = {"type":"arrow_cross","stroke":"dotted","text":$2};} - | '-.' text DOTTED_ARROW_OPEN - {$$ = {"type":"arrow_open","stroke":"dotted","text":$2};} - | '==' text THICK_ARROW_POINT - {$$ = {"type":"arrow","stroke":"thick","text":$2};} - | '==' text THICK_ARROW_CIRCLE - {$$ = {"type":"arrow_circle","stroke":"thick","text":$2};} - | '==' text THICK_ARROW_CROSS - {$$ = {"type":"arrow_cross","stroke":"thick","text":$2};} - | '==' text THICK_ARROW_OPEN - {$$ = {"type":"arrow_open","stroke":"thick","text":$2};} - ; - -linkStatement: ARROW_POINT - {$$ = {"type":"arrow","stroke":"normal"};} - | DOUBLE_ARROW_POINT - {$$ = {"type":"double_arrow_point","stroke":"normal"};} - | ARROW_CIRCLE - {$$ = {"type":"arrow_circle","stroke":"normal"};} -% | DOUBLE_ARROW_CIRCLE -% {$$ = {"type":"double_arrow_circle","stroke":"normal"};} - | ARROW_CROSS - {$$ = {"type":"arrow_cross","stroke":"normal"};} - % | DOUBLE_ARROW_CROSS - % {$$ = {"type":"double_arrow_cross","stroke":"normal"};} - | ARROW_OPEN - {$$ = {"type":"arrow_open","stroke":"normal"};} - | DOTTED_ARROW_POINT - {$$ = {"type":"arrow","stroke":"dotted"};} -% | DOUEBL_DOTTED_ARROW_POINT -% {$$ = {"type":"doueble_arrow_point","stroke":"dotted"};} - | DOTTED_ARROW_CIRCLE - {$$ = {"type":"arrow_circle","stroke":"dotted"};} -% | DOTTED_ARROW_CIRCLE -% {$$ = {"type":"double_arrow_circle","stroke":"dotted"};} - | DOTTED_ARROW_CROSS - {$$ = {"type":"arrow_cross","stroke":"dotted"};} -% | DOTTED_ARROW_CROSS -% {$$ = {"type":"double_arrow_cross","stroke":"dotted"};} - | DOTTED_ARROW_OPEN - {$$ = {"type":"arrow_open","stroke":"dotted"};} - | THICK_ARROW_POINT - {$$ = {"type":"arrow","stroke":"thick"};} -% | THICK_ARROW_POINT -% {$$ = {"type":"double_arrow_point","stroke":"thick"};} - | THICK_ARROW_CIRCLE - {$$ = {"type":"arrow_circle","stroke":"thick"};} -% | THICK_ARROW_CIRCLE -% {$$ = {"type":"double_arrow_circle","stroke":"thick"};} - | THICK_ARROW_CROSS - {$$ = {"type":"arrow_cross","stroke":"thick"};} -% | THICK_ARROW_CROSS -% {$$ = {"type":"double_arrow_cross","stroke":"thick"};} - | THICK_ARROW_OPEN - {$$ = {"type":"arrow_open","stroke":"thick"};} - ; - -arrowText: - PIPE text PIPE - {$$ = $2;} - ; - -text: textToken - {$$=$1;} - | text textToken - {$$=$1+''+$2;} - | STR - {$$=$1;} - ; - - - -commentText: commentToken - {$$=$1;} - | commentText commentToken - {$$=$1+''+$2;} - ; - - -keywords - : STYLE | LINKSTYLE | CLASSDEF | CLASS | CLICK | GRAPH | DIR | subgraph | end | DOWN | UP; - - -textNoTags: textNoTagsToken - {$$=$1;} - | textNoTags textNoTagsToken - {$$=$1+''+$2;} - ; - - -classDefStatement:CLASSDEF SPACE DEFAULT SPACE stylesOpt - {$$ = $1;yy.addClass($3,$5);} - | CLASSDEF SPACE alphaNum SPACE stylesOpt - {$$ = $1;yy.addClass($3,$5);} - ; - -classStatement:CLASS SPACE alphaNum SPACE alphaNum - {$$ = $1;yy.setClass($3, $5);} - ; - -clickStatement - : CLICK SPACE alphaNum SPACE alphaNum {$$ = $1;yy.setClickEvent($3, $5, undefined);} - | CLICK SPACE alphaNum SPACE alphaNum SPACE STR {$$ = $1;yy.setClickEvent($3, $5, $7) ;} - | CLICK SPACE alphaNum SPACE STR {$$ = $1;yy.setLink($3, $5, undefined);} - | CLICK SPACE alphaNum SPACE STR SPACE STR {$$ = $1;yy.setLink($3, $5, $7 );} - ; - -styleStatement:STYLE SPACE alphaNum SPACE stylesOpt - {$$ = $1;yy.addVertex($3,undefined,undefined,$5);} - | STYLE SPACE HEX SPACE stylesOpt - {$$ = $1;yy.updateLink($3,$5);} - ; - -linkStyleStatement - : LINKSTYLE SPACE DEFAULT SPACE stylesOpt - {$$ = $1;yy.updateLink([$3],$5);} - | LINKSTYLE SPACE numList SPACE stylesOpt - {$$ = $1;yy.updateLink($3,$5);} - | LINKSTYLE SPACE DEFAULT SPACE INTERPOLATE SPACE alphaNum SPACE stylesOpt - {$$ = $1;yy.updateLinkInterpolate([$3],$7);yy.updateLink([$3],$9);} - | LINKSTYLE SPACE numList SPACE INTERPOLATE SPACE alphaNum SPACE stylesOpt - {$$ = $1;yy.updateLinkInterpolate($3,$7);yy.updateLink($3,$9);} - | LINKSTYLE SPACE DEFAULT SPACE INTERPOLATE SPACE alphaNum - {$$ = $1;yy.updateLinkInterpolate([$3],$7);} - | LINKSTYLE SPACE numList SPACE INTERPOLATE SPACE alphaNum - {$$ = $1;yy.updateLinkInterpolate($3,$7);} - ; - -commentStatement: PCT PCT commentText; - -numList: NUM - {$$ = [$1]} - | numList COMMA NUM - {$1.push($3);$$ = $1;} - ; - -stylesOpt: style - {$$ = [$1]} - | stylesOpt COMMA style - {$1.push($3);$$ = $1;} - ; - -style: styleComponent - |style styleComponent - {$$ = $1 + $2;} - ; - -styleComponent: ALPHA | COLON | MINUS | NUM | UNIT | SPACE | HEX | BRKT | DOT | STYLE | PCT ; - -/* Token lists */ - -commentToken : textToken | graphCodeTokens ; - -textToken : textNoTagsToken | TAGSTART | TAGEND | '==' | '--' | PCT | DEFAULT; - -textNoTagsToken: alphaNumToken | SPACE | MINUS | keywords ; - -alphaNumToken : ALPHA | PUNCTUATION | UNICODE_TEXT | NUM | COLON | COMMA | PLUS | EQUALS | MULT | DOT | BRKT ; - -graphCodeTokens: PIPE | PS | PE | SQS | SQE | DIAMOND_START | DIAMOND_STOP | TAG_START | TAG_END | ARROW_CROSS | ARROW_POINT | ARROW_CIRCLE | ARROW_OPEN | QUOTE | SEMI ; -%% diff --git a/packages/mermaid/src/diagrams/flowchart/types.ts b/packages/mermaid/src/diagrams/flowchart/types.ts new file mode 100644 index 000000000..954759f39 --- /dev/null +++ b/packages/mermaid/src/diagrams/flowchart/types.ts @@ -0,0 +1,53 @@ +export interface FlowVertex { + classes: string[]; + dir?: string; + domId: string; + haveCallback?: boolean; + id: string; + labelType: 'text'; + link?: string; + linkTarget?: string; + props?: any; + styles: string[]; + text?: string; + type?: string; +} + +export interface FlowText { + text: string; + type: 'text'; +} + +export interface FlowEdge { + start: string; + end: string; + interpolate?: string; + type?: string; + stroke?: string; + style?: string[]; + length?: number; + text: string; + labelType: 'text'; +} + +export interface FlowClass { + id: string; + styles: string[]; + textStyles: string[]; +} + +export interface FlowSubGraph { + classes: string[]; + dir?: string; + id: string; + labelType: string; + nodes: string[]; + title: string; +} + +export interface FlowLink { + length?: number; + stroke: string; + type: string; + text?: string; +}