swig.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #!/usr/bin/env node
  2. var swig = require('../index')
  3. var optimist = require('optimist')
  4. var fs = require('fs')
  5. var path = require('path')
  6. var filters = require('../lib/filters')
  7. var utils = require('../lib/utils')
  8. var uglify = require('uglify-js')
  9. var command,
  10. wrapstart = 'var tpl = ',
  11. argv = optimist
  12. .usage('\n Usage:\n' +
  13. ' $0 compile [files] [options]\n' +
  14. ' $0 run [files] [options]\n' +
  15. ' $0 render [files] [options]\n'
  16. )
  17. .describe({
  18. v: 'Show the Swig version number.',
  19. o: 'Output location.',
  20. h: 'Show this help screen.',
  21. j: 'Variable context as a JSON file.',
  22. c: 'Variable context as a CommonJS-style file. Used only if option `j` is not provided.',
  23. m: 'Minify compiled functions with uglify-js',
  24. 'filters': 'Custom filters as a CommonJS-style file',
  25. 'tags': 'Custom tags as a CommonJS-style file',
  26. 'options': 'Customize Swig\'s Options from a CommonJS-style file',
  27. 'wrap-start': 'Template wrapper beginning for "compile".',
  28. 'wrap-end': 'Template wrapper end for "compile".',
  29. 'method-name': 'Method name to set template to and run from.'
  30. })
  31. .alias('v', 'version')
  32. .alias('o', 'output')
  33. .default('o', 'stdout')
  34. .alias('h', 'help')
  35. .alias('j', 'json')
  36. .alias('c', 'context')
  37. .alias('m', 'minify')
  38. .default('wrap-start', wrapstart)
  39. .default('wrap-end', ';')
  40. .default('method-name', 'tpl')
  41. .check(function (argv) {
  42. if (argv.v) {
  43. return
  44. }
  45. if (!argv._.length) {
  46. throw new Error('')
  47. }
  48. command = argv._.shift()
  49. if (command !== 'compile' && command !== 'render' && command !== 'run') {
  50. throw new Error('Unrecognized command "' + command + '". Use -h for help.')
  51. }
  52. if (argv['method-name'] !== 'tpl' && argv['wrap-start'] !== wrapstart) {
  53. throw new Error('Cannot use arguments "--method-name" and "--wrap-start" together.')
  54. }
  55. if (argv['method-name'] !== 'tpl') {
  56. argv['wrap-start'] = 'var ' + argv['method-name'] + ' = '
  57. }
  58. })
  59. .argv,
  60. ctx = {},
  61. out = function (file, str) {
  62. console.log(str)
  63. },
  64. efn = function () { },
  65. anonymous,
  66. files,
  67. fn
  68. // What version?
  69. if (argv.v) {
  70. console.log(require('../package').version)
  71. process.exit(0)
  72. }
  73. // Pull in any context data provided
  74. if (argv.j) {
  75. ctx = JSON.parse(fs.readFileSync(argv.j, 'utf8'))
  76. } else if (argv.c) {
  77. ctx = require(argv.c)
  78. }
  79. if (argv.o !== 'stdout') {
  80. argv.o += '/'
  81. argv.o = path.normalize(argv.o)
  82. try {
  83. fs.mkdirSync(argv.o)
  84. } catch (e) {
  85. if (e.code !== 'EEXIST') {
  86. throw e
  87. }
  88. }
  89. out = function (file, str) {
  90. file = path.basename(file)
  91. fs.writeFileSync(argv.o + file, str, { flags: 'w' })
  92. console.log('Wrote', argv.o + file)
  93. }
  94. }
  95. // Set any custom filters
  96. if (argv.filters) {
  97. utils.each(require(path.resolve(argv.filters)), function (filter, name) {
  98. swig.setFilter(name, filter)
  99. })
  100. }
  101. // Set any custom tags
  102. if (argv.tags) {
  103. utils.each(require(path.resolve(argv.tags)), function (tag, name) {
  104. swig.setTag(name, tag.parse, tag.compile, tag.ends, tag.block)
  105. })
  106. }
  107. // Specify swig default options
  108. if (argv.options) {
  109. swig.setDefaults(require(argv.options))
  110. }
  111. switch (command) {
  112. case 'compile':
  113. fn = function (file, str) {
  114. var r = swig.precompile(str, { filename: file, locals: ctx }).tpl.toString().replace('anonymous', '')
  115. r = argv['wrap-start'] + r + argv['wrap-end']
  116. if (argv.m) {
  117. r = uglify.minify(r, { fromString: true }).code
  118. }
  119. out(file, r)
  120. }
  121. break
  122. case 'run':
  123. fn = function (file, str) {
  124. (function () {
  125. eval(str)
  126. var __tpl = eval(argv['method-name'])
  127. out(file, __tpl(swig, ctx, filters, utils, efn))
  128. }())
  129. }
  130. break
  131. case 'render':
  132. fn = function (file, str) {
  133. out(file, swig.render(str, { filename: file, locals: ctx }))
  134. }
  135. break
  136. }
  137. argv._.forEach(function (file) {
  138. var str = fs.readFileSync(file, 'utf8')
  139. fn(file, str)
  140. })