[antlr-interest] Able to emulate java.text.ChoiceFormat ?

Harald Mueller harald_m_mueller at gmx.de
Mon Nov 26 05:16:51 PST 2007


Great :-) I'd only say that your template should read:

fileInfo(fileName,fileSize) ::= <<
File $fileName$, $fileSize.Value$ $if(fileSize.One)$byte$else$bytes$endif$.
>>

because the text for a zero-byte file should be

File abc.txt, 0 bytes

not

File abc.txt, 0 byte

- IMVHO.

Regards
Harald

-------- Original-Nachricht --------
> Datum: Mon, 26 Nov 2007 14:13:15 +0100
> Von: "Christopher Brown" <chris77550 at gmail.com>
> An: "Harald Mueller" <harald_m_mueller at gmx.de>
> Betreff: Re: [antlr-interest] Able to emulate java.text.ChoiceFormat ?

> Harald,
> 
> You're quite right about language difficulties, but I try to overcome
> as many as I can :-)
> 
> Your previous posting however helped me figure out a general solution
> that's StringTemplate-friendly and not much of a burden for the
> controller.  Basically, for numbers, I wrote a simple general wrapper
> that I push to the template, instead of pushing the number.  Here's
> what it looks like in C#:
> 
> public sealed class StInt32 {
>  private readonly int _value;
>  public StInt32(int value) {
>   _value = value;
>  }
>  public int Value {
>   get { return _value; }
>  }
>  public bool Zero {
>   get { return _value == 0; }
>  }
>  public bool One {
>   get { return _value == 1; }
>  }
>  public bool Many {
>   get { return _value > 1; }
>  }
>  public override bool Equals(object obj) {
>   return obj is StInt32 && ((StInt32)obj)._value == _value;
>  }
>  public override int GetHashCode() {
>   return _value;
>  }
>  public override string ToString() {
>   return _value.ToString();
>  }
> }
> 
> In Java, that'd be:
> 
> public final class StInt {
>  private final int _value;
>  public StInt(int value) {
>   _value = value;
>  }
>  public int getValue() {
>   return _value;
>  }
>  public boolean isZero() {
>   return _value == 0;
>  }
>  public boolean isOne() {
>   return _value == 1;
>  }
>  public boolean isMany() {
>   return _value > 1;
>  }
>  public boolean equals(Object obj) {
>   return obj instanceof StInt && ((StInt)obj)._value == _value;
>  }
>  public int hashCode() {
>   return _value;
>  }
>  public String toString() {
>   return Integer.toString(_value);
>  }
> }
> 
> The template for the C# version is as follows:
> fileInfo(fileName,fileSize) ::= <<
> File $fileName$, $fileSize.Value$
> $if(fileSize.Many)$bytes$else$byte$endif$.
> >>
> 
> I guess first-letter capitalization rules are an irritation for
> cross-platform templates :-)
> 
> Hope this helps someone else!
> Christopher
> 
> On 26/11/2007, Harald Mueller <harald_m_mueller at gmx.de> wrote:
> > (Sorry for following up on my own posting - but there's something more I
> wanted to say ...):
> >
> > Christopher, I'm not really sure that you can fundamentally solve the
> translation problem without "programming" (i.e., doing more than writing
> templates).
> >
> > Let's assume you split your text generation according to the conditions
> n=0, n=1, n>1. However, there might be a natural language where the phrase
> for n=2 is different from other phrases (there have been languages like
> this - in addition to singular and plural, they had a form called "dual"; I
> think ancient Greek was such a language; and - don't laugh - the Bavarian
> dialects have some left-over dual word forms... but I digress ;-) ).
> >
> > However, if your information-providing class only has property for
> checking "Zero", "One", "More" (as in my example), you'll never find out whether
> there are exactly two - and you are stranded again.
> >
> > Here are more radical examples: The flection of words might change
> depending on the sex of a person associated with the thing; or even on the
> position where the thing is; etc.etc. Even if you know all this in your program,
> you'd have to expose the relevant knowledge to the "view" ("template") -
> which will at least confuse other people as to what of this plethora of
> properties they are supposed to use ...
> >
> > So, you'll end up with a compromise in any case, wouldn't you?
> >
> > Regards
> > Harald
> >
> >
> > -------- Original-Nachricht --------
> > > Datum: Mon, 26 Nov 2007 12:09:07 +0100
> > > Von: "Harald Mueller" <harald_m_mueller at gmx.de>
> > > An: "Christopher Brown" <chris77550 at gmail.com>
> > > CC: antlr-interest at antlr.org
> > > Betreff: Re: [antlr-interest] Able to emulate java.text.ChoiceFormat ?
> >
> > > Hi -
> > >
> > > well, I didn't invent this thing ;-) ...
> > >
> > > ... but n = 0, n = 1, n > 0 are all *computations* (you need to know
> about
> > > numbers and comparison to evaluate these). So none of these things
> should
> > > be done in the view (the template).
> > >
> > > Also (I overlooked this in your original posting), passing of simple
> > > values (like fileSize) is not a good idea - you must always pass
> objects with
> > > properties (that's StringTemplates "type" system at work here ...).
> > >
> > > So, provide properties in your class to find out what to do:
> > >
> > > public class FileInfo {
> > >     public string getFileName() { ... }
> > >     public int getFileSize() { ... }
> > >     public boolean isZeroByteFile() { ... } // not necessary below -
> but
> > > would be in your three-way text creation example
> > >     public boolean isOneByteFile() { ... }
> > > }
> > >
> > > Now, your template could be:
> > >
> > > fileInfo(fi) ::= <<
> > > File $fi.fileName$, $fi.fileSize$
> > > $if(fi.oneByteFile)$byte$else$bytes$endif$.
> > > >>
> > >
> > > (I am not sure I did this perfectly - I have not used
> Java+StringTemplate
> > > for a year or so, only C#, so maybe I did something wrong with the
> implicit
> > > get/is truncation ... But the concept is ok).
> > >
> > > However, an even better (? - at least more interesting) way is
> template
> > > indirection:
> > >
> > > enum FileSizeType { ZeroByteFile, OneByteFile, LargerFile }
> > >
> > > public class FileInfo {
> > >     public string getFileName() { ... }
> > >     public int getFileSize() { ... }
> > >     public FileSizeType getFileSizeType() { ... }
> > > }
> > >
> > > fileInfo(fi) ::= <<
> > > File $fi.fileName$, $fi.fileSize$ $(fi.fileSizeType)()$
> > > >>
> > > // note the parentheses around fi.fileSizeType! -
> > > // this means to evaluate the property and THEN call
> > > // the template whose name you COMPUTED! Here they are:
> > >
> > > ZeroByteFile() ::= <<bytes>>
> > > OneByteFile() ::= <<byte>>
> > > LargerFile() ::= <<bytes>>
> > >
> > > Now, there is no $if...$ any longer! OTOH, there is coupling of the
> > > template names to the enum constants; still, as there is always
> coupling from the
> > > view to the model (at least the properties must conform to each
> other!),
> > > this is not a principal problem ...
> > >
> > > If you need to do *different* things based on the fileSizeType, it
> becomes
> > > a little more complicated; what we do is to have various "template
> name
> > > returning properties" in the model classes which follow strict rules.
> If
> > > someone wants to know about this, email me ...
> > >
> > > I hope this helps!
> > >
> > > Regards
> > > Harald
> > >
> > > P.S. Once again: DO NOT pass simple values around in StringTemplate -
> even
> > > if it works (I dont know whether it does), it's not what is intended.
> > >
> > > -------- Original-Nachricht --------
> > > > Datum: Mon, 26 Nov 2007 11:29:32 +0100
> > > > Von: "Christopher Brown" <chris77550 at gmail.com>
> > > > An: "Harald Mueller" <harald_m_mueller at gmx.de>
> > > > Betreff: Re: [antlr-interest] Able to emulate java.text.ChoiceFormat
> ?
> > >
> > > > Hi Harald,
> > > >
> > > > I can understand that the template engine shouldn't do computation,
> > > > but I'm not trying to do computation here.  And I'm not a
> GUI-builder
> > > > type person anyway, which is why StringTemplate.NET attracts me, now
> > > > that I'm doing a lot of C# work ;-)
> > > >
> > > > For me, I'd like to be able to have one template per language.  A
> lot
> > > > of that targets user interfaces.  With ChoiceFormat, the templating
> > > > isn't computational (and I'd prefer something like ChoiceFormat's
> > > > syntax over if/else/endif), so it's easy to produce the three
> > > > following variations for "n" (the content of the square brackets is
> to
> > > > show the value, not part of any syntax):
> > > >
> > > > [n=0] No records updated.
> > > > [n=1] One record updated.
> > > > [n>1] $n$ records updated.
> > > >
> > > > [n=0] Aucune ligne n'a été modifiée.
> > > > [n=1] Une ligne a été modifiée.
> > > > [n>1] $n$ lignes modifiées.
> > > >
> > > > That's not computation, that's just linguistically-correct output.
> > > > It'd be a shame to limit myself to phrases like "1 record(s)
> updated"
> > > > and "1 ligne(s) modifiée(s)", and it's certainly NOT model or
> > > > controller logic to start spitting out translated content (that's
> one
> > > > of the main aims of using a template engine).
> > > >
> > > > That's the problem I'm trying to solve, not in any way about adding
> > > > more complex expressions and types to $if()$ !!!
> > > >
> > > > So, is there anyway StringTemplate can help in providing
> > > > reader-friendly translations?
> > > >
> > > > Thanks,
> > > > Christopher
> > > >
> > > >
> > > > On 26/11/2007, Harald Mueller <harald_m_mueller at gmx.de> wrote:
> > > > > Hi -
> > > > >
> > > > > The whole idea of StringTemplate is to separate "computation" from
> > > > "string building". Even the $if$ is in a way a concession - one
> could do
> > > > everything with lazily evaluated template names (things like
> $(abc)()$).
> > > > >
> > > > > The favored way is the definition of a clean interface which
> provides
> > > > all the attributes for the template; and do all the computation
> there.
> > > > >
> > > > > Stringtemplate is, as I see it, NOT an abstraction layer on a
> FIXED
> > > > value-providing machine (as are e.g. most report generators);
> rather, it
> > > is
> > > > intended that the templates evolve together with the accessed
> > > interfaces.
> > > > >
> > > > > In a way, Stringtemplate tries to do "MV(C)": It provides ONLY the
> > > VIEW
> > > > for a model; and like in MVC, the view itself is not supposed to
> compute
> > > > anything (even if some people with GUI builders in their hands
> prefer it
> > > > otherwise ...).
> > > > >
> > > > > Regards
> > > > > Harald M.
> > > > >
> > > > > -------- Original-Nachricht --------
> > > > > > Datum: Mon, 26 Nov 2007 10:35:23 +0100
> > > > > > Von: "Christopher Brown" <chris77550 at gmail.com>
> > > > > > An: antlr-interest at antlr.org
> > > > > > Betreff: [antlr-interest] Able to emulate java.text.ChoiceFormat
> ?
> > > > >
> > > > > > Hi,
> > > > > >
> > > > > > Is it possible to create templates that have the capabilities of
> > > > > > ChoiceFormat with StringTemplate (I'm using ST#3)?
> > > > > >
> > > > > >
> http://java.sun.com/javase/6/docs/api/java/text/ChoiceFormat.html
> > > > > >
> > > > > > For example, the following template doesn't work:
> > > > > >
> > > > > > fileInfo(fileName,fileSize) ::= <<
> > > > > > File $fileName$, $fileSize$
> $if(fileSize>1)$bytes$else$byte$endif$.
> > > > > > >>
> > > > > >
> > > > > > (I'm using a group template file with the default lexer, not the
> > > angle
> > > > > > bracket one, as my target is HTML...).
> > > > > >
> > > > > > There only seems to be support for conditions based on string
> > > equality
> > > > > > or just non-nullity, not numeric comparisons.  I'm not wanting
> to
> > > add
> > > > > > computation into the view, but it's important in many (human)
> > > > > > languages to be able to vary the text along with a quantity, and
> I
> > > > > > don't want to hard-code parts of the template into the code that
> > > calls
> > > > > > it.
> > > > > >
> > > > > > Thanks,
> > > > > > Christopher
> > > > >
> > > > > --
> > > > > Psssst! Schon vom neuen GMX MultiMessenger gehört?
> > > > > Der kann`s mit allen: http://www.gmx.net/de/go/multimessenger
> > > > >
> > >
> > > --
> > > GMX FreeMail: 1 GB Postfach, 5 E-Mail-Adressen, 10 Free SMS.
> > > Alle Infos und kostenlose Anmeldung: http://www.gmx.net/de/go/freemail
> >
> > --
> > Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
> > Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer
> >

-- 
GMX FreeMail: 1 GB Postfach, 5 E-Mail-Adressen, 10 Free SMS.
Alle Infos und kostenlose Anmeldung: http://www.gmx.net/de/go/freemail


More information about the antlr-interest mailing list