UNPKG

mermaid

Version:

Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.

198 lines (174 loc) 5.52 kB
import fs from 'fs' import chalk from 'chalk' import which from 'which' import parseArgs from 'minimist' import semver from 'semver' import path from 'path' import { exec } from 'child_process' import phantom from 'phantomjs' import pkg from '../package.json' var PHANTOM_VERSION = '^2.1.15' var info = chalk.blue.bold function Cli (options) { this.options = { alias: { help: 'h', png: 'p', outputDir: 'o', outputSuffix: 'O', svg: 's', verbose: 'v', phantomPath: 'e', sequenceConfig: 'c', ganttConfig: 'g', css: 't', width: 'w' }, 'boolean': ['help', 'png', 'svg', 'verbose'], 'string': ['outputDir', 'outputSuffix'] } this.errors = [] this.message = null this.helpMessage = [ info('Usage: mermaid [options] <file>...'), '', 'file The mermaid description file to be rendered', '', 'Options:', ' -s --svg Output SVG instead of PNG (experimental)', ' -p --png If SVG was selected, and you also want PNG, set this flag', ' -o --outputDir Directory to save files, will be created automatically, defaults to `cwd`', " -O --outputSuffix Suffix to output filenames in front of '.svg' or '.png', defaults to ''", ' -e --phantomPath Specify the path to the phantomjs executable', ' -t --css Specify the path to a CSS file to be included when processing output', ' -c --sequenceConfig Specify the path to the file with the configuration to be applied in the sequence diagram', ' -g --ganttConfig Specify the path to the file with the configuration to be applied in the gantt diagram', ' -h --help Show this message', ' -v --verbose Show logging', ' -w --width width of the generated png (number)', ' --version Print version and quit' ] return this } Cli.prototype.parse = function (argv, next) { this.errors = [] // clear errors var options = parseArgs(argv, this.options) if (options.version) { this.message = '' + pkg.version next(null, this.message) } else if (options.help) { this.message = this.helpMessage.join('\n') next(null, this.message) } else { options.files = options._ if (!options.files.length) { this.errors.push(new Error('You must specify at least one source file.')) } // ensure that parameter-expecting options have parameters ;['outputDir', 'outputSuffix', 'phantomPath', 'sequenceConfig', 'ganttConfig', 'css'].forEach(function (i) { if (typeof options[i] !== 'undefined') { if (typeof options[i] !== 'string' || options[i].length < 1) { this.errors.push(new Error(i + ' expects a value.')) } } }.bind(this)) // set svg/png flags appropriately if (options.svg && !options.png) { options.png = false } else { options.png = true } if (options.sequenceConfig) { try { fs.accessSync(options.sequenceConfig, fs.R_OK) } catch (err) { this.errors.push(err) } } else { options.sequenceConfig = null } if (options.ganttConfig) { try { fs.accessSync(options.ganttConfig, fs.R_OK) } catch (err) { this.errors.push(err) } } else { options.ganttConfig = null } if (options.css) { try { fs.accessSync(options.css, fs.R_OK) } catch (err) { this.errors.push(err) } } else { options.css = path.join(__dirname, '..', 'dist', 'mermaid.css') } // set svg/png flags appropriately if (!options.width) { options.width = 1200 } this.checkPhantom = createCheckPhantom(options.phantomPath) this.checkPhantom(function (err, path) { if (err) { this.errors.push(err) } options.phantomPath = path next( this.errors.length > 0 ? this.errors : null , this.message , options ) }.bind(this)) } } function createCheckPhantom (_phantomPath) { var phantomPath = _phantomPath return function checkPhantom (_next) { var next = _next || function () { } var err if (typeof phantomPath === 'undefined') { try { phantomPath = phantom.path } catch (e) { try { phantomPath = which.sync('phantomjs') } catch (e) { if (!phantomPath) { phantomPath = null err = new Error( [ 'Cannot find phantomjs in your PATH. If phantomjs is installed', "you may need to specify its path manually with the '-e' option.", "Run this executable with '--help' or view the README for more", 'details.' ].join('\n') ) next(err) return } } } } // If we have phantompath, see if its version satisfies our requirements exec('"' + phantomPath + '" --version', function (err, stdout, stderr) { if (err) { next(new Error('Could not find phantomjs at the specified path.')) } else if (!semver.satisfies(stdout, PHANTOM_VERSION)) { next(new Error( 'mermaid requires phantomjs ' + PHANTOM_VERSION + ' to be installed, found version ' + stdout )) } else { next(null, phantomPath) } }) } } const cli = (function () { return new Cli() }()) export default cli