Implement access to hunspell's stemming function and let the Thesaurus use that (part of bug #8060).

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@40830 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jürgen Spitzmüller 2012-03-02 10:20:09 +00:00
parent 44ed83dd86
commit a7caeda683
10 changed files with 64 additions and 15 deletions

View File

@ -26,6 +26,7 @@ public:
//@{ //@{
enum Result check(WordLangTuple const &); enum Result check(WordLangTuple const &);
void suggest(WordLangTuple const &, docstring_list &); void suggest(WordLangTuple const &, docstring_list &);
void stem(WordLangTuple const &, docstring_list &) {};
void insert(WordLangTuple const &); void insert(WordLangTuple const &);
void remove(WordLangTuple const &); void remove(WordLangTuple const &);
void accept(WordLangTuple const &); void accept(WordLangTuple const &);

View File

@ -27,6 +27,7 @@ public:
//@{ //@{
enum Result check(WordLangTuple const &); enum Result check(WordLangTuple const &);
void suggest(WordLangTuple const &, docstring_list &); void suggest(WordLangTuple const &, docstring_list &);
void stem(WordLangTuple const &, docstring_list &) {};
void insert(WordLangTuple const &); void insert(WordLangTuple const &);
void remove(WordLangTuple const &); void remove(WordLangTuple const &);
void accept(WordLangTuple const &); void accept(WordLangTuple const &);

View File

@ -33,6 +33,7 @@ public:
///@{ ///@{
enum Result check(WordLangTuple const &); enum Result check(WordLangTuple const &);
void suggest(WordLangTuple const &, docstring_list &); void suggest(WordLangTuple const &, docstring_list &);
void stem(WordLangTuple const &, docstring_list &) {};
void insert(WordLangTuple const &); void insert(WordLangTuple const &);
void remove(WordLangTuple const &); void remove(WordLangTuple const &);
void accept(WordLangTuple const &); void accept(WordLangTuple const &);

View File

