Custom Ignore and Spelling Files for server side integration

Hi,

We integrated LT in our Server Environment to use it as a Spell Checking Backend for our JavaScript client application. This works fine, now we would like to give the User to possibility to do two things. The user should have to possibility to mark a word to be ignored in further spell checks and second to add a word to the dictionary ( for example company specific terms).

As the software is shipped to our customers, we cannot add the words manually. Searching the forum, I found a way of adding the ignore words (Adding additional ignore words). But I am not sure how this works server side, currently I have a map containing instances of all supported languages (i.e. AustrianGerman) and create a JLanguagetool instance per request. If I add the ignore words that way can I still cache the languages?

Is there a way to add words which should be used as suggestion during runtime?

EDIT: In the meantime I tried to add words to the dictionary at runtime. I was able do add them via hunspellDict.addWord. The word is recognized after the addition, but when I missspell it, it is not shown as a suggestion.

I searched the code for a solution and found that it would be possible to overwrite the getIngoreFileName and getSpellingFileName methods to hold the files outside the jar. Unfortunately the addIngoreWords method in the HunspellRule class uses the filename to load the contents from the jars resources directory.

Would it generally be possible to use external files for the spelling.txt and ingore.txt files? In my opinion this could be a good way to build up custom dictionaries.

Is there any better way to add words to the ignore and spelling lists during runtime? If coding would be required, I could try to supply a patch.

Greetings,
Martinstrong text

Yes, I think setting up the suggestions happens only once the rule gets created.

I don’t think so. If you have an idea how to clean up the situation, it would be welcome. The spell checker code is a bit complicated, unfortunately. Overwriting methods is also more of a workaround, a better solutions would work with just using the existing API.

Thank you for your response,

I can get a closer look to the code tomorrow, at the moment I am not sure what would be the preferred solution. Would it be ok to somehow enhance the API to make the paths for the spelling and ignore files configurable from outside so files outside the jar could be used? Or is it better to create the possibility to add words to both lists at runtime and refresh the internal structures properly so that the new words for the spelling dictionary are used for suggestions?

For our use case it would be ok if you have to recreate the Languages every time a word is added to one of the lists.

I think this approach is more appropriate for an API, as it gives the most flexibility.

I took a deeper look at the code, I cannot find a way to enable adding words at runtime to the spelling dictionary via API. The spelling.txt is converted and stored in morfologik.speller.Speller and from there the suggestions are calculated.

For me the only way to enable runtime spelling additions is to use an external spelling.txt file and recreate the Language/JLanguageTool instance whenenver a word gets added.

Is this an option for you?

I’m not sure I understand - do you suggest checking the file for updates? Or do you suggest an API that adds words at runtime but still requires the Language/JLanguageTool instance to be re-created?

Nachdem nur wir beide in diesen Beitrag schreiben, tue ich mir leichter es auf Deutsch zu schreiben.

Ich habe es nicht geschafft einen Weg zu finden Begriffe zur Laufzeit hinzuzufügen damit sie als Vorschläge zurückgeliefert werden können. Ich glaube um das zu ermöglichen müsste man auch in das Morfologik Projekt reingreifen. Was ich gesehen habe werden die Vorschläge in morfologik.speller.Speller.findRepl generiert. Ich hab keine Möglichkeit gefunden etwas zu den Datenstrukturen die da verwendet werden zur Laufzeit etwas hinzuzufügen.

Ich hab mir den Code jetzt noch einmal ein bisschen durchgeschaut. Ich glaube die einzige Möglichkeit zusätzliche Wörter hinzuzufügen ohne das die jars neu erstellt werden müssen, ist die Wörter irgendwie in die jeweilige SpellingRule(z.B. GermanSpellerRule) der Sprache zu bringen. Hier wären mir zwei verschiedene Varianten eingefallen.

  • Man gibt eine Methode getExternalSpellingFileName() z.B. in die Klasse SpellingCheckRule und schleift den Pfad über die Konstruktoren bis zur GermanSpellerRule z.B. durch und überschreibt da die getExternalSpellingFileName() Methode. Die Übergabe über den Konstruktur ist leider nicht wirklich schön.
  • Man übergibt gleich eine Liste von Wörtern die nachdem die Wörter aus dem internen spelling.txt geladen worden sind ebenfalls hinzugefügt werden. Wär leider das gleiche Problem mit den Kontstruktoren, Zusätzlich müsste man glaub ich noch eine temporäre Datei schreiben, da derzeit direkt ein BufferedReader übergeben wird. Ein Vorteil wäre das man nicht die existierende spelling.txt in die eigene externe Datei aufnehmen müsste und immer den letzen Stand hätte und bei neuen LT Versionen nichts manuell aktualisieren müsste.

