@Override public final RuleMatch[] match(final AnalyzedSentence text) { final List<RuleMatch> ruleMatches = new ArrayList<RuleMatch>(); final AnalyzedTokenReadings[] tokens = text.getTokens(); String prevToken = ""; String prevPrevToken = ""; boolean prevWhite = false; int pos = 0; int prevLen = 0; for (int i = 0; i < tokens.length; i++) { final String token = tokens[i].getToken(); final boolean isWhite = tokens[i].isWhitespace() || tokens[i].isFieldCode(); pos += token.length(); String msg = null; int fixLen = 0; String suggestionText = null; if (isWhite && isLeftBracket(prevToken)) { msg = messages.getString("no_space_after"); suggestionText = prevToken; fixLen = 1; } else if (!isWhite && prevToken.equals(",") && isNotQuoteOrHyphen(token) && containsNoNumber(prevPrevToken) && containsNoNumber(token) && !",".equals(prevPrevToken)) { msg = messages.getString("missing_space_after_comma"); suggestionText = ", "; } else if (prevWhite) { if (isRightBracket(token)) { msg = messages.getString("no_space_before"); suggestionText = token; fixLen = 1; } else if (token.equals(",")) { msg = messages.getString("space_after_comma"); suggestionText = ","; fixLen = 1; // exception for duplicated comma (we already have another rule for that) if (i + 1 < tokens.length && ",".equals(tokens[i + 1].getToken())) { msg = null; } } else if (token.equals(".")) { msg = messages.getString("no_space_before_dot"); suggestionText = "."; fixLen = 1; // exception case for figures such as ".5" and ellipsis if (i + 1 < tokens.length && isNumberOrDot(tokens[i + 1].getToken())) { msg = null; } } } if (msg != null) { final int fromPos = tokens[i - 1].getStartPos(); final int toPos = tokens[i - 1].getStartPos() + fixLen + prevLen; // TODO: add some good short comment here final RuleMatch ruleMatch = new RuleMatch(this, fromPos, toPos, msg); ruleMatch.setSuggestedReplacement(suggestionText); ruleMatches.add(ruleMatch); } prevPrevToken = prevToken; prevToken = token; prevWhite = isWhite && !tokens[i].isFieldCode(); // OOo code before comma/dot prevLen = tokens[i].getToken().length(); } return toRuleMatchArray(ruleMatches); }