From 6a89e28e1e7641f27867e7681dd3f89ae4667bb0 Mon Sep 17 00:00:00 2001 From: Nikolay Rozhkov Date: Thu, 6 Jul 2023 21:57:47 +0300 Subject: [PATCH] Started railroad diagrams --- __mocks__/railroadRenderer.js | 13 +++++ .../integration/rendering/railroad.spec.ts | 0 demos/index.html | 4 +- demos/railroad.html | 32 ++++++++++++ .../src/diagram-api/diagram-orchestration.ts | 4 +- .../src/diagrams/railroad/railroadDB.ts | 13 +++++ .../src/diagrams/railroad/railroadDetector.ts | 22 ++++++++ .../src/diagrams/railroad/railroadDiagram.ts | 15 ++++++ .../diagrams/railroad/railroadParser.jison | 46 ++++++++++++++++ .../src/diagrams/railroad/railroadRenderer.ts | 52 +++++++++++++++++++ .../diagrams/railroad/railroadTests.spec.ts | 25 +++++++++ .../src/diagrams/railroad/railroadTypes.ts | 5 ++ .../mermaid/src/docs/.vitepress/config.ts | 1 + packages/mermaid/src/docs/syntax/railroad.md | 0 14 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 __mocks__/railroadRenderer.js create mode 100644 cypress/integration/rendering/railroad.spec.ts create mode 100644 demos/railroad.html create mode 100644 packages/mermaid/src/diagrams/railroad/railroadDB.ts create mode 100644 packages/mermaid/src/diagrams/railroad/railroadDetector.ts create mode 100644 packages/mermaid/src/diagrams/railroad/railroadDiagram.ts create mode 100644 packages/mermaid/src/diagrams/railroad/railroadParser.jison create mode 100644 packages/mermaid/src/diagrams/railroad/railroadRenderer.ts create mode 100644 packages/mermaid/src/diagrams/railroad/railroadTests.spec.ts create mode 100644 packages/mermaid/src/diagrams/railroad/railroadTypes.ts create mode 100644 packages/mermaid/src/docs/syntax/railroad.md diff --git a/__mocks__/railroadRenderer.js b/__mocks__/railroadRenderer.js new file mode 100644 index 000000000..cf0c9dcfa --- /dev/null +++ b/__mocks__/railroadRenderer.js @@ -0,0 +1,13 @@ +/** + * Mocked Railroad diagram renderer + */ + +import { vi } from 'vitest'; + +export const draw = vi.fn().mockImplementation(() => { + return ''; +}); + +export default { + draw, +}; diff --git a/cypress/integration/rendering/railroad.spec.ts b/cypress/integration/rendering/railroad.spec.ts new file mode 100644 index 000000000..e69de29bb diff --git a/demos/index.html b/demos/index.html index 24c4fbf3b..9d39c9e4c 100644 --- a/demos/index.html +++ b/demos/index.html @@ -7,7 +7,6 @@ @@ -78,6 +77,9 @@
  • Sankey

  • +
  • +

    Railroad

    +
  • diff --git a/demos/railroad.html b/demos/railroad.html new file mode 100644 index 000000000..435e999a2 --- /dev/null +++ b/demos/railroad.html @@ -0,0 +1,32 @@ + + + + + + Railroad Mermaid Quick Test Page + + + + + +

    Railroad diagram demos

    +

    Example

    +
    +      railroad-beta
    +    
    + + + + diff --git a/packages/mermaid/src/diagram-api/diagram-orchestration.ts b/packages/mermaid/src/diagram-api/diagram-orchestration.ts index 9c03e27f3..402b03665 100644 --- a/packages/mermaid/src/diagram-api/diagram-orchestration.ts +++ b/packages/mermaid/src/diagram-api/diagram-orchestration.ts @@ -21,6 +21,7 @@ import mindmap from '../diagrams/mindmap/detector.js'; import sankey from '../diagrams/sankey/sankeyDetector.js'; import { registerLazyLoadedDiagrams } from './detectType.js'; import { registerDiagram } from './diagramAPI.js'; +import { railroad } from '../diagrams/railroad/railroadDetector.js'; let hasLoadedDiagrams = false; export const addDiagrams = () => { @@ -81,6 +82,7 @@ export const addDiagrams = () => { state, journey, quadrantChart, - sankey + sankey, + railroad ); }; diff --git a/packages/mermaid/src/diagrams/railroad/railroadDB.ts b/packages/mermaid/src/diagrams/railroad/railroadDB.ts new file mode 100644 index 000000000..5ef453006 --- /dev/null +++ b/packages/mermaid/src/diagrams/railroad/railroadDB.ts @@ -0,0 +1,13 @@ +import type { RailroadDB } from './railroadTypes.js'; + +import { + clear as commonClear, +} from '../../commonDb.js'; + +const clear = (): void => { + commonClear(); +}; + +export const db: RailroadDB = { + clear, +}; diff --git a/packages/mermaid/src/diagrams/railroad/railroadDetector.ts b/packages/mermaid/src/diagrams/railroad/railroadDetector.ts new file mode 100644 index 000000000..9b8725d90 --- /dev/null +++ b/packages/mermaid/src/diagrams/railroad/railroadDetector.ts @@ -0,0 +1,22 @@ +import type { + DiagramDetector, + DiagramLoader, + ExternalDiagramDefinition, +} from '../../diagram-api/types.js'; + +const id = 'railroad'; + +const detector: DiagramDetector = (txt) => { + return /^\s*railroad-beta/.test(txt); +}; + +const loader: DiagramLoader = async () => { + const { diagram } = await import('./railroadDiagram.js'); + return { id, diagram }; +}; + +export const railroad: ExternalDiagramDefinition = { + id, + detector, + loader, +}; diff --git a/packages/mermaid/src/diagrams/railroad/railroadDiagram.ts b/packages/mermaid/src/diagrams/railroad/railroadDiagram.ts new file mode 100644 index 000000000..0cead2d77 --- /dev/null +++ b/packages/mermaid/src/diagrams/railroad/railroadDiagram.ts @@ -0,0 +1,15 @@ +import { DiagramDefinition } from '../../diagram-api/types.js'; +// @ts-ignore: jison doesn't export types +import parser from './railroadParser.jison'; +import { db } from './railroadDB.js'; +import renderer from './railroadRenderer.js'; +// import { prepareTextForParsing } from './railroadUtils.js'; + +// const originalParse = parser.parse.bind(parser); +// parser.parse = (text: string) => originalParse(prepareTextForParsing(text)); + +export const diagram: DiagramDefinition = { + parser, + db, + renderer, +}; diff --git a/packages/mermaid/src/diagrams/railroad/railroadParser.jison b/packages/mermaid/src/diagrams/railroad/railroadParser.jison new file mode 100644 index 000000000..ded0de27a --- /dev/null +++ b/packages/mermaid/src/diagrams/railroad/railroadParser.jison @@ -0,0 +1,46 @@ +/* + Mermaid + https://mermaid.js.org/ + MIT license. +*/ + +//------------------ +// Lexical analysis +//------------------ + +%lex + +// Pre lexer steps + +%{ +%} + +// Start conditions +%x diagram + +// Definitions +DIAGRAM_KEYWORD "railroad-beta" + +%% + +// Tokenization +DIAGRAM_KEYWORD { this.pushState('diagram'); return 'DIAGRAM_KEYWORD'; } +\s+ {} +<> { return 'EOF' } // match end of file + +/lex + +//----------------- +// Syntax analysis +//----------------- + +// Configuration + +%start start + +%% + +// Grammar + +start: DIAGRAM_KEYWORD EOF; + diff --git a/packages/mermaid/src/diagrams/railroad/railroadRenderer.ts b/packages/mermaid/src/diagrams/railroad/railroadRenderer.ts new file mode 100644 index 000000000..7dca207f2 --- /dev/null +++ b/packages/mermaid/src/diagrams/railroad/railroadRenderer.ts @@ -0,0 +1,52 @@ +import { Diagram } from '../../Diagram.js'; +import * as configApi from '../../config.js'; +import type { DrawDefinition, HTML, SVG } from '../../diagram-api/types.js'; +import { select } from 'd3'; +// import { configureSvgSize } from '../../setupGraphViewbox.js'; +// import { Uid } from '../../rendering-util/uid.js'; + +const fetchSVGElement = (id: string): SVG => { + // Get config + const { securityLevel } = configApi.getConfig(); + + // Handle root and document for when rendering in sandbox mode + let sandboxElement: HTML | undefined; + let document: Document | null | undefined; + if (securityLevel === 'sandbox') { + sandboxElement = select('#i' + id); + document = sandboxElement.nodes()[0].contentDocument; + } + + // @ts-ignore - figure out how to assign HTML to document type + const root: HTML = (sandboxElement && document) ? select(document) : select('body'); + const svg: SVG = root.select('#' + id); + return svg; +} + +/** + * Draws Railroad diagram. + * + * @param text - The text of the diagram + * @param id - The id of the diagram which will be used as a DOM element id¨ + * @param _version - Mermaid version from package.json + * @param diagObj - A standard diagram containing the db and the text and type etc of the diagram + */ +export const draw: DrawDefinition = (text: string, id: string, _version: string, diagObj: Diagram): void => { + const svg: SVG = fetchSVGElement(id); + + // const defaultRailroadConfig = configApi!.defaultConfig!.railroad!; + // Establish svg dimensions and get width and height + // + // const width = conf?.width || defaultRailroadConfig.width!; + // const height = conf?.height || defaultRailroadConfig.width!; + // const useMaxWidth = conf?.useMaxWidth || defaultRailroadConfig.useMaxWidth!; + + // configureSvgSize(svg, height, width, useMaxWidth); + + // Compute layout + // +}; + +export default { + draw, +}; diff --git a/packages/mermaid/src/diagrams/railroad/railroadTests.spec.ts b/packages/mermaid/src/diagrams/railroad/railroadTests.spec.ts new file mode 100644 index 000000000..32686ac4b --- /dev/null +++ b/packages/mermaid/src/diagrams/railroad/railroadTests.spec.ts @@ -0,0 +1,25 @@ +// @ts-ignore: jison doesn't export types +import railroad from './railroad.jison'; +// import { prepareTextForParsing } from '../railroadUtils.js'; +import * as fs from 'fs'; +import * as path from 'path'; +import { cleanupComments } from '../../diagram-api/comments.js'; +import { db } from './railroadDB.js'; + +describe('Railroad diagram', function () { + describe('when parsing an info graph it', function () { + beforeEach(function () { + railroad.parser.yy = db; + railroad.parser.yy.clear(); + }); + + it('parses csv', async () => { + const csv = path.resolve(__dirname, './energy.csv'); + const data = fs.readFileSync(csv, 'utf8'); + // const graphDefinition = prepareTextForParsing(cleanupComments('railroad-beta\n\n ' + data)); + const graphDefinition = cleanupComments('railroad-beta\n\n ' + data); + + railroad.parser.parse(graphDefinition); + }); + }); +}); diff --git a/packages/mermaid/src/diagrams/railroad/railroadTypes.ts b/packages/mermaid/src/diagrams/railroad/railroadTypes.ts new file mode 100644 index 000000000..c5a4cc0ee --- /dev/null +++ b/packages/mermaid/src/diagrams/railroad/railroadTypes.ts @@ -0,0 +1,5 @@ +import type { DiagramDB } from '../../diagram-api/types.js'; + +export interface RailroadDB extends DiagramDB { + clear: () => void; +} diff --git a/packages/mermaid/src/docs/.vitepress/config.ts b/packages/mermaid/src/docs/.vitepress/config.ts index 1d609c13e..72edc14ef 100644 --- a/packages/mermaid/src/docs/.vitepress/config.ts +++ b/packages/mermaid/src/docs/.vitepress/config.ts @@ -144,6 +144,7 @@ function sidebarSyntax() { { text: 'Timeline 🔥', link: '/syntax/timeline' }, { text: 'Zenuml 🔥', link: '/syntax/zenuml' }, { text: 'Sankey 🔥', link: '/syntax/sankey' }, + { text: 'Railroad 🔥', link: '/syntax/railroad' }, { text: 'Other Examples', link: '/syntax/examples' }, ], }, diff --git a/packages/mermaid/src/docs/syntax/railroad.md b/packages/mermaid/src/docs/syntax/railroad.md new file mode 100644 index 000000000..e69de29bb