UNPKG

toffee

Version:

A NodeJs and browser-side templating language based on CoffeeScript with slicker tokens and syntax.

599 lines (543 loc) 27.3 kB
// Generated by CoffeeScript 1.12.7 (function() { var TAB_SPACES, coffee, e, errorHandler, errorTypes, getBundleHeaders, getCommonHeaders, getCommonHeadersJs, parser, ref, ref1, spaces, states, tabs, toffeeError, util, utils, view, vm; parser = require('./toffee_lang').parser; ref = require('./errorHandler'), errorHandler = ref.errorHandler, toffeeError = ref.toffeeError, errorTypes = ref.errorTypes; ref1 = require('./consts'), states = ref1.states, TAB_SPACES = ref1.TAB_SPACES; utils = require('./utils'); vm = require('vm'); util = require('util'); try { coffee = require("iced-coffee-script"); } catch (error) { e = error; coffee = require("coffee-script"); } spaces = function(n) { var i; return ((function() { var j, ref2, results; results = []; for (i = j = 0, ref2 = n; 0 <= ref2 ? j < ref2 : j > ref2; i = 0 <= ref2 ? ++j : --j) { results.push(" "); } return results; })()).join(""); }; tabs = function(n) { var i; return ((function() { var j, ref2, results; results = []; for (i = j = 0, ref2 = n; 0 <= ref2 ? j < ref2 : j > ref2; i = 0 <= ref2 ? ++j : --j) { results.push(spaces(TAB_SPACES)); } return results; })()).join(""); }; getCommonHeaders = function(tab_level, include_bundle_headers, auto_escape) { /* each view will use this, or if they're bundled together, it'll only be used once. include_bundle_headers: includes some functions needed for browser use */ var __; __ = tabs(tab_level); return "\n\n" + __ + "if not toffee? then toffee = {}\n" + __ + "if not toffee.templates then toffee.templates = {}\n\n" + __ + "toffee.states = " + (JSON.stringify(states)) + "\n\n" + __ + "toffee.__json = (locals, o, opts) ->\n" + __ + " opts or= {}\n" + __ + " opts.indent or= \"\"\n" + __ + " if not o?\n" + __ + " return \"null\"\n" + __ + " else\n" + __ + " return \"\" + JSON.stringify(o,null,opts.indent)\n" + __ + " .replace(/</g,'\\\\u003C').replace(/>/g,'\\\\u003E')\n" + __ + " .replace(/&/g,'\\\\u0026').replace(/\\u2028/g, '\\\\u2028')\n" + __ + " .replace(/\\u2029/g, '\\\\u2029')\n" + __ + " .replace(/\\u200e/g, '\\\\u200e') # LEFT-TO-RIGHT MARK\n" + __ + " .replace(/\\u200f/g, '\\\\u200f') # RIGHT-TO-LEFT MARK\n" + __ + " .replace(/\\u202a/g, '\\\\u202a') # LEFT-TO-RIGHT EMBEDDING\n" + __ + " .replace(/\\u202b/g, '\\\\u202b') # RIGHT-TO-LEFT EMBEDDING\n" + __ + " .replace(/\\u202c/g, '\\\\u202c') # POP DIRECTIONAL FORMATTING\n" + __ + " .replace(/\\u202d/g, '\\\\u202d') # LEFT-TO-RIGHT OVERRIDE\n" + __ + " .replace(/\\u202e/g, '\\\\u202e') # RIGHT-TO-LEFT OVERRIDE\n" + __ + " .replace(/\\u206a/g, '\\\\u206a') # INHIBIT SYMMETRIC SWAPPING\n" + __ + " .replace(/\\u206b/g, '\\\\u206b') # ACTIVATE SYMMETRIC SWAPPING\n" + __ + " .replace(/\\u206c/g, '\\\\u206c') # INHIBIT ARABIC FORM SHAPING\n" + __ + " .replace(/\\u206d/g, '\\\\u206d') # ACTIVATE ARABIC FORM SHAPING\n" + __ + " .replace(/\\u206e/g, '\\\\u206e') # NATIONAL DIGIT SHAPES\n" + __ + " .replace(/\\u206f/g, '\\\\u206f') # NOMINAL DIGIT SHAPES\n" + __ + " .replace(/\\u2066/g, '\\\\u2066') # LEFT-TO-RIGHT ISOLATE (LRI)\n" + __ + " .replace(/\\u2067/g, '\\\\u2067') # RIGHT-TO-LEFT ISOLATE (RLI)\n" + __ + " .replace(/\\u2068/g, '\\\\u2068') # FIRST STRONG ISOLATE (FSI)\n" + __ + " .replace(/\\u2069/g, '\\\\u2069') # POP DIRECTIONAL ISOLATE (PDI)\n\n\n" + __ + "toffee.__raw = (locals, o) -> o\n\n" + __ + "toffee.__html = (locals, o) ->\n" + __ + " (\"\"+o).replace(/&/g, '&amp;')\n" + __ + " .replace(/</g, '&lt;').replace(/>/g, '&gt;')\n" + __ + " .replace(/\"/g, '&quot;')\n" + __ + " .replace(/\\u200e/g, '') # LEFT-TO-RIGHT MARK\n" + __ + " .replace(/\\u200f/g, '') # RIGHT-TO-LEFT MARK\n" + __ + " .replace(/\\u202a/g, '') # LEFT-TO-RIGHT EMBEDDING\n" + __ + " .replace(/\\u202b/g, '') # RIGHT-TO-LEFT EMBEDDING\n" + __ + " .replace(/\\u202c/g, '') # POP DIRECTIONAL FORMATTING\n" + __ + " .replace(/\\u202d/g, '') # LEFT-TO-RIGHT OVERRIDE\n" + __ + " .replace(/\\u202e/g, '') # RIGHT-TO-LEFT OVERRIDE\n" + __ + " .replace(/\\u206a/g, '') # INHIBIT SYMMETRIC SWAPPING\n" + __ + " .replace(/\\u206b/g, '') # ACTIVATE SYMMETRIC SWAPPING\n" + __ + " .replace(/\\u206c/g, '') # INHIBIT ARABIC FORM SHAPING\n" + __ + " .replace(/\\u206d/g, '') # ACTIVATE ARABIC FORM SHAPING\n" + __ + " .replace(/\\u206e/g, '') # NATIONAL DIGIT SHAPES\n" + __ + " .replace(/\\u206f/g, '') # NOMINAL DIGIT SHAPES\n" + __ + " .replace(/\\u2066/g, '') # LEFT-TO-RIGHT ISOLATE (LRI)\n" + __ + " .replace(/\\u2067/g, '') # RIGHT-TO-LEFT ISOLATE (RLI)\n" + __ + " .replace(/\\u2068/g, '') # FIRST STRONG ISOLATE (FSI)\n" + __ + " .replace(/\\u2069/g, '') # POP DIRECTIONAL ISOLATE (PDI)\n\n\n" + __ + "toffee.__escape = (locals, o) ->\n" + __ + " if locals.__toffee.autoEscape? then ae = locals.__toffee.autoEscape\n" + __ + " else if " + (auto_escape != null) + " then ae = " + auto_escape + "\n" + __ + " else ae = true\n" + __ + " if ae\n" + __ + " if o is undefined then return ''\n" + __ + " if o? and (typeof o) is \"object\" then return locals.json o\n" + __ + " return locals.html o\n" + __ + " return o\n\n" + __ + "toffee.__augmentLocals = (locals, bundle_path) ->\n" + __ + " _l = locals\n" + __ + " _t = _l.__toffee = {out: []}\n" + __ + " if not _l.print? then _l.print = (o) -> toffee.__print _l, o\n" + __ + " if not _l.json? then _l.json = (o, opts) -> toffee.__json _l, o, opts\n" + __ + " if not _l.raw? then _l.raw = (o) -> toffee.__raw _l, o\n" + __ + " if not _l.html? then _l.html = (o) -> toffee.__html _l, o\n" + __ + " if not _l.escape? then _l.escape = (o) -> toffee.__escape _l, o\n" + __ + " if not _l.partial? then _l.partial = (path, vars) -> toffee.__partial toffee.templates[\"\#{bundle_path}\"], _l, path, vars\n" + __ + " if not _l.snippet? then _l.snippet = (path, vars) -> toffee.__snippet toffee.templates[\"\#{bundle_path}\"], _l, path, vars\n" + __ + " if not _l.load? then _l.load = (path, vars) -> toffee.__load toffee.templates[\"\#{bundle_path}\"], _l, path, vars\n" + __ + " _t.print = _l.print\n" + __ + " _t.json = _l.json\n" + __ + " _t.raw = _l.raw\n" + __ + " _t.html = _l.html\n" + __ + " _t.escape = _l.escape\n" + __ + " _t.partial = _l.partial\n" + __ + " _t.snippet = _l.snippet\n" + __ + " _t.load = _l.load\n\n" + (include_bundle_headers ? getBundleHeaders(tab_level) : ""); }; getBundleHeaders = function(tab_level) { /* header stuff only needed when compiling to a JS file */ var __; __ = tabs(tab_level); return "\n\n" + __ + "toffee.__print = (locals, o) ->\n" + __ + " if locals.__toffee.state is toffee.states.COFFEE\n" + __ + " locals.__toffee.out.push o\n" + __ + " return ''\n" + __ + " else\n" + __ + " return \"\#{o}\"\n\n" + __ + "toffee.__normalize = (path) ->\n" + __ + " if (not path?) or path is \"/\"\n" + __ + " return path\n" + __ + " else\n" + __ + " parts = path.split \"/\"\n" + __ + " np = []\n" + __ + " # make sure path always starts with '/'\n" + __ + " if parts[0]\n" + __ + " np.push ''\n" + __ + " for part in parts\n" + __ + " if part is \"..\"\n" + __ + " if np.length > 1\n" + __ + " np.pop()\n" + __ + " else\n" + __ + " np.push part\n" + __ + " else\n" + __ + " if part isnt \".\"\n" + __ + " np.push part\n" + __ + " path = np.join \"/\"\n" + __ + " if not path then path = \"/\"\n" + __ + " return path\n\n" + __ + "toffee.__partial = (parent_tmpl, parent_locals, path, vars) ->\n" + __ + " path = toffee.__normalize parent_tmpl.bundlePath + \"/../\" + path\n" + __ + " return toffee.__inlineInclude path, vars, parent_locals\n\n" + __ + "toffee.__snippet = (parent_tmpl, parent_locals, path, vars) ->\n" + __ + " path = toffee.__normalize parent_tmpl.bundlePath + \"/../\" + path\n" + __ + " vars = if vars? then vars else {}\n" + __ + " vars.__toffee = vars.__toffee or {}\n" + __ + " vars.__toffee.noInheritance = true\n" + __ + " return toffee.__inlineInclude path, vars, parent_locals\n\n" + __ + "toffee.__load = (parent_tmpl, parent_locals, path, vars) ->\n" + __ + " path = toffee.__normalize parent_tmpl.bundlePath + \"/../\" + path\n" + __ + " vars = if vars? then vars else {}\n" + __ + " vars.__toffee = vars.__toffee or {}\n" + __ + " vars.__toffee.repress = true\n" + __ + " return toffee.__inlineInclude path, vars, parent_locals\n\n" + __ + "toffee.__inlineInclude = (path, locals, parent_locals) ->\n" + __ + " options = locals or {}\n" + __ + " options.passback = {}\n" + __ + " options.__toffee = options.__toffee or {}\n" + __ + "\n" + __ + " # we need to make a shallow copy of parent variables\n" + __ + " reserved = {}\n" + __ + " reserved[k] = true for k in [\"passback\", \"load\", \"print\", \"partial\", \"snippet\", \"layout\", \"__toffee\", \"postProcess\"]\n" + __ + " if not options.__toffee.noInheritance\n" + __ + " for k,v of parent_locals when not locals?[k]?\n" + __ + " if not reserved[k]?\n" + __ + " options[k] = v\n" + __ + "\n" + __ + " if not toffee.templates[path]\n" + __ + " return \"Inline toffee include: Could not find \#{path}\"\n" + __ + " else\n" + __ + " res = toffee.templates[path].pub options\n" + __ + " for k,v of options.passback\n" + __ + " parent_locals[k] = v\n" + __ + " return res"; }; getCommonHeadersJs = function(include_bundle_headers, auto_escape) { var ch, js; ch = getCommonHeaders(0, include_bundle_headers, auto_escape); js = coffee.compile(ch, { bare: true }); return js; }; view = (function() { function view(txt, options) { /* important options: cb: if this is set, compilation will happen async and cb will be executed when it's ready */ options = options || {}; this.fileName = options.fileName || options.filename || null; this.bundlePath = options.bundlePath || "/"; this.browserMode = options.browserMode || false; this.verbose = options.verbose || false; this.fsError = options.fsError || false; this.prettyPrintErrors = options.prettyPrintErrors != null ? options.prettyPrintErrors : true; this.prettyLogErrors = options.prettyLogErrors != null ? options.prettyLogErrors : false; this.autoEscape = options.autoEscape != null ? options.autoEscape : false; this.additionalErrorHandler = options.additionalErrorHandler || null; this.txt = txt; this.tokenObj = null; this.coffeeScript = null; this.javaScript = null; this.fun = null; this.error = null; if (options.cb) { this._prepAsync(txt, options.ctx, ((function(_this) { return function() { return options.cb(_this); }; })(this))); } } view.prototype._prepAsync = function(txt, ctx, cb) { /* Only once it's fully compiled does it callback. Defers via setTimeouts in each stage in the compile process for CPU friendliness. This is a lot prettier with iced-coffee-script. */ var v; ctx = ctx || vm.createContext({}); this._log("Prepping " + (this.fileName != null ? this.fileName : 'unknown') + " async."); this._toTokenObj(); v = this; return setTimeout(function() { v.toCoffee(); return setTimeout(function() { v.toJavaScript(); return setTimeout(function() { v._toFun(ctx); v._log("Done async prep of " + (v.fileName != null ? v.fileName : 'unknown') + ". Calling back."); return cb(); }, 0); }, 0); }, 0); }; view.prototype._log = function(o) { var ref2; if (this.verbose) { if ((ref2 = typeof o) === "string" || ref2 === "number" || ref2 === "boolean") { return console.log("toffee: " + o); } else { return console.log("toffee: " + (util.inspect(o))); } } }; view.prototype._cleanTabs = function(obj) { /* replaces tabs with spaces in their coffee regions */ var item, j, len, ref2, ref3, results; if ((ref2 = obj[0]) === "TOFFEE_ZONE" || ref2 === "COFFEE_ZONE") { ref3 = obj[1]; results = []; for (j = 0, len = ref3.length; j < len; j++) { item = ref3[j]; results.push(this._cleanTabs(item)); } return results; } else if (obj[0] === "COFFEE") { return obj[1] = obj[1].replace(/\t/g, tabs(1)); } }; view.prototype.run = function(options, ctx) { /* returns [err, str] */ var fun, j, len, line, pair, ref2, res, txt; ctx = ctx || vm.createContext({}); fun = this._toFun(ctx); res = null; if (!this.error) { try { res = fun(options); } catch (error) { e = error; this.error = new toffeeError(this, errorTypes.RUNTIME, e); } } if (this.error) { if (this.prettyLogErrors) { txt = this.error.getPrettyPrintText(); ref2 = txt.split("\n"); for (j = 0, len = ref2.length; j < len; j++) { line = ref2[j]; console.log("toffee err: " + line); } } if (this.additionalErrorHandler) { this.additionalErrorHandler(this.error.getPrettyPrintText(), this.error.getPrettyPrint(), this.fileName, options); } if (this.prettyPrintErrors) { pair = [null, this.error.getPrettyPrint()]; } else { pair = [this.error.e, null]; } if (this.error.errType === errorTypes.RUNTIME) { this.error = null; } } else { pair = [null, res]; } return pair; }; view.prototype._toTokenObj = function() { /* compiles Toffee to token array */ if (this.tokenObj == null) { try { this.tokenObj = parser.parse(this.txt); } catch (error) { e = error; this.error = new toffeeError(this, errorTypes.PARSER, e); } if (this.error == null) { this._cleanTabs(this.tokenObj); } } return this.tokenObj; }; view.prototype._toFun = function(ctx) { var d, txt; if (this.fun == null) { txt = this.toJavaScript(); if (!this.error) { d = Date.now(); vm.runInContext(txt, ctx); this.fun = ctx['_TMPL_']; this._log(this.fileName + " compiled to scriptObj in " + (Date.now() - d) + "ms"); } } return this.fun; }; view.prototype.toJavaScript = function() { var c, d, opts; if (this.javaScript == null) { c = this.toCoffee(); if (!this.error) { d = Date.now(); try { opts = { bare: true }; if (this.browserMode) { opts.bare = false; } this.javaScript = coffee.compile(c, opts); } catch (error) { e = error; this.error = new toffeeError(this, errorTypes.COFFEE_COMPILE, e); } this._log(this.fileName + " compiled to JavaScript in " + (Date.now() - d) + "ms"); } } return this.javaScript; }; view.prototype.toCoffee = function() { var d, res, tobj; if (this.coffeeScript == null) { tobj = this._toTokenObj(); if (!this.error) { d = Date.now(); res = this._coffeeHeaders(); try { res += this._toCoffeeRecurse(tobj, TAB_SPACES * (1 + this._globalTabLevel()), 0, {})[0]; res += this._coffeeFooters(); this.coffeeScript = res; } catch (error) { e = error; console.log(e); this.error; } this._log(this.fileName + " compiled to CoffeeScript in " + (Date.now() - d) + "ms"); } } return this.coffeeScript; }; view.prototype._printLineNo = function(n, ind) { if ((this.lastLineNo != null) && (n === this.lastLineNo)) { return ""; } else { this.lastLineNo = n; return "\n" + (spaces(ind)) + "_ln " + n; } }; view.prototype._snippetHasEscapeOverride = function(str) { var j, len, ref2, ref3, token; ref2 = ['print', ' snippet', 'load', 'partial', 'raw', 'html', 'json', '__toffee.raw', '__toffee.html', '__toffee.json']; for (j = 0, len = ref2.length; j < len; j++) { token = ref2[j]; if (str.slice(0, token.length) === token) { if ((str.length > token.length) && ((ref3 = str[token.length]) === ' ' || ref3 === '\t' || ref3 === '\n' || ref3 === '(')) { return true; } } } return false; }; view.prototype._snippetIsSoloToken = function(str) { /* if the inside is something like #{ foo } not #{ foo.bar } or other complex thing. */ if (str.match(/^[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*$/)) { return true; } return false; }; view.prototype._toCoffeeRecurse = function(obj, indent_level, indent_baseline, state_carry) { var c, chunk, delta, i, i_delta, ind, interp, item, j, k, l, lbreak, len, len1, len2, len3, line, lineno, lines, m, part, ref2, ref3, ref4, ref5, res, s, t_int, temp_indent_level, zone_baseline; res = ""; i_delta = 0; switch (obj[0]) { case "TOFFEE_ZONE": if (state_carry.last_coffee_ends_with_newline === false) { indent_level += TAB_SPACES; } res += "\n" + (spaces(indent_level)) + "_ts " + states.TOFFEE; ref2 = obj[1]; for (j = 0, len = ref2.length; j < len; j++) { item = ref2[j]; ref3 = this._toCoffeeRecurse(item, indent_level, indent_baseline, state_carry), s = ref3[0], delta = ref3[1]; res += s; } break; case "COFFEE_ZONE": res += "\n" + (spaces(indent_level)) + "_ts " + states.COFFEE; zone_baseline = this._getZoneBaseline(obj[1]); temp_indent_level = indent_level; ref4 = obj[1]; for (k = 0, len1 = ref4.length; k < len1; k++) { item = ref4[k]; ref5 = this._toCoffeeRecurse(item, temp_indent_level, zone_baseline, state_carry), s = ref5[0], delta = ref5[1]; res += s; temp_indent_level = indent_level + delta; } break; case "TOFFEE": ind = indent_level; res += "\n" + (spaces(ind)) + "_ts " + states.TOFFEE; lineno = obj[2]; try { t_int = utils.interpolateString(obj[1]); } catch (error) { e = error; e.relayed_line_range = [lineno, lineno + obj[1].split("\n").length]; this.error = new toffeeError(this, errorTypes.STR_INTERPOLATE, e); throw e; } for (l = 0, len2 = t_int.length; l < len2; l++) { part = t_int[l]; if (part[0] === "TOKENS") { res += this._printLineNo(lineno, ind); interp = part[1].replace(/(^[\n \t]+)|([\n \t]+)$/g, ''); interp = interp.replace(/[\u2028\u2029]/g, '\n'); if (this._snippetIsSoloToken(interp)) { chunk = "\#{if " + interp + "? then escape " + interp + " else ''}"; } else if (this._snippetHasEscapeOverride(interp)) { chunk = "\#{" + interp + "}"; } else { chunk = "\#{escape(" + interp + ")}"; } res += "\n" + (spaces(ind)) + "_to " + (this._quoteStr(chunk)); lineno += part[1].split("\n").length - 1; } else { lines = part[1].split(/[\n\u2028\u2029]/); for (i = m = 0, len3 = lines.length; m < len3; i = ++m) { line = lines[i]; res += this._printLineNo(lineno, ind); lbreak = i !== lines.length - 1 ? "\n" : ""; chunk = this._escapeForStr("" + line + lbreak); if (chunk.length) { res += "\n" + (spaces(ind)) + "_to " + (this._quoteStr(chunk + lbreak)); } if (i < lines.length - 1) { lineno++; } } } } res += this._printLineNo(obj[2] + (obj[1].split('\n').length - 1), ind); res += "\n" + (spaces(ind)) + "_ts " + states.COFFEE; break; case "COFFEE": c = obj[1]; c = c.replace(/[\u2028\u2029]/g, '\n'); res += "\n" + (this._reindent(c, indent_level, indent_baseline)); i_delta = this._getIndentationDelta(c, indent_baseline); state_carry.last_coffee_ends_with_newline = this._doesEndWithNewline(c); break; default: throw "Bad parsing. " + obj + " not handled."; return ["", 0]; } return [res, i_delta]; }; view.prototype._quoteStr = function(s) { /* returns a triple-quoted string, dividing into single quoted start and stops, if the string begins with double quotes, since coffee doesn't want to let us escape those. */ var follow, lead, res; lead = ""; follow = ""; while (s.length && (s[0] === '"')) { s = s.slice(1); lead += '"'; } while (s.length && (s.slice(-1) === '"')) { s = s.slice(0, -1); follow += '"'; } res = ''; if (lead.length) { res += "\'" + lead + "\' + "; } res += '"""' + s + '"""'; if (follow.length) { res += "+ \'" + follow + "\'"; } return res; }; view.prototype._doesEndWithNewline = function(s) { var parts; parts = s.split("\n"); if ((parts.length > 1) && parts[parts.length - 1].match(/^[\t ]*$/)) { return true; } else { return false; } }; view.prototype._escapeForStr = function(s) { /* escapes a string so it can make it into coffeescript triple quotes without losing whitespace, etc. */ s = s.replace(/\\/g, '\\\\'); s = s.replace(/\n/g, '\\n'); s = s.replace(/\t/g, '\\t'); return s; }; view.prototype._getZoneBaseline = function(obj_arr) { var ib, j, len, obj; for (j = 0, len = obj_arr.length; j < len; j++) { obj = obj_arr[j]; if (obj[0] === "COFFEE") { ib = this._getIndentationBaseline(obj[1]); if (ib != null) { return ib; } } } return 0; }; view.prototype._getIndentationBaseline = function(coffee) { var i, j, len, line, lines, res; res = null; lines = coffee.split("\n"); if (lines.length) { for (i = j = 0, len = lines.length; j < len; i = ++j) { line = lines[i]; if ((!line.match(/^[ ]*$/)) || i === (lines.length - 1)) { res = line.match(/[ ]*/)[0].length; break; } } } if (res == null) { res = coffee.length; } return res; }; view.prototype._getIndentationDelta = function(coffee, baseline) { /* given an arbitrarily indented set of coffeescript, returns the delta between the first and last lines, in chars. Ignores leading/trailing whitespace lines If passed a baseline, uses that instead of own. */ var lines, res, y, y_l; if (baseline == null) { baseline = this._getIndentationBaseline(coffee); } if (baseline == null) { res = 0; } else { lines = coffee.split("\n"); if (lines.length < 1) { res = 0; } else { y = lines[lines.length - 1]; y_l = y.match(/[ ]*/)[0].length; res = y_l - baseline; } } return res; }; view.prototype._reindent = function(coffee, indent_level, indent_baseline) { var indent, line, lines, res, rxx, strip; lines = coffee.split('\n'); while (lines.length && lines[0].match(/^[ ]*$/)) { lines = lines.slice(1); } if (!lines.length) { return ''; } rxx = /^[ ]*/; strip = indent_baseline; indent = spaces(indent_level); res = ((function() { var j, len, results; results = []; for (j = 0, len = lines.length; j < len; j++) { line = lines[j]; results.push("" + indent + line.slice(strip)); } return results; })()).join("\n"); return res; }; view.prototype._globalTabLevel = function() { if (this.browserMode) { return 0; } else { return 1; } }; view.prototype._globalTabs = function() { return tabs(this._globalTabLevel()); }; view.prototype._coffeeHeaders = function() { var __, ___; __ = this._globalTabs(); ___ = tabs(1); return (this.browserMode ? '' : '_TMPL_ = (__toffee_run_input) ->' + (getCommonHeaders(1, false, this.autoEscape))) + "\n" + __ + "# browser mode = " + this.browserMode + "\n" + __ + "tmpl = toffee.templates[\"" + this.bundlePath + "\"] =\n" + __ + " bundlePath: \"" + this.bundlePath + "\"\n" + __ + "tmpl.render = tmpl.pub = (__locals) ->\n" + __ + ___ + "__locals = __locals or {}\n" + __ + ___ + "__repress = __locals.__toffee?.repress\n" + __ + ___ + "_to = (x) -> __locals.__toffee.out.push x\n" + __ + ___ + "_ln = (x) -> __locals.__toffee.lineno = x\n" + __ + ___ + "_ts = (x) -> __locals.__toffee.state = x\n" + __ + ___ + "toffee.__augmentLocals __locals, \"" + this.bundlePath + "\"\n\n" + __ + ___ + "`with (__locals) {`\n" + __ + ___ + "__toffee.out = []"; }; view.prototype._coffeeFooters = function() { var __, ___; __ = this._globalTabs(); ___ = tabs(1); return "\n\n" + __ + ___ + "__toffee.res = __toffee.out.join \"\"\n" + __ + ___ + "if postProcess?\n" + __ + ___ + ___ + "__toffee.res = postProcess __toffee.res\n" + __ + ___ + "if (not __repress) then return __toffee.res else return \"\"\n" + __ + "`true; } /* closing JS 'with' */ `\n" + __ + "# sometimes we want to execute the whole thing in a sandbox\n" + __ + "# and just output results\n" + __ + "if __toffee_run_input?\n" + __ + ___ + "return tmpl.pub __toffee_run_input"; }; return view; })(); exports.view = view; exports.getCommonHeaders = getCommonHeaders; exports.getCommonHeadersJs = getCommonHeadersJs; exports.expressCompile = function(txt, options) { var v; v = new view(txt, options); return function(vars) { var res; res = v.run(vars); if (res[0]) { return res[0]; } else { return res[1]; } }; }; }).call(this);