[stringtemplate-interest] format option implementation details

Terence Parr parrt at cs.usfca.edu
Sun Dec 10 12:07:45 PST 2006


On Dec 9, 2006, at 11:12 PM, John Snyders wrote:

> Here are the details of what I have implemented for the format option.
>
> format is treated syntactically like any other option and can be  
> combined with any of the other options. The syntax is
> $template;format=expr$. Where expr is an expression resulting in a  
> string value that names the format to be applied to the template by  
> the renderer available to the template if available.  There is no  
> default for the format expression so it must be given. For example  
> $myDate;format="longDate"$
>
> Format applies to either the attribute type or the result of the  
> template, which is a string. Format will apply to the value of the  
> null option but not to the separator.
>
> For example
>   $list : {a $it$ b};format="toUpper",separator=" and ",null="woops"$
> results in
>   A X B and A Y B and A WOOPS B and A Z B
> when list contains x, y, <null>, y and toUpper is a supported  
> format option of the available renderer for type String that  
> returns the upper case input string.

Sounds great!

> Note that the value of null was upper cased but the separator " and  
> " was not.
> If you really want the separator to be formatted then you must do this
>
>   ${$list : {a $it$ b};separator={ and },null={null}$};format= 
> {toUpper}$
> which results in
>   A X B AND A Y B AND A NULL B AND A Z B
> To make use of format you must create a renderer that implements  
> AttributeRenderer. AttributeRenderer is enhanced to add the  
> toString method that takes a formatName. (Now that I think of it,  
> for backwards compatibility perhaps we should create a new  
> interface such as AttributeRendererEx? so that existing renderers  
> don't break)

Well, at least the compiler will tell them and it's a quick  
change...I'd prefer to force this "upgrade" probably.

> public interface AttributeRenderer {
>     public String toString(Object o);
>     public String toString(Object o, String formatName);
> }
> Implement the second toString method to check the formatName and  
> apply the appropriate formatting.
> Register the renderer with a template group or template as you  
> normally would.
> If the format string passed to the renderer is not recognized then  
> simply call toString on the object or throw an exception.

Yup.

> If the format option is used but there is no renderer for the type  
> then format is ignored and the value is rendered as if format was  
> not specified.

Yup.  Good.

> Here is an example renderer toString method:
>     public String toString(Object o, String formatName)
>     {
>         String s = (String)o;
>         if (formatName.equals("toUpper"))
>         {
>             s = s.toUpperCase();
>         }
>         else {
>             throw new IllegalArgumentException();
>         }
>         return s;
>     }
> The details of the renderer could easily change without affecting  
> the behavior of the format option.
>
> There are two interesting things to be aware of with the format option
> 1) If format is applied to a template rather than an attribute an  
> intermediate string must be created so that the format can be  
> applied to the result of the template. This is not unlike when a  
> template is used in an indirect property (i.e. $attribute.({<some  
> template})$

Good point.  format forces early evaluation. :)

> 2) if the renderer is associated with type String then it is  
> possible for the value of an attribute to be rendered twice. This  
> will only happen if the format is applied to a template rather than  
> an attribute.It happens because the String attribute is rendered  
> and written as part of the value of the template expansion then the  
> format is applied to the String value of the template. Now that I  
> think of this more it may be a bug. I'll look into it.

Just an efficiency thing.

> I need to do more testing but here is what I have done so far. If  
> someone wants the whole file let me know and I can send it but it  
> has other changes as well.

I'll do my own implementation, using your excellent work as a guide!   
May I paraphrase your text here for the manual?

>  The changes were in ASTExpr.java and AttributeRenderer.java (which  
> is shown above). While working on ASTExpr I also implemented  
> checking of the option to make sure it is one of the supported  
> options. I saw this issue come up on the list and it was also  
> bothering me because I can't spell seperator right. Now if you use  
> an unsupported option you get a warning.

Good on you!

Thanks,
Ter



More information about the stringtemplate-interest mailing list