4 // tmpl function scooped from underscore.
5 // http://documentcloud.github.com/underscore/#template
9 // List of HTML entities for escaping.
16 /*jshint quotmark:false */
22 var escapeKeys = '&<>"\'/';
23 var unescapeKeys = '&|<|>|"|'|/';
25 // Regexes containing the keys and values listed immediately above.
27 escape: new RegExp('[' + escapeKeys + ']', 'g'),
28 unescape: new RegExp('(' + unescapeKeys + ')', 'g')
31 // Functions for escaping and unescaping strings to/from HTML interpolation.
32 ['escape', 'unescape'].forEach(function (method) {
33 _[method] = function (string) {
34 if (string === null || string === undefined) {
38 return ('' + string).replace(entityRegexes[method], function (match) {
39 return entityMap[method][match];
45 evaluate: /<%([\s\S]+?)%>/g,
46 interpolate: /<%=([\s\S]+?)%>/g,
47 escape: /<%-([\s\S]+?)%>/g
52 /*jshint quotmark:false */
62 var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
64 // JavaScript micro-templating, similar to John Resig's implementation.
65 // Underscore templating handles arbitrary delimiters, preserves whitespace,
66 // and correctly escapes quotes within interpolated code.
67 var template = function (text, data) {
70 // Combine delimiters into one regular expression via alternation.
71 var matcher = new RegExp([
72 (settings.escape || noMatch).source,
73 (settings.interpolate || noMatch).source,
74 (settings.evaluate || noMatch).source
75 ].join('|') + '|$', 'g');
77 // Compile the template source, escaping string literals appropriately.
79 var source = "__p+='";
80 text.replace(matcher, function (match, escape, interpolate, evaluate, offset) {
81 source += text.slice(index, offset)
82 .replace(escaper, function (match) {
83 return '\\' + escapes[match];
87 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
90 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
93 source += "';\n" + evaluate + "\n__p+='";
95 index = offset + match.length;
100 // If a variable is not specified, place data values in local scope.
101 if (!settings.variable) {
102 source = 'with(obj||{}){\n' + source + '}\n';
105 source = "var __t,__p='',__j=Array.prototype.join," +
106 "print=function(){__p+=__j.call(arguments,'');};\n" +
107 source + "return __p;\n";
110 /*jshint evil:true */
111 render = new Function(settings.variable || 'obj', '_', source);
118 return render(data, _);
121 var template = function (data) {
122 return render.call(this, data, _);
125 // Provide the compiled function source as a convenience for precompilation.
126 template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';