UNPKG

2.41 kBJavaScriptView Raw
1#!/usr/bin/env node
2const commander = require('commander')
3const chalk = require('chalk')
4const fs = require('fs')
5const path = require('path')
6const puppeteer = require('puppeteer')
7
8const pkg = require('./package.json')
9
10const error = (message) => {
11 console.log(chalk.red(`\n${message}\n`))
12 process.exit(1)
13}
14
15commander
16 .version(pkg.version)
17 .option('-t, --theme [name]', 'Theme of the chart, could be default, forest, dark or neutral. Optional. Default: default', /^default|forest|dark|neutral$/, 'default')
18 .option('-w, --width [width]', 'Width of the page. Optional. Default: 800', /^\d+$/, '800')
19 .option('-H, --height [height]', 'Height of the page. Optional. Default: 600', /^\d+$/, '600')
20 .option('-i, --input <input>', 'Input mermaid file. Required.')
21 .option('-o, --output [output]', 'Output image file. It should be either svg or png. Optional. Default: input + ".svg"')
22 .parse(process.argv)
23
24let { theme, width, height, input, output } = commander
25
26// check input file
27if (!input) {
28 error('Please specify input file: -i <input>')
29}
30if (!fs.existsSync(input)) {
31 error(`Input file "${input}" doesn't exist`)
32}
33
34// check output file
35if (!output) {
36 output = input + '.svg'
37}
38if (!/\.(?:svg|png)$/.test(output)) {
39 error(`Output file must end with ".svg" or ".png"`)
40}
41const outputDir = path.dirname(output)
42if (!fs.existsSync(outputDir)) {
43 error(`Output directory "${outputDir}/" doesn't exist`)
44}
45
46// normalize args
47width = parseInt(width)
48height = parseInt(height)
49
50;(async () => {
51 const browser = await puppeteer.launch()
52 const page = await browser.newPage()
53 page.setViewport({ width, height })
54 await page.goto(`file://${path.join(__dirname, 'index.html')}`)
55
56 const definition = fs.readFileSync(input, 'utf-8')
57 await page.$eval('#container', (container, definition, theme) => {
58 container.innerHTML = definition
59 window.mermaid_config = { theme }
60 window.mermaid.init(undefined, container)
61 }, definition, theme)
62
63 if (output.endsWith('svg')) {
64 const svg = await page.$eval('#container', container => container.innerHTML)
65 fs.writeFileSync(output, svg)
66 } else { // png
67 const clip = await page.$eval('svg', svg => {
68 const react = svg.getBoundingClientRect()
69 return { x: react.left, y: react.top, width: react.width, height: react.height }
70 })
71 await page.screenshot({ path: output, clip })
72 }
73
74 browser.close()
75})()