You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2015/10/04 21:17:05 UTC
[01/16] incubator-freemarker git commit: (Test class name typo...)
Repository: incubator-freemarker
Updated Branches:
refs/heads/2.3 4b1550e78 -> d07ad04ce
(Test class name typo...)
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/0c3e1461
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/0c3e1461
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/0c3e1461
Branch: refs/heads/2.3
Commit: 0c3e1461f937fa0115dd70a92c13ad1a0bd0e317
Parents: c798862
Author: ddekany <dd...@apache.org>
Authored: Tue Sep 29 02:23:05 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Tue Sep 29 02:23:05 2015 +0200
----------------------------------------------------------------------
.../freemarker/core/CoercionToTextualTest.java | 119 +++++++++++++++++++
.../freemarker/core/CorectionToTextualTest.java | 119 -------------------
2 files changed, 119 insertions(+), 119 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c3e1461/src/test/java/freemarker/core/CoercionToTextualTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/CoercionToTextualTest.java b/src/test/java/freemarker/core/CoercionToTextualTest.java
new file mode 100644
index 0000000..c35ace6
--- /dev/null
+++ b/src/test/java/freemarker/core/CoercionToTextualTest.java
@@ -0,0 +1,119 @@
+package freemarker.core;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Date;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import freemarker.template.Configuration;
+import freemarker.template.SimpleDate;
+import freemarker.template.TemplateDateModel;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateModelException;
+import freemarker.test.TemplateTest;
+
+@SuppressWarnings("boxing")
+public class CoercionToTextualTest extends TemplateTest {
+
+ /** 2015-09-06T12:00:00Z */
+ private static long T = 1441540800000L;
+ private static TemplateDateModel TM = new SimpleDate(new Date(T), TemplateDateModel.DATETIME);
+
+ @Test
+ public void testBasicStringBuiltins() throws IOException, TemplateException {
+ assertOutput("${s?upperCase}", "ABC");
+ assertOutput("${n?string?lowerCase}", "1.50e+03");
+ assertErrorContains("${n?lowerCase}", "convert", "string", "markup", "text/html");
+ assertOutput("${dt?string?lowerCase}", "2015-09-06t12:00:00z");
+ assertErrorContains("${dt?lowerCase}", "convert", "string", "markup", "text/html");
+ assertOutput("${b?upperCase}", "Y");
+ assertErrorContains("${m?upperCase}", "convertible to string", "HTMLOutputModel");
+ }
+
+ @Test
+ public void testEscBuiltin() throws IOException, TemplateException {
+ Configuration cfg = getConfiguration();
+ cfg.setOutputFormat(HTMLOutputFormat.INSTANCE);
+ cfg.setAutoEscapingPolicy(Configuration.DISABLE_AUTO_ESCAPING_POLICY);
+ cfg.setBooleanFormat("<y>,<n>");
+
+ assertOutput("${'a<b'?esc}", "a<b");
+ assertOutput("${n?string?esc}", "1.50E+03");
+ assertOutput("${n?esc}", "1.50*10<sup>3</sup>");
+ assertOutput("${dt?string?esc}", "2015-09-06T12:00:00Z");
+ assertOutput("${dt?esc}", "2015-09-06<span class='T'>T</span>12:00:00Z");
+ assertOutput("${b?esc}", "<y>");
+ assertOutput("${m?esc}", "<p>M</p>");
+ }
+
+ @Test
+ public void testStringOverloadedBuiltIns() throws IOException, TemplateException {
+ assertOutput("${s?contains('b')}", "y");
+ assertOutput("${n?string?contains('E')}", "y");
+ assertErrorContains("${n?contains('E')}", "convert", "string", "markup", "text/html");
+ assertErrorContains("${n?indexOf('E')}", "convert", "string", "markup", "text/html");
+ assertOutput("${dt?string?contains('0')}", "y");
+ assertErrorContains("${dt?contains('0')}", "convert", "string", "markup", "text/html");
+ assertErrorContains("${m?contains('0')}", "convertible to string", "HTMLOutputModel");
+ assertErrorContains("${m?indexOf('0')}", "convertible to string", "HTMLOutputModel");
+ }
+
+ @Test
+ public void testMarkupStringBuiltIns() throws IOException, TemplateException {
+ assertErrorContains("${n?string?markupString}", "Expected", "markup", "string");
+ assertErrorContains("${n?markupString}", "Expected", "markup", "number");
+ assertErrorContains("${dt?markupString}", "Expected", "markup", "date");
+ }
+
+ @Test
+ public void testSimpleInterpolation() throws IOException, TemplateException {
+ assertOutput("${s}", "abc");
+ assertOutput("${n?string}", "1.50E+03");
+ assertOutput("${n}", "1.50*10<sup>3</sup>");
+ assertOutput("${dt?string}", "2015-09-06T12:00:00Z");
+ assertOutput("${dt}", "2015-09-06<span class='T'>T</span>12:00:00Z");
+ assertOutput("${b}", "y");
+ assertOutput("${m}", "<p>M</p>");
+ }
+
+ @Test
+ public void testConcatenation() throws IOException, TemplateException {
+ assertOutput("${s + '&'}", "abc&");
+ assertOutput("${n?string + '&'}", "1.50E+03&");
+ assertOutput("${n + '&'}", "1.50*10<sup>3</sup>&");
+ assertOutput("${dt?string + '&'}", "2015-09-06T12:00:00Z&");
+ assertOutput("${dt + '&'}", "2015-09-06<span class='T'>T</span>12:00:00Z&");
+ assertOutput("${b + '&'}", "y&");
+ assertOutput("${m + '&'}", "<p>M</p>&");
+ }
+
+ @Test
+ public void testConcatenation2() throws IOException, TemplateException {
+ assertOutput("${'&' + s}", "&abc");
+ assertOutput("${'&' + n?string}", "&1.50E+03");
+ assertOutput("${'&' + n}", "&1.50*10<sup>3</sup>");
+ assertOutput("${'&' + dt?string}", "&2015-09-06T12:00:00Z");
+ assertOutput("${'&' + dt}", "&2015-09-06<span class='T'>T</span>12:00:00Z");
+ assertOutput("${'&' + b}", "&y");
+ assertOutput("${'&' + m}", "&<p>M</p>");
+ }
+
+ @Before
+ public void setup() throws TemplateModelException {
+ Configuration cfg = getConfiguration();
+ cfg.setCustomNumberFormats(Collections.singletonMap("G", PrintfGTemplateNumberFormatFactory.INSTANCE));
+ cfg.setCustomDateFormats(Collections.singletonMap("HI", HTMLISOTemplateDateFormatFactory.INSTANCE));
+ cfg.setNumberFormat("@G 3");
+ cfg.setDateTimeFormat("@HI");
+ cfg.setBooleanFormat("y,n");
+
+ addToDataModel("s", "abc");
+ addToDataModel("n", 1500);
+ addToDataModel("dt", TM);
+ addToDataModel("b", Boolean.TRUE);
+ addToDataModel("m", HTMLOutputFormat.INSTANCE.fromMarkup("<p>M</p>"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0c3e1461/src/test/java/freemarker/core/CorectionToTextualTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/CorectionToTextualTest.java b/src/test/java/freemarker/core/CorectionToTextualTest.java
deleted file mode 100644
index 968981a..0000000
--- a/src/test/java/freemarker/core/CorectionToTextualTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package freemarker.core;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Date;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import freemarker.template.Configuration;
-import freemarker.template.SimpleDate;
-import freemarker.template.TemplateDateModel;
-import freemarker.template.TemplateException;
-import freemarker.template.TemplateModelException;
-import freemarker.test.TemplateTest;
-
-@SuppressWarnings("boxing")
-public class CorectionToTextualTest extends TemplateTest {
-
- /** 2015-09-06T12:00:00Z */
- private static long T = 1441540800000L;
- private static TemplateDateModel TM = new SimpleDate(new Date(T), TemplateDateModel.DATETIME);
-
- @Test
- public void testBasicStringBuiltins() throws IOException, TemplateException {
- assertOutput("${s?upperCase}", "ABC");
- assertOutput("${n?string?lowerCase}", "1.50e+03");
- assertErrorContains("${n?lowerCase}", "convert", "string", "markup", "text/html");
- assertOutput("${dt?string?lowerCase}", "2015-09-06t12:00:00z");
- assertErrorContains("${dt?lowerCase}", "convert", "string", "markup", "text/html");
- assertOutput("${b?upperCase}", "Y");
- assertErrorContains("${m?upperCase}", "convertible to string", "HTMLOutputModel");
- }
-
- @Test
- public void testEscBuiltin() throws IOException, TemplateException {
- Configuration cfg = getConfiguration();
- cfg.setOutputFormat(HTMLOutputFormat.INSTANCE);
- cfg.setAutoEscapingPolicy(Configuration.DISABLE_AUTO_ESCAPING_POLICY);
- cfg.setBooleanFormat("<y>,<n>");
-
- assertOutput("${'a<b'?esc}", "a<b");
- assertOutput("${n?string?esc}", "1.50E+03");
- assertOutput("${n?esc}", "1.50*10<sup>3</sup>");
- assertOutput("${dt?string?esc}", "2015-09-06T12:00:00Z");
- assertOutput("${dt?esc}", "2015-09-06<span class='T'>T</span>12:00:00Z");
- assertOutput("${b?esc}", "<y>");
- assertOutput("${m?esc}", "<p>M</p>");
- }
-
- @Test
- public void testStringOverloadedBuiltIns() throws IOException, TemplateException {
- assertOutput("${s?contains('b')}", "y");
- assertOutput("${n?string?contains('E')}", "y");
- assertErrorContains("${n?contains('E')}", "convert", "string", "markup", "text/html");
- assertErrorContains("${n?indexOf('E')}", "convert", "string", "markup", "text/html");
- assertOutput("${dt?string?contains('0')}", "y");
- assertErrorContains("${dt?contains('0')}", "convert", "string", "markup", "text/html");
- assertErrorContains("${m?contains('0')}", "convertible to string", "HTMLOutputModel");
- assertErrorContains("${m?indexOf('0')}", "convertible to string", "HTMLOutputModel");
- }
-
- @Test
- public void testMarkupStringBuiltIns() throws IOException, TemplateException {
- assertErrorContains("${n?string?markupString}", "Expected", "markup", "string");
- assertErrorContains("${n?markupString}", "Expected", "markup", "number");
- assertErrorContains("${dt?markupString}", "Expected", "markup", "date");
- }
-
- @Test
- public void testSimpleInterpolation() throws IOException, TemplateException {
- assertOutput("${s}", "abc");
- assertOutput("${n?string}", "1.50E+03");
- assertOutput("${n}", "1.50*10<sup>3</sup>");
- assertOutput("${dt?string}", "2015-09-06T12:00:00Z");
- assertOutput("${dt}", "2015-09-06<span class='T'>T</span>12:00:00Z");
- assertOutput("${b}", "y");
- assertOutput("${m}", "<p>M</p>");
- }
-
- @Test
- public void testConcatenation() throws IOException, TemplateException {
- assertOutput("${s + '&'}", "abc&");
- assertOutput("${n?string + '&'}", "1.50E+03&");
- assertOutput("${n + '&'}", "1.50*10<sup>3</sup>&");
- assertOutput("${dt?string + '&'}", "2015-09-06T12:00:00Z&");
- assertOutput("${dt + '&'}", "2015-09-06<span class='T'>T</span>12:00:00Z&");
- assertOutput("${b + '&'}", "y&");
- assertOutput("${m + '&'}", "<p>M</p>&");
- }
-
- @Test
- public void testConcatenation2() throws IOException, TemplateException {
- assertOutput("${'&' + s}", "&abc");
- assertOutput("${'&' + n?string}", "&1.50E+03");
- assertOutput("${'&' + n}", "&1.50*10<sup>3</sup>");
- assertOutput("${'&' + dt?string}", "&2015-09-06T12:00:00Z");
- assertOutput("${'&' + dt}", "&2015-09-06<span class='T'>T</span>12:00:00Z");
- assertOutput("${'&' + b}", "&y");
- assertOutput("${'&' + m}", "&<p>M</p>");
- }
-
- @Before
- public void setup() throws TemplateModelException {
- Configuration cfg = getConfiguration();
- cfg.setCustomNumberFormats(Collections.singletonMap("G", PrintfGTemplateNumberFormatFactory.INSTANCE));
- cfg.setCustomDateFormats(Collections.singletonMap("HI", HTMLISOTemplateDateFormatFactory.INSTANCE));
- cfg.setNumberFormat("@G 3");
- cfg.setDateTimeFormat("@HI");
- cfg.setBooleanFormat("y,n");
-
- addToDataModel("s", "abc");
- addToDataModel("n", 1500);
- addToDataModel("dt", TM);
- addToDataModel("b", Boolean.TRUE);
- addToDataModel("m", HTMLOutputFormat.INSTANCE.fromMarkup("<p>M</p>"));
- }
-
-}
[02/16] incubator-freemarker git commit: Documented that JDK 8 is
needed for building.
Posted by dd...@apache.org.
Documented that JDK 8 is needed for building.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/a3612431
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/a3612431
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/a3612431
Branch: refs/heads/2.3
Commit: a361243146a62ca19552074e4b8d74d76ca9abb4
Parents: 0c3e146
Author: ddekany <dd...@apache.org>
Authored: Tue Sep 29 21:42:10 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Tue Sep 29 21:42:10 2015 +0200
----------------------------------------------------------------------
README.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a3612431/README.txt
----------------------------------------------------------------------
diff --git a/README.txt b/README.txt
index 5985918..f1aafc9 100644
--- a/README.txt
+++ b/README.txt
@@ -71,8 +71,8 @@ application already uses the related library.
Building
--------
-You need Apache Ant and Ivy be installed. (As of this writing it was
-tested with Ant 1.8.1 and Ivy 2.3.0.)
+You need JDK 8(!), Apache Ant and Ivy be installed. (As of this writing
+it was tested with Ant 1.8.1 and Ivy 2.3.0.)
If you need to ensure compliance with certain J2SE versions, copy
build.properties.sample into build.properties, and edit it
[06/16] incubator-freemarker git commit: `${...}` inside string
literals is equivalent to using the `+` operator again. This rule was broken
by `+` supporting markup operands,
while `${...}` inside string literals didn't. Now similarly as `"foo " + someM
Posted by dd...@apache.org.
`${...}` inside string literals is equivalent to using the `+` operator again. This rule was broken by `+` supporting markup operands, while `${...}` inside string literals didn't. Now similarly as `"foo " + someMarkup` works and gives a markup result, `"foo ${someMarkup}"` does too.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/fa6ac0ee
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/fa6ac0ee
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/fa6ac0ee
Branch: refs/heads/2.3
Commit: fa6ac0eea88c38c816298b518c5d249d4599f93e
Parents: d8487ff
Author: ddekany <dd...@apache.org>
Authored: Sun Oct 4 01:42:47 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sun Oct 4 01:43:45 2015 +0200
----------------------------------------------------------------------
.../freemarker/core/AddConcatExpression.java | 32 +-----
.../java/freemarker/core/DollarVariable.java | 10 +-
src/main/java/freemarker/core/EvalUtil.java | 28 ++++-
.../java/freemarker/core/Interpolation.java | 9 ++
.../java/freemarker/core/NumericalOutput.java | 18 ++-
.../java/freemarker/core/ParameterRole.java | 1 +
.../java/freemarker/core/StringLiteral.java | 105 +++++++++++------
src/main/javacc/FTL.jj | 66 ++++++++++-
src/manual/book.xml | 114 ++++++++-----------
.../java/freemarker/core/NumberFormatTest.java | 4 +-
.../java/freemarker/core/OutputFormatTest.java | 23 +++-
.../core/StringLiteralInterpolationTest.java | 23 ++++
src/test/java/freemarker/test/TemplateTest.java | 6 +-
src/test/resources/freemarker/core/ast-1.ast | 19 ++--
.../resources/freemarker/core/ast-builtins.ast | 3 -
.../resources/freemarker/core/ast-range.ast | 2 -
.../freemarker/core/ast-strlitinterpolation.ast | 72 ++++++++++--
.../freemarker/core/ast-strlitinterpolation.ftl | 8 +-
.../AutoEscapingExample-stringLiteral2.ftlh | 2 +-
.../AutoEscapingExample-stringLiteral2.ftlh.out | 2 +-
20 files changed, 364 insertions(+), 183 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/main/java/freemarker/core/AddConcatExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/AddConcatExpression.java b/src/main/java/freemarker/core/AddConcatExpression.java
index 7c1eb75..4dbfd78 100644
--- a/src/main/java/freemarker/core/AddConcatExpression.java
+++ b/src/main/java/freemarker/core/AddConcatExpression.java
@@ -85,18 +85,18 @@ final class AddConcatExpression extends Expression {
return new SimpleScalar(((String) leftOMOrStr).concat((String) rightOMOrStr));
} else { // rightOMOrStr instanceof TemplateMarkupOutputModel
TemplateMarkupOutputModel<?> rightMO = (TemplateMarkupOutputModel<?>) rightOMOrStr;
- return concatMarkupOutputs(parent,
+ return EvalUtil.concatMarkupOutputs(parent,
rightMO.getOutputFormat().fromPlainTextByEscaping((String) leftOMOrStr),
rightMO);
}
} else { // leftOMOrStr instanceof TemplateMarkupOutputModel
TemplateMarkupOutputModel<?> leftMO = (TemplateMarkupOutputModel<?>) leftOMOrStr;
if (rightOMOrStr instanceof String) { // markup output
- return concatMarkupOutputs(parent,
+ return EvalUtil.concatMarkupOutputs(parent,
leftMO,
leftMO.getOutputFormat().fromPlainTextByEscaping((String) rightOMOrStr));
} else { // rightOMOrStr instanceof TemplateMarkupOutputModel
- return concatMarkupOutputs(parent,
+ return EvalUtil.concatMarkupOutputs(parent,
leftMO,
(TemplateMarkupOutputModel) rightOMOrStr);
}
@@ -124,32 +124,6 @@ final class AddConcatExpression extends Expression {
}
}
- private static TemplateModel concatMarkupOutputs(TemplateObject parent, TemplateMarkupOutputModel leftMO,
- TemplateMarkupOutputModel rightMO) throws TemplateModelException {
- MarkupOutputFormat leftOF = leftMO.getOutputFormat();
- MarkupOutputFormat rightOF = rightMO.getOutputFormat();
- if (rightOF != leftOF) {
- String rightPT;
- String leftPT;
- if ((rightPT = rightOF.getSourcePlainText(rightMO)) != null) {
- return leftOF.concat(leftMO, leftOF.fromPlainTextByEscaping(rightPT));
- } else if ((leftPT = leftOF.getSourcePlainText(leftMO)) != null) {
- return rightOF.concat(rightOF.fromPlainTextByEscaping(leftPT), rightMO);
- } else {
- Object[] message = { "Concatenation left hand operand is in ", new _DelayedToString(leftOF),
- " format, while the right hand operand is in ", new _DelayedToString(rightOF),
- ". Conversion to common format wasn't possible." };
- if (parent instanceof Expression) {
- throw new _TemplateModelException((Expression) parent, message);
- } else {
- throw new _TemplateModelException(message);
- }
- }
- } else {
- return leftOF.concat(leftMO, rightMO);
- }
- }
-
static TemplateModel _evalOnNumbers(Environment env, TemplateObject parent, Number first, Number second)
throws TemplateException {
ArithmeticEngine ae = EvalUtil.getArithmeticEngine(env, parent);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/main/java/freemarker/core/DollarVariable.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/DollarVariable.java b/src/main/java/freemarker/core/DollarVariable.java
index a3abc31..2ecab8c 100644
--- a/src/main/java/freemarker/core/DollarVariable.java
+++ b/src/main/java/freemarker/core/DollarVariable.java
@@ -23,7 +23,6 @@ import java.io.IOException;
import java.io.Writer;
import freemarker.template.TemplateException;
-import freemarker.template.TemplateModel;
import freemarker.template.utility.StringUtil;
/**
@@ -57,10 +56,8 @@ final class DollarVariable extends Interpolation {
*/
@Override
void accept(Environment env) throws TemplateException, IOException {
- final TemplateModel tm = escapedExpression.eval(env);
+ final Object moOrStr = calculateInterpolatedStringOrMarkup(env);
final Writer out = env.getOut();
- final Object moOrStr = EvalUtil.coerceModelToStringOrMarkup(
- tm, escapedExpression, null, env);
if (moOrStr instanceof String) {
final String s = (String) moOrStr;
if (autoEscape) {
@@ -94,6 +91,11 @@ final class DollarVariable extends Interpolation {
}
@Override
+ protected Object calculateInterpolatedStringOrMarkup(Environment env) throws TemplateException {
+ return EvalUtil.coerceModelToStringOrMarkup(escapedExpression.eval(env), escapedExpression, null, env);
+ }
+
+ @Override
protected String dump(boolean canonical, boolean inStringLiteral) {
StringBuilder sb = new StringBuilder();
sb.append("${");
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/main/java/freemarker/core/EvalUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/EvalUtil.java b/src/main/java/freemarker/core/EvalUtil.java
index ca21ac5..886308c 100644
--- a/src/main/java/freemarker/core/EvalUtil.java
+++ b/src/main/java/freemarker/core/EvalUtil.java
@@ -528,10 +528,36 @@ class EvalUtil {
throw new NullPointerException("TemplateValueFormatter result can't be null");
}
+ static TemplateMarkupOutputModel concatMarkupOutputs(TemplateObject parent, TemplateMarkupOutputModel leftMO,
+ TemplateMarkupOutputModel rightMO) throws TemplateException {
+ MarkupOutputFormat leftOF = leftMO.getOutputFormat();
+ MarkupOutputFormat rightOF = rightMO.getOutputFormat();
+ if (rightOF != leftOF) {
+ String rightPT;
+ String leftPT;
+ if ((rightPT = rightOF.getSourcePlainText(rightMO)) != null) {
+ return leftOF.concat(leftMO, leftOF.fromPlainTextByEscaping(rightPT));
+ } else if ((leftPT = leftOF.getSourcePlainText(leftMO)) != null) {
+ return rightOF.concat(rightOF.fromPlainTextByEscaping(leftPT), rightMO);
+ } else {
+ Object[] message = { "Concatenation left hand operand is in ", new _DelayedToString(leftOF),
+ " format, while the right hand operand is in ", new _DelayedToString(rightOF),
+ ". Conversion to common format wasn't possible." };
+ if (parent instanceof Expression) {
+ throw new _MiscTemplateException((Expression) parent, message);
+ } else {
+ throw new _MiscTemplateException(message);
+ }
+ }
+ } else {
+ return leftOF.concat(leftMO, rightMO);
+ }
+ }
+
/**
* Returns an {@link ArithmeticEngine} even if {@code env} is {@code null}, because we are in parsing phase.
*/
- public static ArithmeticEngine getArithmeticEngine(Environment env, TemplateObject tObj) {
+ static ArithmeticEngine getArithmeticEngine(Environment env, TemplateObject tObj) {
return env != null
? env.getArithmeticEngine()
: tObj.getTemplate().getParserConfiguration().getArithmeticEngine();
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/main/java/freemarker/core/Interpolation.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Interpolation.java b/src/main/java/freemarker/core/Interpolation.java
index 733fafa..2dcb11a 100644
--- a/src/main/java/freemarker/core/Interpolation.java
+++ b/src/main/java/freemarker/core/Interpolation.java
@@ -18,6 +18,8 @@
*/
package freemarker.core;
+import freemarker.template.TemplateException;
+
abstract class Interpolation extends TemplateElement {
protected abstract String dump(boolean canonical, boolean inStringLiteral);
@@ -31,4 +33,11 @@ abstract class Interpolation extends TemplateElement {
return dump(true, true);
}
+ /**
+ * Returns the already type-converted value that this interpolation will insert into the output.
+ *
+ * @return A {@link String} or {@link TemplateMarkupOutputModel}. Not {@code null}.
+ */
+ protected abstract Object calculateInterpolatedStringOrMarkup(Environment env) throws TemplateException;
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/main/java/freemarker/core/NumericalOutput.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/NumericalOutput.java b/src/main/java/freemarker/core/NumericalOutput.java
index 0ded83f..c9028c6 100644
--- a/src/main/java/freemarker/core/NumericalOutput.java
+++ b/src/main/java/freemarker/core/NumericalOutput.java
@@ -60,6 +60,17 @@ final class NumericalOutput extends Interpolation {
@Override
void accept(Environment env) throws TemplateException, IOException {
+ String s = calculateInterpolatedStringOrMarkup(env);
+ Writer out = env.getOut();
+ if (autoEscapeOutputFormat != null) {
+ autoEscapeOutputFormat.output(s, out);
+ } else {
+ out.write(s);
+ }
+ }
+
+ @Override
+ protected String calculateInterpolatedStringOrMarkup(Environment env) throws TemplateException {
Number num = expression.evalToNumber(env);
FormatHolder fmth = formatCache; // atomic sampling
@@ -85,12 +96,7 @@ final class NumericalOutput extends Interpolation {
// Some locales may use non-Arabic digits, thus replacing the
// decimal separator in the result of toString() is not enough.
String s = fmth.format.format(num);
- Writer out = env.getOut();
- if (autoEscapeOutputFormat != null) {
- autoEscapeOutputFormat.output(s, out);
- } else {
- out.write(s);
- }
+ return s;
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/main/java/freemarker/core/ParameterRole.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/ParameterRole.java b/src/main/java/freemarker/core/ParameterRole.java
index d178881..1293d5c 100644
--- a/src/main/java/freemarker/core/ParameterRole.java
+++ b/src/main/java/freemarker/core/ParameterRole.java
@@ -62,6 +62,7 @@ final class ParameterRole {
static final ParameterRole ARGUMENT_VALUE = new ParameterRole("argument value");
static final ParameterRole CONTENT = new ParameterRole("content");
static final ParameterRole EMBEDDED_TEMPLATE = new ParameterRole("embedded template");
+ static final ParameterRole VALUE_PART = new ParameterRole("value part");
static final ParameterRole MINIMUM_DECIMALS = new ParameterRole("minimum decimals");
static final ParameterRole MAXIMUM_DECIMALS = new ParameterRole("maximum decimals");
static final ParameterRole NODE = new ParameterRole("node");
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/main/java/freemarker/core/StringLiteral.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/StringLiteral.java b/src/main/java/freemarker/core/StringLiteral.java
index 051c0aa..aa32d3e 100644
--- a/src/main/java/freemarker/core/StringLiteral.java
+++ b/src/main/java/freemarker/core/StringLiteral.java
@@ -19,14 +19,12 @@
package freemarker.core;
-import java.io.IOException;
import java.io.StringReader;
-import java.util.Enumeration;
+import java.util.List;
import freemarker.template.SimpleScalar;
import freemarker.template.Template;
import freemarker.template.TemplateException;
-import freemarker.template.TemplateExceptionHandler;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateScalarModel;
import freemarker.template.utility.StringUtil;
@@ -34,7 +32,9 @@ import freemarker.template.utility.StringUtil;
final class StringLiteral extends Expression implements TemplateScalarModel {
private final String value;
- private TemplateElement dynamicValue;
+
+ /** {@link List} of {@link String}-s and {@link Interpolation}-s. */
+ private List<Object> dynamicValue;
StringLiteral(String value) {
this.value = value;
@@ -45,8 +45,9 @@ final class StringLiteral extends Expression implements TemplateScalarModel {
* The token source of the template that contains this string literal. As of this writing, we only need
* this to share the {@code namingConvetion} with that.
*/
- // TODO This should be the part of the "parent" parsing; now it contains hacks like those with namingConvention.
- void parseValue(FMParserTokenManager parentTkMan) throws ParseException {
+ void parseValue(FMParserTokenManager parentTkMan, OutputFormat outputFormat) throws ParseException {
+ // The way this work is incorrect (the literal should be parsed without un-escaping),
+ // but we can't fix this backward compatibly.
if (value.length() > 3 && (value.indexOf("${") >= 0 || value.indexOf("#{") >= 0)) {
Template parentTemplate = getTemplate();
@@ -60,9 +61,9 @@ final class StringLiteral extends Expression implements TemplateScalarModel {
FMParser parser = new FMParser(parentTemplate, false, tkMan, parentTemplate.getParserConfiguration());
// We continue from the parent parser's current state:
- parser.setupStringLiteralMode(parentTkMan);
+ parser.setupStringLiteralMode(parentTkMan, outputFormat);
try {
- dynamicValue = parser.FreeMarkerText();
+ dynamicValue = parser.StaticTextAndInterpolations();
} finally {
// The parent parser continues from this parser's current state:
parser.tearDownStringLiteralMode(parentTkMan);
@@ -77,7 +78,51 @@ final class StringLiteral extends Expression implements TemplateScalarModel {
@Override
TemplateModel _eval(Environment env) throws TemplateException {
- return new SimpleScalar(evalAndCoerceToPlainText(env));
+ if (dynamicValue == null) {
+ return new SimpleScalar(value);
+ } else {
+ // This should behave like concatenating the values with `+`. Thus, an interpolated expression that
+ // returns markup promotes the result of the whole expression to markup.
+
+ // Exactly one of these is non-null, depending on if the result will be plain text or markup, which can
+ // change during evaluation, depending on the result of the interpolations:
+ StringBuilder plainTextResult = null;
+ TemplateMarkupOutputModel<?> markupResult = null;
+
+ for (Object part : dynamicValue) {
+ Object calcedPart =
+ part instanceof String ? part
+ : ((Interpolation) part).calculateInterpolatedStringOrMarkup(env);
+ if (markupResult != null) {
+ TemplateMarkupOutputModel<?> partMO = calcedPart instanceof String
+ ? markupResult.getOutputFormat().fromPlainTextByEscaping((String) calcedPart)
+ : (TemplateMarkupOutputModel<?>) calcedPart;
+ markupResult = EvalUtil.concatMarkupOutputs(this, markupResult, partMO);
+ } else { // We are using `plainTextOutput` (or nothing yet)
+ if (calcedPart instanceof String) {
+ String partStr = (String) calcedPart;
+ if (plainTextResult == null) {
+ plainTextResult = new StringBuilder(partStr);
+ } else {
+ plainTextResult.append(partStr);
+ }
+ } else { // `calcedPart` is TemplateMarkupOutputModel
+ TemplateMarkupOutputModel<?> moPart = (TemplateMarkupOutputModel<?>) calcedPart;
+ if (plainTextResult != null) {
+ TemplateMarkupOutputModel<?> leftHandMO = moPart.getOutputFormat()
+ .fromPlainTextByEscaping(plainTextResult.toString());
+ markupResult = EvalUtil.concatMarkupOutputs(this, leftHandMO, moPart);
+ plainTextResult = null;
+ } else {
+ markupResult = moPart;
+ }
+ }
+ }
+ } // for each part
+ return markupResult != null ? markupResult
+ : plainTextResult != null ? new SimpleScalar(plainTextResult.toString())
+ : SimpleScalar.EMPTY_STRING;
+ }
}
public String getAsString() {
@@ -88,40 +133,22 @@ final class StringLiteral extends Expression implements TemplateScalarModel {
* Tells if this is something like <tt>"${foo}"</tt>, which is usually a user mistake.
*/
boolean isSingleInterpolationLiteral() {
- return dynamicValue != null && dynamicValue.getChildCount() == 1
- && dynamicValue.getChildAt(0) instanceof DollarVariable;
+ return dynamicValue != null && dynamicValue.size() == 1
+ && dynamicValue.get(0) instanceof Interpolation;
}
@Override
- String evalAndCoerceToPlainText(Environment env) throws TemplateException {
- if (dynamicValue == null) {
- return value;
- } else {
- TemplateExceptionHandler teh = env.getTemplateExceptionHandler();
- env.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
- try {
- return env.renderElementToString(dynamicValue);
- } catch (IOException ioe) {
- throw new _MiscTemplateException(ioe, env);
- } finally {
- env.setTemplateExceptionHandler(teh);
- }
- }
- }
-
- @Override
public String getCanonicalForm() {
if (dynamicValue == null) {
return StringUtil.ftlQuote(value);
} else {
StringBuilder sb = new StringBuilder();
sb.append('"');
- for (Enumeration childrenEnum = dynamicValue.children(); childrenEnum.hasMoreElements(); ) {
- TemplateElement child = (TemplateElement) childrenEnum.nextElement();
+ for (Object child : dynamicValue) {
if (child instanceof Interpolation) {
sb.append(((Interpolation) child).getCanonicalFormInStringLiteral());
} else {
- sb.append(StringUtil.FTLStringLiteralEnc(child.getCanonicalForm(), '"'));
+ sb.append(StringUtil.FTLStringLiteralEnc((String) child, '"'));
}
}
sb.append('"');
@@ -150,19 +177,25 @@ final class StringLiteral extends Expression implements TemplateScalarModel {
@Override
int getParameterCount() {
- return 1;
+ return dynamicValue == null ? 0 : dynamicValue.size();
}
@Override
Object getParameterValue(int idx) {
- if (idx != 0) throw new IndexOutOfBoundsException();
- return dynamicValue;
+ checkIndex(idx);
+ return dynamicValue.get(idx);
+ }
+
+ private void checkIndex(int idx) {
+ if (dynamicValue == null || idx >= dynamicValue.size()) {
+ throw new IndexOutOfBoundsException();
+ }
}
@Override
ParameterRole getParameterRole(int idx) {
- if (idx != 0) throw new IndexOutOfBoundsException();
- return ParameterRole.EMBEDDED_TEMPLATE;
+ checkIndex(idx);
+ return ParameterRole.VALUE_PART;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj
index 9c6bae1..34f737b 100644
--- a/src/main/javacc/FTL.jj
+++ b/src/main/javacc/FTL.jj
@@ -254,13 +254,13 @@ public class FMParser {
}
}
- void setupStringLiteralMode(FMParserTokenManager parentTokenSource) {
+ void setupStringLiteralMode(FMParserTokenManager parentTokenSource, OutputFormat outputFormat) {
token_source.initialNamingConvention = parentTokenSource.initialNamingConvention;
token_source.namingConvention = parentTokenSource.namingConvention;
token_source.namingConventionEstabilisher = parentTokenSource.namingConventionEstabilisher;
token_source.SwitchTo(NODIRECTIVE);
- outputFormat = PlainTextOutputFormat.INSTANCE;
+ this.outputFormat = outputFormat;
recalculateAutoEscapingField();
if (incompatibleImprovements < _TemplateAPI.VERSION_INT_2_3_24) {
// Emulate bug, where the string literal parser haven't inherited the IcI:
@@ -2271,7 +2271,7 @@ StringLiteral StringLiteral(boolean interpolate) :
result.setLocation(template, t, t);
if (interpolate && !raw) {
// TODO: This logic is broken. It can't handle literals that contains both ${...} and $\{...}.
- if (t.image.indexOf("${") >= 0 || t.image.indexOf("#{") >= 0) result.parseValue(token_source);
+ if (t.image.indexOf("${") >= 0 || t.image.indexOf("#{") >= 0) result.parseValue(token_source, outputFormat);
}
return result;
}
@@ -4205,6 +4205,66 @@ Map ParamList() :
}
/**
+ * Parses the already un-escaped content of a string literal (input must not include the quotation marks).
+ *
+ * @return A {@link List} of {@link String}-s and {@link Interpolation}-s.
+ */
+List<Object> StaticTextAndInterpolations() :
+{
+ Token t;
+ Interpolation interpolation;
+ StringBuilder staticTextCollector = null;
+ ArrayList<Object> parts = new ArrayList<Object>();
+}
+{
+ (
+ (
+ t = <STATIC_TEXT_WS>
+ |
+ t = <STATIC_TEXT_NON_WS>
+ |
+ t = <STATIC_TEXT_FALSE_ALARM>
+ )
+ {
+ String s = t.image;
+ if (!s.isEmpty()) {
+ if (staticTextCollector == null) {
+ staticTextCollector = new StringBuilder(t.image);
+ } else {
+ staticTextCollector.append(t.image);
+ }
+ }
+ }
+ |
+ (
+ LOOKAHEAD(<DOLLAR_INTERPOLATION_OPENING>)
+ (
+ interpolation = StringOutput()
+ )
+ |
+ LOOKAHEAD(<HASH_INTERPOLATION_OPENING>)
+ (
+ interpolation = NumericalOutput()
+ )
+ )
+ {
+ if (staticTextCollector != null) {
+ parts.add(staticTextCollector.toString());
+ staticTextCollector.setLength(0);
+ }
+ parts.add(interpolation);
+ }
+ )*
+ {
+ if (staticTextCollector != null && staticTextCollector.length() != 0) {
+ parts.add(staticTextCollector.toString());
+ }
+ parts.trimToSize();
+ return parts;
+ }
+}
+
+/**
* Root production to be used when parsing
* an entire file.
*/
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/manual/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/book.xml b/src/manual/book.xml
index 6decbd9..3546923 100644
--- a/src/manual/book.xml
+++ b/src/manual/book.xml
@@ -2798,14 +2798,7 @@ baz
literals <link linkend="dgui_template_valueinsertion">behaves
similarly as in <phrase role="markedText">text</phrase>
sections</link> (so it goes through the same <emphasis>locale
- sensitive</emphasis> number and date/time formatting), except that
- no automatic escaping will happen (the deprecated <link
- linkend="ref.directive.escape">escaping by
- <literal>escape</literal> directive</link> has no effect there,
- nor <link linkend="dgui_misc_autoescaping">auto-escaping</link>
- happens as <link
- linkend="dgui_misc_autoescaping_stringliteral">explained
- here</link>).</para>
+ sensitive</emphasis> number and date/time formatting).</para>
<para>Example (assume that user is <quote>Big Joe</quote>):</para>
@@ -2865,17 +2858,6 @@ ${s} <#-- Just to see what the value of s is -->
something like <literal>"someUrl?id=1234"</literal>, regardless
of locale and format settings.</para>
</warning>
-
- <para>Note for advanced users that <literal>+</literal> is more
- flexible than <literal>${<replaceable>...</replaceable>}</literal>
- when it comes to handling <link
- linkend="dgui_misc_autoescaping_movalues">markup output
- values</link>, because <link
- linkend="dgui_misc_autoescaping_concatenation"><literal>+</literal>
- can have markup output result</link>, while <link
- linkend="dgui_misc_autoescaping_stringliteral">string literal
- interpolation can't</link>, as the literal must yield a
- string.</para>
</section>
<section xml:id="dgui_template_exp_get_character">
@@ -5690,51 +5672,6 @@ XML: <p>Test</p>
RTF: \par Test</programlisting>
</section>
- <section xml:id="dgui_misc_autoescaping_stringliteral">
- <title>Auto-escaping and ${...} inside string literals</title>
-
- <para>Inside string literals (quoted text expressions), the <link
- linkend="dgui_misc_autoescaping_outputformat">output format</link>
- is <literal>plainText</literal>. Thus no auto-escaping will occur
- there:</para>
-
- <programlisting role="template"><#-- We assume that we have "HTML" output format by default. -->
-<#assign s = "Foo & bar">
-${s}
-${"${s} & baz"}</programlisting>
-
- <programlisting role="output">Foo &amp; bar
-Foo &amp; bar &amp; baz</programlisting>
-
- <para>Above, because inside the string literal
- <literal>${s}</literal> did no auto-escaping, when we print the
- whole string we don't end up with double-escaping.</para>
-
- <para>The <literal>plainText</literal> output format only allows
- the inserting of markup output values that were created by
- escaping plain text
- (<literal><replaceable>plainText</replaceable>?esc</literal>), as
- those are trivially convertible back to plain text. Thus only such
- markup output values can be insert into string literals with
- <literal>${<replaceable>...</replaceable>}</literal> (the
- <literal>+</literal> operator is more flexible, but see that
- later):</para>
-
- <programlisting role="template"><#-- We assume that we have "HTML" output format by default. -->
-
-<#-- Markup output value created by escaping plain text: -->
-<#assign mo1 = "Foo & bar"?esc>
-
-<#-- Markup output value created outherwise: -->
-<#assign mo2 = "<p>Foo"?no_esc>
-
-${"${mo1} baz"}
-<#attempt>${"${mo2} baz"}<#recover>Failed</#attempt></programlisting>
-
- <programlisting role="output">Foo &amp; bar baz
-Failed</programlisting>
- </section>
-
<section xml:id="dgui_misc_autoescaping_concatenation">
<title>Markup output values and the <quote>+</quote>
operator</title>
@@ -5764,6 +5701,32 @@ ${"<h1>"?no_esc + "Foo & bar" + "</h1>"?no_esc}</programlisting>
of conversions here</link>.)</para>
</section>
+ <section xml:id="dgui_misc_autoescaping_stringliteral">
+ <title>Auto-escaping and ${...} inside string literals</title>
+
+ <para>A string <emphasis>expression</emphasis> like
+ <literal>"Hello ${name}!"</literal> is just a shorthand for
+ <literal>"Hello" + name + "!"</literal>, so that
+ <literal>${<replaceable>...</replaceable>}</literal> doesn't
+ auto-escape.</para>
+
+ <programlisting role="template"><#-- We assume that we have "HTML" output format by default. -->
+<#assign name = "Foo & Bar">
+
+<#assign s = "<p>Hello ${name}!">
+${s}
+<p>Hello ${name}!
+
+To prove that s didn't contain the value escaped:
+${s?replace('&'), 'and'}</programlisting>
+
+ <programlisting role="output">&lt;p&gt;Hello Foo &amp; Bar!
+<p>Hello Foo &amp; Bar!
+
+To prove that s didn't contain the value escaped:
+&lt;p&gt;Hello Foo and Bar!</programlisting>
+ </section>
+
<section>
<title>Combined output formats</title>
@@ -26158,6 +26121,18 @@ TemplateModel x = env.getVariable("x"); // get variable x</programlisting>
which can't be loaded due to zip format errors in the error
message.</para>
</listitem>
+
+ <listitem>
+ <para>The non-public AST API of
+ <literal>freemarker.core.StringLiteral</literal>-s has been
+ changed. In principle it doesn't mater as it isn't a public API,
+ but some might used these regardless to introspect templates.
+ Earlier it had an <quote>embedded template</quote> parameter
+ inside, now it has 0 (for purely static string literals), one or
+ multiple <quote>value part</quote>-ts, which are
+ <literal>String</literal>-s and
+ <literal>Interpolation</literal>-s.</para>
+ </listitem>
</itemizedlist>
</section>
@@ -26267,6 +26242,17 @@ TemplateModel x = env.getVariable("x"); // get variable x</programlisting>
</listitem>
<listitem>
+ <para><literal>${<replaceable>...</replaceable>}</literal>
+ inside string literals is equivalent to using the
+ <literal>+</literal> operator again. This rule was broken by
+ <literal>+</literal> supporting markup operands, while
+ <literal>${<replaceable>...</replaceable>}</literal> inside
+ string literals didn't. Now similarly as <literal>"foo " +
+ someMarkup</literal> works and gives a markup result,
+ <literal>"foo ${someMarkup}"</literal> does too.</para>
+ </listitem>
+
+ <listitem>
<para>Added <literal>XHTMLOutputFormat</literal> and
<literal>TemplateXHTMLOutputModel</literal>.</para>
</listitem>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/test/java/freemarker/core/NumberFormatTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/NumberFormatTest.java b/src/test/java/freemarker/core/NumberFormatTest.java
index ddfbf28..19d2cba 100644
--- a/src/test/java/freemarker/core/NumberFormatTest.java
+++ b/src/test/java/freemarker/core/NumberFormatTest.java
@@ -297,9 +297,7 @@ public class NumberFormatTest extends TemplateTest {
assertOutput("<#escape x as x?html>" + commonFTL + "</#escape>", commonOutput);
assertOutput("<#escape x as x?xhtml>" + commonFTL + "</#escape>", commonOutput);
assertOutput("<#escape x as x?xml>" + commonFTL + "</#escape>", commonOutput);
- // TODO: Should give markup, but currently does interpolation in plain text:
- // assertOutput("${\"" + commonFTL + "\"}",
- // "1.23*10<sup>6</sup> cat:1.23*10<sup>6</sup> 1.23*10<sup>-5</sup>");
+ assertOutput("${\"" + commonFTL + "\"}", "1.23*10<sup>6</sup> cat:1.23*10<sup>6</sup> 1.23*10<sup>-5</sup>");
assertErrorContains("<#ftl outputFormat='plainText'>" + commonFTL, "HTML", "plainText", "conversion");
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/test/java/freemarker/core/OutputFormatTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/OutputFormatTest.java b/src/test/java/freemarker/core/OutputFormatTest.java
index f7614c3..b36761e 100644
--- a/src/test/java/freemarker/core/OutputFormatTest.java
+++ b/src/test/java/freemarker/core/OutputFormatTest.java
@@ -436,12 +436,21 @@ public class OutputFormatTest extends TemplateTest {
}
@Test
- public void testStringLiteralTemplateModificationBug() throws IOException, TemplateException {
+ public void testStringLiteralInterpolation() throws IOException, TemplateException {
Template t = new Template(null, "<#ftl outputFormat='XML'>${'&'} ${\"(${'&'})\"?noEsc}", getConfiguration());
assertEquals(XMLOutputFormat.INSTANCE, t.getOutputFormat());
- assertOutput("${.outputFormat} ${'${.outputFormat}'} ${.outputFormat}", "undefined plainText undefined");
- assertOutput("${'foo ${xmlPlain}'}", "foo a < {x'}");
- assertErrorContains("${'${xmlMarkup}'}", "plainText", "XML", "conversion");
+
+ assertOutput("${.outputFormat} ${'${.outputFormat}'} ${.outputFormat}",
+ "undefined undefined undefined");
+ assertOutput("<#ftl outputFormat='HTML'>${.outputFormat} ${'${.outputFormat}'} ${.outputFormat}",
+ "HTML HTML HTML");
+ assertOutput("${.outputFormat} <#outputFormat 'XML'>${'${.outputFormat}'}</#outputFormat> ${.outputFormat}",
+ "undefined XML undefined");
+ assertOutput("${'foo ${xmlPlain}'}", "foo a < {x'}");
+ assertOutput("${'${xmlMarkup}'}", "<p>c</p>");
+ assertErrorContains("${'${\"x\"?esc}'}", "?esc", "undefined");
+ assertOutput("<#ftl outputFormat='XML'>${'${xmlMarkup?esc} ${\"<\"?esc} ${\">\"} ${\"&\"?noEsc}'}",
+ "<p>c</p> < > &");
}
@Test
@@ -875,11 +884,13 @@ public class OutputFormatTest extends TemplateTest {
assertOutput(commonFTL, "x");
assertErrorContains("<#ftl outputFormat='HTML'>" + commonFTL,
"?" + biName, "HTML", "double-escaping");
+ assertErrorContains("<#ftl outputFormat='HTML'>${'${\"x\"?" + biName + "}'}",
+ "?" + biName, "HTML", "double-escaping");
assertOutput("<#ftl outputFormat='plainText'>" + commonFTL, "x");
assertOutput("<#ftl outputFormat='HTML' autoEsc=false>" + commonFTL, "x");
assertOutput("<#ftl outputFormat='HTML'><#noAutoEsc>" + commonFTL + "</#noAutoEsc>", "x");
- assertOutput("<#ftl outputFormat='HTML'><#outputFormat 'plainText'>" + commonFTL + "</#outputFormat>", "x");
- assertOutput("<#ftl outputFormat='HTML'>${'${\"x\"?" + biName + "}'}", "x");
+ assertOutput("<#ftl outputFormat='HTML'><#outputFormat 'plainText'>" + commonFTL + "</#outputFormat>",
+ "x");
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/StringLiteralInterpolationTest.java b/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
index fd6fb14..b7bfeee 100644
--- a/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
+++ b/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
@@ -19,6 +19,7 @@
package freemarker.core;
import java.io.IOException;
+import java.util.Collections;
import org.junit.Test;
@@ -36,6 +37,7 @@ public class StringLiteralInterpolationTest extends TemplateTest {
assertOutput("${'#{x}'}", "1");
assertOutput("${'a${x}b${x*2}c'}", "a1b2c");
assertOutput("${'a#{x}b#{x*2}c'}", "a1b2c");
+ assertOutput("${'a#{x; m2}'}", "a1.00");
assertOutput("${'${x} ${x}'}", "1 1");
assertOutput("${'$\\{x}'}", "${x}");
assertOutput("${'$\\{x} $\\{x}'}", "${x} ${x}");
@@ -73,6 +75,13 @@ public class StringLiteralInterpolationTest extends TemplateTest {
assertOutput("${'${1}'}", "1");
assertErrorContains("${'${ '}", "");
}
+
+ @Test
+ public void testErrors() {
+ addToDataModel("x", 1);
+ assertErrorContains("${'${noSuchVar}'}", InvalidReferenceException.class, "missing", "noSuchVar");
+ assertErrorContains("${'${x/0}'}", ArithmeticException.class, "zero");
+ }
@Test
public void escaping() throws IOException, TemplateException {
@@ -90,4 +99,18 @@ public class StringLiteralInterpolationTest extends TemplateTest {
assertOutput("${'&\\''?html} ${\"${'&\\\\\\''?html}\"}", "&' &'");
}
+ @Test
+ public void markup() throws IOException, TemplateException {
+ Configuration cfg = getConfiguration();
+ cfg.setCustomNumberFormats(Collections.singletonMap("G", PrintfGTemplateNumberFormatFactory.INSTANCE));
+ cfg.setNumberFormat("@G 3");
+
+ assertOutput("${\"${1000}\"}", "1.00*10<sup>3</sup>");
+ assertOutput("${\"&_${1000}\"}", "&_1.00*10<sup>3</sup>");
+ assertOutput("${\"${1000}_&\"}", "1.00*10<sup>3</sup>_&");
+ assertOutput("${\"${1000}, ${2000}\"}", "1.00*10<sup>3</sup>, 2.00*10<sup>3</sup>");
+ assertOutput("${\"& ${'x'}, ${2000}\"}", "& x, 2.00*10<sup>3</sup>");
+ assertOutput("${\"& ${'x'}, #{2000}\"}", "& x, 2000");
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/test/java/freemarker/test/TemplateTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/test/TemplateTest.java b/src/test/java/freemarker/test/TemplateTest.java
index 0b1e03d..6047e2e 100644
--- a/src/test/java/freemarker/test/TemplateTest.java
+++ b/src/test/java/freemarker/test/TemplateTest.java
@@ -229,11 +229,13 @@ public abstract class TemplateTest {
}
assertContainsAll(e.getEditorMessage(), expectedSubstrings);
return e;
- } catch (IOException e) {
+ } catch (Exception e) {
if (exceptionClass != null) {
assertThat(e, instanceOf(exceptionClass));
+ return e;
+ } else {
+ throw new RuntimeException("Unexpected exception class: " + e.getClass().getName(), e);
}
- throw new RuntimeException("Unexpected exception class: " + e.getClass().getName(), e);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/test/resources/freemarker/core/ast-1.ast
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/core/ast-1.ast b/src/test/resources/freemarker/core/ast-1.ast
index 6c5a753..9c3b8d1 100644
--- a/src/test/resources/freemarker/core/ast-1.ast
+++ b/src/test/resources/freemarker/core/ast-1.ast
@@ -64,19 +64,15 @@
- AST-node subtype: "1" // Integer
${...} // f.c.DollarVariable
- content: "static" // f.c.StringLiteral
- - embedded template: null // Null
${...} // f.c.DollarVariable
- content: dynamic "..." // f.c.StringLiteral
- - embedded template: #mixed_content // f.c.MixedContent
- #text // f.c.TextBlock
- - content: "x" // String
- ${...} // f.c.DollarVariable
- - content: * // f.c.ArithmeticExpression
- - left-hand operand: baaz // f.c.Identifier
- - right-hand operand: 10 // f.c.NumberLiteral
- - AST-node subtype: "1" // Integer
- #text // f.c.TextBlock
- - content: "y" // String
+ - value part: "x" // String
+ - value part: ${...} // f.c.DollarVariable
+ - content: * // f.c.ArithmeticExpression
+ - left-hand operand: baaz // f.c.Identifier
+ - right-hand operand: 10 // f.c.NumberLiteral
+ - AST-node subtype: "1" // Integer
+ - value part: "y" // String
#text // f.c.TextBlock
- content: "\n5 " // String
#switch // f.c.SwitchBlock
@@ -163,7 +159,6 @@
- content: "\n11 " // String
#outputformat // f.c.OutputFormatBlock
- value: "XML" // f.c.StringLiteral
- - embedded template: null // Null
#noautoesc // f.c.NoAutoEscBlock
${...} // f.c.DollarVariable
- content: a // f.c.Identifier
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/test/resources/freemarker/core/ast-builtins.ast
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/core/ast-builtins.ast b/src/test/resources/freemarker/core/ast-builtins.ast
index 164c790..9278d8b 100644
--- a/src/test/resources/freemarker/core/ast-builtins.ast
+++ b/src/test/resources/freemarker/core/ast-builtins.ast
@@ -20,7 +20,6 @@
- right-hand operand: "left_pad" // String
- argument value: 5 // f.c.NumberLiteral
- argument value: "-" // f.c.StringLiteral
- - embedded template: null // Null
#text // f.c.TextBlock
- content: "\n" // String
${...} // f.c.DollarVariable
@@ -28,9 +27,7 @@
- left-hand operand: x // f.c.Identifier
- right-hand operand: "then" // String
- argument value: "y" // f.c.StringLiteral
- - embedded template: null // Null
- argument value: "n" // f.c.StringLiteral
- - embedded template: null // Null
#text // f.c.TextBlock
- content: "\n" // String
${...} // f.c.DollarVariable
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/test/resources/freemarker/core/ast-range.ast
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/core/ast-range.ast b/src/test/resources/freemarker/core/ast-range.ast
index eb862f4..3ddae45 100644
--- a/src/test/resources/freemarker/core/ast-range.ast
+++ b/src/test/resources/freemarker/core/ast-range.ast
@@ -102,13 +102,11 @@
- left-hand operand: n // f.c.Identifier
- right-hand operand: "index_of" // String
- argument value: "x" // f.c.StringLiteral
- - embedded template: null // Null
- right-hand operand: ...(...) // f.c.MethodCall
- callee: ?index_of // f.c.BuiltInsForStringsBasic$index_ofBI
- left-hand operand: m // f.c.Identifier
- right-hand operand: "index_of" // String
- argument value: "y" // f.c.StringLiteral
- - embedded template: null // Null
- variable scope: "1" // Integer
- namespace: null // Null
#assign // f.c.Assignment
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/test/resources/freemarker/core/ast-strlitinterpolation.ast
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/core/ast-strlitinterpolation.ast b/src/test/resources/freemarker/core/ast-strlitinterpolation.ast
index f8f57bd..c55a320 100644
--- a/src/test/resources/freemarker/core/ast-strlitinterpolation.ast
+++ b/src/test/resources/freemarker/core/ast-strlitinterpolation.ast
@@ -1,10 +1,64 @@
-@ // f.c.UnifiedCall
- - callee: m // f.c.Identifier
- - argument name: "x" // String
- - argument value: dynamic "..." // f.c.StringLiteral
- - embedded template: #mixed_content // f.c.MixedContent
- ${...} // f.c.DollarVariable
+#mixed_content // f.c.MixedContent
+ #text // f.c.TextBlock
+ - content: "1. " // String
+ @ // f.c.UnifiedCall
+ - callee: m // f.c.Identifier
+ - argument name: "x" // String
+ - argument value: dynamic "..." // f.c.StringLiteral
+ - value part: ${...} // f.c.DollarVariable
- content: e1 // f.c.Identifier
- - argument name: "y" // String
- - argument value: "$\\{e2}" // f.c.StringLiteral
- - embedded template: null // Null
\ No newline at end of file
+ - argument name: "y" // String
+ - argument value: "$\\{e2}" // f.c.StringLiteral
+ #text // f.c.TextBlock
+ - content: "\n2. " // String
+ ${...} // f.c.DollarVariable
+ - content: dynamic "..." // f.c.StringLiteral
+ - value part: "a" // String
+ - value part: ${...} // f.c.DollarVariable
+ - content: x // f.c.Identifier
+ - value part: "b" // String
+ - value part: ${...} // f.c.DollarVariable
+ - content: x // f.c.Identifier
+ - value part: "c" // String
+ #text // f.c.TextBlock
+ - content: "\n3. " // String
+ ${...} // f.c.DollarVariable
+ - content: dynamic "..." // f.c.StringLiteral
+ - value part: ${...} // f.c.DollarVariable
+ - content: x // f.c.Identifier
+ - value part: "b" // String
+ #text // f.c.TextBlock
+ - content: "\n4. " // String
+ ${...} // f.c.DollarVariable
+ - content: dynamic "..." // f.c.StringLiteral
+ - value part: "a" // String
+ - value part: ${...} // f.c.DollarVariable
+ - content: x // f.c.Identifier
+ #text // f.c.TextBlock
+ - content: "\n5. " // String
+ ${...} // f.c.DollarVariable
+ - content: dynamic "..." // f.c.StringLiteral
+ - value part: ${...} // f.c.DollarVariable
+ - content: x // f.c.Identifier
+ - value part: #{...} // f.c.NumericalOutput
+ - content: y // f.c.Identifier
+ - minimum decimals: "0" // Integer
+ - maximum decimals: "0" // Integer
+ #text // f.c.TextBlock
+ - content: "\n6. " // String
+ ${...} // f.c.DollarVariable
+ - content: dynamic "..." // f.c.StringLiteral
+ - value part: "a b " // String
+ - value part: ${...} // f.c.DollarVariable
+ - content: x // f.c.Identifier
+ - value part: " c d" // String
+ #text // f.c.TextBlock
+ - content: "\n7. " // String
+ ${...} // f.c.DollarVariable
+ - content: dynamic "..." // f.c.StringLiteral
+ - value part: ${...} // f.c.DollarVariable
+ - content: x // f.c.Identifier
+ - value part: " a b " // String
+ - value part: ${...} // f.c.DollarVariable
+ - content: y // f.c.Identifier
+ - value part: " c$d" // String
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/test/resources/freemarker/core/ast-strlitinterpolation.ftl
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/core/ast-strlitinterpolation.ftl b/src/test/resources/freemarker/core/ast-strlitinterpolation.ftl
index efaced8..f67ba55 100644
--- a/src/test/resources/freemarker/core/ast-strlitinterpolation.ftl
+++ b/src/test/resources/freemarker/core/ast-strlitinterpolation.ftl
@@ -1 +1,7 @@
-<@m x='${e1}' y='$\\{e2}' />
\ No newline at end of file
+1. <@m x='${e1}' y='$\\{e2}' />
+2. ${'a${x}b${x}c'}
+3. ${'${x}b'}
+4. ${'a${x}'}
+5. ${'${x}#{y}'}
+6. ${'a b ${x} c d'}
+7. ${'${x} a b ${y} c$d'}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/test/resources/freemarker/manual/AutoEscapingExample-stringLiteral2.ftlh
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/AutoEscapingExample-stringLiteral2.ftlh b/src/test/resources/freemarker/manual/AutoEscapingExample-stringLiteral2.ftlh
index 6d951a6..060b000 100644
--- a/src/test/resources/freemarker/manual/AutoEscapingExample-stringLiteral2.ftlh
+++ b/src/test/resources/freemarker/manual/AutoEscapingExample-stringLiteral2.ftlh
@@ -6,4 +6,4 @@
<#assign mo2 = "<p>Foo"?no_esc>
${"${mo1} baz"}
-<#attempt>${"${mo2} baz"}<#recover>Failed</#attempt>
\ No newline at end of file
+${"${mo2} baz"}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/fa6ac0ee/src/test/resources/freemarker/manual/AutoEscapingExample-stringLiteral2.ftlh.out
----------------------------------------------------------------------
diff --git a/src/test/resources/freemarker/manual/AutoEscapingExample-stringLiteral2.ftlh.out b/src/test/resources/freemarker/manual/AutoEscapingExample-stringLiteral2.ftlh.out
index bc280c6..b8e929b 100644
--- a/src/test/resources/freemarker/manual/AutoEscapingExample-stringLiteral2.ftlh.out
+++ b/src/test/resources/freemarker/manual/AutoEscapingExample-stringLiteral2.ftlh.out
@@ -1,3 +1,3 @@
Foo & bar baz
-Failed
\ No newline at end of file
+<p>Foo baz
\ No newline at end of file
[09/16] incubator-freemarker git commit: (Some Manual adjustments
regarding string literal interpolations.)
Posted by dd...@apache.org.
(Some Manual adjustments regarding string literal interpolations.)
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/db94e072
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/db94e072
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/db94e072
Branch: refs/heads/2.3
Commit: db94e0726416af827bdd8868f46dcfb75cbebd7b
Parents: 83a30d5
Author: ddekany <dd...@apache.org>
Authored: Sun Oct 4 14:11:03 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sun Oct 4 14:15:16 2015 +0200
----------------------------------------------------------------------
src/manual/book.xml | 40 ++++++++++++++++++++++++++++------------
1 file changed, 28 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/db94e072/src/manual/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/book.xml b/src/manual/book.xml
index 5685b35..75aa34d 100644
--- a/src/manual/book.xml
+++ b/src/manual/book.xml
@@ -2858,6 +2858,12 @@ ${s} <#-- Just to see what the value of s is -->
something like <literal>"someUrl?id=1234"</literal>, regardless
of locale and format settings.</para>
</warning>
+
+ <para>As when <literal>${<replaceable>...</replaceable>}</literal>
+ is used inside string <emphasis>expressions</emphasis> it's just a
+ shorthand of using the <literal>+</literal> operator, <link
+ linkend="dgui_misc_autoescaping">auto-escaping</link> is not
+ applied on it.</para>
</section>
<section xml:id="dgui_template_exp_get_character">
@@ -5271,10 +5277,12 @@ jsmith@other.com, jsmith@other.com, jsmith@other.com</programlisting>
<literal>freemarker.core.OutputFormat</literal> instance)</phrase>.
The output format dictates the escaping rules, which is applied on
all <literal>${<replaceable>...</replaceable>}</literal>-s (and
- <literal>#{<replaceable>...</replaceable>}</literal>-s). It also
- specifies a MIME type (e.g. <literal>"text/HTML"</literal>) and a
- canonical name (e.g. <literal>"HTML"</literal>) that the embedding
- application/framework can leverage for its own purposes.</para>
+ <literal>#{<replaceable>...</replaceable>}</literal>-s) that aren't
+ <link linkend="dgui_misc_autoescaping_stringliteral">inside a string
+ literal</link>. It also specifies a MIME type (e.g.
+ <literal>"text/HTML"</literal>) and a canonical name (e.g.
+ <literal>"HTML"</literal>) that the embedding application/framework
+ can leverage for its own purposes.</para>
<para>It's the programmer's responsibility to <link
linkend="pgui_config_outputformatsautoesc">associate output format
@@ -5702,13 +5710,15 @@ ${"<h1>"?no_esc + "Foo & bar" + "</h1>"?no_esc}</programlisting>
</section>
<section xml:id="dgui_misc_autoescaping_stringliteral">
- <title>Auto-escaping and ${...} inside string literals</title>
+ <title>${...} inside string literals</title>
- <para>A string <emphasis>expression</emphasis> like
- <literal>"Hello ${name}!"</literal> is just a shorthand for
- <literal>"Hello" + name + "!"</literal>, so that
- <literal>${<replaceable>...</replaceable>}</literal> doesn't
- auto-escape.</para>
+ <para>When <literal>${<replaceable>...</replaceable>}</literal> is
+ used inside string <emphasis>expressions</emphasis> (e.g., in
+ <literal><#assign s = "Hello ${name}!"></literal>), it's
+ just a shorthand of using the <literal>+</literal> operator
+ (<literal><#assign s = "Hello" + name + "!"></literal>).
+ Thus, <literal>${<replaceable>...</replaceable>}</literal> inside
+ string expressions isn't auto-escaped.</para>
<programlisting role="template"><#-- We assume that we have "HTML" output format by default. -->
<#assign name = "Foo & Bar">
@@ -5717,13 +5727,13 @@ ${"<h1>"?no_esc + "Foo & bar" + "</h1>"?no_esc}</programlisting>
${s}
<p>Hello ${name}!
-To prove that s didn't contain the value escaped:
+To prove that s didn't contain the value in escaped form:
${s?replace('&'), 'and'}</programlisting>
<programlisting role="output">&lt;p&gt;Hello Foo &amp; Bar!
<p>Hello Foo &amp; Bar!
-To prove that s didn't contain the value escaped:
+To prove that s didn't contain the value in escaped form:
&lt;p&gt;Hello Foo and Bar!</programlisting>
</section>
@@ -26270,6 +26280,12 @@ TemplateModel x = env.getVariable("x"); // get variable x</programlisting>
<para>Added <literal>XHTMLOutputFormat</literal> and
<literal>TemplateXHTMLOutputModel</literal>.</para>
</listitem>
+
+ <listitem>
+ <para>Added new built-in: <literal>is_markup_output</literal>,
+ returns <literal>true</literal> if the value is of type
+ <quote>markup output</quote>.</para>
+ </listitem>
</itemizedlist>
</section>
</section>
[07/16] incubator-freemarker git commit: Added new built-in:
is_markup_output, returns true if the value is of type markup output.
Posted by dd...@apache.org.
Added new built-in: is_markup_output, returns true if the value is of type markup output.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/75fab1f7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/75fab1f7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/75fab1f7
Branch: refs/heads/2.3
Commit: 75fab1f789523ed8513a1aa6b938f6a89e9fe906
Parents: fa6ac0e
Author: ddekany <dd...@apache.org>
Authored: Sun Oct 4 12:45:26 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sun Oct 4 12:45:26 2015 +0200
----------------------------------------------------------------------
src/main/java/freemarker/core/BuiltIn.java | 3 ++-
.../freemarker/core/BuiltInsForMultipleTypes.java | 10 ++++++++++
src/manual/book.xml | 14 ++++++++++++++
src/test/java/freemarker/core/OutputFormatTest.java | 9 +++++++++
4 files changed, 35 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/75fab1f7/src/main/java/freemarker/core/BuiltIn.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BuiltIn.java b/src/main/java/freemarker/core/BuiltIn.java
index 11e9be4..144d70b 100644
--- a/src/main/java/freemarker/core/BuiltIn.java
+++ b/src/main/java/freemarker/core/BuiltIn.java
@@ -77,7 +77,7 @@ abstract class BuiltIn extends Expression implements Cloneable {
protected Expression target;
protected String key;
- static final int NUMBER_OF_BIS = 257;
+ static final int NUMBER_OF_BIS = 259;
static final HashMap builtins = new HashMap(NUMBER_OF_BIS * 3 / 2 + 1, 1f);
static {
// Note that you must update NUMBER_OF_BIS if you add new items here!
@@ -140,6 +140,7 @@ abstract class BuiltIn extends Expression implements Cloneable {
putBI("is_infinite", "isInfinite", new is_infiniteBI());
putBI("is_indexable", "isIndexable", new BuiltInsForMultipleTypes.is_indexableBI());
putBI("is_macro", "isMacro", new BuiltInsForMultipleTypes.is_macroBI());
+ putBI("is_markup_output", "isMarkupOutput", new BuiltInsForMultipleTypes.is_markup_outputBI());
putBI("is_method", "isMethod", new BuiltInsForMultipleTypes.is_methodBI());
putBI("is_nan", "isNan", new is_nanBI());
putBI("is_node", "isNode", new BuiltInsForMultipleTypes.is_nodeBI());
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/75fab1f7/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java b/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
index 4b5d548..a15c3b6 100644
--- a/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
+++ b/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
@@ -391,6 +391,16 @@ class BuiltInsForMultipleTypes {
}
}
+ static class is_markup_outputBI extends BuiltIn {
+ @Override
+ TemplateModel _eval(Environment env) throws TemplateException {
+ TemplateModel tm = target.eval(env);
+ target.assertNonNull(tm, env);
+ return (tm instanceof TemplateMarkupOutputModel) ?
+ TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
+ }
+ }
+
static class is_methodBI extends BuiltIn {
@Override
TemplateModel _eval(Environment env) throws TemplateException {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/75fab1f7/src/manual/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/book.xml b/src/manual/book.xml
index 3546923..5685b35 100644
--- a/src/manual/book.xml
+++ b/src/manual/book.xml
@@ -17168,6 +17168,13 @@ Sorted by name.last:
<td>node</td>
</tr>
+
+ <tr>
+ <td><literal>is_markup_output</literal></td>
+
+ <td>markup output (a value that won't be <link
+ linkend="dgui_misc_autoescaping">auto-escaped</link>)</td>
+ </tr>
</tbody>
</informaltable>
</section>
@@ -25673,6 +25680,13 @@ TemplateModel x = env.getVariable("x"); // get variable x</programlisting>
</listitem>
<listitem>
+ <para>Added new built-in:
+ <literal>is_markup_output</literal>, returns
+ <literal>true</literal> if the value is of type
+ <quote>markup output</quote>.</para>
+ </listitem>
+
+ <listitem>
<para>New directive: <literal>outputformat</literal>, used
to change the output format for a section of a template,
like <literal><#outputformat
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/75fab1f7/src/test/java/freemarker/core/OutputFormatTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/OutputFormatTest.java b/src/test/java/freemarker/core/OutputFormatTest.java
index b36761e..b596437 100644
--- a/src/test/java/freemarker/core/OutputFormatTest.java
+++ b/src/test/java/freemarker/core/OutputFormatTest.java
@@ -991,6 +991,15 @@ public class OutputFormatTest extends TemplateTest {
assertErrorContains(ftl, InvalidReferenceException.class, "noSuchVar", "null or missing");
}
}
+
+ @Test
+ public void testIsMarkupOutputBI() throws Exception {
+ addToDataModel("m1", HTMLOutputFormat.INSTANCE.fromPlainTextByEscaping("x"));
+ addToDataModel("m2", HTMLOutputFormat.INSTANCE.fromMarkup("x"));
+ addToDataModel("s", "x");
+ assertOutput("${m1?isMarkupOutput?c} ${m2?isMarkupOutput?c} ${s?isMarkupOutput?c}", "true true false");
+ assertOutput("${m1?is_markup_output?c}", "true");
+ }
@Override
protected Configuration createConfiguration() throws TemplateModelException {
[10/16] incubator-freemarker git commit: (Added a date format test
for a markup producing format.)
Posted by dd...@apache.org.
(Added a date format test for a markup producing format.)
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/dd545946
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/dd545946
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/dd545946
Branch: refs/heads/2.3
Commit: dd54594617cd382b60c6113649c7717b20cd54b8
Parents: db94e07
Author: ddekany <dd...@apache.org>
Authored: Sun Oct 4 16:31:21 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sun Oct 4 16:31:21 2015 +0200
----------------------------------------------------------------------
src/test/java/freemarker/core/DateFormatTest.java | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/dd545946/src/test/java/freemarker/core/DateFormatTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/DateFormatTest.java b/src/test/java/freemarker/core/DateFormatTest.java
index b36a97f..6902b95 100644
--- a/src/test/java/freemarker/core/DateFormatTest.java
+++ b/src/test/java/freemarker/core/DateFormatTest.java
@@ -62,7 +62,8 @@ public class DateFormatTest extends TemplateTest {
"epoch", EpochMillisTemplateDateFormatFactory.INSTANCE,
"loc", LocAndTZSensitiveTemplateDateFormatFactory.INSTANCE,
"div", EpochMillisDivTemplateDateFormatFactory.INSTANCE,
- "appMeta", AppMetaTemplateDateFormatFactory.INSTANCE));
+ "appMeta", AppMetaTemplateDateFormatFactory.INSTANCE,
+ "htmlIso", HTMLISOTemplateDateFormatFactory.INSTANCE));
}
@Test
@@ -77,6 +78,14 @@ public class DateFormatTest extends TemplateTest {
"<#assign d = d?datetime>"
+ "${d} ${d?string} <#setting locale='de_DE'>${d}",
"123456789 123456789 123456789");
+
+ getConfiguration().setDateTimeFormat("@htmlIso");
+ assertOutput(
+ "<#assign d = d?datetime>"
+ + "${d} ${d?string} <#setting locale='de_DE'>${d}",
+ "1970-01-02<span class='T'>T</span>10:17:36Z "
+ + "1970-01-02T10:17:36Z "
+ + "1970-01-02<span class='T'>T</span>10:17:36Z");
}
@Test
[03/16] incubator-freemarker git commit: <@ and @ is now allowed in
String literals that contain ${exp},
and will be part of the literal as is. Earlier it was a syntactical error.
Posted by dd...@apache.org.
<@ and </@ is now allowed in String literals that contain ${exp}, and will be part of the literal as is. Earlier it was a syntactical error.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/6ac1b86a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/6ac1b86a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/6ac1b86a
Branch: refs/heads/2.3
Commit: 6ac1b86a48ab9826e5061e497df22ea289b0c17b
Parents: a361243
Author: ddekany <dd...@apache.org>
Authored: Thu Oct 1 12:46:50 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Thu Oct 1 12:46:50 2015 +0200
----------------------------------------------------------------------
src/main/javacc/FTL.jj | 33 +++++++++++++-------
src/manual/book.xml | 8 +++++
.../core/StringLiteralInterpolationTest.java | 14 +++++++++
3 files changed, 44 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6ac1b86a/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj
index e234e90..f65f4c5 100644
--- a/src/main/javacc/FTL.jj
+++ b/src/main/javacc/FTL.jj
@@ -731,6 +731,11 @@ TOKEN_MGR_DECLS:
}
private void unifiedCall(Token tok) {
+ if (onlyTextOutput) {
+ tok.kind = STATIC_TEXT_NON_WS;
+ return;
+ }
+
char firstChar = tok.image.charAt(0);
if (autodetectTagSyntax && !directiveSyntaxEstablished) {
squBracTagSyntax = (firstChar == '[');
@@ -748,6 +753,11 @@ TOKEN_MGR_DECLS:
}
private void unifiedCallEnd(Token tok) {
+ if (onlyTextOutput) {
+ tok.kind = STATIC_TEXT_NON_WS;
+ return;
+ }
+
char firstChar = tok.image.charAt(0);
if (squBracTagSyntax && firstChar == '<') {
tok.kind = STATIC_TEXT_NON_WS;
@@ -2225,19 +2235,20 @@ StringLiteral StringLiteral(boolean interpolate) :
t = <RAW_STRING> { raw = true; }
)
{
- String s = t.image;
+ String s;
// Get rid of the quotes.
- s = s.substring(1, s.length() -1);
if (raw) {
- s = s.substring(1);
- } else try {
- s = StringUtil.FTLStringLiteralDec(s);
- } catch (ParseException pe) {
- pe.lineNumber = t.beginLine;
- pe.columnNumber = t.beginColumn;
- pe.endLineNumber = t.endLine;
- pe.endColumnNumber = t.endColumn;
- throw pe;
+ s = t.image.substring(2, t.image.length() -1);
+ } else {
+ try {
+ s = StringUtil.FTLStringLiteralDec(t.image.substring(1, t.image.length() -1));
+ } catch (ParseException pe) {
+ pe.lineNumber = t.beginLine;
+ pe.columnNumber = t.beginColumn;
+ pe.endLineNumber = t.endLine;
+ pe.endColumnNumber = t.endColumn;
+ throw pe;
+ }
}
StringLiteral result = new StringLiteral(s);
result.setLocation(template, t, t);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6ac1b86a/src/manual/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/book.xml b/src/manual/book.xml
index b8bc656..6decbd9 100644
--- a/src/manual/book.xml
+++ b/src/manual/book.xml
@@ -25810,6 +25810,14 @@ TemplateModel x = env.getVariable("x"); // get variable x</programlisting>
keeping the exact class can be important in some
applications.</para>
</listitem>
+
+ <listitem>
+ <para><literal><@</literal> and <literal></@</literal> is
+ now allowed in String literals that contain
+ <literal>${<replaceable>exp</replaceable>}</literal>, and will
+ be part of the literal as is. Earlier it was a syntactical
+ error.</para>
+ </listitem>
</itemizedlist>
</section>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6ac1b86a/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/StringLiteralInterpolationTest.java b/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
index 6abe579..e6d86e4 100644
--- a/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
+++ b/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
@@ -34,6 +34,20 @@ public class StringLiteralInterpolationTest extends TemplateTest {
assertOutput("<#assign x = 1>${'${x} ${x}'}", "1 1");
assertOutput("<#assign x = 1>${'$\\{x}'}", "${x}");
assertOutput("<#assign x = 1>${'$\\{x} $\\{x}'}", "${x} ${x}");
+ assertOutput("<#assign x = 1>${'<#-- not a comment -->${x}'}", "<#-- not a comment -->1");
+ assertOutput("<#assign x = 1>${'<#-- not a comment -->$\\{x}'}", "<#-- not a comment -->${x}");
+ assertOutput("<#assign x = 1>${'<@x/>${x}'}", "<@x/>1");
+ assertOutput("<#assign x = 1>${'<@x/>$\\{x}'}", "<@x/>${x}");
+ assertOutput("<#assign x = 1>${'<@ ${x}<@'}", "<@ 1<@");
+ assertOutput("<#assign x = 1>${'<@ $\\{x}<@'}", "<@ ${x}<@");
+ assertOutput("<#assign x = 1>${'</...@x>${x}'}", "</...@x>1");
+ assertOutput("<#assign x = 1>${'</...@x>$\\{x}'}", "</...@x>${x}");
+ assertOutput("<#assign x = 1>${'</@ ${x}</@'}", "</@ 1</@");
+ assertOutput("<#assign x = 1>${'</@ $\\{x}</@'}", "</@ ${x}</@");
+ assertOutput("<#assign x = 1>${'[@ ${x}'}", "[@ 1");
+ assertOutput("<#assign x = 1>${'[@ $\\{x}'}", "[@ ${x}");
+ assertOutput("<#assign x = 1>${'<#assign x = 2> ${x}'}", "<#assign x = 2> 1");
+ assertOutput("<#assign x = 1>${'<#assign x = 2> $\\{x}'}", "<#assign x = 2> ${x}");
}
/**
[04/16] incubator-freemarker git commit: Simplified static text
parsing
Posted by dd...@apache.org.
Simplified static text parsing
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/6802cc71
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/6802cc71
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/6802cc71
Branch: refs/heads/2.3
Commit: 6802cc7110d796c841f4d49d401dda1c3f78048a
Parents: 6ac1b86
Author: ddekany <dd...@apache.org>
Authored: Thu Oct 1 14:17:11 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Thu Oct 1 14:17:11 2015 +0200
----------------------------------------------------------------------
src/main/javacc/FTL.jj | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/6802cc71/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj
index f65f4c5..a3c5870 100644
--- a/src/main/javacc/FTL.jj
+++ b/src/main/javacc/FTL.jj
@@ -3893,9 +3893,7 @@ TextBlock PCData() :
}
{
(
- LOOKAHEAD(<STATIC_TEXT_WS>|<STATIC_TEXT_NON_WS>|<STATIC_TEXT_FALSE_ALARM>)
(
- { prevToken = t; }
t = <STATIC_TEXT_WS>
|
t = <STATIC_TEXT_NON_WS>
@@ -3906,6 +3904,7 @@ TextBlock PCData() :
buf.append(t.image);
if (start == null) start = t;
if (prevToken != null) prevToken.next = null;
+ prevToken = t;
}
)+
{
[08/16] incubator-freemarker git commit: Some more markup string
literal interpolation tests
Posted by dd...@apache.org.
Some more markup string literal interpolation tests
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/83a30d5a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/83a30d5a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/83a30d5a
Branch: refs/heads/2.3
Commit: 83a30d5ae03b76ef637cda926ed13009e8fc0294
Parents: 75fab1f
Author: ddekany <dd...@apache.org>
Authored: Sun Oct 4 13:58:20 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sun Oct 4 13:58:20 2015 +0200
----------------------------------------------------------------------
.../core/StringLiteralInterpolationTest.java | 13 +++++++++++++
1 file changed, 13 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/83a30d5a/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/StringLiteralInterpolationTest.java b/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
index b7bfeee..fc66013 100644
--- a/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
+++ b/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
@@ -111,6 +111,19 @@ public class StringLiteralInterpolationTest extends TemplateTest {
assertOutput("${\"${1000}, ${2000}\"}", "1.00*10<sup>3</sup>, 2.00*10<sup>3</sup>");
assertOutput("${\"& ${'x'}, ${2000}\"}", "& x, 2.00*10<sup>3</sup>");
assertOutput("${\"& ${'x'}, #{2000}\"}", "& x, 2000");
+
+ assertOutput("${\"${2000}\"?isMarkupOutput?c}", "true");
+ assertOutput("${\"x ${2000}\"?isMarkupOutput?c}", "true");
+ assertOutput("${\"${2000} x\"?isMarkupOutput?c}", "true");
+ assertOutput("${\"#{2000}\"?isMarkupOutput?c}", "false");
+ assertOutput("${\"${'x'}\"?isMarkupOutput?c}", "false");
+ assertOutput("${\"x ${'x'}\"?isMarkupOutput?c}", "false");
+ assertOutput("${\"${'x'} x\"?isMarkupOutput?c}", "false");
+
+ addToDataModel("rtf", RTFOutputFormat.INSTANCE.fromMarkup("\\p"));
+ assertOutput("${\"${rtf}\"?isMarkupOutput?c}", "true");
+ assertErrorContains("${\"${1000}${rtf}\"}", TemplateException.class, "HTML", "RTF", "onversion");
+ assertErrorContains("x${\"${1000}${rtf}\"}", TemplateException.class, "HTML", "RTF", "onversion");
}
}
[16/16] incubator-freemarker git commit: Merge remote-tracking branch
'origin/2.3-gae' into 2.3
Posted by dd...@apache.org.
Merge remote-tracking branch 'origin/2.3-gae' into 2.3
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/d07ad04c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/d07ad04c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/d07ad04c
Branch: refs/heads/2.3
Commit: d07ad04ceb1e735af3f216c101632ed7e37a0844
Parents: a8814b8 8adee32
Author: ddekany <dd...@apache.org>
Authored: Sun Oct 4 21:16:07 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sun Oct 4 21:16:07 2015 +0200
----------------------------------------------------------------------
.../core/ExtendedDecimalFormatParser.java | 44 +++---
src/manual/book.xml | 150 +++++++++++--------
.../core/ExtendedDecimalFormatTest.java | 139 +++++++++--------
3 files changed, 188 insertions(+), 145 deletions(-)
----------------------------------------------------------------------
[13/16] incubator-freemarker git commit: (Added unknown date-type
test)
Posted by dd...@apache.org.
(Added unknown date-type test)
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/1e905a47
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/1e905a47
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/1e905a47
Branch: refs/heads/2.3
Commit: 1e905a47da788a9e0d5fa5b820e6250bc0980c1a
Parents: 43007bf
Author: ddekany <dd...@apache.org>
Authored: Sun Oct 4 16:44:42 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sun Oct 4 16:44:42 2015 +0200
----------------------------------------------------------------------
src/test/java/freemarker/core/DateFormatTest.java | 8 ++++++++
1 file changed, 8 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1e905a47/src/test/java/freemarker/core/DateFormatTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/DateFormatTest.java b/src/test/java/freemarker/core/DateFormatTest.java
index 6902b95..20b2cc9 100644
--- a/src/test/java/freemarker/core/DateFormatTest.java
+++ b/src/test/java/freemarker/core/DateFormatTest.java
@@ -428,6 +428,14 @@ public class DateFormatTest extends TemplateTest {
T + " " + T + "/foo");
}
+ @Test
+ public void testUnknownDateType() throws IOException, TemplateException {
+ addToDataModel("u", new Date(T));
+ assertErrorContains("${u?string}", "isn't known");
+ assertOutput("${u?string('yyyy')}", "2015");
+ assertOutput("<#assign s = u?string>${s('yyyy')}", "2015");
+ }
+
private static class MutableTemplateDateModel implements TemplateDateModel {
private Date date;
[12/16] incubator-freemarker git commit: (Minor code cleanup)
Posted by dd...@apache.org.
(Minor code cleanup)
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/43007bfe
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/43007bfe
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/43007bfe
Branch: refs/heads/2.3
Commit: 43007bfed4b663e76d99aa77735a42e7a354acc1
Parents: 14fab44
Author: ddekany <dd...@apache.org>
Authored: Sun Oct 4 16:44:24 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sun Oct 4 16:44:24 2015 +0200
----------------------------------------------------------------------
.../freemarker/core/BuiltInsForMultipleTypes.java | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/43007bfe/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java b/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
index a15c3b6..861b370 100644
--- a/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
+++ b/src/main/java/freemarker/core/BuiltInsForMultipleTypes.java
@@ -580,14 +580,14 @@ class BuiltInsForMultipleTypes {
public String getAsString()
throws TemplateModelException {
if (cachedValue == null) {
- try {
- if (defaultFormat == null) {
- if (dateModel.getDateType() == TemplateDateModel.UNKNOWN) {
- throw MessageUtil.newCantFormatUnknownTypeDateException(target, null);
- } else {
- throw new BugException();
- }
+ if (defaultFormat == null) {
+ if (dateModel.getDateType() == TemplateDateModel.UNKNOWN) {
+ throw MessageUtil.newCantFormatUnknownTypeDateException(target, null);
+ } else {
+ throw new BugException();
}
+ }
+ try {
cachedValue = EvalUtil.assertFormatResultNotNull(defaultFormat.formatToPlainText(dateModel));
} catch (TemplateValueFormatException e) {
try {
[05/16] incubator-freemarker git commit: Reworked how ${...}-s are
lexed a bit,
to make the lexing of string literals (which may contain ${...}) more
manageable.
Posted by dd...@apache.org.
Reworked how ${...}-s are lexed a bit, to make the lexing of string literals (which may contain ${...}) more manageable.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/d8487ffe
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/d8487ffe
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/d8487ffe
Branch: refs/heads/2.3
Commit: d8487ffee38a1fd3ab9291c9174d8f7e7ce15be8
Parents: 6802cc7
Author: ddekany <dd...@apache.org>
Authored: Thu Oct 1 16:20:45 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Fri Oct 2 00:07:17 2015 +0200
----------------------------------------------------------------------
src/main/javacc/FTL.jj | 57 +++++++++++++-------
.../core/ParsingErrorMessagesTest.java | 7 +++
.../core/StringLiteralInterpolationTest.java | 55 ++++++++++++-------
3 files changed, 79 insertions(+), 40 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d8487ffe/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj
index a3c5870..9c6bae1 100644
--- a/src/main/javacc/FTL.jj
+++ b/src/main/javacc/FTL.jj
@@ -255,10 +255,11 @@ public class FMParser {
}
void setupStringLiteralMode(FMParserTokenManager parentTokenSource) {
- token_source.onlyTextOutput = true;
token_source.initialNamingConvention = parentTokenSource.initialNamingConvention;
token_source.namingConvention = parentTokenSource.namingConvention;
token_source.namingConventionEstabilisher = parentTokenSource.namingConventionEstabilisher;
+ token_source.SwitchTo(NODIRECTIVE);
+
outputFormat = PlainTextOutputFormat.INSTANCE;
recalculateAutoEscapingField();
if (incompatibleImprovements < _TemplateAPI.VERSION_INT_2_3_24) {
@@ -578,12 +579,12 @@ TOKEN_MGR_DECLS:
* distinguish the } used to close a hash literal and the one used to close a ${
*/
private FMParser parser;
+ private int postInterpolationLexState = -1;
private int hashLiteralNesting;
private int parenthesisNesting;
private int bracketNesting;
private boolean inFTLHeader;
boolean strictEscapeSyntax,
- onlyTextOutput,
squBracTagSyntax,
autodetectTagSyntax,
directiveSyntaxEstablished,
@@ -602,11 +603,6 @@ TOKEN_MGR_DECLS:
// tag syntax detection. If you update this logic, take a look
// at the UNKNOWN_DIRECTIVE token too.
private void strictSyntaxCheck(Token tok, int tokenNamingConvention, int newLexState) {
- if (onlyTextOutput) {
- tok.kind = STATIC_TEXT_NON_WS;
- return;
- }
-
final String image = tok.image;
// Non-strict syntax (deprecated) only supports legacy naming convention.
@@ -731,11 +727,6 @@ TOKEN_MGR_DECLS:
}
private void unifiedCall(Token tok) {
- if (onlyTextOutput) {
- tok.kind = STATIC_TEXT_NON_WS;
- return;
- }
-
char firstChar = tok.image.charAt(0);
if (autodetectTagSyntax && !directiveSyntaxEstablished) {
squBracTagSyntax = (firstChar == '[');
@@ -753,11 +744,6 @@ TOKEN_MGR_DECLS:
}
private void unifiedCallEnd(Token tok) {
- if (onlyTextOutput) {
- tok.kind = STATIC_TEXT_NON_WS;
- return;
- }
-
char firstChar = tok.image.charAt(0);
if (squBracTagSyntax && firstChar == '<') {
tok.kind = STATIC_TEXT_NON_WS;
@@ -781,6 +767,37 @@ TOKEN_MGR_DECLS:
SwitchTo(DEFAULT);
}
}
+
+ private void startInterpolation(Token tok) {
+ if (postInterpolationLexState != -1) {
+ char c = tok.image.charAt(0);
+ throw new TokenMgrError(
+ "You can't start an interpolation (" + c + "{...}) here "
+ + "as you are inside another interpolation.)",
+ TokenMgrError.LEXICAL_ERROR,
+ tok.beginLine, tok.beginColumn,
+ tok.endLine, tok.endColumn);
+ }
+ postInterpolationLexState = curLexState;
+ SwitchTo(FM_EXPRESSION);
+ }
+
+ /**
+ * @param tok
+ * Assumed to be an '}', or something that is the closing pair of another "mirror image" character.
+ */
+ private void endInterpolation(Token tok) {
+ if (postInterpolationLexState == -1) {
+ char c = tok.image.charAt(0);
+ throw new TokenMgrError(
+ "You can't have an \"" + c + "\" here, as there's nothing open that it could close.",
+ TokenMgrError.LEXICAL_ERROR,
+ tok.beginLine, tok.beginColumn,
+ tok.endLine, tok.endColumn);
+ }
+ SwitchTo(postInterpolationLexState);
+ postInterpolationLexState = -1;
+ }
private void eatNewline() {
int charsRead = 0;
@@ -1096,9 +1113,9 @@ TOKEN:
|
<STATIC_TEXT_FALSE_ALARM : "$" | "#" | "<" | "[" | "{"> // to handle a lone dollar sign or "<" or "# or <@ with whitespace after"
|
- <DOLLAR_INTERPOLATION_OPENING : "${"> : FM_EXPRESSION
+ <DOLLAR_INTERPOLATION_OPENING : "${"> { startInterpolation(matchedToken); }
|
- <HASH_INTERPOLATION_OPENING : "#{"> : FM_EXPRESSION
+ <HASH_INTERPOLATION_OPENING : "#{"> { startInterpolation(matchedToken); }
}
<FM_EXPRESSION, IN_PAREN, NAMED_PARAMETER_EXPRESSION> SKIP :
@@ -1259,7 +1276,7 @@ TOKEN:
|
<CLOSING_CURLY_BRACKET : "}">
{
- if (hashLiteralNesting == 0) SwitchTo(DEFAULT);
+ if (hashLiteralNesting == 0) endInterpolation(matchedToken);
else --hashLiteralNesting;
}
|
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d8487ffe/src/test/java/freemarker/core/ParsingErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/ParsingErrorMessagesTest.java b/src/test/java/freemarker/core/ParsingErrorMessagesTest.java
index d528675..f34ddf2 100644
--- a/src/test/java/freemarker/core/ParsingErrorMessagesTest.java
+++ b/src/test/java/freemarker/core/ParsingErrorMessagesTest.java
@@ -74,6 +74,13 @@ public class ParsingErrorMessagesTest {
assertErrorContains("${blah", "\"{\"", "unclosed");
}
+ @Test
+ public void testInterpolatingClosingsErrors() {
+ assertErrorContains("${x", "unclosed");
+ assertErrorContains("<#assign x = x}>", "\"}\"", "open");
+ // TODO assertErrorContains("<#assign x = '${x'>", "unclosed");
+ }
+
private void assertErrorContains(String ftl, String... expectedSubstrings) {
assertErrorContains(false, ftl, expectedSubstrings);
assertErrorContains(true, ftl, expectedSubstrings);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/d8487ffe/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/StringLiteralInterpolationTest.java b/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
index e6d86e4..fd6fb14 100644
--- a/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
+++ b/src/test/java/freemarker/core/StringLiteralInterpolationTest.java
@@ -26,28 +26,33 @@ import freemarker.template.Configuration;
import freemarker.template.TemplateException;
import freemarker.test.TemplateTest;
+@SuppressWarnings("boxing")
public class StringLiteralInterpolationTest extends TemplateTest {
@Test
public void basics() throws IOException, TemplateException {
- assertOutput("<#assign x = 1>${'${x}'}", "1");
- assertOutput("<#assign x = 1>${'${x} ${x}'}", "1 1");
- assertOutput("<#assign x = 1>${'$\\{x}'}", "${x}");
- assertOutput("<#assign x = 1>${'$\\{x} $\\{x}'}", "${x} ${x}");
- assertOutput("<#assign x = 1>${'<#-- not a comment -->${x}'}", "<#-- not a comment -->1");
- assertOutput("<#assign x = 1>${'<#-- not a comment -->$\\{x}'}", "<#-- not a comment -->${x}");
- assertOutput("<#assign x = 1>${'<@x/>${x}'}", "<@x/>1");
- assertOutput("<#assign x = 1>${'<@x/>$\\{x}'}", "<@x/>${x}");
- assertOutput("<#assign x = 1>${'<@ ${x}<@'}", "<@ 1<@");
- assertOutput("<#assign x = 1>${'<@ $\\{x}<@'}", "<@ ${x}<@");
- assertOutput("<#assign x = 1>${'</...@x>${x}'}", "</...@x>1");
- assertOutput("<#assign x = 1>${'</...@x>$\\{x}'}", "</...@x>${x}");
- assertOutput("<#assign x = 1>${'</@ ${x}</@'}", "</@ 1</@");
- assertOutput("<#assign x = 1>${'</@ $\\{x}</@'}", "</@ ${x}</@");
- assertOutput("<#assign x = 1>${'[@ ${x}'}", "[@ 1");
- assertOutput("<#assign x = 1>${'[@ $\\{x}'}", "[@ ${x}");
- assertOutput("<#assign x = 1>${'<#assign x = 2> ${x}'}", "<#assign x = 2> 1");
- assertOutput("<#assign x = 1>${'<#assign x = 2> $\\{x}'}", "<#assign x = 2> ${x}");
+ addToDataModel("x", 1);
+ assertOutput("${'${x}'}", "1");
+ assertOutput("${'#{x}'}", "1");
+ assertOutput("${'a${x}b${x*2}c'}", "a1b2c");
+ assertOutput("${'a#{x}b#{x*2}c'}", "a1b2c");
+ assertOutput("${'${x} ${x}'}", "1 1");
+ assertOutput("${'$\\{x}'}", "${x}");
+ assertOutput("${'$\\{x} $\\{x}'}", "${x} ${x}");
+ assertOutput("${'<#-- not a comment -->${x}'}", "<#-- not a comment -->1");
+ assertOutput("${'<#-- not a comment -->$\\{x}'}", "<#-- not a comment -->${x}");
+ assertOutput("${'<#assign x = 2> ${x} <#assign x = 2>'}", "<#assign x = 2> 1 <#assign x = 2>");
+ assertOutput("${'<#assign x = 2> $\\{x} <#assign x = 2>'}", "<#assign x = 2> ${x} <#assign x = 2>");
+ assertOutput("${'<@x/>${x}<@x/>'}", "<@x/>1<@x/>");
+ assertOutput("${'<@x/>$\\{x}<@x/>'}", "<@x/>${x}<@x/>");
+ assertOutput("${'<@ ${x}<@'}", "<@ 1<@");
+ assertOutput("${'<@ $\\{x}<@'}", "<@ ${x}<@");
+ assertOutput("${'</...@x>${x}'}", "</...@x>1");
+ assertOutput("${'</...@x>$\\{x}'}", "</...@x>${x}");
+ assertOutput("${'</@ ${x}</@'}", "</@ 1</@");
+ assertOutput("${'</@ $\\{x}</@'}", "</@ ${x}</@");
+ assertOutput("${'[@ ${x}'}", "[@ 1");
+ assertOutput("${'[@ $\\{x}'}", "[@ ${x}");
}
/**
@@ -55,8 +60,18 @@ public class StringLiteralInterpolationTest extends TemplateTest {
*/
@Test
public void legacyEscapingBugStillPresent() throws IOException, TemplateException {
- assertOutput("<#assign x = 1>${'$\\{x} ${x}'}", "1 1");
- assertOutput("<#assign x = 1>${'${x} $\\{x}'}", "1 1");
+ addToDataModel("x", 1);
+ assertOutput("${'$\\{x} ${x}'}", "1 1");
+ assertOutput("${'${x} $\\{x}'}", "1 1");
+ }
+
+ @Test
+ public void legacyLengthGlitch() throws IOException, TemplateException {
+ assertOutput("${'${'}", "${");
+ assertOutput("${'${1'}", "${1");
+ assertOutput("${'${}'}", "${}");
+ assertOutput("${'${1}'}", "1");
+ assertErrorContains("${'${ '}", "");
}
@Test
[14/16] incubator-freemarker git commit: Merge remote-tracking branch
'origin/2.3-gae' into 2.3
Posted by dd...@apache.org.
Merge remote-tracking branch 'origin/2.3-gae' into 2.3
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/a8814b88
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/a8814b88
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/a8814b88
Branch: refs/heads/2.3
Commit: a8814b8803a4cafe857924419cda475bf5ad07ec
Parents: 4b1550e 1e905a4
Author: ddekany <dd...@apache.org>
Authored: Sun Oct 4 16:45:42 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sun Oct 4 16:45:42 2015 +0200
----------------------------------------------------------------------
README.txt | 4 +-
.../freemarker/core/AddConcatExpression.java | 32 +---
src/main/java/freemarker/core/BuiltIn.java | 3 +-
.../core/BuiltInsForMultipleTypes.java | 24 ++-
.../java/freemarker/core/DollarVariable.java | 10 +-
src/main/java/freemarker/core/EvalUtil.java | 28 +++-
.../java/freemarker/core/Interpolation.java | 9 ++
.../java/freemarker/core/NumericalOutput.java | 18 ++-
.../java/freemarker/core/ParameterRole.java | 1 +
.../java/freemarker/core/StringLiteral.java | 105 +++++++-----
src/main/javacc/FTL.jj | 139 +++++++++++++---
src/manual/book.xml | 158 +++++++++++--------
.../freemarker/core/CoercionToTextualTest.java | 119 ++++++++++++++
.../freemarker/core/CorectionToTextualTest.java | 119 --------------
.../java/freemarker/core/DateFormatTest.java | 19 ++-
.../java/freemarker/core/NumberFormatTest.java | 4 +-
.../java/freemarker/core/OutputFormatTest.java | 32 +++-
.../core/ParsingErrorMessagesTest.java | 7 +
.../core/StringLiteralInterpolationTest.java | 77 ++++++++-
src/test/java/freemarker/test/TemplateTest.java | 6 +-
src/test/resources/freemarker/core/ast-1.ast | 19 +--
.../resources/freemarker/core/ast-builtins.ast | 3 -
.../resources/freemarker/core/ast-range.ast | 2 -
.../freemarker/core/ast-strlitinterpolation.ast | 72 +++++++--
.../freemarker/core/ast-strlitinterpolation.ftl | 8 +-
.../AutoEscapingExample-stringLiteral2.ftlh | 2 +-
.../AutoEscapingExample-stringLiteral2.ftlh.out | 2 +-
27 files changed, 677 insertions(+), 345 deletions(-)
----------------------------------------------------------------------
[15/16] incubator-freemarker git commit: The extended decimal format
options don't use abbreviations anymore. Like instead of rnd=hu,
now there's roundingMode=halfUp.
Posted by dd...@apache.org.
The extended decimal format options don't use abbreviations anymore. Like instead of rnd=hu, now there's roundingMode=halfUp.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/8adee326
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/8adee326
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/8adee326
Branch: refs/heads/2.3
Commit: 8adee326161c928aaa02525bc84b7293d86262cd
Parents: 1e905a4
Author: ddekany <dd...@apache.org>
Authored: Sun Oct 4 16:44:42 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sun Oct 4 21:14:09 2015 +0200
----------------------------------------------------------------------
.../core/ExtendedDecimalFormatParser.java | 44 +++---
src/manual/book.xml | 150 +++++++++++--------
.../core/ExtendedDecimalFormatTest.java | 139 +++++++++--------
3 files changed, 188 insertions(+), 145 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8adee326/src/main/java/freemarker/core/ExtendedDecimalFormatParser.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/ExtendedDecimalFormatParser.java b/src/main/java/freemarker/core/ExtendedDecimalFormatParser.java
index 76484cf..8824531 100644
--- a/src/main/java/freemarker/core/ExtendedDecimalFormatParser.java
+++ b/src/main/java/freemarker/core/ExtendedDecimalFormatParser.java
@@ -32,29 +32,29 @@ import freemarker.template.utility.StringUtil;
class ExtendedDecimalFormatParser {
- private static final String PARAM_ROUNDING_MODE = "rnd";
- private static final String PARAM_MULTIPIER = "mul";
- private static final String PARAM_DECIMAL_SEPARATOR = "dec";
- private static final String PARAM_MONETARY_DECIMAL_SEPARATOR = "mdec";
- private static final String PARAM_GROUP_SEPARATOR = "grp";
- private static final String PARAM_EXPONENT_SEPARATOR = "exp";
- private static final String PARAM_MINUS_SIGN = "min";
- private static final String PARAM_INFINITY = "inf";
+ private static final String PARAM_ROUNDING_MODE = "roundingMode";
+ private static final String PARAM_MULTIPIER = "multipier";
+ private static final String PARAM_DECIMAL_SEPARATOR = "decimalSeparator";
+ private static final String PARAM_MONETARY_DECIMAL_SEPARATOR = "monetaryDecimalSeparator";
+ private static final String PARAM_GROUP_SEPARATOR = "groupingSeparator";
+ private static final String PARAM_EXPONENT_SEPARATOR = "exponentSeparator";
+ private static final String PARAM_MINUS_SIGN = "minusSign";
+ private static final String PARAM_INFINITY = "infinity";
private static final String PARAM_NAN = "nan";
- private static final String PARAM_PERCENT = "prc";
- private static final String PARAM_PER_MILL = "prm";
- private static final String PARAM_ZERO_DIGIT = "zero";
- private static final String PARAM_CURRENCY_CODE = "curc";
- private static final String PARAM_CURRENCY_SYMBOL = "curs";
-
- private static final String PARAM_VALUE_RND_UP = "u";
- private static final String PARAM_VALUE_RND_DOWN = "d";
- private static final String PARAM_VALUE_RND_CEILING = "c";
- private static final String PARAM_VALUE_RND_FLOOR = "f";
- private static final String PARAM_VALUE_RND_HALF_DOWN = "hd";
- private static final String PARAM_VALUE_RND_HALF_EVEN = "he";
- private static final String PARAM_VALUE_RND_HALF_UP = "hu";
- private static final String PARAM_VALUE_RND_UNNECESSARY = "un";
+ private static final String PARAM_PERCENT = "percent";
+ private static final String PARAM_PER_MILL = "perMill";
+ private static final String PARAM_ZERO_DIGIT = "zeroDigit";
+ private static final String PARAM_CURRENCY_CODE = "currencyCode";
+ private static final String PARAM_CURRENCY_SYMBOL = "currencySymbol";
+
+ private static final String PARAM_VALUE_RND_UP = "up";
+ private static final String PARAM_VALUE_RND_DOWN = "down";
+ private static final String PARAM_VALUE_RND_CEILING = "ceiling";
+ private static final String PARAM_VALUE_RND_FLOOR = "floor";
+ private static final String PARAM_VALUE_RND_HALF_DOWN = "halfDown";
+ private static final String PARAM_VALUE_RND_HALF_EVEN = "halfEven";
+ private static final String PARAM_VALUE_RND_HALF_UP = "halfUp";
+ private static final String PARAM_VALUE_RND_UNNECESSARY = "unnecessary";
private static final HashMap<String, ? extends ParameterHandler> PARAM_HANDLERS;
static {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8adee326/src/manual/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/book.xml b/src/manual/book.xml
index 75aa34d..da26c70 100644
--- a/src/manual/book.xml
+++ b/src/manual/book.xml
@@ -14550,15 +14550,17 @@ German people write: 12.345.678,00</programlisting>
0.0"</literal>), the after only one semicolon. For example:</para>
<programlisting role="template">Standard decimal format: ${10002.5?string[",000"]}
-Extended decimal format: ${10002.5?string[",000<emphasis>;; rnd=hu grp=_</emphasis>"]}</programlisting>
+Extended decimal format: ${10002.5?string[",000<emphasis>;; roundingMode=halfUp groupingSeparator=_</emphasis>"]}</programlisting>
<programlisting role="output">Standard decimal format: 10,002
Extended decimal format: 10<emphasis>_</emphasis>00<emphasis>3</emphasis></programlisting>
<para>Above, in the extended decimal format, we have specified
- half-up rounding mode (<literal>rnd=hu</literal>), and group
- separator <literal>"_"</literal> (<literal>grp=_</literal>). The
- table of all options:</para>
+ half-up rounding mode and group separator <literal>"_"</literal>.
+ The table of all options follows (note that these are defined by
+ <literal>java.text.DecimalFormat</literal> and
+ <literal>java.text.DecimalFormatSymbols</literal>, not by
+ FreeMarker):</para>
<informaltable border="1">
<thead>
@@ -14571,101 +14573,120 @@ Extended decimal format: 10<emphasis>_</emphasis>00<emphasis>3</emphasis></progr
<tbody>
<tr>
- <td><literal>rnd</literal></td>
-
- <td>Rounding mode. The value is one of <literal>u</literal>
- for up, <literal>d</literal> for down, <literal>c</literal>
- for ceiling, <literal>f</literal> for floor,
- <literal>hu</literal> for half-up, <literal>hd</literal> for
- half-down, <literal>he</literal> for half-even, and
- <literal>un</literal> for unused. (See <link
+ <td><literal>roundingMode</literal></td>
+
+ <td>The value is one of <literal>up</literal>,
+ <literal>down</literal>, <literal>ceiling</literal>,
+ <literal>floor</literal>, <literal>halfUp</literal>,
+ <literal>halfDown</literal>, <literal>halfEven</literal>,
+ and <literal>unnecessary</literal>. The behavior that most
+ people learns in school is <literal>halfUp</literal>, but
+ the Java default is <literal>halfEven</literal> (also called
+ bankers' rounding). (See <link
xlink:href="http://docs.oracle.com/javase/7/docs/api/java/math/RoundingMode.html">the
<literal>java.math.RoundingMode</literal> API</link> for
explanations.)</td>
</tr>
<tr>
- <td><literal>mul</literal></td>
+ <td><literal>multipier</literal></td>
- <td>Multiplier. The number will be shown after multiplied
- with this integer number.</td>
+ <td>The number will be shown after multiplied with this
+ integer number.</td>
</tr>
<tr>
- <td><literal>dec</literal></td>
+ <td><literal>decimalSeparator</literal></td>
- <td>Decimal separator character (like <literal>"."</literal>
- in <literal>3.14</literal>).</td>
+ <td>The character separating the integer part from the
+ fraction part (like <literal>"."</literal> in
+ <literal>3.14</literal>).</td>
</tr>
<tr>
- <td><literal>mdec</literal></td>
+ <td><literal>monetaryDecimalSeparator</literal></td>
- <td>Monetary decimal separator character. This is used
- instead of <literal>dec</literal> when the pattern contains
- parts that make it a monetary format. (See the <link
+ <td>This is used instead of
+ <literal>decimalSeparator</literal> when the pattern
+ contains parts that make it a monetary format. (See the
+ <link
xlink:href="http://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html">Java
decimal number format documentation</link> for more.)</td>
</tr>
<tr>
- <td><literal>grp</literal></td>
-
- <td>Grouping separator character. Note that grouping is
- turned on by using <literal>","</literal> in the pattern, as
- shown in the earlier example. If it's not turned on, this
- option won't have visible effect.</td>
+ <td><literal>groupingSeparator</literal></td>
+
+ <td>The single character used for grouping the integer part
+ (like <literal>","</literal> in
+ <literal>1,000,000</literal>) Note that grouping is turned
+ on by using <literal>","</literal> in the pattern, as shown
+ in the earlier example. If it's not turned on, this option
+ won't have visible effect.</td>
</tr>
<tr>
- <td><literal>exp</literal></td>
+ <td><literal>exponentSeparator</literal></td>
- <td>Exponent separator string. Only has visible effect if
- the pattern specifies exponential form, like
+ <td>This string (of arbitrary length) is used to separate
+ the exponent from the part before it. (like
+ <literal>"E"</literal> in <literal>1.23E6</literal>). Only
+ has visible effect if the pattern specifies exponential
+ (also known as scientific) format, like
<literal>"0.##E0"</literal>.</td>
</tr>
<tr>
- <td><literal>min</literal></td>
+ <td><literal>minusSign</literal></td>
- <td>Minus sign character.</td>
+ <td>The single character used as minus sign (like
+ <literal>"-"</literal> in <literal>-1</literal>).</td>
</tr>
<tr>
- <td><literal>inf</literal></td>
+ <td><literal>infinity</literal></td>
- <td>The string used to show infinity.</td>
+ <td>The string (of arbitrary length) used to show
+ infinity.</td>
</tr>
<tr>
<td><literal>nan</literal></td>
- <td>The string used to show not-a-number (NaN).</td>
+ <td>The string (of arbitrary length) used to show
+ not-a-number (NaN).</td>
</tr>
<tr>
- <td><literal>prc</literal></td>
+ <td><literal>percent</literal></td>
- <td>Percent character.</td>
+ <td>The single character used as the percent symbol (like
+ <literal>"%"</literal> in <literal>50%</literal>). Only has
+ visible effect if the pattern contains
+ <literal>%</literal>.</td>
</tr>
<tr>
- <td><literal>prm</literal></td>
+ <td><literal>perMill</literal></td>
- <td>Per-mill character.</td>
+ <td>The single character used as the per-mill symbol (like
+ <literal>"‰"</literal> in <literal>50021‰</literal>). Only
+ has visible effect if the pattern contains
+ <literal>‰</literal>.</td>
</tr>
<tr>
- <td><literal>zero</literal></td>
+ <td><literal>zeroDigit</literal></td>
- <td>Zero character. This modifies the other digits too, for
- example, if zero is <literal>A</literal>, then 1 will
+ <td>The first character in the 10 character range (of
+ character codes) that contains the digits to be used. For
+ example, if this is <literal>A</literal>, then 1 will
<literal>B</literal>, 2 will be <literal>C</literal>, and so
on.</td>
</tr>
<tr>
- <td><literal>curc</literal></td>
+ <td><literal>currencyCode</literal></td>
<td>Currency ISO 4217 code. Only has effect when the pattern
contains parts that make it a monetary format. It's an error
@@ -14674,11 +14695,11 @@ Extended decimal format: 10<emphasis>_</emphasis>00<emphasis>3</emphasis></progr
</tr>
<tr>
- <td><literal>curs</literal></td>
+ <td><literal>currencySymbol</literal></td>
<td>Currency symbol; shown where the localized currency name
is present in the pattern. Overrides the symbol determined
- from <literal>curc</literal>.</td>
+ based on the <literal>currencyCode</literal>.</td>
</tr>
</tbody>
</informaltable>
@@ -14699,19 +14720,23 @@ Extended decimal format: 10<emphasis>_</emphasis>00<emphasis>3</emphasis></progr
<listitem>
<para>The option value can be quoted with apostrophe
(<literal>'</literal>) or normal quotation mark
- (<literal>"</literal>) , like <literal>exp='*10^'</literal> or
- <literal>exp="*10^"</literal>. If the value itself has to
- contain the character used for quotation, then it has to be
- entered twice (like <literal>inf='It''s infinite'</literal>,
- but you could also write <literal>inf="It's
- infinite"</literal>). Backslash has no special meaning.</para>
+ (<literal>"</literal>) , like
+ <literal>exponentSeparator='*10^'</literal> or
+ <literal>exponentSeparator="*10^"</literal>. If the value
+ itself has to contain the character used for quotation, then
+ it has to be entered twice (like <literal>infinity='It''s
+ infinite'</literal>, but you could also write
+ <literal>infinity="It's infinite"</literal>). Backslash has no
+ special meaning.</para>
</listitem>
<listitem>
<para>Non-string values must not be quoted. Strings only has
to be quoted if they contain punctuation or whitespace, or any
other non-letter non-digit non-<literal>"_"</literal>
- non-<literal>"$"</literal> characters.</para>
+ non-<literal>"$"</literal> characters. Thus, for example, both
+ <literal>roundingMode=down</literal> and
+ <literal>roundingMode="down"</literal> are legal.</para>
</listitem>
</itemizedlist>
</simplesect>
@@ -25822,12 +25847,12 @@ TemplateModel x = env.getVariable("x"); // get variable x</programlisting>
</listitem>
<listitem>
- <para><emphasis>Attention!</emphasis> FreeMarker's JSP support
- (if it's used) now requires at least JSP 2.0. Earlier it only
- required JSP 1.1. (Reason: The <literal>jsp-api</literal>
- dependency for JSP 1.x, which was needed for building, can't be
- legally present in the Maven Central Repository, nor be provided
- by freemarker.org.)</para>
+ <para><emphasis role="strong">Attention!</emphasis> FreeMarker's
+ JSP support (if it's used) now requires at least JSP 2.0.
+ Earlier it only required JSP 1.1. (Reason: The
+ <literal>jsp-api</literal> dependency for JSP 1.x, which was
+ needed for building, can't be legally present in the Maven
+ Central Repository, nor be provided by freemarker.org.)</para>
</listitem>
<listitem>
@@ -26277,6 +26302,13 @@ TemplateModel x = env.getVariable("x"); // get variable x</programlisting>
</listitem>
<listitem>
+ <para>The extended decimal format options don't use
+ abbreviations anymore. Like instead of
+ <literal>rnd=hu</literal>, now there's
+ <literal>roundingMode=halfUp</literal>.</para>
+ </listitem>
+
+ <listitem>
<para>Added <literal>XHTMLOutputFormat</literal> and
<literal>TemplateXHTMLOutputModel</literal>.</para>
</listitem>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/8adee326/src/test/java/freemarker/core/ExtendedDecimalFormatTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/ExtendedDecimalFormatTest.java b/src/test/java/freemarker/core/ExtendedDecimalFormatTest.java
index d53fc84..264c1ea 100644
--- a/src/test/java/freemarker/core/ExtendedDecimalFormatTest.java
+++ b/src/test/java/freemarker/core/ExtendedDecimalFormatTest.java
@@ -107,84 +107,89 @@ public class ExtendedDecimalFormatTest extends TemplateTest {
@Test
public void testExtendedParamsParsing() throws ParseException {
for (String fs : new String[] {
- "00.##;; dec='D'", "00.##;;dec=D", "00.##;; dec = D ", "00.##;; dec = 'D' " }) {
+ "00.##;; decimalSeparator='D'",
+ "00.##;;decimalSeparator=D",
+ "00.##;; decimalSeparator = D ", "00.##;; decimalSeparator = 'D' " }) {
assertFormatted(fs, 1.125, "01D12");
}
for (String fs : new String[] {
- ",#0.0;; dec=D, grp=_", ",#0.0;;dec=D,grp=_", ",#0.0;; dec = D , grp = _ ", ",#0.0;; dec='D', grp='_'"
+ ",#0.0;; decimalSeparator=D, groupingSeparator=_",
+ ",#0.0;;decimalSeparator=D,groupingSeparator=_",
+ ",#0.0;; decimalSeparator = D , groupingSeparator = _ ",
+ ",#0.0;; decimalSeparator='D', groupingSeparator='_'"
}) {
assertFormatted(fs, 12345, "1_23_45D0");
}
- assertFormatted("0.0;;inf=infinity", Double.POSITIVE_INFINITY, "infinity");
- assertFormatted("0.0;;inf='infinity'", Double.POSITIVE_INFINITY, "infinity");
- assertFormatted("0.0;;inf=\"infinity\"", Double.POSITIVE_INFINITY, "infinity");
- assertFormatted("0.0;;inf=''", Double.POSITIVE_INFINITY, "");
- assertFormatted("0.0;;inf=\"\"", Double.POSITIVE_INFINITY, "");
- assertFormatted("0.0;;inf='x''y'", Double.POSITIVE_INFINITY, "x'y");
- assertFormatted("0.0;;inf=\"x'y\"", Double.POSITIVE_INFINITY, "x'y");
- assertFormatted("0.0;;inf='x\"\"y'", Double.POSITIVE_INFINITY, "x\"\"y");
- assertFormatted("0.0;;inf=\"x''y\"", Double.POSITIVE_INFINITY, "x''y");
- assertFormatted("0.0;;dec=''''", 1, "1'0");
- assertFormatted("0.0;;dec=\"'\"", 1, "1'0");
- assertFormatted("0.0;;dec='\"'", 1, "1\"0");
- assertFormatted("0.0;;dec=\"\"\"\"", 1, "1\"0");
+ assertFormatted("0.0;;infinity=infinity", Double.POSITIVE_INFINITY, "infinity");
+ assertFormatted("0.0;;infinity='infinity'", Double.POSITIVE_INFINITY, "infinity");
+ assertFormatted("0.0;;infinity=\"infinity\"", Double.POSITIVE_INFINITY, "infinity");
+ assertFormatted("0.0;;infinity=''", Double.POSITIVE_INFINITY, "");
+ assertFormatted("0.0;;infinity=\"\"", Double.POSITIVE_INFINITY, "");
+ assertFormatted("0.0;;infinity='x''y'", Double.POSITIVE_INFINITY, "x'y");
+ assertFormatted("0.0;;infinity=\"x'y\"", Double.POSITIVE_INFINITY, "x'y");
+ assertFormatted("0.0;;infinity='x\"\"y'", Double.POSITIVE_INFINITY, "x\"\"y");
+ assertFormatted("0.0;;infinity=\"x''y\"", Double.POSITIVE_INFINITY, "x''y");
+ assertFormatted("0.0;;decimalSeparator=''''", 1, "1'0");
+ assertFormatted("0.0;;decimalSeparator=\"'\"", 1, "1'0");
+ assertFormatted("0.0;;decimalSeparator='\"'", 1, "1\"0");
+ assertFormatted("0.0;;decimalSeparator=\"\"\"\"", 1, "1\"0");
try {
- ExtendedDecimalFormatParser.parse(";;dec=D,", LOC);
+ ExtendedDecimalFormatParser.parse(";;decimalSeparator=D,", LOC);
fail();
} catch (java.text.ParseException e) {
assertThat(e.getMessage(),
allOf(containsStringIgnoringCase("expected a(n) name"), containsString(" end of ")));
}
try {
- ExtendedDecimalFormatParser.parse(";;xdec=D,", LOC);
+ ExtendedDecimalFormatParser.parse(";;foo=D,", LOC);
fail();
} catch (java.text.ParseException e) {
assertThat(e.getMessage(),
- allOf(containsString("\"xdec\""), containsString("name")));
+ allOf(containsString("\"foo\""), containsString("name")));
}
try {
- ExtendedDecimalFormatParser.parse(";;dec='D", LOC);
+ ExtendedDecimalFormatParser.parse(";;decimalSeparator='D", LOC);
fail();
} catch (java.text.ParseException e) {
assertThat(e.getMessage(),
allOf(containsString("quotation"), containsString("closed")));
}
try {
- ExtendedDecimalFormatParser.parse(";;dec=\"D", LOC);
+ ExtendedDecimalFormatParser.parse(";;decimalSeparator=\"D", LOC);
fail();
} catch (java.text.ParseException e) {
assertThat(e.getMessage(),
allOf(containsString("quotation"), containsString("closed")));
}
try {
- ExtendedDecimalFormatParser.parse(";;dec='D'grp=G", LOC);
+ ExtendedDecimalFormatParser.parse(";;decimalSeparator='D'groupingSeparator=G", LOC);
fail();
} catch (java.text.ParseException e) {
assertThat(e.getMessage(), allOf(
containsString("separator"), containsString("whitespace"), containsString("comma")));
}
try {
- ExtendedDecimalFormatParser.parse(";;dec=., grp=G", LOC);
+ ExtendedDecimalFormatParser.parse(";;decimalSeparator=., groupingSeparator=G", LOC);
fail();
} catch (java.text.ParseException e) {
assertThat(e.getMessage(), allOf(
- containsStringIgnoringCase("expected a(n) value"), containsString("., grp")));
+ containsStringIgnoringCase("expected a(n) value"), containsString("., gr[...]")));
}
try {
- ExtendedDecimalFormatParser.parse("0.0;;dec=''", LOC);
+ ExtendedDecimalFormatParser.parse("0.0;;decimalSeparator=''", LOC);
fail();
} catch (java.text.ParseException e) {
assertThat(e.getMessage(), allOf(
- containsStringIgnoringCase("\"dec\""), containsString("exactly 1 char")));
+ containsStringIgnoringCase("\"decimalSeparator\""), containsString("exactly 1 char")));
}
try {
- ExtendedDecimalFormatParser.parse("0.0;;mul=ten", LOC);
+ ExtendedDecimalFormatParser.parse("0.0;;multipier=ten", LOC);
fail();
} catch (java.text.ParseException e) {
assertThat(e.getMessage(), allOf(
- containsString("\"mul\""), containsString("\"ten\""), containsString("integer")));
+ containsString("\"multipier\""), containsString("\"ten\""), containsString("integer")));
}
}
@@ -193,71 +198,77 @@ public class ExtendedDecimalFormatTest extends TemplateTest {
public void testExtendedParamsEffect() throws ParseException {
assertFormatted("0",
1.5, "2", 2.5, "2", 3.5, "4", 1.4, "1", 1.6, "2", -1.4, "-1", -1.5, "-2", -2.5, "-2", -1.6, "-2");
- assertFormatted("0;; rnd=he",
+ assertFormatted("0;; roundingMode=halfEven",
1.5, "2", 2.5, "2", 3.5, "4", 1.4, "1", 1.6, "2", -1.4, "-1", -1.5, "-2", -2.5, "-2", -1.6, "-2");
- assertFormatted("0;; rnd=hu",
+ assertFormatted("0;; roundingMode=halfUp",
1.5, "2", 2.5, "3", 3.5, "4", 1.4, "1", 1.6, "2", -1.4, "-1", -1.5, "-2", -2.5, "-3", -1.6, "-2");
- assertFormatted("0;; rnd=hd",
+ assertFormatted("0;; roundingMode=halfDown",
1.5, "1", 2.5, "2", 3.5, "3", 1.4, "1", 1.6, "2", -1.4, "-1", -1.5, "-1", -2.5, "-2", -1.6, "-2");
- assertFormatted("0;; rnd=f",
+ assertFormatted("0;; roundingMode=floor",
1.5, "1", 2.5, "2", 3.5, "3", 1.4, "1", 1.6, "1", -1.4, "-2", -1.5, "-2", -2.5, "-3", -1.6, "-2");
- assertFormatted("0;; rnd=c",
+ assertFormatted("0;; roundingMode=ceiling",
1.5, "2", 2.5, "3", 3.5, "4", 1.4, "2", 1.6, "2", -1.4, "-1", -1.5, "-1", -2.5, "-2", -1.6, "-1");
- assertFormatted("0;; rnd=un", 2, "2");
+ assertFormatted("0;; roundingMode=up",
+ 1.5, "2", 2.5, "3", 3.5, "4", 1.4, "2", 1.6, "2", -1.4, "-2", -1.5, "-2", -2.5, "-3", -1.6, "-2");
+ assertFormatted("0;; roundingMode=down",
+ 1.5, "1", 2.5, "2", 3.5, "3", 1.4, "1", 1.6, "1", -1.4, "-1", -1.5, "-1", -2.5, "-2", -1.6, "-1");
+ assertFormatted("0;; roundingMode=unnecessary", 2, "2");
try {
- assertFormatted("0;; rnd=un", 2.5, "2");
+ assertFormatted("0;; roundingMode=unnecessary", 2.5, "2");
fail();
} catch (ArithmeticException e) {
// Expected
}
- assertFormatted("0.##;; mul=100", 12.345, "1234.5");
- assertFormatted("0.##;; mul=1000", 12.345, "12345");
+ assertFormatted("0.##;; multipier=100", 12.345, "1234.5");
+ assertFormatted("0.##;; multipier=1000", 12.345, "12345");
- assertFormatted(",##0.##;; grp=_ dec=D", 12345.1, "12_345D1", 1, "1");
+ assertFormatted(",##0.##;; groupingSeparator=_ decimalSeparator=D", 12345.1, "12_345D1", 1, "1");
- assertFormatted("0.##E0;; exp='*10^'", 12345.1, "1.23*10^4");
+ assertFormatted("0.##E0;; exponentSeparator='*10^'", 12345.1, "1.23*10^4");
- assertFormatted("0.##;; min=m", -1, "m1", 1, "1");
+ assertFormatted("0.##;; minusSign=m", -1, "m1", 1, "1");
- assertFormatted("0.##;; inf=foo", Double.POSITIVE_INFINITY, "foo", Double.NEGATIVE_INFINITY, "-foo");
+ assertFormatted("0.##;; infinity=foo", Double.POSITIVE_INFINITY, "foo", Double.NEGATIVE_INFINITY, "-foo");
assertFormatted("0.##;; nan=foo", Double.NaN, "foo");
- assertFormatted("0%;; prc='c'", 0.75, "75c");
+ assertFormatted("0%;; percent='c'", 0.75, "75c");
- assertFormatted("0\u2030;; prm='m'", 0.75, "750m");
+ assertFormatted("0\u2030;; perMill='m'", 0.75, "750m");
- assertFormatted("0.00;; zero='@'", 10.5, "A@.E@");
+ assertFormatted("0.00;; zeroDigit='@'", 10.5, "A@.E@");
- assertFormatted("0;; curc=USD", 10, "10");
- assertFormatted("0 \u00A4;; curc=USD", 10, "10 $");
- assertFormatted("0 \u00A4\u00A4;; curc=USD", 10, "10 USD");
- assertFormatted(Locale.GERMANY, "0 \u00A4;; curc=EUR", 10, "10 \u20AC");
- assertFormatted(Locale.GERMANY, "0 \u00A4\u00A4;; curc=EUR", 10, "10 EUR");
+ assertFormatted("0;; currencyCode=USD", 10, "10");
+ assertFormatted("0 \u00A4;; currencyCode=USD", 10, "10 $");
+ assertFormatted("0 \u00A4\u00A4;; currencyCode=USD", 10, "10 USD");
+ assertFormatted(Locale.GERMANY, "0 \u00A4;; currencyCode=EUR", 10, "10 \u20AC");
+ assertFormatted(Locale.GERMANY, "0 \u00A4\u00A4;; currencyCode=EUR", 10, "10 EUR");
try {
- assertFormatted("0;; curc=USDX", 10, "10");
+ assertFormatted("0;; currencyCode=USDX", 10, "10");
} catch (ParseException e) {
assertThat(e.getMessage(), containsString("ISO 4217"));
}
- assertFormatted("0 \u00A4;; curc=USD curs=bucks", 10, "10 bucks");
- assertFormatted("0 \u00A4;; curs=bucks curc=USD", 10, "10 bucks"); // Order doesn't mater
- assertFormatted("0 \u00A4\u00A4;; curc=USD curs=bucks", 10, "10 USD"); // International symbol isn't affected
+ assertFormatted("0 \u00A4;; currencyCode=USD currencySymbol=bucks", 10, "10 bucks");
+ // Order doesn't mater:
+ assertFormatted("0 \u00A4;; currencySymbol=bucks currencyCode=USD", 10, "10 bucks");
+ // International symbol isn't affected:
+ assertFormatted("0 \u00A4\u00A4;; currencyCode=USD currencySymbol=bucks", 10, "10 USD");
- assertFormatted("0.0 \u00A4;; mdec=m", 10.5, "10m5 $");
- assertFormatted("0.0 kg;; mdec=m", 10.5, "10.5 kg");
- assertFormatted("0.0 \u00A4;; dec=d", 10.5, "10.5 $");
- assertFormatted("0.0 kg;; dec=d", 10.5, "10d5 kg");
- assertFormatted("0.0 \u00A4;; mdec=m dec=d", 10.5, "10m5 $");
- assertFormatted("0.0 kg;; mdec=m dec=d", 10.5, "10d5 kg");
+ assertFormatted("0.0 \u00A4;; monetaryDecimalSeparator=m", 10.5, "10m5 $");
+ assertFormatted("0.0 kg;; monetaryDecimalSeparator=m", 10.5, "10.5 kg");
+ assertFormatted("0.0 \u00A4;; decimalSeparator=d", 10.5, "10.5 $");
+ assertFormatted("0.0 kg;; decimalSeparator=d", 10.5, "10d5 kg");
+ assertFormatted("0.0 \u00A4;; monetaryDecimalSeparator=m decimalSeparator=d", 10.5, "10m5 $");
+ assertFormatted("0.0 kg;; monetaryDecimalSeparator=m decimalSeparator=d", 10.5, "10d5 kg");
}
@Test
public void testLocale() throws ParseException {
assertEquals("1000.0", ExtendedDecimalFormatParser.parse("0.0", Locale.US).format(1000));
assertEquals("1000,0", ExtendedDecimalFormatParser.parse("0.0", Locale.FRANCE).format(1000));
- assertEquals("1_000.0", ExtendedDecimalFormatParser.parse(",000.0;;grp=_", Locale.US).format(1000));
- assertEquals("1_000,0", ExtendedDecimalFormatParser.parse(",000.0;;grp=_", Locale.FRANCE).format(1000));
+ assertEquals("1_000.0", ExtendedDecimalFormatParser.parse(",000.0;;groupingSeparator=_", Locale.US).format(1000));
+ assertEquals("1_000,0", ExtendedDecimalFormatParser.parse(",000.0;;groupingSeparator=_", Locale.FRANCE).format(1000));
}
@Test
@@ -267,16 +278,16 @@ public class ExtendedDecimalFormatTest extends TemplateTest {
cfg.setNumberFormat(",000.#");
assertOutput("${1000.15} ${1000.25}", "1,000.2 1,000.2");
- cfg.setNumberFormat(",000.#;; rnd=hu grp=_");
+ cfg.setNumberFormat(",000.#;; roundingMode=halfUp groupingSeparator=_");
assertOutput("${1000.15} ${1000.25}", "1_000.2 1_000.3");
cfg.setLocale(Locale.GERMANY);
assertOutput("${1000.15} ${1000.25}", "1_000,2 1_000,3");
cfg.setLocale(Locale.US);
assertOutput(
"${1000.15}; "
- + "${1000.15?string(',##.#;;grp=\" \"')}; "
+ + "${1000.15?string(',##.#;;groupingSeparator=\" \"')}; "
+ "<#setting locale='de_DE'>${1000.15}; "
- + "<#setting numberFormat='0.0;;rnd=d'>${1000.15}",
+ + "<#setting numberFormat='0.0;;roundingMode=down'>${1000.15}",
"1_000.2; 10 00.2; 1_000,2; 1000,1");
assertErrorContains("${1?string('#E')}",
TemplateException.class, "\"#E\"", "format string", "exponential");
@@ -284,7 +295,7 @@ public class ExtendedDecimalFormatTest extends TemplateTest {
TemplateException.class, "\"#E\"", "format string", "exponential");
assertErrorContains("<#setting numberFormat=';;foo=bar'>${1}",
TemplateException.class, "\"foo\"", "supported");
- assertErrorContains("<#setting numberFormat='0;;rnd=un'>${1.5}",
+ assertErrorContains("<#setting numberFormat='0;;roundingMode=unnecessary'>${1.5}",
TemplateException.class, "can't format", "1.5", "UNNECESSARY");
}
[11/16] incubator-freemarker git commit: Fixed accidental use of Java
6 API.
Posted by dd...@apache.org.
Fixed accidental use of Java 6 API.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/14fab44f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/14fab44f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/14fab44f
Branch: refs/heads/2.3
Commit: 14fab44fe1a20bee814c086f110ec01e97bcbefc
Parents: dd54594
Author: ddekany <dd...@apache.org>
Authored: Sun Oct 4 16:32:06 2015 +0200
Committer: ddekany <dd...@apache.org>
Committed: Sun Oct 4 16:32:06 2015 +0200
----------------------------------------------------------------------
src/main/javacc/FTL.jj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/14fab44f/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj
index 34f737b..a10552f 100644
--- a/src/main/javacc/FTL.jj
+++ b/src/main/javacc/FTL.jj
@@ -4227,7 +4227,7 @@ List<Object> StaticTextAndInterpolations() :
)
{
String s = t.image;
- if (!s.isEmpty()) {
+ if (s.length() != 0) {
if (staticTextCollector == null) {
staticTextCollector = new StringBuilder(t.image);
} else {