@mermaid-js/mermaid-cli 9.1.5 → 9.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -0
- package/mermaid.min.js +1 -1
- package/package.json +23 -13
- package/src/cli.js +6 -0
- package/src/index.js +411 -0
- package/index.bundle.js +0 -336
package/index.bundle.js
DELETED
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
|
|
4
|
-
var _commander = _interopRequireDefault(require("commander"));
|
|
5
|
-
|
|
6
|
-
var _chalk = _interopRequireDefault(require("chalk"));
|
|
7
|
-
|
|
8
|
-
var _fs = _interopRequireDefault(require("fs"));
|
|
9
|
-
|
|
10
|
-
var _path = _interopRequireDefault(require("path"));
|
|
11
|
-
|
|
12
|
-
var _puppeteer = _interopRequireDefault(require("puppeteer"));
|
|
13
|
-
|
|
14
|
-
var _package = _interopRequireDefault(require("./package.json"));
|
|
15
|
-
|
|
16
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
-
|
|
18
|
-
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
19
|
-
|
|
20
|
-
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
21
|
-
|
|
22
|
-
process.title = "mmdc";
|
|
23
|
-
|
|
24
|
-
const error = message => {
|
|
25
|
-
console.error(_chalk.default.red(`\n${message}\n`));
|
|
26
|
-
process.exit(1);
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const warn = message => {
|
|
30
|
-
console.log(_chalk.default.yellow(`\n${message}\n`));
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const checkConfigFile = file => {
|
|
34
|
-
if (!_fs.default.existsSync(file)) {
|
|
35
|
-
error(`Configuration file "${file}" doesn't exist`);
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const inputPipedFromStdin = () => _fs.default.fstatSync(0).isFIFO();
|
|
40
|
-
|
|
41
|
-
const getInputData = /*#__PURE__*/function () {
|
|
42
|
-
var _ref = _asyncToGenerator(function* (inputFile) {
|
|
43
|
-
return new Promise((resolve, reject) => {
|
|
44
|
-
// if an input file has been specified using '-i', it takes precedence over
|
|
45
|
-
// piping from stdin
|
|
46
|
-
if (typeof inputFile !== 'undefined') {
|
|
47
|
-
return _fs.default.readFile(inputFile, 'utf-8', (err, data) => {
|
|
48
|
-
if (err) {
|
|
49
|
-
return reject(err);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return resolve(data);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
let data = '';
|
|
57
|
-
process.stdin.on('readable', function () {
|
|
58
|
-
var chunk = this.read();
|
|
59
|
-
|
|
60
|
-
if (chunk !== null) {
|
|
61
|
-
data += chunk;
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
process.stdin.on('error', function (err) {
|
|
65
|
-
reject(err);
|
|
66
|
-
});
|
|
67
|
-
process.stdin.on('end', function () {
|
|
68
|
-
resolve(data);
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
return function getInputData(_x) {
|
|
74
|
-
return _ref.apply(this, arguments);
|
|
75
|
-
};
|
|
76
|
-
}();
|
|
77
|
-
|
|
78
|
-
const convertToValidXML = html => {
|
|
79
|
-
// <br> tags in valid HTML (from innerHTML) look like <br>, but they must look like <br/> to be valid XML (such as SVG)
|
|
80
|
-
return html.replace(/<br>/gi, '<br/>');
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
_commander.default.version(_package.default.version).option('-t, --theme [theme]', 'Theme of the chart, could be default, forest, dark or neutral. Optional. Default: default', /^default|forest|dark|neutral$/, 'default').option('-w, --width [width]', 'Width of the page. Optional. Default: 800', /^\d+$/, '800').option('-H, --height [height]', 'Height of the page. Optional. Default: 600', /^\d+$/, '600').option('-i, --input <input>', 'Input mermaid file. Files ending in .md will be treated as Markdown and all charts (e.g. ```mermaid (...)```) will be extracted and generated. Required.').option('-o, --output [output]', 'Output file. It should be either md, svg, png or pdf. Optional. Default: input + ".svg"').option('-b, --backgroundColor [backgroundColor]', 'Background color. Example: transparent, red, \'#F0F0F0\'. Optional. Default: white').option('-c, --configFile [configFile]', 'JSON configuration file for mermaid. Optional').option('-C, --cssFile [cssFile]', 'CSS file for the page. Optional').option('-s, --scale [scale]', 'Puppeteer scale factor, default 1. Optional').option('-f, --pdfFit [pdfFit]', 'Scale PDF to fit chart').option('-q, --quiet', 'Suppress log output').option('-p --puppeteerConfigFile [puppeteerConfigFile]', 'JSON configuration file for puppeteer. Optional').parse(process.argv);
|
|
84
|
-
|
|
85
|
-
const options = _commander.default.opts();
|
|
86
|
-
|
|
87
|
-
let {
|
|
88
|
-
theme,
|
|
89
|
-
width,
|
|
90
|
-
height,
|
|
91
|
-
input,
|
|
92
|
-
output,
|
|
93
|
-
backgroundColor,
|
|
94
|
-
configFile,
|
|
95
|
-
cssFile,
|
|
96
|
-
puppeteerConfigFile,
|
|
97
|
-
scale,
|
|
98
|
-
pdfFit,
|
|
99
|
-
quiet
|
|
100
|
-
} = options; // check input file
|
|
101
|
-
|
|
102
|
-
if (!(input || inputPipedFromStdin())) {
|
|
103
|
-
console.error(_chalk.default.red(`\nPlease specify input file: -i <input>\n`)); // Log to stderr, and return with error exitCode
|
|
104
|
-
|
|
105
|
-
_commander.default.help({
|
|
106
|
-
error: true
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (input && !_fs.default.existsSync(input)) {
|
|
111
|
-
error(`Input file "${input}" doesn't exist`);
|
|
112
|
-
} // check output file
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (!output) {
|
|
116
|
-
// if an input file is defined, it should take precedence, otherwise, input is
|
|
117
|
-
// coming from stdin and just name the file out.svg, if it hasn't been
|
|
118
|
-
// specified with the '-o' option
|
|
119
|
-
output = input ? input + '.svg' : 'out.svg';
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (!/\.(?:svg|png|pdf|md)$/.test(output)) {
|
|
123
|
-
error(`Output file must end with ".md", ".svg", ".png" or ".pdf"`);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const outputDir = _path.default.dirname(output);
|
|
127
|
-
|
|
128
|
-
if (!_fs.default.existsSync(outputDir)) {
|
|
129
|
-
error(`Output directory "${outputDir}/" doesn't exist`);
|
|
130
|
-
} // check config files
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
let mermaidConfig = {
|
|
134
|
-
theme
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
if (configFile) {
|
|
138
|
-
checkConfigFile(configFile);
|
|
139
|
-
mermaidConfig = Object.assign(mermaidConfig, JSON.parse(_fs.default.readFileSync(configFile, 'utf-8')));
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
let puppeteerConfig = {};
|
|
143
|
-
|
|
144
|
-
if (puppeteerConfigFile) {
|
|
145
|
-
checkConfigFile(puppeteerConfigFile);
|
|
146
|
-
puppeteerConfig = JSON.parse(_fs.default.readFileSync(puppeteerConfigFile, 'utf-8'));
|
|
147
|
-
} // check cssFile
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
let myCSS;
|
|
151
|
-
|
|
152
|
-
if (cssFile) {
|
|
153
|
-
if (!_fs.default.existsSync(cssFile)) {
|
|
154
|
-
error(`CSS file "${cssFile}" doesn't exist`);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
myCSS = _fs.default.readFileSync(cssFile, 'utf-8');
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const info = message => {
|
|
161
|
-
if (!quiet) {
|
|
162
|
-
console.info(message);
|
|
163
|
-
}
|
|
164
|
-
}; // normalize args
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
width = parseInt(width);
|
|
168
|
-
height = parseInt(height);
|
|
169
|
-
backgroundColor = backgroundColor || 'white';
|
|
170
|
-
const deviceScaleFactor = parseInt(scale || 1, 10);
|
|
171
|
-
|
|
172
|
-
const parseMMD = /*#__PURE__*/function () {
|
|
173
|
-
var _ref2 = _asyncToGenerator(function* (browser, definition, output) {
|
|
174
|
-
const page = yield browser.newPage();
|
|
175
|
-
page.setViewport({
|
|
176
|
-
width,
|
|
177
|
-
height,
|
|
178
|
-
deviceScaleFactor
|
|
179
|
-
});
|
|
180
|
-
yield page.goto(`file://${_path.default.join(__dirname, 'index.html')}`);
|
|
181
|
-
yield page.evaluate(`document.body.style.background = '${backgroundColor}'`);
|
|
182
|
-
const result = yield page.$eval('#container', (container, definition, mermaidConfig, myCSS) => {
|
|
183
|
-
container.textContent = definition;
|
|
184
|
-
window.mermaid.initialize(mermaidConfig);
|
|
185
|
-
|
|
186
|
-
if (myCSS) {
|
|
187
|
-
const head = window.document.head || window.document.getElementsByTagName('head')[0];
|
|
188
|
-
const style = document.createElement('style');
|
|
189
|
-
style.type = 'text/css';
|
|
190
|
-
|
|
191
|
-
if (style.styleSheet) {
|
|
192
|
-
style.styleSheet.cssText = myCSS;
|
|
193
|
-
} else {
|
|
194
|
-
style.appendChild(document.createTextNode(myCSS));
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
head.appendChild(style);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
try {
|
|
201
|
-
window.mermaid.initThrowsErrors(undefined, container);
|
|
202
|
-
return {
|
|
203
|
-
status: 'success'
|
|
204
|
-
};
|
|
205
|
-
} catch (error) {
|
|
206
|
-
return {
|
|
207
|
-
status: 'error',
|
|
208
|
-
error,
|
|
209
|
-
message: error.message
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
}, definition, mermaidConfig, myCSS);
|
|
213
|
-
|
|
214
|
-
if (result.status === 'error') {
|
|
215
|
-
error(result.message);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (output.endsWith('svg')) {
|
|
219
|
-
const svg = yield page.$eval('#container', (container, backgroundColor) => {
|
|
220
|
-
var _container$getElement, _container$getElement2;
|
|
221
|
-
|
|
222
|
-
const svg = (_container$getElement = container.getElementsByTagName) === null || _container$getElement === void 0 ? void 0 : (_container$getElement2 = _container$getElement.call(container, 'svg')) === null || _container$getElement2 === void 0 ? void 0 : _container$getElement2[0];
|
|
223
|
-
|
|
224
|
-
if (svg.style) {
|
|
225
|
-
svg.style.backgroundColor = backgroundColor;
|
|
226
|
-
} else {
|
|
227
|
-
warn("svg not found. Not applying background color.");
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
return container.innerHTML;
|
|
231
|
-
}, backgroundColor);
|
|
232
|
-
const svgXML = convertToValidXML(svg);
|
|
233
|
-
|
|
234
|
-
_fs.default.writeFileSync(output, svgXML);
|
|
235
|
-
} else if (output.endsWith('png')) {
|
|
236
|
-
const clip = yield page.$eval('svg', svg => {
|
|
237
|
-
const react = svg.getBoundingClientRect();
|
|
238
|
-
return {
|
|
239
|
-
x: Math.floor(react.left),
|
|
240
|
-
y: Math.floor(react.top),
|
|
241
|
-
width: Math.ceil(react.width),
|
|
242
|
-
height: Math.ceil(react.height)
|
|
243
|
-
};
|
|
244
|
-
});
|
|
245
|
-
yield page.setViewport({
|
|
246
|
-
width: clip.x + clip.width,
|
|
247
|
-
height: clip.y + clip.height,
|
|
248
|
-
deviceScaleFactor
|
|
249
|
-
});
|
|
250
|
-
yield page.screenshot({
|
|
251
|
-
path: output,
|
|
252
|
-
clip,
|
|
253
|
-
omitBackground: backgroundColor === 'transparent'
|
|
254
|
-
});
|
|
255
|
-
} else {
|
|
256
|
-
// pdf
|
|
257
|
-
if (pdfFit) {
|
|
258
|
-
const clip = yield page.$eval('svg', svg => {
|
|
259
|
-
const react = svg.getBoundingClientRect();
|
|
260
|
-
return {
|
|
261
|
-
x: react.left,
|
|
262
|
-
y: react.top,
|
|
263
|
-
width: react.width,
|
|
264
|
-
height: react.height
|
|
265
|
-
};
|
|
266
|
-
});
|
|
267
|
-
yield page.pdf({
|
|
268
|
-
path: output,
|
|
269
|
-
omitBackground: backgroundColor === 'transparent',
|
|
270
|
-
width: Math.ceil(clip.width) + clip.x * 2 + 'px',
|
|
271
|
-
height: Math.ceil(clip.height) + clip.y * 2 + 'px',
|
|
272
|
-
pageRanges: '1-1'
|
|
273
|
-
});
|
|
274
|
-
} else {
|
|
275
|
-
yield page.pdf({
|
|
276
|
-
path: output,
|
|
277
|
-
omitBackground: backgroundColor === 'transparent'
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
return function parseMMD(_x2, _x3, _x4) {
|
|
284
|
-
return _ref2.apply(this, arguments);
|
|
285
|
-
};
|
|
286
|
-
}();
|
|
287
|
-
|
|
288
|
-
_asyncToGenerator(function* () {
|
|
289
|
-
const mermaidChartsInMarkdown = '^```(?:mermaid)(\r?\n([\\s\\S]*?))```$';
|
|
290
|
-
const mermaidChartsInMarkdownRegexGlobal = new RegExp(mermaidChartsInMarkdown, 'gm');
|
|
291
|
-
const mermaidChartsInMarkdownRegex = new RegExp(mermaidChartsInMarkdown);
|
|
292
|
-
const browser = yield _puppeteer.default.launch(puppeteerConfig);
|
|
293
|
-
const definition = yield getInputData(input);
|
|
294
|
-
|
|
295
|
-
if (/\.md$/.test(input)) {
|
|
296
|
-
const diagrams = [];
|
|
297
|
-
const outDefinition = definition.replace(mermaidChartsInMarkdownRegexGlobal, mermaidMd => {
|
|
298
|
-
const md = mermaidChartsInMarkdownRegex.exec(mermaidMd)[1]; // Output can be either a template image file, or a `.md` output file.
|
|
299
|
-
// If it is a template image file, use that to created numbered diagrams
|
|
300
|
-
// I.e. if "out.png", use "out-1.png", "out-2.png", etc
|
|
301
|
-
// If it is an output `.md` file, use that to base .svg numbered diagrams on
|
|
302
|
-
// I.e. if "out.md". use "out-1.svg", "out-2.svg", etc
|
|
303
|
-
|
|
304
|
-
const outputFile = output.replace(/(\.(md|png))$/, `-${diagrams.length + 1}$1`).replace(/(\.md)$/, '.svg');
|
|
305
|
-
const outputFileRelative = `./${_path.default.relative(_path.default.dirname(_path.default.resolve(output)), _path.default.resolve(outputFile))}`;
|
|
306
|
-
diagrams.push([outputFile, md]);
|
|
307
|
-
return ``;
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
if (diagrams.length) {
|
|
311
|
-
info(`Found ${diagrams.length} mermaid charts in Markdown input`);
|
|
312
|
-
yield Promise.all(diagrams.map( /*#__PURE__*/function () {
|
|
313
|
-
var _ref4 = _asyncToGenerator(function* ([imgFile, md]) {
|
|
314
|
-
yield parseMMD(browser, md, imgFile);
|
|
315
|
-
info(` ✅ ${imgFile}`);
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
return function (_x5) {
|
|
319
|
-
return _ref4.apply(this, arguments);
|
|
320
|
-
};
|
|
321
|
-
}()));
|
|
322
|
-
} else {
|
|
323
|
-
info(`No mermaid charts found in Markdown input`);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
if (/\.md$/.test(output)) {
|
|
327
|
-
yield _fs.default.promises.writeFile(output, outDefinition, 'utf-8');
|
|
328
|
-
info(` ✅ ${output}`);
|
|
329
|
-
}
|
|
330
|
-
} else {
|
|
331
|
-
info(`Generating single mermaid chart`);
|
|
332
|
-
yield parseMMD(browser, definition, output);
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
yield browser.close();
|
|
336
|
-
})().catch(exception => error(exception instanceof Error ? exception.stack : exception));
|