X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FThesaurus.cpp;h=357ddbbe0bf42c919b08996ca031280f1f91c5ee;hb=bd8788f377c365519f8cf77eb88002e90c1b6a5e;hp=6e5d80a07d351068aaf4690c760ae81ea10b90d3;hpb=9383f4c3c6f9cfab2d658701ba66e2b54cd68bea;p=lyx.git diff --git a/src/Thesaurus.cpp b/src/Thesaurus.cpp index 6e5d80a07d..357ddbbe0b 100644 --- a/src/Thesaurus.cpp +++ b/src/Thesaurus.cpp @@ -4,6 +4,7 @@ * Licence details can be found in the file COPYING. * * \author John Levon + * \author Jürgen Spitzmüller * * Full author contact details are available in file CREDITS. */ @@ -12,34 +13,43 @@ #include "Thesaurus.h" +#include "support/debug.h" #include "support/gettext.h" +#include "LyXRC.h" +#include "support/FileNameList.h" +#include "support/filetools.h" #include "support/lstrings.h" +#include "support/os.h" +#include "support/unicode.h" #include "frontends/alert.h" #include +#include using namespace std; +using namespace lyx::support; +using namespace lyx::support::os; namespace lyx { +#ifndef HAVE_LIBMYTHES #ifdef HAVE_LIBAIKSAURUS -using support::bformat; Thesaurus::Thesaurus() - : aik_(new Aiksaurus) + : thes_(new Aiksaurus) {} Thesaurus::~Thesaurus() { - delete aik_; + delete thes_; } -Thesaurus::Meanings Thesaurus::lookup(docstring const & t) +Thesaurus::Meanings Thesaurus::lookup(docstring const & t, docstring const &) { Meanings meanings; @@ -53,7 +63,7 @@ Thesaurus::Meanings Thesaurus::lookup(docstring const & t) string const text = to_ascii(t); - docstring error = from_ascii(aik_->error()); + docstring error = from_ascii(thes_->error()); if (!error.empty()) { static bool sent_error = false; if (!sent_error) { @@ -64,7 +74,7 @@ Thesaurus::Meanings Thesaurus::lookup(docstring const & t) } return meanings; } - if (!aik_->find(text.c_str())) + if (!thes_->find(text.c_str())) return meanings; // weird api, but ... @@ -74,19 +84,19 @@ Thesaurus::Meanings Thesaurus::lookup(docstring const & t) docstring meaning; // correct, returns "" at the end - string ret = aik_->next(cur_meaning); + string ret = thes_->next(cur_meaning); while (!ret.empty()) { if (cur_meaning != prev_meaning) { meaning = from_ascii(ret); - ret = aik_->next(cur_meaning); + ret = thes_->next(cur_meaning); prev_meaning = cur_meaning; } else { if (ret != text) meanings[meaning].push_back(from_ascii(ret)); } - ret = aik_->next(cur_meaning); + ret = thes_->next(cur_meaning); } for (Meanings::iterator it = meanings.begin(); @@ -96,8 +106,166 @@ Thesaurus::Meanings Thesaurus::lookup(docstring const & t) return meanings; } -#else +bool Thesaurus::thesaurusAvailable(docstring const & lang) const +{ + // we support English only + return prefixIs(lang, from_ascii("en_")); +} + +#endif // HAVE_LIBAIKSAURUS +#endif // !HAVE_LIBMYTHES + + +#ifdef HAVE_LIBMYTHES + +namespace { + +string const to_iconv_encoding(docstring const & s, string const & encoding) +{ + std::vector const encoded = + ucs4_to_eightbit(s.data(), s.length(), encoding); + return string(encoded.begin(), encoded.end()); +} + + +docstring const from_iconv_encoding(string const & s, string const & encoding) +{ + std::vector const ucs4 = + eightbit_to_ucs4(s.data(), s.length(), encoding); + return docstring(ucs4.begin(), ucs4.end()); +} + +} // namespace anon + + +Thesaurus::Thesaurus() +{} + + +Thesaurus::~Thesaurus() +{ + for (Thesauri::iterator it = thes_.begin(); + it != thes_.end(); ++it) { + delete it->second; + } +} + + +bool Thesaurus::addThesaurus(docstring const & lang) +{ + string const thes_path = external_path(lyxrc.thesaurusdir_path); + LYXERR(Debug::FILES, "thesaurus path: " << thes_path); + if (thes_path.empty()) + return false; + + if (thesaurusAvailable(lang)) + return true; + + FileNameList const idx_files = FileName(thes_path).dirList("idx"); + FileNameList const data_files = FileName(thes_path).dirList("dat"); + string idx; + string data; + + for (FileNameList::const_iterator it = idx_files.begin(); + it != idx_files.end(); ++it) { + LYXERR(Debug::FILES, "found thesaurus idx file: " << it->onlyFileName()); + if (contains(it->onlyFileName(), to_ascii(lang))) { + idx = it->absFilename(); + LYXERR(Debug::FILES, "selected thesaurus idx file: " << idx); + break; + } + } + + for (support::FileNameList::const_iterator it = data_files.begin(); + it != data_files.end(); ++it) { + LYXERR(Debug::FILES, "found thesaurus data file: " << it->onlyFileName()); + if (contains(it->onlyFileName(), to_ascii(lang))) { + data = it->absFilename(); + LYXERR(Debug::FILES, "selected thesaurus data file: " << data); + break; + } + } + + if (idx.empty() || data.empty()) + return false; + + char const * af = idx.c_str(); + char const * df = data.c_str(); + thes_[lang] = new MyThes(af, df); + return true; +} + + +bool Thesaurus::thesaurusAvailable(docstring const & lang) const +{ + for (Thesauri::const_iterator it = thes_.begin(); + it != thes_.end(); ++it) { + if (it->first == lang) + if (it->second) + return true; + } + + return false; +} + + +Thesaurus::Meanings Thesaurus::lookup(docstring const & t, docstring const & lang) +{ + Meanings meanings; + MyThes * mythes = 0; + + if (!addThesaurus(lang)) + return meanings; + + for (Thesauri::const_iterator it = thes_.begin(); + it != thes_.end(); ++it) { + if (it->first == lang) { + mythes = it->second; + break; + } + } + + if (!mythes) + return meanings; + + string const encoding = mythes->get_th_encoding(); + + mentry * pmean; + string const text = to_iconv_encoding(support::lowercase(t), encoding); + int len = strlen(text.c_str()); + int count = mythes->Lookup(text.c_str(), len, &pmean); + if (!count) + return meanings; + + // don't change value of pmean or count + // they are needed for the CleanUpAfterLookup routine + mentry * pm = pmean; + docstring meaning; + docstring ret; + for (int i = 0; i < count; i++) { + meaning = from_iconv_encoding(string(pm->defn), encoding); + // remove silly item + if (support::prefixIs(meaning, '-')) + meaning = support::ltrim(meaning, "- "); + for (int j = 0; j < pm->count; j++) { + ret = from_iconv_encoding(string(pm->psyns[j]), encoding); + } + meanings[meaning].push_back(ret); + pm++; + } + // now clean up all allocated memory + mythes->CleanUpAfterLookup(&pmean, count); + + for (Meanings::iterator it = meanings.begin(); + it != meanings.end(); ++it) + sort(it->second.begin(), it->second.end()); + + return meanings; +} + +#else +#ifndef HAVE_LIBAIKSAURUS Thesaurus::Thesaurus() { } @@ -108,12 +276,19 @@ Thesaurus::~Thesaurus() } -Thesaurus::Meanings Thesaurus::lookup(docstring const &) +Thesaurus::Meanings Thesaurus::lookup(docstring const &, docstring const &) { return Meanings(); } -#endif // HAVE_LIBAIKSAURUS + +bool Thesaurus::thesaurusAvailable(docstring const & lang) const +{ + return false; +} + +#endif +#endif // HAVE_LIBMYTHES // Global instance Thesaurus thesaurus;