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;
}
}