/******************************************************************************* * Copyright (c) 2005 RadRails.org and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.rubypeople.rdt.ui.text.ansi; import java.util.LinkedList; import java.util.List; /** * Provides a method to parse a given String that may be ANSI encoded into tokens * which represent each ANSI formatted substring. * * @author Johannes Holzer <Johannes.Holzer@gmail.com> * */ public class ANSIParser { /** ASCII-Code of the ESC-Symbol marking the possible beginning of an ANSI Sequence */ public final static byte ESC = 27; // states private final static byte TEXT = 0; /** the ANSI_ESC_START state is reached when an ESC-Symbol is detected */ private final static byte ANSI_ESC_START = 1; /** the ANSI state is reached when ESC was followed by [ */ private final static byte ANSI = 2; public List<ANSIToken> parse(String s) { if (s == null) return null; List<ANSIToken> tokens = new LinkedList<ANSIToken>(); ANSIToken t = new ANSIToken(); int state = TEXT; char[] c = s.toCharArray(); StringBuffer ansiBuffer = new StringBuffer(); /* * An ANSI-Sequence looks something like this: * ESC[3;2mThis is textESC[0m */ for (int i = 0; i < c.length; i++) { switch (state) { case TEXT: if (c[i] == ESC) state = ANSI_ESC_START; else t.add(c[i]); break; case ANSI_ESC_START: if (c[i] == '[') { state = ANSI; tokens.add(t); t = new ANSIToken(); } else { state = TEXT; } break; case ANSI: if (c[i] == 'm') state = TEXT; if (c[i] == 'm' || c[i] == ';') { if (ansiBuffer.length() > 0) { try { int value = Integer.parseInt(ansiBuffer.toString()); t.addProperty(value); } catch (NumberFormatException e) { // ignore } } ansiBuffer = new StringBuffer(); } else { ansiBuffer.append(c[i]); } break; } } tokens.add(t); return tokens; } }