Skip to content

Commit

Permalink
Adding Hunspell loading
Browse files Browse the repository at this point in the history
  • Loading branch information
marigostra committed Jun 20, 2022
1 parent 4f083d0 commit 4ede84d
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 89 deletions.
13 changes: 10 additions & 3 deletions src/main/java/org/luwrain/controls/EditSpellChecking.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,20 @@ public class EditSpellChecking implements EditArea.ChangeListener
LOG_COMPONENT = "spelling";

private final Luwrain luwrain;
private final SpellChecker checker = new SpellCheckerFactory().newChecker("ru");
public EditSpellChecking(Luwrain luwrain )
private final SpellChecker checker;
public EditSpellChecking(Luwrain luwrain , String lang)
{
NullCheck.notNull(luwrain, "luwrain ");
this .luwrain = luwrain;
NullCheck.notEmpty(lang, "lang");
this .luwrain = luwrain;
this.checker = new SpellCheckerFactory().newChecker(luwrain, lang);
}

public EditSpellChecking(Luwrain luwrain )
{
this(luwrain, "ru");
}

@Override public void onEditChange(EditArea editArea, MarkedLines lines, HotPoint hotPoint)
{
final SortedMap<Integer, String> text = new TreeMap<>();
Expand Down
41 changes: 21 additions & 20 deletions src/main/java/org/luwrain/nlp/Hunspell.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// * Copyright (C) 2021 Pavel Bakhvalov
/* Copyright (C) 2021 Pavel Bakhvalov*/

package org.luwrain.io.nlp;
package org.luwrain.nlp;

import dumonts.hunspell.bindings.HunspellLibrary;
import org.bridj.Pointer;
Expand All @@ -14,27 +14,28 @@

public final class Hunspell
{
private final Pointer<HunspellLibrary.Hunhandle> handle;
private final Charset charset;
private final Pointer<HunspellLibrary.Hunhandle> handle;
private final Charset charset;

public Hunspell(Path dictionary, Path affix)
{
try {
Pointer<Byte> aff = Pointer.pointerToCString(affix.toString());
Pointer<Byte> dic = Pointer.pointerToCString(dictionary.toString());
handle = HunspellLibrary.Hunspell_create(aff, dic);
charset = Charset.forName(HunspellLibrary.Hunspell_get_dic_encoding(handle).getCString());
if (this.handle == null) {
throw new RuntimeException("Unable to create Hunspell instance");
}
} catch (UnsatisfiedLinkError e) {
throw new RuntimeException("Could not create hunspell instance. Please note that LanguageTool supports only 64-bit platforms " +
"(Linux, Windows, Mac) and that it requires a 64-bit JVM (Java).", e);
public Hunspell(String dictionary, String affix)
{
try {
Pointer<Byte> aff = Pointer.pointerToCString(affix);
Pointer<Byte> dic = Pointer.pointerToCString(dictionary);
handle = HunspellLibrary.Hunspell_create(aff, dic);
charset = Charset.forName(HunspellLibrary.Hunspell_get_dic_encoding(handle).getCString());
if (this.handle == null) {
throw new RuntimeException("Unable to create Hunspell instance");
}
} catch (UnsatisfiedLinkError e) {
throw new RuntimeException("Could not create hunspell instance. Please note that LanguageTool supports only 64-bit platforms " +
"(Linux, Windows, Mac) and that it requires a 64-bit JVM (Java).", e);
}
}
}

public boolean spell(String word) {
if (handle == null) {
public boolean spell(String word)
{
if (handle == null) {
throw new RuntimeException("Attempt to use hunspell instance after closing");
}
@SuppressWarnings("unchecked")
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/luwrain/nlp/SpellChecker.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@
public interface SpellChecker
{
List<SpellProblem> check(String text);
List<String> suggestCorrections(String word);
}
5 changes: 3 additions & 2 deletions src/main/java/org/luwrain/nlp/SpellCheckerFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@

package org.luwrain.nlp;

import org.luwrain.core.*;
import org.luwrain.nlp.ru.spell.RuSpellChecker;

public final class SpellCheckerFactory
{
static private RuSpellChecker ru = null;

public SpellChecker newChecker(String lang)
public SpellChecker newChecker(Luwrain luwrain, String lang)
{
switch(lang.toUpperCase())
{
case "RU": {
if (ru == null)
ru = new RuSpellChecker();
ru = new RuSpellChecker(luwrain);
return ru;
}
default:
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/org/luwrain/nlp/SpellText.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ public List<List<LineMarks.Mark>> buildMarks()
return res;
}

public List<Fragment> getFragments()
{
return fragments;
}

public List<SpellProblem> getProblems()
{
return problems;
}

static public final class Fragment
{
final int posFrom, posTo;
Expand Down
22 changes: 21 additions & 1 deletion src/main/java/org/luwrain/nlp/ru/spell/RuSpellChecker.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,23 @@
public final class RuSpellChecker implements SpellChecker
{
final JLanguageTool langTool;
final Hunspell hunspell;

public RuSpellChecker()
public RuSpellChecker(Luwrain luwrain)
{
this.langTool = new JLanguageTool(new Russian());
final File
hunspellDataDir = new File(luwrain.getFileProperty(Luwrain.PROP_DIR_DATA), "hunspell"),
dictFile = new File(hunspellDataDir, "ru.dict"),
affFile = new File(hunspellDataDir, "ru.aff");
this.hunspell = new Hunspell(dictFile.getAbsolutePath(), affFile.getAbsolutePath());
}

//Just for unit tests
RuSpellChecker()
{
this.langTool = new JLanguageTool(new Russian());
this.hunspell = null;
}

@Override public List<SpellProblem> check(String text)
Expand All @@ -50,4 +63,11 @@ public RuSpellChecker()
throw new RuntimeException(e);
}
}

@Override public List<String> suggestCorrections(String word)
{
return null;
}


}
58 changes: 0 additions & 58 deletions src/test/java/org/luwrain/io/nlp/SpellTextTest.java

This file was deleted.

34 changes: 29 additions & 5 deletions src/test/java/org/luwrain/io/nlp/ru/spell/RuSpellCheckerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,47 @@
//https://languagetool.org/development/api/org/languagetool/rules/spelling/SpellingCheckRule.html


import java.io.*;
import java.net.*;
import java.util.*;

import org.junit.*;

import org.luwrain.core.*;
import org.luwrain.nlp.*;

public class RuSpellCheckerTest extends Assert
{
private RuSpellChecker c = null;
private RuSpellChecker checker = null;

@Test public void main()
@Test public void shortSent()
{
final String text = "Это было превосходная день!";
final SpellText t = new SpellText(new String[]{text}, checker);
assertNotNull(t.getFragments());
assertEquals(1, t.getFragments().size());
assertNotNull(t.getProblems());
assertEquals(1, t.getProblems().size());
final List<List<LineMarks.Mark>> res = t.buildMarks();
assertNotNull(res);
assertEquals(1, res.size());
List<LineMarks.Mark> marks = res.get(0);
assertNotNull(marks);
assertEquals(1, marks.size());
final LineMarks.Mark mark = marks.get(0);
assertNotNull(mark);
final SpellProblem problem = (SpellProblem)mark.getMarkObject();
assertNotNull(problem);
assertEquals("Прилагательное не согласуется с существительным по роду.", problem.getComment());
assertEquals("", problem.getShortComment());
final int
start = problem.getStart(),
end = problem.getEnd();
assertEquals("превосходная день", text.substring(start, end));
}



@Before public void create()
{
c = new RuSpellChecker();
checker = new RuSpellChecker();
}
}

0 comments on commit 4ede84d

Please sign in to comment.