Fixes #33: Provide custom delimiters to the compiler

This commit is contained in:
hierynomus
2013-03-26 12:51:50 +01:00
parent ffce9032cc
commit 80217949e3
3 changed files with 83 additions and 12 deletions
@@ -60,6 +60,9 @@ public class Mustache
/** The collector used by templates compiled with this compiler. */ /** The collector used by templates compiled with this compiler. */
public final Collector collector; public final Collector collector;
/** The Delimiters used by default int he templates compiled with this compiler. */
public final Delims delims;
/** Compiles the supplied template into a repeatedly executable intermediate form. */ /** Compiles the supplied template into a repeatedly executable intermediate form. */
public Template compile (String template) { public Template compile (String template) {
return compile(new StringReader(template)); return compile(new StringReader(template));
@@ -73,7 +76,7 @@ public class Mustache
/** Returns a compiler that either does or does not escape HTML by default. */ /** Returns a compiler that either does or does not escape HTML by default. */
public Compiler escapeHTML (boolean escapeHTML) { public Compiler escapeHTML (boolean escapeHTML) {
return new Compiler(escapeHTML, this.standardsMode, this.nullValue, this.missingIsNull, return new Compiler(escapeHTML, this.standardsMode, this.nullValue, this.missingIsNull,
this.emptyStringIsFalse, this.loader, this.collector); this.emptyStringIsFalse, this.loader, this.collector, this.delims);
} }
/** Returns a compiler that either does or does not use standards mode. Standards mode /** Returns a compiler that either does or does not use standards mode. Standards mode
@@ -81,7 +84,7 @@ public class Mustache
* context. */ * context. */
public Compiler standardsMode (boolean standardsMode) { public Compiler standardsMode (boolean standardsMode) {
return new Compiler(this.escapeHTML, standardsMode, this.nullValue, this.missingIsNull, return new Compiler(this.escapeHTML, standardsMode, this.nullValue, this.missingIsNull,
this.emptyStringIsFalse, this.loader, this.collector); this.emptyStringIsFalse, this.loader, this.collector, this.delims);
} }
/** Returns a compiler that will use the given value for any variable that is missing, or /** Returns a compiler that will use the given value for any variable that is missing, or
@@ -89,7 +92,7 @@ public class Mustache
* supplied default for missing keys and existing keys that return null values. */ * supplied default for missing keys and existing keys that return null values. */
public Compiler defaultValue (String defaultValue) { public Compiler defaultValue (String defaultValue) {
return new Compiler(this.escapeHTML, this.standardsMode, defaultValue, true, return new Compiler(this.escapeHTML, this.standardsMode, defaultValue, true,
this.emptyStringIsFalse, this.loader, this.collector); this.emptyStringIsFalse, this.loader, this.collector, this.delims);
} }
/** Returns a compiler that will use the given value for any variable that resolves to /** Returns a compiler that will use the given value for any variable that resolves to
@@ -105,25 +108,31 @@ public class Mustache
* </ul> */ * </ul> */
public Compiler nullValue (String nullValue) { public Compiler nullValue (String nullValue) {
return new Compiler(this.escapeHTML, this.standardsMode, nullValue, false, return new Compiler(this.escapeHTML, this.standardsMode, nullValue, false,
this.emptyStringIsFalse, this.loader, this.collector); this.emptyStringIsFalse, this.loader, this.collector, this.delims);
} }
/** Returns a compiler that will treat empty string as a false value if parameter is true. */ /** Returns a compiler that will treat empty string as a false value if parameter is true. */
public Compiler emptyStringIsFalse (boolean emptyStringIsFalse) { public Compiler emptyStringIsFalse (boolean emptyStringIsFalse) {
return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue, return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue,
this.missingIsNull, emptyStringIsFalse, this.loader, this.collector); this.missingIsNull, emptyStringIsFalse, this.loader, this.collector, this.delims);
} }
/** Returns a compiler configured to use the supplied template loader to handle partials. */ /** Returns a compiler configured to use the supplied template loader to handle partials. */
public Compiler withLoader (TemplateLoader loader) { public Compiler withLoader (TemplateLoader loader) {
return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue, return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue,
this.missingIsNull, this.emptyStringIsFalse, loader, this.collector); this.missingIsNull, this.emptyStringIsFalse, loader, this.collector, this.delims);
} }
/** Returns a compiler configured to use the supplied collector. */ /** Returns a compiler configured to use the supplied collector. */
public Compiler withCollector (Collector collector) { public Compiler withCollector (Collector collector) {
return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue, return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue,
this.missingIsNull, this.emptyStringIsFalse, this.loader, collector); this.missingIsNull, this.emptyStringIsFalse, this.loader, collector, this.delims);
}
/** Returns a compiler configured to use the supplied delims as default delimiters. */
public Compiler withDelims (Delims delims) {
return new Compiler(this.escapeHTML, this.standardsMode, this.nullValue,
this.missingIsNull, this.emptyStringIsFalse, this.loader, this.collector, delims);
} }
/** Returns the value to use in the template for the null-valued property {@code name}. See /** Returns the value to use in the template for the null-valued property {@code name}. See
@@ -134,7 +143,7 @@ public class Mustache
protected Compiler (boolean escapeHTML, boolean standardsMode, String nullValue, protected Compiler (boolean escapeHTML, boolean standardsMode, String nullValue,
boolean missingIsNull, boolean emptyStringIsFalse, TemplateLoader loader, boolean missingIsNull, boolean emptyStringIsFalse, TemplateLoader loader,
Collector collector) { Collector collector, Delims delims) {
this.escapeHTML = escapeHTML; this.escapeHTML = escapeHTML;
this.standardsMode = standardsMode; this.standardsMode = standardsMode;
this.nullValue = nullValue; this.nullValue = nullValue;
@@ -142,6 +151,7 @@ public class Mustache
this.emptyStringIsFalse = emptyStringIsFalse; this.emptyStringIsFalse = emptyStringIsFalse;
this.loader = loader; this.loader = loader;
this.collector = collector; this.collector = collector;
this.delims = delims;
} }
} }
@@ -159,7 +169,7 @@ public class Mustache
/** Executes this lambda on the supplied template fragment. The lambda should write its /** Executes this lambda on the supplied template fragment. The lambda should write its
* results to {@code out}. * results to {@code out}.
* *
* @param tmpl the fragment of the template that was passed to the lambda. * @param frag the fragment of the template that was passed to the lambda.
* @param out the writer to which the lambda should write its output. * @param out the writer to which the lambda should write its output.
*/ */
void execute (Template.Fragment frag, Writer out) throws IOException; void execute (Template.Fragment frag, Writer out) throws IOException;
@@ -195,7 +205,7 @@ public class Mustache
*/ */
public static Compiler compiler () public static Compiler compiler ()
{ {
return new Compiler(true, false, null, true, false, FAILING_LOADER, new DefaultCollector()); return new Compiler(true, false, null, true, false, FAILING_LOADER, new DefaultCollector(), new Delims());
} }
/** /**
@@ -238,7 +248,7 @@ public class Mustache
// a hand-rolled parser; whee! // a hand-rolled parser; whee!
protected static class Parser { protected static class Parser {
final Delims delims = new Delims(); final Delims delims;
final StringBuilder text = new StringBuilder(); final StringBuilder text = new StringBuilder();
Reader source; Reader source;
@@ -251,6 +261,7 @@ public class Mustache
public Parser (Compiler compiler) { public Parser (Compiler compiler) {
this.accum = new Accumulator(compiler); this.accum = new Accumulator(compiler);
this.delims = compiler.delims;
} }
public Accumulator parse (Reader source) { public Accumulator parse (Reader source) {
@@ -396,12 +407,28 @@ public class Mustache
protected static class Delims { protected static class Delims {
public char start1 = '{'; public char start1 = '{';
private final char defaultStart1;
public char start2 = '{'; public char start2 = '{';
private final char defaultStart2;
public char end1 = '}'; public char end1 = '}';
private final char defaultEnd1;
public char end2 = '}'; public char end2 = '}';
private final char defaultEnd2;
public Delims () {
this("{{ }}");
}
public Delims (String s) {
updateDelims(s);
defaultStart1 = start1;
defaultStart2 = start2;
defaultEnd1 = end1;
defaultEnd2 = end2;
}
public boolean isDefault () { public boolean isDefault () {
return start1 == '{' && start2 == '{' && end1 == '}' && end2 == '}'; return start1 == defaultStart1 && start2 == defaultStart2 && end1 == defaultEnd1 && end2 == defaultEnd2;
} }
public void updateDelims (String dtext) { public void updateDelims (String dtext) {
@@ -0,0 +1,38 @@
package com.samskivert.mustache;
import org.junit.Test;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
public class DelimsTest {
@Test public void shouldConstructDefaultDelims () {
test(new Mustache.Delims(), '{', '{', '}', '}', true);
}
@Test public void shouldUpdateDefaultDelims () {
Mustache.Delims delims = new Mustache.Delims();
delims.updateDelims("<% %>");
test(delims, '<', '%', '%', '>', false);
}
@Test public void shouldConstructCustomDelims () {
test(new Mustache.Delims("<% %>"), '<', '%', '%', '>', true);
}
@Test public void shouldUpdateCustomConstructedDelims () {
Mustache.Delims delims = new Mustache.Delims("<% %>");
delims.updateDelims("{{ }}");
test(delims, '{', '{', '}', '}', false);
}
protected void test (Mustache.Delims delims, char start1, char start2, char end1, char end2, boolean isDefault)
{
assertThat(delims.start1, equalTo(start1));
assertThat(delims.start2, equalTo(start2));
assertThat(delims.end1, equalTo(end1));
assertThat(delims.end2, equalTo(end2));
assertThat(delims.isDefault(), equalTo(isDefault));
}
}
@@ -516,6 +516,12 @@ public class MustacheTest
})); }));
} }
@Test public void testNonStandardDefaultDelims () {
test(Mustache.compiler().withDelims(new Mustache.Delims("<% %>")), "bar", "<%foo%>", new Object() {
String foo = "bar";
});
}
protected void test (Mustache.Compiler compiler, String expected, String template, Object ctx) protected void test (Mustache.Compiler compiler, String expected, String template, Object ctx)
{ {
assertEquals(expected, compiler.compile(template).execute(ctx)); assertEquals(expected, compiler.compile(template).execute(ctx));