mirror of
https://github.com/showdownjs/showdown.git
synced 2024-03-22 13:30:55 +08:00
refactor(CLI): refactoring of CLI code
This commit is contained in:
parent
2d6cd1e908
commit
e3521bd8fa
BIN
dist/showdown.js
vendored
BIN
dist/showdown.js
vendored
Binary file not shown.
BIN
dist/showdown.min.js
vendored
BIN
dist/showdown.min.js
vendored
Binary file not shown.
|
@ -1,6 +0,0 @@
|
||||||
module.exports = exports = function errorExit(e) {
|
|
||||||
'use strict';
|
|
||||||
console.error('ERROR: ' + e.message);
|
|
||||||
console.error('Run \'showdown <command> -h\' for help');
|
|
||||||
process.exit(1);
|
|
||||||
};
|
|
|
@ -1,18 +1,20 @@
|
||||||
var yargs = require('yargs'),
|
var yargs = require('yargs'),
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
errorExit = require('./errorexit.js'),
|
Messenger = require('./messenger.js'),
|
||||||
showdown = require('../../dist/showdown');
|
showdown = require('../../dist/showdown'),
|
||||||
|
showdownOptions = showdown.getDefaultOptions(false);
|
||||||
|
|
||||||
yargs.reset()
|
yargs.reset()
|
||||||
.usage('Usage: showdown makehtml [options]')
|
.usage('Usage: showdown makehtml [options]')
|
||||||
.example('showdown makehtml -i', 'Reads from stdin and outputs to stdout')
|
.example('showdown makehtml -i', 'Reads from stdin and outputs to stdout')
|
||||||
.example('showdown makehtml -i foo.md -o bar.html', 'Reads \'foo.md\' and writes to \'bar.html\'')
|
.example('showdown makehtml -i foo.md -o bar.html', 'Reads \'foo.md\' and writes to \'bar.html\'')
|
||||||
|
.example('showdown makehtml -i --flavor="github"', 'Parses stdin using GFM style')
|
||||||
|
.version()
|
||||||
|
.alias('v', 'version')
|
||||||
.config('c')
|
.config('c')
|
||||||
.alias('c', 'config')
|
.alias('c', 'config')
|
||||||
.help('h')
|
.help('h')
|
||||||
.alias('h', 'help')
|
.alias('h', 'help')
|
||||||
.version()
|
|
||||||
.alias('v', 'version')
|
|
||||||
.option('i', {
|
.option('i', {
|
||||||
alias : 'input',
|
alias : 'input',
|
||||||
describe: 'Input source. Usually a md file. If omitted or empty, reads from stdin',
|
describe: 'Input source. Usually a md file. If omitted or empty, reads from stdin',
|
||||||
|
@ -32,7 +34,8 @@ yargs.reset()
|
||||||
.option('a', {
|
.option('a', {
|
||||||
alias : 'append',
|
alias : 'append',
|
||||||
describe: 'Append data to output instead of overwriting',
|
describe: 'Append data to output instead of overwriting',
|
||||||
type: 'string'
|
type: 'string',
|
||||||
|
default: false
|
||||||
})
|
})
|
||||||
.option('e', {
|
.option('e', {
|
||||||
alias : 'extensions',
|
alias : 'extensions',
|
||||||
|
@ -45,87 +48,135 @@ yargs.reset()
|
||||||
type: 'string'
|
type: 'string'
|
||||||
});
|
});
|
||||||
|
|
||||||
yargs.options(showdown.getDefaultOptions(false));
|
// load showdown default options
|
||||||
argv = yargs.argv;
|
for (var opt in showdownOptions) {
|
||||||
|
if (showdownOptions.hasOwnProperty(opt)) {
|
||||||
|
if (showdownOptions[opt].defaultValue === false) {
|
||||||
|
showdownOptions[opt].default = null;
|
||||||
|
} else {
|
||||||
|
showdownOptions[opt].default = showdownOptions[opt].defaultValue;
|
||||||
|
}
|
||||||
|
yargs.option(opt, showdownOptions[opt]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function run() {
|
function run() {
|
||||||
'use strict';
|
'use strict';
|
||||||
var input = '',
|
var argv = yargs.argv,
|
||||||
enc = 'utf8',
|
readMode = (!argv.i || argv.i === '') ? 'stdin' : 'file',
|
||||||
output;
|
writeMode = (!argv.o || argv.o === '') ? 'stdout' : 'file',
|
||||||
|
msgMode = (writeMode === 'file') ? 'stdout' : 'stderr',
|
||||||
if (argv.encoding) {
|
/**
|
||||||
enc = argv.encoding;
|
* MSG object
|
||||||
}
|
* @type {Messenger}
|
||||||
|
*/
|
||||||
// to avoid passing extensions to converter
|
messenger = new Messenger(msgMode),
|
||||||
delete argv.extensions;
|
read = (readMode === 'stdin') ? readFromStdIn : readFromFile,
|
||||||
var converter = new showdown.Converter(argv);
|
write = (writeMode === 'stdout') ? writeToStdOut : writeToFile,
|
||||||
|
enc = argv.encoding || 'utf8',
|
||||||
|
flavor = argv.p,
|
||||||
|
append = argv.a || false,
|
||||||
|
options = parseOptions(flavor),
|
||||||
|
converter = new showdown.Converter(options),
|
||||||
|
md, html;
|
||||||
|
|
||||||
// Load extensions
|
// Load extensions
|
||||||
if (argv.e) {
|
if (argv.e) {
|
||||||
|
messenger.printMsg('Loading extensions');
|
||||||
for (var i = 0; i < argv.e.length; ++i) {
|
for (var i = 0; i < argv.e.length; ++i) {
|
||||||
loadExtension(argv.e[i], converter);
|
try {
|
||||||
|
var ext = require(argv.e[i]);
|
||||||
|
converter.addExtension(ext, argv.e[i]);
|
||||||
|
} catch (e) {
|
||||||
|
messenger.printError('Could not load extension ' + argv.e[i] + '. Reason:');
|
||||||
|
messenger.errorExit(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!argv.i || argv.i === '') {
|
messenger.printMsg('...');
|
||||||
// 'i' is undefined or empty, read from stdin
|
// read the input
|
||||||
|
messenger.printMsg('Reading data from ' + readMode + '...');
|
||||||
|
md = read(enc);
|
||||||
|
|
||||||
|
// process the input
|
||||||
|
messenger.printMsg('Parsing markdown...');
|
||||||
|
html = converter.makeHtml(md);
|
||||||
|
|
||||||
|
// write the output
|
||||||
|
messenger.printMsg('Writing data to ' + writeMode + '...');
|
||||||
|
write(html, append);
|
||||||
|
|
||||||
|
messenger.printMsg('\n');
|
||||||
|
messenger.okExit();
|
||||||
|
|
||||||
|
function parseOptions(flavor) {
|
||||||
|
var options = {},
|
||||||
|
flavorOpts = showdown.getFlavorOptions(flavor) || {};
|
||||||
|
|
||||||
|
// if flavor is not undefined, let's tell the user we're loading that preset
|
||||||
|
if (flavor) {
|
||||||
|
messenger.printMsg('Loading ' + flavor + ' flavor.');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var opt in argv) {
|
||||||
|
if (argv.hasOwnProperty(opt)) {
|
||||||
|
// first we load the default options
|
||||||
|
if (showdownOptions.hasOwnProperty(opt) && showdownOptions[opt].default !== null) {
|
||||||
|
options[opt] = showdownOptions[opt].default;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we now override defaults with flavor, if a flavor was indeed passed
|
||||||
|
if (flavorOpts.hasOwnProperty(opt)) {
|
||||||
|
options[opt] = flavorOpts[opt];
|
||||||
|
}
|
||||||
|
|
||||||
|
// lastly we override with explicit passed options
|
||||||
|
// being careful not to pass CLI specific options, such as -v, -h or --extensions
|
||||||
|
if (showdownOptions.hasOwnProperty(opt)) {
|
||||||
|
if (argv[opt] === true) {
|
||||||
|
messenger.printMsg('Enabling option ' + opt);
|
||||||
|
options[opt] = argv[opt];
|
||||||
|
} else if (argv[opt] === false) {
|
||||||
|
options[opt] = argv[opt];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
function readFromStdIn() {
|
||||||
try {
|
try {
|
||||||
var size = fs.fstatSync(process.stdin.fd).size;
|
var size = fs.fstatSync(process.stdin.fd).size;
|
||||||
input = size > 0 ? fs.readSync(process.stdin.fd, size)[0] : '';
|
return size > 0 ? fs.readSync(process.stdin.fd, size)[0] : '';
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
var err = new Error('Could not read from stdin, reason: ' + e.message);
|
var err = new Error('Could not read from stdin, reason: ' + e.message);
|
||||||
errorExit(err);
|
messenger.errorExit(err);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// 'i' has a value, read from file
|
|
||||||
|
function readFromFile(encoding) {
|
||||||
try {
|
try {
|
||||||
input = fs.readFileSync(argv.i, enc);
|
return fs.readFileSync(argv.i, encoding);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
errorExit(err);
|
messenger.errorExit(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load flavor
|
function writeToStdOut(html) {
|
||||||
if (argv.p) {
|
return process.stdout.write(html);
|
||||||
converter.setFlavor(argv.p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse and convert file
|
function writeToFile(html, append) {
|
||||||
output = converter.makeHtml(input);
|
|
||||||
|
|
||||||
// Write output
|
|
||||||
if (!argv.o || argv.o === '') {
|
|
||||||
// o is undefined or empty, write to stdout
|
|
||||||
process.stdout.write(output);
|
|
||||||
// we won't print anything since it would conspurcate stdout and,
|
|
||||||
// consequently, the outputted file
|
|
||||||
} else {
|
|
||||||
// o is has a value, presumably a file, write to it.
|
|
||||||
|
|
||||||
// If a flag is passed, it means we should append instead of overwriting.
|
// If a flag is passed, it means we should append instead of overwriting.
|
||||||
// Only works with files, obviously
|
// Only works with files, obviously
|
||||||
var write = (argv.a) ? fs.appendFileSync : fs.writeFileSync;
|
var write = (append) ? fs.appendFileSync : fs.writeFileSync;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
write(argv.o, output);
|
write(argv.o, html);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
errorExit(err);
|
messenger.errorExit(err);
|
||||||
}
|
}
|
||||||
console.error('DONE!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadExtension(path, converter) {
|
|
||||||
'use strict';
|
|
||||||
var ext;
|
|
||||||
try {
|
|
||||||
ext = require(path);
|
|
||||||
converter.addExtension(ext, path);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Could not load extension ' + path + '. Reason:');
|
|
||||||
console.error(e.message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
39
src/cli/messenger.js
Normal file
39
src/cli/messenger.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
function Messenger(writeMode, supress, mute) {
|
||||||
|
'use strict';
|
||||||
|
writeMode = writeMode || 'stderr';
|
||||||
|
supress = !!supress;
|
||||||
|
mute = (!!supress || !!mute);
|
||||||
|
this._print = (writeMode === 'stdout') ? console.log : console.error;
|
||||||
|
|
||||||
|
this.errorExit = function (e) {
|
||||||
|
if (!mute) {
|
||||||
|
console.error('ERROR: ' + e.message);
|
||||||
|
console.error('Run \'showdown <command> -h\' for help');
|
||||||
|
}
|
||||||
|
process.exit(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.okExit = function () {
|
||||||
|
if (!mute) {
|
||||||
|
this._print('DONE!');
|
||||||
|
}
|
||||||
|
process.exit(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.printMsg = function (msg) {
|
||||||
|
if (supress || mute || !msg) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._print(msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.printError = function (msg) {
|
||||||
|
if (mute) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.error(msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Messenger;
|
|
@ -1,4 +1,3 @@
|
||||||
/*
|
|
||||||
var semver = require('semver'),
|
var semver = require('semver'),
|
||||||
cmd = 'node bin/showdown.js';
|
cmd = 'node bin/showdown.js';
|
||||||
|
|
||||||
|
@ -15,4 +14,3 @@ describe('showdown cli', function () {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
*/
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user