Auto-indentation
Auto-indentation
StringTemplate
has auto-indentation on by default. To turn it off, use NoIndentWriter
rather than (the default) AutoIndentWriter
.
At the simplest level, the indentation looks like a simple column count:
My dogs' names $names; separator="\n"$ The last, unindented line
will yield output like:
My dog's names Fido Rex Stinky The last, unindented line
where the last line gets "unindented" after displaying the list. StringTemplate
tracks the characters to the left of the $
or <
rather than the column number so that if you indent with tabs versus spaces, you'll get the same indentation in the output.
When there are nested templates, StringTemplate
tracks the combined indentation:
// <user> is indented two spaces main(user) ::= << Hi \t$user:quote(); separator="\n"$ >> quote ::= " '$it$'"
In this case, you would get output like:
Hi \t 'Bob' \t 'Ephram' \t 'Mary'
where the combined indentation is tab plus space for the attribute references in template quote
. Expression $user$
is indented by 1 tab and hence any attribute generated from it (in this case the $attr$
of quote()
) must have
at least the tab.
Consider generating nested statement lists as in C. Any statements inside must be nested 4 spaces. Here are two templates that could take care of this:
function(name,body) ::= << void $name$() $body$ >> slist(statements) ::= << { $statements; separator="\n"$ }>>
Your code would create a function
template instance and an slist
instance, which gets passed to the function
template as attribute body
. The following code:
Java |
StringTemplate f = group.getInstanceOf("function"); f.setAttribute("name", "foo"); StringTemplate body = group.getInstanceOf("slist"); body.setAttribute("statements", "i=1;"); StringTemplate nestedSList = group.getInstanceOf("slist"); nestedSList.setAttribute("statements", "i=2;"); body.setAttribute("statements", nestedSList); body.setAttribute("statements", "i=3;"); f.setAttribute("body", body); |
---|---|
C# |
StringTemplate f = group.GetInstanceOf("function"); f.SetAttribute("name", "foo"); StringTemplate body = group.GetInstanceOf("slist"); body.SetAttribute("statements", "i=1;"); StringTemplate nestedSList = group.GetInstanceOf("slist"); nestedSList.SetAttribute("statements", "i=2;"); body.SetAttribute("statements", nestedSList); body.SetAttribute("statements", "i=3;"); f.SetAttribute("body", body); |
Python |
f = group.getInstanceOf("function") f["name"] = "foo" body = group.getInstanceOf("slist") body["statements"] = "i=1;" nestedSList = group.getInstanceOf("slist") nestedSList["statements"] = "i=2;" body["statements"] = nestedSList body["statements"] = "i=3;" f["body"] = body |
should generate something like:
void foo() { i=1; { i=2; } i=3; }
Indentation can only occur at the start of a line so indentation is only tracked in front of attribute expressions following a newline.
The one exception to indentation is that naturally, $if$
actions do not cause indentation as they do not result in any output. However, the subtemplates (THEN and ELSE clauses) will see indentations. For example, in the following template, the two subtemplates are indented by exactly 1 space each:
$if(foo)$ $x$ \t\t$else $y$ $endif$