Merge pull request #3436 from mermaid-js/3061_decoupling
Creating detectors and moving out diagram specific code from the diag…
This commit is contained in:
commit
0edc2751f3
|
@ -38,7 +38,7 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<pre class="mermaid2" style="width: 50%">
|
<pre class="mermaid" style="width: 50%">
|
||||||
flowchart LR
|
flowchart LR
|
||||||
classDef aPID stroke:#4e4403,fill:#fdde29,color:#4e4403,rx:5px,ry:5px;
|
classDef aPID stroke:#4e4403,fill:#fdde29,color:#4e4403,rx:5px,ry:5px;
|
||||||
classDef crm stroke:#333333,fill:#DCDCDC,color:#333333,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 A someclass;
|
||||||
class C someclass;
|
class C someclass;
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="mermaid2" style="width: 50%">
|
<pre class="mermaid" style="width: 50%">
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
title: My Sequence Diagram Title
|
title: My Sequence Diagram Title
|
||||||
accTitle: My Acc Sequence Diagram
|
accTitle: My Acc Sequence Diagram
|
||||||
|
@ -109,14 +109,14 @@ flowchart TD
|
||||||
John-->>Alice: Great!
|
John-->>Alice: Great!
|
||||||
Alice-)John: See you later!
|
Alice-)John: See you later!
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="mermaid2" style="width: 50%">
|
<pre class="mermaid" style="width: 50%">
|
||||||
graph TD
|
graph TD
|
||||||
A -->|000| B
|
A -->|000| B
|
||||||
B -->|111| C
|
B -->|111| C
|
||||||
|
|
||||||
linkStyle 1 stroke:#ff3,stroke-width:4px,color:red;
|
linkStyle 1 stroke:#ff3,stroke-width:4px,color:red;
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="mermaid2" style="width: 100%">
|
<pre class="mermaid" style="width: 100%">
|
||||||
journey
|
journey
|
||||||
accTitle: My User Journey Diagram
|
accTitle: My User Journey Diagram
|
||||||
accDescr: My User Journey Diagram Description
|
accDescr: My User Journey Diagram Description
|
||||||
|
@ -130,10 +130,10 @@ graph TD
|
||||||
Go downstairs: 5: Me
|
Go downstairs: 5: Me
|
||||||
Sit down: 5: Me
|
Sit down: 5: Me
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="mermaid2" style="width: 100%">
|
<pre class="mermaid" style="width: 100%">
|
||||||
info
|
info
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="mermaid2" style="width: 100%">
|
<pre class="mermaid" style="width: 100%">
|
||||||
requirementDiagram
|
requirementDiagram
|
||||||
accTitle: My req Diagram
|
accTitle: My req Diagram
|
||||||
accDescr: My req Diagram Description
|
accDescr: My req Diagram Description
|
||||||
|
@ -174,7 +174,7 @@ requirementDiagram
|
||||||
test_req - contains -> test_req3
|
test_req - contains -> test_req3
|
||||||
test_req <- copies - test_entity2
|
test_req <- copies - test_entity2
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="mermaid2" style="width: 100%">
|
<pre class="mermaid" style="width: 100%">
|
||||||
gantt
|
gantt
|
||||||
dateFormat YYYY-MM-DD
|
dateFormat YYYY-MM-DD
|
||||||
title Adding GANTT diagram functionality to mermaid
|
title Adding GANTT diagram functionality to mermaid
|
||||||
|
@ -206,7 +206,7 @@ gantt
|
||||||
Add gantt diagram to demo page :20h
|
Add gantt diagram to demo page :20h
|
||||||
Add another diagram to demo page :48h
|
Add another diagram to demo page :48h
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="mermaid2" style="width: 100%">
|
<pre class="mermaid" style="width: 100%">
|
||||||
stateDiagram
|
stateDiagram
|
||||||
state Active {
|
state Active {
|
||||||
Idle
|
Idle
|
||||||
|
@ -234,7 +234,7 @@ stateDiagram
|
||||||
end
|
end
|
||||||
B ->> A: Return
|
B ->> A: Return
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="mermaid2" style="width: 100%">
|
<pre class="mermaid" style="width: 100%">
|
||||||
classDiagram
|
classDiagram
|
||||||
accTitle: My class diagram
|
accTitle: My class diagram
|
||||||
accDescr: My class diagram Description
|
accDescr: My class diagram Description
|
||||||
|
@ -259,7 +259,7 @@ class Class10 {
|
||||||
A->>Bob: Hola
|
A->>Bob: Hola
|
||||||
Bob-->A: Pasten !
|
Bob-->A: Pasten !
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="mermaid2" style="width: 100%">
|
<pre class="mermaid" style="width: 100%">
|
||||||
gitGraph
|
gitGraph
|
||||||
commit id: "ZERO"
|
commit id: "ZERO"
|
||||||
branch develop
|
branch develop
|
||||||
|
@ -288,7 +288,7 @@ flowchart TD
|
||||||
C -->|Two| E[iPhone]
|
C -->|Two| E[iPhone]
|
||||||
C -->|Three| F[fa:fa-car Car]
|
C -->|Three| F[fa:fa-car Car]
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="mermaid2" style="width: 100%">
|
<pre class="mermaid" style="width: 100%">
|
||||||
classDiagram
|
classDiagram
|
||||||
Animal "1" <|-- Duck
|
Animal "1" <|-- Duck
|
||||||
Animal <|-- Fish
|
Animal <|-- Fish
|
||||||
|
@ -311,7 +311,7 @@ flowchart TD
|
||||||
+run()
|
+run()
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="mermaid2" style="width: 100%">
|
<pre class="mermaid" style="width: 100%">
|
||||||
erDiagram
|
erDiagram
|
||||||
CAR ||--o{ NAMED-DRIVER : allows
|
CAR ||--o{ NAMED-DRIVER : allows
|
||||||
CAR {
|
CAR {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "mermaid",
|
"name": "mermaid",
|
||||||
"version": "9.1.6",
|
"version": "9.2.0-rc1",
|
||||||
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
|
||||||
"main": "dist/mermaid.min.js",
|
"main": "dist/mermaid.min.js",
|
||||||
"module": "dist/mermaid.esm.min.mjs",
|
"module": "dist/mermaid.esm.min.mjs",
|
||||||
|
|
|
@ -1,26 +1,12 @@
|
||||||
import { MermaidConfig } from '../config.type';
|
import { MermaidConfig } from '../config.type';
|
||||||
|
|
||||||
export type DiagramDetector = (text: string) => boolean;
|
export type DiagramDetector = (text: string, config?: MermaidConfig) => boolean;
|
||||||
|
|
||||||
const directive =
|
const directive =
|
||||||
/[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi;
|
/[%]{2}[{]\s*(?:(?:(\w+)\s*:|(\w+))\s*(?:(?:(\w+))|((?:(?![}][%]{2}).|\r?\n)*))?\s*)(?:[}][%]{2})?/gi;
|
||||||
const anyComment = /\s*%%.*\n/gm;
|
const anyComment = /\s*%%.*\n/gm;
|
||||||
|
|
||||||
const detectors: Record<string, DiagramDetector> = {};
|
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
|
* @function detectType Detects the type of the graph text. Takes into consideration the possible
|
||||||
|
@ -47,28 +33,9 @@ const diagramMatchers: Record<string, RegExp> = {
|
||||||
*/
|
*/
|
||||||
export const detectType = function (text: string, config?: MermaidConfig): string {
|
export const detectType = function (text: string, config?: MermaidConfig): string {
|
||||||
text = text.replace(directive, '').replace(anyComment, '\n');
|
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)) {
|
for (const [key, detector] of Object.entries(detectors)) {
|
||||||
if (detector(text)) {
|
if (detector(text, config)) {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,310 @@
|
||||||
import { registerDiagram } from './diagramAPI';
|
import { registerDiagram } from './diagramAPI';
|
||||||
import * as mindmapDb from '../diagrams/mindmap/mindmapDb';
|
|
||||||
import mindmapRenderer from '../diagrams/mindmap/mindmapRenderer';
|
|
||||||
// @ts-ignore: TODO Fix ts errors
|
// @ts-ignore: TODO Fix ts errors
|
||||||
import mindmapParser from '../diagrams/mindmap/parser/mindmap';
|
import mindmapParser from '../diagrams/mindmap/parser/mindmap';
|
||||||
|
import * as mindmapDb from '../diagrams/mindmap/mindmapDb';
|
||||||
import { mindmapDetector } from '../diagrams/mindmap/mindmapDetector';
|
import { mindmapDetector } from '../diagrams/mindmap/mindmapDetector';
|
||||||
|
import mindmapRenderer from '../diagrams/mindmap/mindmapRenderer';
|
||||||
import mindmapStyles from '../diagrams/mindmap/styles';
|
import mindmapStyles from '../diagrams/mindmap/styles';
|
||||||
|
|
||||||
import gitGraphDb from '../diagrams/git/gitGraphAst';
|
|
||||||
import gitGraphRenderer from '../diagrams/git/gitGraphRenderer';
|
|
||||||
// @ts-ignore: TODO Fix ts errors
|
// @ts-ignore: TODO Fix ts errors
|
||||||
import gitGraphParser from '../diagrams/git/parser/gitGraph';
|
import gitGraphParser from '../diagrams/git/parser/gitGraph';
|
||||||
import { gitGraphDetector } from '../diagrams/git/gitGraphDetector';
|
import { gitGraphDetector } from '../diagrams/git/gitGraphDetector';
|
||||||
|
import gitGraphDb from '../diagrams/git/gitGraphAst';
|
||||||
|
import gitGraphRenderer from '../diagrams/git/gitGraphRenderer';
|
||||||
import gitGraphStyles from '../diagrams/git/styles';
|
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 = () => {
|
export const addDiagrams = () => {
|
||||||
// Register mindmap and other built-in diagrams
|
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
|
||||||
|
);
|
||||||
registerDiagram(
|
registerDiagram(
|
||||||
'gitGraph',
|
'gitGraph',
|
||||||
{ parser: gitGraphParser, db: gitGraphDb, renderer: gitGraphRenderer, styles: gitGraphStyles },
|
{ parser: gitGraphParser, db: gitGraphDb, renderer: gitGraphRenderer, styles: gitGraphStyles },
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import { detectType } from './detectType';
|
import { detectType } from './detectType';
|
||||||
import { getDiagram, registerDiagram } from './diagramAPI';
|
import { getDiagram, registerDiagram } from './diagramAPI';
|
||||||
|
import { addDiagrams } from './diagram-orchestration';
|
||||||
|
|
||||||
|
addDiagrams();
|
||||||
|
|
||||||
describe('DiagramAPI', () => {
|
describe('DiagramAPI', () => {
|
||||||
it('should return default diagrams', () => {
|
it('should return default diagrams', () => {
|
||||||
|
|
|
@ -1,70 +1,23 @@
|
||||||
import c4Db from '../diagrams/c4/c4Db';
|
import { addDetector, DiagramDetector as _DiagramDetector } from './detectType';
|
||||||
import c4Renderer from '../diagrams/c4/c4Renderer';
|
import { log as _log, setLogLevel as _setLogLevel } from '../logger';
|
||||||
import c4Styles from '../diagrams/c4/styles';
|
|
||||||
// @ts-ignore: TODO Fix ts errors
|
|
||||||
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: TODO Fix ts errors
|
|
||||||
import classParser from '../diagrams/class/parser/classDiagram';
|
|
||||||
import erDb from '../diagrams/er/erDb';
|
|
||||||
import erRenderer from '../diagrams/er/erRenderer';
|
|
||||||
// @ts-ignore: TODO Fix ts errors
|
|
||||||
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: TODO Fix ts errors
|
|
||||||
import flowParser from '../diagrams/flowchart/parser/flow';
|
|
||||||
import ganttDb from '../diagrams/gantt/ganttDb';
|
|
||||||
import ganttRenderer from '../diagrams/gantt/ganttRenderer';
|
|
||||||
// @ts-ignore: TODO Fix ts errors
|
|
||||||
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: TODO Fix ts errors
|
|
||||||
import infoParser from '../diagrams/info/parser/info';
|
|
||||||
import infoStyles from '../diagrams/info/styles';
|
|
||||||
// @ts-ignore: TODO Fix ts errors
|
|
||||||
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: TODO Fix ts errors
|
|
||||||
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: TODO Fix ts errors
|
|
||||||
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: TODO Fix ts errors
|
|
||||||
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: TODO Fix ts errors
|
|
||||||
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 { getConfig as _getConfig } from '../config';
|
||||||
import { sanitizeText as _sanitizeText } from '../diagrams/common/common';
|
import { sanitizeText as _sanitizeText } from '../diagrams/common/common';
|
||||||
import { MermaidConfig } from '../config.type';
|
import { MermaidConfig } from '../config.type';
|
||||||
import { setupGraphViewbox as _setupGraphViewbox } from '../setupGraphViewbox';
|
import { setupGraphViewbox as _setupGraphViewbox } from '../setupGraphViewbox';
|
||||||
import { addStylesForDiagram } from '../styles';
|
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 {
|
export interface DiagramDefinition {
|
||||||
db: any;
|
db: any;
|
||||||
renderer: any;
|
renderer: any;
|
||||||
|
@ -73,158 +26,7 @@ export interface DiagramDefinition {
|
||||||
init?: (config: MermaidConfig) => void;
|
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 = (
|
export const registerDiagram = (
|
||||||
id: string,
|
id: string,
|
||||||
|
@ -245,8 +47,3 @@ export const getDiagram = (name: string): DiagramDefinition => {
|
||||||
}
|
}
|
||||||
throw new Error(`Diagram ${name} not found.`);
|
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;
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||||
|
|
||||||
|
export const c4Detector: DiagramDetector = (txt) => {
|
||||||
|
return txt.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/) !== null;
|
||||||
|
};
|
|
@ -0,0 +1,9 @@
|
||||||
|
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;
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
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;
|
||||||
|
};
|
|
@ -0,0 +1,5 @@
|
||||||
|
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||||
|
|
||||||
|
export const erDetector: DiagramDetector = (txt) => {
|
||||||
|
return txt.match(/^\s*erDiagram/) !== null;
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
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;
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
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;
|
||||||
|
};
|
|
@ -0,0 +1,154 @@
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||||
|
|
||||||
|
export const ganttDetector: DiagramDetector = (txt) => {
|
||||||
|
return txt.match(/^\s*gantt/) !== null;
|
||||||
|
};
|
|
@ -0,0 +1,5 @@
|
||||||
|
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||||
|
|
||||||
|
export const infoDetector: DiagramDetector = (txt) => {
|
||||||
|
return txt.match(/^\s*info/) !== null;
|
||||||
|
};
|
|
@ -1,6 +1,6 @@
|
||||||
import { parser as mindmap } from './parser/mindmap';
|
import { parser as mindmap } from './parser/mindmap';
|
||||||
import * as mindmapDB from './mindmapDb';
|
import * as mindmapDB from './mindmapDb';
|
||||||
import { setLogLevel } from '../../logger';
|
import { setLogLevel } from '../../diagram-api/diagramAPI';
|
||||||
|
|
||||||
describe('when parsing a mindmap ', function () {
|
describe('when parsing a mindmap ', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/** Created by knut on 15-01-14. */
|
/** Created by knut on 15-01-14. */
|
||||||
import { sanitizeText, getConfig } from '../../diagram-api/diagramAPI';
|
import { sanitizeText, getConfig, log as _log } from '../../diagram-api/diagramAPI';
|
||||||
import { log as _log } from '../../logger';
|
|
||||||
|
|
||||||
let nodes = [];
|
let nodes = [];
|
||||||
let cnt = 0;
|
let cnt = 0;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
const lineBreakRegex = /<br\s*\/?>/gi;
|
|
||||||
import { select } from 'd3';
|
import { select } from 'd3';
|
||||||
import * as db from './mindmapDb';
|
import * as db from './mindmapDb';
|
||||||
|
|
||||||
|
@ -15,7 +14,6 @@ function wrap(text, width) {
|
||||||
.reverse(),
|
.reverse(),
|
||||||
word,
|
word,
|
||||||
line = [],
|
line = [],
|
||||||
lineNumber = 0,
|
|
||||||
lineHeight = 1.1, // ems
|
lineHeight = 1.1, // ems
|
||||||
y = text.attr('y'),
|
y = text.attr('y'),
|
||||||
dy = parseFloat(text.attr('dy')),
|
dy = parseFloat(text.attr('dy')),
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||||
|
|
||||||
|
export const pieDetector: DiagramDetector = (txt) => {
|
||||||
|
return txt.match(/^\s*pie/) !== null;
|
||||||
|
};
|
|
@ -0,0 +1,5 @@
|
||||||
|
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||||
|
|
||||||
|
export const requirementDetector: DiagramDetector = (txt) => {
|
||||||
|
return txt.match(/^\s*requirement(Diagram)?/) !== null;
|
||||||
|
};
|
|
@ -0,0 +1,5 @@
|
||||||
|
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||||
|
|
||||||
|
export const sequenceDetector: DiagramDetector = (txt) => {
|
||||||
|
return txt.match(/^\s*sequenceDiagram/) !== null;
|
||||||
|
};
|
|
@ -1,12 +1,8 @@
|
||||||
// import sequence from './parser/sequenceDiagram';
|
|
||||||
// import sequenceDb from './sequenceDb';
|
|
||||||
import * as configApi from '../../config';
|
import * as configApi from '../../config';
|
||||||
// import renderer from './sequenceRenderer';
|
|
||||||
import mermaidAPI from '../../mermaidAPI';
|
import mermaidAPI from '../../mermaidAPI';
|
||||||
// import '../../diagram-api/diagramAPI';
|
|
||||||
import Diagram from '../../Diagram';
|
import Diagram from '../../Diagram';
|
||||||
|
import { addDiagrams } from '../../diagram-api/diagram-orchestration';
|
||||||
// console.log('sequenceDiagram', sequenceDb);
|
addDiagrams();
|
||||||
/**
|
/**
|
||||||
* @param conf
|
* @param conf
|
||||||
* @param key
|
* @param key
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
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;
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
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;
|
||||||
|
};
|
|
@ -0,0 +1,5 @@
|
||||||
|
import type { DiagramDetector } from '../../diagram-api/detectType';
|
||||||
|
|
||||||
|
export const journeyDetector: DiagramDetector = (txt) => {
|
||||||
|
return txt.match(/^\s*journey/) !== null;
|
||||||
|
};
|
|
@ -2,8 +2,6 @@ import mermaid from './mermaid';
|
||||||
import { mermaidAPI } from './mermaidAPI';
|
import { mermaidAPI } from './mermaidAPI';
|
||||||
import flowDb from './diagrams/flowchart/flowDb';
|
import flowDb from './diagrams/flowchart/flowDb';
|
||||||
import flowParser from './diagrams/flowchart/parser/flow';
|
import flowParser from './diagrams/flowchart/parser/flow';
|
||||||
import flowRenderer from './diagrams/flowchart/flowRenderer';
|
|
||||||
import Diagram from './Diagram';
|
|
||||||
|
|
||||||
const spyOn = jest.spyOn;
|
const spyOn = jest.spyOn;
|
||||||
|
|
||||||
|
@ -58,149 +56,6 @@ 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 () {
|
describe('checking validity of input ', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
flowParser.parser.yy = flowDb;
|
flowParser.parser.yy = flowDb;
|
||||||
|
|
Loading…
Reference in New Issue