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 | if (configFile) {
|
44 | if (!fs.existsSync(configFile)) {
|
45 | error(`Configuration file "${configFile}" doesn't exist`);
|
46 | } else if (!/\.(?:json)$/.test(configFile)) {
|
47 | error(`Config file must end with ".json"`);
|
48 | }
|
49 | }
|
50 |
|
51 | if (cssFile) {
|
52 | if (!fs.existsSync(cssFile)) {
|
53 | error(`CSS file "${cssFile}" doesn't exist`);
|
54 | } else if (!/\.(?:css)$/.test(cssFile)) {
|
55 | error(`CSS file must end with ".css"`);
|
56 | }
|
57 | }
|
58 |
|
59 |
|
60 | width = parseInt(width);
|
61 | height = parseInt(height);
|
62 | backgroundColor = backgroundColor || 'white';_asyncToGenerator(function* () {
|
63 | const browser = yield puppeteer.launch();
|
64 | const page = yield browser.newPage();
|
65 | page.setViewport({ width, height });
|
66 | yield page.goto(`file://${path.join(__dirname, 'index.html')}`);
|
67 |
|
68 | yield page.evaluate(`document.body.style.background = '${backgroundColor}'`);
|
69 |
|
70 | const definition = fs.readFileSync(input, 'utf-8');
|
71 |
|
72 | var myconfig, myCSS;
|
73 |
|
74 | if (configFile) {
|
75 | myconfig = JSON.parse(fs.readFileSync(configFile, 'utf-8'));
|
76 | }
|
77 |
|
78 | if (cssFile) {
|
79 | myCSS = fs.readFileSync(cssFile, 'utf-8');
|
80 | }
|
81 |
|
82 | yield page.$eval('#container', function (container, definition, theme, myconfig, myCSS) {
|
83 | container.innerHTML = definition;
|
84 | window.mermaid_config = { theme };
|
85 |
|
86 | if (myconfig) {
|
87 |
|
88 | window.mermaid.initialize(myconfig);
|
89 | }
|
90 |
|
91 | if (myCSS) {
|
92 | var head = window.document.head || window.document.getElementsByTagName('head')[0],
|
93 | style = document.createElement('style');
|
94 |
|
95 | style.type = 'text/css';
|
96 | if (style.styleSheet) {
|
97 | style.styleSheet.cssText = myCSS;
|
98 | } else {
|
99 | style.appendChild(document.createTextNode(myCSS));
|
100 | }
|
101 |
|
102 | head.appendChild(style);
|
103 | }
|
104 |
|
105 | window.mermaid.init(undefined, container);
|
106 | }, definition, theme, myconfig, myCSS);
|
107 |
|
108 | if (output.endsWith('svg')) {
|
109 | const svg = yield page.$eval('#container', function (container) {
|
110 | return container.innerHTML;
|
111 | });
|
112 | fs.writeFileSync(output, svg);
|
113 | } else if (output.endsWith('png')) {
|
114 | const clip = yield page.$eval('svg', function (svg) {
|
115 | const react = svg.getBoundingClientRect();
|
116 | return { x: react.left, y: react.top, width: react.width, height: react.height };
|
117 | });
|
118 | yield page.screenshot({ path: output, clip, omitBackground: backgroundColor === 'transparent' });
|
119 | } else {
|
120 |
|
121 | yield page.pdf({ path: output, printBackground: backgroundColor !== 'transparent' });
|
122 | }
|
123 |
|
124 | browser.close();
|
125 | })();
|