]> git.lyx.org Git - lyx.git/blob - src/ASpell.cpp
rename assert.h to lassert.h
[lyx.git] / src / ASpell.cpp
1 /**
2  * \file ASpell.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Kevin Atkinson
7  * \author John Levon
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "support/debug.h"
15
16 #include <aspell.h>
17
18 #include "ASpell_local.h"
19 #include "LyXRC.h"
20 #include "WordLangTuple.h"
21
22 #include "support/lassert.h"
23
24 using namespace std;
25
26 namespace lyx {
27
28 ASpell::ASpell(BufferParams const &, string const & lang)
29         : els(0), spell_error_object(0)
30 {
31         addSpeller(lang);
32 }
33
34
35 ASpell::~ASpell()
36 {
37         if (spell_error_object) {
38                 delete_aspell_can_have_error(spell_error_object);
39                 spell_error_object = 0;
40         }
41
42         if (els)
43                 delete_aspell_string_enumeration(els);
44
45         Spellers::iterator it = spellers_.begin();
46         Spellers::iterator end = spellers_.end();
47
48         for (; it != end; ++it) {
49                 aspell_speller_save_all_word_lists(it->second.speller);
50                 delete_aspell_speller(it->second.speller);
51                 delete_aspell_config(it->second.config);
52         }
53 }
54
55
56 void ASpell::addSpeller(string const & lang)
57 {
58         AspellConfig * config = new_aspell_config();
59         // FIXME The aspell documentation says to use "lang"
60         aspell_config_replace(config, "language-tag", lang.c_str());
61         // Set the encoding to utf-8.
62         // aspell does also understand "ucs-4", so we would not need a
63         // conversion in theory, but if this is used it expects all
64         // char const * arguments to be a cast from  uint const *, and it
65         // seems that this uint is not compatible with our char_type on some
66         // platforms (cygwin, OS X). Therefore we use utf-8, that does
67         // always work.
68         aspell_config_replace(config, "encoding", "utf-8");
69         if (lyxrc.isp_accept_compound)
70                 // Consider run-together words as legal compounds
71                 aspell_config_replace(config, "run-together", "true");
72         else
73                 // Report run-together words as errors
74                 aspell_config_replace(config, "run-together", "false");
75         AspellCanHaveError * err = new_aspell_speller(config);
76         if (spell_error_object)
77                 delete_aspell_can_have_error(spell_error_object);
78         spell_error_object = 0;
79
80         if (aspell_error_number(err) == 0) {
81                 Speller m;
82                 m.speller = to_aspell_speller(err);
83                 m.config = config;
84                 spellers_[lang] = m;
85         } else {
86                 spell_error_object = err;
87         }
88 }
89
90
91 ASpell::Result ASpell::check(WordLangTuple const & word)
92 {
93         Result res = UNKNOWN_WORD;
94
95         Spellers::iterator it = spellers_.find(word.lang_code());
96         if (it == spellers_.end()) {
97                 addSpeller(word.lang_code());
98                 it = spellers_.find(word.lang_code());
99                 // FIXME
100                 if (it == spellers_.end())
101                         return res;
102         }
103
104         AspellSpeller * m = it->second.speller;
105
106         int const word_ok = aspell_speller_check(m, to_utf8(word.word()).c_str(), -1);
107         LASSERT(word_ok != -1, /**/);
108
109         if (word_ok)
110                 return OK;
111
112         AspellWordList const * sugs =
113                 aspell_speller_suggest(m, to_utf8(word.word()).c_str(), -1);
114         LASSERT(sugs != 0, /**/);
115         els = aspell_word_list_elements(sugs);
116         if (aspell_word_list_empty(sugs))
117                 res = UNKNOWN_WORD;
118         else
119                 res = SUGGESTED_WORDS;
120
121         return res;
122 }
123
124
125 void ASpell::insert(WordLangTuple const & word)
126 {
127         Spellers::iterator it = spellers_.find(word.lang_code());
128         if (it != spellers_.end())
129                 aspell_speller_add_to_personal(it->second.speller, to_utf8(word.word()).c_str(), -1);
130 }
131
132
133 void ASpell::accept(WordLangTuple const & word)
134 {
135         Spellers::iterator it = spellers_.find(word.lang_code());
136         if (it != spellers_.end())
137                 aspell_speller_add_to_session(it->second.speller, to_utf8(word.word()).c_str(), -1);
138 }
139
140
141 docstring const ASpell::nextMiss()
142 {
143         char const * str = 0;
144
145         if (els)
146                 str = aspell_string_enumeration_next(els);
147
148         return (str ? from_utf8(str) : docstring());
149 }
150
151
152 docstring const ASpell::error()
153 {
154         char const * err = 0;
155
156         if (spell_error_object && aspell_error_number(spell_error_object) != 0)
157                 err = aspell_error_message(spell_error_object);
158
159         // FIXME UNICODE: err is not in UTF8, but probably the locale encoding
160         return (err ? from_utf8(err) : docstring());
161 }
162
163
164 } // namespace lyx