diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 1b1ccd685..e19d53ae4 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -58,13 +58,8 @@
-stateDiagram-v2 - [*] --> Still - Still --> [*] - Still --> Moving - Moving --> Still - Moving --> Crash - Crash --> [*]
flowchart RL diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts index a0c97fc0f..bec5c33c3 100644 --- a/packages/mermaid/src/diagrams/block/blockDB.ts +++ b/packages/mermaid/src/diagrams/block/blockDB.ts @@ -1,6 +1,6 @@ // import type { BlockDB } from './blockTypes.js'; import type { DiagramDB } from '../../diagram-api/types.js'; -import { BlockConfig } from './blockTypes.js'; +import { BlockConfig, BlockType, Block, Link } from './blockTypes.js'; import * as configApi from '../../config.js'; // import common from '../common/common.js'; @@ -13,47 +13,78 @@ import { // getDiagramTitle, clear as commonClear, } from '../../commonDb.js'; +import { log } from '../../logger.js'; // export type TBlockColumnsDefaultValue = 'H'; // Do we support something else, like 'auto' | 0? +// Initialize the node database for simple lookups +let nodeDatabase: Record= {}; +const blockDatabase: Record = {}; + +// Function to get a node by its ID +export const getNodeById = (id: string): Node | undefined => { + return nodeDatabase[id]; +}; + // TODO: Convert to generic TreeNode type? Convert to class? -export interface Block { - ID: string; - label?: string; - parent?: Block; - children?: Block[]; - columns?: number; // | TBlockColumnsDefaultValue; -} -export interface Link { - source: Block; - target: Block; -} - -let rootBlocks: Block[] = []; +let rootBlock = { ID: 'root', children: [] as Block[], columns: -1 }; let blocks: Block[] = []; const links: Link[] = []; -let rootBlock = { ID: 'root', children: [], columns: -1 } as Block; -let currentBlock: Block | undefined; +// let rootBlock = { ID: 'root', children: [], columns: -1 } as Block; +let currentBlock = rootBlock; const clear = (): void => { - rootBlocks = []; - blocks = []; + log.info('Clear called'); + // rootBlocks = []; + blocks = [] as Block[]; commonClear(); rootBlock = { ID: 'root', children: [], columns: -1 }; currentBlock = rootBlock; + nodeDatabase = {}; + blockDatabase[rootBlock.ID] = rootBlock; }; -type IAddBlock = (block: Block) => Block; -const addBlock: IAddBlock = (block: Block, parent?: Block): Block => { - if (parent) { - parent.children ??= []; - parent.children.push(block); - } else { - rootBlocks.push(block); +// type IAddBlock = (block: Block) => Block; +// const addBlock: IAddBlock = (block: Block, parent?: Block): Block => { +// log.info('addBlock', block, parent); +// if (parent) { +// parent.children ??= []; +// parent.children.push(block); +// } else { +// rootBlock.children.push(block); +// } +// blocks.push(block); +// return block; +// }; + +type ITypeStr2Type = (typeStr: string) => BlockType; +export function typeStr2Type(typeStr: string) { + // TODO: add all types + switch (typeStr) { + case '[]': + return 'square'; + case '()': + return 'round'; + default: + return 'square'; } - blocks.push(block); - return block; +} + +type IAddBlock = (id: string, label: string, type: BlockType) => Block; +// Function to add a node to the database +export const addBlock = (id: string, _label?: string, type?: BlockType) => { + log.info('addNode called:', id, _label, type); + const label = _label || id; + const node: Block = { + ID: id, + label, + type: type || 'square', + }; + blockDatabase[node.ID] = node; + currentBlock.children ??= []; + currentBlock.children.push(node); + return node; }; type IAddLink = (link: Link) => Link; @@ -84,16 +115,21 @@ const getBlock = (id: string, blocks: Block[]): Block | undefined => { type IGetColumns = (blockID: string) => number; const getColumns = (blockID: string): number => { - const blocks = [rootBlock]; - const block = getBlock(blockID, blocks); + const block = blockDatabase[blockID]; if (!block) { return -1; } - return block.columns || -1; + if (block.columns) { + return block.columns; + } + if (!block.children) { + return -1; + } + return block.children.length; }; type IGetBlocks = () => Block[]; -const getBlocks: IGetBlocks = () => blocks; +const getBlocks: IGetBlocks = () => rootBlock.children || []; type IGetLinks = () => Link[]; const getLinks: IGetLinks = () => links; @@ -111,12 +147,14 @@ export interface BlockDB extends DiagramDB { getLinks: IGetLinks; setColumns: ISetColumns; getColumns: IGetColumns; + typeStr2Type: ITypeStr2Type; } const db: BlockDB = { getConfig: () => configApi.getConfig().block, addBlock: addBlock, addLink: addLink, + typeStr2Type: typeStr2Type, getLogger, // TODO: remove getBlocks, getLinks, diff --git a/packages/mermaid/src/diagrams/block/blockTypes.ts b/packages/mermaid/src/diagrams/block/blockTypes.ts index c190c5779..b373d6b9c 100644 --- a/packages/mermaid/src/diagrams/block/blockTypes.ts +++ b/packages/mermaid/src/diagrams/block/blockTypes.ts @@ -3,3 +3,36 @@ import type { BaseDiagramConfig } from '../../config.type.js'; export interface BlockConfig extends BaseDiagramConfig { padding?: number; } + +export type BlockType = + | 'round' + | 'square' + | 'diamond' + | 'hexagon' + | 'odd' + | 'lean_right' + | 'lean_left' + | 'trapezoid' + | 'inv_trapezoid' + | 'odd_right' + | 'circle' + | 'ellipse' + | 'stadium' + | 'subroutine' + | 'cylinder' + | 'group' + | 'doublecircle'; + +export interface Block { + ID: string; + label?: string; + parent?: Block; + type?: BlockType; + children?: Block[]; + columns?: number; // | TBlockColumnsDefaultValue; +} + +export interface Link { + source: Block; + target: Block; +} diff --git a/packages/mermaid/src/diagrams/block/parser/block.jison b/packages/mermaid/src/diagrams/block/parser/block.jison index afd645d96..9422d8ee3 100644 --- a/packages/mermaid/src/diagrams/block/parser/block.jison +++ b/packages/mermaid/src/diagrams/block/parser/block.jison @@ -64,7 +64,7 @@ accDescr\s*"{"\s* { this.pushState("acc_descr_mul // Start of nodes with shapes and description "-)" { yy.getLogger().info('Lex: -)'); this.pushState('NODE');return 'NODE_D START'; } -"(-" { yy.getLogger().info('Lex: (-'); this.pushState('NODE');return 'NODE_DSTART'; } +"(-" { yy.getLogger().info('Lex: (-'); this.pushState('NODE');return 'NODE_DSTART'; } "))" { yy.getLogger().info('Lex: ))'); this.pushState('NODE');return 'NODE_DSTART'; } ")" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; } "((" { yy.getLogger().info('Lex: )'); this.pushState('NODE');return 'NODE_DSTART'; } @@ -177,8 +177,8 @@ statement ; nodeStatement - : nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) ');} - | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1);} + : nodeStatement link node { yy.getLogger().info('Rule: nodeStatement (nodeStatement link node) '); yy.addBlock($1.id);} + | node { yy.getLogger().info('Rule: nodeStatement (node) ', $1); yy.addBlock($1.id, $1.label, yy.typeStr2Type($1)); } ; columnsStatement @@ -192,16 +192,16 @@ blockStatement node : NODE_ID - { yy.getLogger().info("Rule: node (NODE_ID seperator): ", $1); } + { yy.getLogger().info("Rule: node (NODE_ID seperator): ", $1); $$ = { id: $1 }; } |NODE_ID nodeShapeNLabel - { yy.getLogger().info("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2); } + { yy.getLogger().info("Rule: node (NODE_ID nodeShapeNLabel seperator): ", $1, $2); $$ = { id: $1, label: $2.label, typeStr: $2.typeStr };} // |nodeShapeNLabel seperator // { yy.getLogger().info("Rule: node (nodeShapeNLabel seperator): ", $1, $2, $3); } ; nodeShapeNLabel : NODE_DSTART STR NODE_DEND - { yy.getLogger().info("Rule: nodeShapeNLabel: ", $1, $2, $3); $$ = { type: $1 + $3, descr: $2 }; } + { yy.getLogger().info("Rule: nodeShapeNLabel: ", $1, $2, $3); $$ = { typeStr: $1 + $3, label: $2 }; } ; %% diff --git a/packages/mermaid/src/diagrams/block/parser/block.spec.ts b/packages/mermaid/src/diagrams/block/parser/block.spec.ts index 75cd76b82..ded6db468 100644 --- a/packages/mermaid/src/diagrams/block/parser/block.spec.ts +++ b/packages/mermaid/src/diagrams/block/parser/block.spec.ts @@ -3,8 +3,7 @@ import block from './block.jison'; import db from '../blockDB.js'; import { cleanupComments } from '../../../diagram-api/comments.js'; import { prepareTextForParsing } from '../blockUtils.js'; -import * as fs from 'fs'; -import * as path from 'path'; +import { setConfig } from '../../../config.js'; describe('Block diagram', function () { describe('when parsing an block diagram graph it should handle > ', function () { @@ -20,6 +19,22 @@ describe('Block diagram', function () { `; block.parse(str); + const blocks = db.getBlocks(); + expect(blocks.length).toBe(1); + expect(blocks[0].ID).toBe('id'); + expect(blocks[0].label).toBe('id'); + }); + it('a node with a square shape and a label', async () => { + const str = `block-beta + id["A label"] + `; + + block.parse(str); + const blocks = db.getBlocks(); + expect(blocks.length).toBe(1); + expect(blocks[0].ID).toBe('id'); + expect(blocks[0].label).toBe('A label'); + expect(blocks[0].type).toBe('square'); }); it('a diagram with multiple nodes', async () => { const str = `block-beta diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow.spec.js index 3852c4f92..8d0aec789 100644 --- a/packages/mermaid/src/diagrams/flowchart/parser/flow.spec.js +++ b/packages/mermaid/src/diagrams/flowchart/parser/flow.spec.js @@ -1,7 +1,7 @@ import flowDb from '../flowDb.js'; import flow from './flow.jison'; -import { setConfig } from '../../../config.js'; import { cleanupComments } from '../../../diagram-api/comments.js'; +import { setConfig } from '../../../config.js'; setConfig({ securityLevel: 'strict',