mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-12-26 06:06:22 +01:00
Compare commits
1 Commits
3061_decou
...
sidv/confi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d621bc4645 |
@@ -1,5 +1,3 @@
|
||||
dist/**
|
||||
.github/**
|
||||
docs/Setup.md
|
||||
cypress.config.js
|
||||
cypress/plugins/index.js
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:jsdoc/recommended",
|
||||
"plugin:json/recommended",
|
||||
"plugin:markdown/recommended",
|
||||
@@ -23,7 +22,6 @@
|
||||
],
|
||||
"plugins": ["@typescript-eslint", "html", "jest", "jsdoc", "json"],
|
||||
"rules": {
|
||||
"no-console": "error",
|
||||
"no-prototype-builtins": "off",
|
||||
"no-unused-vars": "off",
|
||||
"jsdoc/check-indentation": "off",
|
||||
@@ -37,16 +35,6 @@
|
||||
"jsdoc/require-returns": "off",
|
||||
"jsdoc/require-returns-description": "off",
|
||||
"cypress/no-async-tests": "off",
|
||||
"@typescript-eslint/ban-ts-comment": [
|
||||
"error",
|
||||
{
|
||||
"ts-expect-error": "allow-with-description",
|
||||
"ts-ignore": "allow-with-description",
|
||||
"ts-nocheck": "allow-with-description",
|
||||
"ts-check": "allow-with-description",
|
||||
"minimumDescriptionLength": 10
|
||||
}
|
||||
],
|
||||
"json/*": ["error", "allowComments"],
|
||||
"no-empty": ["error", { "allowEmptyCatch": true }]
|
||||
},
|
||||
@@ -57,12 +45,6 @@
|
||||
"no-undef": "off",
|
||||
"jsdoc/require-jsdoc": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["./cypress/**", "./demos/**"],
|
||||
"rules": {
|
||||
"no-console": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
15
.github/workflows/lint.yml
vendored
15
.github/workflows/lint.yml
vendored
@@ -40,18 +40,3 @@ jobs:
|
||||
|
||||
- name: Verify Docs
|
||||
run: yarn docs:verify
|
||||
|
||||
- name: Check no `console.log()` in .jison files
|
||||
# ESLint can't parse .jison files directly
|
||||
# In the future, it might be worth making a `eslint-plugin-jison`, so
|
||||
# that this will be built into the `yarn lint` command.
|
||||
run: |
|
||||
shopt -s globstar
|
||||
mkdir -p tmp/
|
||||
for jison_file in src/**/*.jison; do
|
||||
outfile="tmp/$(basename -- "$jison_file" .jison)-jison.js"
|
||||
echo "Converting $jison_file to $outfile"
|
||||
# default module-type (CJS) always adds a console.log()
|
||||
yarn jison "$jison_file" --outfile "$outfile" --module-type "amd"
|
||||
done
|
||||
yarn eslint --no-eslintrc --rule no-console:error --parser "@babel/eslint-parser" "./tmp/*-jison.js"
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
|
||||
const { defineConfig } = require('cypress');
|
||||
const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin');
|
||||
require('@applitools/eyes-cypress')(module);
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre class="mermaid" style="width: 50%">
|
||||
<pre class="mermaid2" style="width: 50%">
|
||||
flowchart LR
|
||||
classDef aPID stroke:#4e4403,fill:#fdde29,color:#4e4403,rx:5px,ry:5px;
|
||||
classDef crm stroke:#333333,fill:#DCDCDC,color:#333333,rx:5px,ry:5px;
|
||||
@@ -99,7 +99,7 @@ flowchart TD
|
||||
class A someclass;
|
||||
class C someclass;
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 50%">
|
||||
<pre class="mermaid2" style="width: 50%">
|
||||
sequenceDiagram
|
||||
title: My Sequence Diagram Title
|
||||
accTitle: My Acc Sequence Diagram
|
||||
@@ -109,14 +109,14 @@ flowchart TD
|
||||
John-->>Alice: Great!
|
||||
Alice-)John: See you later!
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 50%">
|
||||
<pre class="mermaid2" style="width: 50%">
|
||||
graph TD
|
||||
A -->|000| B
|
||||
B -->|111| C
|
||||
|
||||
linkStyle 1 stroke:#ff3,stroke-width:4px,color:red;
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
journey
|
||||
accTitle: My User Journey Diagram
|
||||
accDescr: My User Journey Diagram Description
|
||||
@@ -130,10 +130,10 @@ graph TD
|
||||
Go downstairs: 5: Me
|
||||
Sit down: 5: Me
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
info
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
requirementDiagram
|
||||
accTitle: My req Diagram
|
||||
accDescr: My req Diagram Description
|
||||
@@ -174,7 +174,7 @@ requirementDiagram
|
||||
test_req - contains -> test_req3
|
||||
test_req <- copies - test_entity2
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
title Adding GANTT diagram functionality to mermaid
|
||||
@@ -206,7 +206,7 @@ gantt
|
||||
Add gantt diagram to demo page :20h
|
||||
Add another diagram to demo page :48h
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
stateDiagram
|
||||
state Active {
|
||||
Idle
|
||||
@@ -234,7 +234,7 @@ stateDiagram
|
||||
end
|
||||
B ->> A: Return
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
classDiagram
|
||||
accTitle: My class diagram
|
||||
accDescr: My class diagram Description
|
||||
@@ -259,7 +259,7 @@ class Class10 {
|
||||
A->>Bob: Hola
|
||||
Bob-->A: Pasten !
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
gitGraph
|
||||
commit id: "ZERO"
|
||||
branch develop
|
||||
@@ -288,7 +288,7 @@ flowchart TD
|
||||
C -->|Two| E[iPhone]
|
||||
C -->|Three| F[fa:fa-car Car]
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
classDiagram
|
||||
Animal "1" <|-- Duck
|
||||
Animal <|-- Fish
|
||||
@@ -311,7 +311,7 @@ flowchart TD
|
||||
+run()
|
||||
}
|
||||
</pre>
|
||||
<pre class="mermaid" style="width: 100%">
|
||||
<pre class="mermaid2" style="width: 100%">
|
||||
erDiagram
|
||||
CAR ||--o{ NAMED-DRIVER : allows
|
||||
CAR {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
|
||||
@@ -1083,9 +1083,7 @@ Enterprise_Boundary(b0, "BankBoundary0") {
|
||||
<script>
|
||||
const testLineEndings = (test, input) => {
|
||||
try {
|
||||
mermaid.render(test, input, () => {
|
||||
//no-op
|
||||
});
|
||||
mermaid.render(test, input, () => {});
|
||||
} catch (err) {
|
||||
console.error('Error in %s:\n\n%s', test, err);
|
||||
}
|
||||
|
||||
@@ -1407,15 +1407,6 @@ This sets the auto-wrap padding for the diagram (sides only)
|
||||
|
||||
**Notes:** Default value: 0.
|
||||
|
||||
## parse
|
||||
|
||||
### Parameters
|
||||
|
||||
- `text` **[string][5]**
|
||||
- `parseError` **[Function][6]?**
|
||||
|
||||
Returns **[boolean][7]**
|
||||
|
||||
## setSiteConfig
|
||||
|
||||
## setSiteConfig
|
||||
@@ -1433,7 +1424,7 @@ function _Default value: At default, will mirror Global Config_
|
||||
|
||||
- `conf` **MermaidConfig** The base currentConfig to use as siteConfig
|
||||
|
||||
Returns **[object][8]** The siteConfig
|
||||
Returns **[object][5]** The siteConfig
|
||||
|
||||
## getSiteConfig
|
||||
|
||||
@@ -1445,7 +1436,7 @@ Returns **[object][8]** The siteConfig
|
||||
|
||||
**Notes**: Returns **any** values in siteConfig.
|
||||
|
||||
Returns **[object][8]** The siteConfig
|
||||
Returns **[object][5]** The siteConfig
|
||||
|
||||
## setConfig
|
||||
|
||||
@@ -1484,10 +1475,10 @@ $(function () {
|
||||
|
||||
### Parameters
|
||||
|
||||
- `id` **[string][5]** The id of the element to be rendered
|
||||
- `text` **[string][5]** The graph definition
|
||||
- `cb` **function (svgCode: [string][5], bindFunctions: function (element: [Element][9]): void): void**
|
||||
- `container` **[Element][9]** Selector to element in which a div with the graph temporarily will be
|
||||
- `id` **[string][6]** The id of the element to be rendered
|
||||
- `text` **[string][6]** The graph definition
|
||||
- `cb` **function (svgCode: [string][6], bindFunctions: function (element: [Element][7]): void): void**
|
||||
- `container` **[Element][7]** Selector to element in which a div with the graph temporarily will be
|
||||
inserted. If one is provided a hidden div will be inserted in the body of the page instead. The
|
||||
element will be removed when rendering is completed.
|
||||
|
||||
@@ -1526,7 +1517,7 @@ Pushes in a directive to the configuration
|
||||
|
||||
### Parameters
|
||||
|
||||
- `directive` **[object][8]** The directive to push in
|
||||
- `directive` **[object][5]** The directive to push in
|
||||
|
||||
## reset
|
||||
|
||||
@@ -1624,8 +1615,6 @@ Returns **void**
|
||||
[2]: Setup.md?id=render
|
||||
[3]: 8.6.0_docs.md
|
||||
[4]: #mermaidapi-configuration-defaults
|
||||
[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
|
||||
[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function
|
||||
[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
|
||||
[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
|
||||
[9]: https://developer.mozilla.org/docs/Web/API/Element
|
||||
[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
|
||||
[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
|
||||
[7]: https://developer.mozilla.org/docs/Web/API/Element
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
# Mindmap
|
||||
|
||||
**Edit this Page** [](https://github.com/mermaid-js/mermaid/blob/develop/src/docs/mindmap.md)
|
||||
|
||||
> Mindmap: This is an experimental diagram for now. The syntax and properties can change in future releases. The syntax is stabel except for the icon integration which is the experimental part.
|
||||
|
||||
"A mind map is a diagram used to visually organize information into a hierarchy, showing relationships among pieces of the whole. It is often created around a single concept, drawn as an image in the center of a blank page, to which associated representations of ideas such as images, words and parts of words are added. Major ideas are connected directly to the central concept, and other ideas branch out from those major ideas." Wikipedia
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const path = require('path');
|
||||
|
||||
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mermaid",
|
||||
"version": "9.2.0-rc1",
|
||||
"version": "9.1.6",
|
||||
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||
"main": "dist/mermaid.min.js",
|
||||
"module": "dist/mermaid.esm.min.mjs",
|
||||
|
||||
@@ -8,7 +8,6 @@ export class Diagram {
|
||||
parser;
|
||||
renderer;
|
||||
db;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
constructor(public txt: string, parseError?: Function) {
|
||||
const cnf = configApi.getConfig();
|
||||
this.txt = txt;
|
||||
@@ -34,7 +33,6 @@ export class Diagram {
|
||||
this.parse(this.txt, parseError);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
parse(text: string, parseError?: Function): boolean {
|
||||
try {
|
||||
text = text + '\n';
|
||||
|
||||
@@ -19,7 +19,6 @@ let hasLoadedDiagrams = false;
|
||||
* @param text
|
||||
* @param parseError
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
function parse(text: string, parseError?: Function): boolean {
|
||||
if (!hasLoadedDiagrams) {
|
||||
addDiagrams();
|
||||
|
||||
@@ -62,9 +62,9 @@ export const setSiteConfig = (conf: MermaidConfig): MermaidConfig => {
|
||||
siteConfig = assignWithDepth({}, defaultConfig);
|
||||
siteConfig = assignWithDepth(siteConfig, conf);
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
// @ts-ignore
|
||||
if (conf.theme && theme[conf.theme]) {
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
// @ts-ignore
|
||||
siteConfig.themeVariables = theme[conf.theme].getThemeVariables(conf.themeVariables);
|
||||
}
|
||||
|
||||
@@ -216,8 +216,6 @@ export const addDirective = (directive: any) => {
|
||||
* | conf | base set of values, which currentConfig could be **reset** to. | Dictionary | Required | Any Values, with respect to the secure Array |
|
||||
*
|
||||
* **Notes**: (default: current siteConfig ) (optional, default `getSiteConfig()`)
|
||||
*
|
||||
* @param config
|
||||
*/
|
||||
export const reset = (config = siteConfig): void => {
|
||||
// Replace current config with siteConfig
|
||||
|
||||
@@ -1,356 +1,350 @@
|
||||
// TODO: This was auto generated from defaultConfig. Needs to be verified.
|
||||
|
||||
import DOMPurify from 'dompurify';
|
||||
import type DOMPurify from 'dompurify';
|
||||
|
||||
export interface MermaidConfig {
|
||||
theme?: string;
|
||||
themeVariables?: any;
|
||||
themeCSS?: string;
|
||||
maxTextSize?: number;
|
||||
darkMode?: boolean;
|
||||
htmlLabels?: boolean;
|
||||
fontFamily?: string;
|
||||
altFontFamily?: string;
|
||||
logLevel?: number;
|
||||
securityLevel?: string;
|
||||
startOnLoad?: boolean;
|
||||
arrowMarkerAbsolute?: boolean;
|
||||
secure?: string[];
|
||||
deterministicIds?: boolean;
|
||||
deterministicIDSeed?: string;
|
||||
flowchart?: FlowchartDiagramConfig;
|
||||
sequence?: SequenceDiagramConfig;
|
||||
gantt?: GanttDiagramConfig;
|
||||
journey?: JourneyDiagramConfig;
|
||||
c4?: C4DiagramConfig;
|
||||
class?: ClassDiagramConfig;
|
||||
state?: StateDiagramConfig;
|
||||
darkMode?: boolean;
|
||||
deterministicIDSeed?: string;
|
||||
deterministicIds?: boolean;
|
||||
dompurifyConfig?: DOMPurify.Config;
|
||||
er?: ErDiagramConfig;
|
||||
flowchart?: FlowchartDiagramConfig;
|
||||
fontFamily?: string;
|
||||
fontSize?: number;
|
||||
gantt?: GanttDiagramConfig;
|
||||
gitGraph?: GitGraphDiagramConfig;
|
||||
htmlLabels?: boolean;
|
||||
journey?: JourneyDiagramConfig;
|
||||
logLevel?: number;
|
||||
maxTextSize?: number;
|
||||
mindmap?: MindmapDiagramConfig;
|
||||
pie?: PieDiagramConfig;
|
||||
requirement?: RequirementDiagramConfig;
|
||||
mindmap?: MindmapDiagramConfig;
|
||||
gitGraph?: GitGraphDiagramConfig;
|
||||
c4?: C4DiagramConfig;
|
||||
dompurifyConfig?: DOMPurify.Config;
|
||||
secure?: string[];
|
||||
securityLevel?: string;
|
||||
sequence?: SequenceDiagramConfig;
|
||||
startOnLoad?: boolean;
|
||||
state?: StateDiagramConfig;
|
||||
theme?: string;
|
||||
themeCSS?: string;
|
||||
themeVariables?: any;
|
||||
wrap?: boolean;
|
||||
fontSize?: number;
|
||||
}
|
||||
|
||||
// TODO: More configs needs to be moved in here
|
||||
export interface BaseDiagramConfig {
|
||||
width?: number;
|
||||
height?: number;
|
||||
useWidth?: number;
|
||||
useMaxWidth?: boolean;
|
||||
}
|
||||
|
||||
export interface C4DiagramConfig extends BaseDiagramConfig {
|
||||
diagramMarginX?: number;
|
||||
diagramMarginY?: number;
|
||||
boundaryFont?: FontCalculator;
|
||||
boundaryFontFamily?: string;
|
||||
boundaryFontSize?: string | number;
|
||||
boundaryFontWeight?: string | number;
|
||||
boxMargin?: number;
|
||||
c4BoundaryInRow?: number;
|
||||
c4ShapeInRow?: number;
|
||||
c4ShapeMargin?: number;
|
||||
c4ShapePadding?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
boxMargin?: number;
|
||||
c4ShapeInRow?: number;
|
||||
nextLinePaddingX?: number;
|
||||
c4BoundaryInRow?: number;
|
||||
personFontSize?: string | number;
|
||||
personFontFamily?: string;
|
||||
personFontWeight?: string | number;
|
||||
external_personFontSize?: string | number;
|
||||
external_personFontFamily?: string;
|
||||
external_personFontWeight?: string | number;
|
||||
systemFontSize?: string | number;
|
||||
systemFontFamily?: string;
|
||||
systemFontWeight?: string | number;
|
||||
external_systemFontSize?: string | number;
|
||||
external_systemFontFamily?: string;
|
||||
external_systemFontWeight?: string | number;
|
||||
system_dbFontSize?: string | number;
|
||||
system_dbFontFamily?: string;
|
||||
system_dbFontWeight?: string | number;
|
||||
external_system_dbFontSize?: string | number;
|
||||
external_system_dbFontFamily?: string;
|
||||
external_system_dbFontWeight?: string | number;
|
||||
system_queueFontSize?: string | number;
|
||||
system_queueFontFamily?: string;
|
||||
system_queueFontWeight?: string | number;
|
||||
external_system_queueFontSize?: string | number;
|
||||
external_system_queueFontFamily?: string;
|
||||
external_system_queueFontWeight?: string | number;
|
||||
boundaryFontSize?: string | number;
|
||||
boundaryFontFamily?: string;
|
||||
boundaryFontWeight?: string | number;
|
||||
messageFontSize?: string | number;
|
||||
messageFontFamily?: string;
|
||||
messageFontWeight?: string | number;
|
||||
containerFontSize?: string | number;
|
||||
containerFontFamily?: string;
|
||||
containerFontWeight?: string | number;
|
||||
external_containerFontSize?: string | number;
|
||||
external_containerFontFamily?: string;
|
||||
external_containerFontWeight?: string | number;
|
||||
container_dbFontSize?: string | number;
|
||||
container_dbFontFamily?: string;
|
||||
container_dbFontWeight?: string | number;
|
||||
external_container_dbFontSize?: string | number;
|
||||
external_container_dbFontFamily?: string;
|
||||
external_container_dbFontWeight?: string | number;
|
||||
container_queueFontSize?: string | number;
|
||||
container_queueFontFamily?: string;
|
||||
container_queueFontWeight?: string | number;
|
||||
external_container_queueFontSize?: string | number;
|
||||
external_container_queueFontFamily?: string;
|
||||
external_container_queueFontWeight?: string | number;
|
||||
componentFontSize?: string | number;
|
||||
componentFont?: FontCalculator;
|
||||
componentFontFamily?: string;
|
||||
componentFontSize?: string | number;
|
||||
componentFontWeight?: string | number;
|
||||
external_componentFontSize?: string | number;
|
||||
external_componentFontFamily?: string;
|
||||
external_componentFontWeight?: string | number;
|
||||
component_dbFontSize?: string | number;
|
||||
component_dbFontFamily?: string;
|
||||
component_dbFontWeight?: string | number;
|
||||
external_component_dbFontSize?: string | number;
|
||||
external_component_dbFontFamily?: string;
|
||||
external_component_dbFontWeight?: string | number;
|
||||
component_queueFontSize?: string | number;
|
||||
component_queueFontFamily?: string;
|
||||
component_queueFontWeight?: string | number;
|
||||
external_component_queueFontSize?: string | number;
|
||||
external_component_queueFontFamily?: string;
|
||||
external_component_queueFontWeight?: string | number;
|
||||
wrap?: boolean;
|
||||
wrapPadding?: number;
|
||||
person_bg_color?: string;
|
||||
person_border_color?: string;
|
||||
external_person_bg_color?: string;
|
||||
external_person_border_color?: string;
|
||||
system_bg_color?: string;
|
||||
system_border_color?: string;
|
||||
system_db_bg_color?: string;
|
||||
system_db_border_color?: string;
|
||||
system_queue_bg_color?: string;
|
||||
system_queue_border_color?: string;
|
||||
external_system_bg_color?: string;
|
||||
external_system_border_color?: string;
|
||||
external_system_db_bg_color?: string;
|
||||
external_system_db_border_color?: string;
|
||||
external_system_queue_bg_color?: string;
|
||||
external_system_queue_border_color?: string;
|
||||
container_bg_color?: string;
|
||||
container_border_color?: string;
|
||||
container_db_bg_color?: string;
|
||||
container_db_border_color?: string;
|
||||
container_queue_bg_color?: string;
|
||||
container_queue_border_color?: string;
|
||||
external_container_bg_color?: string;
|
||||
external_container_border_color?: string;
|
||||
external_container_db_bg_color?: string;
|
||||
external_container_db_border_color?: string;
|
||||
external_container_queue_bg_color?: string;
|
||||
external_container_queue_border_color?: string;
|
||||
component_bg_color?: string;
|
||||
component_border_color?: string;
|
||||
component_dbFont?: FontCalculator;
|
||||
component_dbFontFamily?: string;
|
||||
component_dbFontSize?: string | number;
|
||||
component_dbFontWeight?: string | number;
|
||||
component_db_bg_color?: string;
|
||||
component_db_border_color?: string;
|
||||
component_queueFont?: FontCalculator;
|
||||
component_queueFontFamily?: string;
|
||||
component_queueFontSize?: string | number;
|
||||
component_queueFontWeight?: string | number;
|
||||
component_queue_bg_color?: string;
|
||||
component_queue_border_color?: string;
|
||||
containerFont?: FontCalculator;
|
||||
containerFontFamily?: string;
|
||||
containerFontSize?: string | number;
|
||||
containerFontWeight?: string | number;
|
||||
container_bg_color?: string;
|
||||
container_border_color?: string;
|
||||
container_dbFont?: FontCalculator;
|
||||
container_dbFontFamily?: string;
|
||||
container_dbFontSize?: string | number;
|
||||
container_dbFontWeight?: string | number;
|
||||
container_db_bg_color?: string;
|
||||
container_db_border_color?: string;
|
||||
container_queueFont?: FontCalculator;
|
||||
container_queueFontFamily?: string;
|
||||
container_queueFontSize?: string | number;
|
||||
container_queueFontWeight?: string | number;
|
||||
container_queue_bg_color?: string;
|
||||
container_queue_border_color?: string;
|
||||
diagramMarginX?: number;
|
||||
diagramMarginY?: number;
|
||||
external_componentFont?: FontCalculator;
|
||||
external_componentFontFamily?: string;
|
||||
external_componentFontSize?: string | number;
|
||||
external_componentFontWeight?: string | number;
|
||||
external_component_bg_color?: string;
|
||||
external_component_border_color?: string;
|
||||
external_component_dbFont?: FontCalculator;
|
||||
external_component_dbFontFamily?: string;
|
||||
external_component_dbFontSize?: string | number;
|
||||
external_component_dbFontWeight?: string | number;
|
||||
external_component_db_bg_color?: string;
|
||||
external_component_db_border_color?: string;
|
||||
external_component_queueFont?: FontCalculator;
|
||||
external_component_queueFontFamily?: string;
|
||||
external_component_queueFontSize?: string | number;
|
||||
external_component_queueFontWeight?: string | number;
|
||||
external_component_queue_bg_color?: string;
|
||||
external_component_queue_border_color?: string;
|
||||
personFont?: FontCalculator;
|
||||
external_personFont?: FontCalculator;
|
||||
systemFont?: FontCalculator;
|
||||
external_systemFont?: FontCalculator;
|
||||
system_dbFont?: FontCalculator;
|
||||
external_system_dbFont?: FontCalculator;
|
||||
system_queueFont?: FontCalculator;
|
||||
external_system_queueFont?: FontCalculator;
|
||||
containerFont?: FontCalculator;
|
||||
external_containerFont?: FontCalculator;
|
||||
container_dbFont?: FontCalculator;
|
||||
external_containerFontFamily?: string;
|
||||
external_containerFontSize?: string | number;
|
||||
external_containerFontWeight?: string | number;
|
||||
external_container_bg_color?: string;
|
||||
external_container_border_color?: string;
|
||||
external_container_dbFont?: FontCalculator;
|
||||
container_queueFont?: FontCalculator;
|
||||
external_container_dbFontFamily?: string;
|
||||
external_container_dbFontSize?: string | number;
|
||||
external_container_dbFontWeight?: string | number;
|
||||
external_container_db_bg_color?: string;
|
||||
external_container_db_border_color?: string;
|
||||
external_container_queueFont?: FontCalculator;
|
||||
componentFont?: FontCalculator;
|
||||
external_componentFont?: FontCalculator;
|
||||
component_dbFont?: FontCalculator;
|
||||
external_component_dbFont?: FontCalculator;
|
||||
component_queueFont?: FontCalculator;
|
||||
external_component_queueFont?: FontCalculator;
|
||||
boundaryFont?: FontCalculator;
|
||||
external_container_queueFontFamily?: string;
|
||||
external_container_queueFontSize?: string | number;
|
||||
external_container_queueFontWeight?: string | number;
|
||||
external_container_queue_bg_color?: string;
|
||||
external_container_queue_border_color?: string;
|
||||
external_personFont?: FontCalculator;
|
||||
external_personFontFamily?: string;
|
||||
external_personFontSize?: string | number;
|
||||
external_personFontWeight?: string | number;
|
||||
external_person_bg_color?: string;
|
||||
external_person_border_color?: string;
|
||||
external_systemFont?: FontCalculator;
|
||||
external_systemFontFamily?: string;
|
||||
external_systemFontSize?: string | number;
|
||||
external_systemFontWeight?: string | number;
|
||||
external_system_bg_color?: string;
|
||||
external_system_border_color?: string;
|
||||
external_system_dbFont?: FontCalculator;
|
||||
external_system_dbFontFamily?: string;
|
||||
external_system_dbFontSize?: string | number;
|
||||
external_system_dbFontWeight?: string | number;
|
||||
external_system_db_bg_color?: string;
|
||||
external_system_db_border_color?: string;
|
||||
external_system_queueFont?: FontCalculator;
|
||||
external_system_queueFontFamily?: string;
|
||||
external_system_queueFontSize?: string | number;
|
||||
external_system_queueFontWeight?: string | number;
|
||||
external_system_queue_bg_color?: string;
|
||||
external_system_queue_border_color?: string;
|
||||
messageFont?: FontCalculator;
|
||||
messageFontFamily?: string;
|
||||
messageFontSize?: string | number;
|
||||
messageFontWeight?: string | number;
|
||||
nextLinePaddingX?: number;
|
||||
personFont?: FontCalculator;
|
||||
personFontFamily?: string;
|
||||
personFontSize?: string | number;
|
||||
personFontWeight?: string | number;
|
||||
person_bg_color?: string;
|
||||
person_border_color?: string;
|
||||
systemFont?: FontCalculator;
|
||||
systemFontFamily?: string;
|
||||
systemFontSize?: string | number;
|
||||
systemFontWeight?: string | number;
|
||||
system_bg_color?: string;
|
||||
system_border_color?: string;
|
||||
system_dbFont?: FontCalculator;
|
||||
system_dbFontFamily?: string;
|
||||
system_dbFontSize?: string | number;
|
||||
system_dbFontWeight?: string | number;
|
||||
system_db_bg_color?: string;
|
||||
system_db_border_color?: string;
|
||||
system_queueFont?: FontCalculator;
|
||||
system_queueFontFamily?: string;
|
||||
system_queueFontSize?: string | number;
|
||||
system_queueFontWeight?: string | number;
|
||||
system_queue_bg_color?: string;
|
||||
system_queue_border_color?: string;
|
||||
wrap?: boolean;
|
||||
wrapPadding?: number;
|
||||
}
|
||||
|
||||
export interface GitGraphDiagramConfig extends BaseDiagramConfig {
|
||||
arrowMarkerAbsolute?: boolean;
|
||||
diagramPadding?: number;
|
||||
nodeLabel?: NodeLabel;
|
||||
mainBranchName?: string;
|
||||
mainBranchOrder?: number;
|
||||
showCommitLabel?: boolean;
|
||||
showBranches?: boolean;
|
||||
nodeLabel?: NodeLabel;
|
||||
rotateCommitLabel?: boolean;
|
||||
arrowMarkerAbsolute?: boolean;
|
||||
showBranches?: boolean;
|
||||
showCommitLabel?: boolean;
|
||||
}
|
||||
|
||||
export interface NodeLabel {
|
||||
width?: number;
|
||||
height?: number;
|
||||
width?: number;
|
||||
x?: number;
|
||||
y?: number;
|
||||
}
|
||||
|
||||
export interface RequirementDiagramConfig extends BaseDiagramConfig {
|
||||
rect_fill?: string;
|
||||
text_color?: string;
|
||||
rect_border_size?: string;
|
||||
rect_border_color?: string;
|
||||
rect_min_width?: number;
|
||||
rect_min_height?: number;
|
||||
fontSize?: number;
|
||||
rect_padding?: number;
|
||||
line_height?: number;
|
||||
rect_border_color?: string;
|
||||
rect_border_size?: string;
|
||||
rect_fill?: string;
|
||||
rect_min_height?: number;
|
||||
rect_min_width?: number;
|
||||
rect_padding?: number;
|
||||
text_color?: string;
|
||||
}
|
||||
|
||||
export interface MindmapDiagramConfig extends BaseDiagramConfig {
|
||||
useMaxWidth: boolean;
|
||||
padding: number;
|
||||
maxNodeWidth: number;
|
||||
padding?: number;
|
||||
maxNodeWidth?: number;
|
||||
}
|
||||
|
||||
export type PieDiagramConfig = BaseDiagramConfig;
|
||||
export interface PieDiagramConfig extends BaseDiagramConfig {}
|
||||
|
||||
export interface ErDiagramConfig extends BaseDiagramConfig {
|
||||
diagramPadding?: number;
|
||||
layoutDirection?: string;
|
||||
minEntityWidth?: number;
|
||||
minEntityHeight?: number;
|
||||
entityPadding?: number;
|
||||
stroke?: string;
|
||||
fill?: string;
|
||||
fontSize?: number;
|
||||
layoutDirection?: string;
|
||||
minEntityHeight?: number;
|
||||
minEntityWidth?: number;
|
||||
stroke?: string;
|
||||
}
|
||||
|
||||
export interface StateDiagramConfig extends BaseDiagramConfig {
|
||||
arrowMarkerAbsolute?: boolean;
|
||||
compositTitleSize?: number;
|
||||
defaultRenderer?: string;
|
||||
dividerMargin?: number;
|
||||
sizeUnit?: number;
|
||||
edgeLengthFactor?: string;
|
||||
fontSize?: number;
|
||||
fontSizeFactor?: number;
|
||||
forkHeight?: number;
|
||||
forkWidth?: number;
|
||||
labelHeight?: number;
|
||||
miniPadding?: number;
|
||||
noteMargin?: number;
|
||||
padding?: number;
|
||||
radius?: number;
|
||||
sizeUnit?: number;
|
||||
textHeight?: number;
|
||||
titleShift?: number;
|
||||
noteMargin?: number;
|
||||
forkWidth?: number;
|
||||
forkHeight?: number;
|
||||
miniPadding?: number;
|
||||
fontSizeFactor?: number;
|
||||
fontSize?: number;
|
||||
labelHeight?: number;
|
||||
edgeLengthFactor?: string;
|
||||
compositTitleSize?: number;
|
||||
radius?: number;
|
||||
defaultRenderer?: string;
|
||||
}
|
||||
|
||||
export interface ClassDiagramConfig extends BaseDiagramConfig {
|
||||
arrowMarkerAbsolute?: boolean;
|
||||
defaultRenderer?: string;
|
||||
dividerMargin?: number;
|
||||
padding?: number;
|
||||
textHeight?: number;
|
||||
defaultRenderer?: string;
|
||||
}
|
||||
|
||||
export interface JourneyDiagramConfig extends BaseDiagramConfig {
|
||||
activationWidth?: number;
|
||||
actorColours?: string[];
|
||||
bottomMarginAdj?: number;
|
||||
boxMargin?: number;
|
||||
boxTextMargin?: number;
|
||||
diagramMarginX?: number;
|
||||
diagramMarginY?: number;
|
||||
leftMargin?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
boxMargin?: number;
|
||||
boxTextMargin?: number;
|
||||
noteMargin?: number;
|
||||
messageMargin?: number;
|
||||
messageAlign?: string;
|
||||
bottomMarginAdj?: number;
|
||||
messageMargin?: number;
|
||||
noteMargin?: number;
|
||||
rightAngles?: boolean;
|
||||
taskFontSize?: string | number;
|
||||
taskFontFamily?: string;
|
||||
taskMargin?: number;
|
||||
activationWidth?: number;
|
||||
textPlacement?: string;
|
||||
actorColours?: string[];
|
||||
sectionFills?: string[];
|
||||
sectionColours?: string[];
|
||||
sectionFills?: string[];
|
||||
taskFontFamily?: string;
|
||||
taskFontSize?: string | number;
|
||||
taskMargin?: number;
|
||||
textPlacement?: string;
|
||||
}
|
||||
|
||||
export interface GanttDiagramConfig extends BaseDiagramConfig {
|
||||
titleTopMargin?: number;
|
||||
barHeight?: number;
|
||||
barGap?: number;
|
||||
topPadding?: number;
|
||||
rightPadding?: number;
|
||||
leftPadding?: number;
|
||||
gridLineStartPadding?: number;
|
||||
fontSize?: number;
|
||||
sectionFontSize?: string | number;
|
||||
numberSectionStyles?: number;
|
||||
axisFormat?: string;
|
||||
barGap?: number;
|
||||
barHeight?: number;
|
||||
fontSize?: number;
|
||||
gridLineStartPadding?: number;
|
||||
leftPadding?: number;
|
||||
numberSectionStyles?: number;
|
||||
rightPadding?: number;
|
||||
sectionFontSize?: string | number;
|
||||
titleTopMargin?: number;
|
||||
topAxis?: boolean;
|
||||
topPadding?: number;
|
||||
}
|
||||
|
||||
export interface SequenceDiagramConfig extends BaseDiagramConfig {
|
||||
arrowMarkerAbsolute?: boolean;
|
||||
hideUnusedParticipants?: boolean;
|
||||
activationWidth?: number;
|
||||
diagramMarginX?: number;
|
||||
diagramMarginY?: number;
|
||||
actorFont?: FontCalculator;
|
||||
actorFontFamily?: string;
|
||||
actorFontSize?: string | number;
|
||||
actorFontWeight?: string | number;
|
||||
actorMargin?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
arrowMarkerAbsolute?: boolean;
|
||||
bottomMarginAdj?: number;
|
||||
boxMargin?: number;
|
||||
boxTextMargin?: number;
|
||||
noteMargin?: number;
|
||||
messageMargin?: number;
|
||||
messageAlign?: string;
|
||||
mirrorActors?: boolean;
|
||||
diagramMarginX?: number;
|
||||
diagramMarginY?: number;
|
||||
forceMenus?: boolean;
|
||||
bottomMarginAdj?: number;
|
||||
hideUnusedParticipants?: boolean;
|
||||
labelBoxHeight?: number;
|
||||
labelBoxWidth?: number;
|
||||
messageAlign?: string;
|
||||
messageFont?: FontCalculator;
|
||||
messageFontFamily?: string;
|
||||
messageFontSize?: string | number;
|
||||
messageFontWeight?: string | number;
|
||||
messageMargin?: number;
|
||||
mirrorActors?: boolean;
|
||||
noteAlign?: string;
|
||||
noteFont?: FontCalculator;
|
||||
noteFontFamily?: string;
|
||||
noteFontSize?: string | number;
|
||||
noteFontWeight?: string | number;
|
||||
noteMargin?: number;
|
||||
rightAngles?: boolean;
|
||||
showSequenceNumbers?: boolean;
|
||||
actorFontSize?: string | number;
|
||||
actorFontFamily?: string;
|
||||
actorFontWeight?: string | number;
|
||||
noteFontSize?: string | number;
|
||||
noteFontFamily?: string;
|
||||
noteFontWeight?: string | number;
|
||||
noteAlign?: string;
|
||||
messageFontSize?: string | number;
|
||||
messageFontFamily?: string;
|
||||
messageFontWeight?: string | number;
|
||||
wrap?: boolean;
|
||||
wrapPadding?: number;
|
||||
labelBoxWidth?: number;
|
||||
labelBoxHeight?: number;
|
||||
messageFont?: FontCalculator;
|
||||
noteFont?: FontCalculator;
|
||||
actorFont?: FontCalculator;
|
||||
}
|
||||
|
||||
export interface FlowchartDiagramConfig extends BaseDiagramConfig {
|
||||
arrowMarkerAbsolute?: boolean;
|
||||
curve?: string;
|
||||
defaultRenderer?: string;
|
||||
diagramPadding?: number;
|
||||
htmlLabels?: boolean;
|
||||
nodeSpacing?: number;
|
||||
rankSpacing?: number;
|
||||
curve?: string;
|
||||
padding?: number;
|
||||
defaultRenderer?: string;
|
||||
rankSpacing?: number;
|
||||
}
|
||||
|
||||
export interface FontConfig {
|
||||
fontSize?: string | number;
|
||||
fontFamily?: string;
|
||||
fontSize?: string | number;
|
||||
fontWeight?: string | number;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,26 @@
|
||||
import { MermaidConfig } from '../config.type';
|
||||
|
||||
export type DiagramDetector = (text: string, config?: MermaidConfig) => boolean;
|
||||
export type DiagramDetector = (text: string) => boolean;
|
||||
|
||||
const directive =
|
||||
/[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi;
|
||||
const anyComment = /\s*%%.*\n/gm;
|
||||
|
||||
const detectors: Record<string, DiagramDetector> = {};
|
||||
const diagramMatchers: Record<string, RegExp> = {
|
||||
c4: /^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/,
|
||||
sequence: /^\s*sequenceDiagram/,
|
||||
gantt: /^\s*gantt/,
|
||||
classDiagram: /^\s*classDiagram-v2/,
|
||||
stateDiagram: /^\s*stateDiagram-v2/,
|
||||
'flowchart-v2': /^\s*flowchart/, // Might need to add |graph to fix #3391
|
||||
info: /^\s*info/,
|
||||
pie: /^\s*pie/,
|
||||
er: /^\s*erDiagram/,
|
||||
journey: /^\s*journey/,
|
||||
// gitGraph: /^\s*gitGraph/,
|
||||
requirement: /^\s*requirement(Diagram)?/,
|
||||
};
|
||||
|
||||
/**
|
||||
* @function detectType Detects the type of the graph text. Takes into consideration the possible
|
||||
@@ -33,9 +47,28 @@ const detectors: Record<string, DiagramDetector> = {};
|
||||
*/
|
||||
export const detectType = function (text: string, config?: MermaidConfig): string {
|
||||
text = text.replace(directive, '').replace(anyComment, '\n');
|
||||
for (const [diagram, matcher] of Object.entries(diagramMatchers)) {
|
||||
if (text.match(matcher)) {
|
||||
return diagram;
|
||||
}
|
||||
}
|
||||
|
||||
if (text.match(/^\s*classDiagram/)) {
|
||||
if (config?.class?.defaultRenderer === 'dagre-wrapper') return 'classDiagram';
|
||||
return 'class';
|
||||
}
|
||||
|
||||
if (text.match(/^\s*stateDiagram/)) {
|
||||
if (config?.state?.defaultRenderer === 'dagre-wrapper') return 'stateDiagram';
|
||||
return 'state';
|
||||
}
|
||||
|
||||
if (config?.flowchart?.defaultRenderer === 'dagre-wrapper') {
|
||||
return 'flowchart-v2';
|
||||
}
|
||||
|
||||
for (const [key, detector] of Object.entries(detectors)) {
|
||||
if (detector(text, config)) {
|
||||
if (detector(text)) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,310 +1,20 @@
|
||||
import { registerDiagram } from './diagramAPI';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import mindmapParser from '../diagrams/mindmap/parser/mindmap';
|
||||
import * as mindmapDb from '../diagrams/mindmap/mindmapDb';
|
||||
import { mindmapDetector } from '../diagrams/mindmap/mindmapDetector';
|
||||
import mindmapRenderer from '../diagrams/mindmap/mindmapRenderer';
|
||||
// @ts-ignore
|
||||
import mindmapParser from '../diagrams/mindmap/parser/mindmap';
|
||||
import { mindmapDetector } from '../diagrams/mindmap/mindmapDetector';
|
||||
import mindmapStyles from '../diagrams/mindmap/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import gitGraphParser from '../diagrams/git/parser/gitGraph';
|
||||
import { gitGraphDetector } from '../diagrams/git/gitGraphDetector';
|
||||
import gitGraphDb from '../diagrams/git/gitGraphAst';
|
||||
import gitGraphRenderer from '../diagrams/git/gitGraphRenderer';
|
||||
// @ts-ignore
|
||||
import gitGraphParser from '../diagrams/git/parser/gitGraph';
|
||||
import { gitGraphDetector } from '../diagrams/git/gitGraphDetector';
|
||||
import gitGraphStyles from '../diagrams/git/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import c4Parser from '../diagrams/c4/parser/c4Diagram';
|
||||
import { c4Detector } from '../diagrams/c4/c4Detector';
|
||||
import c4Db from '../diagrams/c4/c4Db';
|
||||
import c4Renderer from '../diagrams/c4/c4Renderer';
|
||||
import c4Styles from '../diagrams/c4/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import classParser from '../diagrams/class/parser/classDiagram';
|
||||
import { classDetector } from '../diagrams/class/classDetector';
|
||||
import { classDetectorV2 } from '../diagrams/class/classDetector-V2';
|
||||
import classDb from '../diagrams/class/classDb';
|
||||
import classRenderer from '../diagrams/class/classRenderer';
|
||||
import classRendererV2 from '../diagrams/class/classRenderer-v2';
|
||||
import classStyles from '../diagrams/class/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import erParser from '../diagrams/er/parser/erDiagram';
|
||||
import { erDetector } from '../diagrams/er/erDetector';
|
||||
import erDb from '../diagrams/er/erDb';
|
||||
import erRenderer from '../diagrams/er/erRenderer';
|
||||
import erStyles from '../diagrams/er/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import flowParser from '../diagrams/flowchart/parser/flow';
|
||||
import { flowDetector } from '../diagrams/flowchart/flowDetector';
|
||||
import { flowDetectorV2 } from '../diagrams/flowchart/flowDetector-v2';
|
||||
import flowDb from '../diagrams/flowchart/flowDb';
|
||||
import flowRenderer from '../diagrams/flowchart/flowRenderer';
|
||||
import flowRendererV2 from '../diagrams/flowchart/flowRenderer-v2';
|
||||
import flowStyles from '../diagrams/flowchart/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import ganttParser from '../diagrams/gantt/parser/gantt';
|
||||
import { ganttDetector } from '../diagrams/gantt/ganttDetector';
|
||||
import ganttDb from '../diagrams/gantt/ganttDb';
|
||||
import ganttRenderer from '../diagrams/gantt/ganttRenderer';
|
||||
import ganttStyles from '../diagrams/gantt/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import infoParser from '../diagrams/info/parser/info';
|
||||
import infoDb from '../diagrams/info/infoDb';
|
||||
import infoRenderer from '../diagrams/info/infoRenderer';
|
||||
import { infoDetector } from '../diagrams/info/infoDetector';
|
||||
import infoStyles from '../diagrams/info/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import pieParser from '../diagrams/pie/parser/pie';
|
||||
import { pieDetector } from '../diagrams/pie/pieDetector';
|
||||
import pieDb from '../diagrams/pie/pieDb';
|
||||
import pieRenderer from '../diagrams/pie/pieRenderer';
|
||||
import pieStyles from '../diagrams/pie/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import requirementParser from '../diagrams/requirement/parser/requirementDiagram';
|
||||
import { requirementDetector } from '../diagrams/requirement/requirementDetector';
|
||||
import requirementDb from '../diagrams/requirement/requirementDb';
|
||||
import requirementRenderer from '../diagrams/requirement/requirementRenderer';
|
||||
import requirementStyles from '../diagrams/requirement/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import sequenceParser from '../diagrams/sequence/parser/sequenceDiagram';
|
||||
import { sequenceDetector } from '../diagrams/sequence/sequenceDetector';
|
||||
import sequenceDb from '../diagrams/sequence/sequenceDb';
|
||||
import sequenceRenderer from '../diagrams/sequence/sequenceRenderer';
|
||||
import sequenceStyles from '../diagrams/sequence/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import stateParser from '../diagrams/state/parser/stateDiagram';
|
||||
import { stateDetector } from '../diagrams/state/stateDetector';
|
||||
import { stateDetectorV2 } from '../diagrams/state/stateDetector-V2';
|
||||
import stateDb from '../diagrams/state/stateDb';
|
||||
import stateRenderer from '../diagrams/state/stateRenderer';
|
||||
import stateRendererV2 from '../diagrams/state/stateRenderer-v2';
|
||||
import stateStyles from '../diagrams/state/styles';
|
||||
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
import journeyParser from '../diagrams/user-journey/parser/journey';
|
||||
import { journeyDetector } from '../diagrams/user-journey/journeyDetector';
|
||||
import journeyDb from '../diagrams/user-journey/journeyDb';
|
||||
import journeyRenderer from '../diagrams/user-journey/journeyRenderer';
|
||||
import journeyStyles from '../diagrams/user-journey/styles';
|
||||
|
||||
export const addDiagrams = () => {
|
||||
registerDiagram(
|
||||
'c4',
|
||||
{
|
||||
parser: c4Parser,
|
||||
db: c4Db,
|
||||
renderer: c4Renderer,
|
||||
styles: c4Styles,
|
||||
init: (cnf) => {
|
||||
c4Renderer.setConf(cnf.c4);
|
||||
},
|
||||
},
|
||||
c4Detector
|
||||
);
|
||||
registerDiagram(
|
||||
'class',
|
||||
{
|
||||
parser: classParser,
|
||||
db: classDb,
|
||||
renderer: classRenderer,
|
||||
styles: classStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.class) {
|
||||
cnf.class = {};
|
||||
}
|
||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
classDb.clear();
|
||||
},
|
||||
},
|
||||
classDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'classDiagram',
|
||||
{
|
||||
parser: classParser,
|
||||
db: classDb,
|
||||
renderer: classRendererV2,
|
||||
styles: classStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.class) {
|
||||
cnf.class = {};
|
||||
}
|
||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
classDb.clear();
|
||||
},
|
||||
},
|
||||
classDetectorV2
|
||||
);
|
||||
registerDiagram(
|
||||
'er',
|
||||
{
|
||||
parser: erParser,
|
||||
db: erDb,
|
||||
renderer: erRenderer,
|
||||
styles: erStyles,
|
||||
},
|
||||
erDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'gantt',
|
||||
{
|
||||
parser: ganttParser,
|
||||
db: ganttDb,
|
||||
renderer: ganttRenderer,
|
||||
styles: ganttStyles,
|
||||
},
|
||||
ganttDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'info',
|
||||
{
|
||||
parser: infoParser,
|
||||
db: infoDb,
|
||||
renderer: infoRenderer,
|
||||
styles: infoStyles,
|
||||
},
|
||||
infoDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'pie',
|
||||
{
|
||||
parser: pieParser,
|
||||
db: pieDb,
|
||||
renderer: pieRenderer,
|
||||
styles: pieStyles,
|
||||
},
|
||||
pieDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'requirement',
|
||||
{
|
||||
parser: requirementParser,
|
||||
db: requirementDb,
|
||||
renderer: requirementRenderer,
|
||||
styles: requirementStyles,
|
||||
},
|
||||
requirementDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'sequence',
|
||||
{
|
||||
parser: sequenceParser,
|
||||
db: sequenceDb,
|
||||
renderer: sequenceRenderer,
|
||||
styles: sequenceStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.sequence) {
|
||||
cnf.sequence = {};
|
||||
}
|
||||
cnf.sequence.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
if ('sequenceDiagram' in cnf) {
|
||||
throw new Error(
|
||||
'`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.'
|
||||
);
|
||||
}
|
||||
sequenceDb.setWrap(cnf.wrap);
|
||||
sequenceRenderer.setConf(cnf.sequence);
|
||||
},
|
||||
},
|
||||
sequenceDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'state',
|
||||
{
|
||||
parser: stateParser,
|
||||
db: stateDb,
|
||||
renderer: stateRenderer,
|
||||
styles: stateStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.state) {
|
||||
cnf.state = {};
|
||||
}
|
||||
cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
stateDb.clear();
|
||||
},
|
||||
},
|
||||
stateDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'stateDiagram',
|
||||
{
|
||||
parser: stateParser,
|
||||
db: stateDb,
|
||||
renderer: stateRendererV2,
|
||||
styles: stateStyles,
|
||||
init: (cnf) => {
|
||||
if (!cnf.state) {
|
||||
cnf.state = {};
|
||||
}
|
||||
cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
stateDb.clear();
|
||||
},
|
||||
},
|
||||
stateDetectorV2
|
||||
);
|
||||
registerDiagram(
|
||||
'journey',
|
||||
{
|
||||
parser: journeyParser,
|
||||
db: journeyDb,
|
||||
renderer: journeyRenderer,
|
||||
styles: journeyStyles,
|
||||
init: (cnf) => {
|
||||
journeyRenderer.setConf(cnf.journey);
|
||||
journeyDb.clear();
|
||||
},
|
||||
},
|
||||
journeyDetector
|
||||
);
|
||||
|
||||
registerDiagram(
|
||||
'flowchart',
|
||||
{
|
||||
parser: flowParser,
|
||||
db: flowDb,
|
||||
renderer: flowRendererV2,
|
||||
styles: flowStyles,
|
||||
init: (cnf) => {
|
||||
flowRenderer.setConf(cnf.flowchart);
|
||||
if (!cnf.flowchart) {
|
||||
cnf.flowchart = {};
|
||||
}
|
||||
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-1');
|
||||
},
|
||||
},
|
||||
flowDetector
|
||||
);
|
||||
registerDiagram(
|
||||
'flowchart-v2',
|
||||
{
|
||||
parser: flowParser,
|
||||
db: flowDb,
|
||||
renderer: flowRendererV2,
|
||||
styles: flowStyles,
|
||||
init: (cnf) => {
|
||||
flowRendererV2.setConf(cnf.flowchart);
|
||||
if (!cnf.flowchart) {
|
||||
cnf.flowchart = {};
|
||||
}
|
||||
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-2');
|
||||
},
|
||||
},
|
||||
flowDetectorV2
|
||||
);
|
||||
// Register mindmap and other built-in diagrams
|
||||
registerDiagram(
|
||||
'gitGraph',
|
||||
{ parser: gitGraphParser, db: gitGraphDb, renderer: gitGraphRenderer, styles: gitGraphStyles },
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { detectType } from './detectType';
|
||||
import { getDiagram, registerDiagram } from './diagramAPI';
|
||||
import { addDiagrams } from './diagram-orchestration';
|
||||
|
||||
addDiagrams();
|
||||
|
||||
describe('DiagramAPI', () => {
|
||||
it('should return default diagrams', () => {
|
||||
|
||||
@@ -1,23 +1,70 @@
|
||||
import { addDetector, DiagramDetector as _DiagramDetector } from './detectType';
|
||||
import { log as _log, setLogLevel as _setLogLevel } from '../logger';
|
||||
import c4Db from '../diagrams/c4/c4Db';
|
||||
import c4Renderer from '../diagrams/c4/c4Renderer';
|
||||
import c4Styles from '../diagrams/c4/styles';
|
||||
// @ts-ignore
|
||||
import c4Parser from '../diagrams/c4/parser/c4Diagram';
|
||||
import classDb from '../diagrams/class/classDb';
|
||||
import classRenderer from '../diagrams/class/classRenderer';
|
||||
import classRendererV2 from '../diagrams/class/classRenderer-v2';
|
||||
import classStyles from '../diagrams/class/styles';
|
||||
// @ts-ignore
|
||||
import classParser from '../diagrams/class/parser/classDiagram';
|
||||
import erDb from '../diagrams/er/erDb';
|
||||
import erRenderer from '../diagrams/er/erRenderer';
|
||||
// @ts-ignore
|
||||
import erParser from '../diagrams/er/parser/erDiagram';
|
||||
import erStyles from '../diagrams/er/styles';
|
||||
import flowDb from '../diagrams/flowchart/flowDb';
|
||||
import flowRenderer from '../diagrams/flowchart/flowRenderer';
|
||||
import flowRendererV2 from '../diagrams/flowchart/flowRenderer-v2';
|
||||
import flowStyles from '../diagrams/flowchart/styles';
|
||||
// @ts-ignore
|
||||
import flowParser from '../diagrams/flowchart/parser/flow';
|
||||
import ganttDb from '../diagrams/gantt/ganttDb';
|
||||
import ganttRenderer from '../diagrams/gantt/ganttRenderer';
|
||||
// @ts-ignore
|
||||
import ganttParser from '../diagrams/gantt/parser/gantt';
|
||||
import ganttStyles from '../diagrams/gantt/styles';
|
||||
|
||||
import infoDb from '../diagrams/info/infoDb';
|
||||
import infoRenderer from '../diagrams/info/infoRenderer';
|
||||
// @ts-ignore
|
||||
import infoParser from '../diagrams/info/parser/info';
|
||||
import infoStyles from '../diagrams/info/styles';
|
||||
// @ts-ignore
|
||||
import pieParser from '../diagrams/pie/parser/pie';
|
||||
import pieDb from '../diagrams/pie/pieDb';
|
||||
import pieRenderer from '../diagrams/pie/pieRenderer';
|
||||
import pieStyles from '../diagrams/pie/styles';
|
||||
// @ts-ignore
|
||||
import requirementParser from '../diagrams/requirement/parser/requirementDiagram';
|
||||
import requirementDb from '../diagrams/requirement/requirementDb';
|
||||
import requirementRenderer from '../diagrams/requirement/requirementRenderer';
|
||||
import requirementStyles from '../diagrams/requirement/styles';
|
||||
// @ts-ignore
|
||||
import sequenceParser from '../diagrams/sequence/parser/sequenceDiagram';
|
||||
import sequenceDb from '../diagrams/sequence/sequenceDb';
|
||||
import sequenceRenderer from '../diagrams/sequence/sequenceRenderer';
|
||||
import sequenceStyles from '../diagrams/sequence/styles';
|
||||
// @ts-ignore
|
||||
import stateParser from '../diagrams/state/parser/stateDiagram';
|
||||
import stateDb from '../diagrams/state/stateDb';
|
||||
import stateRenderer from '../diagrams/state/stateRenderer';
|
||||
import stateRendererV2 from '../diagrams/state/stateRenderer-v2';
|
||||
import stateStyles from '../diagrams/state/styles';
|
||||
import journeyDb from '../diagrams/user-journey/journeyDb';
|
||||
import journeyRenderer from '../diagrams/user-journey/journeyRenderer';
|
||||
import journeyStyles from '../diagrams/user-journey/styles';
|
||||
// @ts-ignore
|
||||
import journeyParser from '../diagrams/user-journey/parser/journey';
|
||||
import { addDetector, DiagramDetector } from './detectType';
|
||||
import { log as _log } from '../logger';
|
||||
import { getConfig as _getConfig } from '../config';
|
||||
import { sanitizeText as _sanitizeText } from '../diagrams/common/common';
|
||||
import { MermaidConfig } from '../config.type';
|
||||
import { setupGraphViewbox as _setupGraphViewbox } from '../setupGraphViewbox';
|
||||
import { addStylesForDiagram } from '../styles';
|
||||
|
||||
/*
|
||||
Packaging and exposing resources for externa diagrams so that they can import
|
||||
diagramAPI and have access to selct parts of mermaid common code reqiored to
|
||||
create diagrams worling like the internal diagrams.
|
||||
*/
|
||||
export const log = _log;
|
||||
export const setLogLevel = _setLogLevel;
|
||||
export type DiagramDetector = _DiagramDetector;
|
||||
export const getConfig = _getConfig;
|
||||
export const sanitizeText = (text: string) => _sanitizeText(text, getConfig());
|
||||
export const setupGraphViewbox = _setupGraphViewbox;
|
||||
|
||||
export interface DiagramDefinition {
|
||||
db: any;
|
||||
renderer: any;
|
||||
@@ -26,7 +73,158 @@ export interface DiagramDefinition {
|
||||
init?: (config: MermaidConfig) => void;
|
||||
}
|
||||
|
||||
const diagrams: Record<string, DiagramDefinition> = {};
|
||||
const diagrams: Record<string, DiagramDefinition> = {
|
||||
c4: {
|
||||
db: c4Db,
|
||||
renderer: c4Renderer,
|
||||
parser: c4Parser,
|
||||
init: (cnf) => {
|
||||
c4Renderer.setConf(cnf.c4);
|
||||
},
|
||||
styles: c4Styles,
|
||||
},
|
||||
class: {
|
||||
db: classDb,
|
||||
renderer: classRenderer,
|
||||
parser: classParser,
|
||||
init: (cnf) => {
|
||||
if (!cnf.class) {
|
||||
cnf.class = {};
|
||||
}
|
||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
classDb.clear();
|
||||
},
|
||||
styles: classStyles,
|
||||
},
|
||||
classDiagram: {
|
||||
db: classDb,
|
||||
renderer: classRendererV2,
|
||||
parser: classParser,
|
||||
init: (cnf) => {
|
||||
if (!cnf.class) {
|
||||
cnf.class = {};
|
||||
}
|
||||
cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
classDb.clear();
|
||||
},
|
||||
styles: classStyles,
|
||||
},
|
||||
er: {
|
||||
db: erDb,
|
||||
renderer: erRenderer,
|
||||
parser: erParser,
|
||||
styles: erStyles,
|
||||
},
|
||||
flowchart: {
|
||||
db: flowDb,
|
||||
renderer: flowRenderer,
|
||||
parser: flowParser,
|
||||
init: (cnf) => {
|
||||
flowRenderer.setConf(cnf.flowchart);
|
||||
if (!cnf.flowchart) {
|
||||
cnf.flowchart = {};
|
||||
}
|
||||
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-1');
|
||||
},
|
||||
styles: flowStyles,
|
||||
},
|
||||
'flowchart-v2': {
|
||||
db: flowDb,
|
||||
renderer: flowRendererV2,
|
||||
parser: flowParser,
|
||||
init: (cnf) => {
|
||||
flowRendererV2.setConf(cnf.flowchart);
|
||||
if (!cnf.flowchart) {
|
||||
cnf.flowchart = {};
|
||||
}
|
||||
cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-2');
|
||||
},
|
||||
styles: flowStyles,
|
||||
},
|
||||
gantt: {
|
||||
db: ganttDb,
|
||||
renderer: ganttRenderer,
|
||||
parser: ganttParser,
|
||||
styles: ganttStyles,
|
||||
},
|
||||
info: {
|
||||
db: infoDb,
|
||||
renderer: infoRenderer,
|
||||
parser: infoParser,
|
||||
styles: infoStyles,
|
||||
},
|
||||
pie: {
|
||||
db: pieDb,
|
||||
renderer: pieRenderer,
|
||||
parser: pieParser,
|
||||
styles: pieStyles,
|
||||
},
|
||||
requirement: {
|
||||
db: requirementDb,
|
||||
renderer: requirementRenderer,
|
||||
parser: requirementParser,
|
||||
styles: requirementStyles,
|
||||
},
|
||||
sequence: {
|
||||
db: sequenceDb,
|
||||
renderer: sequenceRenderer,
|
||||
parser: sequenceParser,
|
||||
init: (cnf) => {
|
||||
if (!cnf.sequence) {
|
||||
cnf.sequence = {};
|
||||
}
|
||||
cnf.sequence.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
if ('sequenceDiagram' in cnf) {
|
||||
throw new Error(
|
||||
'`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.'
|
||||
);
|
||||
}
|
||||
sequenceDb.setWrap(cnf.wrap);
|
||||
sequenceRenderer.setConf(cnf.sequence);
|
||||
},
|
||||
styles: sequenceStyles,
|
||||
},
|
||||
state: {
|
||||
db: stateDb,
|
||||
renderer: stateRenderer,
|
||||
parser: stateParser,
|
||||
init: (cnf) => {
|
||||
if (!cnf.state) {
|
||||
cnf.state = {};
|
||||
}
|
||||
cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
stateDb.clear();
|
||||
},
|
||||
styles: stateStyles,
|
||||
},
|
||||
stateDiagram: {
|
||||
db: stateDb,
|
||||
renderer: stateRendererV2,
|
||||
parser: stateParser,
|
||||
init: (cnf) => {
|
||||
if (!cnf.state) {
|
||||
cnf.state = {};
|
||||
}
|
||||
cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
|
||||
stateDb.clear();
|
||||
},
|
||||
styles: stateStyles,
|
||||
},
|
||||
journey: {
|
||||
db: journeyDb,
|
||||
renderer: journeyRenderer,
|
||||
parser: journeyParser,
|
||||
init: (cnf) => {
|
||||
journeyRenderer.setConf(cnf.journey);
|
||||
journeyDb.clear();
|
||||
},
|
||||
styles: journeyStyles,
|
||||
},
|
||||
};
|
||||
|
||||
export const registerDiagram = (
|
||||
id: string,
|
||||
@@ -47,3 +245,8 @@ export const getDiagram = (name: string): DiagramDefinition => {
|
||||
}
|
||||
throw new Error(`Diagram ${name} not found.`);
|
||||
};
|
||||
|
||||
export const log = _log;
|
||||
export const getConfig = _getConfig;
|
||||
export const sanitizeText = (text: string) => _sanitizeText(text, getConfig());
|
||||
export const setupGraphViewbox = _setupGraphViewbox;
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const c4Detector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/) !== null;
|
||||
};
|
||||
@@ -1,110 +0,0 @@
|
||||
import c4Db from '../c4Db';
|
||||
import c4 from './c4Diagram.jison';
|
||||
import { setConfig } from '../../../config';
|
||||
|
||||
setConfig({
|
||||
securityLevel: 'strict',
|
||||
});
|
||||
|
||||
describe.each(['Boundary'])('parsing a C4 %s', function (macroName) {
|
||||
beforeEach(function () {
|
||||
c4.parser.yy = c4Db;
|
||||
c4.parser.yy.clear();
|
||||
});
|
||||
|
||||
it('should parse a C4 diagram with one Boundary correctly', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
title System Context diagram for Internet Banking System
|
||||
${macroName}(b1, "BankBoundary") {
|
||||
System(SystemAA, "Internet Banking System")
|
||||
}`);
|
||||
|
||||
const yy = c4.parser.yy;
|
||||
|
||||
const boundaries = yy.getBoundarys();
|
||||
expect(boundaries.length).toBe(2);
|
||||
const boundary = boundaries[1];
|
||||
|
||||
expect(boundary).toEqual({
|
||||
alias: 'b1',
|
||||
label: {
|
||||
text: 'BankBoundary',
|
||||
},
|
||||
// TODO: Why are link, and tags undefined instead of not appearing at all?
|
||||
// Compare to Person where they don't show up.
|
||||
link: undefined,
|
||||
tags: undefined,
|
||||
parentBoundary: 'global',
|
||||
type: {
|
||||
// TODO: Why is this `system` instead of `boundary`?
|
||||
text: 'system',
|
||||
},
|
||||
wrap: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse the alias', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
${macroName}(b1, "BankBoundary") {
|
||||
System(SystemAA, "Internet Banking System")
|
||||
}`);
|
||||
|
||||
expect(c4.parser.yy.getBoundarys()[1]).toMatchObject({
|
||||
alias: 'b1',
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse the label', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
${macroName}(b1, "BankBoundary") {
|
||||
System(SystemAA, "Internet Banking System")
|
||||
}`);
|
||||
|
||||
expect(c4.parser.yy.getBoundarys()[1]).toMatchObject({
|
||||
label: {
|
||||
text: 'BankBoundary',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse the type', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
${macroName}(b1, "", "company") {
|
||||
System(SystemAA, "Internet Banking System")
|
||||
}`);
|
||||
|
||||
expect(c4.parser.yy.getBoundarys()[1]).toMatchObject({
|
||||
type: { text: 'company' },
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse a link', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
${macroName}(b1, $link="https://github.com/mermaidjs") {
|
||||
System(SystemAA, "Internet Banking System")
|
||||
}`);
|
||||
|
||||
expect(c4.parser.yy.getBoundarys()[1]).toMatchObject({
|
||||
label: {
|
||||
text: {
|
||||
link: 'https://github.com/mermaidjs',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse tags', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
${macroName}(b1, $tags="tag1,tag2") {
|
||||
System(SystemAA, "Internet Banking System")
|
||||
}`);
|
||||
|
||||
expect(c4.parser.yy.getBoundarys()[1]).toMatchObject({
|
||||
label: {
|
||||
text: {
|
||||
tags: 'tag1,tag2',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -115,80 +115,80 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
|
||||
"C4Dynamic" return 'C4_DYNAMIC';
|
||||
"C4Deployment" return 'C4_DEPLOYMENT';
|
||||
|
||||
"Person_Ext" { this.begin("person_ext"); return 'PERSON_EXT';}
|
||||
"Person" { this.begin("person"); return 'PERSON';}
|
||||
"SystemQueue_Ext" { this.begin("system_ext_queue"); return 'SYSTEM_EXT_QUEUE';}
|
||||
"SystemDb_Ext" { this.begin("system_ext_db"); return 'SYSTEM_EXT_DB';}
|
||||
"System_Ext" { this.begin("system_ext"); return 'SYSTEM_EXT';}
|
||||
"SystemQueue" { this.begin("system_queue"); return 'SYSTEM_QUEUE';}
|
||||
"SystemDb" { this.begin("system_db"); return 'SYSTEM_DB';}
|
||||
"System" { this.begin("system"); return 'SYSTEM';}
|
||||
"Person_Ext" { this.begin("person_ext"); console.log('begin person_ext'); return 'PERSON_EXT';}
|
||||
"Person" { this.begin("person"); console.log('begin person'); return 'PERSON';}
|
||||
"SystemQueue_Ext" { this.begin("system_ext_queue"); console.log('begin system_ext_queue'); return 'SYSTEM_EXT_QUEUE';}
|
||||
"SystemDb_Ext" { this.begin("system_ext_db"); console.log('begin system_ext_db'); return 'SYSTEM_EXT_DB';}
|
||||
"System_Ext" { this.begin("system_ext"); console.log('begin system_ext'); return 'SYSTEM_EXT';}
|
||||
"SystemQueue" { this.begin("system_queue"); console.log('begin system_queue'); return 'SYSTEM_QUEUE';}
|
||||
"SystemDb" { this.begin("system_db"); console.log('begin system_db'); return 'SYSTEM_DB';}
|
||||
"System" { this.begin("system"); console.log('begin system'); return 'SYSTEM';}
|
||||
|
||||
"Boundary" { this.begin("boundary"); return 'BOUNDARY';}
|
||||
"Enterprise_Boundary" { this.begin("enterprise_boundary"); return 'ENTERPRISE_BOUNDARY';}
|
||||
"System_Boundary" { this.begin("system_boundary"); return 'SYSTEM_BOUNDARY';}
|
||||
"Boundary" { this.begin("boundary"); console.log('begin boundary'); return 'BOUNDARY';}
|
||||
"Enterprise_Boundary" { this.begin("enterprise_boundary"); console.log('begin enterprise_boundary'); return 'ENTERPRISE_BOUNDARY';}
|
||||
"System_Boundary" { this.begin("system_boundary"); console.log('begin system_boundary'); return 'SYSTEM_BOUNDARY';}
|
||||
|
||||
"ContainerQueue_Ext" { this.begin("container_ext_queue"); return 'CONTAINER_EXT_QUEUE';}
|
||||
"ContainerDb_Ext" { this.begin("container_ext_db"); return 'CONTAINER_EXT_DB';}
|
||||
"Container_Ext" { this.begin("container_ext"); return 'CONTAINER_EXT';}
|
||||
"ContainerQueue" { this.begin("container_queue"); return 'CONTAINER_QUEUE';}
|
||||
"ContainerDb" { this.begin("container_db"); return 'CONTAINER_DB';}
|
||||
"Container" { this.begin("container"); return 'CONTAINER';}
|
||||
"ContainerQueue_Ext" { this.begin("container_ext_queue"); console.log('begin container_ext_queue'); return 'CONTAINER_EXT_QUEUE';}
|
||||
"ContainerDb_Ext" { this.begin("container_ext_db"); console.log('begin container_ext_db'); return 'CONTAINER_EXT_DB';}
|
||||
"Container_Ext" { this.begin("container_ext"); console.log('begin container_ext'); return 'CONTAINER_EXT';}
|
||||
"ContainerQueue" { this.begin("container_queue"); console.log('begin container_queue'); return 'CONTAINER_QUEUE';}
|
||||
"ContainerDb" { this.begin("container_db"); console.log('begin container_db'); return 'CONTAINER_DB';}
|
||||
"Container" { this.begin("container"); console.log('begin container'); return 'CONTAINER';}
|
||||
|
||||
"Container_Boundary" { this.begin("container_boundary"); return 'CONTAINER_BOUNDARY';}
|
||||
"Container_Boundary" { this.begin("container_boundary"); console.log('begin container_boundary'); return 'CONTAINER_BOUNDARY';}
|
||||
|
||||
"ComponentQueue_Ext" { this.begin("component_ext_queue"); return 'COMPONENT_EXT_QUEUE';}
|
||||
"ComponentDb_Ext" { this.begin("component_ext_db"); return 'COMPONENT_EXT_DB';}
|
||||
"Component_Ext" { this.begin("component_ext"); return 'COMPONENT_EXT';}
|
||||
"ComponentQueue" { this.begin("component_queue"); return 'COMPONENT_QUEUE';}
|
||||
"ComponentDb" { this.begin("component_db"); return 'COMPONENT_DB';}
|
||||
"Component" { this.begin("component"); return 'COMPONENT';}
|
||||
"ComponentQueue_Ext" { this.begin("component_ext_queue"); console.log('begin component_ext_queue'); return 'COMPONENT_EXT_QUEUE';}
|
||||
"ComponentDb_Ext" { this.begin("component_ext_db"); console.log('begin component_ext_db'); return 'COMPONENT_EXT_DB';}
|
||||
"Component_Ext" { this.begin("component_ext"); console.log('begin component_ext'); return 'COMPONENT_EXT';}
|
||||
"ComponentQueue" { this.begin("component_queue"); console.log('begin component_queue'); return 'COMPONENT_QUEUE';}
|
||||
"ComponentDb" { this.begin("component_db"); console.log('begin component_db'); return 'COMPONENT_DB';}
|
||||
"Component" { this.begin("component"); console.log('begin component'); return 'COMPONENT';}
|
||||
|
||||
"Deployment_Node" { this.begin("node"); return 'NODE';}
|
||||
"Node" { this.begin("node"); return 'NODE';}
|
||||
"Node_L" { this.begin("node_l"); return 'NODE_L';}
|
||||
"Node_R" { this.begin("node_r"); return 'NODE_R';}
|
||||
"Deployment_Node" { this.begin("node"); console.log('begin node'); return 'NODE';}
|
||||
"Node" { this.begin("node"); console.log('begin node'); return 'NODE';}
|
||||
"Node_L" { this.begin("node_l"); console.log('begin node_l'); return 'NODE_L';}
|
||||
"Node_R" { this.begin("node_r"); console.log('begin node_r'); return 'NODE_R';}
|
||||
|
||||
|
||||
"Rel" { this.begin("rel"); return 'REL';}
|
||||
"BiRel" { this.begin("birel"); return 'BIREL';}
|
||||
"Rel_Up" { this.begin("rel_u"); return 'REL_U';}
|
||||
"Rel_U" { this.begin("rel_u"); return 'REL_U';}
|
||||
"Rel_Down" { this.begin("rel_d"); return 'REL_D';}
|
||||
"Rel_D" { this.begin("rel_d"); return 'REL_D';}
|
||||
"Rel_Left" { this.begin("rel_l"); return 'REL_L';}
|
||||
"Rel_L" { this.begin("rel_l"); return 'REL_L';}
|
||||
"Rel_Right" { this.begin("rel_r"); return 'REL_R';}
|
||||
"Rel_R" { this.begin("rel_r"); return 'REL_R';}
|
||||
"Rel_Back" { this.begin("rel_b"); return 'REL_B';}
|
||||
"RelIndex" { this.begin("rel_index"); return 'REL_INDEX';}
|
||||
"Rel" { this.begin("rel"); console.log('begin rel'); return 'REL';}
|
||||
"BiRel" { this.begin("birel"); console.log('begin birel'); return 'BIREL';}
|
||||
"Rel_Up" { this.begin("rel_u"); console.log('begin rel_u'); return 'REL_U';}
|
||||
"Rel_U" { this.begin("rel_u"); console.log('begin rel_u'); return 'REL_U';}
|
||||
"Rel_Down" { this.begin("rel_d"); console.log('begin rel_d'); return 'REL_D';}
|
||||
"Rel_D" { this.begin("rel_d"); console.log('begin rel_d'); return 'REL_D';}
|
||||
"Rel_Left" { this.begin("rel_l"); console.log('begin rel_l'); return 'REL_L';}
|
||||
"Rel_L" { this.begin("rel_l"); console.log('begin rel_l'); return 'REL_L';}
|
||||
"Rel_Right" { this.begin("rel_r"); console.log('begin rel_r'); return 'REL_R';}
|
||||
"Rel_R" { this.begin("rel_r"); console.log('begin rel_r'); return 'REL_R';}
|
||||
"Rel_Back" { this.begin("rel_b"); console.log('begin rel_b'); return 'REL_B';}
|
||||
"RelIndex" { this.begin("rel_index"); console.log('begin rel_index'); return 'REL_INDEX';}
|
||||
|
||||
"UpdateElementStyle" { this.begin("update_el_style"); return 'UPDATE_EL_STYLE';}
|
||||
"UpdateRelStyle" { this.begin("update_rel_style"); return 'UPDATE_REL_STYLE';}
|
||||
"UpdateLayoutConfig" { this.begin("update_layout_config"); return 'UPDATE_LAYOUT_CONFIG';}
|
||||
"UpdateElementStyle" { this.begin("update_el_style"); console.log('begin update_el_style'); return 'UPDATE_EL_STYLE';}
|
||||
"UpdateRelStyle" { this.begin("update_rel_style"); console.log('begin update_rel_style'); return 'UPDATE_REL_STYLE';}
|
||||
"UpdateLayoutConfig" { this.begin("update_layout_config"); console.log('begin update_layout_config'); return 'UPDATE_LAYOUT_CONFIG';}
|
||||
|
||||
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config><<EOF>> return "EOF_IN_STRUCT";
|
||||
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config>[(][ ]*[,] { this.begin("attribute"); return "ATTRIBUTE_EMPTY";}
|
||||
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config>[(] { this.begin("attribute"); }
|
||||
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config,attribute>[)] { this.popState();this.popState();}
|
||||
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config>[(][ ]*[,] { console.log('begin attribute with ATTRIBUTE_EMPTY'); this.begin("attribute"); return "ATTRIBUTE_EMPTY";}
|
||||
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config>[(] { console.log('begin attribute'); this.begin("attribute"); }
|
||||
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config,attribute>[)] { console.log('STOP attribute'); this.popState();console.log('STOP diagram'); this.popState();}
|
||||
|
||||
<attribute>",," { return 'ATTRIBUTE_EMPTY';}
|
||||
<attribute>"," { }
|
||||
<attribute>[ ]*["]["] { return 'ATTRIBUTE_EMPTY';}
|
||||
<attribute>[ ]*["] { this.begin("string");}
|
||||
<string>["] { this.popState(); }
|
||||
<string>[^"]* { return "STR";}
|
||||
<attribute>",," { console.log(',,'); return 'ATTRIBUTE_EMPTY';}
|
||||
<attribute>"," { console.log(','); }
|
||||
<attribute>[ ]*["]["] { console.log('ATTRIBUTE_EMPTY'); return 'ATTRIBUTE_EMPTY';}
|
||||
<attribute>[ ]*["] { console.log('begin string'); this.begin("string");}
|
||||
<string>["] { console.log('STOP string'); this.popState(); }
|
||||
<string>[^"]* { console.log('STR'); return "STR";}
|
||||
|
||||
<attribute>[ ]*[\$] { this.begin("string_kv");}
|
||||
<string_kv>[^=]* { this.begin("string_kv_key"); return "STR_KEY";}
|
||||
<string_kv_key>[=][ ]*["] { this.popState(); this.begin("string_kv_value"); }
|
||||
<string_kv_value>[^"]+ { return "STR_VALUE";}
|
||||
<string_kv_value>["] { this.popState(); this.popState(); }
|
||||
<attribute>[ ]*[\$] { console.log('begin string_kv'); this.begin("string_kv");}
|
||||
<string_kv>[^=]* { console.log('STR_KEY'); this.begin("string_kv_key"); return "STR_KEY";}
|
||||
<string_kv_key>[=][ ]*["] { console.log('begin string_kv_value'); this.popState(); this.begin("string_kv_value"); }
|
||||
<string_kv_value>[^"]+ { console.log('STR_VALUE'); return "STR_VALUE";}
|
||||
<string_kv_value>["] { console.log('STOP string_kv_value'); this.popState(); this.popState(); }
|
||||
|
||||
<attribute>[^,]+ { return "STR";}
|
||||
<attribute>[^,]+ { console.log('not STR'); return "STR";}
|
||||
|
||||
'{' { /* this.begin("lbrace"); */ return "LBRACE";}
|
||||
'}' { /* this.popState(); */ return "RBRACE";}
|
||||
'{' { /* this.begin("lbrace"); */ console.log('begin boundary block'); return "LBRACE";}
|
||||
'}' { /* this.popState(); */ console.log('STOP boundary block'); return "RBRACE";}
|
||||
|
||||
[\s]+ return 'SPACE';
|
||||
[\n\r]+ return 'EOL';
|
||||
@@ -231,7 +231,7 @@ directive
|
||||
;
|
||||
|
||||
openDirective
|
||||
: open_directive { yy.parseDirective('%%{', 'open_directive'); }
|
||||
: open_directive { console.log("open_directive: ", $1); yy.parseDirective('%%{', 'open_directive'); }
|
||||
;
|
||||
|
||||
typeDirective
|
||||
@@ -239,11 +239,11 @@ typeDirective
|
||||
;
|
||||
|
||||
argDirective
|
||||
: arg_directive { $1 = $1.trim().replace(/'/g, '"'); yy.parseDirective($1, 'arg_directive'); }
|
||||
: arg_directive { $1 = $1.trim().replace(/'/g, '"'); console.log("arg_directive: ", $1); yy.parseDirective($1, 'arg_directive'); }
|
||||
;
|
||||
|
||||
closeDirective
|
||||
: close_directive { yy.parseDirective('}%%', 'close_directive', 'c4Context'); }
|
||||
: close_directive { console.log("close_directive: ", $1); yy.parseDirective('}%%', 'close_directive', 'c4Context'); }
|
||||
;
|
||||
|
||||
graphConfig
|
||||
@@ -285,13 +285,13 @@ boundaryStartStatement
|
||||
;
|
||||
|
||||
boundaryStart
|
||||
: ENTERPRISE_BOUNDARY attributes {$2.splice(2, 0, 'ENTERPRISE'); yy.addPersonOrSystemBoundary(...$2); $$=$2;}
|
||||
| SYSTEM_BOUNDARY attributes {$2.splice(2, 0, 'ENTERPRISE'); yy.addPersonOrSystemBoundary(...$2); $$=$2;}
|
||||
| BOUNDARY attributes {yy.addPersonOrSystemBoundary(...$2); $$=$2;}
|
||||
| CONTAINER_BOUNDARY attributes {$2.splice(2, 0, 'CONTAINER'); yy.addContainerBoundary(...$2); $$=$2;}
|
||||
| NODE attributes {yy.addDeploymentNode('node', ...$2); $$=$2;}
|
||||
| NODE_L attributes {yy.addDeploymentNode('nodeL', ...$2); $$=$2;}
|
||||
| NODE_R attributes {yy.addDeploymentNode('nodeR', ...$2); $$=$2;}
|
||||
: ENTERPRISE_BOUNDARY attributes {console.log($1,JSON.stringify($2)); $2.splice(2, 0, 'ENTERPRISE'); yy.addPersonOrSystemBoundary(...$2); $$=$2;}
|
||||
| SYSTEM_BOUNDARY attributes {console.log($1,JSON.stringify($2)); $2.splice(2, 0, 'ENTERPRISE'); yy.addPersonOrSystemBoundary(...$2); $$=$2;}
|
||||
| BOUNDARY attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystemBoundary(...$2); $$=$2;}
|
||||
| CONTAINER_BOUNDARY attributes {console.log($1,JSON.stringify($2)); $2.splice(2, 0, 'CONTAINER'); yy.addContainerBoundary(...$2); $$=$2;}
|
||||
| NODE attributes {console.log($1,JSON.stringify($2)); yy.addDeploymentNode('node', ...$2); $$=$2;}
|
||||
| NODE_L attributes {console.log($1,JSON.stringify($2)); yy.addDeploymentNode('nodeL', ...$2); $$=$2;}
|
||||
| NODE_R attributes {console.log($1,JSON.stringify($2)); yy.addDeploymentNode('nodeR', ...$2); $$=$2;}
|
||||
;
|
||||
|
||||
boundaryStopStatement
|
||||
@@ -305,48 +305,48 @@ diagramStatements
|
||||
;
|
||||
|
||||
diagramStatement
|
||||
: PERSON attributes {yy.addPersonOrSystem('person', ...$2); $$=$2;}
|
||||
| PERSON_EXT attributes {yy.addPersonOrSystem('external_person', ...$2); $$=$2;}
|
||||
| SYSTEM attributes {yy.addPersonOrSystem('system', ...$2); $$=$2;}
|
||||
| SYSTEM_DB attributes {yy.addPersonOrSystem('system_db', ...$2); $$=$2;}
|
||||
| SYSTEM_QUEUE attributes {yy.addPersonOrSystem('system_queue', ...$2); $$=$2;}
|
||||
| SYSTEM_EXT attributes {yy.addPersonOrSystem('external_system', ...$2); $$=$2;}
|
||||
| SYSTEM_EXT_DB attributes {yy.addPersonOrSystem('external_system_db', ...$2); $$=$2;}
|
||||
| SYSTEM_EXT_QUEUE attributes {yy.addPersonOrSystem('external_system_queue', ...$2); $$=$2;}
|
||||
| CONTAINER attributes {yy.addContainer('container', ...$2); $$=$2;}
|
||||
| CONTAINER_DB attributes {yy.addContainer('container_db', ...$2); $$=$2;}
|
||||
| CONTAINER_QUEUE attributes {yy.addContainer('container_queue', ...$2); $$=$2;}
|
||||
| CONTAINER_EXT attributes {yy.addContainer('external_container', ...$2); $$=$2;}
|
||||
| CONTAINER_EXT_DB attributes {yy.addContainer('external_container_db', ...$2); $$=$2;}
|
||||
| CONTAINER_EXT_QUEUE attributes {yy.addContainer('external_container_queue', ...$2); $$=$2;}
|
||||
| COMPONENT attributes {yy.addComponent('component', ...$2); $$=$2;}
|
||||
| COMPONENT_DB attributes {yy.addComponent('component_db', ...$2); $$=$2;}
|
||||
| COMPONENT_QUEUE attributes {yy.addComponent('component_queue', ...$2); $$=$2;}
|
||||
| COMPONENT_EXT attributes {yy.addComponent('external_component', ...$2); $$=$2;}
|
||||
| COMPONENT_EXT_DB attributes {yy.addComponent('external_component_db', ...$2); $$=$2;}
|
||||
| COMPONENT_EXT_QUEUE attributes {yy.addComponent('external_component_queue', ...$2); $$=$2;}
|
||||
: PERSON attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('person', ...$2); $$=$2;}
|
||||
| PERSON_EXT attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('external_person', ...$2); $$=$2;}
|
||||
| SYSTEM attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('system', ...$2); $$=$2;}
|
||||
| SYSTEM_DB attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('system_db', ...$2); $$=$2;}
|
||||
| SYSTEM_QUEUE attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('system_queue', ...$2); $$=$2;}
|
||||
| SYSTEM_EXT attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('external_system', ...$2); $$=$2;}
|
||||
| SYSTEM_EXT_DB attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('external_system_db', ...$2); $$=$2;}
|
||||
| SYSTEM_EXT_QUEUE attributes {console.log($1,JSON.stringify($2)); yy.addPersonOrSystem('external_system_queue', ...$2); $$=$2;}
|
||||
| CONTAINER attributes {console.log($1,JSON.stringify($2)); yy.addContainer('container', ...$2); $$=$2;}
|
||||
| CONTAINER_DB attributes {console.log($1,JSON.stringify($2)); yy.addContainer('container_db', ...$2); $$=$2;}
|
||||
| CONTAINER_QUEUE attributes {console.log($1,JSON.stringify($2)); yy.addContainer('container_queue', ...$2); $$=$2;}
|
||||
| CONTAINER_EXT attributes {console.log($1,JSON.stringify($2)); yy.addContainer('external_container', ...$2); $$=$2;}
|
||||
| CONTAINER_EXT_DB attributes {console.log($1,JSON.stringify($2)); yy.addContainer('external_container_db', ...$2); $$=$2;}
|
||||
| CONTAINER_EXT_QUEUE attributes {console.log($1,JSON.stringify($2)); yy.addContainer('external_container_queue', ...$2); $$=$2;}
|
||||
| COMPONENT attributes {console.log($1,JSON.stringify($2)); yy.addComponent('component', ...$2); $$=$2;}
|
||||
| COMPONENT_DB attributes {console.log($1,JSON.stringify($2)); yy.addComponent('component_db', ...$2); $$=$2;}
|
||||
| COMPONENT_QUEUE attributes {console.log($1,JSON.stringify($2)); yy.addComponent('component_queue', ...$2); $$=$2;}
|
||||
| COMPONENT_EXT attributes {console.log($1,JSON.stringify($2)); yy.addComponent('external_component', ...$2); $$=$2;}
|
||||
| COMPONENT_EXT_DB attributes {console.log($1,JSON.stringify($2)); yy.addComponent('external_component_db', ...$2); $$=$2;}
|
||||
| COMPONENT_EXT_QUEUE attributes {console.log($1,JSON.stringify($2)); yy.addComponent('external_component_queue', ...$2); $$=$2;}
|
||||
| boundaryStatement
|
||||
| REL attributes {yy.addRel('rel', ...$2); $$=$2;}
|
||||
| BIREL attributes {yy.addRel('birel', ...$2); $$=$2;}
|
||||
| REL_U attributes {yy.addRel('rel_u', ...$2); $$=$2;}
|
||||
| REL_D attributes {yy.addRel('rel_d', ...$2); $$=$2;}
|
||||
| REL_L attributes {yy.addRel('rel_l', ...$2); $$=$2;}
|
||||
| REL_R attributes {yy.addRel('rel_r', ...$2); $$=$2;}
|
||||
| REL_B attributes {yy.addRel('rel_b', ...$2); $$=$2;}
|
||||
| REL_INDEX attributes {$2.splice(0, 1); yy.addRel('rel', ...$2); $$=$2;}
|
||||
| UPDATE_EL_STYLE attributes {yy.updateElStyle('update_el_style', ...$2); $$=$2;}
|
||||
| UPDATE_REL_STYLE attributes {yy.updateRelStyle('update_rel_style', ...$2); $$=$2;}
|
||||
| UPDATE_LAYOUT_CONFIG attributes {yy.updateLayoutConfig('update_layout_config', ...$2); $$=$2;}
|
||||
| REL attributes {console.log($1,JSON.stringify($2)); yy.addRel('rel', ...$2); $$=$2;}
|
||||
| BIREL attributes {console.log($1,JSON.stringify($2)); yy.addRel('birel', ...$2); $$=$2;}
|
||||
| REL_U attributes {console.log($1,JSON.stringify($2)); yy.addRel('rel_u', ...$2); $$=$2;}
|
||||
| REL_D attributes {console.log($1,JSON.stringify($2)); yy.addRel('rel_d', ...$2); $$=$2;}
|
||||
| REL_L attributes {console.log($1,JSON.stringify($2)); yy.addRel('rel_l', ...$2); $$=$2;}
|
||||
| REL_R attributes {console.log($1,JSON.stringify($2)); yy.addRel('rel_r', ...$2); $$=$2;}
|
||||
| REL_B attributes {console.log($1,JSON.stringify($2)); yy.addRel('rel_b', ...$2); $$=$2;}
|
||||
| REL_INDEX attributes {console.log($1,JSON.stringify($2)); $2.splice(0, 1); yy.addRel('rel', ...$2); $$=$2;}
|
||||
| UPDATE_EL_STYLE attributes {console.log($1,JSON.stringify($2)); yy.updateElStyle('update_el_style', ...$2); $$=$2;}
|
||||
| UPDATE_REL_STYLE attributes {console.log($1,JSON.stringify($2)); yy.updateRelStyle('update_rel_style', ...$2); $$=$2;}
|
||||
| UPDATE_LAYOUT_CONFIG attributes {console.log($1,JSON.stringify($2)); yy.updateLayoutConfig('update_layout_config', ...$2); $$=$2;}
|
||||
;
|
||||
|
||||
attributes
|
||||
: attribute { $$ = [$1]; }
|
||||
| attribute attributes { $2.unshift($1); $$=$2;}
|
||||
: attribute { console.log('PUSH ATTRIBUTE: ', $1); $$ = [$1]; }
|
||||
| attribute attributes { console.log('PUSH ATTRIBUTE: ', $1); $2.unshift($1); $$=$2;}
|
||||
;
|
||||
|
||||
attribute
|
||||
: STR { $$ = $1.trim(); }
|
||||
| STR_KEY STR_VALUE { let kv={}; kv[$1.trim()]=$2.trim(); $$=kv; }
|
||||
| STR_KEY STR_VALUE { console.log('kv: ', $1, $2); let kv={}; kv[$1.trim()]=$2.trim(); $$=kv; }
|
||||
| ATTRIBUTE { $$ = $1.trim(); }
|
||||
| ATTRIBUTE_EMPTY { $$ = ""; }
|
||||
;
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
import c4Db from '../c4Db';
|
||||
import c4 from './c4Diagram.jison';
|
||||
import { setConfig } from '../../../config';
|
||||
|
||||
setConfig({
|
||||
securityLevel: 'strict',
|
||||
});
|
||||
|
||||
describe('parsing a C4 Person', function () {
|
||||
beforeEach(function () {
|
||||
c4.parser.yy = c4Db;
|
||||
c4.parser.yy.clear();
|
||||
});
|
||||
|
||||
it('should parse a C4 diagram with one Person correctly', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
title System Context diagram for Internet Banking System
|
||||
Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")`);
|
||||
|
||||
const yy = c4.parser.yy;
|
||||
|
||||
const shapes = yy.getC4ShapeArray();
|
||||
expect(shapes.length).toBe(1);
|
||||
const onlyShape = shapes[0];
|
||||
|
||||
expect(onlyShape).toEqual({
|
||||
alias: 'customerA',
|
||||
descr: {
|
||||
text: 'A customer of the bank, with personal bank accounts.',
|
||||
},
|
||||
label: {
|
||||
text: 'Banking Customer A',
|
||||
},
|
||||
parentBoundary: 'global',
|
||||
typeC4Shape: {
|
||||
text: 'person',
|
||||
},
|
||||
wrap: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse the alias', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
Person(customerA, "Banking Customer A")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
alias: 'customerA',
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse the label', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
Person(customerA, "Banking Customer A")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
label: {
|
||||
text: 'Banking Customer A',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse the description', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
Person(customerA, "", "A customer of the bank, with personal bank accounts.")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
descr: {
|
||||
text: 'A customer of the bank, with personal bank accounts.',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse a sprite', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
Person(customerA, $sprite="users")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
label: {
|
||||
text: {
|
||||
sprite: 'users',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse a link', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
Person(customerA, $link="https://github.com/mermaidjs")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
label: {
|
||||
text: {
|
||||
link: 'https://github.com/mermaidjs',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse tags', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
Person(customerA, $tags="tag1,tag2")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
label: {
|
||||
text: {
|
||||
tags: 'tag1,tag2',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,116 +0,0 @@
|
||||
import c4Db from '../c4Db';
|
||||
import c4 from './c4Diagram.jison';
|
||||
import { setConfig } from '../../../config';
|
||||
|
||||
setConfig({
|
||||
securityLevel: 'strict',
|
||||
});
|
||||
|
||||
describe('parsing a C4 Person_Ext', function () {
|
||||
beforeEach(function () {
|
||||
c4.parser.yy = c4Db;
|
||||
c4.parser.yy.clear();
|
||||
});
|
||||
|
||||
it('should parse a C4 diagram with one Person_Ext correctly', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
title System Context diagram for Internet Banking System
|
||||
Person_Ext(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")`);
|
||||
|
||||
const yy = c4.parser.yy;
|
||||
|
||||
const shapes = yy.getC4ShapeArray();
|
||||
expect(shapes.length).toBe(1);
|
||||
const onlyShape = shapes[0];
|
||||
|
||||
expect(onlyShape).toEqual({
|
||||
alias: 'customerA',
|
||||
descr: {
|
||||
text: 'A customer of the bank, with personal bank accounts.',
|
||||
},
|
||||
label: {
|
||||
text: 'Banking Customer A',
|
||||
},
|
||||
// TODO: Why are link, sprite, and tags undefined instead of not appearing at all?
|
||||
// Compare to Person where they don't show up.
|
||||
link: undefined,
|
||||
sprite: undefined,
|
||||
tags: undefined,
|
||||
parentBoundary: 'global',
|
||||
typeC4Shape: {
|
||||
text: 'external_person',
|
||||
},
|
||||
wrap: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse the alias', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
Person_Ext(customerA, "Banking Customer A")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
alias: 'customerA',
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse the label', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
Person_Ext(customerA, "Banking Customer A")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
label: {
|
||||
text: 'Banking Customer A',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse the description', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
Person_Ext(customerA, "", "A customer of the bank, with personal bank accounts.")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
descr: {
|
||||
text: 'A customer of the bank, with personal bank accounts.',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse a sprite', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
Person_Ext(customerA, $sprite="users")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
label: {
|
||||
text: {
|
||||
sprite: 'users',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse a link', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
Person_Ext(customerA, $link="https://github.com/mermaidjs")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
label: {
|
||||
text: {
|
||||
link: 'https://github.com/mermaidjs',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse tags', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
Person_Ext(customerA, $tags="tag1,tag2")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
label: {
|
||||
text: {
|
||||
tags: 'tag1,tag2',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,123 +0,0 @@
|
||||
import c4Db from '../c4Db';
|
||||
import c4 from './c4Diagram.jison';
|
||||
import { setConfig } from '../../../config';
|
||||
|
||||
setConfig({
|
||||
securityLevel: 'strict',
|
||||
});
|
||||
|
||||
describe.each([
|
||||
['System', 'system'],
|
||||
['SystemDb', 'system_db'],
|
||||
['SystemQueue', 'system_queue'],
|
||||
['System_Ext', 'external_system'],
|
||||
['SystemDb_Ext', 'external_system_db'],
|
||||
['SystemQueue_Ext', 'external_system_queue'],
|
||||
])('parsing a C4 %s', function (macroName, elementName) {
|
||||
beforeEach(function () {
|
||||
c4.parser.yy = c4Db;
|
||||
c4.parser.yy.clear();
|
||||
});
|
||||
|
||||
it('should parse a C4 diagram with one System correctly', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
title System Context diagram for Internet Banking System
|
||||
${macroName}(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")`);
|
||||
|
||||
const yy = c4.parser.yy;
|
||||
|
||||
const shapes = yy.getC4ShapeArray();
|
||||
expect(shapes.length).toBe(1);
|
||||
const onlyShape = shapes[0];
|
||||
|
||||
expect(onlyShape).toEqual({
|
||||
alias: 'SystemAA',
|
||||
descr: {
|
||||
text: 'Allows customers to view information about their bank accounts, and make payments.',
|
||||
},
|
||||
label: {
|
||||
text: 'Internet Banking System',
|
||||
},
|
||||
// TODO: Why are link, sprite, and tags undefined instead of not appearing at all?
|
||||
// Compare to Person where they don't show up.
|
||||
link: undefined,
|
||||
sprite: undefined,
|
||||
tags: undefined,
|
||||
parentBoundary: 'global',
|
||||
typeC4Shape: {
|
||||
text: elementName,
|
||||
},
|
||||
wrap: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse the alias', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
${macroName}(SystemAA, "Internet Banking System")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
alias: 'SystemAA',
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse the label', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
${macroName}(SystemAA, "Internet Banking System")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
label: {
|
||||
text: 'Internet Banking System',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse the description', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
${macroName}(SystemAA, "", "Allows customers to view information about their bank accounts, and make payments.")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
descr: {
|
||||
text: 'Allows customers to view information about their bank accounts, and make payments.',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse a sprite', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
${macroName}(SystemAA, $sprite="users")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
label: {
|
||||
text: {
|
||||
sprite: 'users',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse a link', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
${macroName}(SystemAA, $link="https://github.com/mermaidjs")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
label: {
|
||||
text: {
|
||||
link: 'https://github.com/mermaidjs',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse tags', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
${macroName}(SystemAA, $tags="tag1,tag2")`);
|
||||
|
||||
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
|
||||
label: {
|
||||
text: {
|
||||
tags: 'tag1,tag2',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,20 +1,49 @@
|
||||
import c4Db from '../c4Db';
|
||||
import c4 from './c4Diagram.jison';
|
||||
import flowDb from '../c4Db';
|
||||
import flow from './c4Diagram.jison';
|
||||
import { setConfig } from '../../../config';
|
||||
|
||||
setConfig({
|
||||
securityLevel: 'strict',
|
||||
});
|
||||
|
||||
describe('parsing a C4 diagram', function () {
|
||||
describe('parsing a flow chart', function () {
|
||||
beforeEach(function () {
|
||||
c4.parser.yy = c4Db;
|
||||
c4.parser.yy.clear();
|
||||
flow.parser.yy = flowDb;
|
||||
flow.parser.yy.clear();
|
||||
});
|
||||
|
||||
it('should parse a C4 diagram with one Person correctly', function () {
|
||||
flow.parser.parse(`C4Context
|
||||
title System Context diagram for Internet Banking System
|
||||
Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")`);
|
||||
|
||||
const yy = flow.parser.yy;
|
||||
expect(yy.getC4Type()).toBe('C4Context');
|
||||
expect(yy.getTitle()).toBe('System Context diagram for Internet Banking System');
|
||||
|
||||
const shapes = yy.getC4ShapeArray();
|
||||
expect(shapes.length).toBe(1);
|
||||
const onlyShape = shapes[0];
|
||||
|
||||
expect(onlyShape).toEqual({
|
||||
alias: 'customerA',
|
||||
descr: {
|
||||
text: 'A customer of the bank, with personal bank accounts.',
|
||||
},
|
||||
label: {
|
||||
text: 'Banking Customer A',
|
||||
},
|
||||
parentBoundary: 'global',
|
||||
typeC4Shape: {
|
||||
text: 'person',
|
||||
},
|
||||
wrap: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle a trailing whitespaces after statements', function () {
|
||||
const whitespace = ' ';
|
||||
const rendered = c4.parser.parse(`C4Context${whitespace}
|
||||
const rendered = flow.parser.parse(`C4Context${whitespace}
|
||||
title System Context diagram for Internet Banking System${whitespace}
|
||||
Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")${whitespace}`);
|
||||
|
||||
@@ -22,11 +51,11 @@ Person(customerA, "Banking Customer A", "A customer of the bank, with personal b
|
||||
});
|
||||
|
||||
it('should handle parameter names that are keywords', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
flow.parser.parse(`C4Context
|
||||
title title
|
||||
Person(Person, "Person", "Person")`);
|
||||
|
||||
const yy = c4.parser.yy;
|
||||
const yy = flow.parser.yy;
|
||||
expect(yy.getTitle()).toBe('title');
|
||||
|
||||
const shapes = yy.getC4ShapeArray();
|
||||
@@ -39,10 +68,10 @@ Person(Person, "Person", "Person")`);
|
||||
});
|
||||
|
||||
it('should allow default in the parameters', function () {
|
||||
c4.parser.parse(`C4Context
|
||||
flow.parser.parse(`C4Context
|
||||
Person(default, "default", "default")`);
|
||||
|
||||
const yy = c4.parser.yy;
|
||||
const yy = flow.parser.yy;
|
||||
|
||||
const shapes = yy.getC4ShapeArray();
|
||||
expect(shapes.length).toBe(1);
|
||||
@@ -1,9 +0,0 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const classDetectorV2: DiagramDetector = (txt, config) => {
|
||||
// If we have confgured to use dagre-wrapper then we should return true in this function for classDiagram code thus making it use the new class diagram
|
||||
if (txt.match(/^\s*classDiagram/) !== null && config?.class?.defaultRenderer === 'dagre-wrapper')
|
||||
return true;
|
||||
// We have not opted to use the new renderer so we should return true if we detect a class diagram
|
||||
return txt.match(/^\s*classDiagram-v2/) !== null;
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const classDetector: DiagramDetector = (txt, config) => {
|
||||
// If we have confgured to use dagre-wrapper then we should never return true in this function
|
||||
if (config?.class?.defaultRenderer === 'dagre-wrapper') return false;
|
||||
// We have not opted to use the new renderer so we should return true if we detect a class diagram
|
||||
return txt.match(/^\s*classDiagram/) !== null;
|
||||
};
|
||||
@@ -1,4 +1,3 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const fs = require('fs');
|
||||
|
||||
import { LALRGenerator } from 'jison';
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const erDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*erDiagram/) !== null;
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const flowDetectorV2: DiagramDetector = (txt, config) => {
|
||||
// If we have confgured to use dagre-wrapper then we should return true in this function for graph code thus making it use the new flowchart diagram
|
||||
if (config?.flowchart?.defaultRenderer === 'dagre-wrapper' && txt.match(/^\s*graph/) !== null)
|
||||
return true;
|
||||
return txt.match(/^\s*flowchart/) !== null;
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const flowDetector: DiagramDetector = (txt, config) => {
|
||||
// If we have confired to only use new flow charts this function shohuld always return false
|
||||
// as in not signalling true for a legacy flowchart
|
||||
if (config?.flowchart?.defaultRenderer === 'dagre-wrapper') return false;
|
||||
return txt.match(/^\s*graph/) !== null;
|
||||
};
|
||||
@@ -1,154 +0,0 @@
|
||||
import flowDb from './flowDb';
|
||||
import flowParser from './parser/flow';
|
||||
import flowRenderer from './flowRenderer';
|
||||
import Diagram from '../../Diagram';
|
||||
import { addDiagrams } from '../../diagram-api/diagram-orchestration';
|
||||
addDiagrams();
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('when using mermaid and ', function () {
|
||||
describe('when calling addEdges ', function () {
|
||||
beforeEach(function () {
|
||||
flowParser.parser.yy = flowDb;
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-2');
|
||||
});
|
||||
it('should handle edges with text', function () {
|
||||
const diag = new Diagram('graph TD;A-->|text ex|B;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('normal');
|
||||
expect(options.label.match('text ex')).toBeTruthy();
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should handle edges without text', function () {
|
||||
const diag = new Diagram('graph TD;A-->B;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('normal');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should handle open-ended edges', function () {
|
||||
const diag = new Diagram('graph TD;A---B;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should handle edges with styles defined', function () {
|
||||
const diag = new Diagram('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
it('should handle edges with interpolation defined', function () {
|
||||
const diag = new Diagram('graph TD;A---B; linkStyle 0 interpolate basis');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.curve).toBe('basis'); // mocked as string
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
it('should handle edges with text and styles defined', function () {
|
||||
const diag = new Diagram(
|
||||
'graph TD;A---|the text|B; linkStyle 0 stroke:val1,stroke-width:val2;'
|
||||
);
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.label.match('the text')).toBeTruthy();
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should set fill to "none" by default when handling edges', function () {
|
||||
const diag = new Diagram('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should not set fill to none if fill is set in linkStyle', function () {
|
||||
const diag = new Diagram(
|
||||
'graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2,fill:blue;'
|
||||
);
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:blue;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,5 +0,0 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const ganttDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*gantt/) !== null;
|
||||
};
|
||||
@@ -363,34 +363,6 @@ describe('when parsing a gitGraph', function () {
|
||||
expect(Object.keys(parser.yy.getBranches()).length).toBe(2);
|
||||
});
|
||||
|
||||
it('should allow branch names starting with unusual prefixes', function () {
|
||||
const str = `gitGraph:
|
||||
commit
|
||||
%% branch names starting with numbers are not recommended, but are supported by git
|
||||
branch branch01
|
||||
branch checkout02
|
||||
branch cherry-pick03
|
||||
branch branch/example-branch
|
||||
branch merge/test_merge
|
||||
`;
|
||||
|
||||
parser.parse(str);
|
||||
const commits = parser.yy.getCommits();
|
||||
expect(Object.keys(commits).length).toBe(1);
|
||||
expect(parser.yy.getCurrentBranch()).toBe('merge/test_merge');
|
||||
expect(parser.yy.getDirection()).toBe('LR');
|
||||
expect(Object.keys(parser.yy.getBranches()).length).toBe(6);
|
||||
expect(Object.keys(parser.yy.getBranches())).toEqual(
|
||||
expect.arrayContaining([
|
||||
'branch01',
|
||||
'checkout02',
|
||||
'cherry-pick03',
|
||||
'branch/example-branch',
|
||||
'merge/test_merge',
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle new branch checkout', function () {
|
||||
const str = `gitGraph:
|
||||
commit
|
||||
@@ -578,6 +550,8 @@ describe('when parsing a gitGraph', function () {
|
||||
testBranch3Merge,
|
||||
] = Object.values(commits);
|
||||
|
||||
console.log(Object.keys(commits));
|
||||
|
||||
expect(mainCommit.branch).toBe('main');
|
||||
expect(mainCommit.parents).toStrictEqual([]);
|
||||
|
||||
|
||||
@@ -173,9 +173,7 @@ export const getCommits = () => {
|
||||
},
|
||||
};
|
||||
};
|
||||
export const clear = () => {
|
||||
//no-op
|
||||
};
|
||||
export const clear = () => {};
|
||||
export const getBranchesAsObjArray = () => [
|
||||
{
|
||||
name: 'master',
|
||||
|
||||
@@ -36,7 +36,7 @@ accDescr\s*"{"\s* { this.begin("ac
|
||||
\#[^\n]* /* skip comments */
|
||||
\%%[^\n]* /* skip comments */
|
||||
"gitGraph" return 'GG';
|
||||
commit(?=\s|$) return 'COMMIT';
|
||||
"commit" return 'COMMIT';
|
||||
"id:" return 'COMMIT_ID';
|
||||
"type:" return 'COMMIT_TYPE';
|
||||
"msg:" return 'COMMIT_MSG';
|
||||
@@ -44,12 +44,12 @@ commit(?=\s|$) return 'COMMIT';
|
||||
"REVERSE" return 'REVERSE';
|
||||
"HIGHLIGHT" return 'HIGHLIGHT';
|
||||
"tag:" return 'COMMIT_TAG';
|
||||
branch(?=\s|$) return 'BRANCH';
|
||||
"branch" return 'BRANCH';
|
||||
"order:" return 'ORDER';
|
||||
merge(?=\s|$) return 'MERGE';
|
||||
cherry-pick(?=\s|$) return 'CHERRY_PICK';
|
||||
"merge" return 'MERGE';
|
||||
"cherry-pick" return 'CHERRY_PICK';
|
||||
// "reset" return 'RESET';
|
||||
checkout(?=\s|$) return 'CHECKOUT';
|
||||
"checkout" return 'CHECKOUT';
|
||||
"LR" return 'DIR';
|
||||
"BT" return 'DIR';
|
||||
":" return ':';
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import { parser } from './parser/info';
|
||||
import infoDb from './infoDb';
|
||||
describe('when parsing an info graph it', function () {
|
||||
let ex;
|
||||
var ex;
|
||||
beforeEach(function () {
|
||||
ex = parser;
|
||||
ex.yy = infoDb;
|
||||
ex = require('./parser/info').parser;
|
||||
ex.yy = require('./infoDb');
|
||||
});
|
||||
|
||||
it('should handle an info definition', function () {
|
||||
let str = `info
|
||||
var str = `info
|
||||
showInfo`;
|
||||
|
||||
ex.parse(str);
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const infoDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*info/) !== null;
|
||||
};
|
||||
@@ -49,6 +49,7 @@ export const draw = (text, id, version, diagObj) => {
|
||||
svg.attr('width', 400);
|
||||
// svg.attr('viewBox', '0 0 300 150');
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
log.error('Error while rendering info diagram');
|
||||
log.error(e.message);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { parser as mindmap } from './parser/mindmap';
|
||||
import * as mindmapDB from './mindmapDb';
|
||||
import { setLogLevel } from '../../diagram-api/diagramAPI';
|
||||
import { setLogLevel } from '../../logger';
|
||||
|
||||
describe('when parsing a mindmap ', function () {
|
||||
let mindmap;
|
||||
beforeEach(function () {
|
||||
mindmap.yy = mindmapDB;
|
||||
mindmap = require('./parser/mindmap').parser;
|
||||
mindmap.yy = require('./mindmapDb');
|
||||
mindmap.yy.clear();
|
||||
setLogLevel('trace');
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/** Created by knut on 15-01-14. */
|
||||
import { sanitizeText, getConfig, log as _log } from '../../diagram-api/diagramAPI';
|
||||
import { sanitizeText, getConfig } from '../../diagram-api/diagramAPI';
|
||||
import { log as _log } from '../../logger';
|
||||
|
||||
let nodes = [];
|
||||
let cnt = 0;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
const lineBreakRegex = /<br\s*\/?>/gi;
|
||||
import { select } from 'd3';
|
||||
import * as db from './mindmapDb';
|
||||
|
||||
@@ -14,6 +15,7 @@ function wrap(text, width) {
|
||||
.reverse(),
|
||||
word,
|
||||
line = [],
|
||||
lineNumber = 0,
|
||||
lineHeight = 1.1, // ems
|
||||
y = text.attr('y'),
|
||||
dy = parseFloat(text.attr('dy')),
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const pieDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*pie/) !== null;
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const requirementDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*requirement(Diagram)?/) !== null;
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const sequenceDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*sequenceDiagram/) !== null;
|
||||
};
|
||||
@@ -1,8 +1,12 @@
|
||||
// import sequence from './parser/sequenceDiagram';
|
||||
// import sequenceDb from './sequenceDb';
|
||||
import * as configApi from '../../config';
|
||||
// import renderer from './sequenceRenderer';
|
||||
import mermaidAPI from '../../mermaidAPI';
|
||||
// import '../../diagram-api/diagramAPI';
|
||||
import Diagram from '../../Diagram';
|
||||
import { addDiagrams } from '../../diagram-api/diagram-orchestration';
|
||||
addDiagrams();
|
||||
|
||||
// console.log('sequenceDiagram', sequenceDb);
|
||||
/**
|
||||
* @param conf
|
||||
* @param key
|
||||
|
||||
@@ -96,7 +96,6 @@ export const bounds = {
|
||||
}
|
||||
},
|
||||
updateBounds: function (startx, starty, stopx, stopy) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
const _self = this;
|
||||
let cnt = 0;
|
||||
/** @param {any} type */
|
||||
@@ -654,7 +653,7 @@ export const draw = function (_text, id, _version, diagObj) {
|
||||
// Draw the messages/signals
|
||||
let sequenceIndex = 1;
|
||||
let sequenceIndexStep = 1;
|
||||
let messagesToDraw = [];
|
||||
let messagesToDraw = Array();
|
||||
messages.forEach(function (msg) {
|
||||
let loopModel, noteModel, msgModel;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import svgDraw from './svgDraw';
|
||||
import { MockD3 } from 'd3';
|
||||
const svgDraw = require('./svgDraw').default;
|
||||
const { MockD3 } = require('d3');
|
||||
|
||||
describe('svgDraw', function () {
|
||||
describe('drawRect', function () {
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const stateDetectorV2: DiagramDetector = (text, config) => {
|
||||
if (text.match(/^\s*stateDiagram-v2/) !== null) return true;
|
||||
if (text.match(/^\s*stateDiagram/) && config?.state?.defaultRenderer === 'dagre-wrapper')
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const stateDetector: DiagramDetector = (txt, config) => {
|
||||
// If we have confired to only use new state diagrams this function should always return false
|
||||
// as in not signalling true for a legacy state diagram
|
||||
if (config?.state?.defaultRenderer === 'dagre-wrapper') return false;
|
||||
return txt.match(/^\s*stateDiagram/) !== null;
|
||||
};
|
||||
@@ -13,9 +13,7 @@ let conf;
|
||||
|
||||
const transformationLog = {};
|
||||
|
||||
export const setConf = function () {
|
||||
//no-op
|
||||
};
|
||||
export const setConf = function () {};
|
||||
|
||||
/**
|
||||
* Setup arrow head and define the marker. The result is appended to the svg.
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||
|
||||
export const journeyDetector: DiagramDetector = (txt) => {
|
||||
return txt.match(/^\s*journey/) !== null;
|
||||
};
|
||||
@@ -151,7 +151,6 @@ export const bounds = {
|
||||
},
|
||||
updateBounds: function (startx, starty, stopx, stopy) {
|
||||
const conf = getConfig().journey;
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
const _self = this;
|
||||
let cnt = 0;
|
||||
/** @param {any} type */
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import { remark } from 'remark';
|
||||
import type { Code, Root } from 'mdast';
|
||||
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
|
||||
// @ts-ignore: no typings
|
||||
// @ts-ignore
|
||||
import flatmap from 'unist-util-flatmap';
|
||||
import { globby } from 'globby';
|
||||
import { join, dirname } from 'path';
|
||||
|
||||
@@ -1405,15 +1405,6 @@ This sets the auto-wrap padding for the diagram (sides only)
|
||||
|
||||
**Notes:** Default value: 0.
|
||||
|
||||
## parse
|
||||
|
||||
### Parameters
|
||||
|
||||
- `text` **[string][5]**
|
||||
- `parseError` **[Function][6]?**
|
||||
|
||||
Returns **[boolean][7]**
|
||||
|
||||
## setSiteConfig
|
||||
|
||||
## setSiteConfig
|
||||
@@ -1431,7 +1422,7 @@ function _Default value: At default, will mirror Global Config_
|
||||
|
||||
- `conf` **MermaidConfig** The base currentConfig to use as siteConfig
|
||||
|
||||
Returns **[object][8]** The siteConfig
|
||||
Returns **[object][5]** The siteConfig
|
||||
|
||||
## getSiteConfig
|
||||
|
||||
@@ -1443,7 +1434,7 @@ Returns **[object][8]** The siteConfig
|
||||
|
||||
**Notes**: Returns **any** values in siteConfig.
|
||||
|
||||
Returns **[object][8]** The siteConfig
|
||||
Returns **[object][5]** The siteConfig
|
||||
|
||||
## setConfig
|
||||
|
||||
@@ -1482,10 +1473,10 @@ $(function () {
|
||||
|
||||
### Parameters
|
||||
|
||||
- `id` **[string][5]** The id of the element to be rendered
|
||||
- `text` **[string][5]** The graph definition
|
||||
- `cb` **function (svgCode: [string][5], bindFunctions: function (element: [Element][9]): void): void**
|
||||
- `container` **[Element][9]** Selector to element in which a div with the graph temporarily will be
|
||||
- `id` **[string][6]** The id of the element to be rendered
|
||||
- `text` **[string][6]** The graph definition
|
||||
- `cb` **function (svgCode: [string][6], bindFunctions: function (element: [Element][7]): void): void**
|
||||
- `container` **[Element][7]** Selector to element in which a div with the graph temporarily will be
|
||||
inserted. If one is provided a hidden div will be inserted in the body of the page instead. The
|
||||
element will be removed when rendering is completed.
|
||||
|
||||
@@ -1524,7 +1515,7 @@ Pushes in a directive to the configuration
|
||||
|
||||
### Parameters
|
||||
|
||||
- `directive` **[object][8]** The directive to push in
|
||||
- `directive` **[object][5]** The directive to push in
|
||||
|
||||
## reset
|
||||
|
||||
@@ -1622,8 +1613,6 @@ Returns **void**
|
||||
[2]: Setup.md?id=render
|
||||
[3]: 8.6.0_docs.md
|
||||
[4]: #mermaidapi-configuration-defaults
|
||||
[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
|
||||
[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function
|
||||
[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
|
||||
[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
|
||||
[9]: https://developer.mozilla.org/docs/Web/API/Element
|
||||
[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
|
||||
[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
|
||||
[7]: https://developer.mozilla.org/docs/Web/API/Element
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Mindmap
|
||||
|
||||
**Edit this Page** [](https://github.com/mermaid-js/mermaid/blob/develop/src/docs/mindmap.md)
|
||||
|
||||
> Mindmap: This is an experimental diagram for now. The syntax and properties can change in future releases. The syntax is stabel except for the icon integration which is the experimental part.
|
||||
|
||||
"A mind map is a diagram used to visually organize information into a hierarchy, showing relationships among pieces of the whole. It is often created around a single concept, drawn as an image in the center of a blank page, to which associated representations of ideas such as images, words and parts of words are added. Major ideas are connected directly to the central concept, and other ideas branch out from those major ideas." Wikipedia
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
let interactionFunctions: (() => void)[] = [];
|
||||
export const addFunction = (func: () => void) => {
|
||||
let interactionFunctions: (() => {})[] = [];
|
||||
export const addFunction = (func: () => {}) => {
|
||||
interactionFunctions.push(func);
|
||||
};
|
||||
export const attachFunctions = () => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { Generator } = require('jison');
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||
/* eslint-disable no-console */
|
||||
import moment from 'moment-mini';
|
||||
|
||||
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
|
||||
|
||||
@@ -2,6 +2,8 @@ import mermaid from './mermaid';
|
||||
import { mermaidAPI } from './mermaidAPI';
|
||||
import flowDb from './diagrams/flowchart/flowDb';
|
||||
import flowParser from './diagrams/flowchart/parser/flow';
|
||||
import flowRenderer from './diagrams/flowchart/flowRenderer';
|
||||
import Diagram from './Diagram';
|
||||
|
||||
const spyOn = jest.spyOn;
|
||||
|
||||
@@ -56,6 +58,149 @@ describe('when using mermaid and ', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when calling addEdges ', function () {
|
||||
beforeEach(function () {
|
||||
flowParser.parser.yy = flowDb;
|
||||
flowDb.clear();
|
||||
flowDb.setGen('gen-2');
|
||||
});
|
||||
it('should handle edges with text', function () {
|
||||
const diag = new Diagram('graph TD;A-->|text ex|B;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('normal');
|
||||
expect(options.label.match('text ex')).toBeTruthy();
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should handle edges without text', function () {
|
||||
const diag = new Diagram('graph TD;A-->B;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('normal');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should handle open-ended edges', function () {
|
||||
const diag = new Diagram('graph TD;A---B;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should handle edges with styles defined', function () {
|
||||
const diag = new Diagram('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
it('should handle edges with interpolation defined', function () {
|
||||
const diag = new Diagram('graph TD;A---B; linkStyle 0 interpolate basis');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.curve).toBe('basis'); // mocked as string
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
it('should handle edges with text and styles defined', function () {
|
||||
const diag = new Diagram(
|
||||
'graph TD;A---|the text|B; linkStyle 0 stroke:val1,stroke-width:val2;'
|
||||
);
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.label.match('the text')).toBeTruthy();
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should set fill to "none" by default when handling edges', function () {
|
||||
const diag = new Diagram('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;');
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
|
||||
it('should not set fill to none if fill is set in linkStyle', function () {
|
||||
const diag = new Diagram(
|
||||
'graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2,fill:blue;'
|
||||
);
|
||||
diag.db.getVertices();
|
||||
const edges = diag.db.getEdges();
|
||||
const mockG = {
|
||||
setEdge: function (start, end, options) {
|
||||
expect(start).toContain('flowchart-A-');
|
||||
expect(end).toContain('flowchart-B-');
|
||||
expect(options.arrowhead).toBe('none');
|
||||
expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:blue;');
|
||||
},
|
||||
};
|
||||
|
||||
flowRenderer.addEdges(edges, mockG, diag);
|
||||
});
|
||||
});
|
||||
|
||||
describe('checking validity of input ', function () {
|
||||
beforeEach(function () {
|
||||
flowParser.parser.yy = flowDb;
|
||||
|
||||
@@ -14,8 +14,7 @@ import { isDetailedError } from './utils';
|
||||
* Function that goes through the document to find the chart definitions in there and render them.
|
||||
*
|
||||
* The function tags the processed attributes with the attribute data-processed and ignores found
|
||||
* elements with the attribute already set. This way the init function can be triggered several
|
||||
* times.
|
||||
* elements with the attribute already set. This way the init function can be triggered several times.
|
||||
*
|
||||
* Optionally, `init` can accept in the second argument one of the following:
|
||||
*
|
||||
@@ -40,7 +39,6 @@ const init = function (
|
||||
config?: MermaidConfig,
|
||||
// eslint-disable-next-line no-undef
|
||||
nodes?: string | HTMLElement | NodeListOf<HTMLElement>,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
callback?: Function
|
||||
) {
|
||||
try {
|
||||
@@ -60,14 +58,13 @@ const initThrowsErrors = function (
|
||||
config?: MermaidConfig,
|
||||
// eslint-disable-next-line no-undef
|
||||
nodes?: string | HTMLElement | NodeListOf<HTMLElement>,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
callback?: Function
|
||||
) {
|
||||
const conf = mermaidAPI.getConfig();
|
||||
// console.log('Starting rendering diagrams (init) - mermaid.init', conf);
|
||||
if (config) {
|
||||
// This is a legacy way of setting config. It is not documented and should be removed in the future.
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
// @ts-ignore
|
||||
mermaid.sequenceConfig = config;
|
||||
}
|
||||
|
||||
@@ -134,7 +131,7 @@ const initThrowsErrors = function (
|
||||
);
|
||||
} catch (error) {
|
||||
log.warn('Catching Error (bootstrap)', error);
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
// @ts-ignore
|
||||
// TODO: We should be throwing an error object.
|
||||
throw { error, message: error.str };
|
||||
}
|
||||
@@ -147,8 +144,7 @@ const initialize = function (config: MermaidConfig) {
|
||||
|
||||
/**
|
||||
* ##contentLoaded Callback function that is called when page is loaded. This functions fetches
|
||||
* configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the
|
||||
* page.
|
||||
* configuration for mermaid rendering and calls init for rendering the mermaid diagrams on the page.
|
||||
*/
|
||||
const contentLoaded = function () {
|
||||
if (mermaid.startOnLoad) {
|
||||
@@ -191,7 +187,6 @@ const parse = (txt: string) => {
|
||||
const mermaid: {
|
||||
startOnLoad: boolean;
|
||||
diagrams: any;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
parseError?: Function;
|
||||
mermaidAPI: typeof mermaidAPI;
|
||||
parse: typeof parse;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
import { select } from 'd3';
|
||||
import { compile, serialize, stringify } from 'stylis';
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
// @ts-ignore
|
||||
import pkg from '../package.json';
|
||||
import * as configApi from './config';
|
||||
import { addDiagrams } from './diagram-api/diagram-orchestration';
|
||||
@@ -38,11 +38,6 @@ import { evaluate } from './diagrams/common/common';
|
||||
|
||||
let hasLoadedDiagrams = false;
|
||||
|
||||
/**
|
||||
* @param text
|
||||
* @param parseError
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
function parse(text: string, parseError?: Function): boolean {
|
||||
if (!hasLoadedDiagrams) {
|
||||
addDiagrams();
|
||||
@@ -131,7 +126,7 @@ const render = function (
|
||||
directiveSanitizer(graphInit);
|
||||
configApi.addDirective(graphInit);
|
||||
}
|
||||
const cnf = configApi.getConfig();
|
||||
let cnf = configApi.getConfig();
|
||||
|
||||
log.debug(cnf);
|
||||
|
||||
@@ -324,8 +319,8 @@ const render = function (
|
||||
svgCode = svgCode.replace(/<br>/g, '<br/>');
|
||||
|
||||
if (cnf.securityLevel === 'sandbox') {
|
||||
const svgEl = root.select('#d' + id + ' svg').node();
|
||||
const width = '100%';
|
||||
let svgEl = root.select('#d' + id + ' svg').node();
|
||||
let width = '100%';
|
||||
let height = '100%';
|
||||
if (svgEl) {
|
||||
height = svgEl.viewBox.baseVal.height + 'px';
|
||||
@@ -402,7 +397,7 @@ const parseDirective = function (p: any, statement: string, context: string, typ
|
||||
log.error(
|
||||
`Error while rendering sequenceDiagram directive: ${statement} jison context: ${context}`
|
||||
);
|
||||
// @ts-ignore: TODO Fix ts errors
|
||||
// @ts-ignore
|
||||
log.error(error.message);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ import { FlowChartStyleOptions } from './diagrams/flowchart/styles';
|
||||
import { log } from './logger';
|
||||
|
||||
// TODO @knut: Inject from registerDiagram.
|
||||
const themes: Record<string, any> = {
|
||||
const themes = {
|
||||
flowchart,
|
||||
'flowchart-v2': flowchart,
|
||||
sequence,
|
||||
@@ -45,7 +45,7 @@ const getStyles = (
|
||||
lineColor: string;
|
||||
} & FlowChartStyleOptions
|
||||
) => {
|
||||
let diagramStyles = '';
|
||||
let diagramStyles: string = '';
|
||||
if (type in themes && themes[type as keyof typeof themes]) {
|
||||
diagramStyles = themes[type as keyof typeof themes](options);
|
||||
} else {
|
||||
@@ -103,7 +103,8 @@ const getStyles = (
|
||||
`;
|
||||
};
|
||||
|
||||
export const addStylesForDiagram = (type: string, diagramTheme: unknown): void => {
|
||||
export const addStylesForDiagram = (type: string, diagramTheme: any) => {
|
||||
// @ts-ignore
|
||||
themes[type] = diagramTheme;
|
||||
};
|
||||
|
||||
|
||||
96
src/utils.ts
96
src/utils.ts
@@ -1,4 +1,4 @@
|
||||
// @ts-nocheck : TODO Fix ts errors
|
||||
// @ts-nocheck
|
||||
import { sanitizeUrl } from '@braintree/sanitize-url';
|
||||
import {
|
||||
curveBasis,
|
||||
@@ -43,20 +43,18 @@ const anyComment = /\s*%%.*\n/gm;
|
||||
|
||||
/**
|
||||
* @function detectInit Detects the init config object from the text
|
||||
* @param config
|
||||
* @param config
|
||||
*
|
||||
* @param config
|
||||
* ```mermaid
|
||||
*
|
||||
* %%{init: {"theme": "debug", "logLevel": 1 }}%%
|
||||
* graph LR
|
||||
* a-->b
|
||||
* b-->c
|
||||
* c-->d
|
||||
* d-->e
|
||||
* e-->f
|
||||
* f-->g
|
||||
* g-->h
|
||||
* a-->b
|
||||
* b-->c
|
||||
* c-->d
|
||||
* d-->e
|
||||
* e-->f
|
||||
* f-->g
|
||||
* g-->h
|
||||
* ```
|
||||
*
|
||||
* Or
|
||||
@@ -77,11 +75,11 @@ const anyComment = /\s*%%.*\n/gm;
|
||||
* @returns {object} The json object representing the init passed to mermaid.initialize()
|
||||
*/
|
||||
export const detectInit = function (text: string, config?: MermaidConfig): MermaidConfig {
|
||||
const inits = detectDirective(text, /(?:init\b)|(?:initialize\b)/);
|
||||
let inits = detectDirective(text, /(?:init\b)|(?:initialize\b)/);
|
||||
let results = {};
|
||||
|
||||
if (Array.isArray(inits)) {
|
||||
const args = inits.map((init) => init.args);
|
||||
let args = inits.map((init) => init.args);
|
||||
directiveSanitizer(args);
|
||||
|
||||
results = assignWithDepth(results, [...args]);
|
||||
@@ -136,8 +134,8 @@ export const detectDirective = function (text, type = null) {
|
||||
log.debug(
|
||||
`Detecting diagram directive${type !== null ? ' type:' + type : ''} based on the text:${text}`
|
||||
);
|
||||
let match;
|
||||
const result = [];
|
||||
let match,
|
||||
result = [];
|
||||
while ((match = directive.exec(text)) !== null) {
|
||||
// This is necessary to avoid infinite loops with zero-width matches
|
||||
if (match.index === directive.lastIndex) {
|
||||
@@ -148,8 +146,8 @@ export const detectDirective = function (text, type = null) {
|
||||
(type && match[1] && match[1].match(type)) ||
|
||||
(type && match[2] && match[2].match(type))
|
||||
) {
|
||||
const type = match[1] ? match[1] : match[2];
|
||||
const args = match[3] ? match[3].trim() : match[4] ? JSON.parse(match[4].trim()) : null;
|
||||
let type = match[1] ? match[1] : match[2];
|
||||
let args = match[3] ? match[3].trim() : match[4] ? JSON.parse(match[4].trim()) : null;
|
||||
result.push({ type, args });
|
||||
}
|
||||
}
|
||||
@@ -175,13 +173,13 @@ export const detectDirective = function (text, type = null) {
|
||||
* @returns {Function} An optimized caching function
|
||||
*/
|
||||
const memoize = (fn, resolver) => {
|
||||
const cache = {};
|
||||
let cache = {};
|
||||
return (...args) => {
|
||||
const n = resolver ? resolver.apply(this, args) : args[0];
|
||||
let n = resolver ? resolver.apply(this, args) : args[0];
|
||||
if (n in cache) {
|
||||
return cache[n];
|
||||
} else {
|
||||
const result = fn(...args);
|
||||
let result = fn(...args);
|
||||
cache[n] = result;
|
||||
return result;
|
||||
}
|
||||
@@ -224,7 +222,7 @@ export const interpolateToCurve = (interpolate, defaultCurve) => {
|
||||
* @returns {string | undefined} The formatted URL
|
||||
*/
|
||||
export const formatUrl = (linkStr, config) => {
|
||||
const url = linkStr.trim();
|
||||
let url = linkStr.trim();
|
||||
|
||||
if (url) {
|
||||
if (config.securityLevel !== 'loose') {
|
||||
@@ -367,10 +365,10 @@ const calcCardinalityPosition = (isRelationTypePresent, points, initialPosition)
|
||||
prevPoint = point;
|
||||
});
|
||||
// if relation is present (Arrows will be added), change cardinality point off-set distance (d)
|
||||
const d = isRelationTypePresent ? 10 : 5;
|
||||
let d = isRelationTypePresent ? 10 : 5;
|
||||
//Calculate Angle for x and y axis
|
||||
const angle = Math.atan2(points[0].y - center.y, points[0].x - center.x);
|
||||
const cardinalityPosition = { x: 0, y: 0 };
|
||||
let angle = Math.atan2(points[0].y - center.y, points[0].x - center.x);
|
||||
let cardinalityPosition = { x: 0, y: 0 };
|
||||
//Calculation cardinality position using angle, center point on the line/curve but pendicular and with offset-distance
|
||||
cardinalityPosition.x = Math.sin(angle) * d + (points[0].x + center.x) / 2;
|
||||
cardinalityPosition.y = -Math.cos(angle) * d + (points[0].y + center.y) / 2;
|
||||
@@ -428,11 +426,11 @@ const calcTerminalLabelPosition = (terminalMarkerSize, position, _points) => {
|
||||
prevPoint = point;
|
||||
});
|
||||
// if relation is present (Arrows will be added), change cardinality point off-set distance (d)
|
||||
const d = 10 + terminalMarkerSize * 0.5;
|
||||
let d = 10 + terminalMarkerSize * 0.5;
|
||||
//Calculate Angle for x and y axis
|
||||
const angle = Math.atan2(points[0].y - center.y, points[0].x - center.x);
|
||||
let angle = Math.atan2(points[0].y - center.y, points[0].x - center.x);
|
||||
|
||||
const cardinalityPosition = { x: 0, y: 0 };
|
||||
let cardinalityPosition = { x: 0, y: 0 };
|
||||
|
||||
//Calculation cardinality position using angle, center point on the line/curve but pendicular and with offset-distance
|
||||
|
||||
@@ -488,10 +486,10 @@ export const generateId = () => {
|
||||
* @returns {any}
|
||||
*/
|
||||
function makeid(length) {
|
||||
let result = '';
|
||||
const characters = '0123456789abcdef';
|
||||
const charactersLength = characters.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
var result = '';
|
||||
var characters = '0123456789abcdef';
|
||||
var charactersLength = characters.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
return result;
|
||||
@@ -634,8 +632,7 @@ const breakString = memoize(
|
||||
* If the wrapped text text has greater height, we extend the height, so it's value won't overflow.
|
||||
*
|
||||
* @param {any} text The text to measure
|
||||
* @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the
|
||||
* resulting size
|
||||
* @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the resulting size
|
||||
* @returns {any} - The height for the given text
|
||||
*/
|
||||
export const calculateTextHeight = function (text, config) {
|
||||
@@ -650,8 +647,7 @@ export const calculateTextHeight = function (text, config) {
|
||||
* This calculates the width of the given text, font size and family.
|
||||
*
|
||||
* @param {any} text - The text to calculate the width of
|
||||
* @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the
|
||||
* resulting size
|
||||
* @param {any} config - The config for fontSize, fontFamily, and fontWeight all impacting the resulting size
|
||||
* @returns {any} - The width for the given text
|
||||
*/
|
||||
export const calculateTextWidth = function (text, config) {
|
||||
@@ -660,8 +656,7 @@ export const calculateTextWidth = function (text, config) {
|
||||
};
|
||||
|
||||
/**
|
||||
* This calculates the dimensions of the given text, font size, font family, font weight, and
|
||||
* margins.
|
||||
* This calculates the dimensions of the given text, font size, font family, font weight, and margins.
|
||||
*
|
||||
* @param {any} text - The text to calculate the width of
|
||||
* @param {any} config - The config for fontSize, fontFamily, fontWeight, and margin all impacting
|
||||
@@ -681,7 +676,7 @@ export const calculateTextDimensions = memoize(
|
||||
// of sans-serif.
|
||||
const fontFamilies = ['sans-serif', fontFamily];
|
||||
const lines = text.split(common.lineBreakRegex);
|
||||
const dims = [];
|
||||
let dims = [];
|
||||
|
||||
const body = select('body');
|
||||
// We don't want to leak DOM elements - if a removal operation isn't available
|
||||
@@ -692,10 +687,10 @@ export const calculateTextDimensions = memoize(
|
||||
|
||||
const g = body.append('svg');
|
||||
|
||||
for (const fontFamily of fontFamilies) {
|
||||
for (let fontFamily of fontFamilies) {
|
||||
let cheight = 0;
|
||||
const dim = { width: 0, height: 0, lineHeight: 0 };
|
||||
for (const line of lines) {
|
||||
let dim = { width: 0, height: 0, lineHeight: 0 };
|
||||
for (let line of lines) {
|
||||
const textObj = getTextObj();
|
||||
textObj.text = line;
|
||||
const textElem = drawSimpleText(g, textObj)
|
||||
@@ -703,7 +698,7 @@ export const calculateTextDimensions = memoize(
|
||||
.style('font-weight', fontWeight)
|
||||
.style('font-family', fontFamily);
|
||||
|
||||
const bBox = (textElem._groups || textElem)[0][0].getBBox();
|
||||
let bBox = (textElem._groups || textElem)[0][0].getBBox();
|
||||
dim.width = Math.round(Math.max(dim.width, bBox.width));
|
||||
cheight = Math.round(bBox.height);
|
||||
dim.height += cheight;
|
||||
@@ -714,7 +709,7 @@ export const calculateTextDimensions = memoize(
|
||||
|
||||
g.remove();
|
||||
|
||||
const index =
|
||||
let index =
|
||||
isNaN(dims[1].height) ||
|
||||
isNaN(dims[1].width) ||
|
||||
isNaN(dims[1].lineHeight) ||
|
||||
@@ -732,11 +727,10 @@ export const calculateTextDimensions = memoize(
|
||||
* Applys d3 attributes
|
||||
*
|
||||
* @param {any} d3Elem D3 Element to apply the attributes onto
|
||||
* @param {[string, string][]} attrs Object.keys equivalent format of key to value mapping of
|
||||
* attributes
|
||||
* @param {[string, string][]} attrs Object.keys equivalent format of key to value mapping of attributes
|
||||
*/
|
||||
const d3Attrs = function (d3Elem, attrs) {
|
||||
for (const attr of attrs) {
|
||||
for (let attr of attrs) {
|
||||
d3Elem.attr(attr[0], attr[1]);
|
||||
}
|
||||
};
|
||||
@@ -866,12 +860,18 @@ export interface DetailedError {
|
||||
hash: any;
|
||||
}
|
||||
|
||||
/** @param error */
|
||||
/**
|
||||
*
|
||||
* @param error
|
||||
*/
|
||||
export function isDetailedError(error: unknown): error is DetailedError {
|
||||
return 'str' in error;
|
||||
}
|
||||
|
||||
/** @param error */
|
||||
/**
|
||||
*
|
||||
* @param error
|
||||
*/
|
||||
export function getErrorMessage(error: unknown): string {
|
||||
if (error instanceof Error) return error.message;
|
||||
return String(error);
|
||||
|
||||
8
test.js
Normal file
8
test.js
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function apa() {
|
||||
// comment's
|
||||
const a = 1;
|
||||
return 'apa' + a;
|
||||
}
|
||||
@@ -3937,9 +3937,9 @@ camelcase@^6.2.0:
|
||||
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
|
||||
|
||||
caniuse-lite@^1.0.30001359:
|
||||
version "1.0.30001397"
|
||||
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001397.tgz"
|
||||
integrity sha512-SW9N2TbCdLf0eiNDRrrQXx2sOkaakNZbCjgNpPyMJJbiOrU5QzMIrXOVMRM1myBXTD5iTkdrtU/EguCrBocHlA==
|
||||
version "1.0.30001390"
|
||||
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001390.tgz"
|
||||
integrity sha512-sS4CaUM+/+vqQUlCvCJ2WtDlV81aWtHhqeEVkLokVJJa3ViN4zDxAGfq9R8i1m90uGHxo99cy10Od+lvn3hf0g==
|
||||
|
||||
caseless@~0.12.0:
|
||||
version "0.12.0"
|
||||
|
||||
Reference in New Issue
Block a user