]> git.lyx.org Git - lyx.git/blob - src/Trans.h
Avoid full metrics computation with Update:FitCursor
[lyx.git] / src / Trans.h
1 // -*- C++ -*-
2 /**
3  * \file Trans.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Lars Gullik Bjønnes
8  * \author Matthias Ettrich
9  * \author John Levon
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13
14 #ifndef TRANS_H
15 #define TRANS_H
16
17 #include "FuncCode.h"
18
19 #include "support/docstring.h"
20
21 #include <list>
22 #include <map>
23
24
25 namespace lyx {
26
27 class Cursor;
28 class Text;
29 class TransManager;
30
31 namespace support { class Lexer; }
32
33 ///
34 enum tex_accent {
35         ///
36         TEX_NOACCENT = 0,
37         ///
38         TEX_ACUTE,
39         ///
40         TEX_GRAVE,
41         ///
42         TEX_MACRON,
43         ///
44         TEX_TILDE,
45         ///
46         TEX_PERISPOMENI,
47         ///
48         TEX_UNDERBAR,
49         ///
50         TEX_CEDILLA,
51         ///
52         TEX_UNDERDOT,
53         ///
54         TEX_CIRCUMFLEX,
55         ///
56         TEX_CIRCLE,
57         ///
58         TEX_TIE,
59         ///
60         TEX_BREVE,
61         ///
62         TEX_CARON,
63 //  TEX_SPECIAL_CARON,
64         ///
65         TEX_HUNGUML,
66         ///
67         TEX_UMLAUT,
68         ///
69         TEX_DOT,
70         ///
71         TEX_OGONEK,
72         ///
73         TEX_MAX_ACCENT = TEX_OGONEK
74 };
75
76
77 struct TeXAccent {
78         ///
79         tex_accent accent;
80         /// UCS4 code point of this accent
81         char_type ucs4;
82         ///
83         char const * name;
84         ///
85         FuncCode action;
86 };
87
88 ///
89 extern TeXAccent get_accent(FuncCode action);
90
91
92 ///
93 struct Keyexc {
94         ///
95         Keyexc() : c('\0'), combined(false), accent(TEX_NOACCENT) {}
96         /// character to make exception
97         char_type c;
98         /// exception data
99         docstring data;
100         /// Combination with another deadkey
101         bool combined;
102         /// The accent comined with
103         tex_accent accent;
104 };
105
106 ///
107 typedef std::list<Keyexc> KmodException;
108
109 ///
110 class KmodInfo {
111 public:
112         ///
113         KmodInfo() : accent(TEX_NOACCENT) {}
114         ///
115         docstring data;
116         ///
117         tex_accent accent;
118         ///
119         KmodException exception_list;
120 };
121
122
123 /////////////////////////////////////////////////////////////////////
124 //
125 // Trans: holds a .kmap file
126 //
127 /////////////////////////////////////////////////////////////////////
128
129 class Trans {
130 public:
131         ///
132         Trans() {}
133         ///
134         ~Trans() { freeKeymap(); }
135
136         ///
137         int load(std::string const & language);
138         ///
139         bool isDefined() const;
140         ///
141         std::string const & getName() const { return name_; }
142         ///
143         docstring const process(char_type, TransManager &);
144         ///
145         bool isAccentDefined(tex_accent, KmodInfo &) const;
146
147 private:
148         ///
149         void addDeadkey(tex_accent, docstring const &);
150         ///
151         void freeKeymap();
152         ///
153         int load(support::Lexer &);
154         ///
155         docstring const & match(char_type c);
156         ///
157         void insertException(KmodException & exclist, char_type c,
158                              docstring const & data, bool = false,
159                              tex_accent = TEX_NOACCENT);
160         ///
161         void freeException(KmodException & exclist);
162
163         ///
164         std::string name_;
165         ///
166         std::map<char_type, docstring> keymap_;
167         ///
168         std::map<tex_accent, KmodInfo> kmod_list_;
169 };
170
171
172 ///
173 inline docstring const & Trans::match(char_type c)
174 {
175         std::map<char_type, docstring>::iterator it = keymap_.find(c);
176         if (it != keymap_.end()) {
177                 return it->second;
178         }
179         static docstring dummy;
180         return dummy;
181 }
182
183
184 /////////////////////////////////////////////////////////////////////
185 //
186 // TransState
187 //
188 /////////////////////////////////////////////////////////////////////
189
190 /// Translation state
191 class TransState {
192 public:
193         ///
194         virtual ~TransState() {}
195         ///
196         virtual docstring const normalkey(char_type) = 0;
197         ///
198         virtual bool backspace() = 0;
199         ///
200         virtual docstring const deadkey(char_type, KmodInfo) = 0;
201         ///
202         static char_type const TOKEN_SEP;
203 };
204
205
206 /// Translation FSM
207 class TransFSMData {
208 protected:
209         ///
210         virtual ~TransFSMData() {}
211         ///
212         char_type deadkey_;
213         ///
214         KmodInfo deadkey_info_;
215         ///
216         char_type deadkey2_;
217         ///
218         KmodInfo deadkey2_info_;
219         ///
220         Keyexc comb_info_;
221         ///
222         TransState * init_state_;
223         ///
224         TransState * deadkey_state_;
225         ///
226         TransState * combined_state_;
227         ///
228 public:
229         ///
230         TransFSMData();
231         ///
232         TransState * currentState;
233 };
234
235
236 /// Init State
237 class TransInitState : virtual public TransFSMData, public TransState {
238 public:
239         ///
240         TransInitState();
241         ///
242         docstring const normalkey(char_type) override;
243         ///
244         bool backspace() override { return true; }
245         ///
246         docstring const deadkey(char_type, KmodInfo) override;
247 };
248
249
250 /// Deadkey State
251 class TransDeadkeyState : virtual public TransFSMData, public TransState {
252 public:
253         ///
254         TransDeadkeyState();
255         ///
256         docstring const normalkey(char_type) override;
257         ///
258         bool backspace() override {
259                 currentState = init_state_;
260                 return false;
261         }
262         ///
263         docstring const deadkey(char_type, KmodInfo) override;
264 };
265
266
267 /// Combined State
268 class TransCombinedState : virtual public TransFSMData, public TransState {
269 public:
270         ///
271         TransCombinedState();
272         ///
273         docstring const normalkey(char_type) override;
274         ///
275         bool backspace() override {
276                 // cancel the second deadkey
277                 deadkey2_ = 0;
278                 deadkey2_info_.accent = TEX_NOACCENT;
279                 currentState = deadkey_state_;
280
281                 return false;
282         }
283         ///
284         docstring const deadkey(char_type, KmodInfo) override;
285 };
286
287
288 ///
289 class TransFSM : virtual public TransFSMData,
290                  public TransInitState,
291                  public TransDeadkeyState,
292                  public TransCombinedState {
293 public:
294         ///
295         TransFSM();
296 };
297
298
299
300 /////////////////////////////////////////////////////////////////////
301 //
302 // TransManager
303 //
304 /////////////////////////////////////////////////////////////////////
305
306 class TransManager {
307 private:
308         ///
309         TransFSM trans_fsm_;
310         ///
311         Trans * active_;
312         ///
313         Trans t1_;
314         ///
315         Trans t2_;
316         ///
317         static Trans default_;
318         ///
319         void insert(docstring const &, Text *, Cursor & cur);
320 public:
321         ///
322         TransManager();
323         ///
324         int setPrimary(std::string const &);
325         ///
326         int setSecondary(std::string const &);
327         ///
328         void enablePrimary();
329         ///
330         void enableSecondary();
331         ///
332         void disableKeymap();
333         ///
334         bool backspace() { return trans_fsm_.currentState->backspace(); }
335         ///
336         void translateAndInsert(char_type, Text *, Cursor &);
337         ///
338         docstring const deadkey(char_type c, KmodInfo t)
339                 { return trans_fsm_.currentState->deadkey(c, t); }
340         ///
341         docstring const normalkey(char_type c)
342                 { return trans_fsm_.currentState->normalkey(c); }
343         ///
344         void deadkey(char_type, tex_accent, Text *, Cursor &);
345 };
346
347 } // namespace lyx
348
349 #endif // TRANS_H