In a StringTemplate how to temporarily suppress automatic indentation?

123 Views Asked by At

In a StringTemplate how to temporarily suppress automatic indentation? Suppose a template:

fooTemplate() ::= <<
  I want this to be indented normally.
  # I do not want this line to be indented.
>>

So you can understand the motivation. I am generating C-lang code and I do not want the preprocessor instructions to be indented. e.g.

#if 

To be clear the fooTemplate is not the only template. It is called by other templates (which may nest several levels deep).

Introducing a special character into the template to temporarily disable indentation would be acceptable.

fooTemplate() ::= <<
   I want this to be indented normally.
<\u0008># I do not want this line to be indented.
>>
1

There are 1 best solutions below

0
phreed On

I see that indentation is actually applied by the 'AutoIndentWriter' https://github.com/antlr/stringtemplate4/blob/master/doc/indent.md I implemented my own 'SemiAutoIndentWriter' which looks for a magic character (\b in my case) in the stream. When seen the magic character sets a 'suppressIndent' switch which causes indentation to be suppressed.

package org.stringtemplate.v4;

import java.io.IOException;
import java.io.Writer;

/** Just pass through the text. */
public class SemiAutoIndentWriter extends AutoIndentWriter {
  public boolean suppressIndent = false;

  public SemiAutoIndentWriter (Writer out) {
    super(out);
  }
  @Override
  public int write(String str) throws IOException {
    int n = 0;
    int nll = newline.length();
    int sl = str.length();
    for (int i=0; i<sl; i++) {
        char c = str.charAt(i);
        if ( c=='\b' ) {
            suppressIndent = true;
            continue;
        }
        // found \n or \r\n newline?
        if ( c=='\r' ) continue;
        if ( c=='\n' ) {
            suppressIndent = false
            atStartOfLine = true;
            charPosition = -nll; // set so the write below sets to 0
            out.write(newline);
            n += nll;
            charIndex += nll;
            charPosition += n; // wrote n more char
            continue;
        }
        // normal character
        // check to see if we are at the start of a line; need indent if so
        if ( atStartOfLine ) {
            if (! suppressIndent) n+=indent();
            atStartOfLine = false;
        }
        n++;
        out.write(c);
        charPosition++;
        charIndex++;
    }
    return n;
}

Note that the '<\b>' is not a recognized special character by ST4 but '' is recognized.