Stroika Library 3.0d25
 
Loading...
Searching...
No Matches
SpellCheckEngine_Basic.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4#ifndef _Stroika_Frameworks_Led_SpellCheckEngine_Basic_h_
5#define _Stroika_Frameworks_Led_SpellCheckEngine_Basic_h_ 1
6
7/*
8@MODULE: SpellCheckEngine_Basic
9@DESCRIPTION: <p></p>
10
11 */
12
13#include "Stroika/Frameworks/StroikaPreComp.h"
14
15#include <memory>
16#include <set>
17
18#include "Stroika/Frameworks/Led/SpellCheckEngine.h"
19#include "Stroika/Frameworks/Led/Support.h"
20#include "Stroika/Frameworks/Led/TextBreaks.h"
21
22namespace Stroika::Frameworks::Led {
23
24/*
25 @CONFIGVAR: qStroika_Frameworks_Led_IncludeBakedInDictionaries
26 @DESCRIPTION: <p>Turning this on (its on by default) includes into the binary - pre-built dictionaries (currently just US-English).
27 Including this allows direct access to the US-English dictionary. However - its large - adding about 2-3MB (depending
28 on if you use UNICODE or single-byte - among other things) to the size of your binary.</p>
29 */
30#ifndef qStroika_Frameworks_Led_IncludeBakedInDictionaries
31// DISABLE BY DEFAULT UNTIL WE PUT IN PLACE BETTER MECHANISM FOR 'RESOURCES' - as we do in HealthFrame for stuff like XSDs...
32#define qStroika_Frameworks_Led_IncludeBakedInDictionaries 0
33#endif
34
35 /*
36 @CLASS: SpellCheckEngine_Basic
37 @DESCRIPTION: <p>
38 </p>
39 */
40 class SpellCheckEngine_Basic : public SpellCheckEngine {
41 private:
42 using inherited = SpellCheckEngine;
43
44 public:
45 class Dictionary;
46 class EditableDictionary;
47 class CompiledDictionary;
48
49 public:
50 SpellCheckEngine_Basic (const Dictionary* mainDictionary = NULL);
51 ~SpellCheckEngine_Basic ();
52
53 public:
54 virtual bool ScanForUndefinedWord (const Led_tChar* startBuf, const Led_tChar* endBuf, const Led_tChar** cursor,
55 const Led_tChar** wordStartResult, const Led_tChar** wordEndResult) override;
56
57 protected:
58 virtual bool LookupWord_ (const Led_tString& checkWord, Led_tString* matchedWordResult) override;
59
60 private:
61 nonvirtual bool LookupWordHelper_ (const Led_tString& checkWord, Led_tString* matchedWordResult) const;
62
63 protected:
64 virtual bool OtherStringToIgnore (const Led_tString& checkWord);
65 nonvirtual bool OtherStringToIgnore_AllPunctuation (const Led_tString& checkWord);
66 nonvirtual bool OtherStringToIgnore_Sentinels (const Led_tString& checkWord);
67 nonvirtual bool OtherStringToIgnore_Number (const Led_tString& checkWord);
68
69 public:
70 virtual vector<Led_tString> GenerateSuggestions (const Led_tString& misspelledWord) override;
71
72 public:
73 virtual UDInterface* GetUDInterface () override;
74
75 public:
76 virtual TextBreaks* PeekAtTextBreaksUsed () override;
77
78 private:
79 nonvirtual float Heuristic (const Led_tString& misspelledWord, const Led_tString& candidateWord, float atLeast);
80
81 private:
82 nonvirtual bool ScanForWord (const Led_tChar* startBuf, const Led_tChar* endBuf, const Led_tChar** cursor,
83 const Led_tChar** wordStartResult, const Led_tChar** wordEndResult);
84
85 public:
86 nonvirtual shared_ptr<TextBreaks> GetTextBreaker () const;
87 nonvirtual void SetTextBreaker (const shared_ptr<TextBreaks>& textBreaker);
88
89 private:
90 mutable shared_ptr<TextBreaks> fTextBreaker;
91
92 public:
93 struct InfoBlock {
94 unsigned int fIndex : 22;
95 unsigned int fWordLen : 8;
96 unsigned int fXXX : 2; // some flags - I forget the design - but I'll need this...
97 };
98
99#if qStroika_Frameworks_Led_IncludeBakedInDictionaries
100 public:
101 static const CompiledDictionary kDictionary_US_English;
102#endif
103
104 public:
105 nonvirtual vector<const Dictionary*> GetDictionaries () const;
106 nonvirtual void SetDictionaries (const vector<const Dictionary*>& dictionaries);
107
108 private:
109 vector<const Dictionary*> fDictionaries;
110
111#if qStroika_Foundation_Debug_AssertionsChecked
112 protected:
113 virtual void Invariant_ () const override;
114#endif
115
116#if qStroika_Foundation_Debug_AssertionsChecked
117 public:
118 /*
119 @METHOD: SpellCheckEngine_Basic::RegressionTest
120 @DESCRIPTION: <p>This function only exists if @'qStroika_Foundation_Debug_AssertionsChecked' is on. When run, it performs a basic regression test.</p>
121 */
122 static void RegressionTest ();
123
124 private:
125 static void RegressionTest_1 ();
126#endif
127 };
128
129 class SpellCheckEngine_Basic::Dictionary {
130 public:
131 using InfoBlock = SpellCheckEngine_Basic::InfoBlock;
132
133 protected:
134 Dictionary ();
135
136 public:
137 virtual ~Dictionary ();
138
139 public:
140 virtual const Led_tChar* GetTextBase () const = 0;
141 virtual const Led_tChar* GetTextEnd () const = 0;
142 virtual void GetInfoBlocks (const InfoBlock** start, const InfoBlock** end) const = 0;
143 };
144
145 class SpellCheckEngine_Basic::EditableDictionary : public SpellCheckEngine_Basic::Dictionary {
146 private:
147 using inherited = SpellCheckEngine_Basic::Dictionary;
148
149 public:
150 EditableDictionary () = default;
151
152 public:
153 virtual ~EditableDictionary ();
154
155 public:
156 nonvirtual void AddWordToUserDictionary (const Led_tString& word);
157
158 public:
159 virtual const Led_tChar* GetTextBase () const override;
160 virtual const Led_tChar* GetTextEnd () const override;
161 virtual void GetInfoBlocks (const InfoBlock** start, const InfoBlock** end) const override;
162
163 public:
164 nonvirtual void ReadFromBuffer (const Led_tChar* readOnlyRAMDictStart, const Led_tChar* readOnlyRAMDictEnd);
165 nonvirtual vector<Led_tChar> SaveToBuffer () const;
166
167 private:
168 nonvirtual void ConstructInfoBlocksEtcFromWordList ();
169
170 private:
171 set<Led_tString> fSortedWordList;
172 Led_tChar* fDictBufStart{nullptr};
173 Led_tChar* fDictBufEnd{nullptr};
174 vector<InfoBlock> fInfoBlocks;
175 };
176
177 class SpellCheckEngine_Basic::CompiledDictionary : public SpellCheckEngine_Basic::Dictionary {
178 private:
179 using inherited = SpellCheckEngine_Basic::Dictionary;
180
181 public:
182 struct CompiledDictionaryData {
183 const Led_tChar* fTextDataStart;
184 const Led_tChar* fTextDataEnd;
185 const InfoBlock* fInfoBlocksStart;
186 const InfoBlock* fInfoBlocksEnd;
187 };
188
189 public:
190 CompiledDictionary (const CompiledDictionaryData& data);
191
192 public:
193 virtual const Led_tChar* GetTextBase () const override;
194 virtual const Led_tChar* GetTextEnd () const override;
195 virtual void GetInfoBlocks (const InfoBlock** start, const InfoBlock** end) const override;
196
197 private:
198 CompiledDictionaryData fData;
199 };
200
201 /*
202 @CLASS: TextBreaks_SpellChecker
203 @BASES: @'TextBreaks_Basic'
204 @DESCRIPTION: <p>Special purpose text-break implementation uses inside spell-checker. Not recomended for use elsewhere, but
205 it could be.</p>
206 */
207 class TextBreaks_SpellChecker : public TextBreaks_Basic {
208 private:
209 using inherited = TextBreaks_Basic;
210
211 public:
212 TextBreaks_SpellChecker ();
213
214 protected:
215 virtual CharacterClasses CharToCharacterClass (const Led_tChar* startOfText, size_t lengthOfText, const Led_tChar* charToExamine) const override;
216
217#if qStroika_Foundation_Debug_AssertionsChecked
218 private:
219 nonvirtual void RegressionTest ();
220#endif
221 };
222
223 /*
224 @CLASS: SpellCheckEngine_Basic_Simple
225 @DESCRIPTION: <p>This is a simple wrapper providing most pre-packaged spellcheck functionality a spellchekcing application would typically want.
226 You easily specify one pre-built 'system' dictionary, and one optional user-dictionary (you just specify the file name
227 and the rest is taken care of automatically).
228 </p>
229 */
230 class SpellCheckEngine_Basic_Simple : public SpellCheckEngine_Basic, private SpellCheckEngine::UDInterface {
231 private:
232 using inherited = SpellCheckEngine_Basic;
233
234 public:
235 using SpellCheckEngine::UDInterface;
236
237 public:
238 SpellCheckEngine_Basic_Simple ();
239 ~SpellCheckEngine_Basic_Simple ();
240
241 public:
242 virtual UDInterface* GetUDInterface () override;
243
244 // From SpellCheckEngine::UDInterface
245 public:
246 virtual bool AddWordToUserDictionarySupported () const override;
247 virtual void AddWordToUserDictionary (const Led_tString& word) override;
248
249 public:
250 nonvirtual const Dictionary* GetMainDictionary () const;
251 nonvirtual void SetMainDictionary (const Dictionary* mainDictionary);
252
253 private:
254 const Dictionary* fMainDictionary;
255
256 public:
257 nonvirtual filesystem::path GetUserDictionary () const;
258 nonvirtual void SetUserDictionary (const filesystem::path& userDictionary);
259
260 private:
261 filesystem::path fUDName;
262 EditableDictionary* fUD;
263
264 private:
265 nonvirtual void ReadFromUD ();
266 nonvirtual void WriteToUD ();
267 };
268
269}
270
271/*
272 ********************************************************************************
273 ***************************** Implementation Details ***************************
274 ********************************************************************************
275 */
276#include "SpellCheckEngine_Basic.inl"
277
278#endif /*_Stroika_Frameworks_Led_SpellCheckEngine_Basic_h_*/