[stringtemplate-interest] [ST4] How to apply multiple "format"s to an expression?

Collin Fagan collin.fagan at gmail.com
Sun Feb 20 18:17:37 PST 2011


Okay so I did some hacking and have this:

STGroup group = new STGroupFile("templates/MultiFormatStringRenderer.stg");

AttributeRenderer stringRenderer = ... your string renderer here ...
group.registerRenderer(String.class, new
MultiFormatStringRenderer(stringRenderer, " "));

ST st = group.getInstanceOf("main");
st.add("string", "     Renderers are fun!     ");

System.out.println(st.render());

-----

main(string) ::= <<
String - Raw Value = "<string>"

String - format="strip" = "<string; format="strip">"
String - format="strip uncapitalize" = "<string; format="strip
uncapitalize">"
String - format="strip uncapitalize swapCase" = "<string; format="strip
uncapitalize swapCase">"

>>

And it outputs:

String - Raw Value = "     Renderers are fun!     "

String - format="strip" = "Renderers are fun!"
String - format="strip uncapitalize" = "renderers are fun!"
String - format="strip uncapitalize swapCase" = "RENDERERS ARE FUN!

It supports splitting on any regex delimiter, because it just uses
String.split() underneath. I got this far and began to wonder if this is
really worth it. First it will never work for the general case, just for
String. That might surprise someone who might attempt a "cross-type"
rendering scenario.

Example:

<trueBooleanValue; format="YN uncapitalize">

Lets pretend there is a Boolean renderer for which YN transforms a Boolean
value into "Yes" and "No" strings. One  might assume that the above
statement would produce "yes" but this in fact is not the case, it's a error
because the entire string is passed to BooleanRenderer and not my special
StringRenderer. A renderer is just not going to get this done on it's own,
you would need a language change.


Lets contrast this with what one might do with one or more ModelAdapters.

<trueBooleanValue.YN.uncapitalize>

This would produce the expected "yes" output and is more concise then the
format statement.

For your specific example:

<n;format="|upper|%15s">

If you used a model adapter it would look like this:

<n.upper.("%15s")>

So it occurs to me ... why would anyone use a renderer with a parameter when
they can just write a model adapter? I know, I know what you are thinking..
"booo! hissss! renderers are great! Model adapters are not for rendering!"
Which is true but syntactically they are very convenient and are "chain
friendly".

What do others think?

Collin


On Sat, Feb 19, 2011 at 8:58 AM, Udo Borkowski <ub at abego-software.de> wrote:

> Hi Colin,
>
> Humm ... but it would be interesting to build a Renderer that took a
> delimited set of format parameters.
>
> <n;format="%15s,upper">
>
> Of course comma works great here but not for the general case .. maybe make
> the delimiter a parameter to the renderer? I might slap something together
> to try it out.
>
>
>
> this sounds like a great idea.
>
> May I throw in some suggestions?
>
> Rather than using the commonly used separator "," I would use the pipe '|'
> character to separate the multiple format parts (by default). Actually the
> new renderer to be written has some "pipe" functionality: the output of one
> renderer is the input for another and so on. So ‘|‘ also makes semantically.
>
> Of cause there should be the option to change the separator. However I
> would not (only) make this a parameter to the renderer but also make this an
> option in the format string itself. E.g. in one application you may want to
> use the same renderer (instance) with different separators.
>
> Here two possible formats:
>
> <n;format="|upper|%15s">
>
> Here the initial ‘|‘ indicates the pipe formatting and the pipe renderer
> splits the rest of the format text and processes each format one after
> another.
>
> To define a different separator one could start with ‘|x|‘, i.e. the new
> separator is framed by two pipe chars. E.g. to use the ";" one would write:
>
> <n;format="|;|upper;%15s">
>
>
> An alternative syntax may start with a keyword to indicate we want to do
> piping. The character following the keyword is then used as the separator.
> E.g. if we use the keyword "pipe" the tag would look like this:
>
> <n;format="pipe|upper|%15s">
>
> or for the semicolon case:
>
> <n;format="pipe;upper;%15s">
>
> I would prefer the second syntax. In that case there would not even be the
> need to decide for a good "default separator" ;-)
>
>
> Udo
>
>
>
> On 18.02.2011, at 23:53, Collin Fagan wrote:
>
> *This could actually be done by extending the ObjectModelAdaptor model
> adapter to have it check for such a method.*
>
> Such an adapter is available as part of STRUM<http://sourceforge.net/apps/mediawiki/project-strum/index.php?title=Main_Page>
> .
>
>    - PublicMethodModelAdapter<http://project-strum.svn.sourceforge.net/viewvc/project-strum/trunk/strum-project/strum/src/main/java/com/collinfagan/strum/adaptors/PublicMethodModelAdapter.java?revision=8&view=markup>- access any public method from ST
>
> Humm ... but it would be interesting to build a Renderer that took a
> delimited set of format parameters.
>
> <n;format="%15s,upper">
>
> Of course comma works great here but not for the general case .. maybe make
> the delimiter a parameter to the renderer? I might slap something together
> to try it out.
>
> Collin
>
> On Fri, Feb 18, 2011 at 4:29 PM, Sam Harwell <sharwell at pixelminegames.com>wrote:
>
>> Does this work:
>>
>>
>> <(upper(n)); format="%-15s">
>>
>>
>> With this definition of upper(x)?
>>
>>
>> upper(x) ::= <<
>>
>> <x; format="upper">
>>
>> >>
>>
>>
>> Also, here’s an interesting case where if <x.y> checked for a method y()
>> (zero parameters and non-void return value), you could use <n.toUpperCase;
>> format="%-15s">. This could actually be done by extending the
>> ObjectModelAdaptor model adapter to have it check for such a method.
>>
>>
>> Sam
>>
>>
>> *From:* stringtemplate-interest-bounces at antlr.org [mailto:
>> stringtemplate-interest-bounces at antlr.org] *On Behalf Of *Udo Borkowski
>> *Sent:* Friday, February 18, 2011 4:02 PM
>> *To:* stringtemplate-interest List
>> *Subject:* [stringtemplate-interest] [ST4] How to apply multiple
>> "format"s to an expression?
>>
>>
>> Hi,
>>
>>
>> I would like to generate a constant definition like this:
>>
>>
>>             public static final int ABC             = 123;
>>
>>             public static final int GHIJKLMN        = 456;
>>
>>
>> To make sure the "="s are aligned I can use the Java String format padding
>> feature, e.g. use a template like this:
>>
>>
>> t1(n,v) ::= <<
>>
>> public static final int «n;*format="%-15s"*» = «v»;
>>
>> >>
>>
>>
>> However the name is given in mixed case and I need to "upper" it, e.g.
>> with something like this:
>>
>>
>> t2(n,v) ::= <<
>>
>> public static final int «n;*format="upper"*» = «v»;
>>
>> >>
>>
>>
>> Is there a way to combine both formats, so I get an uppercased, right
>> padded name?
>>
>>
>>
>> Udo
>>
>>
>> _______________________________________________
>> 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/20110220/43b7a364/attachment.html 


More information about the stringtemplate-interest mailing list