package fitnesse.wikitext.parser;
import java.util.regex.Pattern;
public class WikiWordPath {
//todo: get rid of these
private static final String SINGLE_WIKIWORD_REGEXP = "\\b[A-Z](?:[a-z0-9]+[A-Z][a-z0-9]*)+";
private static final String REGEXP = "(?:[<>^.])?(?:" + SINGLE_WIKIWORD_REGEXP + "[.]?)+\\b";
public static boolean isSingleWikiWord(String s) {
return Pattern.matches(SINGLE_WIKIWORD_REGEXP, s);
}
public static boolean isWikiWord(String word) {
return Pattern.matches(REGEXP, word);
}
public static String makeWikiWord(String input) {
if (isWikiWord(input)) return input;
String base = input;
while (base.length() < 3) base += "a";
return base.substring(0, 1).toUpperCase()
+ base.substring(1, base.length() - 1).toLowerCase()
+ base.substring(base.length() - 1).toUpperCase();
}
public int findLength(String text) {
String candidate = text + ".";
int offset = "<>^.".indexOf(candidate.substring(0, 1)) >= 0 ? 1 : 0;
while (offset < candidate.length()) {
int dot = candidate.indexOf(".", offset);
int word = wikiWordLength(candidate.substring(offset, dot));
if (word == 0) return offset > 1 ? offset - 1 : 0;
if (offset + word < dot) return offset + word;
offset = dot + 1;
}
return text.length();
}
private int wikiWordLength(String candidate) {
if (candidate.length() < 3) return 0;
if (!isUpperCaseLetter(candidate, 0)) return 0;
if (!isDigit(candidate, 1) && !isLowerCaseLetter(candidate, 1)) return 0;
int lastUpperCaseLetter = 0;
int i;
for (i = 2; i < candidate.length(); i++) {
if (isCharacter(candidate, '_', i)) return 0;
if (isUpperCaseLetter(candidate, i)) {
if (i == lastUpperCaseLetter + 1) return 0;
lastUpperCaseLetter = i;
}
else if (!isDigit(candidate, i) && !isLetter(candidate, i) && !isCharacter(candidate, '.', i)) break;
}
if (lastUpperCaseLetter > 0 && i > 2) return i;
return 0;
}
private boolean isUpperCaseLetter(String candidate, int offset) {
return isLetter(candidate, offset) && Character.isUpperCase(candidate.charAt(offset));
}
private boolean isLowerCaseLetter(String candidate, int offset) {
return isLetter(candidate, offset) && Character.isLowerCase(candidate.charAt(offset));
}
private boolean isDigit(String candidate, int offset) {
return Character.isDigit(candidate.charAt(offset));
}
private boolean isLetter(String candidate, int offset) {
return Character.isLetter(candidate.charAt(offset));
}
private boolean isCharacter(String candidate, char character, int offset) {
return candidate.charAt(offset) == character;
}
}