How do I generate indentation events when using '<% ... %>' bounded templates in StringTemplate - stringtemplate-4

This is related to
https://www.stringtemplate.org/api/org/stringtemplate/v4/AutoIndentWriter.html
https://github.com/antlr/stringtemplate4/blob/master/src/org/stringtemplate/v4/AutoIndentWriter.java
If I have a template like...
foo(bar) ::= <<
{
inner
}
>>
...it will cause an indentation event before 'inner' which ultimately calls pushIndentation.
My question is how to cause an indentation event when using '<% ... %>' templates?
Or, what would be the equivalent to the previous template?
The following is similar but not equivalent to the previous example.
foo(bar) ::= <%
{
<\n><\ ><\ >inner
<\n>}
%>
What needs to be done to make it equivalent?

Related

Is there a method to write a response in an EJS template?

With classic ASP you can do a response.write('foo') inside <% ... %>. Is this possible with EJS?
The current workaround is to use 2 tags, one for logic, one for output:
<%
let someString = generateSomeStringHere()
%>
<%- someString %>
I do understand that some will recommend generating someString outside of the template but let's say for the sake of argument that is not desirable.
We would like to do:
<%
let someString = generateSomeStringHere()
ejs.write(someString);
%>

Multiple method overrides in Mason2

Building a website using Mason2. Each page should call 3 filters (methods, called by content):
<% $.filter1(args...) {{ %>
<% $.filter2(args...) {{ %>
<% $.filter3(args...) {{ %>
I have 3 different implementation of those filters (methods). The default set of those 3 filters, are defined in the top level /Base.mc component.
Now, for a different parts of the site - (different routes), say for the
/a/all/paths>/...>
/b/.....
need use the above default set of filters/methods, but for another routes,
/c/...
/d/...
/e/...
need use another set of filter1, filter2, filter3 and for the
/x/....
/y/...
want use the third set.
The methods can be easily redefined, in lower level components, but doing it as in (this question), isn't honors the DRY principe, e.g. in each
/c/Base.mc
/d/Base.mc
/e/Base.mc
Need repeat the same 3
<%override filter1>
...
<%override filter2>
...
<%override filter3>
The question is:
how to write only once the 3 different implementations of the methods, and how to use them at once?
I tried make an compomponent, like: /set2.mi, /set3.mi, where I tried override those filter-methods, and called it in the needed /{c,d,e}/Base.mc as
<& /set2.mi &>
But this doesn't works.
How to write the 3 different methods implementatinons and call them at once in the needed deeprr Base.mc? Is it possible?
In standard perl i would probably use roles, so in the needed packages I would use something like:
with 'Set1';
with 'Set2';
Where the packages Set1 and Set2 would contain the implementations of the needed methods, or for dynamic loading would use the require ... . Is something like possible in the Mason2, or i must repeat the %ovverride?
Hope this make sense... if not, please add an comment and i will try update the question.
EDIT
Example, for shorting the code, using only one filter not 3.
The /Base.mc
<%augment wrap><% inner() %></%augment>
% #this is the "default" MyHead filter
<%filter MyHead($arg)>
<!-- in the real code it is more complicated, but for an illustration it is enough -->
<h1 class="<% $arg %>"><% $yield->() %></h1>
</%filter>
When in the /a/index.mc using it as
% $.MyHead('big') {{
some head text
% }}
will output like:
<h1 class="big">some head text</h1>
now, have an another MyHead.
<%filter MyHead($arg)>
<!-- in the real code it is more complicated - basically want output different thing -->
<h2 id="<% $arg %>"><% $yield->() %></h2>
</%filter>
If I add the above code to my /b/Base.mc it will work, and calling the MyHead filter in the /b/index.mc
% $.MyHead('modal') {{
some other text
% }}
will call the redefined filter, and will output what i want
<h2 id="modal">some other text</h2>
The problem is,
I don't want repeat the above filter code, in N other Base.mc components, like in /c/Base.mc and /d/Base.mc and so on.
How to achieve, to write the filter once and "use" it in many other components for "redefine" the default one.
One solution could be (not a nice one and produces an "spaghetty" like code) playing with the inheritance chain, as next:
Remove your "default" filter from the /Base.mc, so it would contains only the <%augment wrap
Create one component called for example: BaseSetDefault.mc and enter into it, your "default" filter and explicitly set the inheritance chain to the top level /Base.mc
<%augment wrap><% inner() %></%augment>
<%filter MyHead($arg)><h1 class="<% $arg %>"><% $yield->() %></h1></%filter>
<%flags>
extends => '/Base.mc'
</%flags>
Similarly, create an another component say called as /BaseSet2.mc and put here your "Set2" filters, like:
<%augment wrap><% inner() %></%augment>
<%filter MyHead($arg)><h2 id="<% $arg %>"><% $yield->() %></h2></%filter>
<%flags>
extends => '/Base.mc'
</%flags>
Now, in the /a/Base.mc and /b/Base.mc - everywhere, you want the "default" set, change the chain
<%flags>
extends => '/BaseSetDefault.mc'
</%flags>
and in the /c/Base.mc and /d/Base.mc - everywhere you want the "Set2" filters, use the
<%flags>
extends => '/BaseSet2.mc'
</%flags>
From now, the inheritance chain for /c/index.mc will be:
/c/index.mc -> /c/Base.mc -> /BaseSet2.mc -> /Base.mc
and the execution would be done as
/Base.mc -augment-> /BaseSet2.mc -augment-> /c/Base.mc -main-> /c/index.mc
^^^^^^^^^^^^ - defines the Set2 filters
and for the /a/index.mc inheritance chain
/a/index.mc -> /a/Base.mc -> /BaseSetDefault.mc -> /Base.mc
the execution
/Base.mc -augment-> /BaseSetDefault.mc -augment-> /a/Base.mc -main-> /a/index.mc
^^^^^^^^^^^^^^^^^^ - defines the "Default" filters
It is not very nice solution, but works...

Is there a concise way to reference a property of a property in StringTemplate

I find myself wanting to write <prop1.subprop1:sometemplate> to apply a template to a list in a property of a property. To do this, I have to make two levels of template: I have to invoke the outer one on prop1 and and then have it process the next property down.
Data model:
class Clazz {
String name;
Class parent;
}
Goal:
class(c) ::= <<
<c.parent.name> <! oops, not allowed !>
>>
So I end up with
<c.parent:{ p | <p.name> }>
which is a little clumsy.
Then I got to this:
class Attr {
List<String> requiredParameters;
Attr baseObject;
}
and I want to generate:
def __init__(self, reqparam1, ... rewqparamN)
where the first 'reqparam' is from the deepest item. I tried to write the following, but ST gives me syntax errors in the second template where I try to recurse to build a list.
self_and_list(list) ::= << self<if(first(list))>, <endif><list;separator=", "> >>
recurse_req(attr) ::= "<[<attr.baseObject:recurse_req()>, <attr.requiredParameters>]>"
self_and_req_params(attribute) ::= "<self_and_list(<attribute:recurse_req()>)>"

How to define a `separator` tag in play-1.x without modifing play's source code

I want to define a tag separator tag, which inside a list tag, can add separator between items.
The sample code is:
List<String> users = new ArrayList<String>();
users.add("Jeff");
users.add("Mike");
#{list users, as: 'user'}
#{separator ' + ' /}
<span>${user}</span>
#{/list}
If I don't use the separator tag, the code will be:
#{list users, as: 'user'}
${user_isFirst ? '' : ' + '}
<span>${user}</span>
#{/list}
The generated html code will be:
<span>Jeff</span> + <span>Mike</span>
I tried defined a fastTag:
public static void _separator(Map<?, ?> args, Closure body, PrintWriter out, GroovyTemplate.ExecutableTemplate template, int fromLine) {
Object value = args.get("arg");
// TODO how to get the value of `as` defined in parent `list` tag?
out.print(value);
}
But the problem is I can't get the value of as defined in list tag (which is user) in this case.
You can create a custom list tag in groovy like this
#{list items:_arg, as:'tmp'}
%{
attrs = [:]
attrs.put(_as, tmp)
}%
#{ifnot tmp_isFirst}${_sep}#{/ifnot}
#{doBody vars:attrs /}
#{/list}
and use it like this
#{myList users, as:'user', sep:','}
${user}
#{/myList}
You should trace into your FastTag implementation. I think you'll see all the variables in scope inside the args map. This is from memory - so, sorry if not.
That said, I think it might be simpler if you copy the Java code for #{list} and add a new parameter, like
#{list users, as: 'user', separator: '+' }
and handle the logic in there. It seems a bit cleaner too from a design point of view - if it is a separator, how come you can put it anywhere you like in the code (and why not put it in twice!).
A final option is to look at Groovy or Java collection operators. http://groovy.codehaus.org/groovy-jdk/java/util/Collection.html

Xml attribute rendering oddness

Using 2.9.0.1
<b time={None}>Hello</b>
=>
<b >Hello</b>
i.e. there is a space after the b in the starting tag.
This makes no sense from an XML perspective.
Is this "feature" supposed to happen?
Thanks.
It happens because of toString implementation of scala.xml.Elem, to be more specific
in object scala.xml.MetaInf method buildString which looks like following:
def buildString(sb: StringBuilder): StringBuilder = {
sb.append(' ')
toString1(sb)
next.buildString(sb)
}
So it's firstly adds a white space to string representation of element, and only after that appends next attribute, so if an attribute is present as class member but doesn't have any string representation you'll end up with one extra space before closing bracket
Actually, it is allowed. See Extensible Markup Language (XML) 1.0 (Fifth Edition), 3.1 Start-Tags, End-Tags, and Empty-Element Tags. From there:
STag ::= '<' Name (S Attribute)* S? '>'
Where S is whitespace and Attribute is an attribute definition. The same is true for end elements:
ETag ::= '</' Name S? '>'
So this is allowed. Whether or not it's what you want is another thing :-)