| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 | #!/usr/bin/env nodevar fs = require('fs'),    path = require('path'),    commander = require('commander'),    async = require('async'),    glob = require('glob'),    mkdirp = require('mkdirp'),    typogr = require('./typogr');function isDirectory(pathString) {  try {    // Query the entry    return fs.statSync(pathString).isDirectory();  }  catch (error) {    // if file doesn't exist, statSync throws an error instead of just returning false    return false;  }}// path.dirname and path.basename don't always work right, so we have to create our own functionsfunction dirname(pathString) {  return pathString.substring(0, pathString.lastIndexOf('/') + 1);}function basename(pathString) {  return pathString.substring(pathString.lastIndexOf('/') + 1);}function readRenderWrite(input, output, force) {  input = path.normalize(input);  output = path.normalize(output);  if(isDirectory(input))    input = input + '/**';  // add glob to get all files under directory  var inputDirectory = dirname(input),      inputGlob = basename(input),      after,      outputString;  // process input  glob(inputGlob, { cwd: inputDirectory }, function (error, files) {    async.eachSeries(files, function (file, eachCallback) {      // only process files; other types such as directories or links are ignored      fs.stat(inputDirectory + '/' + file, function (error, stats) {        if(stats.isFile()) {          // read file          fs.readFile(inputDirectory + '/' + file, 'utf8', function (error, before) {            // process the html            after = typogr.typogrify(before);            // write file            if(output === '/dev/stdout') // writeFile doesn't like /dev/stdout even though readFile works with /dev/stdin              console.log(after);            else {              if(files.length > 1) {                // multiple input files means we are dealing with a directory or a glob,                // so make sure directory exists                mkdirp.sync(output + '/' + dirname(file));                outputString = path.normalize(output + '/' + file);              }              else // one input file means we are only writing one file                outputString = output;              if(force) {                fs.writeFile(outputString, after, function (error) {                  eachCallback(error);                });              }              else {                confirmOverwrite(outputString, function (ok) {                  if(ok)                    fs.writeFile(outputString, after, function (error) {                      eachCallback(error);                    });                });              }            }          });        }        else          eachCallback(null);      });    }, function (error) {      if(error) throw error;    });  });}function confirmOverwrite(fileName, callback) {  fs.stat(fileName, function(error, stats) {    if(stats) {      if(stats.isFile()) {        commander.confirm('Confirm: overwrite file (' + fileName + ')? ', function(ok) {          // work around bug in commander.js           // see (https://github.com/visionmedia/commander.js/issues/109)          // also see (https://github.com/visionmedia/commander.js/pull/133)          process.stdin.pause();          if(ok)            callback(true);          else {            console.log("  Cancelling action, file wasn't modified.");            callback(false);          }        });      }      else {        // fileName is not of type 'file' (close our eyes and assume it's a directory)        callback(true);      }    }    else {      // fileName doesn't exist      callback(true);    }  });}function main() {  // specify cli options  commander    .version('0.6.8')    .usage('[options] [input] [output]')    .option('-i, --inplace', 'Use single path as both input and output')    .option('-f, --force', 'Do not prompt to verify file overwrites');  // specify example help text  commander.on('--help', function() {    console.log('  reads input from stdin, individual files, directories, or globs');    console.log('  writes ouput to stdout, individual files, or directories');    console.log('');    console.log('  Examples:');    console.log('');    console.log('    $ typogr inputFile.html outputFile.html');    console.log('    $ typogr < inputFile.html > outputFile.html');    console.log('    $ typogr -i singleFile.html');    console.log('    $ typogr inputDirectory outputDirectory');    console.log('    $ typogr inputDirectory/*.html outputDirectory');    console.log('');  });  // parse arguments and generate object mappings in the *commander* object  commander.parse(process.argv);  switch (commander.args.length) {    case 0:      // get input from stdin and send output to stdout      readRenderWrite('/dev/stdin', '/dev/stdout');      break;    case 1:      if (commander.inplace) {        // modify the file in place        readRenderWrite(commander.args[0], commander.args[0], commander.force);      }      else {        // get input from file specified and send output to stdout        readRenderWrite(commander.args[0], '/dev/stdout');      }      break;    case 2:      // get input from first parameter and send output to second parameter      readRenderWrite(commander.args[0], commander.args[1], commander.force);      break;  }}module.exports.main = main;
 |