package ring.util;
/**
* <p>Title: RingMUD Codebase</p>
* <p>Description: RingMUD is a java codebase for a MUD with a working similar to DikuMUD</p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: RaiSoft/Thermetics</p>
* @author Jeff Hair
* @version 1.0
*/
import java.util.*;
//TODO refactor this into a non static class. will allow for better code
//in parseOutgoingData
public class TextParser {
//Constants
public static final int SCREEN_WIDTH = 80;
private static final Map<String, String> colors = new HashMap<String, String>();
static {
//Black.
colors.put("[BLACK]", "\033[30m");
//Blue.
colors.put("[BLUE]", "\033[34m");
//Cyan.
colors.put("[CYAN]", "\033[36m");
//Green.
colors.put("[GREEN]", "\033[32m");
//Magenta.
colors.put("[MAGENTA]", "\033[35m");
//Red.
colors.put("[RED]", "\033[31m");
//White.
colors.put("[WHITE]", "\033[39m");
//Yellow.
colors.put("[YELLOW]", "\033[33m");
//Bold.
colors.put("[B]", "\033[1m");
//Regular.
colors.put("[R]", "\033[0m");
}
public TextParser() {}
public static String trimNewlines(String text) {
//Don't need to make any changes to an empty string.
if (text.length() == 0) return text;
char[] textChars = text.toCharArray();
int start = 0;
int end = text.length() - 1;
//first remove \ns from the beginning.
while(textChars[start] == '\n')
start++;
//now the end.
while(textChars[end] == '\n')
end--;
//we now have the start and end of the string where there are no newlines.
return text.substring(start, end + 1);
}
public static String parseOutgoingData(String data, boolean screenWidthParsing) {
if (screenWidthParsing) {
return parseOutgoingData(data);
}
else {
return parseOutgoingDataNoSWP(data);
}
}
//Explicitly does not insert newlines.
private static String parseOutgoingDataNoSWP(String data) {
StringTokenizer st = new StringTokenizer(data, "\n[], \t", true);
StringBuilder res = new StringBuilder();
int count = 0;
while (st.hasMoreTokens()) {
String text = st.nextToken();
//handle possibility of inline commands
if (text.equals("[")) {
text += st.nextToken() + st.nextToken();
String replaceValue = colors.get(text);
//if there was a replacement match found, use that.
//otherwise it's not a command.
if (replaceValue != null)
text = replaceValue;
else
count += text.length();
}
//handle \ns directly.
else if (text.equals("\n")) {
res.append("\r\n");
count = 0;
continue;
}
//normal data handling
else {
count += text.length();
}
//finally we can append normally, if we reach this part.
res.append(text);
}
//make sure we return to default.
res.append(colors.get("[R]"));
return res.toString();
}
//This method is used to replace the color tags with the correct ANSI codes.
public static String parseOutgoingData(String data) {
StringTokenizer st = new StringTokenizer(data, "\n[], \t", true);
StringBuilder res = new StringBuilder();
int count = 0;
while (st.hasMoreTokens()) {
String text = st.nextToken();
//handle possibility of inline commands
if (text.equals("[")) {
text += st.nextToken() + st.nextToken();
String replaceValue = colors.get(text);
//if there was a replacement match found, use that.
//otherwise it's not a command.
if (replaceValue != null)
text = replaceValue;
else
count += text.length();
}
//handle \ns directly.
else if (text.equals("\n")) {
res.append("\n");
count = 0;
continue;
}
//normal data handling
else {
count += text.length();
}
if (count >= SCREEN_WIDTH) {
res.append(text);
int offset = count - SCREEN_WIDTH;
int maxIndex = res.length() - 1;
char c = res.charAt(maxIndex - offset);
//rewind until we find a character that is whitespace
while (Character.isWhitespace(c) == false) {
offset++;
c = res.charAt(maxIndex - offset);
}
//Leave whitespace on the line above by moving offset back one
if (offset != 0) {
offset--;
}
//Now we should have a safe insert.
res.insert(maxIndex - offset, "\r\n");
count = offset;
continue;
}
//finally we can append normally, if we reach this part.
res.append(text);
}
//make sure we return to default.
res.append(colors.get("[R]"));
//It is FAR simpler to remove spaces on the beginning/end of lines this way
//instead of in the parsing loop.
//This funky character class is actually the \s class with the \n removed.
//This ensures newlines in the suffix from communicators are left alone.
//See: http://java.sun.com/docs/books/tutorial/essential/regex/pre_char_classes.html
String ret = res.toString();
ret = ret.replaceAll("\n[ \\t\\x0B\\f\\r]+", "\n");
return ret;
}
/**
* Removes all formatting from the given String. Useful for
* sending data to players who have ANSI turned off, as well
* as other internal uses.
* @param displayName
* @return
*/
public static String stripFormatting(String text) {
for (String color : colors.keySet()) {
//These two lines turn the color string
//into a regex.
color = color.replace("[", "\\[");
color = color.replace("]", "\\]");
//Now we can destroy all colors via regex power!
text = text.replaceAll(color, "");
}
return text;
}
public static void main(String[] args) {
System.out.println(stripFormatting("[WHITE]blah[CYAN]"));
}
}