170 lines
4.8 KiB
JavaScript
170 lines
4.8 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/*
|
|
* Copyright 2011 Twitter, Inc.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
|
|
// dependencies
|
|
var hogan = require('../lib/hogan.js')
|
|
, path = require('path')
|
|
, nopt = require('nopt')
|
|
, mkderp = require('mkdirp')
|
|
, fs = require('fs');
|
|
|
|
|
|
// locals
|
|
var specials = ['/', '.', '*', '+', '?', '|','(', ')', '[', ']', '{', '}', '\\']
|
|
, specialsRegExp = new RegExp('(\\' + specials.join('|\\') + ')', 'g')
|
|
, options = {
|
|
'namespace': String,
|
|
'outputdir': path,
|
|
'variable': String,
|
|
'wrapper': String,
|
|
'version': true,
|
|
'help': true
|
|
}
|
|
, shortHand = {
|
|
'n': ['--namespace'],
|
|
'o': ['--outputdir'],
|
|
'v': ['--variable'],
|
|
'w': ['--wrapper'],
|
|
'h': ['--help'],
|
|
'v': ['--version']
|
|
}
|
|
, templates;
|
|
|
|
|
|
// options
|
|
options = nopt(options, shortHand);
|
|
|
|
|
|
// escape special regexp characters
|
|
function esc(text) {
|
|
return text.replace(specialsRegExp, '\\$1');
|
|
}
|
|
|
|
|
|
// cyan function for rob
|
|
function cyan(text) {
|
|
return '\033[36m' + text + '\033[39m';
|
|
}
|
|
|
|
|
|
// check for dirs and correct ext (<3 for windows)
|
|
function extractFiles(args) {
|
|
var usage = '\n' +
|
|
cyan('USAGE:') + ' hulk [--wrapper wrapper] [--outputdir outputdir] [--namespace namespace] [--variable variable] FILES\n\n' +
|
|
cyan('OPTIONS:') + ' [-w, --wrapper] :: wraps the template (i.e. amd)\n' +
|
|
' [-o, --outputdir] :: outputs the templates as individual files to a directory\n\n' +
|
|
' [-n, --namespace] :: prepend string to template names\n\n' +
|
|
' [-v, --variable] :: variable name for non-amd wrapper\n\n' +
|
|
cyan('EXAMPLE:') + ' hulk --wrapper amd ./templates/*.mustache\n\n' +
|
|
cyan('NOTE:') + ' hulk supports the "*" wildcard and allows you to target specific extensions too\n',
|
|
files = [];
|
|
|
|
if (options.version) {
|
|
console.log(require('../package.json').version);
|
|
process.exit(0);
|
|
}
|
|
|
|
if (!args.length || options.help) {
|
|
console.log(usage);
|
|
process.exit(0);
|
|
}
|
|
|
|
args.forEach(function (arg) {
|
|
|
|
if (/\*/.test(arg)) {
|
|
arg = arg.split('*');
|
|
return files = files.concat(
|
|
fs.readdirSync(arg[0] || '.')
|
|
.map(function (f) {
|
|
var file = path.join(arg[0], f);
|
|
return new RegExp(esc(arg[1]) + '$').test(f) && fs.statSync(file).isFile() && file;
|
|
})
|
|
.filter(function (f) {
|
|
return f;
|
|
})
|
|
);
|
|
}
|
|
|
|
if (fs.statSync(arg).isFile()) files.push(arg);
|
|
|
|
})
|
|
|
|
return files;
|
|
}
|
|
|
|
|
|
// remove utf-8 byte order mark, http://en.wikipedia.org/wiki/Byte_order_mark
|
|
function removeByteOrderMark(text) {
|
|
if (text.charCodeAt(0) === 0xfeff) {
|
|
return text.substring(1);
|
|
}
|
|
return text;
|
|
}
|
|
|
|
|
|
// wrap templates
|
|
function wrap(file, name, openedFile) {
|
|
switch(options.wrapper) {
|
|
case "amd":
|
|
return 'define('+ (!options.outputdir ? '"' + path.join(path.dirname(file), name) + '", ' : '') + '[ "hogan.js" ], function(Hogan){ return new Hogan.Template(' + hogan.compile(openedFile, { asString: 1 }) + ');});';
|
|
default:
|
|
return (options.variable || 'templates')
|
|
+ '["' + name + '"] = new Hogan.Template('
|
|
+ hogan.compile(openedFile, { asString: 1 })
|
|
+ ');';
|
|
}
|
|
}
|
|
|
|
|
|
// write the directory
|
|
if (options.outputdir) {
|
|
mkderp.sync(options.outputdir);
|
|
}
|
|
|
|
|
|
// Prepend namespace to template name
|
|
function namespace(name) {
|
|
return (options.namespace || '') + name;
|
|
}
|
|
|
|
|
|
// write a template foreach file that matches template extension
|
|
templates = extractFiles(options.argv.remain)
|
|
.map(function (file) {
|
|
var openedFile = fs.readFileSync(file, 'utf-8'), name;
|
|
if (!openedFile) return;
|
|
name = namespace(path.basename(file).replace(/\..*$/, ''));
|
|
openedFile = removeByteOrderMark(openedFile.trim());
|
|
openedFile = wrap(file, name, openedFile);
|
|
if (!options.outputdir) return openedFile;
|
|
var vn = options.variable || 'templates';
|
|
fs.writeFileSync(path.join(options.outputdir, name + '.js')
|
|
, 'if (!!!' + vn + ') var ' + vn + ' = {};\n' + openedFile);
|
|
})
|
|
.filter(function (t) {
|
|
return t;
|
|
});
|
|
|
|
|
|
// output templates
|
|
if (!templates.length || options.outputdir) process.exit(0);
|
|
if (!options.wrapper) {
|
|
var vn = options.variable || 'templates';
|
|
console.log('if (!!!' + vn + ') var ' + vn + ' = {};');
|
|
}
|
|
console.log(templates.join('\n')); |