package net.lucky_dip.hamleditor; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * A class to hold haml or sass text. * * It provides a few helpful functions to sort and manipulate blocks too. * * @author brad */ public class HamlesqueBlock { /** * Counts the number of spaces at the beginning of the given line */ public static int countIndentSpaces(String line) { int res = 0; for (int i = 0; i < line.length(); i++) { if (line.charAt(i) != ' ') { break; } else { res++; } } return res; } protected List<String> lines; /** * Construct a new hamlesque block object to hold the given text */ public HamlesqueBlock(String text) { lines = textToLines(text); } /** * Construct a new hamlesque block object to hold the given lines */ public HamlesqueBlock(String[] lines) { this.lines = Arrays.asList(lines); } /** * Calculates all hamlesque blocks contained in this block */ public HamlesqueBlock[] getSubBlocks() { return getSubBlocks(0); } /** * Returns the lines in this block */ public String[] getLines() { return lines.toArray(new String[lines.size()]); } /** * Calculates all hamlesque blocks contained in this block, starting at the * given line index. */ public HamlesqueBlock[] getSubBlocks(int startLine) { List<HamlesqueBlock> res = new ArrayList<HamlesqueBlock>(); while (startLine < lines.size()) { if (isBlankLine(startLine)) { startLine++; continue; } else { HamlesqueBlock nextBlock = getBlockStartingAt(startLine); startLine += nextBlock.getLines().length; res.add(nextBlock); } } return (HamlesqueBlock[]) res.toArray(new HamlesqueBlock[0]); } /** * Calculates and returns the block starting on the given line. */ private HamlesqueBlock getBlockStartingAt(int startLine) { int initialOffset = countIndentSpaces(lines.get(startLine)); int endLine; for (endLine = startLine + 1; endLine < lines.size(); endLine++) { if (!isBlankLine(endLine)) { int currentOffset = countIndentSpaces(lines.get(endLine)); if (currentOffset <= initialOffset) { endLine--; break; } } } // if (endLine < lines.length - 1) { // endLine--; // } // if there's a bunch of blank lines at the end of // the block, we need to trim them out. for (int i = endLine - 1; endLine > startLine; i--) { if (!isBlankLine(i)) { endLine = i; break; } } int length = endLine + 1 - startLine; String[] linesInBlock = new String[length]; int x = 0; for (int i = startLine; i < endLine + 1; i++) { linesInBlock[x++] = lines.get(i); } return new HamlesqueBlock(linesInBlock); } /** * Returns true if the line at the given index only contains whitespace. * * Returns false otherwise. */ private boolean isBlankLine(int index) { if (index < 0 || index >= lines.size()) return false; String line = lines.get(index); return line.trim().length() == 0; } /** * Splits the given text into an array of lines */ protected List<String> textToLines(String text) { return Arrays.asList(text.split("\n")); } /** * Adds a line to this block at the given index */ protected void addLine(int i, String line) { lines.add(i, line); } /** * Removes the line at the given index from this block */ protected String removeLine(int i) { return lines.remove(i); } public String toString() { StringBuffer sb = new StringBuffer(); for (String line : lines) { sb.append(line); sb.append("\n"); } if (!lines.isEmpty()) sb.deleteCharAt(sb.length() - 1); return sb.toString(); } }