Skip to content

Commit 4c13e34

Browse files
committed
Made changes in mermaid parser for client side.
1 parent f525d48 commit 4c13e34

File tree

6 files changed

+108
-70
lines changed

6 files changed

+108
-70
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
4. [mermaid](#mermaid)
1010
3. [Installation](#installation)
1111
4. [Usage](#usage)
12+
1. [Additional steps for mermaid](#additional-steps-for-mermaid)
1213
5. [References](#references)
1314
6. [License](#license)
1415

@@ -99,6 +100,21 @@ const md = require('markdown-it')()
99100
.use(markdownItTextualUml);
100101
```
101102
103+
### Additional steps for mermaid
104+
105+
For mermaid, you have to include the `mermaid js` file in your application and initialize it **_after_** the window has loaded. Just using this plugin is not enough to ensure that the diagram is rendered correctly.
106+
107+
**Note:** mermaid js has a dependency on the browser window being loaded before it can initialize. Related GitHub [issue](https://github.com/knsv/mermaid/issues/485).
108+
109+
So you should have the following in your html page in order for the mermaid text definitions to be translated into svg.
110+
111+
```html
112+
<script src="mermaid.min.js"></script>
113+
<script>mermaid.initialize({startOnLoad:true});</script>
114+
```
115+
116+
Details [here](https://mermaidjs.github.io/#/usage?id=simple-usage-on-a-web-page).
117+
102118
## References
103119
104120
Here are some alternative npm packages:

src/mermaid-parser.js

Lines changed: 1 addition & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,19 @@
11
'use strict'
22

3-
const path = require('path')
4-
const fs = require('fs')
5-
const childProcess = require('child_process');
6-
7-
const tempDir = path.join(__dirname, 'temp', 'mermaid')
8-
const outputFile = path.join(tempDir, 'output.data')
9-
const puppeteerScript = path.join(__dirname, './mermaid-puppeteer.js')
10-
113
const functions = {
124
options: {},
135

14-
mermaidParserDefaults: {
15-
startOnLoad: false,
16-
theme: 'default',
17-
flowchart: {
18-
htmlLabels: false,
19-
useMaxWidth: true
20-
}
21-
},
22-
236
initialize(options) {
247
if (options) {
258
this.options = options;
269
}
27-
if (!fs.existsSync(tempDir)){
28-
fs.mkdirSync(tempDir);
29-
}
30-
const optionsFile = path.join(tempDir, 'options.data')
31-
// overwrites existing file
32-
fs.writeFileSync(optionsFile, JSON.stringify(this.options))
3310
},
3411

3512
getMarkup(code) {
36-
37-
const codeFile = path.join(tempDir, 'code.data')
38-
if (!fs.existsSync(tempDir)){
39-
fs.mkdirSync(tempDir);
40-
}
41-
// overwrites existing file
42-
fs.writeFileSync(codeFile, code)
43-
44-
/*runScript(puppeteerScript, function (err) {
45-
if (err) throw err;
46-
console.log('finished running mermaid-puppeteer.js');
47-
});*/
48-
49-
childProcess.execSync('node ' + puppeteerScript)
50-
51-
const output = fs.readFileSync(outputFile, 'utf-8')
52-
return '<div class="mermaid" data-processed="true">\n' + output + '\n</div>\n'
13+
return `<div class="mermaid">\n${code}\n</div>\n`
5314
}
5415
}
5516

56-
// https://stackoverflow.com/a/22649812/420827
57-
function runScript(scriptPath, callback) {
58-
59-
// keep track of whether callback has been invoked to prevent multiple invocations
60-
var invoked = false;
61-
62-
var process = childProcess.fork(scriptPath);
63-
64-
// listen for errors as they may prevent the exit event from firing
65-
process.on('error', function (err) {
66-
if (invoked) return;
67-
invoked = true;
68-
callback(err);
69-
});
70-
71-
// execute the callback once the process has finished running
72-
process.on('exit', function (code) {
73-
if (invoked) return;
74-
invoked = true;
75-
var err = code === 0 ? null : new Error('exit code ' + code);
76-
callback(err);
77-
});
78-
79-
}
80-
8117
module.exports = {
8218
functions
8319
};

src/mermaid-parser.js.server

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
'use strict'
2+
3+
const path = require('path')
4+
const fs = require('fs')
5+
const childProcess = require('child_process');
6+
7+
const tempDir = path.join(__dirname, 'temp', 'mermaid')
8+
const outputFile = path.join(tempDir, 'output.data')
9+
const puppeteerScript = path.join(__dirname, './mermaid-puppeteer.js')
10+
11+
const functions = {
12+
options: {},
13+
14+
mermaidParserDefaults: {
15+
startOnLoad: false,
16+
theme: 'default',
17+
flowchart: {
18+
htmlLabels: false,
19+
useMaxWidth: true
20+
}
21+
},
22+
23+
initialize(options) {
24+
if (options) {
25+
this.options = options;
26+
}
27+
if (!fs.existsSync(tempDir)){
28+
fs.mkdirSync(tempDir);
29+
}
30+
const optionsFile = path.join(tempDir, 'options.data')
31+
// overwrites existing file
32+
fs.writeFileSync(optionsFile, JSON.stringify(this.options))
33+
},
34+
35+
getMarkup(code) {
36+
37+
const codeFile = path.join(tempDir, 'code.data')
38+
if (!fs.existsSync(tempDir)){
39+
fs.mkdirSync(tempDir);
40+
}
41+
// overwrites existing file
42+
fs.writeFileSync(codeFile, code)
43+
44+
/*runScript(puppeteerScript, function (err) {
45+
if (err) throw err;
46+
console.log('finished running mermaid-puppeteer.js');
47+
});*/
48+
49+
childProcess.execSync('node ' + puppeteerScript)
50+
51+
const output = fs.readFileSync(outputFile, 'utf-8')
52+
return '<div class="mermaid" data-processed="true">\n' + output + '\n</div>\n'
53+
}
54+
}
55+
56+
// https://stackoverflow.com/a/22649812/420827
57+
function runScript(scriptPath, callback) {
58+
59+
// keep track of whether callback has been invoked to prevent multiple invocations
60+
var invoked = false;
61+
62+
var process = childProcess.fork(scriptPath);
63+
64+
// listen for errors as they may prevent the exit event from firing
65+
process.on('error', function (err) {
66+
if (invoked) return;
67+
invoked = true;
68+
callback(err);
69+
});
70+
71+
// execute the callback once the process has finished running
72+
process.on('exit', function (code) {
73+
if (invoked) return;
74+
invoked = true;
75+
var err = code === 0 ? null : new Error('exit code ' + code);
76+
callback(err);
77+
});
78+
79+
}
80+
81+
module.exports = {
82+
functions
83+
};
File renamed without changes.

test/fixtures/mermaid/default.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ graph TD;
88
C-->D;
99
```
1010
.
11-
<div class="mermaid" data-processed="true">
12-
<svg id="mermaid-1567470580104" width="100%" xmlns="http://www.w3.org/2000/svg" style="max-width: 124.640625px;" viewBox="0 0 124.640625 233"><style>#mermaid-1567470580104 .label{font-family:\'trebuchet ms\', verdana, arial;color:#333}#mermaid-1567470580104 .label text{fill:#333}#mermaid-1567470580104 .node rect,#mermaid-1567470580104 .node circle,#mermaid-1567470580104 .node ellipse,#mermaid-1567470580104 .node polygon{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-1567470580104 .node.clickable{cursor:pointer}#mermaid-1567470580104 .arrowheadPath{fill:#333}#mermaid-1567470580104 .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-1567470580104 .edgeLabel{background-color:#e8e8e8}#mermaid-1567470580104 .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-1567470580104 .cluster text{fill:#333}#mermaid-1567470580104 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\'trebuchet ms\', verdana, arial;font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-1567470580104 .actor{stroke:#ccf;fill:#ECECFF}#mermaid-1567470580104 text.actor{fill:#000;stroke:none}#mermaid-1567470580104 .actor-line{stroke:grey}#mermaid-1567470580104 .messageLine0{stroke-width:1.5;stroke-dasharray:\'2 2\';stroke:#333}#mermaid-1567470580104 .messageLine1{stroke-width:1.5;stroke-dasharray:\'2 2\';stroke:#333}#mermaid-1567470580104 #arrowhead{fill:#333}#mermaid-1567470580104 .sequenceNumber{fill:#fff}#mermaid-1567470580104 #sequencenumber{fill:#333}#mermaid-1567470580104 #crosshead path{fill:#333 !important;stroke:#333 !important}#mermaid-1567470580104 .messageText{fill:#333;stroke:none}#mermaid-1567470580104 .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-1567470580104 .labelText{fill:#000;stroke:none}#mermaid-1567470580104 .loopText{fill:#000;stroke:none}#mermaid-1567470580104 .loopLine{stroke-width:2;stroke-dasharray:\'2 2\';stroke:#ccf}#mermaid-1567470580104 .note{stroke:#aa3;fill:#fff5ad}#mermaid-1567470580104 .noteText{fill:black;stroke:none;font-family:\'trebuchet ms\', verdana, arial;font-size:14px}#mermaid-1567470580104 .activation0{fill:#f4f4f4;stroke:#666}#mermaid-1567470580104 .activation1{fill:#f4f4f4;stroke:#666}#mermaid-1567470580104 .activation2{fill:#f4f4f4;stroke:#666}#mermaid-1567470580104 .section{stroke:none;opacity:0.2}#mermaid-1567470580104 .section0{fill:rgba(102,102,255,0.49)}#mermaid-1567470580104 .section2{fill:#fff400}#mermaid-1567470580104 .section1,#mermaid-1567470580104 .section3{fill:#fff;opacity:0.2}#mermaid-1567470580104 .sectionTitle0{fill:#333}#mermaid-1567470580104 .sectionTitle1{fill:#333}#mermaid-1567470580104 .sectionTitle2{fill:#333}#mermaid-1567470580104 .sectionTitle3{fill:#333}#mermaid-1567470580104 .sectionTitle{text-anchor:start;font-size:11px;text-height:14px}#mermaid-1567470580104 .grid .tick{stroke:#d3d3d3;opacity:0.3;shape-rendering:crispEdges}#mermaid-1567470580104 .grid path{stroke-width:0}#mermaid-1567470580104 .today{fill:none;stroke:red;stroke-width:2px}#mermaid-1567470580104 .task{stroke-width:2}#mermaid-1567470580104 .taskText{text-anchor:middle;font-size:11px}#mermaid-1567470580104 .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px}#mermaid-1567470580104 .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-1567470580104 .task.clickable{cursor:pointer}#mermaid-1567470580104 .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-1567470580104 .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-1567470580104 .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-1567470580104 .taskText0,#mermaid-1567470580104 .taskText1,#mermaid-1567470580104 .taskText2,#mermaid-1567470580104 .taskText3{fill:#fff}#mermaid-1567470580104 .task0,#mermaid-1567470580104 .task1,#mermaid-1567470580104 .task2,#mermaid-1567470580104 .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-1567470580104 .taskTextOutside0,#mermaid-1567470580104 .taskTextOutside2{fill:#000}#mermaid-1567470580104 .taskTextOutside1,#mermaid-1567470580104 .taskTextOutside3{fill:#000}#mermaid-1567470580104 .active0,#mermaid-1567470580104 .active1,#mermaid-1567470580104 .active2,#mermaid-1567470580104 .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-1567470580104 .activeText0,#mermaid-1567470580104 .activeText1,#mermaid-1567470580104 .activeText2,#mermaid-1567470580104 .activeText3{fill:#000 !important}#mermaid-1567470580104 .done0,#mermaid-1567470580104 .done1,#mermaid-1567470580104 .done2,#mermaid-1567470580104 .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-1567470580104 .doneText0,#mermaid-1567470580104 .doneText1,#mermaid-1567470580104 .doneText2,#mermaid-1567470580104 .doneText3{fill:#000 !important}#mermaid-1567470580104 .crit0,#mermaid-1567470580104 .crit1,#mermaid-1567470580104 .crit2,#mermaid-1567470580104 .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-1567470580104 .activeCrit0,#mermaid-1567470580104 .activeCrit1,#mermaid-1567470580104 .activeCrit2,#mermaid-1567470580104 .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-1567470580104 .doneCrit0,#mermaid-1567470580104 .doneCrit1,#mermaid-1567470580104 .doneCrit2,#mermaid-1567470580104 .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-1567470580104 .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-1567470580104 .milestoneText{font-style:italic}#mermaid-1567470580104 .doneCritText0,#mermaid-1567470580104 .doneCritText1,#mermaid-1567470580104 .doneCritText2,#mermaid-1567470580104 .doneCritText3{fill:#000 !important}#mermaid-1567470580104 .activeCritText0,#mermaid-1567470580104 .activeCritText1,#mermaid-1567470580104 .activeCritText2,#mermaid-1567470580104 .activeCritText3{fill:#000 !important}#mermaid-1567470580104 .titleText{text-anchor:middle;font-size:18px;fill:#000}#mermaid-1567470580104 g.classGroup text{fill:#9370db;stroke:none;font-family:\'trebuchet ms\', verdana, arial;font-size:10px}#mermaid-1567470580104 g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-1567470580104 g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-1567470580104 .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-1567470580104 .classLabel .label{fill:#9370db;font-size:10px}#mermaid-1567470580104 .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-1567470580104 #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-1567470580104 #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-1567470580104 #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-1567470580104 #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-1567470580104 #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-1567470580104 #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-1567470580104 #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-1567470580104 #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-1567470580104 .commit-id,#mermaid-1567470580104 .commit-msg,#mermaid-1567470580104 .branch-label{fill:lightgrey;color:lightgrey}\n</style><style>#mermaid-1567470580104 {\n color: rgb(0, 0, 0);\n font: normal normal 400 normal 16px / normal "Times New Roman";\n }</style><g transform="translate(-12, -12)"><g class="output"><g class="clusters"></g><g class="edgePaths"><g class="edgePath" style="opacity: 1;"><path class="path" d="M59.19140625,56.33049345021176L34.53125,84L34.53125,109" marker-end="url(#arrowhead14)" style="fill:none"></path><defs><marker id="arrowhead14" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M89.19140625,56.33049345021176L113.8515625,84L113.8515625,109" marker-end="url(#arrowhead15)" style="fill:none"></path><defs><marker id="arrowhead15" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M34.53125,148L34.53125,173L59.19140625,200.66950654978825" marker-end="url(#arrowhead16)" style="fill:none"></path><defs><marker id="arrowhead16" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g><g class="edgePath" style="opacity: 1;"><path class="path" d="M113.8515625,148L113.8515625,173L89.19140625,200.66950654978825" marker-end="url(#arrowhead17)" style="fill:none"></path><defs><marker id="arrowhead17" viewBox="0 0 10 10" refX="9" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowheadPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker></defs></g></g><g class="edgeLabels"><g class="edgeLabel" style="opacity: 1;" transform=""><g transform="translate(0,0)" class="label"><rect rx="0" ry="0" width="0" height="0" style="fill:#e8e8e8;"></rect><text><tspan xml:space="preserve" dy="1em" x="1"></tspan></text></g></g><g
13-
class="edgeLabel" style="opacity: 1;" transform=""><g transform="translate(0,0)" class="label"><rect rx="0" ry="0" width="0" height="0" style="fill:#e8e8e8;"></rect><text><tspan xml:space="preserve" dy="1em" x="1"></tspan></text></g></g><g class="edgeLabel" style="opacity: 1;" transform=""><g transform="translate(0,0)" class="label"><rect rx="0" ry="0" width="0" height="0" style="fill:#e8e8e8;"></rect><text><tspan xml:space="preserve" dy="1em" x="1"></tspan></text></g></g><g class="edgeLabel" style="opacity: 1;" transform=""><g transform="translate(0,0)" class="label"><rect rx="0" ry="0" width="0" height="0" style="fill:#e8e8e8;"></rect><text><tspan xml:space="preserve" dy="1em" x="1"></tspan></text></g></g></g><g class="nodes"><g class="node" id="A" transform="translate(74.19140625,39.5)" style="opacity: 1;"><rect rx="0" ry="0" x="-15" y="-19.5" width="30" height="39"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-5,-9.5)"><text><tspan xml:space="preserve" dy="1em" x="1">A</tspan></text></g></g></g><g class="node" id="B" transform="translate(34.53125,128.5)" style="opacity: 1;"><rect rx="0" ry="0" x="-14.53125" y="-19.5" width="29.0625" height="39"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-4.53125,-9.5)"><text><tspan xml:space="preserve" dy="1em" x="1">B</tspan></text></g></g></g><g class="node" id="C" transform="translate(113.8515625,128.5)" style="opacity: 1;"><rect rx="0" ry="0" x="-14.7890625" y="-19.5" width="29.578125" height="39"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-4.7890625,-9.5)"><text><tspan xml:space="preserve" dy="1em" x="1">C</tspan></text></g></g></g><g class="node" id="D" transform="translate(74.19140625,217.5)" style="opacity: 1;"><rect rx="0" ry="0" x="-15" y="-19.5" width="30" height="39"></rect><g class="label" transform="translate(0,0)"><g transform="translate(-5,-9.5)"><text><tspan xml:space="preserve" dy="1em" x="1">D</tspan></text></g></g></g></g></g></g></svg>
11+
<div class="mermaid">
12+
graph TD;
13+
A-->B;
14+
A-->C;
15+
B-->D;
16+
C-->D;
1417
</div>
1518
.
1619

test/mermaid.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('markdown-it-textual-uml: mermaid', function() {
2525
\`\`\``));
2626
});
2727

28-
/*it('test default', function() {
28+
it('test default', function() {
2929
var defaultParser = md().use(umlPlugin)
3030

3131
function runGenerate() {
@@ -40,5 +40,5 @@ describe('markdown-it-textual-uml: mermaid', function() {
4040
})
4141
}
4242
runGenerate();
43-
})*/
43+
})
4444
})

0 commit comments

Comments
 (0)