2 National Institute of Advanced Industrial Science and Technology (AIST)
3 Registration Number H15PRO112
4 See the end for copying conditions. */
8 @page mdbTutorialIM Tutorial of input method
10 @section im-struct Structure of an input method file
12 An input method is defined in a *.mim file with this format.
15 (input-method LANG NAME)
17 (description (_ "DESCRIPTION"))
19 (title "TITLE-STRING")
23 (KEYSEQ MAP-ACTION MAP-ACTION ...) <- rule
24 (KEYSEQ MAP-ACTION MAP-ACTION ...) <- rule
27 (KEYSEQ MAP-ACTION MAP-ACTION ...) <- rule
28 (KEYSEQ MAP-ACTION MAP-ACTION ...) <- rule
34 (MAP-NAME BRANCH-ACTION BRANCH-ACTION ...) <- branch
37 (MAP-NAME BRANCH-ACTION BRANCH-ACTION ...) <- branch
41 Lowercase letters and parentheses are literals, so they must be
42 written as they are. Uppercase letters represent arbitrary strings.
44 KEYSEQ specifies a sequence of keys in this format:
46 (SYMBOLIC-KEY SYMBOLIC-KEY ...)
48 where SYMBOLIC-KEY is the keysym value returned by the xev command.
53 represents a key sequence of \<n\> and \<i\>.
54 If all SYMBOLIC-KEYs are ASCII characters, you can use the short form
58 instead. Consult #mdbIM for Non-ASCII characters.
60 Both MAP-ACTION and BRANCH-ACTION are a sequence of actions of this format:
64 The most common action is [[insert]], which is written as this:
68 But as it is very frequently used, you can use the short form
72 If [["TEXT"]] contains only one character "C", you can write it as
80 So the shortest notation for an action of inserting "a" is
85 @section im-upcase Simple example of capslock
87 Here is a simple example of an input method that works as CapsLock.
90 (input-method en capslock)
91 (description (_ "Upcase all lowercase letters"))
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")
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.
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
118 As a result, "A" is given to the application program.
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.
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]].
132 However, we already have the following rule:
138 What will happen when a key event \<i\> is sent to the input method?
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.
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 "İ".
154 Then, what will happen when the next key event is \<a\> instead of \<i\>?
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".
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.
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:
176 (toupper (shift non-upcase)))
179 Here [[(shift non-upcase)]] is an action to shift to the new state
180 [[non-upcase]], which has two branches as below:
188 The first branch is simple. We can define the new map [[lower]] as the
189 following to insert lowercase letters as they are.
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")
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.
209 (input-method en titlecase)
210 (description (_ "Titlecase letters"))
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")
227 (toupper (shift non-upcase)))
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.
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.
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
255 @section im-surrounding-text Example of utilizing surrounding text support
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.
264 Before explaining how to utilize "surrounding text support", you must
265 understand how to use variables, arithmetic comparisons, and
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
272 (set X 32) (insert X)
275 set the variable [[X]] to integer value 32, then insert a character
276 whose Unicode character code is 32 (i.e. SPACE).
278 The second argument of the [[set]] action can be an expression of this form:
281 (OPERATOR ARG1 [ARG2])
284 Both ARG1 and ARG2 can be an expression. So,
287 (set X (+ (* Y 32) Z))
290 sets [[X]] to the value of [[Y * 32 + Z]].
292 We have the following arithmetic/bitwise OPERATORs (require two arguments):
298 these relational OPERATORs (require two arguments):
304 and this logical OPERATOR (requires one argument):
310 For surrounding text support, we have these preserved variables:
313 @-0, @-N, @+N (N is a positive integer)
316 The values of them are predefined as below and can not be altered.
321 -1 if surrounding text is supported, -2 if not.
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.
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.
337 So, provided that you have this context:
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:
356 Next, you have to understand the conditional action of this form:
360 (EXPR1 ACTION ACTION ...)
361 (EXPR2 ACTION ACTION ...)
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.
370 Now you are ready to write a new version of the input method "Titlecase".
373 (input-method en titlecase2)
374 (description (_ "Titlecase letters"))
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" "İ")))
387 ;; Now we have exactly one uppercase character in the preedit
388 ;; buffer. So, "@-2" is the character just before the inputting
391 (cond ((| (& (>= @-2 ?A) (<= @-2 ?Z))
392 (& (>= @-2 ?a) (<= @-2 ?z))
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.
399 (set X @-1) (delete @-)
401 ;; Then insert the lowercase version of X.
404 (1 (set X (+ X 32)) (insert X))))))))
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),
420 changes the buffer to "abxyz.c".
422 There are several predefined variables that represent a specific position in the
423 preedit buffer. They are:
426 <li> [[@@<, @=, @@>]]
428 The first, current, and last positions.
432 The previous and the next positions.
435 The format of the [[delete]] action is this:
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:
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
452 You can change the current position using the [[move]] action as below:
455 (move @-) ; move the current position to the position before the
457 (move @<) ; move to the first position
460 Other positional variables work similarly.
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]].
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.
472 It first checks if the character [[@-2]] is between A to Z, between
473 a to z, or İ by the conditional below.
476 (cond ((| (& (>= @-2 ?A) (<= @-2 ?Z))
477 (& (>= @-2 ?a) (<= @-2 ?z))
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
490 and then delete that character by
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
504 means that "if the character remembered in X is 'İ', 'i' is inserted".
509 (1 (set X (+ X 32)) (insert X))
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.
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>>.
528 National Institute of Advanced Industrial Science and Technology (AIST)
529 Registration Number H15PRO112
531 This file is part of the m17n database; a sub-part of the m17n
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.
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.
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.