UNPKG

kiwi

Version:

Simple, modular, fast and lightweight template engine, based on jQuery templates syntax.

144 lines (112 loc) 3.19 kB
/*! * Coolony's Kiwi * Copyright ©2012 Pierre Matri <pierre.matri@coolony.com> * MIT Licensed */ /** * Module dependencies */ // if node var _ = require('underscore'); // end var filter = require('../filter'); var utils = require('../utils'); /** * Constants */ var TAG_REPLACE_RE = /\$\{([^\}]*)\}/g; var TAG_PARSE_RE = /^(?:=|html)\s+(?:\:(\d+)\s+)?([^|]+)(?:\|(.*))?$/; var DEFAULT_VARIABLE_FILTERS = ['escapeIfUnsafe'].map(JSON.stringify); var DEFAULT_HTML_FILTERS = []; /** * Global variables */ module.exports.tags = {}; var variableTag = module.exports.tags['='] = {}; var htmlTag = module.exports.tags['html'] = {}; /** * Basic tag settings */ variableTag.isBlock = false; htmlTag.isBlock = false; /** * Before Processor. * Replace "${…}" to "{{= …}}" in `source`, and invoke * `callback(err, replaced)`. * * @param {String} source * @param {Function} callback * @api private */ variableTag.beforeProcessor = function(source, compiler, callback) { compiler.__print = []; source = source.replace(TAG_REPLACE_RE, function(all, contents) { compiler.__print.push(all); return '{{= :' + compiler.__print.length + ' ' + contents + '}}'; }); callback(null, source); }; /** * Compilers. */ variableTag.compile = createPrintTagCompiler(DEFAULT_VARIABLE_FILTERS); htmlTag.compile = createPrintTagCompiler(DEFAULT_HTML_FILTERS); /** * Create print tag based on `defaultFilters`. * Return `function(token, compiledContents, compiler, callback)`. * * @param {Array} defaultFilters * @return {Function} * @api private */ function createPrintTagCompiler(defaultFilters) { var compiler = function(token, compiledContents, compiler, callback) { var parsed = token.tag.match(TAG_PARSE_RE); if(!parsed) { return callback(new Error('Compilation error: Unable to parse tag `' + token.tag + '`.' )); } // Handle decompiler if(parsed[1]) { var key = parseInt(parsed[1], 10) - 1; token.__originalTag = compiler.__print[key]; } var contents = parsed[2]; var filters; try { filters = parsed[3] ? utils.parseFilters(parsed[3], defaultFilters) : defaultFilters; } catch(err) { return callback(err); } contents = '$tools.filter(' + contents + ', ' + '[' + filters.join(',') + ']' + ')'; var ret; if(!token.options.strict) { ret = 'try {' + 'var __tmp = ' + contents + ';' + '} catch(__err) {' + 'if(__err instanceof ReferenceError) {' + '__tmp = "";' + '} else {' + 'throw __err;' + '}' + '}' + '__acc.push(__tmp);'; } else { ret = '__acc.push(' + contents + ');'; } callback(null, ret); }; compiler.untokenize = function(token, compiler) { return token.__originalTag ? token.__originalTag : ('{{' + token.tag + '}}'); }; return compiler; }