package fitnesse.wikitext.parser; import java.util.regex.Pattern; public class TextMaker { public static final String eMailPattern = "[\\w-_.]+@[\\w-_.]+\\.[\\w-_.]+"; private VariableSource variableSource; private SourcePage sourcePage; public TextMaker(VariableSource variableSource, SourcePage sourcePage) { this.variableSource = variableSource; this.sourcePage = sourcePage; } public SymbolMatch make(ParseSpecification specification, int offset, String text) { if (specification.matchesFor(WikiWord.symbolType)) { int length = findWikiWordLength(text); if (length > 0) { Symbol wikiWord = new Symbol(new WikiWord(sourcePage), text.substring(0, length), offset); wikiWord.evaluateVariables(new String[]{WikiWord.REGRACE_LINK}, variableSource); return new SymbolMatch(wikiWord, offset, length); } } if (specification.matchesFor(SymbolType.EMail) && isEmailAddress(text)) { return new SymbolMatch(SymbolType.EMail, text, offset); } return new SymbolMatch(SymbolType.Text, text, offset); } private boolean isEmailAddress(String text) { return text.indexOf("@") > 0 && Pattern.matches(eMailPattern, text); } public int findWikiWordLength(String text) { String candidate = text + "."; int offset = "<>^.".contains(candidate.substring(0, 1)) ? 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 candidate.charAt(offset) >= 'A' && candidate.charAt(offset) <= 'Z'; } private boolean isLowerCaseLetter(String candidate, int offset) { return candidate.charAt(offset) >= 'a' && candidate.charAt(offset) <= 'z'; } private boolean isDigit(String candidate, int offset) { return candidate.charAt(offset) >= '0' && candidate.charAt(offset) <= '9'; } private boolean isLetter(String candidate, int offset) { return isUpperCaseLetter(candidate, offset) || isLowerCaseLetter(candidate, offset); } private boolean isCharacter(String candidate, char character, int offset) { return candidate.charAt(offset) == character; } }