marked 4.2 KB

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