/* Ejs parser for Nodejs
*
* Copyright (c) 2009, Howard Rauscher
* Licensed under the MIT License
*/
// PUBLIC METHODS
function parse(input) {
var output = [];
var innerOutput = [];
var isEval = false;
output.push('(function() {\nvar output = [];');
for(var i = 0, len = input.length; i < len; i++) {
var chr = input[i];
if(isEval) {
if(chr === '%' && input[i+1] === '>') {
i++;
isEval = false;
output.push(new EvalString(innerOutput.join('')));
innerOutput = [];
}
else {
innerOutput.push(chr);
}
}
else {
if(chr === '<' && input[i+1] === '%') {
i++;
isEval = true;
output.push(new LiteralString(innerOutput.join('')));
innerOutput = [];
}
else {
innerOutput.push(chr);
}
}
}
if(isEval) {
output.push(new EvalString(innerOutput.join('')));
}
else {
output.push(new LiteralString(innerOutput.join('')));
}
innerOutput = [];
output.push('return output.join(\'\');\n})();');
return output.join('\n');
}
// HELPERS
function escapeString(src) {
return src
.replace(escapeString.ESCAPE, '\\$1')
.replace(escapeString.LINE_FEED, "\\n")
.replace(escapeString.CARRIAGE_RETURN, "\\r");
}
escapeString.ESCAPE = /(["'\\])/g;
escapeString.LINE_FEED = /\n/g;
escapeString.CARRIAGE_RETURN = /\r/g;
// OBJECTS
function LiteralString(value) {
this.value = value;
}
LiteralString.prototype.toString = function() {
return 'output.push("'+escapeString(this.value)+'");';
};
function EvalString(value) {
this.value = value;
this.print = (value[0] === '=');
this.include_trailing_line_feed = (value[value.length - 1] !== '-');
if(this.print) {
this.value = this.value.substring(1);
}
if(!this.include_trailing_line_feed) {
this.value = this.value.substring(0, this.value.length - 1);
}
}
EvalString.prototype.toString = function() {
if(this.print) {
return 'output.push('+this.value+');';
}
else {
return this.value;
}
};
exports.parse = parse;