1 | #!/usr/bin/env node
|
2 | 'use strict';
|
3 |
|
4 | function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
5 |
|
6 | const commander = require('commander');
|
7 | const chalk = require('chalk');
|
8 | const fs = require('fs');
|
9 | const path = require('path');
|
10 | const puppeteer = require('puppeteer');
|
11 |
|
12 | const pkg = require('./package.json');
|
13 |
|
14 | const error = message => {
|
15 | console.log(chalk.red(`\n${message}\n`));
|
16 | process.exit(1);
|
17 | };
|
18 |
|
19 | commander.version(pkg.version).option('-t, --theme [name]', '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. Required.').option('-o, --output [output]', 'Output file. It should be either svg, png or pdf. Optional. Default: input + ".svg"').option('-b, --backgroundColor [backgroundColor]', 'Background color. Example: transparent, red, \'#F0F0F0\'. Optional. Default: white').option('-c, --configFile [config]', 'JSON configuration file for mermaid. Optional').option('-C, --cssFile [cssFile]', 'CSS alternate file for mermaid. Optional').parse(process.argv);
|
20 |
|
21 | let { theme, width, height, input, output, backgroundColor, configFile, cssFile } = commander;
|
22 |
|
23 |
|
24 | if (!input) {
|
25 | error('Please specify input file: -i <input>');
|
26 | }
|
27 | if (!fs.existsSync(input)) {
|
28 | error(`Input file "${input}" doesn't exist`);
|
29 | }
|
30 |
|
31 |
|
32 | if (!output) {
|
33 | output = input + '.svg';
|
34 | }
|
35 | if (!/\.(?:svg|png|pdf)$/.test(output)) {
|
36 | error(`Output file must end with ".svg", ".png" or ".pdf"`);
|
37 | }
|
38 | const outputDir = path.dirname(output);
|
39 | if (!fs.existsSync(outputDir)) {
|
40 | error(`Output directory "${outputDir}/" doesn't exist`);
|
41 | }
|
42 |
|
43 |
|
44 | let mermaidConfig = { theme };
|
45 | if (configFile) {
|
46 | if (!fs.existsSync(configFile)) {
|
47 | error(`Configuration file "${configFile}" doesn't exist`);
|
48 | } else if (!/\.(?:json)$/.test(configFile)) {
|
49 | error(`Config file must end with ".json"`);
|
50 | }
|
51 | mermaidConfig = Object.assign(mermaidConfig, JSON.parse(fs.readFileSync(configFile, 'utf-8')));
|
52 | }
|
53 |
|
54 |
|
55 | let myCSS;
|
56 | if (cssFile) {
|
57 | if (!fs.existsSync(cssFile)) {
|
58 | error(`CSS file "${cssFile}" doesn't exist`);
|
59 | } else if (!/\.(?:css)$/.test(cssFile)) {
|
60 | error(`CSS file must end with ".css"`);
|
61 | }
|
62 | myCSS = fs.readFileSync(cssFile, 'utf-8');
|
63 | }
|
64 |
|
65 |
|
66 | width = parseInt(width);
|
67 | height = parseInt(height);
|
68 | backgroundColor = backgroundColor || 'white';
|
69 |
|
70 | _asyncToGenerator(function* () {
|
71 | const browser = yield puppeteer.launch();
|
72 | const page = yield browser.newPage();
|
73 | page.setViewport({ width, height });
|
74 | yield page.goto(`file://${path.join(__dirname, 'index.html')}`);
|
75 | yield page.evaluate(`document.body.style.background = '${backgroundColor}'`);
|
76 | const definition = fs.readFileSync(input, 'utf-8');
|
77 |
|
78 | yield page.$eval('#container', function (container, definition, mermaidConfig, myCSS) {
|
79 | container.innerHTML = definition;
|
80 | window.mermaid.initialize(mermaidConfig);
|
81 |
|
82 | if (myCSS) {
|
83 | const head = window.document.head || window.document.getElementsByTagName('head')[0];
|
84 | const style = document.createElement('style');
|
85 | style.type = 'text/css';
|
86 | if (style.styleSheet) {
|
87 | style.styleSheet.cssText = myCSS;
|
88 | } else {
|
89 | style.appendChild(document.createTextNode(myCSS));
|
90 | }
|
91 | head.appendChild(style);
|
92 | }
|
93 |
|
94 | window.mermaid.init(undefined, container);
|
95 | }, definition, mermaidConfig, myCSS);
|
96 |
|
97 | if (output.endsWith('svg')) {
|
98 | const svg = yield page.$eval('#container', function (container) {
|
99 | return container.innerHTML;
|
100 | });
|
101 | fs.writeFileSync(output, svg);
|
102 | } else if (output.endsWith('png')) {
|
103 | const clip = yield page.$eval('svg', function (svg) {
|
104 | const react = svg.getBoundingClientRect();
|
105 | return { x: react.left, y: react.top, width: react.width, height: react.height };
|
106 | });
|
107 | yield page.screenshot({ path: output, clip, omitBackground: backgroundColor === 'transparent' });
|
108 | } else {
|
109 |
|
110 | yield page.pdf({ path: output, printBackground: backgroundColor !== 'transparent' });
|
111 | }
|
112 |
|
113 | browser.close();
|
114 | })();
|