1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
#!/usr/bin/env coffee
#
# ***** BEGIN LICENSE BLOCK *****
# Copyright (c) 2011-2012 VMware, Inc.
#
# For the license see COPYING.
# ***** END LICENSE BLOCK *****
fs = require('fs')
uglify = require('uglify-js')
optimist = require('optimist')
array_flatten = (arr, acc) ->
if typeof acc is 'undefined'
acc = []
if typeof arr is 'string'
acc.push(arr)
return acc
if arr.constructor isnt Array
throw "Value is not an Array nor a String!"
for v in arr
if typeof v is 'string'
acc.push(v)
else if v.constructor is Array
array_flatten(v, acc)
else
throw "Value is not an Array nor a String!"
return acc
stringify_unicode = (str) ->
str = str.replace /[\u0100-\uffff]/g, (ch) ->
return "\\u" + ('0000' + ch.charCodeAt(0).toString(16)).substr(-4)
str = str.replace /[\x00-\x08\x0b-\x1f\x7f-\xff]/g, (ch) ->
return "\\x" + ('00' + ch.charCodeAt(0).toString(16)).substr(-2)
return str
minify = (data, minify_options)->
ast = uglify.parse(data)
compressor = uglify.Compressor()
ast.figure_out_scope()
ast = ast.transform(compressor)
ast.compute_char_frequency()
ast.mangle_names()
ast.print_to_string()
render = (filename, depth, options) ->
tags =
include: (args) ->
if (args.length > 1 and args[1].indexOf('c') isnt -1 and
options.minify is false)
options.comment = true
render(args[0], depth + ' ', options)
version: ->
options.version
include_and_minify: (args) ->
if (args.length > 1 and args[1].indexOf('c') isnt -1 and
options.minify is false)
options.comment = true
d = render(args[0], depth + ' ', options)
if options.minify
return minify(array_flatten(d).join(''), options)
return d
console.warn(depth + " [.] Rendering", filename)
# no trailing whitespace
data = fs.readFileSync(filename, encoding='utf8').replace(/\s+$/, '')
content = []
if options.comment
content.push('\n// ' + depth + '[*] Including ' + filename + '\n')
elements = data.split(/<!--\s*([^>]+)\s*-->/g)
for i in [0...elements.length]
e = elements[i];
if i % 2 is 0
content.push(e)
else
p = e.split(' ')
content.push( tags[p[0]](p.slice(1)) )
if options.comment
content.push('\n// ' + depth + '[*] End of ' + filename + '\n')
return content
main = ->
argv = optimist.options({
'c': {
alias: 'comment',
default: false,
describe: 'Add comments',
},
'm': {
alias: 'minify',
default: true,
describe: 'Minify javascript',
},
'p': {
alias: 'pretty',
default: true,
describe: 'Prettify javascript',
},
's': {
alias: 'set-version',
default: 'unknown',
describe: 'Set the value of version tag',
}})
.boolean('c')
.boolean('m')
.boolean('p')
.string('s')
.argv
options = {comment: argv.comment, minify: argv.minify, pretty: argv.pretty, toplevel: true, version: (argv.s || "unknown")}
filenames = argv._
content = for filename in filenames
render(filename, '', options)
content.push('\n')
process.stdout.write(
stringify_unicode(array_flatten(content).join('')),
'utf8')
main()
|