3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
7 * \author Jürgen Spitzmüller
9 * Full author contact details are available in file CREDITS.
14 #include "Thesaurus.h"
18 #include "support/FileNameList.h"
19 #include "support/debug.h"
20 #include "support/filetools.h"
21 #include "support/gettext.h"
22 #include "support/lstrings.h"
23 #include "support/os.h"
24 #include "support/unicode.h"
26 #include "support/mythes/mythes.hxx"
28 #include "frontends/alert.h"
34 using namespace lyx::support
;
35 using namespace lyx::support::os
;
41 string
const to_iconv_encoding(docstring
const & s
, string
const & encoding
)
43 std::vector
<char> const encoded
=
44 ucs4_to_eightbit(s
.data(), s
.length(), encoding
);
45 return string(encoded
.begin(), encoded
.end());
49 docstring
const from_iconv_encoding(string
const & s
, string
const & encoding
)
51 std::vector
<char_type
> const ucs4
=
52 eightbit_to_ucs4(s
.data(), s
.length(), encoding
);
53 return docstring(ucs4
.begin(), ucs4
.end());
56 typedef std::map
<docstring
, MyThes
*> Thesauri
;
61 struct Thesaurus::Private
65 for (Thesauri::iterator it
= thes_
.begin();
66 it
!= thes_
.end(); ++it
) {
71 bool thesaurusAvailable(docstring
const & lang
) const
73 for (Thesauri::const_iterator it
= thes_
.begin();
74 it
!= thes_
.end(); ++it
) {
75 if (it
->first
== lang
)
82 /// add a thesaurus to the list
83 bool addThesaurus(docstring
const & lang
);
89 bool Thesaurus::Private::addThesaurus(docstring
const & lang
)
91 string
const thes_path
= external_path(lyxrc
.thesaurusdir_path
);
92 LYXERR(Debug::FILES
, "thesaurus path: " << thes_path
);
93 if (thes_path
.empty())
96 if (thesaurusAvailable(lang
))
99 FileNameList
const idx_files
= FileName(thes_path
).dirList("idx");
100 FileNameList
const data_files
= FileName(thes_path
).dirList("dat");
104 for (FileNameList::const_iterator it
= idx_files
.begin();
105 it
!= idx_files
.end(); ++it
) {
106 LYXERR(Debug::FILES
, "found thesaurus idx file: " << it
->onlyFileName());
107 if (contains(it
->onlyFileName(), to_ascii(lang
))) {
108 idx
= it
->absFilename();
109 LYXERR(Debug::FILES
, "selected thesaurus idx file: " << idx
);
114 for (support::FileNameList::const_iterator it
= data_files
.begin();
115 it
!= data_files
.end(); ++it
) {
116 LYXERR(Debug::FILES
, "found thesaurus data file: " << it
->onlyFileName());
117 if (contains(it
->onlyFileName(), to_ascii(lang
))) {
118 data
= it
->absFilename();
119 LYXERR(Debug::FILES
, "selected thesaurus data file: " << data
);
124 if (idx
.empty() || data
.empty())
127 char const * af
= idx
.c_str();
128 char const * df
= data
.c_str();
129 thes_
[lang
] = new MyThes(af
, df
);
134 bool Thesaurus::thesaurusAvailable(docstring
const & lang
) const
136 return d
->thesaurusAvailable(lang
);
140 Thesaurus::Meanings
Thesaurus::lookup(docstring
const & t
, docstring
const & lang
)
145 if (!d
->addThesaurus(lang
))
148 for (Thesauri::const_iterator it
= d
->thes_
.begin();
149 it
!= d
->thes_
.end(); ++it
) {
150 if (it
->first
== lang
) {
159 string
const encoding
= mythes
->get_th_encoding();
162 string
const text
= to_iconv_encoding(support::lowercase(t
), encoding
);
163 int len
= strlen(text
.c_str());
164 int count
= mythes
->Lookup(text
.c_str(), len
, &pmean
);
168 // don't change value of pmean or count
169 // they are needed for the CleanUpAfterLookup routine
173 for (int i
= 0; i
< count
; i
++) {
174 meaning
= from_iconv_encoding(string(pm
->defn
), encoding
);
176 if (support::prefixIs(meaning
, '-'))
177 meaning
= support::ltrim(meaning
, "- ");
178 for (int j
= 0; j
< pm
->count
; j
++) {
179 ret
= from_iconv_encoding(string(pm
->psyns
[j
]), encoding
);
181 meanings
[meaning
].push_back(ret
);
184 // now clean up all allocated memory
185 mythes
->CleanUpAfterLookup(&pmean
, count
);
187 for (Meanings::iterator it
= meanings
.begin();
188 it
!= meanings
.end(); ++it
)
189 sort(it
->second
.begin(), it
->second
.end());
195 Thesaurus::Thesaurus() : d(new Thesaurus::Private
)
200 Thesaurus::~Thesaurus()