l0bsterssg

node.js static responsive blog post generator
Log | Files | Refs | README

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 }