FreeMarker: keep identation when using macros
It would seem that docAsComment
is always invoked at the same level of indentation in the code generate. You could bake that indentation into the macro.
If the indentation of the comment is variable, you'd have to pass in the indentation level. I don't understand your comment about that making the template harder to read. It does make the macro a little more complicated.
The invocation would look like this:
<@docAsComment class.doc 1/>
Macro would change to something like this:
<#macro docAsComment doc indent=1>
<#local spc>${""?left_pad(indent * 4)}</#local>
${spc}/*
<#if doc.title != "">
${spc}* ${doc.title}
</#if>
<#list doc.content as content>
<#if content != "">${spc} * ${content}</#if>
</#list>
${spc}*/
</#macro>
Not too bad, really. You can make the macro a little easier to read by indenting it:
<#macro docAsComment doc indent=1>
<#local spc>${""?left_pad(indent * 4)}</#local>
${spc}/*<#lt>
<#if doc.title != "">
${spc}* ${doc.title}<#lt>
</#if>
<#list doc.content as content>
<#if content != "">${spc} * ${content}</#if><#lt>
</#list>
${spc}*/<#lt>
</#macro>
Today, it is possible to use <#nt>
. The whitespace documentation says the following about it:
White-space stripping can be disabled for a single line with the nt directive (for No Trim).
According to the V2.3 changelog, in previous versions, lines containing only FTL tags get trimmed, with the exception of <#include>
and custom directives (like <@macroname>
). But in V2.3 they changed this behavior to ALWAYS trim such lines. So, when using your macro, you may put <#nt>
on the line to prevent trimming, and so, keeping indentation.
<#macro test>
...<#t>
</#macro>
Example:
- <@test /><#nt>
gives the result:
Example:
- ...
You can see, in the macro, I defined <#t>
, this is because the new line from inside the macro, will not be trimmed, and would always give a new line where you <@macro>
it, so in one part, we trim the white-space, and in the other part, we keep it!
Edit:
It should be worth mentioning that, for some reason, this only works for one line. If you have multiple lines in your macro, it only keeps the indentation for the first line. Thus far I have found no fix for this but I created an issue in the Freemarker JIRA for this.
Example:
<#macro test>
...
wow
</#macro>
Example:
- <@test><#nt>
will result in:
Example:
- ...
wow