*** empty log message ***
[m17n/m17n-db.git] / FORMATS / IM-tut.txt
1 /* Copyright (C) 2007
2      National Institute of Advanced Industrial Science and Technology (AIST)
3      Registration Number H15PRO112
4    See the end for copying conditions.  */
5
6 /***
7
8 @page mdbTutorialIM Tutorial of input method
9
10 @section im-struct Structure of an input method file
11
12 An input method is defined in a *.mim file with this format.
13
14 @verbatim
15 (input-method LANG NAME)
16
17 (description (_ "DESCRIPTION"))
18
19 (title "TITLE-STRING")
20
21 (map
22   (MAP-NAME
23     (KEYSEQ MAP-ACTION MAP-ACTION ...)        <- rule
24     (KEYSEQ MAP-ACTION MAP-ACTION ...)        <- rule
25     ...)
26   (MAP-NAME
27     (KEYSEQ MAP-ACTION MAP-ACTION ...)        <- rule
28     (KEYSEQ MAP-ACTION MAP-ACTION ...)        <- rule
29     ...)
30   ...)
31
32 (state
33   (STATE-NAME
34     (MAP-NAME BRANCH-ACTION BRANCH-ACTION ...)   <- branch
35     ...)
36   (STATE-NAME
37     (MAP-NAME BRANCH-ACTION BRANCH-ACTION ...)   <- branch
38     ...)
39   ...)
40 @endverbatim
41 Lowercase letters and parentheses are literals, so they must be
42 written as they are.  Uppercase letters represent arbitrary strings.
43
44 KEYSEQ specifies a sequence of keys in this format:
45 @verbatim
46   (SYMBOLIC-KEY SYMBOLIC-KEY ...)
47 @endverbatim
48 where SYMBOLIC-KEY is the keysym value returned by the xev command.
49 For instance
50 @verbatim
51   (n i)
52 @endverbatim
53 represents a key sequence of \<n\> and \<i\>.
54 If all SYMBOLIC-KEYs are ASCII characters, you can use the short form
55 @verbatim
56   "ni"
57 @endverbatim
58 instead.  Consult #mdbIM for Non-ASCII characters.
59
60 Both MAP-ACTION and BRANCH-ACTION are a sequence of actions of this format:
61 @verbatim
62   (ACTION ARG ARG ...)
63 @endverbatim
64 The most common action is [[insert]], which is written as this:
65 @verbatim
66   (insert "TEXT")
67 @endverbatim
68 But as it is very frequently used, you can use the short form
69 @verbatim
70   "TEXT"
71 @endverbatim
72 If [["TEXT"]] contains only one character "C", you can write it as
73 @verbatim
74   (insert ?C)
75 @endverbatim
76 or even shorter as
77 @verbatim
78   ?C
79 @endverbatim
80 So the shortest notation for an action of inserting "a" is
81 @verbatim
82   ?a
83 @endverbatim
84
85 @section im-upcase Simple example of capslock
86
87 Here is a simple example of an input method that works as CapsLock.
88
89 @verbatim
90 (input-method en capslock)
91 (description (_ "Upcase all lowercase letters"))
92 (title "a->A")
93 (map
94   (toupper ("a" "A") ("b" "B") ("c" "C") ("d" "D") ("e" "E")
95            ("f" "F") ("g" "G") ("h" "H") ("i" "I") ("j" "J")
96            ("k" "K") ("l" "L") ("m" "M") ("n" "N") ("o" "O")
97            ("p" "P") ("q" "Q") ("r" "R") ("s" "S") ("t" "T")
98            ("u" "U") ("v" "V") ("w" "W") ("x" "X") ("y" "Y")
99            ("z" "Z")))
100 (state
101   (init (toupper)))
102 @endverbatim
103
104 When this input method is activated, it is in the initial condition of
105 the first state (in this case, the only state [[init]]).  In the
106 initial condition, no key is being processed and no action is
107 suspended.  When the input method receives a key event \<a\>, it
108 searches branches in the current state for a rule that matches \<a\>
109 and finds one in the map [[toupper]].  Then it executes MAP-ACTIONs
110 (in this case, just inserting "A" in the preedit buffer).  After all
111 MAP-ACTIONs have been executed, the input method shifts to the initial
112 condition of the current state.
113
114 The shift to <em>the initial condition of the first state</em> has a special
115 meaning; it commits all characters in the preedit buffer then clears
116 the preedit buffer.
117
118 As a result, "A" is given to the application program.
119
120 When a key event does not match with any rule in the current state,
121 that event is unhandled and given back to the application program.
122
123 Turkish users may want to extend the above example for "İ" (U+0130:
124 LATIN CAPITAL LETTER I WITH DOT ABOVE).  It seems that assigning the
125 key sequence \<i\> \<i\> for that character is convenient.  So, he
126 will add this rule in [[toupper]].
127
128 @verbatim
129     ("ii" "İ")
130 @endverbatim
131
132 However, we already have the following rule:
133
134 @verbatim
135     ("i" "I")
136 @endverbatim
137
138 What will happen when a key event \<i\> is sent to the input method?
139
140 No problem.  When the input method receives \<i\>, it inserts "I" in the
141 preedit buffer.  It knows that there is another rule that may
142 match the additional key event \<i\>.  So, after inserting "I", it
143 suspends the normal behavior of shifting to the initial condition, and
144 waits for another key.  Thus, the user sees "I" with underline, which
145 indicates it is not yet committed.
146
147 When the input method receives the next \<i\>, it cancels the effects
148 done by the rule for the previous "i" (in this case, the preedit buffer is
149 cleared), and executes MAP-ACTIONs of the rule for "ii".  So, "İ" is
150 inserted in the preedit buffer.  This time, as there are no other rules
151 that match with an additional key, it shifts to the initial condition
152 of the current state, which leads to commit "İ".
153
154 Then, what will happen when the next key event is \<a\> instead of \<i\>?
155
156 No problem, either.
157
158 The input method knows that there are no rules that match the \<i\> \<a\> key
159 sequence.  So, when it receives the next \<a\>, it executes the
160 suspended behavior (i.e. shifting to the initial condition), which
161 leads to commit "I".  Then the input method tries to handle \<a\> in
162 the current state, which leads to commit "A".
163
164 So far, we have explained MAP-ACTION, but not
165 BRANCH-ACTION.  The format of BRANCH-ACTION is the same as that of MAP-ACTION.
166 It is executed only after a matching rule has been determined and the
167 corresponding MAP-ACTIONs have been executed.  A typical use of
168 BRANCH-ACTION is to shift to a different state.
169
170 To see this effect, let us modify the current input method to upcase only
171 word-initial letters (i.e. to capitalize).  For that purpose,
172 we modify the "init" state as this:
173
174 @verbatim
175   (init
176     (toupper (shift non-upcase)))
177 @endverbatim
178
179 Here [[(shift non-upcase)]] is an action to shift to the new state
180 [[non-upcase]], which has two branches as below:
181
182 @verbatim
183   (non-upcase
184     (lower)
185     (nil (shift init)))
186 @endverbatim
187
188 The first branch is simple.  We can define the new map [[lower]] as the
189 following to insert lowercase letters as they are.
190
191 @verbatim
192 (map
193   ...
194   (lower ("a" "a") ("b" "b") ("c" "c") ("d" "d") ("e" "e")
195          ("f" "f") ("g" "g") ("h" "h") ("i" "i") ("j" "j")
196          ("k" "k") ("l" "l") ("m" "m") ("n" "n") ("o" "o")
197          ("p" "p") ("q" "q") ("r" "r") ("s" "s") ("t" "t")
198          ("u" "u") ("v" "v") ("w" "w") ("x" "x") ("y" "y")
199          ("z" "z")))
200 @endverbatim
201
202 The second branch has a special meaning.  The map name [[nil]] means
203 that it matches with any key event that does not match any rules in the
204 other maps in the current state.  In addition, it does not
205 consume any key event.  We will show the full code of the new input
206 method before explaining how it works.
207
208 @verbatim
209 (input-method en titlecase)
210 (description (_ "Titlecase letters"))
211 (title "abc->Abc")
212 (map
213   (toupper ("a" "A") ("b" "B") ("c" "C") ("d" "D") ("e" "E")
214            ("f" "F") ("g" "G") ("h" "H") ("i" "I") ("j" "J")
215            ("k" "K") ("l" "L") ("m" "M") ("n" "N") ("o" "O")
216            ("p" "P") ("q" "Q") ("r" "R") ("s" "S") ("t" "T")
217            ("u" "U") ("v" "V") ("w" "W") ("x" "X") ("y" "Y")
218            ("z" "Z") ("ii" "İ"))
219   (lower ("a" "a") ("b" "b") ("c" "c") ("d" "d") ("e" "e")
220          ("f" "f") ("g" "g") ("h" "h") ("i" "i") ("j" "j")
221          ("k" "k") ("l" "l") ("m" "m") ("n" "n") ("o" "o")
222          ("p" "p") ("q" "q") ("r" "r") ("s" "s") ("t" "t")
223          ("u" "u") ("v" "v") ("w" "w") ("x" "x") ("y" "y")
224          ("z" "z")))
225 (state
226   (init
227     (toupper (shift non-upcase)))
228   (non-upcase
229     (lower (commit))
230     (nil (shift init))))
231 @endverbatim
232
233 Let's see what happens when the user types the key sequence \<a\> \<b\> \< \>.
234 Upon \<a\>, "A" is committed and the state shifts to [[non-upcase]].
235 So, the next \<b\> is handled in the [[non-upcase]] state.
236 As it matches a
237 rule in the map [[lower]], "b" is inserted in the preedit buffer and it
238 is committed explicitly by the "commit" command in BRANCH-ACTION.  After
239 that, the input method is still in the [[non-upcase]] state.  So the next \< \>
240 is also handled in [[non-upcase]].  For this time, no rule in this state
241 matches it.  Thus the branch [[(nil (shift init))]] is selected and the
242 state is shifted to [[init]].  Please note that \< /> is not yet
243 handled because the map [[nil]] does not consume any key event.
244 So, the input method tries to handle it in the [[init]] state.  Again no
245 rule matches it.  Therefore, that event is given back to the application
246 program, which usually inserts a space for that.
247
248 When you type "a quick blown fox" with this input method, you get "A
249 Quick Blown Fox".  OK, you find a typo in "blown", which should be
250 "brown".  To correct it, you probably move the cursor after "l" and type
251 \<Backspace>> and \<r>>.  However, if the current input method is still
252 active, a capital "R" is inserted.  It is not a sophisticated
253 behavior.
254
255 @section im-surrounding-text Example of utilizing surrounding text support
256
257 To make the input method work well also in such a case, we must use
258 "surrounding text support".  It is a way to check characters around
259 the inputting spot and delete them if necessary.  Note that
260 this facility is available only with Gtk+ applications and Qt
261 applications.  You cannot use it with applications that use XIM
262 to communicate with an input method.
263
264 Before explaining how to utilize "surrounding text support", you must
265 understand how to use variables, arithmetic comparisons, and
266 conditional actions.
267
268 At first, any symbol (except for several preserved ones) used as ARG
269 of an action is treated as a variable.  For instance, the commands
270
271 @verbatim
272   (set X 32) (insert X)
273 @endverbatim
274
275 set the variable [[X]] to integer value 32, then insert a character
276 whose Unicode character code is 32 (i.e. SPACE).
277
278 The second argument of the [[set]] action can be an expression of this form:
279
280 @verbatim
281   (OPERATOR ARG1 [ARG2])
282 @endverbatim
283
284 Both ARG1 and ARG2 can be an expression.  So,
285
286 @verbatim
287   (set X (+ (* Y 32) Z))
288 @endverbatim
289
290 sets [[X]] to the value of [[Y * 32 + Z]].
291
292 We have the following arithmetic/bitwise OPERATORs (require two arguments):
293
294 @verbatim
295   + - * / & |
296 @endverbatim
297
298 these relational OPERATORs (require two arguments):
299
300 @verbatim
301   == <= >= < >
302 @endverbatim
303
304 and this logical OPERATOR (requires one argument):
305
306 @verbatim
307   !
308 @endverbatim
309
310 For surrounding text support, we have these preserved variables:
311
312 @verbatim
313   @-0, @-N, @+N (N is a positive integer)
314 @endverbatim
315
316 The values of them are predefined as below and can not be altered.
317
318 <ul>
319 <li> [[@-0]]
320
321 -1 if surrounding text is supported, -2 if not.
322
323 <li> [[@-N]]
324
325 The Nth previous character in the preedit buffer.  If there are only M
326 (M<N) previous characters in it, the value is the (N-M)th previous
327 character from the inputting spot.
328
329 <li> [[@+N]]
330
331 The Nth following character in the preedit buffer.  If there are only M
332 (M<N) following characters in it, the value is the (N-M)th following
333 character from the inputting spot.
334
335 </ul>
336
337 So, provided that you have this context:
338
339 @verbatim
340   ABC|def|GHI
341 @endverbatim
342
343 ("def" is in the preedit buffer, two "|"s indicate borders between the
344 preedit buffer and the surrounding text) and your current position in
345 the preedit buffer is between "d" and "e", you get these values:
346
347 @verbatim
348   @-3 -- ?B
349   @-2 -- ?C
350   @-1 -- ?d
351   @+1 -- ?e
352   @+2 -- ?f
353   @+3 -- ?G
354 @endverbatim
355
356 Next, you have to understand the conditional action of this form:
357
358 @verbatim
359   (cond
360     (EXPR1 ACTION ACTION ...)
361     (EXPR2 ACTION ACTION ...)
362     ...)
363 @endverbatim
364
365 where EXPRn are expressions.  When an input method executes this
366 action, it resolves the values of EXPRn one by one from the first branch.
367 If the value of EXPRn is resolved into nonzero, the corresponding
368 actions are executed.
369
370 Now you are ready to write a new version of the input method "Titlecase".
371
372 @verbatim
373 (input-method en titlecase2)
374 (description (_ "Titlecase letters"))
375 (title "abc->Abc")
376 (map
377   (toupper ("a" "A") ("b" "B") ("c" "C") ("d" "D") ("e" "E")
378            ("f" "F") ("g" "G") ("h" "H") ("i" "I") ("j" "J")
379            ("k" "K") ("l" "L") ("m" "M") ("n" "N") ("o" "O")
380            ("p" "P") ("q" "Q") ("r" "R") ("s" "S") ("t" "T")
381            ("u" "U") ("v" "V") ("w" "W") ("x" "X") ("y" "Y")
382            ("z" "Z") ("ii" "İ")))
383 (state
384   (init
385     (toupper
386
387      ;; Now we have exactly one uppercase character in the preedit
388      ;; buffer.  So, "@-2" is the character just before the inputting
389      ;; spot.
390
391      (cond ((| (& (>= @-2 ?A) (<= @-2 ?Z))
392                (& (>= @-2 ?a) (<= @-2 ?z))
393                (= @-2 ?İ))
394
395             ;; If the character before the inputting spot is A..Z,
396             ;; a..z, or İ, remember the only character in the preedit
397             ;; buffer in the variable X and delete it.
398
399             (set X @-1) (delete @-)
400
401             ;; Then insert the lowercase version of X.
402
403             (cond ((= X ?İ) "i") 
404                   (1 (set X (+ X 32)) (insert X))))))))
405 @endverbatim
406
407 The above example contains the new action [[delete]].  So, it is time
408 to explain more about the preedit buffer.  The preedit buffer is a
409 temporary place to store a sequence of characters.  In this buffer,
410 the input method keeps a position called the "current position".  The
411 current position exists between two characters, at the beginning of
412 the buffer, or at the end of the buffer.  The [[insert]] action inserts
413 characters before the current position.  For instance, when your
414 preedit buffer contains "ab.c" ("." indicates the current position),
415
416 @verbatim
417   (insert "xyz")
418 @endverbatim
419
420 changes the buffer to "abxyz.c".
421
422 There are several predefined variables that represent a specific position in the
423 preedit buffer.  They are:
424
425 <ul>
426 <li> [[@@<, @=, @@>]] 
427
428 The first, current, and last positions.
429
430 <li> [[@-, @+]]
431
432 The previous and the next positions.
433 </ul>
434
435 The format of the [[delete]] action is this:
436
437 @verbatim
438   (delete POS)
439 @endverbatim
440
441 where POS is a predefined positional variable.
442 The above action deletes the characters between POS and
443 the current position.  So, [[(delete @-)]] deletes one character before
444 the current position.  The other examples of [[delete]] include the followings:
445
446 @verbatim
447   (delete @+)  ; delete the next character
448   (delete @<)  ; delete all the preceding characters in the buffer
449   (delete @>)  ; delete all the following characters in the buffer
450 @endverbatim
451
452 You can change the current position using the [[move]] action as below:
453
454 @verbatim
455   (move @-)  ; move the current position to the position before the
456                previous character
457   (move @<)  ; move to the first position
458 @endverbatim
459
460 Other positional variables work similarly.
461
462 Let's see how our new example works.  Whatever a key event is, the
463 input method is in its only state, [[init]].  Since an event of a lower letter
464 key is firstly handled by MAP-ACTIONs, every key is changed into the
465 corresponding uppercase and put into the preedit buffer.  Now this character
466 can be accessed with [[@-1]].
467
468 How can we tell whether the new character should be a lowercase or an
469 uppercase?  We can do so by checking the character before it, i.e.
470 [[@-2]].  BRANCH-ACTIONs in the [[init]] state do the job.
471
472 It first checks if the character [[@-2]] is between A to Z, between
473 a to z, or İ by the conditional below.
474
475 @verbatim
476      (cond ((| (& (>= @-2 ?A) (<= @-2 ?Z))
477                (& (>= @-2 ?a) (<= @-2 ?z))
478                (= @-2 ?İ))
479 @endverbatim
480
481 If not, there is nothing to do specially.  If so, our new key should
482 be changed back into lowercase.  Since the uppercase character is
483 already in the preedit buffer, we retrieve and remember it in the
484 variable [[X]] by
485
486 @verbatim
487     (set X @-1)
488 @endverbatim
489
490 and then delete that character by
491
492 @verbatim
493     (delete @-)
494 @endverbatim
495
496 Lastly we re-insert the character in its lowercase form.  The
497 problem here is that "İ" must be changed into "i", so we need another
498 conditional.  The first branch
499
500 @verbatim
501     ((= X ?İ) "i")
502 @endverbatim
503
504 means that "if the character remembered in X is 'İ', 'i' is inserted".
505
506 The second branch 
507
508 @verbatim
509     (1 (set X (+ X 32)) (insert X))
510 @endverbatim
511
512 starts with "1", which is always resolved into nonzero, so this branch
513 is a catchall.  Actions in this branch increase [[X]] by 32, then
514 insert [[X]].  In other words, they change A...Z into a...z
515 respectively and insert the resulting lowercase character into the
516 preedit buffer.  As the input method reaches the end of the
517 BRANCH-ACTIONs, the character is commited.
518
519 This new input method always checks the character before the current
520 position, so "A Quick Blown Fox" will be successfully fixed to "A
521 Quick Brown Fox" by the key sequence \<BackSpace>> \<r>>.
522
523
524 */
525
526 /* 
527 Copyright (C) 2007
528   National Institute of Advanced Industrial Science and Technology (AIST)
529   Registration Number H15PRO112
530
531 This file is part of the m17n database; a sub-part of the m17n
532 library.
533
534 The m17n library is free software; you can redistribute it and/or
535 modify it under the terms of the GNU Lesser General Public License
536 as published by the Free Software Foundation; either version 2.1 of
537 the License, or (at your option) any later version.
538
539 The m17n library is distributed in the hope that it will be useful,
540 but WITHOUT ANY WARRANTY; without even the implied warranty of
541 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
542 Lesser General Public License for more details.
543
544 You should have received a copy of the GNU Lesser General Public
545 License along with the m17n library; if not, write to the Free
546 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
547 Boston, MA 02110-1301, USA.
548 */