#!/usr/bin/env node var fs = require('fs') ,path = require('path') ,uglify = require('uglify-js') ,cli = require('commander') ,vash = require('../index') function prefix(tplStr, options){ if( options.targetNamespace ){ tplStr = options.targetNamespace + '["' + ( options.propertyName || options.file.replace(/\/|\\/g, options.separator) ) + '"]=' + tplStr; // ensure the simple namespace exists var accum = ''; options.targetNamespace.split('.').reduce(function(all, prop, i){ accum += all + prop + ' = ' + all + prop + ' || {};\n'; all += prop; return all + '.'; }, '') tplStr = accum + tplStr; } return tplStr; } function ugly(tplStr, options){ var ast ,jsp = uglify.parser ,pro = uglify.uglify; if( options.uglify ){ ast = jsp.parse(tplStr); ast = pro.ast_mangle(ast); ast = pro.ast_squeeze(ast); tplStr = pro.gen_code(ast); } return tplStr; } function render(tpl, options){ var model = {}; if( options.render ){ try { model = JSON.parse( options.render ); } catch(e) { try { model = JSON.parse(fs.readFileSync(options.render)); } catch(e) { } } return tpl(model); } return tpl; } function stdin(options){ var buffer = '' process.stdin.resume(); process.stdin.setEncoding('utf8'); process.stdin.on('data', function(chunk){ buffer += chunk; }) process.stdin.on('end', function(){ var tpl = vash[options.helper ? 'compileHelper' : 'compile'](buffer, options.vopts); if( options.render ){ tpl = render(tpl, options); } else { tpl = prefix( options.autolink ? tpl.toClientString() : tpl.toString(), options); tpl = ugly(tpl, options); } process.stdout.write(tpl); }) } function file(filepath, options){ var contents = fs.readFileSync( filepath, 'utf8' ) ,tpl = vash[options.helper ? 'compileHelper' : 'compile'](contents, options.vopts) ,outpath = path.join( options.out ,path.join( path.dirname(filepath) ,path.basename(filepath) + '.js' ).replace(/\/|\\/g, options.separator) ) if( options.render ){ tpl = render(tpl, options); } else { tpl = prefix( options.autolink ? tpl.toClientString() : tpl.toString(), options); tpl = ugly(tpl, options); } if( options.out ) { fs.writeFile( outpath, tpl.toString(), 'utf8', function(err){ if(err){ process.stderr.write( err ) } } ) } else { process.stdout.write(tpl.toString()); } } // TODO: if passed a directory, recursively traverse cli.on('--help', function(){ console.log(' Examples:'); console.log(''); console.log(' $ echo \'

Hello!

\' | vash --json \'{ "debug": false }\' -t myapp.tplcache -p hello'); console.log(''); console.log(' > myapp = myapp || {};'); console.log(' > myapp.tplcache = myapp.tplcache || {};'); console.log(' > myapp.tplcache["hello"]=vash.link( function anonymous(model,html) {'); console.log(' > html.buffer.push(\'

\\n\'); '); console.log(' > return html.buffer.flush(); '); console.log(' > } )'); console.log(''); console.log(' Remember to include vash-runtime.js if precompiling for client-side usage.') console.log(''); }); cli .option('-t, --target-namespace ', 'Assign template to a . Recommended is `vash.helpers.tplcache` for view engine compatibility') .option('-p, --property-name [name]', 'Assign template to property named . Defaults to filename, and requires --target-namespace.') .option('-f, --file ', 'Compile the template in ') .option('-j, --json ', 'Pass options to the Vash compiler. See docs for valid options.') .option('-o, --out ', 'Write template into directory') .option('-u, --uglify', 'Uglify the template, safely') .option('-a, --no-autolink', 'Do not wrap each template in `vash.link`.') //.option('-d, --prepend-runtime', 'Include the required Vash runtime') .option('-r, --render [json]', 'Render the template using as the model. If is not valid json, assume a filename and load those contents as json.') .option('-s, --separator [separator]', 'Templates are auto-named by concatenating the file path with [separator]', '/') .option('--helper', 'Assume the input is a to-be-compiled helper') .option('--helpers ', 'Execute these compiled helpers') .parse(process.argv) if( cli.json ){ cli.vopts = JSON.parse(cli.json); } // helpers via .toClientString, therefore vash.link if( cli.helpers ){ eval(fs.readFileSync(cli.helpers, 'utf8')); } if(cli.file){ cli.file = path.normalize( cli.file ) // assume file input file( cli.file, cli ) } else { // assume stdin stdin( cli ); }