marked (4260B)
1 #!/usr/bin/env node 2 3 /** 4 * Marked CLI 5 * Copyright (c) 2011-2013, Christopher Jeffrey (MIT License) 6 */ 7 8 const fs = require('fs'), 9 path = require('path'), 10 marked = require('../'); 11 12 /** 13 * Man Page 14 */ 15 16 function help() { 17 const spawn = require('child_process').spawn; 18 19 const options = { 20 cwd: process.cwd(), 21 env: process.env, 22 setsid: false, 23 stdio: 'inherit' 24 }; 25 26 spawn('man', [path.resolve(__dirname, '../man/marked.1')], options) 27 .on('error', function() { 28 fs.readFile(path.resolve(__dirname, '../man/marked.1.txt'), 'utf8', function(err, data) { 29 if (err) throw err; 30 console.log(data); 31 }); 32 }); 33 } 34 35 function version() { 36 const pkg = require('../package.json'); 37 console.log(pkg.version); 38 } 39 40 /** 41 * Main 42 */ 43 44 function main(argv, callback) { 45 const files = [], 46 options = {}; 47 let input, 48 output, 49 string, 50 arg, 51 tokens, 52 opt; 53 54 function getarg() { 55 let arg = argv.shift(); 56 57 if (arg.indexOf('--') === 0) { 58 // e.g. --opt 59 arg = arg.split('='); 60 if (arg.length > 1) { 61 // e.g. --opt=val 62 argv.unshift(arg.slice(1).join('=')); 63 } 64 arg = arg[0]; 65 } else if (arg[0] === '-') { 66 if (arg.length > 2) { 67 // e.g. -abc 68 argv = arg.substring(1).split('').map(function(ch) { 69 return '-' + ch; 70 }).concat(argv); 71 arg = argv.shift(); 72 } else { 73 // e.g. -a 74 } 75 } else { 76 // e.g. foo 77 } 78 79 return arg; 80 } 81 82 while (argv.length) { 83 arg = getarg(); 84 switch (arg) { 85 case '--test': 86 return require('../test').main(process.argv.slice()); 87 case '-o': 88 case '--output': 89 output = argv.shift(); 90 break; 91 case '-i': 92 case '--input': 93 input = argv.shift(); 94 break; 95 case '-s': 96 case '--string': 97 string = argv.shift(); 98 break; 99 case '-t': 100 case '--tokens': 101 tokens = true; 102 break; 103 case '-h': 104 case '--help': 105 return help(); 106 case '-v': 107 case '--version': 108 return version(); 109 default: 110 if (arg.indexOf('--') === 0) { 111 opt = camelize(arg.replace(/^--(no-)?/, '')); 112 if (!marked.defaults.hasOwnProperty(opt)) { 113 continue; 114 } 115 if (arg.indexOf('--no-') === 0) { 116 options[opt] = typeof marked.defaults[opt] !== 'boolean' 117 ? null 118 : false; 119 } else { 120 options[opt] = typeof marked.defaults[opt] !== 'boolean' 121 ? argv.shift() 122 : true; 123 } 124 } else { 125 files.push(arg); 126 } 127 break; 128 } 129 } 130 131 function getData(callback) { 132 if (!input) { 133 if (files.length <= 2) { 134 if (string) { 135 return callback(null, string); 136 } 137 return getStdin(callback); 138 } 139 input = files.pop(); 140 } 141 return fs.readFile(input, 'utf8', callback); 142 } 143 144 return getData(function(err, data) { 145 if (err) return callback(err); 146 147 data = tokens 148 ? JSON.stringify(marked.lexer(data, options), null, 2) 149 : marked(data, options); 150 151 if (!output) { 152 process.stdout.write(data + '\n'); 153 return callback(); 154 } 155 156 return fs.writeFile(output, data, callback); 157 }); 158 } 159 160 /** 161 * Helpers 162 */ 163 164 function getStdin(callback) { 165 const stdin = process.stdin; 166 let buff = ''; 167 168 stdin.setEncoding('utf8'); 169 170 stdin.on('data', function(data) { 171 buff += data; 172 }); 173 174 stdin.on('error', function(err) { 175 return callback(err); 176 }); 177 178 stdin.on('end', function() { 179 return callback(null, buff); 180 }); 181 182 try { 183 stdin.resume(); 184 } catch (e) { 185 callback(e); 186 } 187 } 188 189 function camelize(text) { 190 return text.replace(/(\w)-(\w)/g, function(_, a, b) { 191 return a + b.toUpperCase(); 192 }); 193 } 194 195 function handleError(err) { 196 if (err.code === 'ENOENT') { 197 console.error('marked: output to ' + err.path + ': No such directory'); 198 return process.exit(1); 199 } 200 throw err; 201 } 202 203 /** 204 * Expose / Entry Point 205 */ 206 207 if (!module.parent) { 208 process.title = 'marked'; 209 main(process.argv.slice(), function(err, code) { 210 if (err) return handleError(err); 211 return process.exit(code || 0); 212 }); 213 } else { 214 module.exports = main; 215 }