1

There's a few posts including this regarding Html escaping but this is not working for me. If I have a simple template such as this:

<html><body>$field$</body></html>

I need only the field to be escaped, not the whole template. I've created a custom render which uses the System.Web.HttpUtility class to perform the escaping of strings:

class HtmlRenderer : IAttributeRenderer
{
    public string ToString(object obj, string formatString, System.Globalization.CultureInfo culture)
    {
        return HttpUtility.HtmlEncode(
            new StringRenderer().ToString(obj, formatString, culture));
    }
}

And some sample code to render the template with some data:

public static string Render()
{
    var group = new TemplateGroup('$', '$');
    group.RegisterRenderer(typeof(string), new HtmlRenderer());
    var template = new Template(group, "<html><body>$field$</body></html>");
    template.Add("field", "Chalk & Cheese");
    return template.Render();
}

Returns the following:

&lt;html&gt;&lt;body&gt;Chalk &amp; Cheese&lt;/body&gt;&lt;/html&gt;

which escapes everything.

How can I escape only the fields added to the template?

Community
  • 1
  • 1
Neil Dobson
  • 1,239
  • 1
  • 12
  • 24

2 Answers2

1

I am new to stringtemplate but I think I have an idea on how to make it work, I think you are nearly there, whats missing is the format option in your stringtemplate. I think what you need is this:

<html><body>$field;format="htmlTag"$</body></html>

After tagging the string template with the "htmlTag" you can register a renderer, like the one you have done above and check for that tag as follows:

public class HtmlRenderer:IAttributeRenderer
{
    public string ToString(object obj,string formatString,CultureInfo culture)
    {
        if(formatString=="htmlEncode")
        { return HttpUtility.HtmlEncode(obj.ToString()); }
        return obj.ToString();
    }
}

More information can be found here: http://www.antlr.org/wiki/display/ST/Object+rendering

Note: This is untested and my C# is not very good :) but I hope I have pointed you to the right direction.

Vincent
  • 938
  • 13
  • 20
Har
  • 3,727
  • 10
  • 41
  • 75
  • Thanks, i'll give this a go. One think I find difficult to figure is the stringtemplate versions which the documentation applies to. From your link it appears to be v2.2+ Hopefully it hasn't changed in v4... Also, from your example I think it should be $field;format="htmlTag"$. – Neil Dobson Jul 31 '13 at 23:25
  • YesI think you are right Ive updated the answer with the correct ST syntax. As for the documentation in general, there is no language reference for any version as such. I get into the situation where I write syntax in the way I expect it to work and it doesn't since the language does not support it that way. I agree it is difficult to go the "right" way syntax wise but as long as there is a feature in old versions im sure there still will be there in future versions just with different syntax. P.S:ST4 also seems to have the same syntax: [link](http://www.antlr.org/wiki/display/ST4/Renderers) – Har Aug 01 '13 at 09:59
0

I suggest another implementation - below. Why? See the default StringRenderer source code at: https://github.com/antlr/antlrcs/blob/master/Antlr4.StringTemplate/StringRenderer.cs

using System;
using System.Globalization;
using System.Security;
using System.Text;
using System.Web;
using Antlr4.StringTemplate;

class Program
{
    static void Main(string[] args)
    {
        TemplateGroup g = new TemplateGroup('$', '$');
        g.RegisterRenderer(typeof(object), new MyTemplateRenderer());
        string temp = "<html>$var;format=\"html-encode\"$</html>\n$date;format=\"{0:R}\"$";
        Template t = new Template(g, temp);
        t.Add("var", "<>");
        t.Add("date", DateTime.Now);
        Console.WriteLine(t.Render());
        Console.ReadLine();
    }
}

public class MyTemplateRenderer : IAttributeRenderer
{
    public virtual string ToString(object o, string formatString, CultureInfo culture)
    {
        if (formatString == null) return o.ToString();

        switch (formatString) {
            case "upper":
                return o.ToString().ToUpper(culture);
            case "lower":
                return o.ToString().ToLower(culture);
            case "cap":
                string s = o.ToString();
                return s.Length > 0 ? Char.ToUpper(s[0], culture) + s.Substring(1) : s;
            case "url-encode":
                return HttpUtility.UrlEncode(o.ToString(), Encoding.UTF8);
            case "xml-encode":
                return SecurityElement.Escape(o.ToString());
            case "html-encode":
                return HttpUtility.HtmlEncode(o);
            default:
                return String.Format(culture, formatString, o);
        }
    }
}
Tomasz
  • 1
  • 1