parseTextWithInlineTags: function (str) { var line = this.line(); var match = /(\\)?#\[((?:.|\n)*)$/.exec(str); if (match) { if (match[1]) { // escape var text = new nodes.Text(str.substr(0, match.index) + '#['); text.line = line; var rest = this.parseTextWithInlineTags(match[2]); if (rest[0].type === 'Text') { text.val += rest[0].val; rest.shift(); } return [text].concat(rest); } else { var text = new nodes.Text(str.substr(0, match.index)); text.line = line; var buffer = [text]; var rest = match[2]; var range = parseJSExpression(rest); var inner = new Parser(range.src, this.filename, this.options); buffer.push(inner.parse()); return buffer.concat(this.parseTextWithInlineTags(rest.substr(range.end + 1))); } } else { var text = new nodes.Text(str); text.line = line; return [text]; } },
return attr.replace(/(\\)?#\{(.+)/g, function(_, escape, expr){ if (escape) return _; var range = characterParser.parseMax(expr); if (expr[range.end] !== '}') return _.substr(0, 2) + interpolate(_.substr(2)); self.assertExpression(range.src) return quote + " + (" + range.src + ") + " + quote + interpolate(expr.substr(range.end + 1)); });
bracketExpression: function(skip){ skip = skip || 0; var start = this.input[skip]; if (start != '(' && start != '{' && start != '[') throw new Error('unrecognized start character'); var end = ({'(': ')', '{': '}', '[': ']'})[start]; var range = characterParser.parseMax(this.input, {start: skip + 1}); if (this.input[range.end] !== end) throw new Error('start character ' + start + ' does not match end character ' + this.input[range.end]); return range; },
return attr.replace(/(\\)?#\{(.+)/g, function (_, escape, expr) { if (escape) return _; try { var range = parseJSExpression(expr); if (expr[range.end] !== '}') return _.substr(0, 2) + interpolate(_.substr(2)); return quote + " + (" + range.src + ") + " + quote + interpolate(expr.substr(range.end + 1)); } catch (ex) { return _.substr(0, 2) + interpolate(_.substr(2)); } });
return attr.replace(/(\\)?#\{(.+)/g, function(_, escape, expr){ if (escape) return _; try { var range = characterParser.parseMax(expr); if (expr[range.end] !== '}') return _.substr(0, 2) + recurse(_.substr(2)); assertExpression(range.src) return quote + " + (" + range.src + ") + " + quote + recurse(expr.substr(range.end + 1)); } catch (ex) { return _.substr(0, 2) + recurse(_.substr(2)); } });
function compile(str) { var i = 0; var buf = []; var currentString = ''; var wasString = false; function pushCharacter(c) { if (!wasString) { currentString = ''; buf.push(''); } wasString = true; currentString += c; buf[buf.length - 1] = JSON.stringify(currentString); } function pushExpression(e) { buf.push('(' + e + ')'); wasString = false; } while (i < str.length) { if (exports.shortcutMap.hasOwnProperty(str[i]) && /[a-zA-Z]/.test(str[i + 1]) && (i + 1) < str.length) { var expansion = exports.shortcutMap[str[i]]; var exp = ''; while(/[\w\-]/.test(str[++i]) && i < str.length) exp += str[i]; i--; pushExpression(expansion + ' && ' + expansion + '["' + exp + '"]'); } else if (str[i] === '[') { var section = parser.parseMax(str, {start: i + 1}); var state = parser.defaultState(); var exp = ''; for (var x = 0; x < section.src.length; x++) { if (exports.shortcutMap.hasOwnProperty(section.src[x]) && !state.lineComment && !state.blockComment && !state.singleQuote && !state.doubleQuote && /[a-zA-Z]/.test(section.src[x + 1]) && x + 1 < section.src.length) { exp += '(' + exports.shortcutMap[section.src[x]] + ' && ' + exports.shortcutMap[section.src[x]] + '["'; while(/[\w\-]/.test(section.src[++x]) && x < section.src.length) exp += section.src[x]; x--; exp += '"] || "")'; } else { exp += section.src[x]; } if (x < section.src.length) parser.parseChar(section.src[x], state); } pushExpression(exp); i = section.end; } else if (str[i] === '\\') { pushCharacter(str[++i]); } else { pushCharacter(str[i]); } i++; } return buf.join('+'); }
bracketExpression: function(skip){ skip = skip || 0; var start = this.input[skip]; assert(start === '(' || start === '{' || start === '[', 'The start character should be "(", "{" or "["'); var end = ({'(': ')', '{': '}', '[': ']'})[start]; var range; try { range = characterParser.parseMax(this.input, {start: skip + 1}); } catch (ex) { this.error(ex.message, 'BRACKET_MISMATCH'); } this.assert(this.input[range.end] === end, 'start character "' + start + '" should match end character "' + this.input[range.end] + '"'); return range; },
buffer: function (str, interpolate) { var self = this; if (interpolate) { var match = /(\\)?([#!]){((?:.|\n)*)$/.exec(str); if (match) { this.buffer(str.substr(0, match.index), false); if (match[1]) { // escape this.buffer(match[2] + '{', false); this.buffer(match[3], true); return; } else { try { var rest = match[3]; var range = parseJSExpression(rest); var code = ('!' == match[2] ? '' : 'jade.escape') + "((jade.interp = " + range.src + ") == null ? '' : jade.interp)"; } catch (ex) { throw ex; //didn't match, just as if escaped this.buffer(match[2] + '{', false); this.buffer(match[3], true); return; } this.bufferExpression(code); this.buffer(rest.substr(range.end + 1), true); return; } } } str = JSON.stringify(str); str = str.substr(1, str.length - 2); if (this.lastBufferedIdx == this.buf.length) { if (this.lastBufferedType === 'code') this.lastBuffered += ' + "'; this.lastBufferedType = 'text'; this.lastBuffered += str; this.buf[this.lastBufferedIdx - 1] = 'buf.push(' + this.bufferStartChar + this.lastBuffered + '");' } else { this.buf.push('buf.push("' + str + '");'); this.lastBufferedType = 'text'; this.bufferStartChar = '"'; this.lastBuffered = str; this.lastBufferedIdx = this.buf.length; } },