code: /* LanguageTool, a natural language style checker
   * Copyright (C) 2012 Jaume Ortolà i Font
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * This library is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this library; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
   * USA
   */
  package org.languagetool.rules.fr;
  
  import java.io.IOException;
  import java.util.Map;
  import java.util.regex.Pattern;
  
  import org.languagetool.AnalyzedToken;
  import org.languagetool.AnalyzedTokenReadings;
  import org.languagetool.rules.RuleMatch;
  import org.languagetool.rules.patterns.RuleFilter;
  import org.languagetool.tools.StringTools;
  
  public class ConvertToSentenceCaseFilter extends RuleFilter {
  
    @Override
    public RuleMatch acceptRuleMatch(RuleMatch match, Map<String, String> arguments, int patternTokenPos,
        AnalyzedTokenReadings[] patternTokens) throws IOException {
      RuleMatch ruleMatch = match;
      boolean firstDone = false;
      StringBuilder replacement = new StringBuilder();
      for (int i = patternTokenPos; i < patternTokens.length; i++) {
        if (patternTokens[i].getStartPos() < match.getFromPos() || patternTokens[i].getEndPos() > match.getToPos()) {
          continue;
        }
        String normalizedCase = normalizedCase(patternTokens[i]);
        if (i+1<patternTokens.length && patternTokens[i+1].getToken().equals(".")) {
          if (normalizedCase.length()==1) {
            normalizedCase = normalizedCase.toUpperCase();
          } else if (normalizedCase.equals("corp")) {
            normalizedCase = "Corp";
          }
        }
        String tokenString = patternTokens[i].getToken();
        String tokenCapitalized = StringTools.uppercaseFirstChar(normalizedCase);
        if (!firstDone & !isPunctuation(tokenString) && !tokenString.isEmpty()) {
          firstDone = true;
          replacement.append(tokenCapitalized);
        } else {
          if (patternTokens[i].isWhitespaceBefore()) {
            replacement.append(" ");
          }
          replacement.append(normalizedCase);
        }
      }
      ruleMatch.setSuggestedReplacement(replacement.toString());
      return ruleMatch;
    }
  
    private boolean isPunctuation(String s) {
      return Pattern.matches("\\p{IsPunctuation}", s);
    }
  
    private String normalizedCase(AnalyzedTokenReadings atr) {
      String tokenLowercase = atr.getToken().toLowerCase();
      if (atr.hasTypographicApostrophe()) {
        tokenLowercase = tokenLowercase.replaceAll("'", "’");
      }
      //if (tokenLowercase.equals("me")) {
        // exception: the lemma is "I"
        //return tokenLowercase;
      //}
      String tokenCapitalized = StringTools.uppercaseFirstChar(tokenLowercase);
      //boolean lemmaIsAllUppercase = false;
      boolean lemmaIsCapitalized = false;
      boolean lemmaIsLowercase = false;
      for (AnalyzedToken at : atr) {
        if (at.hasNoTag() || at.getLemma() == null) {
          return tokenCapitalized;
        }
        // for multi-words lemmas, take the first word
        String lemma = at.getLemma().split(" ")[0];
        //lemmaIsAllUppercase = lemmaIsAllUppercase || StringTools.isAllUppercase(lemma);
        lemmaIsCapitalized = lemmaIsCapitalized || StringTools.isCapitalizedWord(lemma);
        lemmaIsLowercase = lemmaIsLowercase || !StringTools.isNotAllLowercase(lemma);
      }
      if (lemmaIsLowercase) {
        return tokenLowercase;
      }
      if (lemmaIsCapitalized) {
        return tokenCapitalized;
      }
      return atr.getToken();
    }
  
  }
  