#include "frontends/alert.h"
+#ifdef HAVE_LIBMYTHES
+#include MYTHES_H_LOCATION
+#else
+#ifdef HAVE_LIBAIKSAURUS
+#include AIKSAURUS_H_LOCATION
+#endif // HAVE_LIBAIKSAURUS
+#endif // !HAVE_LIBMYTHES
+
#include <algorithm>
#include <cstring>
namespace lyx {
-#ifndef HAVE_LIBMYTHES
-#ifdef HAVE_LIBAIKSAURUS
-
-
-Thesaurus::Thesaurus()
- : thes_(new Aiksaurus)
-{}
-
-
-Thesaurus::~Thesaurus()
-{
- delete thes_;
-}
-
-
-Thesaurus::Meanings Thesaurus::lookup(docstring const & t, docstring const &)
-{
- Meanings meanings;
-
- // aiksaurus is for english text only, therefore it does not work
- // with non-ascii strings.
- // The interface of the Thesaurus class uses docstring because a
- // non-english thesaurus is possible in theory.
- if (!support::isAscii(t))
- // to_ascii() would assert
- return meanings;
-
- string const text = to_ascii(t);
-
- docstring error = from_ascii(thes_->error());
- if (!error.empty()) {
- static bool sent_error = false;
- if (!sent_error) {
- frontend::Alert::error(_("Thesaurus failure"),
- bformat(_("Aiksaurus returned the following error:\n\n%1$s."),
- error));
- sent_error = true;
- }
- return meanings;
- }
- if (!thes_->find(text.c_str()))
- return meanings;
-
- // weird api, but ...
-
- int prev_meaning = -1;
- int cur_meaning;
- docstring meaning;
-
- // correct, returns "" at the end
- string ret = thes_->next(cur_meaning);
-
- while (!ret.empty()) {
- if (cur_meaning != prev_meaning) {
- meaning = from_ascii(ret);
- ret = thes_->next(cur_meaning);
- prev_meaning = cur_meaning;
- } else {
- if (ret != text)
- meanings[meaning].push_back(from_ascii(ret));
- }
-
- ret = thes_->next(cur_meaning);
- }
-
- for (Meanings::iterator it = meanings.begin();
- it != meanings.end(); ++it)
- sort(it->second.begin(), it->second.end());
-
- return meanings;
-}
-
-
-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 {
return docstring(ucs4.begin(), ucs4.end());
}
-} // namespace anon
-
+typedef std::map<docstring, MyThes *> Thesauri;
-Thesaurus::Thesaurus()
-{}
+} // namespace anon
-Thesaurus::~Thesaurus()
+struct Thesaurus::Private
{
- for (Thesauri::iterator it = thes_.begin();
- it != thes_.end(); ++it) {
- delete it->second;
+ ~Private()
+ {
+ for (Thesauri::iterator it = thes_.begin();
+ it != thes_.end(); ++it) {
+ delete it->second;
+ }
}
-}
+ ///
+ bool 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;
+ }
+
+ /// add a thesaurus to the list
+ bool addThesaurus(docstring const & lang);
+ /// the thesauri
+ Thesauri thes_;
+};
-bool Thesaurus::addThesaurus(docstring const & lang)
+bool Thesaurus::Private::addThesaurus(docstring const & lang)
{
string const thes_path = external_path(lyxrc.thesaurusdir_path);
LYXERR(Debug::FILES, "thesaurus path: " << thes_path);
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;
+ return d->thesaurusAvailable(lang);
}
Meanings meanings;
MyThes * mythes = 0;
- if (!addThesaurus(lang))
+ if (!d->addThesaurus(lang))
return meanings;
- for (Thesauri::const_iterator it = thes_.begin();
- it != thes_.end(); ++it) {
+ for (Thesauri::const_iterator it = d->thes_.begin();
+ it != d->thes_.end(); ++it) {
if (it->first == lang) {
mythes = it->second;
break;
return meanings;
}
-#else
-#ifndef HAVE_LIBAIKSAURUS
-Thesaurus::Thesaurus()
+#else // HAVE_LIBMYTHES
+#ifdef HAVE_LIBAIKSAURUS
+
+struct Thesaurus::Private
+{
+ Private(): thes_(new Aiksaurus) {}
+ Aiksaurus * thes_;
+};
+
+Thesaurus::Meanings Thesaurus::lookup(docstring const & t, docstring const &)
{
+ Meanings meanings;
+
+ // aiksaurus is for english text only, therefore it does not work
+ // with non-ascii strings.
+ // The interface of the Thesaurus class uses docstring because a
+ // non-english thesaurus is possible in theory.
+ if (!support::isAscii(t))
+ // to_ascii() would assert
+ return meanings;
+
+ string const text = to_ascii(t);
+
+ docstring error = from_ascii(d->thes_->error());
+ if (!error.empty()) {
+ static bool sent_error = false;
+ if (!sent_error) {
+ frontend::Alert::error(_("Thesaurus failure"),
+ bformat(_("Aiksaurus returned the following error:\n\n%1$s."),
+ error));
+ sent_error = true;
+ }
+ return meanings;
+ }
+ if (!d->thes_->find(text.c_str()))
+ return meanings;
+
+ // weird api, but ...
+
+ int prev_meaning = -1;
+ int cur_meaning;
+ docstring meaning;
+
+ // correct, returns "" at the end
+ string ret = d->thes_->next(cur_meaning);
+
+ while (!ret.empty()) {
+ if (cur_meaning != prev_meaning) {
+ meaning = from_ascii(ret);
+ ret = d->thes_->next(cur_meaning);
+ prev_meaning = cur_meaning;
+ } else {
+ if (ret != text)
+ meanings[meaning].push_back(from_ascii(ret));
+ }
+
+ ret = d->thes_->next(cur_meaning);
+ }
+
+ for (Meanings::iterator it = meanings.begin();
+ it != meanings.end(); ++it)
+ sort(it->second.begin(), it->second.end());
+
+ return meanings;
}
-Thesaurus::~Thesaurus()
+bool Thesaurus::thesaurusAvailable(docstring const & lang) const
{
+ // we support English only
+ return prefixIs(lang, from_ascii("en_"));
}
+#else // HAVE_LIBAIKSAURUS
+
+struct Thesaurus::Private
+{
+};
+
Thesaurus::Meanings Thesaurus::lookup(docstring const &, docstring const &)
{
return false;
}
-#endif
+#endif // HAVE_LIBAIKSAURUS
#endif // HAVE_LIBMYTHES
+Thesaurus::Thesaurus() : d(new Thesaurus::Private)
+{
+}
+
+
+Thesaurus::~Thesaurus()
+{
+ delete d;
+}
+
// Global instance
Thesaurus thesaurus;