freemarker-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ddek...@apache.org
Subject [08/12] incubator-freemarker git commit: In string literals, \= is now a valid escape sequence, resulting in a =. This is useful when you are using the new [=exp] interpolation syntax, which can be escaped in a string literal like "Literal [\=x]".
Date Mon, 19 Mar 2018 21:29:54 GMT
In string literals, \= is now a valid escape sequence, resulting in a =. This is useful when
you are using the new [=exp] interpolation syntax, which can be escaped in a string literal
like "Literal [\=x]".

(Also improved [=...] related documentation and test a bit.)


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/df4dc52f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/df4dc52f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/df4dc52f

Branch: refs/heads/2.3
Commit: df4dc52f2f1799299a9455ac016dfecaecf9004b
Parents: aeaafe5
Author: ddekany <ddekany@apache.org>
Authored: Fri Mar 16 23:58:29 2018 +0100
Committer: ddekany <ddekany@apache.org>
Committed: Fri Mar 16 23:58:29 2018 +0100

----------------------------------------------------------------------
 .../freemarker/template/utility/StringUtil.java | 22 +++++--
 src/main/javacc/FTL.jj                          |  2 +-
 src/manual/en_US/book.xml                       | 67 +++++++++++++++++---
 .../core/InterpolationSyntaxTest.java           |  7 ++
 .../template/utility/StringUtilTest.java        | 24 +++++++
 5 files changed, 108 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/df4dc52f/src/main/java/freemarker/template/utility/StringUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/template/utility/StringUtil.java b/src/main/java/freemarker/template/utility/StringUtil.java