Bei beiden Varianten müsste man sowohl die Sprache als ich die JLanguagetool Instanz neu erzeugen wenn Wörter hinzugefügt werden. Ich denke das ist aber immer noch besser als die jars neu bauen zu müssen.

Wäre eine der beiden Varianten in Ordnung? Fällt Dir eine andere Möglichkeit ein?

Tut mir leid wegen der späten Antwort, aber mir fehlt im Moment die Zeit, mich damit im Detail zu beschäftigen. Trotzdem muss man, denke ich, das JAR nicht neu bauen: die spellings.txt liegt ja direkt im Classpath und nicht in einem JAR. Man kann also die Datei ändern und das Sprachobjekt neu erzeugen, JLanguageTool neu erzeugen (letzteres geht schnell) und fertig.

Kein Problem :slight_smile: Ich komme im Moment leider selber auch nicht dazu mir das weiter anzuschauen :frowning: . Hab jetzt nur kurz geschaut, das spelling.txt liegt direkt unter src/main/ressources/ im language-de Projekt. Zur Laufzeit müsste man dann die Datei über den Classpath lesen, modifizieren und dann wieder zurückspeichern. Das lesen und ändern sollte kein Problem sein, ich hab aber keine Idee wie ich die Datei wieder speichern kann.

Was ich gesehen habe sollte es möglich sein, zur Laufzeit Classpath Einträge hinzuzufügen, vlt wäre es eine Möglichkeit in LT etwas vorzusehen das nach einer bestimmten Classpath Ressource sucht und wenn Sie existiert die Einträge aus der Datei zusätzlich zu den Einträgen aus den spelling.txt zu laden. Ist glaub ich aber fehleranfälliger und unschöner wie eine Konfiguration einer externen Datei.

Hallo,
eigentlich ist es relative simpel das ganze um eine eigene spelling.txt zu erweitern. In der Klasse GermanSpellerRule gibt es die Methode getSpeller welche am Ende die eigentliche spelling.txt in einen BufferedReader einliest. Dies wird zur Laufzeit bei jedem Erzeugen der Klasse GermanyGerman gemacht. über die Klasse GermanyGerman lässt sich dann auch ein eigenes Txt File über die initialisierung des GermanSpellerRule im Konstruktor bis hin zur Methode getSpeller schleifen. Hier kann das File dann einfach mittels eines SequenceInputStreams zusätzlich in den Buffered reader gelesen werden. Dadurch werden alle Worte die in der SpellingsTxt stehen zur Laufzeit in das LT übernommen.
Zusätzlich muss die Liste der Worte dann natürlich noch auf die Ignore Liste gesetzt werden. Aber dafür gibt es ja dann extra eine API.

Hallo,

Ich habe jetzt längere Zeit in der Firma nichts in Richtung LanguageTool gemacht, deshalb bin ich mit den neueren Versionen nicht so vertraut, gibt es vlt. mittlerweile eine Möglichkeit eigene Wörter ohne die Jars neu erzeigen zu müssen in die Vorschläge aufzunehmen?

Vielen Dank
lg
Martin

In den aktuellen Snapshots kann man dem JLanguageTool-Objekt ein UserConfig-Parameter mitgeben und der kann eine Wortliste beinhalten. Diese Wörter werden dann akzeptiert und auch als Kandidaten für Vorschläge genutzt, wenn jemand etwas Ähnliches tippt.

Das sind super Neuigkeiten, haben die Erweiterung schon für unsere nächste Version eingeplant.

Danke für den Hinweis