diff --git a/handlebars/src/main/antlr4/com/github/jknack/handlebars/internal/HbsLexer.g4 b/handlebars/src/main/antlr4/com/github/jknack/handlebars/internal/HbsLexer.g4 index bc6727a7b..d8f4feda6 100644 --- a/handlebars/src/main/antlr4/com/github/jknack/handlebars/internal/HbsLexer.g4 +++ b/handlebars/src/main/antlr4/com/github/jknack/handlebars/internal/HbsLexer.g4 @@ -76,6 +76,11 @@ lexer grammar HbsLexer; } private boolean varEscape(final String start, final String end) { + // Support escaping raw expressions (TVar) and normal expressions (VAR) + return consumeVarEscape(start + "{", end + "}") || consumeVarEscape(start, end); + } + + private boolean consumeVarEscape(final String start, final String end) { if (ahead("\\" + start)) { int offset = start.length(); while (!isEOF(offset)) { diff --git a/handlebars/src/test/java/com/github/jknack/handlebars/AbstractTest.java b/handlebars/src/test/java/com/github/jknack/handlebars/AbstractTest.java index 338d233d8..b78a2ed11 100644 --- a/handlebars/src/test/java/com/github/jknack/handlebars/AbstractTest.java +++ b/handlebars/src/test/java/com/github/jknack/handlebars/AbstractTest.java @@ -87,7 +87,7 @@ public void shouldCompileTo(final String template, final Object context, throws IOException { Template t = compile(template, helpers, partials); String result = t.apply(configureContext(context)); - assertEquals("'" + expected + "' should === '" + result + "': " + message, expected, result); + assertEquals("'" + result + "' should === '" + expected + "': " + message, expected, result); } protected Object configureContext(final Object context) { diff --git a/handlebars/src/test/java/com/github/jknack/handlebars/i1084/Issue1084.java b/handlebars/src/test/java/com/github/jknack/handlebars/i1084/Issue1084.java new file mode 100644 index 000000000..97b92bd51 --- /dev/null +++ b/handlebars/src/test/java/com/github/jknack/handlebars/i1084/Issue1084.java @@ -0,0 +1,47 @@ +package com.github.jknack.handlebars.i1084; + +import com.github.jknack.handlebars.AbstractTest; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +public class Issue1084 extends AbstractTest { + + @Test + public void escapeRawVars() throws IOException { + shouldCompileTo("\\{{{foo}}}", $, "{{{foo}}}"); + } + + @Test + public void escapeRawVarsWithText() throws IOException { + shouldCompileTo("before \\{{{foo}}} after", $, "before {{{foo}}} after"); + } + + @Test + public void escapeRawVsUnescape() throws IOException { + shouldCompileTo("\\{{{foo}}} {{{foo}}}", $("foo", "bar"), "{{{foo}}} bar"); + } + + @Test + public void escapeRawMultiline() throws IOException { + shouldCompileTo("\\{{{foo\n}}}", $("foo", "bar"), "{{{foo\n}}}"); + } + + @Test + public void rawBlockEscape() throws IOException { + shouldCompileTo("\\{{{#foo}}}", $("foo", "bar"), "{{{#foo}}}"); + } + + @Test + public void rawBlockEscapeWithParams() throws IOException { + shouldCompileTo("\\{{{#foo x a x}}}", $("foo", "bar"), "{{{#foo x a x}}}"); + } + + @Test + public void escapeRawVarToText() throws IOException { + assertEquals("\\{{{foo}}}", compile("\\{{{foo}}}").text()); + } + +}