All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.stringtemplate.v4.AutoIndentWriter Maven / Gradle / Ivy

Go to download

StringTemplate is a java template engine for generating source code, web pages, emails, or any other formatted text output. StringTemplate is particularly good at multi-targeted code generators, multiple site skins, and internationalization/localization. It evolved over years of effort developing jGuru.com. StringTemplate also powers the ANTLR 3 and 4 code generator. Its distinguishing characteristic is that unlike other engines, it strictly enforces model-view separation. Strict separation makes websites and code generators more flexible and maintainable; it also provides an excellent defense against malicious template authors.

There is a newer version: 4.3.4
Show newest version
/*
 * [The "BSD license"]
 *  Copyright (c) 2011 Terence Parr
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.stringtemplate.v4;

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

/** Essentially a char filter that knows how to auto-indent output
 *  by maintaining a stack of indent levels.
 *
 *  The indent stack is a stack of strings so we can repeat original indent
 *  not just the same number of columns (don't have to worry about tabs vs
 *  spaces then).
 *
 *  Anchors are char positions (tabs won't work) that indicate where all
 *  future wraps should justify to.  The wrap position is actually the
 *  larger of either the last anchor or the indentation level.
 *
 *  This is a filter on a Writer.
 *
 *  \n is the proper way to say newline for options and templates.
 *  Templates can mix \r\n and \n them but use \n for sure in options like
 *  wrap="\n". ST will generate the right thing. Override the default (locale)
 *  newline by passing in a string to the constructor.
 */
public class AutoIndentWriter implements STWriter {
	/** stack of indents; use List as it's much faster than Stack. Grows
	 *  from 0..n-1.
	 */
	public List indents = new ArrayList();

	/** Stack of integer anchors (char positions in line); avoid Integer
	 *  creation overhead.
	 */
	public int[] anchors = new int[10];
	public int anchors_sp = -1;

	/** \n or \r\n? */
	public String newline;

	public Writer out = null;
    public boolean atStartOfLine = true;

	/** Track char position in the line (later we can think about tabs).
	 *  Indexed from 0.  We want to keep charPosition <= lineWidth.
	 *  This is the position we are *about* to write not the position
	 *  last written to.
	 */
    public int charPosition = 0;

    /** The absolute char index into the output of the next char to be written. */
    public int charIndex = 0;

	public int lineWidth = NO_WRAP;

	public AutoIndentWriter(Writer out, String newline) {
		this.out = out;
		indents.add(null); // s oftart with no indent
		this.newline = newline;
	}

	public AutoIndentWriter(Writer out) {
		this(out, System.getProperty("line.separator"));
	}

	public void setLineWidth(int lineWidth) {
		this.lineWidth = lineWidth;
	}

    public void pushIndentation(String indent) {
        indents.add(indent);
    }

    public String popIndentation() {
        return indents.remove(indents.size()-1);
    }

	public void pushAnchorPoint() {
		if ( (anchors_sp +1)>=anchors.length ) {
			int[] a = new int[anchors.length*2];
			System.arraycopy(anchors, 0, a, 0, anchors.length-1);
			anchors = a;
		}
		anchors_sp++;
		anchors[anchors_sp] = charPosition;
	}

	public void popAnchorPoint() {
		anchors_sp--;
	}

    public int index() { return charIndex; }

	/** Write out a string literal or attribute expression or expression element.*/
	public int write(String str) throws IOException {
		int n = 0;
		int nll = newline.length();
		int sl = str.length();
		for (int i=0; i= lineWidth )
		{
			// ok to wrap
			// Walk wrap string and look for A\nB.  Spit out A\n
			// then spit indent or anchor, whichever is larger
			// then spit out B.
			for (int i=0; i=0 && anchors[anchors_sp]>indentWidth ) {
            int remainder = anchors[anchors_sp]-indentWidth;
            for (int i=1; i<=remainder; i++) out.write(' ');
            n += remainder;
        }

        charPosition += n;
        charIndex += n;
		return n;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy