All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.languagetool.rules.uk.SimpleReplaceRule Maven / Gradle / Ivy

The newest version!
/* LanguageTool, a natural language style checker 
 * Copyright (C) 2005 Daniel Naber (http://www.danielnaber.de)
 * 
 * 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.uk;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.languagetool.AnalyzedSentence;
import org.languagetool.AnalyzedToken;
import org.languagetool.AnalyzedTokenReadings;
import org.languagetool.JLanguageTool;
import org.languagetool.Language;
import org.languagetool.rules.AbstractSimpleReplaceRule;
import org.languagetool.rules.RuleMatch;
import org.languagetool.tagging.uk.IPOSTag;
import org.languagetool.tagging.uk.PosTagHelper;
import org.languagetool.tools.Tools;

/**
 * A rule that matches words which should not be used and suggests correct ones
 * instead.
 * 
 * Ukrainian implementations. Loads the relevant words from
 * rules/uk/replace.txt.
 * 
 * @author Andriy Rysin
 */
public class SimpleReplaceRule extends AbstractSimpleReplaceRule {

  private static final Map> wrongWords = loadFromPath("/uk/replace.txt");
//  private static final Set FORCE_REPLACE_LIST = new HashSet<>(Arrays.asList("главком"));
  private final MorfologikUkrainianSpellerRule morfologikSpellerRule;

  @Override
  public Map> getWrongWords() {
    return wrongWords;
  }

  public SimpleReplaceRule(ResourceBundle messages, MorfologikUkrainianSpellerRule morfologikSpellerRule,
                           final Language language) throws IOException {
    super(messages, language);
    setIgnoreTaggedWords();
    this.morfologikSpellerRule = morfologikSpellerRule;
  }

  @Override
  public final String getId() {
    return "UK_SIMPLE_REPLACE";
  }

  @Override
  public String getDescription() {
    return "Пошук помилкових слів";
  }

  @Override
  public String getShort() {
    return "Помилка?";
  }

  @Override
  public String getMessage(String tokenStr, List replacements) {
    return "«" + tokenStr + "» - помилкове слово, виправлення: "
        + String.join(", ", replacements) + ".";
  }

  @Override
  protected boolean isTagged(AnalyzedTokenReadings tokenReadings) {
//    if( FORCE_REPLACE_LIST.contains(tokenReadings.getToken()) )
//      return false;
    
    for (AnalyzedToken token: tokenReadings.getReadings()) {
      // optimize
      if ( token.hasNoTag() )
        return false;

      String posTag = token.getPOSTag();
      if (isGoodPosTag(posTag)) {
        return true;
      }
    }

    return false;
  }

  @Override
  protected List findMatches(AnalyzedTokenReadings tokenReadings, AnalyzedSentence sentence) throws IOException {
    List matches = super.findMatches(tokenReadings, sentence);
    if( matches.isEmpty() ) {
      if( PosTagHelper.hasPosTag(tokenReadings, Pattern.compile(".*?adjp:actv.*?:bad.*")) ) {
        String msg = "Активні дієприкметники не властиві українській мові.";
        String url;

        if( tokenReadings.getAnalyzedToken(0).getLemma().endsWith("ший") ) {
          msg += " Їх можна замінити на що + дієслово (випавший сніг - сніг, що випав), або на форму з суфіксом -л- (промокший - промоклий)";
          url = "http://padaread.com/?book=53784&pg=94";
        }
        else { // -ючий, -ющий тощо
          msg += " Їх можна замінити питомими словами в різний спосіб: що + дієслово (роблячий  - що робить), дієслівний корінь+ суфікси -льн-, -лив- тощо (збираючий - збиральний, обтяжуючий - обтяжливий),"
          + " заміна іменником (завідуючий - завідувач), заміна прикметником із відповідним значенням (діюча модель - робоча модель), зміна конструкції (з наступаючим Новим роком - з настанням Нового року) тощо.";
          url = "http://nbuv.gov.ua/j-pdf/Nchnpu_8_2013_5_2.pdf";
        }

        RuleMatch match = new RuleMatch(this, sentence, tokenReadings.getStartPos(), tokenReadings.getStartPos()
            + tokenReadings.getToken().length(), msg, getShort());

        match.setUrl(Tools.getUrl(url));

        matches.add(match);
      }
      else {
        List derivatSuggestions = findInDeriv(tokenReadings.getCleanToken().toLowerCase());

        if( derivatSuggestions.size() > 0 ) {
          String msg = "Неправильне слово.";

          RuleMatch match = new RuleMatch(this, sentence, tokenReadings.getStartPos(), tokenReadings.getStartPos()
              + tokenReadings.getToken().length(), msg, getShort());

          match.setSuggestedReplacements(derivatSuggestions);
          matches.add(match);
          return matches;
        }

        if( PosTagHelper.hasPosTagPart(tokenReadings, ":bad") 
            && ! PosTagHelper.hasPosTagStart(tokenReadings, "number") ) {
          String msg = "Неправильно написане слово.";

          RuleMatch match = new RuleMatch(this, sentence, tokenReadings.getStartPos(), tokenReadings.getStartPos()
              + tokenReadings.getToken().length(), msg, getShort());

          List suggestions = morfologikSpellerRule.getSpeller1().getSuggestionsFromDefaultDicts(tokenReadings.getToken());
          suggestions.removeIf(s -> s.contains(" "));
          match.setSuggestedReplacements(suggestions);
          //            RuleMatch[] spellerMatches = morfologikSpellerRule.match(new AnalyzedSentence(new AnalyzedTokenReadings[] {tokenReadings}));
          //            if( spellerMatches.length > 0 ) {
          //              match.setSuggestedReplacements(spellerMatches[0].getSuggestedReplacements());
          //            }
          matches.add(match);
        }
      }
    }
    //    else {
//      if( PosTagHelper.hasPosTag(tokenReadings, Pattern.compile("(?!verb).*:subst")) ) {
//        for(int i=0; i findInDeriv(String w) {
    
    Set derivats = CaseGovernmentHelper.DERIVATIVES_MAP.get(w);
    if ( derivats == null ) 
      return new ArrayList<>();

    String ending = StringUtils.right(w, 3);

    List suggestions = 
        derivats.stream()
        .map(d -> getWrongWords().get(d))
        .flatMap(c -> c.stream())
        .map(t ->
          CaseGovernmentHelper.DERIVATIVES_MAP.entrySet().stream()
          .filter(e -> e.getValue().contains(t) && e.getKey().endsWith(ending)) // filter -ючи vs -вши
          .map(e -> e.getKey())
          .findAny()
          .orElse(t)
        )
        .collect(Collectors.toList());

    return suggestions;
  }

  private boolean isGoodPosTag(String posTag) {
    return posTag != null
        && !JLanguageTool.PARAGRAPH_END_TAGNAME.equals(posTag)
        && !JLanguageTool.SENTENCE_END_TAGNAME.equals(posTag)
        && !posTag.contains(IPOSTag.bad.getText())
        && !posTag.contains("subst")
        && !posTag.startsWith("<");
  }

  @Override
  public boolean isCaseSensitive() {
    return false;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy