[stringtemplate-interest] summarizing white space and indentation

Zenaan Harkness zen at freedbms.net
Sun Nov 8 17:48:10 PST 2009


On Sun, Nov 08, 2009 at 12:59:43PM -0800, Jonathan Buhacoff wrote:
>
> On Nov 8, 2009, at 10:40 AM, Terence Parr wrote:
>
>> Verrrrrrry interesting.  Perhaps this gives an opport. to format  
>> templates w/o messing up output.
>>
>> <if(x)>
>> foo
>> <endif>
>>
>> would give "foo\n" by default if x.  It would give "" if !x.  Wait,  
>> how to remove \n from after foo?
>>
>> <if(x)>
>> foo
>> <-endif>

Yes. Looks very clean. Aligns with an existing syntax that Jonathan
raised. Perfect.

Only thing is, you're still assuming removing initial \n.
So instead perhaps use:

   <if(x)->
   foo
   <-endif>

Of course, if we wanted to be really strict here, then it might be:

   <-if(x)>
   foo
   <endif->

with the question arising, does the '-' be the syntax that removes
all whitespace, or just \n. I suggest that anything other than "all
whitespace between this point and the next bit of non-whitespace is
removed" would be confusing.

So in my last example above, the pre-fix '-' removes whitespace
before the 'if', including any newline, and the - after the endif
would remove whitespace after the if. This of course assumes that the
user of the template wants "\n   foo\n   " in their template, which
is what I tend to use.

But of course, '-' is so simple and visually innocuous, it works a
treat as far as I can tell, for any scenario someone might want.

Great stuff.


>> ?? probably not.

Why not?


> You could remove the \n from after foo like this:
>
> <if(x)>
> foo<empty->    <! where empty is an empty template named "empty" !>
> <endif>
>
> or
>
> <if(x)>
> foo<""->   <! empty string as literal empty template  !>
> <endif>
>
>
> Maybe <""-> looks rather ugly,  but how nice can a representation of  
> nothingness be?  Maybe <\\-> is a little better, but I would expect a  
> backslash out of that and not an empty string.  Maybe \e meaning empty  
> string could then be used as <\e->.   I like \e because it doesn't step 
> on any existing standard that I know of.  ANSI-C  defines only \n \r \t 
> \b \\ \? \' and \"

How about just <> and <->, for completely-empty template (if ever
needed) and for white-space-removing empty template, respectively?

Clean as it gets.


>> Let's use a real example where I have a huge single template line to  
>> obtain a single output line (it might wrap in your emailer:
>>
>> public <returnType()> <ruleDescriptor 
>> .name>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>)  
>> throws RecognitionException \{ 
>> <if(ruleDescriptor.hasReturnValue)>return <endif><ruleDescriptor 
>> .grammar:delegateName 
>> ()>.<ruleDescriptor.name>(<ruleDescriptor.parameterScope.attributes: 
>> {a|<a.name>}; separator=", ">); \}}; separator="\n">
>>
>> Here we have exprs and IF stuff and {...} stuff with separator option.  
>> What I'd like is to add some formatting:
>>
>> public <returnType()> <ruleDescriptor.name>(
>>     <ruleDescriptor.parameterScope:parameterScope(scope=it)>
>> ) throws RecognitionException {
>>     <if(ruleDescriptor.hasReturnValue)>return <endif>
>>     <ruleDescriptor.grammar:delegateName()>.<ruleDescriptor.name>(
>>         <ruleDescriptor.parameterScope.attributes:{a|<a.name>};  
>> separator=", ">
>>     );
>> \}}; separator="\n">
>>
>
> My attempt, this time trying <\e-> to see how it looks.  Notice also the 
> leading/trailing whitespace control on other tags:
>
> public <returnType()> <ruleDescriptor.name>(<\e->
>     <-ruleDescriptor.parameterScope:parameterScope(scope=it)->

Looking at the above two lines, if the '-' prefixing ruleDescriptor
removes "all whitespace", then surely the '<\e->' (or <-> or whatever)
is not necessary at all ??


> ) throws RecognitionException {<\e->
>     <-if(ruleDescriptor.hasReturnValue)>return <endif->
>     <-ruleDescriptor.grammar:delegateName()>.<ruleDescriptor.name>(<\e->
>         <-ruleDescriptor.parameterScope.attributes:{a|<a.name>};
> separator=", "->
>     );<\e->
> \}}; separator="\n">
>
> Or, if the rule for trailing whitespace control is eliminate all  
> whitespace up to the next template tag or literal character (like what  
> <\\> is currently supposed to do), then this specific example wouldn't  
> need to use the leading whitespace controls (but they'd still be  
> necessary for other situations):

Ahh of course. Similar thought process. How about:

public <returnType()> <ruleDescriptor.name>(
    <-ruleDescriptor.parameterScope:parameterScope(scope=it)->
) throws RecognitionException {
    <-if(ruleDescriptor.hasReturnValue)>return <endif->
    <ruleDescriptor.grammar:delegateName()>.<ruleDescriptor.name>(
        <-ruleDescriptor.parameterScope.attributes:{a|<a.name>};
separator=", "->
    );<->
\}}; separator="\n">


Very clean yes? Ter, does this give you exactly what you want?

...
>> I guess that works. The <\\> would scarf \n followed by whitespace.   
>> Hmm....seems ok.
>>
>> I like the '-' idea so we could indent IFs:
>>
>> <if(x)>
>>     <-name>  <! don't indent; I'm just formatting template !>
>> <endif>
>>
>> OTOH, that makes it harder to read templates. have to read carefully  
>> to figure out indentation.

I think what you need is any of the following:

<if(x)>
    <-name>
<-endif>

<if(x)>
    <-name->
<endif>

<if(x)->
    <name>
<-endif>

etc

Any of those look about as clean and sweet as it gets, and immediately
easy to see the output, each of which should be the same?


best
zen


-- 
Free Australia: www.UPMART.org
Please respect the confidentiality of this email as sensibly warranted.


More information about the stringtemplate-interest mailing list