diff --git a/.github/lychee.toml b/.github/lychee.toml new file mode 100644 index 0000000000..b13e536161 --- /dev/null +++ b/.github/lychee.toml @@ -0,0 +1,44 @@ +############################# Display ############################# + +# Verbose program output +# Accepts log level: "error", "warn", "info", "debug", "trace" +verbose = "debug" + +# Don't show interactive progress bar while checking links. +no_progress = true + +############################# Cache ############################### + +# Enable link caching. This can be helpful to avoid checking the same links on +# multiple runs. +cache = true + +# Discard all cached requests older than this duration. +max_cache_age = "1d" + +############################# Requests ############################ + +# Comma-separated list of accepted status codes for valid links. +accept = [200, 429] + +############################# Exclusions ########################## + +# Exclude URLs and mail addresses from checking (supports regex). +exclude = [ +# Network error: Forbidden +"https://codepen.io", + +# Timeout error, maybe Twitter has anti-bot defenses against GitHub's CI servers? +"https://twitter.com/mermaidjs_", + +# Don't check files that are generated during the build via `pnpm docs:code` +'packages/mermaid/src/docs/config/setup/*', + +# Ignore slack invite +"https://join.slack.com/" +] + +# Exclude all private IPs from checking. +# Equivalent to setting `exclude_private`, `exclude_link_local`, and +# `exclude_loopback` to true. +exclude_all_private = true diff --git a/.github/workflows/link-checker.yml b/.github/workflows/link-checker.yml index a2dc989e71..70580bfff1 100644 --- a/.github/workflows/link-checker.yml +++ b/.github/workflows/link-checker.yml @@ -20,7 +20,7 @@ on: - cron: '30 8 * * *' jobs: - linkChecker: + link-checker: runs-on: ubuntu-latest permissions: # lychee only uses the GITHUB_TOKEN to avoid rate-limiting @@ -39,10 +39,7 @@ jobs: uses: lycheeverse/lychee-action@v1.8.0 with: args: >- - --verbose - --no-progress - --cache - --max-cache-age 1d + --config .github/lychee.toml packages/mermaid/src/docs/**/*.md README.md README.zh-CN.md diff --git a/.lycheeignore b/.lycheeignore deleted file mode 100644 index d22d3cb153..0000000000 --- a/.lycheeignore +++ /dev/null @@ -1,17 +0,0 @@ -# These links are ignored by our link checker https://github.com/lycheeverse/lychee -# The file allows you to list multiple regular expressions for exclusion (one pattern per line). - -# Network error: Forbidden -https://codepen.io - -# Timeout error, maybe Twitter has anti-bot defenses against GitHub's CI servers? -https://twitter.com/mermaidjs_ - -# Don't check files that are generated during the build via `pnpm docs:code` -packages/mermaid/src/docs/config/setup/* - -# Ignore localhost -http://localhost:3333/ - -# Ignore slack invite -https://join.slack.com/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e8ac09325e..307bd038b6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -64,7 +64,7 @@ eg: `feature/2945_state-diagram-new-arrow-florbs`, `bug/1123_fix_random_ugly_red Documentation is necessary for all non bugfix/refactoring changes. -Only make changes to files are in [`/packages/mermaid/src/docs`](packages/mermaid/src/docs) +Only make changes to files that are in [`/packages/mermaid/src/docs`](packages/mermaid/src/docs) **_DO NOT CHANGE FILES IN `/docs`_** diff --git a/cypress/integration/rendering/flowchart-v2.spec.js b/cypress/integration/rendering/flowchart-v2.spec.js index 0f4b079c9d..aac4a31b17 100644 --- a/cypress/integration/rendering/flowchart-v2.spec.js +++ b/cypress/integration/rendering/flowchart-v2.spec.js @@ -449,7 +449,7 @@ flowchart TD { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' } ); }); - it('65: text-color from classes', () => { + it('65-1: text-color from classes', () => { imgSnapshotTest( ` flowchart LR @@ -460,6 +460,31 @@ flowchart TD { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' } ); }); + it('65-2: bold text from classes', () => { + imgSnapshotTest( + ` + flowchart + classDef cat fill:#f9d5e5, stroke:#233d4d,stroke-width:2px, font-weight:bold; + CS(A long bold text to be viewed):::cat + `, + { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' } + ); + }); + it('65-3: bigger font from classes', () => { + imgSnapshotTest( + ` +flowchart + Node1:::class1 --> Node2:::class2 + Node1:::class1 --> Node3:::class2 + Node3 --> Node4((I am a circle)):::larger + + classDef class1 fill:lightblue + classDef class2 fill:pink + classDef larger font-size:30px,fill:yellow + `, + { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' } + ); + }); it('66: More nested subgraph cases (TB)', () => { imgSnapshotTest( ` diff --git a/cypress/integration/rendering/flowchart.spec.js b/cypress/integration/rendering/flowchart.spec.js index 4f6d6478ef..e4766e7923 100644 --- a/cypress/integration/rendering/flowchart.spec.js +++ b/cypress/integration/rendering/flowchart.spec.js @@ -891,4 +891,27 @@ graph TD { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' } ); }); + it('66: apply class called default on node called default', () => { + imgSnapshotTest( + ` + graph TD + classDef default fill:#a34,stroke:#000,stroke-width:4px,color:#fff + hello --> default + `, + { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' } + ); + }); + + it('67: should be able to style default node independently', () => { + imgSnapshotTest( + ` + flowchart TD + classDef default fill:#a34 + hello --> default + + style default stroke:#000,stroke-width:4px + `, + { htmlLabels: true, flowchart: { htmlLabels: true }, securityLevel: 'loose' } + ); + }); }); diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 13de19ba03..f9a9f3756d 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -58,12 +58,21 @@
----
-title: Simple flowchart with invisible edges
----
-flowchart TD
-A ~~~ B
-  
+
+flowchart
+Node1:::class1 --> Node2:::class2
+Node1:::class1 --> Node3:::class2
+Node3 --> Node4((I am a circle)):::larger
+
+classDef class1 fill:lightblue
+classDef class2 fill:pink
+classDef larger font-size:30px,fill:yellow
+      
 stateDiagram-v2
diff --git a/docs/community/newDiagram.md b/docs/community/newDiagram.md
index bb7e2a9615..5dd616e668 100644
--- a/docs/community/newDiagram.md
+++ b/docs/community/newDiagram.md
@@ -10,7 +10,7 @@
 
 #### Grammar
 
-This would be to define a jison grammar for the new diagram type. That should start with a way to identify that the text in the mermaid tag is a diagram of that type. Create a new folder under diagrams for your new diagram type and a parser folder in it. This leads us to step 2.
+This would be to define a JISON grammar for the new diagram type. That should start with a way to identify that the text in the mermaid tag is a diagram of that type. Create a new folder under diagrams for your new diagram type and a parser folder in it. This leads us to step 2.
 
 For instance:
 
@@ -60,7 +60,7 @@ Place the renderer in the diagram folder.
 
 ### Step 3: Detection of the new diagram type
 
