jade 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #!/usr/bin/env node
  2. /**
  3. * Module dependencies.
  4. */
  5. var fs = require('fs')
  6. , program = require('commander')
  7. , path = require('path')
  8. , basename = path.basename
  9. , dirname = path.dirname
  10. , resolve = path.resolve
  11. , exists = fs.existsSync || path.existsSync
  12. , join = path.join
  13. , mkdirp = require('mkdirp')
  14. , jade = require('../');
  15. // jade options
  16. var options = {};
  17. // options
  18. program
  19. .version(jade.version)
  20. .usage('[options] [dir|file ...]')
  21. .option('-o, --obj <str>', 'javascript options object')
  22. .option('-O, --out <dir>', 'output the compiled html to <dir>')
  23. .option('-p, --path <path>', 'filename used to resolve includes')
  24. .option('-P, --pretty', 'compile pretty html output')
  25. .option('-c, --client', 'compile function for client-side runtime.js')
  26. .option('-D, --no-debug', 'compile without debugging (smaller functions)')
  27. .option('-w, --watch', 'watch files for changes and automatically re-render')
  28. program.on('--help', function(){
  29. console.log(' Examples:');
  30. console.log('');
  31. console.log(' # translate jade the templates dir');
  32. console.log(' $ jade templates');
  33. console.log('');
  34. console.log(' # create {foo,bar}.html');
  35. console.log(' $ jade {foo,bar}.jade');
  36. console.log('');
  37. console.log(' # jade over stdio');
  38. console.log(' $ jade < my.jade > my.html');
  39. console.log('');
  40. console.log(' # jade over stdio');
  41. console.log(' $ echo "h1 Jade!" | jade');
  42. console.log('');
  43. console.log(' # foo, bar dirs rendering to /tmp');
  44. console.log(' $ jade foo bar --out /tmp ');
  45. console.log('');
  46. });
  47. program.parse(process.argv);
  48. // options given, parse them
  49. if (program.obj) {
  50. if (exists(program.obj)) {
  51. options = JSON.parse(fs.readFileSync(program.obj));
  52. } else {
  53. options = eval('(' + program.obj + ')');
  54. }
  55. }
  56. // --filename
  57. if (program.path) options.filename = program.path;
  58. // --no-debug
  59. options.compileDebug = program.debug;
  60. // --client
  61. options.client = program.client;
  62. // --pretty
  63. options.pretty = program.pretty;
  64. // --watch
  65. options.watch = program.watch;
  66. // left-over args are file paths
  67. var files = program.args;
  68. // compile files
  69. if (files.length) {
  70. console.log();
  71. files.forEach(renderFile);
  72. if (options.watch) {
  73. files.forEach(function (file) {
  74. fs.watchFile(file, {interval: 100}, function (curr, prev) {
  75. if (curr.mtime > prev.mtime) renderFile(file);
  76. });
  77. });
  78. }
  79. process.on('exit', function () {
  80. console.log();
  81. });
  82. // stdio
  83. } else {
  84. stdin();
  85. }
  86. /**
  87. * Compile from stdin.
  88. */
  89. function stdin() {
  90. var buf = '';
  91. process.stdin.setEncoding('utf8');
  92. process.stdin.on('data', function(chunk){ buf += chunk; });
  93. process.stdin.on('end', function(){
  94. var fn = jade.compile(buf, options);
  95. var output = options.client
  96. ? fn.toString()
  97. : fn(options);
  98. process.stdout.write(output);
  99. }).resume();
  100. }
  101. /**
  102. * Process the given path, compiling the jade files found.
  103. * Always walk the subdirectories.
  104. */
  105. function renderFile(path) {
  106. var re = /\.jade$/;
  107. fs.lstat(path, function(err, stat) {
  108. if (err) throw err;
  109. // Found jade file
  110. if (stat.isFile() && re.test(path)) {
  111. fs.readFile(path, 'utf8', function(err, str){
  112. if (err) throw err;
  113. options.filename = path;
  114. var fn = jade.compile(str, options);
  115. var extname = options.client ? '.js' : '.html';
  116. path = path.replace(re, extname);
  117. if (program.out) path = join(program.out, basename(path));
  118. var dir = resolve(dirname(path));
  119. mkdirp(dir, 0755, function(err){
  120. if (err) throw err;
  121. var output = options.client
  122. ? fn.toString()
  123. : fn(options);
  124. fs.writeFile(path, output, function(err){
  125. if (err) throw err;
  126. console.log(' \033[90mrendered \033[36m%s\033[0m', path);
  127. });
  128. });
  129. });
  130. // Found directory
  131. } else if (stat.isDirectory()) {
  132. fs.readdir(path, function(err, files) {
  133. if (err) throw err;
  134. files.map(function(filename) {
  135. return path + '/' + filename;
  136. }).forEach(renderFile);
  137. });
  138. }
  139. });
  140. }