summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYehuda Katz <tomhuda@Yehudas-iMac.local>2011-12-27 17:04:59 -0800
committerYehuda Katz <tomhuda@Yehudas-iMac.local>2011-12-27 17:04:59 -0800
commitc79c761460f7d08e3862c0c9992f65a799771851 (patch)
treeeb2c1d67bdf7f37ea235e9e83620fc02a168a0c6
parente474e56b804d55d294d7bd1ae6c37c4bc57eb1f0 (diff)
downloadhandlebars.js-c79c761460f7d08e3862c0c9992f65a799771851.zip
handlebars.js-c79c761460f7d08e3862c0c9992f65a799771851.tar.gz
handlebars.js-c79c761460f7d08e3862c0c9992f65a799771851.tar.bz2
Add support for escaping mustaches
-rw-r--r--spec/tokenizer_spec.rb14
-rw-r--r--src/handlebars.l17
2 files changed, 26 insertions, 5 deletions
diff --git a/spec/tokenizer_spec.rb b/spec/tokenizer_spec.rb
index 17af70c..a8bb94d 100644
--- a/spec/tokenizer_spec.rb
+++ b/spec/tokenizer_spec.rb
@@ -44,6 +44,20 @@ describe "Tokenizer" do
result[1].should be_token("ID", "foo")
end
+ it "supports escaping delimiters" do
+ result = tokenize("{{foo}} \\{{bar}} {{baz}}")
+ result.should match_tokens(%w(OPEN ID CLOSE CONTENT CONTENT OPEN ID CLOSE))
+
+ result[4].should be_token("CONTENT", "{{bar}} ")
+ end
+
+ it "supports escaping a triple stash" do
+ result = tokenize("{{foo}} \\{{{bar}}} {{baz}}")
+ result.should match_tokens(%w(OPEN ID CLOSE CONTENT CONTENT OPEN ID CLOSE))
+
+ result[4].should be_token("CONTENT", "{{{bar}}} ")
+ end
+
it "tokenizes a simple path" do
result = tokenize("{{foo/bar}}")
result.should match_tokens(%w(OPEN ID SEP ID CLOSE))
diff --git a/src/handlebars.l b/src/handlebars.l
index dd92cbf..e47c5b1 100644
--- a/src/handlebars.l
+++ b/src/handlebars.l
@@ -1,11 +1,18 @@
-%x mu
+%x mu emu
%%
-[^\x00]*?/("{{") { this.begin("mu"); if (yytext) return 'CONTENT'; }
+[^\x00]*?/("{{") {
+ if(yytext.slice(-1) !== "\\") this.begin("mu");
+ if(yytext.slice(-1) === "\\") yytext = yytext.substr(0,yyleng-1), this.begin("emu");
+ if(yytext) return 'CONTENT';
+ }
+
[^\x00]+ { return 'CONTENT'; }
+<emu>[^\x00]{2,}?/("{{") { this.popState(); return 'CONTENT'; }
+
<mu>"{{>" { return 'OPEN_PARTIAL'; }
<mu>"{{#" { return 'OPEN_BLOCK'; }
<mu>"{{/" { return 'OPEN_ENDBLOCK'; }
@@ -13,7 +20,7 @@
<mu>"{{"\s*"else" { return 'OPEN_INVERSE'; }
<mu>"{{{" { return 'OPEN_UNESCAPED'; }
<mu>"{{&" { return 'OPEN_UNESCAPED'; }
-<mu>"{{!"[\s\S]*?"}}" { yytext = yytext.substr(3,yyleng-5); this.begin("INITIAL"); return 'COMMENT'; }
+<mu>"{{!"[\s\S]*?"}}" { yytext = yytext.substr(3,yyleng-5); this.popState(); return 'COMMENT'; }
<mu>"{{" { return 'OPEN'; }
<mu>"=" { return 'EQUALS'; }
@@ -21,8 +28,8 @@
<mu>".." { return 'ID'; }
<mu>[\/.] { return 'SEP'; }
<mu>\s+ { /*ignore whitespace*/ }
-<mu>"}}}" { this.begin("INITIAL"); return 'CLOSE'; }
-<mu>"}}" { this.begin("INITIAL"); return 'CLOSE'; }
+<mu>"}}}" { this.popState(); return 'CLOSE'; }
+<mu>"}}" { this.popState(); return 'CLOSE'; }
<mu>'"'("\\"["]|[^"])*'"' { yytext = yytext.substr(1,yyleng-2).replace(/\\"/g,'"'); return 'STRING'; }
<mu>"true"/[}\s] { return 'BOOLEAN'; }
<mu>"false"/[}\s] { return 'BOOLEAN'; }