Package org.fife.ui.rsyntaxtextarea.folding

Source Code of org.fife.ui.rsyntaxtextarea.folding.JsonFoldParser

/*
* 12/23/2012
*
* JsonFoldParser.java - Fold parser for JSON.
*
* This library is distributed under a modified BSD license.  See the included
* RSyntaxTextArea.License.txt file for details.
*/
package org.fife.ui.rsyntaxtextarea.folding;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import javax.swing.text.BadLocationException;

import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.Token;
import org.fife.ui.rsyntaxtextarea.TokenTypes;


/**
* The fold parser for JSON.  Objects (<code>"{ ... }</code>") and arrays
* (<code>"[ ... ]"</code>) that span multiple lines are considered fold
* regions.
*
* @author Robert Futrell
* @version 1.0
*/
public class JsonFoldParser implements FoldParser {

  private static final Object OBJECT_BLOCK = new Object();
  private static final Object ARRAY_BLOCK = new Object();


  /**
   * {@inheritDoc}
   */
  public List getFolds(RSyntaxTextArea textArea) {

    Stack blocks = new Stack();
    List folds = new ArrayList();

    Fold currentFold = null;
    int lineCount = textArea.getLineCount();

    try {

      for (int line=0; line<lineCount; line++) {

        Token t = textArea.getTokenListForLine(line);
        while (t!=null && t.isPaintable()) {

          if (t.isLeftCurly()) {
            if (currentFold==null) {
              currentFold = new Fold(FoldType.CODE, textArea, t.offset);
              folds.add(currentFold);
            }
            else {
              currentFold = currentFold.createChild(FoldType.CODE, t.offset);
            }
            blocks.push(OBJECT_BLOCK);
          }

          else if (t.isRightCurly() && popOffTop(blocks, OBJECT_BLOCK)) {
            if (currentFold!=null) {
              currentFold.setEndOffset(t.offset);
              Fold parentFold = currentFold.getParent();
              //System.out.println("... Adding regular fold at " + t.offset + ", parent==" + parentFold);
              // Don't add fold markers for single-line blocks
              if (currentFold.isOnSingleLine()) {
                if (!currentFold.removeFromParent()) {
                  folds.remove(folds.size()-1);
                }
              }
              currentFold = parentFold;
            }
          }

          else if (isLeftBracket(t)) {
            if (currentFold==null) {
              currentFold = new Fold(FoldType.CODE, textArea, t.offset);
              folds.add(currentFold);
            }
            else {
              currentFold = currentFold.createChild(FoldType.CODE, t.offset);
            }
            blocks.push(ARRAY_BLOCK);
          }

          else if (isRightBracket(t) && popOffTop(blocks, ARRAY_BLOCK)) {
            if (currentFold!=null) {
              currentFold.setEndOffset(t.offset);
              Fold parentFold = currentFold.getParent();
              //System.out.println("... Adding regular fold at " + t.offset + ", parent==" + parentFold);
              // Don't add fold markers for single-line blocks
              if (currentFold.isOnSingleLine()) {
                if (!currentFold.removeFromParent()) {
                  folds.remove(folds.size()-1);
                }
              }
              currentFold = parentFold;
            }
          }

          t = t.getNextToken();

        }

      }

    } catch (BadLocationException ble) { // Should never happen
      ble.printStackTrace();
    }

    return folds;

  }


  /**
   * Returns whether a token is the left bracket token.
   *
   * @param t The token.
   * @return Whether the token is the left bracket token.
   * @see #isRightBracket(Token)
   */
  private static final boolean isLeftBracket(Token t) {
    return t.type==TokenTypes.SEPARATOR && t.isSingleChar('[');
  }


  /**
   * Returns whether a token is the right bracket token.
   *
   * @param t The token.
   * @return Whether the token is the right bracket token.
   * @see #isLeftBracket(Token)
   */
  private static final boolean isRightBracket(Token t) {
    return t.type==TokenTypes.SEPARATOR && t.isSingleChar(']');
  }


  /**
   * If the specified value is on top of the stack, pop it off and return
   * <code>true</code>.  Otherwise, return <code>false</code>.
   *
   * @param stack The stack.
   * @param value The value to check for.
   * @return Whether the value was found on top of the stack.
   */
  private static final boolean popOffTop(Stack stack, Object value) {
    if (stack.size()>0 && stack.peek()==value) {
      stack.pop();
      return true;
    }
    return false;
  }


}
TOP

Related Classes of org.fife.ui.rsyntaxtextarea.folding.JsonFoldParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.