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

com.google.gxp.compiler.io..svn.text-base.CIndenter.svn-base Maven / Gradle / Ivy

Go to download

Google XML Pages (GXP) is a templating system used to generate XML/SGML markup (most often HTML).

The newest version!
/*
 * Copyright (C) 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.gxp.compiler.io;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;

import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Utility class for generating nicely indented code in C-like languages. It's
 * almost an Appendable "decorator" in that it wraps around an existing
 * Appendable. It has a different interface from Appendable though, so it
 * doesn't implement Appendable.
 *
 * 

It performs the following transformations on the input before passing it * through to the underlying Appendable: *

    *
  • adds newlines. CIndenter is line based. *
  • adds indentation. The indentation level is automatically adjusted based * on the presence of curly braces. *
  • (optionally) adds trailing comments. *
*/ public final class CIndenter { private static final String INDENT = " "; private static final String HALF_INDENT = " "; private static final Pattern NEWLINE_PATTERN = Pattern.compile("\n"); private final Appendable out; private final List halfIndentMarkers; private int indentationLevel = 0; public CIndenter(Appendable out, String... halfIndentMarkers) { this.out = Preconditions.checkNotNull(out); this.halfIndentMarkers = ImmutableList.copyOf(halfIndentMarkers); } private void appendIndent(boolean oneLessSpace) throws IOException { for (int i = 0; i < indentationLevel; i++) { out.append((oneLessSpace && (i == indentationLevel - 1)) ? HALF_INDENT : INDENT); } } /** * Appends the tail comment to the line (if there is one). Inserts an * appropriate amount of spaces so that the tail comment will begin at * column 80, unless the line is already too long in which case 3 spaces * are inserted. */ private void appendTailComment(int lineLength, String tailComment) throws IOException { if (tailComment.length() > 0) { int indentLength = indentationLevel * INDENT.length(); int spacerLength = Math.max(80 - (lineLength + indentLength), 3); for (int i = 0; i < spacerLength; i++) { out.append(" "); } out.append(tailComment); } } public void addIndent() { indentationLevel++; } /** * Appends the specified line with indentation and a trailing newline. * The presence of leading or trailing curly braces will adjust the * indentation. A leading "}" will cause this line and subsequent lines to be * outdented, while a trailing "{" will cause subsequent lines to be * indented. * @param line the line to be appended * @throws RuntimeIOException if underlying Appendable throws IOException. */ public void appendLine(CharSequence line) { appendLine(line, ""); } /** * Like {@link #appendLine(CharSequence)}, but also accepts a trailing * comment. * @param line the line to be appended * @param tailComment a "line comment" to add to the end of the line. This is * appended after the braces are inspected, making it possible to have a * "trailing" open brace which causes an indent which is actually followed by * this comment. Note that the caller is responsible for ensuring that this * is actually a comment by using a "//" prefix, or whatever else is * necessary for the language being generated. * @throws RuntimeIOException if underlying Appendable throws IOException. */ public void appendLine(CharSequence line, String tailComment) { try { if (line.length() == 0) { if (tailComment.length() > 0) { appendIndent(false); appendTailComment(0, tailComment); } out.append("\n"); } else { if (line.charAt(0) == '}') { indentationLevel--; } appendIndent(halfIndentMarkers.contains(line)); Matcher m = NEWLINE_PATTERN.matcher(line); int sliceStart = 0; while (m.find()) { CharSequence cs = line.subSequence(sliceStart, m.start()); out.append(cs); appendTailComment(cs.length(), tailComment); out.append("\n"); appendIndent(halfIndentMarkers.contains(line)); sliceStart = m.end(); } CharSequence cs = line.subSequence(sliceStart, line.length()); out.append(cs); appendTailComment(cs.length(), tailComment); out.append("\n"); if (line.charAt(line.length() - 1) == '{') { indentationLevel++; } } } catch (IOException iox) { throw new RuntimeIOException(iox); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy