Merge branch 'master' of https://github.com/zaach/handlebars.js into zaach-master

This commit is contained in:
wycats
2010-12-27 13:02:20 -08:00
10 changed files with 52 additions and 234 deletions
-1
View File
@@ -7,7 +7,6 @@ Handlebars.Parser = handlebars;
Handlebars.parse = function(string) {
Handlebars.Parser.yy = Handlebars.AST;
Handlebars.Parser.lexer = new Handlebars.HandlebarsLexer();
return Handlebars.Parser.parse(string);
};
-127
View File
@@ -1,127 +0,0 @@
var Handlebars = {};
Handlebars.Lexer = require("handlebars/jison_ext").Lexer;
// BEGIN(BROWSER)
Handlebars.HandlebarsLexer = function() {
this.state = "CONTENT";
};
Handlebars.HandlebarsLexer.prototype = new Handlebars.Lexer();
// The HandlebarsLexer uses a Lexer interface that is compatible
// with Jison.
//
// setupLex reset internal state for a new token
// peek(n) lookahead n characters and return (default 1)
// getchar(n) remove n characters from the input and add
// them to the matched text (default 1)
// readchar(n) remove n characters from the input, but do not
// add them to the matched text (default 1)
// ignorechar(n) remove n characters from the input, and act
// as though they were already matched in a
// previous lex. this will ensure that the
// pointer in the case of parse errors is in
// the right place.
Handlebars.HandlebarsLexer.prototype.lex = function() {
if(this.input === "") { return; }
this.setupLex();
var lookahead = this.peek(2);
var result = '';
var peek;
if(lookahead === "") { return; }
if(this.state == "MUSTACHE") {
if(this.peek() === "/") {
this.getchar();
return "SEP";
}
// chomp optional whitespace
while(this.peek() === " ") { this.ignorechar(); }
lookahead = this.peek(2);
// in a mustache, but less than 2 characters left => error
if(lookahead.length != 2) { return; }
// if the next characters are '}}', the mustache is done
if(lookahead === "}}") {
this.state = "CONTENT";
this.getchar(2);
// handle the case of {{{ foo }}} by always chomping
// a final }. TODO: Track escape state and handle the
// error condition here
if(this.peek() == "}") { this.getchar(); }
return "CLOSE";
// if the next character is a quote => enter a String
} else if(this.peek() === '"') {
this.readchar();
// scan the String until another quote is reached, skipping over escaped quotes
while(this.peek() !== '"') { if(this.peek(2) === '\\"') { this.readchar(); } this.getchar(); }
this.readchar();
return "STRING";
// All other cases are IDs or errors
} else {
// grab alphanumeric characters
while(this.peek().match(/[_0-9A-Za-z\.]/)) { this.getchar(); }
peek = this.peek();
if(peek !== "}" && peek !== " " && peek !== "/") {
return;
}
// if any characters were grabbed => ID
if(this.yytext.length) { return "ID"; }
// Otherwise => Error
else { return; }
}
// Next chars are {{ => Open mustache
} else if(lookahead == "{{") {
this.state = "MUSTACHE";
this.getchar(2);
peek = this.peek();
if(peek === ">") {
this.getchar();
return "OPEN_PARTIAL";
} else if(peek === "#") {
this.getchar();
return "OPEN_BLOCK";
} else if(peek === "/") {
this.getchar();
return "OPEN_ENDBLOCK";
} else if(peek === "^") {
this.getchar();
return "OPEN_INVERSE";
} else if(peek === "{" || peek === "&") {
this.getchar();
return "OPEN_UNESCAPED";
} else if(peek === "!") {
this.readchar();
this.setupLex(); // reset the lexer state so the yytext is the comment only
while(this.peek(2) !== "}}") { this.getchar(); }
this.readchar(2);
this.state = "CONTENT";
return "COMMENT";
} else {
return "OPEN";
}
// Otherwise => content section
} else {
while(this.peek(2) !== "{{" && this.peek(2) !== "") { result = result + this.getchar(); }
return "CONTENT";
}
};
// END(BROWSER)
exports.Lexer = Handlebars.HandlebarsLexer;
-94
View File
@@ -1,94 +0,0 @@
var Handlebars = {};
// BEGIN(BROWSER)
Handlebars.Lexer = function() {};
Handlebars.Lexer.prototype = {
setInput: function(input) {
this.input = input;
this.matched = this.match = '';
this.yylineno = 0;
},
setupLex: function() {
this.yyleng = 0;
this.yytext = '';
this.match = '';
this.readchars = 0;
},
getchar: function(n) {
n = n || 1;
var chars = "", chr = "";
for(var i=0; i<n; i++) {
chr = this.input[0];
chars += chr;
this.yytext += chr;
this.yyleng++;
this.matched += chr;
this.match += chr;
if(chr === "\n") { this.yylineno++; }
this.input = this.input.slice(1);
}
return chr;
},
readchar: function(n, ignore) {
n = n || 1;
var chr;
for(var i=0; i<n; i++) {
chr = this.input[i];
if(chr === "\n") { this.yylineno++; }
this.matched += chr;
this.match += chr;
if(ignore) { this.readchars++; }
}
this.input = this.input.slice(n);
},
ignorechar: function(n) {
this.readchar(n, true);
},
peek: function(n) {
return this.input.slice(0, n || 1);
},
pastInput:function () {
var past = this.matched.substr(0, this.matched.length - this.match.length);
return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
},
upcomingInput:function () {
var next = this.match;
if (next.length < 20) {
next += this.input.substr(0, 20-next.length);
}
return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
},
showPosition:function () {
var pre = this.pastInput();
var c = new Array(pre.length + 1 + this.readchars).join("-");
return pre + this.upcomingInput() + "\n" + c+"^";
}
};
Handlebars.Visitor = function() {};
Handlebars.Visitor.prototype = {
accept: function(object) {
return this[object.type](object);
}
};
// END(BROWSER)
exports.Lexer = Handlebars.Lexer;
exports.Visitor = Handlebars.Visitor;
+1 -1
View File
@@ -1,5 +1,5 @@
var Handlebars = {};
Handlebars.Visitor = require("handlebars/jison_ext").Visitor;
Handlebars.Visitor = require("handlebars/visitor").Visitor;
// BEGIN(BROWSER)
Handlebars.PrintVisitor = function() { this.padding = 0; };
+14
View File
@@ -0,0 +1,14 @@
var Handlebars = {};
// BEGIN(BROWSER)
Handlebars.Visitor = function() {};
Handlebars.Visitor.prototype = {
accept: function(object) {
return this[object.type](object);
}
};
// END(BROWSER)
exports.Visitor = Handlebars.Visitor;