#!/usr/bin/env node /** * Marked CLI * Copyright (c) 2011-2013, Christopher Jeffrey (MIT License) */ var fs = require('fs'), path = require('path'), marked = require('../'); /** * Man Page */ function help() { var spawn = require('child_process').spawn; var options = { cwd: process.cwd(), env: process.env, setsid: false, stdio: 'inherit' }; spawn('man', [path.resolve(__dirname, '/../man/marked.1')], options) .on('error', function() { fs.readFile(path.resolve(__dirname, '/../man/marked.1.txt'), 'utf8', function(err, data) { if (err) throw err; console.log(data); }); }); } /** * Main */ function main(argv, callback) { var files = [], options = {}, input, output, string, arg, tokens, opt; function getarg() { var arg = argv.shift(); if (arg.indexOf('--') === 0) { // e.g. --opt arg = arg.split('='); if (arg.length > 1) { // e.g. --opt=val argv.unshift(arg.slice(1).join('=')); } arg = arg[0]; } else if (arg[0] === '-') { if (arg.length > 2) { // e.g. -abc argv = arg.substring(1).split('').map(function(ch) { return '-' + ch; }).concat(argv); arg = argv.shift(); } else { // e.g. -a } } else { // e.g. foo } return arg; } while (argv.length) { arg = getarg(); switch (arg) { case '--test': return require('../test').main(process.argv.slice()); case '-o': case '--output': output = argv.shift(); break; case '-i': case '--input': input = argv.shift(); break; case '-s': case '--string': string = argv.shift(); break; case '-t': case '--tokens': tokens = true; break; case '-h': case '--help': return help(); default: if (arg.indexOf('--') === 0) { opt = camelize(arg.replace(/^--(no-)?/, '')); if (!marked.defaults.hasOwnProperty(opt)) { continue; } if (arg.indexOf('--no-') === 0) { options[opt] = typeof marked.defaults[opt] !== 'boolean' ? null : false; } else { options[opt] = typeof marked.defaults[opt] !== 'boolean' ? argv.shift() : true; } } else { files.push(arg); } break; } } function getData(callback) { if (!input) { if (files.length <= 2) { if (string) { return callback(null, string); } return getStdin(callback); } input = files.pop(); } return fs.readFile(input, 'utf8', callback); } return getData(function(err, data) { if (err) return callback(err); data = tokens ? JSON.stringify(marked.lexer(data, options), null, 2) : marked(data, options); if (!output) { process.stdout.write(data + '\n'); return callback(); } return fs.writeFile(output, data, callback); }); } /** * Helpers */ function getStdin(callback) { var stdin = process.stdin, buff = ''; stdin.setEncoding('utf8'); stdin.on('data', function(data) { buff += data; }); stdin.on('error', function(err) { return callback(err); }); stdin.on('end', function() { return callback(null, buff); }); try { stdin.resume(); } catch (e) { callback(e); } } function camelize(text) { return text.replace(/(\w)-(\w)/g, function(_, a, b) { return a + b.toUpperCase(); }); } function handleError(err) { if (err.code === 'ENOENT') { console.error(`marked: output to ${err.path}: No such directory`); return process.exit(1); } throw err; } /** * Expose / Entry Point */ if (!module.parent) { process.title = 'marked'; main(process.argv.slice(), function(err, code) { if (err) return handleError(err); return process.exit(code || 0); }); } else { module.exports = main; }