@ -413,6 +413,25 @@ void HunspellChecker::suggest(WordLangTuple const & wl,
} }
void HunspellChecker::stem(WordLangTuple const & wl,
docstring_list & suggestions)
{
suggestions.clear();
Hunspell * h = d->speller(wl.lang());
if (!h)
return;
string const encoding = h->get_dic_encoding();
string const word_to_check = to_iconv_encoding(wl.word(), encoding);
char ** suggestion_list;
int const suggestion_number = h->stem(&suggestion_list, word_to_check.c_str());
if (suggestion_number <= 0)
return;
for (int i = 0; i != suggestion_number; ++i)
suggestions.push_back(from_iconv_encoding(suggestion_list[i], encoding));
h->free_list(&suggestion_list, suggestion_number);
}
bool HunspellChecker::hasDictionary(Language const * lang) const bool HunspellChecker::hasDictionary(Language const * lang) const
{ {
if (!lang) if (!lang)

View File

@ -27,6 +27,7 @@ public:
///@{ ///@{
enum Result check(WordLangTuple const &); enum Result check(WordLangTuple const &);
void suggest(WordLangTuple const &, docstring_list &); void suggest(WordLangTuple const &, docstring_list &);
void stem(WordLangTuple const &, docstring_list &);
void insert(WordLangTuple const &); void insert(WordLangTuple const &);
void remove(WordLangTuple const &); void remove(WordLangTuple const &);
void accept(WordLangTuple const &); void accept(WordLangTuple const &);

View File

@ -62,6 +62,9 @@ public:
/// Gives suggestions. /// Gives suggestions.
virtual void suggest(WordLangTuple const &, docstring_list & suggestions) = 0; virtual void suggest(WordLangTuple const &, docstring_list & suggestions) = 0;
/// Lemmatizing: return stem of word (used by Thesaurus).
virtual void stem(WordLangTuple const &, docstring_list & suggestions) = 0;
/// insert the given word into the personal dictionary /// insert the given word into the personal dictionary
virtual void insert(WordLangTuple const &) = 0; virtual void insert(WordLangTuple const &) = 0;

View File

@ -15,9 +15,13 @@
#include "LyXRC.h" #include "LyXRC.h"
#include "SpellChecker.h"
#include "WordLangTuple.h"
#include "support/FileNameList.h" #include "support/FileNameList.h"
#include "support/Package.h" #include "support/Package.h"
#include "support/debug.h" #include "support/debug.h"
#include "support/docstring_list.h"
#include "support/filetools.h" #include "support/filetools.h"
#include "support/gettext.h" #include "support/gettext.h"
#include "support/lstrings.h" #include "support/lstrings.h"
@ -195,17 +199,20 @@ bool Thesaurus::thesaurusInstalled(docstring const & lang) const
} }
Thesaurus::Meanings Thesaurus::lookup(docstring const & t, docstring const & lang) Thesaurus::Meanings Thesaurus::lookup(WordLangTuple const & wl)
{ {
Meanings meanings; Meanings meanings;
MyThes * mythes = 0; MyThes * mythes = 0;
if (!d->addThesaurus(lang)) docstring const lang_code = from_ascii(wl.lang()->code());
docstring const t = wl.word();
if (!d->addThesaurus(lang_code))
return meanings; return meanings;
for (Thesauri::const_iterator it = d->thes_.begin(); for (Thesauri::const_iterator it = d->thes_.begin();
it != d->thes_.end(); ++it) { it != d->thes_.end(); ++it) {
if (it->first == lang) { if (it->first == lang_code) {
mythes = it->second; mythes = it->second;
break; break;
} }
@ -220,8 +227,22 @@ Thesaurus::Meanings Thesaurus::lookup(docstring const & t, docstring const & lan
string const text = to_iconv_encoding(support::lowercase(t), encoding); string const text = to_iconv_encoding(support::lowercase(t), encoding);
int len = strlen(text.c_str()); int len = strlen(text.c_str());
int count = mythes->Lookup(text.c_str(), len, &pmean); int count = mythes->Lookup(text.c_str(), len, &pmean);
if (!count) {
SpellChecker * speller = theSpellChecker();
if (!speller)
return meanings;
docstring_list suggestions;
speller->stem(wl, suggestions);
for (size_t i = 0; i != suggestions.size(); ++i) {
string const wordform = to_iconv_encoding(support::lowercase(suggestions[i]), encoding);
len = strlen(wordform.c_str());
count = mythes->Lookup(wordform.c_str(), len, &pmean);
if (count)
break;
}
if (!count) if (!count)
return meanings; return meanings;
}
// don't change value of pmean or count // don't change value of pmean or count
// they are needed for the CleanUpAfterLookup routine // they are needed for the CleanUpAfterLookup routine

View File

@ -14,6 +14,7 @@
#define THESAURUS_H #define THESAURUS_H
#include "support/docstring.h" #include "support/docstring.h"
#include "WordLangTuple.h"
#include <map> #include <map>
#include <string> #include <string>
@ -38,7 +39,7 @@ public:
/** /**
* look up some text in the thesaurus * look up some text in the thesaurus
*/ */
Meanings lookup(docstring const & text, docstring const & lang); Meanings lookup(WordLangTuple const & wl);
/** check if a thesaurus for a given language \p lang is available /** check if a thesaurus for a given language \p lang is available
* (installed and loaded) * (installed and loaded)
*/ */

View File

@ -22,6 +22,7 @@
#include "FuncRequest.h" #include "FuncRequest.h"
#include "Language.h" #include "Language.h"
#include "lyxfind.h" #include "lyxfind.h"
#include "WordLangTuple.h"
#include "support/debug.h" #include "support/debug.h"
#include "support/gettext.h" #include "support/gettext.h"
@ -173,11 +174,11 @@ void GuiThesaurus::updateLists()
QString const lang = languageCO->itemData( QString const lang = languageCO->itemData(
languageCO->currentIndex()).toString(); languageCO->currentIndex()).toString();
docstring const lang_code = Language * language = const_cast<Language*>(lyx::languages.getLanguage(fromqstr(lang)));
from_ascii(lyx::languages.getLanguage(fromqstr(lang))->code()); docstring const lang_code = from_ascii(language->code());
Thesaurus::Meanings meanings = Thesaurus::Meanings meanings =
getMeanings(qstring_to_ucs4(entryCO->currentText()), lang_code); getMeanings(WordLangTuple(qstring_to_ucs4(entryCO->currentText()), language));
for (Thesaurus::Meanings::const_iterator cit = meanings.begin(); for (Thesaurus::Meanings::const_iterator cit = meanings.begin();
cit != meanings.end(); ++cit) { cit != meanings.end(); ++cit) {
@ -271,11 +272,10 @@ void GuiThesaurus::replace(docstring const & newstr)
} }
Thesaurus::Meanings const & GuiThesaurus::getMeanings(docstring const & str, Thesaurus::Meanings const & GuiThesaurus::getMeanings(WordLangTuple const & wl)
docstring const & lang)
{ {
if (str != laststr_) if (wl.word() != laststr_)
meanings_ = thesaurus.lookup(str, lang); meanings_ = thesaurus.lookup(wl);
return meanings_; return meanings_;
} }

View File

@ -16,6 +16,8 @@
#include "Thesaurus.h" #include "Thesaurus.h"
#include "ui_ThesaurusUi.h" #include "ui_ThesaurusUi.h"
#include "WordLangTuple.h"
class QTreeWidgetItem; class QTreeWidgetItem;
namespace lyx { namespace lyx {
@ -56,8 +58,7 @@ private:
void replace(docstring const & newstr); void replace(docstring const & newstr);
/// get meanings /// get meanings
Thesaurus::Meanings const & getMeanings(docstring const & str, Thesaurus::Meanings const & getMeanings(WordLangTuple const & wl);
docstring const & lang);
private: private:
/// last string looked up /// last string looked up