-The second thing to do is to add the capability to detect the new diagram to type to the detectType in utils.js. The detection should return a key for the new diagram type.
+The second thing to do is to add the capability to detect the new diagram to type to the detectType in `diagram-api/detectType.ts`. The detection should return a key for the new diagram type.
 [This key will be used to as the aria roledescription](#aria-roledescription), so it should be a word that clearly describes the diagram type.
 For example, if your new diagram use a UML deployment diagram, a good key would be "UMLDeploymentDiagram" because assistive technologies such as a screen reader
 would voice that as "U-M-L Deployment diagram." Another good key would be "deploymentDiagram" because that would be voiced as "Deployment Diagram." A bad key would be "deployment" because that would not sufficiently describe the diagram.
@@ -124,53 +124,6 @@ There are a few features that are common between the different types of diagrams
 
 Here some pointers on how to handle these different areas.
 
-#### [Directives](../config/directives.md)
-
-Here is example handling from flowcharts:
-Jison:
-
-```jison
-/* lexical grammar */
-%lex
-%x open_directive
-%x type_directive
-%x arg_directive
-%x close_directive
-
-\%\%\{                                                          { this.begin('open_directive'); return 'open_directive'; }
-((?:(?!\}\%\%)[^:.])*)                          { this.begin('type_directive'); return 'type_directive'; }
-":"                                             { this.popState(); this.begin('arg_directive'); return ':'; }
-\}\%\%                            { this.popState(); this.popState(); return 'close_directive'; }
-((?:(?!\}\%\%).|\n)*)                            return 'arg_directive';
-
-/* language grammar */
-
-/* ... */
-
-directive
-  : openDirective typeDirective closeDirective separator
-  | openDirective typeDirective ':' argDirective closeDirective separator
-  ;
-
-openDirective
-  : open_directive { yy.parseDirective('%%{', 'open_directive'); }
-  ;
-
-typeDirective
-  : type_directive { yy.parseDirective($1, 'type_directive'); }
-  ;
-
-argDirective
-  : arg_directive { $1 = $1.trim().replace(/'/g, '"'); yy.parseDirective($1, 'arg_directive'); }
-  ;
-
-closeDirective
-  : close_directive { yy.parseDirective('}%%', 'close_directive', 'flowchart'); }
-  ;
-```
-
-It is probably a good idea to keep the handling similar to this in your new diagram. The parseDirective function is provided by the mermaidAPI.
-
 ## Accessibility
 
 Mermaid automatically adds the following accessibility information for the diagram SVG HTML element:
@@ -189,7 +142,7 @@ See [the definition of aria-roledescription](https://www.w3.org/TR/wai-aria-1.1/
 
 The syntax for accessible titles and descriptions is described in [the Accessibility documenation section.](../config/accessibility.md)
 
-In a similar way to the directives, the jison syntax are quite similar between the diagrams.
+As a design goal, the jison syntax should be similar between the diagrams.
 
 ```jison
 
diff --git a/docs/config/setup/modules/mermaidAPI.md b/docs/config/setup/modules/mermaidAPI.md
index 72f18cace9..1160a5dda5 100644
--- a/docs/config/setup/modules/mermaidAPI.md
+++ b/docs/config/setup/modules/mermaidAPI.md
@@ -96,7 +96,7 @@ mermaid.initialize(config);
 
 #### Defined in
 
-[mermaidAPI.ts:667](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L667)
+[mermaidAPI.ts:668](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L668)
 
 ## Functions
 
@@ -127,7 +127,7 @@ Return the last node appended
 
 #### Defined in
 
-[mermaidAPI.ts:308](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L308)
+[mermaidAPI.ts:309](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L309)
 
 ---
 
@@ -153,7 +153,7 @@ the cleaned up svgCode
 
 #### Defined in
 
-[mermaidAPI.ts:256](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L256)
+[mermaidAPI.ts:255](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L255)
 
 ---
 
@@ -179,7 +179,7 @@ the string with all the user styles
 
 #### Defined in
 
-[mermaidAPI.ts:185](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L185)
+[mermaidAPI.ts:184](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L184)
 
 ---
 
@@ -202,7 +202,7 @@ the string with all the user styles
 
 #### Defined in
 
-[mermaidAPI.ts:233](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L233)
+[mermaidAPI.ts:232](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L232)
 
 ---
 
@@ -229,7 +229,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
 
 #### Defined in
 
-[mermaidAPI.ts:169](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L169)
+[mermaidAPI.ts:168](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L168)
 
 ---
 
@@ -249,7 +249,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
 
 #### Defined in
 
-[mermaidAPI.ts:155](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L155)
+[mermaidAPI.ts:154](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L154)
 
 ---
 
@@ -269,7 +269,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
 
 #### Defined in
 
-[mermaidAPI.ts:126](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L126)
+[mermaidAPI.ts:125](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L125)
 
 ---
 
@@ -295,7 +295,7 @@ Put the svgCode into an iFrame. Return the iFrame code
 
 #### Defined in
 
-[mermaidAPI.ts:287](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L287)
+[mermaidAPI.ts:286](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L286)
 
 ---
 
@@ -320,4 +320,4 @@ Remove any existing elements from the given document
 
 #### Defined in
 
-[mermaidAPI.ts:358](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L358)
+[mermaidAPI.ts:359](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L359)
diff --git a/docs/intro/index.md b/docs/intro/index.md
index 36707bace0..b6065c85f7 100644
--- a/docs/intro/index.md
+++ b/docs/intro/index.md
@@ -387,7 +387,9 @@ The above command generates files into the `dist` folder and publishes them to \
 - [Live Editor](https://github.com/mermaid-js/mermaid-live-editor)
 - [HTTP Server](https://github.com/TomWright/mermaid-server)
 
-## Contributors [![Good first issue](https://img.shields.io/github/labels/mermaid-js/mermaid/Good%20first%20issue%21)](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%21%22) [![Contributors](https://img.shields.io/github/contributors/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors) [![Commits](https://img.shields.io/github/commit-activity/m/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors)
+## Contributors
+
+[![Good first issue](https://img.shields.io/github/labels/mermaid-js/mermaid/Good%20first%20issue%21)](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%21%22) [![Contributors](https://img.shields.io/github/contributors/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors) [![Commits](https://img.shields.io/github/commit-activity/m/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors)
 
 Mermaid is a growing community and is always accepting new contributors. There's a lot of different ways to help out and we're always looking for extra hands! Look at [this issue](https://github.com/mermaid-js/mermaid/issues/866) if you want to know where to start helping out.
 
diff --git a/docs/news/announcements.md b/docs/news/announcements.md
index b7620ec096..fd53daa4ef 100644
--- a/docs/news/announcements.md
+++ b/docs/news/announcements.md
@@ -6,8 +6,8 @@
 
 # Announcements
 
-## [Mermaid Chart Announces Visual Studio Code Plugin to Simplify Development Workflows](https://www.mermaidchart.com/blog/posts/mermaid-chart-announces-visual-studio-code-plugin)
+## [From Chaos to Clarity: Exploring Mind Maps with MermaidJS](https://www.mermaidchart.com/blog/posts/from-chaos-to-clarity-exploring-mind-maps-with-mermaidjs)
 
-17 July 2023 · 3 mins
+24 July 2023 · 4 mins
 
-New Integration Enhances Workflows By Enabling Developers To Reference And Edit Diagrams Within Visual Studio Code.
+Introducing the concept of mind mapping as a tool for organizing complex information, and highlights Mermaid as a user-friendly software that simplifies the creation and editing of mind maps for applications in IT solution design, business decision-making, and knowledge organization.
diff --git a/docs/news/blog.md b/docs/news/blog.md
index 8701569b16..be2f484618 100644
--- a/docs/news/blog.md
+++ b/docs/news/blog.md
@@ -6,6 +6,12 @@
 
 # Blog
 
+## [From Chaos to Clarity: Exploring Mind Maps with MermaidJS](https://www.mermaidchart.com/blog/posts/from-chaos-to-clarity-exploring-mind-maps-with-mermaidjs)
+
+24 July 2023 · 4 mins
+
+Introducing the concept of mind mapping as a tool for organizing complex information, and highlights Mermaid as a user-friendly software that simplifies the creation and editing of mind maps for applications in IT solution design, business decision-making, and knowledge organization.
+
 ## [Mermaid Chart Announces Visual Studio Code Plugin to Simplify Development Workflows](https://www.mermaidchart.com/blog/posts/mermaid-chart-announces-visual-studio-code-plugin)
 
 17 July 2023 · 3 mins
diff --git a/docs/syntax/flowchart.md b/docs/syntax/flowchart.md
index 92678fb6ec..0440c91691 100644
--- a/docs/syntax/flowchart.md
+++ b/docs/syntax/flowchart.md
@@ -608,12 +608,12 @@ It is possible to escape characters using the syntax exemplified here.
 
 ```mermaid-example
     flowchart LR
-        A["A double quote:#quot;"] -->B["A dec char:#9829;"]
+        A["A double quote:#quot;"] --> B["A dec char:#9829;"]
 ```
 
 ```mermaid
     flowchart LR
-        A["A double quote:#quot;"] -->B["A dec char:#9829;"]
+        A["A double quote:#quot;"] --> B["A dec char:#9829;"]
 ```
 
 Numbers given are base 10, so `#` can be encoded as `#35;`. It is also supported to use HTML character names.
diff --git a/package.json b/package.json
index 47fae3be46..03ab8c6ecb 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
   "version": "10.2.4",
   "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
   "type": "module",
-  "packageManager": "pnpm@8.6.10",
+  "packageManager": "pnpm@8.6.11",
   "keywords": [
     "diagram",
     "markdown",
@@ -109,7 +109,7 @@
     "lint-staged": "^13.2.1",
     "nyc": "^15.1.0",
     "path-browserify": "^1.0.1",
-    "pnpm": "^8.3.1",
+    "pnpm": "^8.6.8",
     "prettier": "^2.8.8",
     "prettier-plugin-jsdoc": "^0.4.2",
     "rimraf": "^5.0.0",
diff --git a/packages/mermaid-example-diagram/package.json b/packages/mermaid-example-diagram/package.json
index 1ea4135ef1..dc468a6c73 100644
--- a/packages/mermaid-example-diagram/package.json
+++ b/packages/mermaid-example-diagram/package.json
@@ -38,7 +38,7 @@
     ]
   },
   "dependencies": {
-    "@braintree/sanitize-url": "^6.0.0",
+    "@braintree/sanitize-url": "^6.0.1",
     "cytoscape": "^3.23.0",
     "cytoscape-cose-bilkent": "^4.1.0",
     "cytoscape-fcose": "^2.1.0",
diff --git a/packages/mermaid-zenuml/package.json b/packages/mermaid-zenuml/package.json
index d4186f05c9..b907e2cbae 100644
--- a/packages/mermaid-zenuml/package.json
+++ b/packages/mermaid-zenuml/package.json
@@ -33,7 +33,7 @@
   ],
   "license": "MIT",
   "dependencies": {
-    "@zenuml/core": "^3.0.3"
+    "@zenuml/core": "^3.0.6"
   },
   "devDependencies": {
     "mermaid": "workspace:^"
diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json
index 51c0b018cd..1230c6d3c9 100644
--- a/packages/mermaid/package.json
+++ b/packages/mermaid/package.json
@@ -1,6 +1,6 @@
 {
   "name": "mermaid",
-  "version": "10.3.0",
+  "version": "10.3.1",
   "description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
   "type": "module",
   "module": "./dist/mermaid.core.mjs",
@@ -57,7 +57,7 @@
     ]
   },
   "dependencies": {
-    "@braintree/sanitize-url": "^6.0.2",
+    "@braintree/sanitize-url": "^6.0.1",
     "@types/d3-scale": "^4.0.3",
     "@types/d3-scale-chromatic": "^3.0.0",
     "cytoscape": "^3.23.0",
@@ -67,7 +67,7 @@
     "d3-sankey": "^0.12.3",
     "dagre-d3-es": "7.0.10",
     "dayjs": "^1.11.7",
-    "dompurify": "3.0.5",
+    "dompurify": "^3.0.5",
     "elkjs": "^0.8.2",
     "khroma": "^2.0.0",
     "lodash-es": "^4.17.21",
diff --git a/packages/mermaid/scripts/create-types-from-json-schema.mts b/packages/mermaid/scripts/create-types-from-json-schema.mts
index e81ea70ffd..836aaa4481 100644
--- a/packages/mermaid/scripts/create-types-from-json-schema.mts
+++ b/packages/mermaid/scripts/create-types-from-json-schema.mts
@@ -18,6 +18,7 @@ import { promisify } from 'node:util';
 
 import { load, JSON_SCHEMA } from 'js-yaml';
 import { compile, type JSONSchema } from 'json-schema-to-typescript';
+import prettier from 'prettier';
 
 import _Ajv2019, { type JSONSchemaType } from 'ajv/dist/2019.js';
 
@@ -207,6 +208,7 @@ async function generateTypescript(mermaidConfigSchema: JSONSchemaType void;
 
@@ -15,9 +16,11 @@ export type ParseErrorFunction = (err: string | DetailedError | unknown, hash?:
  */
 export class Diagram {
   type = 'graph';
-  parser;
-  renderer;
-  db;
+  parser: DiagramDefinition['parser'];
+  renderer: DiagramDefinition['renderer'];
+  db: DiagramDefinition['db'];
+  private init?: DiagramDefinition['init'];
+
   private detectError?: UnknownDiagramError;
   constructor(public text: string) {
     this.text += '\n';
@@ -32,7 +35,6 @@ export class Diagram {
     log.debug('Type ' + this.type);
     // Setup diagram
     this.db = diagram.db;
-    this.db.clear?.();
     this.renderer = diagram.renderer;
     this.parser = diagram.parser;
     const originalParse = this.parser.parse.bind(this.parser);
@@ -49,10 +51,7 @@ export class Diagram {
       originalParse(cleanupComments(extractFrontMatter(text, this.db)));
 
     this.parser.parser.yy = this.db;
-    if (diagram.init) {
-      diagram.init(cnf);
-      log.info('Initialized diagram ' + this.type, cnf);
-    }
+    this.init = diagram.init;
     this.parse();
   }
 
@@ -61,6 +60,7 @@ export class Diagram {
       throw this.detectError;
     }
     this.db.clear?.();
+    this.init?.(configApi.getConfig());
     this.parser.parse(this.text);
   }
 
diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts
index df87e9c406..c378660ca8 100644
--- a/packages/mermaid/src/config.type.ts
+++ b/packages/mermaid/src/config.type.ts
@@ -8,7 +8,7 @@
 /**
  * Configuration options to pass to the `dompurify` library.
  */
-export type DOMPurifyConfiguration = import("dompurify").Config;
+export type DOMPurifyConfiguration = import('dompurify').Config;
 /**
  * JavaScript function that returns a `FontConfig`.
  *
@@ -39,7 +39,7 @@ export type FontCalculator = () => Partial;
  * This interface was referenced by `MermaidConfig`'s JSON-Schema
  * via the `definition` "SankeyLinkColor".
  */
-export type SankeyLinkColor = "source" | "target" | "gradient";
+export type SankeyLinkColor = 'source' | 'target' | 'gradient';
 /**
  * Controls the alignment of the Sankey diagrams.
  *
@@ -49,7 +49,7 @@ export type SankeyLinkColor = "source" | "target" | "gradient";
  * This interface was referenced by `MermaidConfig`'s JSON-Schema
  * via the `definition` "SankeyNodeAlignment".
  */
-export type SankeyNodeAlignment = "left" | "right" | "center" | "justify";
+export type SankeyNodeAlignment = 'left' | 'right' | 'center' | 'justify';
 /**
  * The font size to use
  */
@@ -61,7 +61,7 @@ export interface MermaidConfig {
    * You may also use `themeCSS` to override this value.
    *
    */
-  theme?: string | "default" | "forest" | "dark" | "neutral" | "null";
+  theme?: string | 'default' | 'forest' | 'dark' | 'neutral' | 'null';
   themeVariables?: any;
   themeCSS?: string;
   /**
@@ -88,12 +88,12 @@ export interface MermaidConfig {
     | 0
     | 2
     | 1
-    | "trace"
-    | "debug"
-    | "info"
-    | "warn"
-    | "error"
-    | "fatal"
+    | 'trace'
+    | 'debug'
+    | 'info'
+    | 'warn'
+    | 'error'
+    | 'fatal'
     | 3
     | 4
     | 5
@@ -101,7 +101,7 @@ export interface MermaidConfig {
   /**
    * Level of trust for parsed diagram
    */
-  securityLevel?: string | "strict" | "loose" | "antiscript" | "sandbox" | undefined;
+  securityLevel?: string | 'strict' | 'loose' | 'antiscript' | 'sandbox' | undefined;
   /**
    * Dictates whether mermaid starts on Page load
    */
@@ -689,11 +689,11 @@ export interface QuadrantChartConfig extends BaseDiagramConfig {
   /**
    * position of x-axis labels
    */
-  xAxisPosition?: "top" | "bottom";
+  xAxisPosition?: 'top' | 'bottom';
   /**
    * position of y-axis labels
    */
-  yAxisPosition?: "left" | "right";
+  yAxisPosition?: 'left' | 'right';
   /**
    * stroke width of edges of the box that are inside the quadrant
    */
@@ -723,7 +723,7 @@ export interface ErDiagramConfig extends BaseDiagramConfig {
   /**
    * Directional bias for layout of entities
    */
-  layoutDirection?: string | "TB" | "BT" | "LR" | "RL";
+  layoutDirection?: string | 'TB' | 'BT' | 'LR' | 'RL';
   /**
    * The minimum width of an entity box. Expressed in pixels.
    */
@@ -788,7 +788,7 @@ export interface StateDiagramConfig extends BaseDiagramConfig {
    * Decides which rendering engine that is to be used for the rendering.
    *
    */
-  defaultRenderer?: string | "dagre-d3" | "dagre-wrapper" | "elk";
+  defaultRenderer?: string | 'dagre-d3' | 'dagre-wrapper' | 'elk';
 }
 /**
  * This interface was referenced by `MermaidConfig`'s JSON-Schema
@@ -812,7 +812,7 @@ export interface ClassDiagramConfig extends BaseDiagramConfig {
    * Decides which rendering engine that is to be used for the rendering.
    *
    */
-  defaultRenderer?: string | "dagre-d3" | "dagre-wrapper" | "elk";
+  defaultRenderer?: string | 'dagre-d3' | 'dagre-wrapper' | 'elk';
   nodeSpacing?: number;
   rankSpacing?: number;
   /**
@@ -872,7 +872,7 @@ export interface JourneyDiagramConfig extends BaseDiagramConfig {
   /**
    * Multiline message alignment
    */
-  messageAlign?: string | "left" | "center" | "right";
+  messageAlign?: string | 'left' | 'center' | 'right';
   /**
    * Prolongs the edge of the diagram downwards.
    *
@@ -951,7 +951,7 @@ export interface TimelineDiagramConfig extends BaseDiagramConfig {
   /**
    * Multiline message alignment
    */
-  messageAlign?: string | "left" | "center" | "right";
+  messageAlign?: string | 'left' | 'center' | 'right';
   /**
    * Prolongs the edge of the diagram downwards.
    *
@@ -1062,12 +1062,12 @@ export interface GanttDiagramConfig extends BaseDiagramConfig {
    * Controls the display mode.
    *
    */
-  displayMode?: string | "compact";
+  displayMode?: string | 'compact';
   /**
    * On which day a week-based interval should start
    *
    */
-  weekday?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday";
+  weekday?: 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday';
 }
 /**
  * The object containing configurations specific for sequence diagrams
@@ -1121,7 +1121,7 @@ export interface SequenceDiagramConfig extends BaseDiagramConfig {
   /**
    * Multiline message alignment
    */
-  messageAlign?: string | "left" | "center" | "right";
+  messageAlign?: string | 'left' | 'center' | 'right';
   /**
    * Mirror actors under diagram
    *
@@ -1178,7 +1178,7 @@ export interface SequenceDiagramConfig extends BaseDiagramConfig {
   /**
    * This sets the text alignment of actor-attached notes
    */
-  noteAlign?: string | "left" | "center" | "right";
+  noteAlign?: string | 'left' | 'center' | 'right';
   /**
    * This sets the font size of actor messages
    */
@@ -1254,7 +1254,7 @@ export interface FlowchartDiagramConfig extends BaseDiagramConfig {
    * Defines how mermaid renders curves for flowcharts.
    *
    */
-  curve?: string | "basis" | "linear" | "cardinal";
+  curve?: string | 'basis' | 'linear' | 'cardinal';
   /**
    * Represents the padding between the labels and the shape
    *
@@ -1266,7 +1266,7 @@ export interface FlowchartDiagramConfig extends BaseDiagramConfig {
    * Decides which rendering engine that is to be used for the rendering.
    *
    */
-  defaultRenderer?: string | "dagre-d3" | "dagre-wrapper" | "elk";
+  defaultRenderer?: string | 'dagre-d3' | 'dagre-wrapper' | 'elk';
   /**
    * Width of nodes where text is wrapped.
    *
@@ -1296,7 +1296,7 @@ export interface SankeyDiagramConfig extends BaseDiagramConfig {
    * See .
    *
    */
-  nodeAlignment?: "left" | "right" | "center" | "justify";
+  nodeAlignment?: 'left' | 'right' | 'center' | 'justify';
   useMaxWidth?: boolean;
 }
 /**
diff --git a/packages/mermaid/src/dagre-wrapper/nodes.js b/packages/mermaid/src/dagre-wrapper/nodes.js
index 6c67333585..e7988c8b53 100644
--- a/packages/mermaid/src/dagre-wrapper/nodes.js
+++ b/packages/mermaid/src/dagre-wrapper/nodes.js
@@ -8,8 +8,25 @@ import note from './shapes/note.js';
 import { parseMember } from '../diagrams/class/svgDraw.js';
 import { evaluate } from '../diagrams/common/common.js';
 
+const formatClass = (str) => {
+  if (str) {
+    return ' ' + str;
+  }
+  return '';
+};
+const getClassesFromNode = (node, otherClasses) => {
+  return `${otherClasses ? otherClasses : 'node default'}${formatClass(node.classes)} ${formatClass(
+    node.class
+  )}`;
+};
+
 const question = async (parent, node) => {
-  const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
+  const { shapeSvg, bbox } = await labelHelper(
+    parent,
+    node,
+    getClassesFromNode(node, undefined),
+    true
+  );
 
   const w = bbox.width + node.padding;
   const h = bbox.height + node.padding;
@@ -70,7 +87,12 @@ const choice = (parent, node) => {
 };
 
 const hexagon = async (parent, node) => {
-  const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
+  const { shapeSvg, bbox } = await labelHelper(
+    parent,
+    node,
+    getClassesFromNode(node, undefined),
+    true
+  );
 
   const f = 4;
   const h = bbox.height + node.padding;
@@ -97,7 +119,12 @@ const hexagon = async (parent, node) => {
 };
 
 const rect_left_inv_arrow = async (parent, node) => {
-  const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
+  const { shapeSvg, bbox } = await labelHelper(
+    parent,
+    node,
+    getClassesFromNode(node, undefined),
+    true
+  );
 
   const w = bbox.width + node.padding;
   const h = bbox.height + node.padding;
@@ -123,7 +150,7 @@ const rect_left_inv_arrow = async (parent, node) => {
 };
 
 const lean_right = async (parent, node) => {
-  const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
+  const { shapeSvg, bbox } = await labelHelper(parent, node, getClassesFromNode(node), true);
 
   const w = bbox.width + node.padding;
   const h = bbox.height + node.padding;
@@ -146,7 +173,12 @@ const lean_right = async (parent, node) => {
 };
 
 const lean_left = async (parent, node) => {
-  const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
+  const { shapeSvg, bbox } = await labelHelper(
+    parent,
+    node,
+    getClassesFromNode(node, undefined),
+    true
+  );
 
   const w = bbox.width + node.padding;
   const h = bbox.height + node.padding;
@@ -169,7 +201,12 @@ const lean_left = async (parent, node) => {
 };
 
 const trapezoid = async (parent, node) => {
-  const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
+  const { shapeSvg, bbox } = await labelHelper(
+    parent,
+    node,
+    getClassesFromNode(node, undefined),
+    true
+  );
 
   const w = bbox.width + node.padding;
   const h = bbox.height + node.padding;
@@ -192,7 +229,12 @@ const trapezoid = async (parent, node) => {
 };
 
 const inv_trapezoid = async (parent, node) => {
-  const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
+  const { shapeSvg, bbox } = await labelHelper(
+    parent,
+    node,
+    getClassesFromNode(node, undefined),
+    true
+  );
 
   const w = bbox.width + node.padding;
   const h = bbox.height + node.padding;
@@ -215,7 +257,12 @@ const inv_trapezoid = async (parent, node) => {
 };
 
 const rect_right_inv_arrow = async (parent, node) => {
-  const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
+  const { shapeSvg, bbox } = await labelHelper(
+    parent,
+    node,
+    getClassesFromNode(node, undefined),
+    true
+  );
 
   const w = bbox.width + node.padding;
   const h = bbox.height + node.padding;
@@ -239,7 +286,12 @@ const rect_right_inv_arrow = async (parent, node) => {
 };
 
 const cylinder = async (parent, node) => {
-  const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
+  const { shapeSvg, bbox } = await labelHelper(
+    parent,
+    node,
+    getClassesFromNode(node, undefined),
+    true
+  );
 
   const w = bbox.width + node.padding;
   const rx = w / 2;
@@ -314,7 +366,7 @@ const rect = async (parent, node) => {
   const { shapeSvg, bbox, halfPadding } = await labelHelper(
     parent,
     node,
-    'node ' + node.classes,
+    'node ' + node.classes + ' ' + node.class,
     true
   );
 
@@ -360,7 +412,7 @@ const rect = async (parent, node) => {
 const labelRect = async (parent, node) => {
   const { shapeSvg } = await labelHelper(parent, node, 'label', true);
 
-  log.trace('Classes = ', node.classes);
+  log.trace('Classes = ', node.class);
   // add the rect
   const rect = shapeSvg.insert('rect', ':first-child');
 
@@ -545,7 +597,12 @@ const rectWithTitle = (parent, node) => {
 };
 
 const stadium = async (parent, node) => {
-  const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
+  const { shapeSvg, bbox } = await labelHelper(
+    parent,
+    node,
+    getClassesFromNode(node, undefined),
+    true
+  );
 
   const h = bbox.height + node.padding;
   const w = bbox.width + h / 4 + node.padding;
@@ -571,7 +628,12 @@ const stadium = async (parent, node) => {
 };
 
 const circle = async (parent, node) => {
-  const { shapeSvg, bbox, halfPadding } = await labelHelper(parent, node, undefined, true);
+  const { shapeSvg, bbox, halfPadding } = await labelHelper(
+    parent,
+    node,
+    getClassesFromNode(node, undefined),
+    true
+  );
   const circle = shapeSvg.insert('circle', ':first-child');
 
   // center the circle around its coordinate
@@ -596,7 +658,12 @@ const circle = async (parent, node) => {
 };
 
 const doublecircle = async (parent, node) => {
-  const { shapeSvg, bbox, halfPadding } = await labelHelper(parent, node, undefined, true);
+  const { shapeSvg, bbox, halfPadding } = await labelHelper(
+    parent,
+    node,
+    getClassesFromNode(node, undefined),
+    true
+  );
   const gap = 5;
   const circleGroup = shapeSvg.insert('g', ':first-child');
   const outerCircle = circleGroup.insert('circle');
@@ -634,7 +701,12 @@ const doublecircle = async (parent, node) => {
 };
 
 const subroutine = async (parent, node) => {
-  const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
+  const { shapeSvg, bbox } = await labelHelper(
+    parent,
+    node,
+    getClassesFromNode(node, undefined),
+    true
+  );
 
   const w = bbox.width + node.padding;
   const h = bbox.height + node.padding;
diff --git a/packages/mermaid/src/dagre-wrapper/shapes/util.js b/packages/mermaid/src/dagre-wrapper/shapes/util.js
index 3eaedb4b9f..95b82ddc07 100644
--- a/packages/mermaid/src/dagre-wrapper/shapes/util.js
+++ b/packages/mermaid/src/dagre-wrapper/shapes/util.js
@@ -13,6 +13,7 @@ export const labelHelper = async (parent, node, _classes, isNode) => {
   } else {
     classes = _classes;
   }
+
   // Add outer g element
   const shapeSvg = parent
     .insert('g')
@@ -49,7 +50,6 @@ export const labelHelper = async (parent, node, _classes, isNode) => {
       )
     );
   }
-
   // Get the size of the label
   let bbox = text.getBBox();
   const halfPadding = node.padding / 2;
diff --git a/packages/mermaid/src/diagram-api/diagramAPI.spec.ts b/packages/mermaid/src/diagram-api/diagramAPI.spec.ts
index 49bde1a66f..b437745cfa 100644
--- a/packages/mermaid/src/diagram-api/diagramAPI.spec.ts
+++ b/packages/mermaid/src/diagram-api/diagramAPI.spec.ts
@@ -35,7 +35,12 @@ describe('DiagramAPI', () => {
       'loki',
       {
         db: {},
-        parser: {},
+        parser: {
+          parse: (_text) => {
+            return;
+          },
+          parser: { yy: {} },
+        },
         renderer: {},
         styles: {},
       },
diff --git a/packages/mermaid/src/diagram-api/diagramAPI.ts b/packages/mermaid/src/diagram-api/diagramAPI.ts
index 7e89d9cd79..3edd982bb4 100644
--- a/packages/mermaid/src/diagram-api/diagramAPI.ts
+++ b/packages/mermaid/src/diagram-api/diagramAPI.ts
@@ -69,11 +69,11 @@ export const getDiagram = (name: string): DiagramDefinition => {
   if (name in diagrams) {
     return diagrams[name];
   }
-  throw new Error(`Diagram ${name} not found.`);
+  throw new DiagramNotFoundError(name);
 };
 
 export class DiagramNotFoundError extends Error {
-  constructor(message: string) {
-    super(`Diagram ${message} not found.`);
+  constructor(name: string) {
+    super(`Diagram ${name} not found.`);
   }
 }
diff --git a/packages/mermaid/src/diagram-api/types.ts b/packages/mermaid/src/diagram-api/types.ts
index 3b8d004563..100b92e871 100644
--- a/packages/mermaid/src/diagram-api/types.ts
+++ b/packages/mermaid/src/diagram-api/types.ts
@@ -1,5 +1,5 @@
 import { Diagram } from '../Diagram.js';
-import { MermaidConfig } from '../config.type.js';
+import type { MermaidConfig } from '../config.type.js';
 import type * as d3 from 'd3';
 
 export interface InjectUtils {
@@ -27,7 +27,7 @@ export interface DiagramDB {
 export interface DiagramDefinition {
   db: DiagramDB;
   renderer: any;
-  parser: any;
+  parser: ParserDefinition;
   styles?: any;
   init?: (config: MermaidConfig) => void;
   injectUtils?: (
@@ -70,6 +70,11 @@ export type DrawDefinition = (
   diagramObject: Diagram
 ) => void;
 
+export interface ParserDefinition {
+  parse: (text: string) => void;
+  parser: { yy: DiagramDB };
+}
+
 /**
  * Type for function parse directive from diagram code.
  *
@@ -79,8 +84,10 @@ export type DrawDefinition = (
  */
 export type ParseDirectiveDefinition = (statement: string, context: string, type: string) => void;
 
-export type HTML = d3.Selection;
+export type HTML = d3.Selection;
+
+export type SVG = d3.Selection;
 
-export type SVG = d3.Selection;
+export type Group = d3.Selection;
 
 export type DiagramStylesProvider = (options?: any) => string;
diff --git a/packages/mermaid/src/diagram.spec.ts b/packages/mermaid/src/diagram.spec.ts
index aa613d8e52..99ce4e2c66 100644
--- a/packages/mermaid/src/diagram.spec.ts
+++ b/packages/mermaid/src/diagram.spec.ts
@@ -49,7 +49,7 @@ describe('diagram detection', () => {
       "Parse error on line 2:
       graph TD; A-->
       --------------^
-      Expecting 'AMP', 'ALPHA', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'MINUS', 'BRKT', 'DOT', 'PUNCTUATION', 'UNICODE_TEXT', 'PLUS', 'EQUALS', 'MULT', 'UNDERSCORE', got 'EOF'"
+      Expecting 'AMP', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'EOF'"
     `);
     await expect(getDiagramFromText('sequenceDiagram; A-->B')).rejects
       .toThrowErrorMatchingInlineSnapshot(`
diff --git a/packages/mermaid/src/diagrams/c4/c4Diagram.ts b/packages/mermaid/src/diagrams/c4/c4Diagram.ts
index 04567fafa3..b3c7ae8ebb 100644
--- a/packages/mermaid/src/diagrams/c4/c4Diagram.ts
+++ b/packages/mermaid/src/diagrams/c4/c4Diagram.ts
@@ -1,4 +1,4 @@
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import c4Parser from './parser/c4Diagram.jison';
 import c4Db from './c4Db.js';
 import c4Renderer from './c4Renderer.js';
diff --git a/packages/mermaid/src/diagrams/class/classDiagram-v2.ts b/packages/mermaid/src/diagrams/class/classDiagram-v2.ts
index 5b952627cf..91e8597a41 100644
--- a/packages/mermaid/src/diagrams/class/classDiagram-v2.ts
+++ b/packages/mermaid/src/diagrams/class/classDiagram-v2.ts
@@ -1,5 +1,5 @@
 import { DiagramDefinition } from '../../diagram-api/types.js';
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import parser from './parser/classDiagram.jison';
 import db from './classDb.js';
 import styles from './styles.js';
diff --git a/packages/mermaid/src/diagrams/class/classDiagram.ts b/packages/mermaid/src/diagrams/class/classDiagram.ts
index 0d2a246b4e..532d52189c 100644
--- a/packages/mermaid/src/diagrams/class/classDiagram.ts
+++ b/packages/mermaid/src/diagrams/class/classDiagram.ts
@@ -1,5 +1,5 @@
 import { DiagramDefinition } from '../../diagram-api/types.js';
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import parser from './parser/classDiagram.jison';
 import db from './classDb.js';
 import styles from './styles.js';
diff --git a/packages/mermaid/src/diagrams/er/erRenderer.js b/packages/mermaid/src/diagrams/er/erRenderer.js
index 63fb056339..b992afd651 100644
--- a/packages/mermaid/src/diagrams/er/erRenderer.js
+++ b/packages/mermaid/src/diagrams/er/erRenderer.js
@@ -555,7 +555,6 @@ const drawRelationshipFromLayout = function (svg, rel, g, insert, diagObj) {
 export const draw = function (text, id, _version, diagObj) {
   conf = getConfig().er;
   log.info('Drawing ER diagram');
-  //  diag.db.clear();
   const securityLevel = getConfig().securityLevel;
   // Handle root and Document for when rendering in sandbox mode
   let sandboxElement;
diff --git a/packages/mermaid/src/diagrams/error/errorDiagram.ts b/packages/mermaid/src/diagrams/error/errorDiagram.ts
index 76efdb0ae5..284dfd7447 100644
--- a/packages/mermaid/src/diagrams/error/errorDiagram.ts
+++ b/packages/mermaid/src/diagrams/error/errorDiagram.ts
@@ -1,23 +1,15 @@
-import { DiagramDefinition } from '../../diagram-api/types.js';
-import styles from './styles.js';
-import renderer from './errorRenderer.js';
-export const diagram: DiagramDefinition = {
-  db: {
-    clear: () => {
-      // Quite ok, clear needs to be there for error to work as a regular diagram
-    },
-  },
-  styles,
+import type { DiagramDefinition } from '../../diagram-api/types.js';
+import { renderer } from './errorRenderer.js';
+
+const diagram: DiagramDefinition = {
+  db: {},
   renderer,
   parser: {
     parser: { yy: {} },
-    parse: () => {
-      // no op
+    parse: (): void => {
+      return;
     },
   },
-  init: () => {
-    // no op
-  },
 };
 
 export default diagram;
diff --git a/packages/mermaid/src/diagrams/error/errorRenderer.ts b/packages/mermaid/src/diagrams/error/errorRenderer.ts
index aa0e9e8164..a8e738e5fd 100644
--- a/packages/mermaid/src/diagrams/error/errorRenderer.ts
+++ b/packages/mermaid/src/diagrams/error/errorRenderer.ts
@@ -1,100 +1,81 @@
-/** Created by knut on 14-12-11. */
-// @ts-ignore TODO: Investigate D3 issue
-import { select } from 'd3';
 import { log } from '../../logger.js';
-import { getErrorMessage } from '../../utils.js';
-
-/**
- * Merges the value of `conf` with the passed `cnf`
- *
- * @param cnf - Config to merge
- */
-export const setConf = function () {
-  // no-op
-};
+import type { Group, SVG } from '../../diagram-api/types.js';
+import { selectSvgElement } from '../../rendering-util/selectSvgElement.js';
+import { configureSvgSize } from '../../setupGraphViewbox.js';
 
 /**
  * Draws a an info picture in the tag with id: id based on the graph definition in text.
  *
  * @param _text - Mermaid graph definition.
  * @param id - The text for the error
- * @param mermaidVersion - The version
+ * @param version - The version
  */
-export const draw = (_text: string, id: string, mermaidVersion: string) => {
-  try {
-    log.debug('Renering svg for syntax error\n');
+export const draw = (_text: string, id: string, version: string) => {
+  log.debug('renering svg for syntax error\n');
 
-    const svg = select('#' + id);
+  const svg: SVG = selectSvgElement(id);
+  svg.attr('viewBox', '0 0 2412 512');
+  configureSvgSize(svg, 100, 512, true);
 
-    const g = svg.append('g');
+  const g: Group = svg.append('g');
+  g.append('path')
+    .attr('class', 'error-icon')
+    .attr(
+      'd',
+      'm411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z'
+    );
 
-    g.append('path')
-      .attr('class', 'error-icon')
-      .attr(
-        'd',
-        'm411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z'
-      );
+  g.append('path')
+    .attr('class', 'error-icon')
+    .attr(
+      'd',
+      'm459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z'
+    );
 
-    g.append('path')
-      .attr('class', 'error-icon')
-      .attr(
-        'd',
-        'm459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z'
-      );
+  g.append('path')
+    .attr('class', 'error-icon')
+    .attr(
+      'd',
+      'm340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z'
+    );
 
-    g.append('path')
-      .attr('class', 'error-icon')
-      .attr(
-        'd',
-        'm340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z'
-      );
+  g.append('path')
+    .attr('class', 'error-icon')
+    .attr(
+      'd',
+      'm400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z'
+    );
 
-    g.append('path')
-      .attr('class', 'error-icon')
-      .attr(
-        'd',
-        'm400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z'
-      );
+  g.append('path')
+    .attr('class', 'error-icon')
+    .attr(
+      'd',
+      'm496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z'
+    );
 
-    g.append('path')
-      .attr('class', 'error-icon')
-      .attr(
-        'd',
-        'm496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z'
-      );
+  g.append('path')
+    .attr('class', 'error-icon')
+    .attr(
+      'd',
+      'm436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z'
+    );
 
-    g.append('path')
-      .attr('class', 'error-icon')
-      .attr(
-        'd',
-        'm436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z'
-      );
-
-    g.append('text') // text label for the x axis
-      .attr('class', 'error-text')
-      .attr('x', 1440)
-      .attr('y', 250)
-      .attr('font-size', '150px')
-      .style('text-anchor', 'middle')
-      .text('Syntax error in text');
-    g.append('text') // text label for the x axis
-      .attr('class', 'error-text')
-      .attr('x', 1250)
-      .attr('y', 400)
-      .attr('font-size', '100px')
-      .style('text-anchor', 'middle')
-      .text('mermaid version ' + mermaidVersion);
-
-    svg.attr('height', 100);
-    svg.attr('width', 500);
-    svg.attr('viewBox', '768 0 912 512');
-  } catch (e) {
-    log.error('Error while rendering info diagram');
-    log.error(getErrorMessage(e));
-  }
+  g.append('text') // text label for the x axis
+    .attr('class', 'error-text')
+    .attr('x', 1440)
+    .attr('y', 250)
+    .attr('font-size', '150px')
+    .style('text-anchor', 'middle')
+    .text('Syntax error in text');
+  g.append('text') // text label for the x axis
+    .attr('class', 'error-text')
+    .attr('x', 1250)
+    .attr('y', 400)
+    .attr('font-size', '100px')
+    .style('text-anchor', 'middle')
+    .text(`mermaid version ${version}`);
 };
 
-export default {
-  setConf,
-  draw,
-};
+export const renderer = { draw };
+
+export default renderer;
diff --git a/packages/mermaid/src/diagrams/error/styles.js b/packages/mermaid/src/diagrams/error/styles.js
deleted file mode 100644
index 0b0729813d..0000000000
--- a/packages/mermaid/src/diagrams/error/styles.js
+++ /dev/null
@@ -1,3 +0,0 @@
-const getStyles = () => ``;
-
-export default getStyles;
diff --git a/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js b/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js
index 5ed06723e9..c7bfdf5246 100644
--- a/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js
+++ b/packages/mermaid/src/diagrams/flowchart/elk/flowRenderer-elk.js
@@ -655,14 +655,7 @@ const addMarkersToEdge = function (svgPath, edgeData, diagramType, arrowMarkerAb
  */
 export const getClasses = function (text, diagObj) {
   log.info('Extracting classes');
-  diagObj.db.clear('ver-2');
-  try {
-    // Parse the graph definition
-    diagObj.parse(text);
-    return diagObj.db.getClasses();
-  } catch (e) {
-    return {};
-  }
+  return diagObj.db.getClasses();
 };
 
 const addSubGraphs = function (db) {
@@ -766,14 +759,8 @@ const insertChildren = (nodeArray, parentLookupDb) => {
  */
 
 export const draw = async function (text, id, _version, diagObj) {
-  // Add temporary render element
-  diagObj.db.clear();
   nodeDb = {};
   portPos = {};
-  diagObj.db.setGen('gen-2');
-  // Parse the graph definition
-  diagObj.parser.parse(text);
-
   const renderEl = select('body').append('div').attr('style', 'height:400px').attr('id', 'cy');
   let graph = {
     id: 'root',
diff --git a/packages/mermaid/src/diagrams/flowchart/flowDiagram-v2.ts b/packages/mermaid/src/diagrams/flowchart/flowDiagram-v2.ts
index 7a2c0e0bc5..7540572115 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowDiagram-v2.ts
+++ b/packages/mermaid/src/diagrams/flowchart/flowDiagram-v2.ts
@@ -1,4 +1,4 @@
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import flowParser from './parser/flow.jison';
 import flowDb from './flowDb.js';
 import flowRendererV2 from './flowRenderer-v2.js';
diff --git a/packages/mermaid/src/diagrams/flowchart/flowDiagram.ts b/packages/mermaid/src/diagrams/flowchart/flowDiagram.ts
index 7018e4890d..2c331f4eb2 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowDiagram.ts
+++ b/packages/mermaid/src/diagrams/flowchart/flowDiagram.ts
@@ -1,4 +1,4 @@
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import flowParser from './parser/flow.jison';
 import flowDb from './flowDb.js';
 import flowRenderer from './flowRenderer.js';
diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
index 23f94942c2..4a3b7a8ce5 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
+++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
@@ -1,10 +1,7 @@
 import * as graphlib from 'dagre-d3-es/src/graphlib/index.js';
 import { select, curveLinear, selectAll } from 'd3';
-
-import flowDb from './flowDb.js';
 import { getConfig } from '../../config.js';
 import utils from '../../utils.js';
-
 import { render } from '../../dagre-wrapper/index.js';
 import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js';
 import { log } from '../../logger.js';
@@ -344,15 +341,7 @@ export const addEdges = function (edges, g, diagObj) {
  * @returns {object} ClassDef styles
  */
 export const getClasses = function (text, diagObj) {
-  log.info('Extracting classes');
-  diagObj.db.clear();
-  try {
-    // Parse the graph definition
-    diagObj.parse(text);
-    return diagObj.db.getClasses();
-  } catch (e) {
-    return;
-  }
+  return diagObj.db.getClasses();
 };
 
 /**
@@ -364,10 +353,6 @@ export const getClasses = function (text, diagObj) {
 
 export const draw = async function (text, id, _version, diagObj) {
   log.info('Drawing flowchart');
-  diagObj.db.clear();
-  flowDb.setGen('gen-2');
-  // Parse the graph definition
-  diagObj.parser.parse(text);
 
   // Fetch the default direction, use TD if none was found
   let dir = diagObj.db.getDirection();
diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js
index 4382aa9a44..fc06cacd4d 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js
+++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js
@@ -273,15 +273,7 @@ export const addEdges = function (edges, g, diagObj) {
  */
 export const getClasses = function (text, diagObj) {
   log.info('Extracting classes');
-  diagObj.db.clear();
-  try {
-    // Parse the graph definition
-    diagObj.parse(text);
-    return diagObj.db.getClasses();
-  } catch (e) {
-    log.error(e);
-    return {};
-  }
+  return diagObj.db.getClasses();
 };
 
 /**
@@ -294,7 +286,6 @@ export const getClasses = function (text, diagObj) {
  */
 export const draw = function (text, id, _version, diagObj) {
   log.info('Drawing flowchart');
-  diagObj.db.clear();
   const { securityLevel, flowchart: conf } = getConfig();
   let sandboxElement;
   if (securityLevel === 'sandbox') {
diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-edges.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-edges.spec.js
index dcac21ee75..21f3a43555 100644
--- a/packages/mermaid/src/diagrams/flowchart/parser/flow-edges.spec.js
+++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-edges.spec.js
@@ -6,6 +6,40 @@ setConfig({
   securityLevel: 'strict',
 });
 
+const keywords = [
+  'graph',
+  'flowchart',
+  'flowchart-elk',
+  'style',
+  'default',
+  'linkStyle',
+  'interpolate',
+  'classDef',
+  'class',
+  'href',
+  'call',
+  'click',
+  '_self',
+  '_blank',
+  '_parent',
+  '_top',
+  'end',
+  'subgraph',
+  'kitty',
+];
+
+const doubleEndedEdges = [
+  { edgeStart: 'x--', edgeEnd: '--x', stroke: 'normal', type: 'double_arrow_cross' },
+  { edgeStart: 'x==', edgeEnd: '==x', stroke: 'thick', type: 'double_arrow_cross' },
+  { edgeStart: 'x-.', edgeEnd: '.-x', stroke: 'dotted', type: 'double_arrow_cross' },
+  { edgeStart: 'o--', edgeEnd: '--o', stroke: 'normal', type: 'double_arrow_circle' },
+  { edgeStart: 'o==', edgeEnd: '==o', stroke: 'thick', type: 'double_arrow_circle' },
+  { edgeStart: 'o-.', edgeEnd: '.-o', stroke: 'dotted', type: 'double_arrow_circle' },
+  { edgeStart: '<--', edgeEnd: '-->', stroke: 'normal', type: 'double_arrow_point' },
+  { edgeStart: '<==', edgeEnd: '==>', stroke: 'thick', type: 'double_arrow_point' },
+  { edgeStart: '<-.', edgeEnd: '.->', stroke: 'dotted', type: 'double_arrow_point' },
+];
+
 describe('[Edges] when parsing', () => {
   beforeEach(function () {
     flow.parser.yy = flowDb;
@@ -39,211 +73,62 @@ describe('[Edges] when parsing', () => {
     expect(edges[0].type).toBe('arrow_circle');
   });
 
-  describe('cross', function () {
-    it('should handle double edged nodes and edges', function () {
-      const res = flow.parser.parse('graph TD;\nA x--x B;');
-
-      const vert = flow.parser.yy.getVertices();
-      const edges = flow.parser.yy.getEdges();
-
-      expect(vert['A'].id).toBe('A');
-      expect(vert['B'].id).toBe('B');
-      expect(edges.length).toBe(1);
-      expect(edges[0].start).toBe('A');
-      expect(edges[0].end).toBe('B');
-      expect(edges[0].type).toBe('double_arrow_cross');
-      expect(edges[0].text).toBe('');
-      expect(edges[0].stroke).toBe('normal');
-      expect(edges[0].length).toBe(1);
-    });
-
-    it('should handle double edged nodes with text', function () {
-      const res = flow.parser.parse('graph TD;\nA x-- text --x B;');
-
-      const vert = flow.parser.yy.getVertices();
-      const edges = flow.parser.yy.getEdges();
-
-      expect(vert['A'].id).toBe('A');
-      expect(vert['B'].id).toBe('B');
-      expect(edges.length).toBe(1);
-      expect(edges[0].start).toBe('A');
-      expect(edges[0].end).toBe('B');
-      expect(edges[0].type).toBe('double_arrow_cross');
-      expect(edges[0].text).toBe('text');
-      expect(edges[0].stroke).toBe('normal');
-      expect(edges[0].length).toBe(1);
-    });
-
-    it('should handle double edged nodes and edges on thick arrows', function () {
-      const res = flow.parser.parse('graph TD;\nA x==x B;');
-
-      const vert = flow.parser.yy.getVertices();
-      const edges = flow.parser.yy.getEdges();
-
-      expect(vert['A'].id).toBe('A');
-      expect(vert['B'].id).toBe('B');
-      expect(edges.length).toBe(1);
-      expect(edges[0].start).toBe('A');
-      expect(edges[0].end).toBe('B');
-      expect(edges[0].type).toBe('double_arrow_cross');
-      expect(edges[0].text).toBe('');
-      expect(edges[0].stroke).toBe('thick');
-      expect(edges[0].length).toBe(1);
-    });
-
-    it('should handle double edged nodes with text on thick arrows', function () {
-      const res = flow.parser.parse('graph TD;\nA x== text ==x B;');
-
-      const vert = flow.parser.yy.getVertices();
-      const edges = flow.parser.yy.getEdges();
-
-      expect(vert['A'].id).toBe('A');
-      expect(vert['B'].id).toBe('B');
-      expect(edges.length).toBe(1);
-      expect(edges[0].start).toBe('A');
-      expect(edges[0].end).toBe('B');
-      expect(edges[0].type).toBe('double_arrow_cross');
-      expect(edges[0].text).toBe('text');
-      expect(edges[0].stroke).toBe('thick');
-      expect(edges[0].length).toBe(1);
-    });
-
-    it('should handle double edged nodes and edges on dotted arrows', function () {
-      const res = flow.parser.parse('graph TD;\nA x-.-x B;');
-
-      const vert = flow.parser.yy.getVertices();
-      const edges = flow.parser.yy.getEdges();
-
-      expect(vert['A'].id).toBe('A');
-      expect(vert['B'].id).toBe('B');
-      expect(edges.length).toBe(1);
-      expect(edges[0].start).toBe('A');
-      expect(edges[0].end).toBe('B');
-      expect(edges[0].type).toBe('double_arrow_cross');
-      expect(edges[0].text).toBe('');
-      expect(edges[0].stroke).toBe('dotted');
-      expect(edges[0].length).toBe(1);
-    });
+  describe('edges', function () {
+    doubleEndedEdges.forEach((edgeType) => {
+      it(`should handle ${edgeType.stroke} ${edgeType.type} with no text`, function () {
+        const res = flow.parser.parse(`graph TD;\nA ${edgeType.edgeStart}${edgeType.edgeEnd} B;`);
 
-    it('should handle double edged nodes with text on dotted arrows', function () {
-      const res = flow.parser.parse('graph TD;\nA x-. text .-x B;');
-
-      const vert = flow.parser.yy.getVertices();
-      const edges = flow.parser.yy.getEdges();
-
-      expect(vert['A'].id).toBe('A');
-      expect(vert['B'].id).toBe('B');
-      expect(edges.length).toBe(1);
-      expect(edges[0].start).toBe('A');
-      expect(edges[0].end).toBe('B');
-      expect(edges[0].type).toBe('double_arrow_cross');
-      expect(edges[0].text).toBe('text');
-      expect(edges[0].stroke).toBe('dotted');
-      expect(edges[0].length).toBe(1);
-    });
-  });
-
-  describe('circle', function () {
-    it('should handle double edged nodes and edges', function () {
-      const res = flow.parser.parse('graph TD;\nA o--o B;');
-
-      const vert = flow.parser.yy.getVertices();
-      const edges = flow.parser.yy.getEdges();
-
-      expect(vert['A'].id).toBe('A');
-      expect(vert['B'].id).toBe('B');
-      expect(edges.length).toBe(1);
-      expect(edges[0].start).toBe('A');
-      expect(edges[0].end).toBe('B');
-      expect(edges[0].type).toBe('double_arrow_circle');
-      expect(edges[0].text).toBe('');
-      expect(edges[0].stroke).toBe('normal');
-      expect(edges[0].length).toBe(1);
-    });
+        const vert = flow.parser.yy.getVertices();
+        const edges = flow.parser.yy.getEdges();
 
-    it('should handle double edged nodes with text', function () {
-      const res = flow.parser.parse('graph TD;\nA o-- text --o B;');
-
-      const vert = flow.parser.yy.getVertices();
-      const edges = flow.parser.yy.getEdges();
-
-      expect(vert['A'].id).toBe('A');
-      expect(vert['B'].id).toBe('B');
-      expect(edges.length).toBe(1);
-      expect(edges[0].start).toBe('A');
-      expect(edges[0].end).toBe('B');
-      expect(edges[0].type).toBe('double_arrow_circle');
-      expect(edges[0].text).toBe('text');
-      expect(edges[0].stroke).toBe('normal');
-      expect(edges[0].length).toBe(1);
-    });
+        expect(vert['A'].id).toBe('A');
+        expect(vert['B'].id).toBe('B');
+        expect(edges.length).toBe(1);
+        expect(edges[0].start).toBe('A');
+        expect(edges[0].end).toBe('B');
+        expect(edges[0].type).toBe(`${edgeType.type}`);
+        expect(edges[0].text).toBe('');
+        expect(edges[0].stroke).toBe(`${edgeType.stroke}`);
+      });
 
-    it('should handle double edged nodes and edges on thick arrows', function () {
-      const res = flow.parser.parse('graph TD;\nA o==o B;');
-
-      const vert = flow.parser.yy.getVertices();
-      const edges = flow.parser.yy.getEdges();
-
-      expect(vert['A'].id).toBe('A');
-      expect(vert['B'].id).toBe('B');
-      expect(edges.length).toBe(1);
-      expect(edges[0].start).toBe('A');
-      expect(edges[0].end).toBe('B');
-      expect(edges[0].type).toBe('double_arrow_circle');
-      expect(edges[0].text).toBe('');
-      expect(edges[0].stroke).toBe('thick');
-      expect(edges[0].length).toBe(1);
-    });
+      it(`should handle ${edgeType.stroke} ${edgeType.type} with text`, function () {
+        const res = flow.parser.parse(
+          `graph TD;\nA ${edgeType.edgeStart} text ${edgeType.edgeEnd} B;`
+        );
 
-    it('should handle double edged nodes with text on thick arrows', function () {
-      const res = flow.parser.parse('graph TD;\nA o== text ==o B;');
-
-      const vert = flow.parser.yy.getVertices();
-      const edges = flow.parser.yy.getEdges();
-
-      expect(vert['A'].id).toBe('A');
-      expect(vert['B'].id).toBe('B');
-      expect(edges.length).toBe(1);
-      expect(edges[0].start).toBe('A');
-      expect(edges[0].end).toBe('B');
-      expect(edges[0].type).toBe('double_arrow_circle');
-      expect(edges[0].text).toBe('text');
-      expect(edges[0].stroke).toBe('thick');
-      expect(edges[0].length).toBe(1);
-    });
+        const vert = flow.parser.yy.getVertices();
+        const edges = flow.parser.yy.getEdges();
 
-    it('should handle double edged nodes and edges on dotted arrows', function () {
-      const res = flow.parser.parse('graph TD;\nA o-.-o B;');
-
-      const vert = flow.parser.yy.getVertices();
-      const edges = flow.parser.yy.getEdges();
-
-      expect(vert['A'].id).toBe('A');
-      expect(vert['B'].id).toBe('B');
-      expect(edges.length).toBe(1);
-      expect(edges[0].start).toBe('A');
-      expect(edges[0].end).toBe('B');
-      expect(edges[0].type).toBe('double_arrow_circle');
-      expect(edges[0].text).toBe('');
-      expect(edges[0].stroke).toBe('dotted');
-      expect(edges[0].length).toBe(1);
-    });
+        expect(vert['A'].id).toBe('A');
+        expect(vert['B'].id).toBe('B');
+        expect(edges.length).toBe(1);
+        expect(edges[0].start).toBe('A');
+        expect(edges[0].end).toBe('B');
+        expect(edges[0].type).toBe(`${edgeType.type}`);
+        expect(edges[0].text).toBe('text');
+        expect(edges[0].stroke).toBe(`${edgeType.stroke}`);
+      });
 
-    it('should handle double edged nodes with text on dotted arrows', function () {
-      const res = flow.parser.parse('graph TD;\nA o-. text .-o B;');
-
-      const vert = flow.parser.yy.getVertices();
-      const edges = flow.parser.yy.getEdges();
-
-      expect(vert['A'].id).toBe('A');
-      expect(vert['B'].id).toBe('B');
-      expect(edges.length).toBe(1);
-      expect(edges[0].start).toBe('A');
-      expect(edges[0].end).toBe('B');
-      expect(edges[0].type).toBe('double_arrow_circle');
-      expect(edges[0].text).toBe('text');
-      expect(edges[0].stroke).toBe('dotted');
-      expect(edges[0].length).toBe(1);
+      it.each(keywords)(
+        `should handle ${edgeType.stroke} ${edgeType.type} with %s text`,
+        function (keyword) {
+          const res = flow.parser.parse(
+            `graph TD;\nA ${edgeType.edgeStart} ${keyword} ${edgeType.edgeEnd} B;`
+          );
+
+          const vert = flow.parser.yy.getVertices();
+          const edges = flow.parser.yy.getEdges();
+
+          expect(vert['A'].id).toBe('A');
+          expect(vert['B'].id).toBe('B');
+          expect(edges.length).toBe(1);
+          expect(edges[0].start).toBe('A');
+          expect(edges[0].end).toBe('B');
+          expect(edges[0].type).toBe(`${edgeType.type}`);
+          expect(edges[0].text).toBe(`${keyword}`);
+          expect(edges[0].stroke).toBe(`${edgeType.stroke}`);
+        }
+      );
     });
   });
 
diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-md-string.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-md-string.spec.js
index 0e6efaef19..13cb262e3a 100644
--- a/packages/mermaid/src/diagrams/flowchart/parser/flow-md-string.spec.js
+++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-md-string.spec.js
@@ -24,7 +24,7 @@ A["\`The cat in **the** hat\`"]-- "\`The *bat* in the chat\`" -->B["The dog in t
     expect(vert['A'].labelType).toBe('markdown');
     expect(vert['B'].id).toBe('B');
     expect(vert['B'].text).toBe('The dog in the hog');
-    expect(vert['B'].labelType).toBe('text');
+    expect(vert['B'].labelType).toBe('string');
     expect(edges.length).toBe(2);
     expect(edges[0].start).toBe('A');
     expect(edges[0].end).toBe('B');
@@ -35,7 +35,7 @@ A["\`The cat in **the** hat\`"]-- "\`The *bat* in the chat\`" -->B["The dog in t
     expect(edges[1].end).toBe('C');
     expect(edges[1].type).toBe('arrow_point');
     expect(edges[1].text).toBe('The rat in the mat');
-    expect(edges[1].labelType).toBe('text');
+    expect(edges[1].labelType).toBe('string');
   });
   it('mardown formatting in subgraphs', function () {
     const res = flow.parser.parse(`flowchart LR
diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-singlenode.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-singlenode.spec.js
index b959f019ea..59336d8d48 100644
--- a/packages/mermaid/src/diagrams/flowchart/parser/flow-singlenode.spec.js
+++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-singlenode.spec.js
@@ -6,6 +6,29 @@ setConfig({
   securityLevel: 'strict',
 });
 
+const keywords = [
+  'graph',
+  'flowchart',
+  'flowchart-elk',
+  'style',
+  'default',
+  'linkStyle',
+  'interpolate',
+  'classDef',
+  'class',
+  'href',
+  'call',
+  'click',
+  '_self',
+  '_blank',
+  '_parent',
+  '_top',
+  'end',
+  'subgraph',
+];
+
+const specialChars = ['#', ':', '0', '&', ',', '*', '.', '\\', 'v', '-', '/', '_'];
+
 describe('[Singlenodes] when parsing', () => {
   beforeEach(function () {
     flow.parser.yy = flowDb;
@@ -259,4 +282,90 @@ describe('[Singlenodes] when parsing', () => {
     expect(edges.length).toBe(0);
     expect(vert['i_d'].styles.length).toBe(0);
   });
+
+  it.each(keywords)('should handle keywords between dashes "-"', function (keyword) {
+    const res = flow.parser.parse(`graph TD;a-${keyword}-node;`);
+    const vert = flow.parser.yy.getVertices();
+    expect(vert[`a-${keyword}-node`].text).toBe(`a-${keyword}-node`);
+  });
+
+  it.each(keywords)('should handle keywords between periods "."', function (keyword) {
+    const res = flow.parser.parse(`graph TD;a.${keyword}.node;`);
+    const vert = flow.parser.yy.getVertices();
+    expect(vert[`a.${keyword}.node`].text).toBe(`a.${keyword}.node`);
+  });
+
+  it.each(keywords)('should handle keywords between underscores "_"', function (keyword) {
+    const res = flow.parser.parse(`graph TD;a_${keyword}_node;`);
+    const vert = flow.parser.yy.getVertices();
+    expect(vert[`a_${keyword}_node`].text).toBe(`a_${keyword}_node`);
+  });
+
+  it.each(keywords)('should handle nodes ending in %s', function (keyword) {
+    const res = flow.parser.parse(`graph TD;node_${keyword};node.${keyword};node-${keyword};`);
+    const vert = flow.parser.yy.getVertices();
+    expect(vert[`node_${keyword}`].text).toBe(`node_${keyword}`);
+    expect(vert[`node.${keyword}`].text).toBe(`node.${keyword}`);
+    expect(vert[`node-${keyword}`].text).toBe(`node-${keyword}`);
+  });
+
+  const errorKeywords = [
+    'graph',
+    'flowchart',
+    'flowchart-elk',
+    'style',
+    'linkStyle',
+    'interpolate',
+    'classDef',
+    'class',
+    '_self',
+    '_blank',
+    '_parent',
+    '_top',
+    'end',
+    'subgraph',
+  ];
+  it.each(errorKeywords)('should throw error at nodes beginning with %s', function (keyword) {
+    const str = `graph TD;${keyword}.node;${keyword}-node;${keyword}/node`;
+    const vert = flow.parser.yy.getVertices();
+
+    expect(() => flow.parser.parse(str)).toThrowError();
+  });
+
+  const workingKeywords = ['default', 'href', 'click', 'call'];
+
+  it.each(workingKeywords)('should parse node beginning with %s', function (keyword) {
+    flow.parser.parse(`graph TD; ${keyword}.node;${keyword}-node;${keyword}/node;`);
+    const vert = flow.parser.yy.getVertices();
+    expect(vert[`${keyword}.node`].text).toBe(`${keyword}.node`);
+    expect(vert[`${keyword}-node`].text).toBe(`${keyword}-node`);
+    expect(vert[`${keyword}/node`].text).toBe(`${keyword}/node`);
+  });
+
+  it.each(specialChars)(
+    'should allow node ids of single special characters',
+    function (specialChar) {
+      flow.parser.parse(`graph TD; ${specialChar} --> A`);
+      const vert = flow.parser.yy.getVertices();
+      expect(vert[`${specialChar}`].text).toBe(`${specialChar}`);
+    }
+  );
+
+  it.each(specialChars)(
+    'should allow node ids with special characters at start of id',
+    function (specialChar) {
+      flow.parser.parse(`graph TD; ${specialChar}node --> A`);
+      const vert = flow.parser.yy.getVertices();
+      expect(vert[`${specialChar}node`].text).toBe(`${specialChar}node`);
+    }
+  );
+
+  it.each(specialChars)(
+    'should allow node ids with special characters at end of id',
+    function (specialChar) {
+      flow.parser.parse(`graph TD; node${specialChar} --> A`);
+      const vert = flow.parser.yy.getVertices();
+      expect(vert[`node${specialChar}`].text).toBe(`node${specialChar}`);
+    }
+  );
 });
diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-style.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-style.spec.js
index 3feaa2469e..1ab7543085 100644
--- a/packages/mermaid/src/diagrams/flowchart/parser/flow-style.spec.js
+++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-style.spec.js
@@ -26,15 +26,6 @@ describe('[Style] when parsing', () => {
     expect(vert['Q'].styles[0]).toBe('background:#fff');
   });
 
-  // log.debug(flow.parser.parse('graph TD;style Q background:#fff;'));
-  it('should handle styles for edges', function () {
-    const res = flow.parser.parse('graph TD;a-->b;\nstyle #0 stroke: #f66;');
-
-    const edges = flow.parser.yy.getEdges();
-
-    expect(edges.length).toBe(1);
-  });
-
   it('should handle multiple styles for a vortex', function () {
     const res = flow.parser.parse('graph TD;style R background:#fff,border:1px solid red;');
 
diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow-text.spec.js b/packages/mermaid/src/diagrams/flowchart/parser/flow-text.spec.js
index db43e75bf1..b127e1b65d 100644
--- a/packages/mermaid/src/diagrams/flowchart/parser/flow-text.spec.js
+++ b/packages/mermaid/src/diagrams/flowchart/parser/flow-text.spec.js
@@ -305,6 +305,95 @@ describe('[Text] when parsing', () => {
       expect(vert['C'].type).toBe('round');
       expect(vert['C'].text).toBe('Chimpansen hoppar');
     });
+
+    const keywords = [
+      'graph',
+      'flowchart',
+      'flowchart-elk',
+      'style',
+      'default',
+      'linkStyle',
+      'interpolate',
+      'classDef',
+      'class',
+      'href',
+      'call',
+      'click',
+      '_self',
+      '_blank',
+      '_parent',
+      '_top',
+      'end',
+      'subgraph',
+      'kitty',
+    ];
+
+    const shapes = [
+      { start: '[', end: ']', name: 'square' },
+      { start: '(', end: ')', name: 'round' },
+      { start: '{', end: '}', name: 'diamond' },
+      { start: '(-', end: '-)', name: 'ellipse' },
+      { start: '([', end: '])', name: 'stadium' },
+      { start: '>', end: ']', name: 'odd' },
+      { start: '[(', end: ')]', name: 'cylinder' },
+      { start: '(((', end: ')))', name: 'doublecircle' },
+      { start: '[/', end: '\\]', name: 'trapezoid' },
+      { start: '[\\', end: '/]', name: 'inv_trapezoid' },
+      { start: '[/', end: '/]', name: 'lean_right' },
+      { start: '[\\', end: '\\]', name: 'lean_left' },
+      { start: '[[', end: ']]', name: 'subroutine' },
+      { start: '{{', end: '}}', name: 'hexagon' },
+    ];
+
+    shapes.forEach((shape) => {
+      it.each(keywords)(`should handle %s keyword in ${shape.name} vertex`, function (keyword) {
+        const rest = flow.parser.parse(
+          `graph TD;A_${keyword}_node-->B${shape.start}This node has a ${keyword} as text${shape.end};`
+        );
+
+        const vert = flow.parser.yy.getVertices();
+        const edges = flow.parser.yy.getEdges();
+        expect(vert['B'].type).toBe(`${shape.name}`);
+        expect(vert['B'].text).toBe(`This node has a ${keyword} as text`);
+      });
+    });
+
+    it.each(keywords)('should handle %s keyword in rect vertex', function (keyword) {
+      const rest = flow.parser.parse(
+        `graph TD;A_${keyword}_node-->B[|borders:lt|This node has a ${keyword} as text];`
+      );
+
+      const vert = flow.parser.yy.getVertices();
+      const edges = flow.parser.yy.getEdges();
+      expect(vert['B'].type).toBe('rect');
+      expect(vert['B'].text).toBe(`This node has a ${keyword} as text`);
+    });
+
+    it('should handle edge case for odd vertex with node id ending with minus', function () {
+      const res = flow.parser.parse('graph TD;A_node-->odd->Vertex Text];');
+      const vert = flow.parser.yy.getVertices();
+
+      expect(vert['odd-'].type).toBe('odd');
+      expect(vert['odd-'].text).toBe('Vertex Text');
+    });
+    it('should allow forward slashes in lean_right vertices', function () {
+      const rest = flow.parser.parse(`graph TD;A_node-->B[/This node has a / as text/];`);
+
+      const vert = flow.parser.yy.getVertices();
+      const edges = flow.parser.yy.getEdges();
+      expect(vert['B'].type).toBe('lean_right');
+      expect(vert['B'].text).toBe(`This node has a / as text`);
+    });
+
+    it('should allow back slashes in lean_left vertices', function () {
+      const rest = flow.parser.parse(`graph TD;A_node-->B[\\This node has a \\ as text\\];`);
+
+      const vert = flow.parser.yy.getVertices();
+      const edges = flow.parser.yy.getEdges();
+      expect(vert['B'].type).toBe('lean_left');
+      expect(vert['B'].text).toBe(`This node has a \\ as text`);
+    });
+
     it('should handle åäö and minus', function () {
       const res = flow.parser.parse('graph TD;A-->C{Chimpansen hoppar åäö-ÅÄÖ};');
 
@@ -484,4 +573,33 @@ describe('[Text] when parsing', () => {
     expect(vert['A'].text).toBe(',.?!+-*');
     expect(edges[0].text).toBe(',.?!+-*');
   });
+
+  it('should throw error at nested set of brackets', function () {
+    const str = 'graph TD; A[This is a () in text];';
+    expect(() => flow.parser.parse(str)).toThrowError("got 'PS'");
+  });
+
+  it('should throw error for strings and text at the same time', function () {
+    const str = 'graph TD;A(this node has "string" and text)-->|this link has "string" and text|C;';
+
+    expect(() => flow.parser.parse(str)).toThrowError("got 'STR'");
+  });
+
+  it('should throw error for escaping quotes in text state', function () {
+    //prettier-ignore
+    const str = 'graph TD; A[This is a \"()\" in text];'; //eslint-disable-line no-useless-escape
+
+    expect(() => flow.parser.parse(str)).toThrowError("got 'STR'");
+  });
+
+  it('should throw error for nested quoatation marks', function () {
+    const str = 'graph TD; A["This is a "()" in text"];';
+
+    expect(() => flow.parser.parse(str)).toThrowError("Expecting 'SQE'");
+  });
+
+  it('should throw error', function () {
+    const str = `graph TD; node[hello ) world] --> works`;
+    expect(() => flow.parser.parse(str)).toThrowError("got 'PE'");
+  });
 });
diff --git a/packages/mermaid/src/diagrams/flowchart/parser/flow.jison b/packages/mermaid/src/diagrams/flowchart/parser/flow.jison
index 70fb491625..8d746f8082 100644
--- a/packages/mermaid/src/diagrams/flowchart/parser/flow.jison
+++ b/packages/mermaid/src/diagrams/flowchart/parser/flow.jison
@@ -13,6 +13,12 @@
 %x acc_descr_multiline
 %x dir
 %x vertex
+%x text
+%x ellipseText
+%x trapText
+%x edgeText
+%x thickEdgeText
+%x dottedEdgeText
 %x click
 %x href
 %x callbackname
@@ -23,41 +29,19 @@
 %x close_directive
 
 %%
-\%\%\{                                                          { this.begin('open_directive'); return 'open_directive'; }
-((?:(?!\}\%\%)[^:.])*)                          { this.begin('type_directive'); return 'type_directive'; }
-":"                                             { this.popState(); this.begin('arg_directive'); return ':'; }
-\}\%\%                            { this.popState(); this.popState(); return 'close_directive'; }
-((?:(?!\}\%\%).|\n)*)                            return 'arg_directive';
-accTitle\s*":"\s*                                               { this.begin("acc_title");return 'acc_title'; }
-(?!\n|;|#)*[^\n]*                                    { this.popState(); return "acc_title_value"; }
-accDescr\s*":"\s*                                               { this.begin("acc_descr");return 'acc_descr'; }
-(?!\n|;|#)*[^\n]*                                    { this.popState(); return "acc_descr_value"; }
-accDescr\s*"{"\s*                                { this.begin("acc_descr_multiline");}
+\%\%\{                                          { this.begin('open_directive'); return 'open_directive'; }
+((?:(?!\}\%\%)[^:.])*)          { this.begin('type_directive'); return 'type_directive'; }
+":"                             { this.popState(); this.begin('arg_directive'); return ':'; }
+\}\%\%            { this.popState(); this.popState(); return 'close_directive'; }
+((?:(?!\}\%\%).|\n)*)            return 'arg_directive';
+accTitle\s*":"\s*                               { this.begin("acc_title");return 'acc_title'; }
+(?!\n|;|#)*[^\n]*                    { this.popState(); return "acc_title_value"; }
+accDescr\s*":"\s*                               { this.begin("acc_descr");return 'acc_descr'; }
+(?!\n|;|#)*[^\n]*                    { this.popState(); return "acc_descr_value"; }
+accDescr\s*"{"\s*                               { this.begin("acc_descr_multiline");}
 [\}]                       { this.popState(); }
 [^\}]*                     return "acc_descr_multiline_value";
-// .*[^\n]*                    {  return "acc_descr_line"}
-["][`]          { this.begin("md_string");}
-[^`"]+        { return "MD_STR";}
-[`]["]          { this.popState();}
-["]                     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';
-
-/*
----interactivity command---
-'href' adds a link to the specified node. 'href' can only be specified when the
-line was introduced with 'click'.
-'href ""' attaches the specified link to the node that was specified by 'click'.
-*/
-"href"[\s]+["]          this.begin("href");
-["]               this.popState();
-[^"]*             return 'HREF';
+// .*[^\n]*                {  return "acc_descr_line"}
 
 /*
 ---interactivity command---
@@ -74,88 +58,128 @@ Function arguments are optional: 'call ()' simply executes 'callba
 \)        this.popState();
 [^)]*     return 'CALLBACKARGS';
 
+[^`"]+       { return "MD_STR";}
+[`]["]       { this.popState();}
+<*>["][`]               { this.begin("md_string");}
+[^"]+           return "STR";
+["]             this.popState();
+<*>["]                  this.pushState("string");
+"style"                 return 'STYLE';
+"default"               return 'DEFAULT';
+"linkStyle"             return 'LINKSTYLE';
+"interpolate"           return 'INTERPOLATE';
+"classDef"              return 'CLASSDEF';
+"class"                 return 'CLASS';
+
+/*
+---interactivity command---
+'href' adds a link to the specified node. 'href' can only be specified when the
+line was introduced with 'click'.
+'href ""' attaches the specified link to the node that was specified by 'click'.
+*/
+"href"[\s]                  return 'HREF';
+
+
 /*
 'click' is the keyword to introduce a line that contains interactivity commands.
 'click' must be followed by an existing node-id. All commands are attached to
 that id.
 'click ' can be followed by href or call commands in any desired order
 */
-"click"[\s]+            this.begin("click");
-[\s\n]           this.popState();
-[^\s\n]*         return 'CLICK';
-
-"flowchart-elk"        {if(yy.lex.firstGraph()){this.begin("dir");}  return 'GRAPH';}
-"graph"                {if(yy.lex.firstGraph()){this.begin("dir");}  return 'GRAPH';}
-"flowchart"            {if(yy.lex.firstGraph()){this.begin("dir");}  return 'GRAPH';}
-"subgraph"            return 'subgraph';
-"end"\b\s*            return 'end';
-
-"_self"               return 'LINK_TARGET';
-"_blank"              return 'LINK_TARGET';
-"_parent"             return 'LINK_TARGET';
-"_top"                return 'LINK_TARGET';
-
-(\r?\n)*\s*\n       {   this.popState();  return 'NODIR'; }
-\s*"LR"             {   this.popState();  return 'DIR'; }
-\s*"RL"             {   this.popState();  return 'DIR'; }
-\s*"TB"             {   this.popState();  return 'DIR'; }
-\s*"BT"             {   this.popState();  return 'DIR'; }
-\s*"TD"             {   this.popState();  return 'DIR'; }
-\s*"BR"             {   this.popState();  return 'DIR'; }
-\s*"<"              {   this.popState();  return 'DIR'; }
-\s*">"              {   this.popState();  return 'DIR'; }
-\s*"^"              {   this.popState();  return 'DIR'; }
-\s*"v"              {   this.popState();  return 'DIR'; }
-
-.*direction\s+TB[^\n]*                                      return 'direction_tb';
-.*direction\s+BT[^\n]*                                      return 'direction_bt';
-.*direction\s+RL[^\n]*                                      return 'direction_rl';
-.*direction\s+LR[^\n]*                                      return 'direction_lr';
-
-[0-9]+                { return 'NUM';}
-\#                    return 'BRKT';
-":::"                 return 'STYLE_SEPARATOR';
-":"                   return 'COLON';
-"&"                   return 'AMP';
-";"                   return 'SEMI';
-","                   return 'COMMA';
-"*"                   return 'MULT';
-\s*[xo<]?\-\-+[-xo>]\s*     return 'LINK';
-\s*[xo<]?\=\=+[=xo>]\s*     return 'LINK';
-\s*[xo<]?\-?\.+\-[xo>]?\s*  return 'LINK';
-\s*\~\~[\~]+\s*  return 'LINK';
-\s*[xo<]?\-\-\s*            return 'START_LINK';
-\s*[xo<]?\=\=\s*            return 'START_LINK';
-\s*[xo<]?\-\.\s*            return 'START_LINK';
-"(-"                  return '(-';
-"-)"                  return '-)';
-"(["                  return 'STADIUMSTART';
-"])"                  return 'STADIUMEND';
-"[["                  return 'SUBROUTINESTART';
-"]]"                  return 'SUBROUTINEEND';
-"[|"                  return 'VERTEX_WITH_PROPS_START';
-"[("                  return 'CYLINDERSTART';
-")]"                  return 'CYLINDEREND';
-"((("                 return 'DOUBLECIRCLESTART';
-")))"                 return 'DOUBLECIRCLEEND';
-\-                    return 'MINUS';
-"."                   return 'DOT';
-[\_]                  return 'UNDERSCORE';
-\+                    return 'PLUS';
-\%                    return 'PCT';
-"="                   return 'EQUALS';
-\=                    return 'EQUALS';
+"click"[\s]+             this.begin("click");
+[\s\n]            this.popState();
+[^\s\n]*          return 'CLICK';
+
+"flowchart-elk"          {if(yy.lex.firstGraph()){this.begin("dir");}  return 'GRAPH';}
+"graph"                  {if(yy.lex.firstGraph()){this.begin("dir");}  return 'GRAPH';}
+"flowchart"              {if(yy.lex.firstGraph()){this.begin("dir");}  return 'GRAPH';}
+"subgraph"               return 'subgraph';
+"end"\b\s*               return 'end';
+
+"_self"                  return 'LINK_TARGET';
+"_blank"                 return 'LINK_TARGET';
+"_parent"                return 'LINK_TARGET';
+"_top"                   return 'LINK_TARGET';
+
+(\r?\n)*\s*\n       { this.popState();  return 'NODIR'; }
+\s*"LR"             { this.popState();  return 'DIR'; }
+\s*"RL"             { this.popState();  return 'DIR'; }
+\s*"TB"             { this.popState();  return 'DIR'; }
+\s*"BT"             { this.popState();  return 'DIR'; }
+\s*"TD"             { this.popState();  return 'DIR'; }
+\s*"BR"             { this.popState();  return 'DIR'; }
+\s*"<"              { this.popState();  return 'DIR'; }
+\s*">"              { this.popState();  return 'DIR'; }
+\s*"^"              { this.popState();  return 'DIR'; }
+\s*"v"              { this.popState();  return 'DIR'; }
+
+.*direction\s+TB[^\n]*       return 'direction_tb';
+.*direction\s+BT[^\n]*       return 'direction_bt';
+.*direction\s+RL[^\n]*       return 'direction_rl';
+.*direction\s+LR[^\n]*       return 'direction_lr';
+
+[0-9]+                       return 'NUM';
+\#                           return 'BRKT';
+":::"                        return 'STYLE_SEPARATOR';
+":"                          return 'COLON';
+"&"                          return 'AMP';
+";"                          return 'SEMI';
+","                          return 'COMMA';
+"*"                          return 'MULT';
+
+\s*[xo<]?\-\-+[-xo>]\s*          { this.popState(); return 'LINK'; }
+\s*[xo<]?\-\-\s*                          { this.pushState("edgeText"); return 'START_LINK'; }
+[^-]|\-(?!\-)+                           return 'EDGE_TEXT';
+
+\s*[xo<]?\=\=+[=xo>]\s*      { this.popState(); return 'LINK'; }
+\s*[xo<]?\=\=\s*                           { this.pushState("thickEdgeText"); return 'START_LINK'; }
+[^=]|\=(?!=)                         return 'EDGE_TEXT';
+
+\s*[xo<]?\-?\.+\-[xo>]?\s*   { this.popState(); return 'LINK'; }
+\s*[xo<]?\-\.\s*                            { this.pushState("dottedEdgeText"); return 'START_LINK'; }
+[^\.]|\.(?!-)                        return 'EDGE_TEXT';
+
+
+<*>\s*\~\~[\~]+\s*              return 'LINK';
+
+[-/\)][\)]         { this.popState(); return '-)'; }
+[^\(\)\[\]\{\}]|-/!\)+       return "TEXT"
+<*>"(-"                         { this.pushState("ellipseText"); return '(-'; }
+
+"])"                { this.popState(); return 'STADIUMEND'; }
+<*>"(["                   { this.pushState("text"); return 'STADIUMSTART'; }
+
+"]]"                { this.popState(); return 'SUBROUTINEEND'; }
+<*>"[["                   { this.pushState("text"); return 'SUBROUTINESTART'; }
+
+"[|"                      { return 'VERTEX_WITH_PROPS_START'; }
+
+\>                    { this.pushState("text"); return 'TAGEND'; }
+
+")]"                { this.popState(); return 'CYLINDEREND'; }
+<*>"[("                   { this.pushState("text") ;return 'CYLINDERSTART'; }
+
+")))"               { this.popState(); return 'DOUBLECIRCLEEND'; }
+<*>"((("                  { this.pushState("text"); return 'DOUBLECIRCLESTART'; }
+
+[\\(?=\])][\]]  { this.popState(); return 'TRAPEND'; }
+\/(?=\])\]     { this.popState(); return 'INVTRAPEND'; }
+\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+        return 'TEXT';
+<*>"[/"                   { this.pushState("trapText"); return 'TRAPSTART'; }
+
+<*>"[\\"                 { this.pushState("trapText"); return 'INVTRAPSTART'; }
+
+
 "<"                   return 'TAGSTART';
 ">"                   return 'TAGEND';
 "^"                   return 'UP';
 "\|"                  return 'SEP';
 "v"                   return 'DOWN';
-[A-Za-z]+             return 'ALPHA';
-"\\]"                 return 'TRAPEND';
-"[/"                  return 'TRAPSTART';
-"/]"                  return 'INVTRAPEND';
-"[\\"                 return 'INVTRAPSTART';
-[!"#$%&'*+,-.`?\\_/]  return 'PUNCTUATION';
+"*"                   return 'MULT';
+"#"                   return 'BRKT';
+"&"                   return 'AMP';
+([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|\-(?=[^\>\-\.])|=(?!=))+  return 'NODE_STRING';
+"-"                   return 'MINUS'
 [\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]|
@@ -218,13 +242,20 @@ that id.
 [\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'
+
+"|"             { this.popState(); return 'PIPE'; }
+<*>"|"                { this.pushState("text"); return 'PIPE'; }
+
+")"             { this.popState(); return 'PE'; }
+<*>"("                { this.pushState("text"); return 'PS'; }
+
+"]"            { this.popState(); return 'SQE'; }
+<*>"["                { this.pushState("text"); return 'SQS'; }
+
+(\})            { this.popState(); return 'DIAMOND_STOP' }
+<*>"{"                { this.pushState("text"); return 'DIAMOND_START' }
+[^\[\]\(\)\{\}\|\"]+    return "TEXT";
+
 "\""                  return 'QUOTE';
 (\r?\n)+              return 'NEWLINE';
 \s                    return 'SPACE';
@@ -255,11 +286,11 @@ openDirective
   ;
 
 typeDirective
-  : type_directive { yy.parseDirective($1, 'type_directive'); }
+  : type_directive { yy.parseDirective($type_directive, 'type_directive'); }
   ;
 
 argDirective
-  : arg_directive { $1 = $1.trim().replace(/'/g, '"'); yy.parseDirective($1, 'arg_directive'); }
+  : arg_directive { $arg_directive = $arg_directive.trim().replace(/'/g, '"'); yy.parseDirective($arg_directive, 'arg_directive'); }
   ;
 
 closeDirective
@@ -275,15 +306,15 @@ document
 	{ $$ = [];}
 	| document line
 	{
-	    if(!Array.isArray($2) || $2.length > 0){
-	        $1.push($2);
+	    if(!Array.isArray($line) || $line.length > 0){
+	        $document.push($line);
 	    }
-	    $$=$1;}
+	    $$=$document;}
 	;
 
 line
 	: statement
-	{$$=$1;}
+	{$$=$statement;}
 	| SEMI
 	| NEWLINE
 	| SPACE
@@ -296,15 +327,15 @@ graphConfig
     | GRAPH NODIR
         { yy.setDirection('TB');$$ = 'TB';}
     | GRAPH DIR FirstStmtSeperator
-        { yy.setDirection($2);$$ = $2;}
+        { yy.setDirection($DIR);$$ = $DIR;}
     // | GRAPH SPACE TAGEND FirstStmtSeperator
-    //     { yy.setDirection("LR");$$ = $3;}
+    //     { yy.setDirection("LR");$$ = $TAGEND;}
     // | GRAPH SPACE TAGSTART FirstStmtSeperator
-    //     { yy.setDirection("RL");$$ = $3;}
+    //     { yy.setDirection("RL");$$ = $TAGSTART;}
     // | GRAPH SPACE UP FirstStmtSeperator
-    //     { yy.setDirection("BT");$$ = $3;}
+    //     { yy.setDirection("BT");$$ = $UP;}
     // | GRAPH SPACE DOWN FirstStmtSeperator
-    //     { yy.setDirection("TB");$$ = $3;}
+    //     { yy.setDirection("TB");$$ = $DOWN;}
     ;
 
 ending: endToken ending
@@ -332,7 +363,7 @@ spaceList
 
 statement
     : verticeStatement separator
-    { /* console.warn('finat vs', $1.nodes); */ $$=$1.nodes}
+    { /* console.warn('finat vs', $verticeStatement.nodes); */ $$=$verticeStatement.nodes}
     | styleStatement separator
     {$$=[];}
     | linkStyleStatement separator
@@ -343,110 +374,121 @@ statement
     {$$=[];}
     | clickStatement separator
     {$$=[];}
-    | subgraph SPACE text SQS text SQE separator document end
-    {$$=yy.addSubGraph($3,$8,$5);}
-    | subgraph SPACE text separator document end
-    {$$=yy.addSubGraph($3,$5,$3);}
-    // | subgraph SPACE text separator document end
-    // {$$=yy.addSubGraph($3,$5,$3);}
+    | subgraph SPACE textNoTags SQS text SQE separator document end
+    {$$=yy.addSubGraph($textNoTags,$document,$text);}
+    | subgraph SPACE textNoTags separator document end
+    {$$=yy.addSubGraph($textNoTags,$document,$textNoTags);}
+    // | subgraph SPACE textNoTags separator document end
+    // {$$=yy.addSubGraph($textNoTags,$document,$textNoTags);}
     | subgraph separator document end
-    {$$=yy.addSubGraph(undefined,$3,undefined);}
+    {$$=yy.addSubGraph(undefined,$document,undefined);}
     | direction
-    | acc_title acc_title_value  { $$=$2.trim();yy.setAccTitle($$); }
-    | acc_descr acc_descr_value  { $$=$2.trim();yy.setAccDescription($$); }
-    | acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
+    | acc_title acc_title_value  { $$=$acc_title_value.trim();yy.setAccTitle($$); }
+    | acc_descr acc_descr_value  { $$=$acc_descr_value.trim();yy.setAccDescription($$); }
+    | acc_descr_multiline_value { $$=$acc_descr_multiline_value.trim();yy.setAccDescription($$); }
     ;
 
 separator: NEWLINE | SEMI | EOF ;
 
- 
+
 verticeStatement: verticeStatement link node
-        { /* console.warn('vs',$1.stmt,$3); */ yy.addLink($1.stmt,$3,$2); $$ = { stmt: $3, nodes: $3.concat($1.nodes) } }
+        { /* console.warn('vs',$verticeStatement.stmt,$node); */ yy.addLink($verticeStatement.stmt,$node,$link); $$ = { stmt: $node, nodes: $node.concat($verticeStatement.nodes) } }
     |  verticeStatement link node spaceList
-        { /* console.warn('vs',$1.stmt,$3); */ yy.addLink($1.stmt,$3,$2); $$ = { stmt: $3, nodes: $3.concat($1.nodes) } }
-    |node spaceList {/*console.warn('noda', $1);*/ $$ = {stmt: $1, nodes:$1 }}
-    |node { /*console.warn('noda', $1);*/ $$ = {stmt: $1, nodes:$1 }}
+        { /* console.warn('vs',$verticeStatement.stmt,$node); */ yy.addLink($verticeStatement.stmt,$node,$link); $$ = { stmt: $node, nodes: $node.concat($verticeStatement.nodes) } }
+    |node spaceList {/*console.warn('noda', $node);*/ $$ = {stmt: $node, nodes:$node }}
+    |node { /*console.warn('noda', $node);*/ $$ = {stmt: $node, nodes:$node }}
     ;
 
 node: styledVertex
-        { /* console.warn('nod', $1); */ $$ = [$1];}
+        { /* console.warn('nod', $styledVertex); */ $$ = [$styledVertex];}
     | node spaceList AMP spaceList styledVertex
-        { $$ = $1.concat($5); /* console.warn('pip', $1[0], $5, $$); */ }
+        { $$ = $node.concat($styledVertex); /* console.warn('pip', $node[0], $styledVertex, $$); */ }
     ;
 
 styledVertex: vertex
-        { /* console.warn('nod', $1); */ $$ = $1;}
+        { /* console.warn('nod', $vertex); */ $$ = $vertex;}
     | vertex STYLE_SEPARATOR idString
-        {$$ = $1;yy.setClass($1,$3)}
+        {$$ = $vertex;yy.setClass($vertex,$idString)}
     ;
 
 vertex:  idString SQS text SQE
-        {$$ = $1;yy.addVertex($1,$3,'square');}
+        {$$ = $idString;yy.addVertex($idString,$text,'square');}
     | idString DOUBLECIRCLESTART text DOUBLECIRCLEEND
-        {$$ = $1;yy.addVertex($1,$3,'doublecircle');}
+        {$$ = $idString;yy.addVertex($idString,$text,'doublecircle');}
     | idString PS PS text PE PE
-        {$$ = $1;yy.addVertex($1,$4,'circle');}
+        {$$ = $idString;yy.addVertex($idString,$text,'circle');}
     | idString '(-' text '-)'
-        {$$ = $1;yy.addVertex($1,$3,'ellipse');}
+        {$$ = $idString;yy.addVertex($idString,$text,'ellipse');}
     | idString STADIUMSTART text STADIUMEND
-        {$$ = $1;yy.addVertex($1,$3,'stadium');}
+        {$$ = $idString;yy.addVertex($idString,$text,'stadium');}
     | idString SUBROUTINESTART text SUBROUTINEEND
-        {$$ = $1;yy.addVertex($1,$3,'subroutine');}
-    | idString VERTEX_WITH_PROPS_START ALPHA COLON ALPHA PIPE text SQE
-        {$$ = $1;yy.addVertex($1,$7,'rect',undefined,undefined,undefined, Object.fromEntries([[$3, $5]]));}
+        {$$ = $idString;yy.addVertex($idString,$text,'subroutine');}
+    | idString VERTEX_WITH_PROPS_START NODE_STRING\[field] COLON NODE_STRING\[value] PIPE text SQE
+        {$$ = $idString;yy.addVertex($idString,$text,'rect',undefined,undefined,undefined, Object.fromEntries([[$field, $value]]));}
     | idString CYLINDERSTART text CYLINDEREND
-        {$$ = $1;yy.addVertex($1,$3,'cylinder');}
+        {$$ = $idString;yy.addVertex($idString,$text,'cylinder');}
     | idString PS text PE
-        {$$ = $1;yy.addVertex($1,$3,'round');}
+        {$$ = $idString;yy.addVertex($idString,$text,'round');}
     | idString DIAMOND_START text DIAMOND_STOP
-        {$$ = $1;yy.addVertex($1,$3,'diamond');}
+        {$$ = $idString;yy.addVertex($idString,$text,'diamond');}
     | idString DIAMOND_START DIAMOND_START text DIAMOND_STOP DIAMOND_STOP
-        {$$ = $1;yy.addVertex($1,$4,'hexagon');}
+        {$$ = $idString;yy.addVertex($idString,$text,'hexagon');}
     | idString TAGEND text SQE
-        {$$ = $1;yy.addVertex($1,$3,'odd');}
+        {$$ = $idString;yy.addVertex($idString,$text,'odd');}
     | idString TRAPSTART text TRAPEND
-        {$$ = $1;yy.addVertex($1,$3,'trapezoid');}
+        {$$ = $idString;yy.addVertex($idString,$text,'trapezoid');}
     | idString INVTRAPSTART text INVTRAPEND
-        {$$ = $1;yy.addVertex($1,$3,'inv_trapezoid');}
+        {$$ = $idString;yy.addVertex($idString,$text,'inv_trapezoid');}
     | idString TRAPSTART text INVTRAPEND
-        {$$ = $1;yy.addVertex($1,$3,'lean_right');}
+        {$$ = $idString;yy.addVertex($idString,$text,'lean_right');}
     | idString INVTRAPSTART text TRAPEND
-        {$$ = $1;yy.addVertex($1,$3,'lean_left');}
+        {$$ = $idString;yy.addVertex($idString,$text,'lean_left');}
     | idString
-        { /*console.warn('h: ', $1);*/$$ = $1;yy.addVertex($1);}
+        { /*console.warn('h: ', $idString);*/$$ = $idString;yy.addVertex($idString);}
     ;
 
 
 
 link: linkStatement arrowText
-    {$1.text = $2;$$ = $1;}
+    {$linkStatement.text = $arrowText;$$ = $linkStatement;}
     | linkStatement TESTSTR SPACE
-    {$1.text = $2;$$ = $1;}
+    {$linkStatement.text = $TESTSTR;$$ = $linkStatement;}
     | linkStatement arrowText SPACE
-    {$1.text = $2;$$ = $1;}
+    {$linkStatement.text = $arrowText;$$ = $linkStatement;}
     | linkStatement
-    {$$ = $1;}
-    | START_LINK text LINK
-        {var inf = yy.destructLink($3, $1); $$ = {"type":inf.type,"stroke":inf.stroke,"length":inf.length,"text":$2};}
+    {$$ = $linkStatement;}
+    | START_LINK edgeText LINK
+        {var inf = yy.destructLink($LINK, $START_LINK); $$ = {"type":inf.type,"stroke":inf.stroke,"length":inf.length,"text":$edgeText};}
     ;
 
+edgeText: edgeTextToken
+    {$$={text:$edgeTextToken, type:'text'};}
+    | edgeText edgeTextToken
+    {$$={text:$edgeText.text+''+$edgeTextToken, type:$edgeText.type};}
+    |STR
+    {$$={text: $STR, type: 'string'};}
+    | MD_STR
+    {$$={text:$MD_STR, type:'markdown'};}
+    ;
+
+
 linkStatement: LINK
-        {var inf = yy.destructLink($1);$$ = {"type":inf.type,"stroke":inf.stroke,"length":inf.length};}
+        {var inf = yy.destructLink($LINK);$$ = {"type":inf.type,"stroke":inf.stroke,"length":inf.length};}
         ;
 
 arrowText:
     PIPE text PIPE
-    {$$ = $2;}
+    {$$ = $text;}
     ;
 
 text: textToken
-    { $$={text:$1, type: 'text'};}
+    { $$={text:$textToken, type: 'text'};}
     | text textToken
-    { $$={text:$1.text+''+$2, type: $1.type};}
+    { $$={text:$text.text+''+$textToken, type: $text.type};}
     | STR
-    { $$={text: $1, type: 'text'};}
+    { $$ = {text: $STR, type: 'string'};}
     | MD_STR
-    { $$={text: $1, type: 'markdown'};}
+    { $$={text: $MD_STR, type: 'markdown'};}
     ;
 
 
@@ -456,109 +498,104 @@ keywords
 
 
 textNoTags: textNoTagsToken
-    {$$=$1;}
+    {$$={text:$textNoTagsToken, type: 'text'};}
     | textNoTags textNoTagsToken
-    {$$=$1+''+$2;}
+    {$$={text:$textNoTags.text+''+$textNoTagsToken, type: $textNoTags.type};}
+    | STR
+    { $$={text: $STR, type: 'text'};}
+    | MD_STR
+    { $$={text: $MD_STR, type: 'markdown'};}
     ;
 
 
-classDefStatement:CLASSDEF SPACE DEFAULT SPACE stylesOpt
-    {$$ = $1;yy.addClass($3,$5);}
-    | CLASSDEF SPACE alphaNum SPACE stylesOpt
-          {$$ = $1;yy.addClass($3,$5);}
+classDefStatement:CLASSDEF SPACE idString SPACE stylesOpt
+    {$$ = $CLASSDEF;yy.addClass($idString,$stylesOpt);}
     ;
 
-classStatement:CLASS SPACE alphaNum SPACE alphaNum
-    {$$ = $1;yy.setClass($3, $5);}
+classStatement:CLASS SPACE idString\[vertex] SPACE idString\[class]
+    {$$ = $CLASS;yy.setClass($vertex, $class);}
     ;
 
 clickStatement
-    : CLICK CALLBACKNAME                           {$$ = $1;yy.setClickEvent($1, $2);}
-    | CLICK CALLBACKNAME SPACE STR                 {$$ = $1;yy.setClickEvent($1, $2);yy.setTooltip($1, $4);}
-    | CLICK CALLBACKNAME CALLBACKARGS              {$$ = $1;yy.setClickEvent($1, $2, $3);}
-    | CLICK CALLBACKNAME CALLBACKARGS SPACE STR    {$$ = $1;yy.setClickEvent($1, $2, $3);yy.setTooltip($1, $5);}
-    | CLICK HREF                                   {$$ = $1;yy.setLink($1, $2);}
-    | CLICK HREF SPACE STR                         {$$ = $1;yy.setLink($1, $2);yy.setTooltip($1, $4);}
-    | CLICK HREF SPACE LINK_TARGET                 {$$ = $1;yy.setLink($1, $2, $4);}
-    | CLICK HREF SPACE STR SPACE LINK_TARGET       {$$ = $1;yy.setLink($1, $2, $6);yy.setTooltip($1, $4);}
-    | CLICK alphaNum                               {$$ = $1;yy.setClickEvent($1, $2);}
-    | CLICK alphaNum SPACE STR                     {$$ = $1;yy.setClickEvent($1, $2);yy.setTooltip($1, $4);}
-    | CLICK STR                                    {$$ = $1;yy.setLink($1, $2);}
-    | CLICK STR SPACE STR                          {$$ = $1;yy.setLink($1, $2);yy.setTooltip($1, $4);}
-    | CLICK STR SPACE LINK_TARGET                  {$$ = $1;yy.setLink($1, $2, $4);}
-    | CLICK STR SPACE STR SPACE LINK_TARGET        {$$ = $1;yy.setLink($1, $2, $6);yy.setTooltip($1, $4);}
+    : CLICK CALLBACKNAME                                    {$$ = $CLICK;yy.setClickEvent($CLICK, $CALLBACKNAME);}
+    | CLICK CALLBACKNAME SPACE STR                          {$$ = $CLICK;yy.setClickEvent($CLICK, $CALLBACKNAME);yy.setTooltip($CLICK, $STR);}
+    | CLICK CALLBACKNAME CALLBACKARGS                       {$$ = $CLICK;yy.setClickEvent($CLICK, $CALLBACKNAME, $CALLBACKARGS);}
+    | CLICK CALLBACKNAME CALLBACKARGS SPACE STR             {$$ = $CLICK;yy.setClickEvent($CLICK, $CALLBACKNAME, $CALLBACKARGS);yy.setTooltip($CLICK, $STR);}
+    | CLICK HREF STR                                        {$$ = $CLICK;yy.setLink($CLICK, $STR);}
+    | CLICK HREF STR SPACE STR                              {$$ = $CLICK;yy.setLink($CLICK, $STR1);yy.setTooltip($CLICK, $STR2);}
+    | CLICK HREF STR SPACE LINK_TARGET                      {$$ = $CLICK;yy.setLink($CLICK, $STR, $LINK_TARGET);}
+    | CLICK HREF STR\[link] SPACE STR\[tooltip] SPACE LINK_TARGET      {$$ = $CLICK;yy.setLink($CLICK, $link, $LINK_TARGET);yy.setTooltip($CLICK, $tooltip);}
+    | CLICK alphaNum                                        {$$ = $CLICK;yy.setClickEvent($CLICK, $alphaNum);}
+    | CLICK alphaNum SPACE STR                              {$$ = $CLICK;yy.setClickEvent($CLICK, $alphaNum);yy.setTooltip($CLICK, $STR);}
+    | CLICK STR                                             {$$ = $CLICK;yy.setLink($CLICK, $STR);}
+    | CLICK STR\[link] SPACE STR\[tooltip]                  {$$ = $CLICK;yy.setLink($CLICK, $link);yy.setTooltip($CLICK, $tooltip);}
+    | CLICK STR SPACE LINK_TARGET                           {$$ = $CLICK;yy.setLink($CLICK, $STR, $LINK_TARGET);}
+    | CLICK STR\[link] SPACE STR\[tooltip] SPACE LINK_TARGET    {$$ = $CLICK;yy.setLink($CLICK, $link, $LINK_TARGET);yy.setTooltip($CLICK, $tooltip);}
     ;
 
-styleStatement:STYLE SPACE alphaNum SPACE stylesOpt
-    {$$ = $1;yy.addVertex($3,undefined,undefined,$5);}
-    | STYLE SPACE HEX SPACE stylesOpt
-          {$$ = $1;yy.updateLink($3,$5);}
+styleStatement:STYLE SPACE idString SPACE stylesOpt
+    {$$ = $STYLE;yy.addVertex($idString,undefined,undefined,$stylesOpt);}
     ;
 
 linkStyleStatement
     : LINKSTYLE SPACE DEFAULT SPACE stylesOpt
-          {$$ = $1;yy.updateLink([$3],$5);}
+          {$$ = $LINKSTYLE;yy.updateLink([$DEFAULT],$stylesOpt);}
     | LINKSTYLE SPACE numList SPACE stylesOpt
-          {$$ = $1;yy.updateLink($3,$5);}
+          {$$ = $LINKSTYLE;yy.updateLink($numList,$stylesOpt);}
     | LINKSTYLE SPACE DEFAULT SPACE INTERPOLATE SPACE alphaNum SPACE stylesOpt
-          {$$ = $1;yy.updateLinkInterpolate([$3],$7);yy.updateLink([$3],$9);}
+          {$$ = $LINKSTYLE;yy.updateLinkInterpolate([$DEFAULT],$alphaNum);yy.updateLink([$DEFAULT],$stylesOpt);}
     | LINKSTYLE SPACE numList SPACE INTERPOLATE SPACE alphaNum SPACE stylesOpt
-          {$$ = $1;yy.updateLinkInterpolate($3,$7);yy.updateLink($3,$9);}
+          {$$ = $LINKSTYLE;yy.updateLinkInterpolate($numList,$alphaNum);yy.updateLink($numList,$stylesOpt);}
     | LINKSTYLE SPACE DEFAULT SPACE INTERPOLATE SPACE alphaNum
-          {$$ = $1;yy.updateLinkInterpolate([$3],$7);}
+          {$$ = $LINKSTYLE;yy.updateLinkInterpolate([$DEFAULT],$alphaNum);}
     | LINKSTYLE SPACE numList SPACE INTERPOLATE SPACE alphaNum
-          {$$ = $1;yy.updateLinkInterpolate($3,$7);}
+          {$$ = $LINKSTYLE;yy.updateLinkInterpolate($numList,$alphaNum);}
     ;
 
 numList: NUM
-        {$$ = [$1]}
+        {$$ = [$NUM]}
     | numList COMMA NUM
-        {$1.push($3);$$ = $1;}
+        {$numList.push($NUM);$$ = $numList;}
     ;
 
 stylesOpt: style
-        {$$ = [$1]}
+        {$$ = [$style]}
     | stylesOpt COMMA style
-        {$1.push($3);$$ = $1;}
+        {$stylesOpt.push($style);$$ = $stylesOpt;}
     ;
 
 style: styleComponent
     |style styleComponent
-    {$$ = $1 + $2;}
+    {$$ = $style + $styleComponent;}
     ;
 
-styleComponent: ALPHA | COLON | MINUS | NUM | UNIT | SPACE | HEX | BRKT | DOT | STYLE | PCT ;
+styleComponent: NUM | NODE_STRING| COLON | UNIT | SPACE | BRKT | STYLE | PCT ;
 
 /* Token lists */
+idStringToken  :  NUM | NODE_STRING | DOWN | MINUS | DEFAULT | COMMA | COLON | AMP | BRKT | MULT | UNICODE_TEXT;
+
+textToken      :   TEXT | TAGSTART | TAGEND | UNICODE_TEXT;
+
+textNoTagsToken: NUM | NODE_STRING | SPACE | MINUS | AMP | UNICODE_TEXT | COLON | MULT | BRKT | keywords | START_LINK ;
 
-textToken      : textNoTagsToken | TAGSTART | TAGEND | START_LINK | PCT | DEFAULT;
+edgeTextToken  :  EDGE_TEXT | UNICODE_TEXT ;
 
-textNoTagsToken: alphaNumToken | SPACE | MINUS | keywords ;
+alphaNumToken  :  NUM | UNICODE_TEXT | NODE_STRING | DIR | DOWN | MINUS | COMMA | COLON | AMP | BRKT | MULT;
 
 idString
     :idStringToken
-    {$$=$1}
+    {$$=$idStringToken}
     | idString idStringToken
-    {$$=$1+''+$2}
+    {$$=$idString+''+$idStringToken}
     ;
 
 alphaNum
-    : alphaNumStatement
-    {$$=$1;}
-    | alphaNum alphaNumStatement
-    {$$=$1+''+$2;}
+    : alphaNumToken
+    {$$=$alphaNumToken;}
+    | alphaNum alphaNumToken
+    {$$=$alphaNum+''+$alphaNumToken;}
     ;
 
-alphaNumStatement
-    : DIR
-        {$$=$1;}
-    | alphaNumToken
-        {$$=$1;}
-    | DOWN
-        {$$='v';}
-    | MINUS
-        {$$='-';}
-    ;
 
 direction
     : direction_tb
@@ -571,9 +608,4 @@ direction
     { $$={stmt:'dir', value:'LR'};}
     ;
 
-alphaNumToken  : PUNCTUATION | AMP | UNICODE_TEXT | NUM| ALPHA | COLON | COMMA | PLUS | EQUALS | MULT | DOT | BRKT| UNDERSCORE ;
-
-idStringToken  : ALPHA|UNDERSCORE |UNICODE_TEXT | NUM|  COLON | COMMA | PLUS | MINUS | DOWN |EQUALS | MULT | BRKT | DOT | PUNCTUATION | AMP | DEFAULT;
-
-graphCodeTokens: STADIUMSTART | STADIUMEND | SUBROUTINESTART | SUBROUTINEEND | VERTEX_WITH_PROPS_START | CYLINDERSTART | CYLINDEREND | TRAPSTART | TRAPEND | INVTRAPSTART | INVTRAPEND | PIPE | PS | PE | SQS | SQE | DIAMOND_START | DIAMOND_STOP | TAGSTART | TAGEND | ARROW_CROSS | ARROW_POINT | ARROW_CIRCLE | ARROW_OPEN | QUOTE | SEMI;
 %%
diff --git a/packages/mermaid/src/diagrams/gantt/ganttDiagram.ts b/packages/mermaid/src/diagrams/gantt/ganttDiagram.ts
index 0104c7d0c8..cf2974d44b 100644
--- a/packages/mermaid/src/diagrams/gantt/ganttDiagram.ts
+++ b/packages/mermaid/src/diagrams/gantt/ganttDiagram.ts
@@ -1,4 +1,4 @@
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import ganttParser from './parser/gantt.jison';
 import ganttDb from './ganttDb.js';
 import ganttRenderer from './ganttRenderer.js';
diff --git a/packages/mermaid/src/diagrams/git/gitGraphDiagram.ts b/packages/mermaid/src/diagrams/git/gitGraphDiagram.ts
index 08ff126c44..c9a21cc2d7 100644
--- a/packages/mermaid/src/diagrams/git/gitGraphDiagram.ts
+++ b/packages/mermaid/src/diagrams/git/gitGraphDiagram.ts
@@ -1,4 +1,4 @@
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import gitGraphParser from './parser/gitGraph.jison';
 import gitGraphDb from './gitGraphAst.js';
 import gitGraphRenderer from './gitGraphRenderer.js';
diff --git a/packages/mermaid/src/diagrams/info/infoRenderer.ts b/packages/mermaid/src/diagrams/info/infoRenderer.ts
index 79f3ec9920..25ae72fce0 100644
--- a/packages/mermaid/src/diagrams/info/infoRenderer.ts
+++ b/packages/mermaid/src/diagrams/info/infoRenderer.ts
@@ -1,7 +1,7 @@
-import { select } from 'd3';
 import { log } from '../../logger.js';
-import { getConfig } from '../../config.js';
-import type { DrawDefinition, HTML, SVG } from '../../diagram-api/types.js';
+import { configureSvgSize } from '../../setupGraphViewbox.js';
+import type { DrawDefinition, Group, SVG } from '../../diagram-api/types.js';
+import { selectSvgElement } from '../../rendering-util/selectSvgElement.js';
 
 /**
  * Draws a an info picture in the tag with id: id based on the graph definition in text.
@@ -11,40 +11,20 @@ import type { DrawDefinition, HTML, SVG } from '../../diagram-api/types.js';
  * @param version - MermaidJS version.
  */
 const draw: DrawDefinition = (text, id, version) => {
-  try {
-    log.debug('rendering info diagram\n' + text);
+  log.debug('rendering info diagram\n' + text);
 
-    const { securityLevel } = 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;
-    }
+  const svg: SVG = selectSvgElement(id);
+  configureSvgSize(svg, 100, 400, true);
 
-    // @ts-ignore - figure out how to assign HTML to document type
-    const root: HTML =
-      sandboxElement !== undefined && document !== undefined && document !== null
-        ? select(document)
-        : select('body');
-
-    const svg: SVG = root.select('#' + id);
-    svg.attr('height', 100);
-    svg.attr('width', 400);
-
-    const g = svg.append('g');
-
-    g.append('text') // text label for the x axis
-      .attr('x', 100)
-      .attr('y', 40)
-      .attr('class', 'version')
-      .attr('font-size', '32px')
-      .style('text-anchor', 'middle')
-      .text('v ' + version);
-  } catch (e) {
-    log.error('error while rendering info diagram', e);
-  }
+  const group: Group = svg.append('g');
+  group
+    .append('text')
+    .attr('x', 100)
+    .attr('y', 40)
+    .attr('class', 'version')
+    .attr('font-size', 32)
+    .style('text-anchor', 'middle')
+    .text(`v${version}`);
 };
 
 export const renderer = { draw };
diff --git a/packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts b/packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts
index 846fd5dc58..b352144359 100644
--- a/packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts
+++ b/packages/mermaid/src/diagrams/mindmap/mindmap-definition.ts
@@ -1,4 +1,4 @@
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import mindmapParser from './parser/mindmap.jison';
 import * as mindmapDb from './mindmapDb.js';
 import mindmapRenderer from './mindmapRenderer.js';
diff --git a/packages/mermaid/src/diagrams/pie/pieDiagram.ts b/packages/mermaid/src/diagrams/pie/pieDiagram.ts
index 4c6b7d3bc9..21756dd4e8 100644
--- a/packages/mermaid/src/diagrams/pie/pieDiagram.ts
+++ b/packages/mermaid/src/diagrams/pie/pieDiagram.ts
@@ -1,5 +1,5 @@
 import { DiagramDefinition } from '../../diagram-api/types.js';
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import parser from './parser/pie.jison';
 import db from './pieDb.js';
 import styles from './styles.js';
diff --git a/packages/mermaid/src/diagrams/quadrant-chart/parser/quadrant.jison.spec.ts b/packages/mermaid/src/diagrams/quadrant-chart/parser/quadrant.jison.spec.ts
index 05b18b9353..f4a9835e19 100644
--- a/packages/mermaid/src/diagrams/quadrant-chart/parser/quadrant.jison.spec.ts
+++ b/packages/mermaid/src/diagrams/quadrant-chart/parser/quadrant.jison.spec.ts
@@ -1,4 +1,4 @@
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import { parser } from './quadrant.jison';
 import { Mock, vi } from 'vitest';
 
diff --git a/packages/mermaid/src/diagrams/quadrant-chart/quadrantDiagram.ts b/packages/mermaid/src/diagrams/quadrant-chart/quadrantDiagram.ts
index 40ae798d2d..c2fc970b1d 100644
--- a/packages/mermaid/src/diagrams/quadrant-chart/quadrantDiagram.ts
+++ b/packages/mermaid/src/diagrams/quadrant-chart/quadrantDiagram.ts
@@ -1,5 +1,5 @@
 import { DiagramDefinition } from '../../diagram-api/types.js';
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import parser from './parser/quadrant.jison';
 import db from './quadrantDb.js';
 import renderer from './quadrantRenderer.js';
diff --git a/packages/mermaid/src/diagrams/requirement/requirementDiagram.ts b/packages/mermaid/src/diagrams/requirement/requirementDiagram.ts
index 4505afc568..c2e997628e 100644
--- a/packages/mermaid/src/diagrams/requirement/requirementDiagram.ts
+++ b/packages/mermaid/src/diagrams/requirement/requirementDiagram.ts
@@ -1,5 +1,5 @@
 import { DiagramDefinition } from '../../diagram-api/types.js';
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import parser from './parser/requirementDiagram.jison';
 import db from './requirementDb.js';
 import styles from './styles.js';
diff --git a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js
index 8b7d6f8d0e..0b84fbe356 100644
--- a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js
+++ b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js
@@ -172,14 +172,11 @@ describe('more than one sequence diagram', () => {
 
 describe('when parsing a sequenceDiagram', function () {
   beforeEach(function () {
-    // diagram.db = sequenceDb;
-    // diagram.db.clear();
     diagram = new Diagram(`
 sequenceDiagram
 Alice->Bob:Hello Bob, how are you?
 Note right of Bob: Bob thinks
 Bob-->Alice: I am good thanks!`);
-    diagram.db.clear();
   });
   it('should handle a sequenceDiagram definition', async function () {
     const str = `
@@ -1482,8 +1479,6 @@ describe('when checking the bounds in a sequenceDiagram', function () {
   let conf;
   beforeEach(function () {
     mermaidAPI.reset();
-    // diagram.db = sequenceDb;
-    // diagram.db.clear();
     diagram.renderer.bounds.init();
     conf = diagram.db.getConfig();
   });
@@ -1635,7 +1630,6 @@ sequenceDiagram
 Alice->Bob:Hello Bob, how are you?
 Note right of Bob: Bob thinks
 Bob-->Alice: I am good thanks!`);
-    diagram.db.clear();
   });
   ['tspan', 'fo', 'old', undefined].forEach(function (textPlacement) {
     it(`
@@ -2009,8 +2003,6 @@ describe('when rendering a sequenceDiagram with actor mirror activated', () => {
   let conf;
   beforeEach(function () {
     mermaidAPI.reset();
-    // diagram.db = sequenceDb;
-    diagram.db.clear();
     conf = diagram.db.getConfig();
     diagram.renderer.bounds.init();
   });
@@ -2052,12 +2044,8 @@ describe('when rendering a sequenceDiagram with directives', () => {
     mermaidAPI.initialize({ sequence: conf });
   });
 
-  let conf;
   beforeEach(function () {
     mermaidAPI.reset();
-    // diagram.db = sequenceDb;
-    diagram.db.clear();
-    conf = diagram.db.getConfig();
     diagram.renderer.bounds.init();
   });
 
@@ -2069,10 +2057,7 @@ sequenceDiagram
 participant Alice
 `;
     diagram = new Diagram(str);
-
     diagram.renderer.bounds.init();
-    await mermaidAPI.parse(str);
-
     diagram.renderer.draw(str, 'tst', '1.2.3', diagram);
 
     const { bounds, models } = diagram.renderer.bounds.getBounds();
@@ -2093,7 +2078,7 @@ sequenceDiagram
 participant Alice
 `;
 
-    diagram.parse(str);
+    diagram = new Diagram(str);
     diagram.renderer.draw(str, 'tst', '1.2.3', diagram);
 
     const { bounds, models } = diagram.renderer.bounds.getBounds();
@@ -2114,7 +2099,7 @@ Alice->Bob:Hello Bob, how are you?
 Note right of Bob: Bob thinks
 Bob-->Alice: I am good thanks!`;
 
-    await mermaidAPI.parse(str1);
+    diagram = new Diagram(str1);
     diagram.renderer.draw(str1, 'tst', '1.2.3', diagram); // needs to be rendered for the correct value of visibility auto numbers
     expect(diagram.db.showSequenceNumbers()).toBe(true);
 
@@ -2124,7 +2109,7 @@ Alice->Bob:Hello Bob, how are you?
 Note right of Bob: Bob thinks
 Bob-->Alice: I am good thanks!`;
 
-    await mermaidAPI.parse(str2);
+    diagram = new Diagram(str2);
     diagram.renderer.draw(str2, 'tst', '1.2.3', diagram);
     expect(diagram.db.showSequenceNumbers()).toBe(false);
   });
diff --git a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.ts b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.ts
index 382d47b619..b4342a694f 100644
--- a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.ts
+++ b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.ts
@@ -1,5 +1,5 @@
 import { DiagramDefinition } from '../../diagram-api/types.js';
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import parser from './parser/sequenceDiagram.jison';
 import db from './sequenceDb.js';
 import styles from './styles.js';
diff --git a/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts b/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts
index 4f8b1889bb..f6fde5001d 100644
--- a/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts
+++ b/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts
@@ -749,9 +749,6 @@ function adjustCreatedDestroyedData(
 export const draw = function (_text: string, id: string, _version: string, diagObj: Diagram) {
   const { securityLevel, sequence } = configApi.getConfig();
   conf = sequence;
-  diagObj.db.clear();
-  // Parse the graph definition
-  diagObj.parser.parse(_text);
   // Handle root and Document for when rendering in sandbox mode
   let sandboxElement;
   if (securityLevel === 'sandbox') {
diff --git a/packages/mermaid/src/diagrams/state/stateDiagram-v2.ts b/packages/mermaid/src/diagrams/state/stateDiagram-v2.ts
index 616a97556a..8f62a64db3 100644
--- a/packages/mermaid/src/diagrams/state/stateDiagram-v2.ts
+++ b/packages/mermaid/src/diagrams/state/stateDiagram-v2.ts
@@ -1,5 +1,5 @@
 import { DiagramDefinition } from '../../diagram-api/types.js';
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import parser from './parser/stateDiagram.jison';
 import db from './stateDb.js';
 import styles from './styles.js';
diff --git a/packages/mermaid/src/diagrams/state/stateDiagram.ts b/packages/mermaid/src/diagrams/state/stateDiagram.ts
index 44552c2461..fd34676079 100644
--- a/packages/mermaid/src/diagrams/state/stateDiagram.ts
+++ b/packages/mermaid/src/diagrams/state/stateDiagram.ts
@@ -1,5 +1,5 @@
 import { DiagramDefinition } from '../../diagram-api/types.js';
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import parser from './parser/stateDiagram.jison';
 import db from './stateDb.js';
 import styles from './styles.js';
diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js
index 592cb43ccd..1c9b2d1d3c 100644
--- a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js
+++ b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js
@@ -84,17 +84,8 @@ export const setConf = function (cnf) {
  * @returns {object} ClassDef styles (a Map with keys = strings, values = )
  */
 export const getClasses = function (text, diagramObj) {
-  log.trace('Extracting classes');
-  diagramObj.db.clear();
-  try {
-    // Parse the graph definition
-    diagramObj.parser.parse(text);
-    // must run extract() to turn the parsed statements into states, relationships, classes, etc.
-    diagramObj.db.extract(diagramObj.db.getRootDocV2());
-    return diagramObj.db.getClasses();
-  } catch (e) {
-    return e;
-  }
+  diagramObj.db.extract(diagramObj.db.getRootDocV2());
+  return diagramObj.db.getClasses();
 };
 
 /**
@@ -384,7 +375,6 @@ const getDir = (parsedItem, defaultDir = DEFAULT_NESTED_DOC_DIR) => {
  */
 export const draw = async function (text, id, _version, diag) {
   log.info('Drawing state diagram (v2)', id);
-  // diag.sb.clear();
   nodeDb = {};
   // Fetch the default direction, use TD if none was found
   let dir = diag.db.getDirection();
diff --git a/packages/mermaid/src/diagrams/timeline/timeline-definition.ts b/packages/mermaid/src/diagrams/timeline/timeline-definition.ts
index 7f671291f2..0c55616108 100644
--- a/packages/mermaid/src/diagrams/timeline/timeline-definition.ts
+++ b/packages/mermaid/src/diagrams/timeline/timeline-definition.ts
@@ -1,4 +1,4 @@
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import parser from './parser/timeline.jison';
 import * as db from './timelineDb.js';
 import renderer from './timelineRenderer.js';
diff --git a/packages/mermaid/src/diagrams/user-journey/journeyDiagram.ts b/packages/mermaid/src/diagrams/user-journey/journeyDiagram.ts
index 969cf0e5e3..1c009d9ea9 100644
--- a/packages/mermaid/src/diagrams/user-journey/journeyDiagram.ts
+++ b/packages/mermaid/src/diagrams/user-journey/journeyDiagram.ts
@@ -1,5 +1,5 @@
 import { DiagramDefinition } from '../../diagram-api/types.js';
-// @ts-ignore: TODO Fix ts errors
+// @ts-ignore: JISON doesn't support types
 import parser from './parser/journey.jison';
 import db from './journeyDb.js';
 import styles from './styles.js';
diff --git a/packages/mermaid/src/docs/.vitepress/theme/redirect.ts b/packages/mermaid/src/docs/.vitepress/theme/redirect.ts
index 24b9a4d1f8..da32e5f8f3 100644
--- a/packages/mermaid/src/docs/.vitepress/theme/redirect.ts
+++ b/packages/mermaid/src/docs/.vitepress/theme/redirect.ts
@@ -50,7 +50,7 @@ const idRedirectMap: Record = {
   'n00b-advanced': 'config/n00b-advanced',
   'n00b-gettingstarted': 'intro/n00b-gettingStarted',
   'n00b-overview': 'community/n00b-overview',
-  'n00b-syntaxreference': '',
+  'n00b-syntaxreference': 'intro/n00b-syntaxReference',
   newdiagram: 'community/newDiagram',
   pie: 'syntax/pie',
   plugins: '',
diff --git a/packages/mermaid/src/docs/community/newDiagram.md b/packages/mermaid/src/docs/community/newDiagram.md
index 75e17e4c9b..7fb47dd302 100644
--- a/packages/mermaid/src/docs/community/newDiagram.md
+++ b/packages/mermaid/src/docs/community/newDiagram.md
@@ -4,7 +4,7 @@
 
 #### Grammar
 
-This would be to define a jison grammar for the new diagram type. That should start with a way to identify that the text in the mermaid tag is a diagram of that type. Create a new folder under diagrams for your new diagram type and a parser folder in it. This leads us to step 2.
+This would be to define a JISON grammar for the new diagram type. That should start with a way to identify that the text in the mermaid tag is a diagram of that type. Create a new folder under diagrams for your new diagram type and a parser folder in it. This leads us to step 2.
 
 For instance:
 
@@ -55,7 +55,7 @@ Place the renderer in the diagram folder.
 
 ### Step 3: Detection of the new diagram type
 
-The second thing to do is to add the capability to detect the new diagram to type to the detectType in utils.js. The detection should return a key for the new diagram type.
+The second thing to do is to add the capability to detect the new diagram to type to the detectType in `diagram-api/detectType.ts`. The detection should return a key for the new diagram type.
 [This key will be used to as the aria roledescription](#aria-roledescription), so it should be a word that clearly describes the diagram type.
 For example, if your new diagram use a UML deployment diagram, a good key would be "UMLDeploymentDiagram" because assistive technologies such as a screen reader
 would voice that as "U-M-L Deployment diagram." Another good key would be "deploymentDiagram" because that would be voiced as "Deployment Diagram." A bad key would be "deployment" because that would not sufficiently describe the diagram.
@@ -119,53 +119,6 @@ There are a few features that are common between the different types of diagrams
 
 Here some pointers on how to handle these different areas.
 
-#### [Directives](../config/directives.md)
-
-Here is example handling from flowcharts:
-Jison:
-
-```jison
-/* lexical grammar */
-%lex
-%x open_directive
-%x type_directive
-%x arg_directive
-%x close_directive
-
-\%\%\{                                                          { this.begin('open_directive'); return 'open_directive'; }
-((?:(?!\}\%\%)[^:.])*)                          { this.begin('type_directive'); return 'type_directive'; }
-":"                                             { this.popState(); this.begin('arg_directive'); return ':'; }
-\}\%\%                            { this.popState(); this.popState(); return 'close_directive'; }
-((?:(?!\}\%\%).|\n)*)                            return 'arg_directive';
-
-/* language grammar */
-
-/* ... */
-
-directive
-  : openDirective typeDirective closeDirective separator
-  | openDirective typeDirective ':' argDirective closeDirective separator
-  ;
-
-openDirective
-  : open_directive { yy.parseDirective('%%{', 'open_directive'); }
-  ;
-
-typeDirective
-  : type_directive { yy.parseDirective($1, 'type_directive'); }
-  ;
-
-argDirective
-  : arg_directive { $1 = $1.trim().replace(/'/g, '"'); yy.parseDirective($1, 'arg_directive'); }
-  ;
-
-closeDirective
-  : close_directive { yy.parseDirective('}%%', 'close_directive', 'flowchart'); }
-  ;
-```
-
-It is probably a good idea to keep the handling similar to this in your new diagram. The parseDirective function is provided by the mermaidAPI.
-
 ## Accessibility
 
 Mermaid automatically adds the following accessibility information for the diagram SVG HTML element:
@@ -184,7 +137,7 @@ See [the definition of aria-roledescription](https://www.w3.org/TR/wai-aria-1.1/
 
 The syntax for accessible titles and descriptions is described in [the Accessibility documenation section.](../config/accessibility.md)
 
-In a similar way to the directives, the jison syntax are quite similar between the diagrams.
+As a design goal, the jison syntax should be similar between the diagrams.
 
 ```jison
 
diff --git a/packages/mermaid/src/docs/intro/index.md b/packages/mermaid/src/docs/intro/index.md
index e886b5f60f..7f2a5c0521 100644
--- a/packages/mermaid/src/docs/intro/index.md
+++ b/packages/mermaid/src/docs/intro/index.md
@@ -164,7 +164,9 @@ The above command generates files into the `dist` folder and publishes them to <
 - [Live Editor](https://github.com/mermaid-js/mermaid-live-editor)
 - [HTTP Server](https://github.com/TomWright/mermaid-server)
 
-## Contributors [![Good first issue](https://img.shields.io/github/labels/mermaid-js/mermaid/Good%20first%20issue%21)](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%21%22) [![Contributors](https://img.shields.io/github/contributors/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors) [![Commits](https://img.shields.io/github/commit-activity/m/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors)
+## Contributors
+
+[![Good first issue](https://img.shields.io/github/labels/mermaid-js/mermaid/Good%20first%20issue%21)](https://github.com/mermaid-js/mermaid/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%21%22) [![Contributors](https://img.shields.io/github/contributors/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors) [![Commits](https://img.shields.io/github/commit-activity/m/mermaid-js/mermaid)](https://github.com/mermaid-js/mermaid/graphs/contributors)
 
 Mermaid is a growing community and is always accepting new contributors. There's a lot of different ways to help out and we're always looking for extra hands! Look at [this issue](https://github.com/mermaid-js/mermaid/issues/866) if you want to know where to start helping out.
 
diff --git a/packages/mermaid/src/docs/news/announcements.md b/packages/mermaid/src/docs/news/announcements.md
index c4313a7f1b..1cf14284a6 100644
--- a/packages/mermaid/src/docs/news/announcements.md
+++ b/packages/mermaid/src/docs/news/announcements.md
@@ -1,7 +1,7 @@
 # Announcements
 
-## [Mermaid Chart Announces Visual Studio Code Plugin to Simplify Development Workflows](https://www.mermaidchart.com/blog/posts/mermaid-chart-announces-visual-studio-code-plugin)
+## [From Chaos to Clarity: Exploring Mind Maps with MermaidJS](https://www.mermaidchart.com/blog/posts/from-chaos-to-clarity-exploring-mind-maps-with-mermaidjs)
 
-17 July 2023 · 3 mins
+24 July 2023 · 4 mins
 
-New Integration Enhances Workflows By Enabling Developers To Reference And Edit Diagrams Within Visual Studio Code.
+Introducing the concept of mind mapping as a tool for organizing complex information, and highlights Mermaid as a user-friendly software that simplifies the creation and editing of mind maps for applications in IT solution design, business decision-making, and knowledge organization.
diff --git a/packages/mermaid/src/docs/news/blog.md b/packages/mermaid/src/docs/news/blog.md
index d3f5f70af6..4c6eac3f32 100644
--- a/packages/mermaid/src/docs/news/blog.md
+++ b/packages/mermaid/src/docs/news/blog.md
@@ -1,5 +1,11 @@
 # Blog
 
+## [From Chaos to Clarity: Exploring Mind Maps with MermaidJS](https://www.mermaidchart.com/blog/posts/from-chaos-to-clarity-exploring-mind-maps-with-mermaidjs)
+
+24 July 2023 · 4 mins
+
+Introducing the concept of mind mapping as a tool for organizing complex information, and highlights Mermaid as a user-friendly software that simplifies the creation and editing of mind maps for applications in IT solution design, business decision-making, and knowledge organization.
+
 ## [Mermaid Chart Announces Visual Studio Code Plugin to Simplify Development Workflows](https://www.mermaidchart.com/blog/posts/mermaid-chart-announces-visual-studio-code-plugin)
 
 17 July 2023 · 3 mins
diff --git a/packages/mermaid/src/docs/package.json b/packages/mermaid/src/docs/package.json
index 64f24fe506..922d8fa32b 100644
--- a/packages/mermaid/src/docs/package.json
+++ b/packages/mermaid/src/docs/package.json
@@ -21,17 +21,17 @@
   },
   "devDependencies": {
     "@iconify-json/carbon": "^1.1.16",
-    "@unocss/reset": "^0.53.0",
+    "@unocss/reset": "^0.54.0",
     "@vite-pwa/vitepress": "^0.2.0",
     "@vitejs/plugin-vue": "^4.2.1",
     "fast-glob": "^3.2.12",
     "https-localhost": "^4.7.1",
     "pathe": "^1.1.0",
-    "unocss": "^0.53.0",
+    "unocss": "^0.54.0",
     "unplugin-vue-components": "^0.25.0",
-    "vite": "^4.3.3",
+    "vite": "^4.3.9",
     "vite-plugin-pwa": "^0.16.0",
-    "vitepress": "1.0.0-beta.6",
+    "vitepress": "1.0.0-beta.7",
     "workbox-window": "^7.0.0"
   }
 }
diff --git a/packages/mermaid/src/docs/syntax/flowchart.md b/packages/mermaid/src/docs/syntax/flowchart.md
index 2e3d78c305..56cad19a03 100644
--- a/packages/mermaid/src/docs/syntax/flowchart.md
+++ b/packages/mermaid/src/docs/syntax/flowchart.md
@@ -390,7 +390,7 @@ It is possible to escape characters using the syntax exemplified here.
 
 ```mermaid-example
     flowchart LR
-        A["A double quote:#quot;"] -->B["A dec char:#9829;"]
+        A["A double quote:#quot;"] --> B["A dec char:#9829;"]
 ```
 
 Numbers given are base 10, so `#` can be encoded as `#35;`. It is also supported to use HTML character names.
diff --git a/packages/mermaid/src/mermaid.spec.ts b/packages/mermaid/src/mermaid.spec.ts
index e27428545e..0b4437d742 100644
--- a/packages/mermaid/src/mermaid.spec.ts
+++ b/packages/mermaid/src/mermaid.spec.ts
@@ -3,6 +3,7 @@ import { mermaidAPI } from './mermaidAPI.js';
 import './diagram-api/diagram-orchestration.js';
 import { addDiagrams } from './diagram-api/diagram-orchestration.js';
 import { beforeAll, describe, it, expect, vi } from 'vitest';
+import type { DiagramDefinition } from './diagram-api/types.js';
 
 beforeAll(async () => {
   addDiagrams();
@@ -92,13 +93,16 @@ describe('when using mermaid and ', () => {
 
     it('should defer diagram load based on parameter', async () => {
       let loaded = false;
-      const dummyDiagram = {
+      const dummyDiagram: DiagramDefinition = {
         db: {},
         renderer: () => {
           // do nothing
         },
-        parser: () => {
-          // do nothing
+        parser: {
+          parse: (_text) => {
+            return;
+          },
+          parser: { yy: {} },
         },
         styles: () => {
           // do nothing
diff --git a/packages/mermaid/src/mermaidAPI.ts b/packages/mermaid/src/mermaidAPI.ts
index 4d8d952906..f8a36f88e6 100644
--- a/packages/mermaid/src/mermaidAPI.ts
+++ b/packages/mermaid/src/mermaidAPI.ts
@@ -108,8 +108,7 @@ export interface RenderResult {
 async function parse(text: string, parseOptions?: ParseOptions): Promise {
   addDiagrams();
   try {
-    const diagram = await getDiagramFromText(text);
-    diagram.parse();
+    await getDiagramFromText(text);
   } catch (error) {
     if (parseOptions?.suppressErrors) {
       return false;
@@ -285,7 +284,9 @@ export const cleanUpSvgCode = (
  * TODO replace btoa(). Replace with  buf.toString('base64')?
  */
 export const putIntoIFrame = (svgCode = '', svgElement?: D3Element): string => {
-  const height = svgElement ? svgElement.viewBox.baseVal.height + 'px' : IFRAME_HEIGHT;
+  const height = svgElement?.viewBox?.baseVal?.height
+    ? svgElement.viewBox.baseVal.height + 'px'
+    : IFRAME_HEIGHT;
   const base64encodedSrc = btoa('' + svgCode + '');
   return `