index 33fe03b..a5156aa 100644
--- a/src/main/java/freemarker/template/utility/StringUtil.java
+++ b/src/main/java/freemarker/template/utility/StringUtil.java
@@ -38,6 +38,10 @@ import freemarker.template.Version;
  */
 public class StringUtil {
     
+    /**
+     *  Used to look up if the chars with low code needs to be escaped, but note that it
gives bad result for '=', as
+     *  there the it matters if it's after '['.
+     */
     private static final char[] ESCAPES = createEscapes();
     
     private static final char[] LT = new char[] { '&', 'l', 't', ';' };
@@ -426,6 +430,7 @@ public class StringUtil {
         escapes['\''] = '\'';
         escapes['"'] = '"';
         escapes['<'] = 'l';
+        // As '=' is only escaped if it's after '[', we can't handle it here
         escapes['>'] = 'g';
         escapes['&'] = 'a';
         escapes['\b'] = 'b';
@@ -480,10 +485,16 @@ public class StringUtil {
         StringBuilder buf = null;
         for (int i = 0; i < ln; i++) {
             char c = s.charAt(i);
-            char escape =
-                    c < escLn ? ESCAPES[c] :
-                    c == '{' && i > 0 && isInterpolationStart(s.charAt(i
- 1)) ? '{' :
-                    0;
+            char escape;
+            if (c == '=') {
+                escape = i > 0 && s.charAt(i - 1) == '[' ? '=' : 0;
+            } else if (c < escLn) {
+                escape = ESCAPES[c]; //
+            } else if (c == '{' && i > 0 && isInterpolationStart(s.charAt(i
- 1))) {
+                escape = '{';
+            } else {
+                escape = 0;
+            }
             if (escape == 0 || escape == otherQuotation) {
                 if (buf != null) {
                     buf.append(c);
@@ -605,7 +616,8 @@ public class StringUtil {
                     bidx = idx + 2;
                     break;
                 case '{':
-                    buf.append('{');
+                case '=':
+                    buf.append(c);
                     bidx = idx + 2;
                     break;
                 case 'x': {

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/df4dc52f/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj
index f1fa595..4134b70 100644
--- a/src/main/javacc/FTL.jj
+++ b/src/main/javacc/FTL.jj
@@ -1194,7 +1194,7 @@ TOKEN:
     <#ESCAPED_CHAR :
         "\\"
         (
-            ("n" | "t" | "r" | "f" | "b" | "g" | "l" | "a" | "\\" | "'" | "\"" | "$" | "{")
+            ("n" | "t" | "r" | "f" | "b" | "g" | "l" | "a" | "\\" | "'" | "\"" | "$" | "{"
| "=")
             |
             ("x" ["0"-"9", "A"-"F", "a"-"f"])
         )

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/df4dc52f/src/manual/en_US/book.xml
----------------------------------------------------------------------
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index cbda1a8..ac58a2a 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -2276,6 +2276,13 @@ this is a backslash: \</programlisting>
                 </tr>
 
                 <tr>
+                  <td><literal>\=</literal></td>
+
+                  <td>Equals character: <literal>=</literal> (Supported
since
+                  FreeMarker 2.3.28.)</td>
+                </tr>
+
+                <tr>
                   <td><literal>\\</literal></td>
 
                   <td>Back slash (u005C)</td>
@@ -2349,15 +2356,20 @@ this is a backslash: \</programlisting>
             digit, you must use all 4 digits or else FreeMarker will
             misunderstand you.</para>
 
-            <para>Note that the character sequence <literal>${</literal>
(and
-            <literal>#{</literal>) has special meaning. It's used to insert
-            the value of expressions (typically: the value of variables, as in
-            <literal>"Hello ${user}!"</literal>). This will be explained <link
+            <para>Note that the character sequence <literal>${</literal>
and
+            <literal>#{</literal> (and rarely <literal>[=</literal>
instead,
+            depending on <link linkend="dgui_misc_alternativesyntax">the
+            configured syntax</link>) has special meaning. They are used to
+            insert the value of expressions (typically: the value of
+            variables, as in <literal>"Hello ${user}!"</literal>). This will
+            be explained <link
             linkend="dgui_template_exp_stringop_interpolation">later</link>.
             If you want to print <literal>${</literal> or
-            <literal>#{</literal>, you should either use raw string literals
-            as explained below, or escape the <literal>{</literal> like in
-            <literal>"foo $\{bar}"</literal>.</para>
+            <literal>#{</literal> (or <literal>[=</literal>), you
should
+            either use raw string literals as explained below, or escape the
+            <literal>{</literal> like in <literal>"foo $\{bar}"</literal>
(or
+            the <literal>=</literal> like in <literal>"foo
+            [\=bar]"</literal>).</para>
 
             <indexterm>
               <primary>raw string literal</primary>
@@ -2839,6 +2851,14 @@ baz
             sections</link> (so it goes through the same <emphasis>locale
             sensitive</emphasis> number and date/time formatting).</para>
 
+            <note>
+              <para>It's possible to configure FreeMarker's interpolation
+              syntax to use
+              <literal>[=<replaceable>...</replaceable>]</literal>
instead;
+              <link linkend="dgui_misc_alternativesyntax_interpolation">see
+              here</link>.</para>
+            </note>
+
             <para>Example (assume that user is <quote>Big Joe</quote>):</para>
 
             <programlisting role="template">&lt;#assign s = "Hello ${user}!"&gt;
@@ -4200,7 +4220,7 @@ ${("green " + "mouse")?upper_case}  &lt;#-- GREEN MOUSE --&gt;
           kind of expression (e.g. <literal>${100 + x}</literal>).</para>
 
           <note>
-            <para>Actually, FreeMarker can be configured to use
+            <para>FreeMarker can be configured to use
             <literal>[=<replaceable>expression</replaceable>]</literal>
syntax
             instead. <link linkend="dgui_misc_alternativesyntax">See more
             about alternative syntaxes...</link></para>
@@ -27559,6 +27579,37 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
             </listitem>
 
             <listitem>
+              <para>The template language can now be configured to use
+              <literal>[=<replaceable>expression</replaceable>]</literal>
+              instead of
+              <literal>${<replaceable>expression</replaceable>}</literal>
and
+              <literal>#{<replaceable>expression</replaceable>}</literal>,
+              which is very useful if you have a lot of
+              <literal>${<replaceable>...</replaceable>}</literal>
or
+              <literal>#{<replaceable>...</replaceable>}</literal>
in the text
+              that you are generating, and so they should be static text. See
+              <link linkend="dgui_misc_alternativesyntax_interpolation">more
+              about the square bracket interpolation syntax here.</link> The
+              template language can also be configured to only use
+              <literal>${<replaceable>expression</replaceable>}</literal>,
and
+              treat
+              <literal>#{<replaceable>expression</replaceable>}</literal>
as
+              static text. (See the <literal>interpolation_syntax</literal>
+              configuration setting, or the
+              <literal>Configuration.setInterpolationSyntax(int)</literal>
+              method.)</para>
+            </listitem>
+
+            <listitem>
+              <para>In string literals, <literal>\=</literal> is now a
valid
+              escape sequence, resulting in a <literal>=</literal>. This is
+              useful when you are using the new
+              <literal>[=<replaceable>exp</replaceable>]</literal>
+              interpolation syntax, which can be escaped in a string literal
+              like <literal>"Literal [\=x]"</literal>.</para>
+            </listitem>
+
+            <listitem>
               <para>Bug fixed (<link
               xlink:href="https://issues.apache.org/jira/browse/FREEMARKER-83">FREEMARKER-83</link>);
               this fix is only active when <link

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/df4dc52f/src/test/java/freemarker/core/InterpolationSyntaxTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/core/InterpolationSyntaxTest.java b/src/test/java/freemarker/core/InterpolationSyntaxTest.java
index c1721c8..adea7c9 100644
--- a/src/test/java/freemarker/core/InterpolationSyntaxTest.java
+++ b/src/test/java/freemarker/core/InterpolationSyntaxTest.java
@@ -71,6 +71,13 @@ public class InterpolationSyntaxTest extends TemplateTest {
         
         assertOutput("<@r'${1} #{1} [=1]'?interpret />", "${1} #{1} 1");
         assertOutput("[='\"${1} #{1} [=1]\"'?eval]", "${1} #{1} 1");
+        
+        assertErrorContains("[=", "end of file");
+        assertErrorContains("[=1", "unclosed \"[\"");
+        
+        assertOutput("[='[\\=1]']", "[=1]");
+        assertOutput("[='[\\=1][=2]']", "12"); // Usual legacy interpolation escaping glitch...
+        assertOutput("[=r'[=1]']", "[=1]");
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/df4dc52f/src/test/java/freemarker/template/utility/StringUtilTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/freemarker/template/utility/StringUtilTest.java b/src/test/java/freemarker/template/utility/StringUtilTest.java
index 49556e2..557c5dc 100644
--- a/src/test/java/freemarker/template/utility/StringUtilTest.java
+++ b/src/test/java/freemarker/template/utility/StringUtilTest.java
@@ -19,6 +19,7 @@
 
 package freemarker.template.utility;
 
+import static org.hamcrest.Matchers.*;
 import static org.junit.Assert.*;
 
 import java.io.IOException;
@@ -28,6 +29,8 @@ import java.util.regex.Pattern;
 import org.hamcrest.Matchers;
 import org.junit.Test;
 
+import freemarker.core.ParseException;
+
 public class StringUtilTest {
 
     @Test
@@ -200,6 +203,27 @@ public class StringUtilTest {
         assertEquals("a\\'c\"d", StringUtil.FTLStringLiteralEnc("a'c\"d", '\''));
         assertEquals("\\n\\r\\t\\f\\x0002\\\\", StringUtil.FTLStringLiteralEnc("\n\r\t\f\u0002\\"));
         assertEquals("\\l\\g\\a", StringUtil.FTLStringLiteralEnc("<>&"));
+        assertEquals("=[\\=]=", StringUtil.FTLStringLiteralEnc("=[=]="));
+        assertEquals("[\\=", StringUtil.FTLStringLiteralEnc("[="));
+    }
+
+    @Test
+    public void testFTLStringLiteralDec() throws ParseException {
+        assertEquals("", StringUtil.FTLStringLiteralDec(""));
+        assertEquals("x", StringUtil.FTLStringLiteralDec("x"));
+        assertEquals("\nq", StringUtil.FTLStringLiteralDec("\\x0Aq"));
+        assertEquals("\n\r1", StringUtil.FTLStringLiteralDec("\\x0A\\x000D1"));
+        assertEquals("\n\r\t", StringUtil.FTLStringLiteralDec("\\n\\r\\t"));
+        assertEquals("${1}#{2}[=3]", StringUtil.FTLStringLiteralDec("$\\{1}#\\{2}[\\=3]"));
+        assertEquals("{=", StringUtil.FTLStringLiteralDec("\\{\\="));
+        assertEquals("\\=", StringUtil.FTLStringLiteralDec("\\\\="));
+           
+        try {
+            StringUtil.FTLStringLiteralDec("\\[");
+            fail();
+        } catch (ParseException e) {
+            assertThat(e.getMessage(), containsString("\\["));
+        }
     }
     
     @Test


Mime
View raw message