marked 3.6 KB

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