[stringtemplate-interest] Formatting vs. Escaping in an AttributeRenderer
Udo Borkowski
ub at abego-software.de
Sun Sep 11 14:17:38 PDT 2011
Hi,
> * It interferes with "normal" renderer usage, i.e., I can either escape
> or format, but not both.
There are several ways to solve this. Some time ago Colin Fagan suggested a "MultiFormatStringRenderer" that allows specify multiple "formats" in one "format" string.
However you can even apply multiple formats to a string without any change to ST4.
E.g. assume you want some attribute to be formatted in UPPER case, but also make sure the result is escaped for xml.
E.g. "Bonny & Clyde" should be rendered as "BONNY & CLYDE"
Then you could write:
main(p) ::= <<
$(f(p));format="xml-encode"$
>>
f(p) ::= <<
$p;format="upper"$
>>
I.e. you pass the attribute to a template that does the "inner" formatting and then the outer formatter will "escape" the result of the template.
> * I have to remember to specify the correct format everywhere.
Seems like a good idea to me.
But maybe I don't get your point. Can you give a concrete example to make it clearer?
> private static class EscapeRenderer implements AttributeRenderer {
> public String toString(Object o, String format, Locale locale) {
> return '[' + String.valueOf(o) + ']';
> }
> }
In your AttributeRenderer you need to check for the formatString. It can be null. In that case you should return the "toString" result for the object. E.g. the StringRenderer starts like this:
public String toString(Object o, String formatString, Locale locale) {
String s = (String)o;
if ( formatString==null ) return s;
if ( formatString.equals("upper") ) return s.toUpperCase(locale);
. . .
If you don't do this check you will get strange results, like the [start]…[end] you saw.
Udo
On 10.09.2011, at 16:36, Tobias Güntner wrote:
> Hello!
>
> I am new to StringTemplate and I am experimenting with string escaping.
>
> The first advice I found was to register a custom attribute renderer and
> specify the escape mechanism in the "format" option. This works fine for
> the most part, but it has a few drawbacks:
>
> * It interferes with "normal" renderer usage, i.e., I can either escape
> or format, but not both. To overcome this limitation, I would have to
> parse the format option and delegate calls to a second renderer which
> does the real formatting - for each type in a STGroup. Certainly doable,
> but it feels like a clumsy workaround.
>
> * I have to remember to specify the correct format everywhere. I find
> this tedious and error-prone. So I figured I could instead escape by
> default and say format="do-not-escape-this-time" if I want something
> else. This did not work, however:
>
> public class Test {
> private static class EscapeRenderer implements AttributeRenderer {
> public String toString(Object o, String format, Locale locale) {
> return '[' + String.valueOf(o) + ']';
> }
> }
> public static void main(String[] args) {
> STGroup g = new STGroup('$', '$');
> ST st = new ST(g, "start$test;separator=\"sep\"$end");
> st.add("test", "aaa").add("test", "bbb").add("test", "ccc");
> g.registerRenderer(Object.class, new EscapeRenderer());
> System.out.println(st.render());
> }
> }
>
> The result (using version 4.0.4) was:
> [start][aaa]sep[bbb]sep[ccc][end]
> For some reason, literals are escaped as well. Shouldn't this print
> start[aaa]sep[bbb]sep[ccc]end
> instead?
>
> * I realize escaping and formatting are mostly orthogonal concepts.
> Formatting converts arbitrary objects into strings depending on the
> needs of the user, whereas escaping transforms strings depending on the
> context of the output. I suppose using an AttributeRenderer to escape
> strings is probably the wrong approach altogether.
>
> Another advice I found was to automatically add properly escaped strings
> whenever new attributes are added to a string template. I do not like
> this either:
>
> * The caller has to know exactly how a certain value is going to be used
> in the template. This dependency can be avoided if every attribute is
> escaped in every possible way, but that would probably be a waste of CPU
> and memory most of the time.
>
> * Recursive escapes (e.g., an HTML fragment in a JS string literal in an
> HTML attribute) are cumbersome.
>
> * Escaping is done before formatting. It should be done last, just
> before the output is concatenated.
>
> A custom model adapter could be used to escape attributes on demand
> (i.e., whenever a magic property name is read), but that does not solve
> the other problems.
>
> Are there other/better ways to escape strings in ST?
>
> Regards,
> Tobias
> _______________________________________________
> stringtemplate-interest mailing list
> stringtemplate-interest at antlr.org
> http://www.antlr.org/mailman/listinfo/stringtemplate-interest
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org/pipermail/stringtemplate-interest/attachments/20110911/186c9978/attachment.html
More information about the stringtemplate-interest
mailing list