;; th-kesmanee.mim -- Thai input method with Kesmanee keyboard layout ;; Copyright (C) 2003, 2004, 2005, 2006, 2007 ;; National Institute of Advanced Industrial Science and Technology (AIST) ;; Registration Number H15PRO112 ;; This file is part of the m17n database; a sub-part of the m17n ;; library. ;; The m17n library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public License ;; as published by the Free Software Foundation; either version 2.1 of ;; the License, or (at your option) any later version. ;; The m17n library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; Lesser General Public License for more details. ;; You should have received a copy of the GNU Lesser General Public ;; License along with the m17n library; if not, write to the Free ;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. (input-method th kesmanee) (description "Thai input method simulating the Kesmanee keyboard with WTT 2.0 input sequence correction. The correction algorithm follows the one shown in the following ") (variable (level (_"Acceptance level The level of character sequence acceptance defined in WTT 2.0. 0 accepts any key sequence. 2 accepts only orthographic ones. 1 is somewhere between.") 1 0 1 2)) (title "ท") (map (map ("!" "+") ("\"" ".") ("#" "๒") ("$" "๓") ("%" "๔") ("&" "฿") ("'" "ง") ("(" "๖") (")" "๗") ("*" "๕") ("+" "๙") ("," "ม") ("-" "ข") ("." "ใ") ("/" "ฝ") ("0" "จ") ("1" "ๅ") ("2" "/") ("3" "-") ("4" "ภ") ("5" "ถ") ("6" "ุ") ("7" "ึ") ("8" "ค") ("9" "ต") (":" "ซ") (";" "ว") ("<" "ฒ") ("=" "ช") (">" "ฬ") ("?" "ฦ") ("@" "๑") ("A" "ฤ") ("B" "ฺ") ("C" "ฉ") ("D" "ฏ") ("E" "ฎ") ("F" "โ") ("G" "ฌ") ("H" "็") ("I" "ณ") ("J" "๋") ("K" "ษ") ("L" "ศ") ("M" "?") ("N" "์") ("O" "ฯ") ("P" "ญ") ("Q" "๐") ("R" "ฑ") ("S" "ฆ") ("T" "ธ") ("U" "๊") ("V" "ฮ") ("W" "\"") ("X" ")") ("Y" "ํ") ("Z" "(") ("[" "บ") ("\\" "ฃ") ("]" "ล") ("^" "ู") ("_" "๘") ("`" "_") ("a" "ฟ") ("b" "ิ") ("c" "แ") ("d" "ก") ("e" "ำ") ("f" "ด") ("g" "เ") ("h" "้") ("i" "ร") ("j" "่") ("k" "า") ("l" "ส") ("m" "ท") ("n" "ื") ("o" "น") ("p" "ย") ("q" "ๆ") ("r" "พ") ("s" "ห") ("t" "ะ") ("u" "ี") ("v" "อ") ("w" "ไ") ("x" "ป") ("y" "ั") ("z" "ผ") ("{" "ฐ") ("|" "ฅ") ("}" ",") ("~" "%"))) ;; CTRL : 0000..0020, 007F..009F ;; NON : 0021..007E, 00A0..0E00 ;; CONS : 0E01..0E23, 0E25, 0E27..0E2E ;; LV : 0E40..0E44 ;; FV1 : 0E30, 0E32, 0E33 ;; FV2 : 0E45 ;; FV3 : 0E24, 0E26 ;; BV1 : 0E38 ;; BV2 : 0E39 ;; BD : 0E3A ;; TONE : 0E48..0E4B ;; AD1 : 0E4C, 0E4D ;; AD2 : 0E47 ;; AD3 : ;; AV1 : 0E34 ;; AV2 : 0E31, 0E36 ;; AV3 : 0E35, 0E37 (macro ;; input global variables : arg1, arg2 ;; output global variable : ret (cp (cond ((= level 0) (set ret 1)) (1 (cp12)))) ;; input global variables : arg1, arg2 ;; output global variable : ret (ac (cond ((= level 0) (set ret 1)) ((= level 1) (ac1)) (1 (ac2)))) ;; Level 1 & 2 composability (cp12 (set ret 0) (cond ;; next = BV1|BV2|BD|AD3|AV1|AV2|AV3, previous = CONS ((| (= arg2 0x0E31) (& (>= arg2 0x0E34) (<= arg2 0x0E3A)) (= arg2 0x0E4E)) (cond ((| (& (>= arg1 0x0E01) (<= arg1 0x0E23)) (= arg1 0x0E25) (& (>= arg1 0x0E27) (<= arg1 0x0E2E))) (set ret 1)))) ;; next = TONE, previous = CONS|BV1|BV2|AV1|AV2|AV3 ((& (>= arg2 0x0E48) (<= arg2 0x0E4B)) (cond ((| (& (>= arg1 0x0E01) (<= arg1 0x0E23)) (= arg1 0x0E25) (& (>= arg1 0x0E27) (<= arg1 0x0E2E)) (= arg1 0x0E31) (& (>= arg1 0x0E34) (<= arg1 0x0E39))) (set ret 1)))) ;; next = AD1, previous = CONS|BV1|AV1 ((& (>= arg2 0x0E4C) (<= arg2 0x0E4D)) (cond ((| (& (>= arg1 0x0E01) (<= arg1 0x0E23)) (= arg1 0x0E25) (& (>= arg1 0x0E27) (<= arg1 0x0E2E)) (= arg1 0x0E38) (= arg1 0x0E34)) (set ret 1)))) ;; next = AD2, previous = TONE| AV3 ((= arg2 0x0E47) (cond ((| (& (>= arg1 0x0E01) (<= arg1 0x0E23)) (= arg1 0x0E25) (& (>= arg1 0x0E27) (<= arg1 0x0E2E)) (= arg1 0x0E35) (= arg1 0x0E37)) (set ret 1)))))) ;; Level 1 acceptance (ac1 (set ret 1) (cond ((| (= arg2 0x0E31) (& (>= arg2 0x0E34) (<= arg2 0x0E3A)) (& (>= arg2 0x0E47) (<= arg2 0x0E4E))) (set ret 0)))) ;; Level 2 acceptance (ac2 (set ret 0) (cond ;; next = CTRL|CONS, previous = * ((| (<= arg2 0x001F) (& (>= arg2 0x0080) (<= arg2 0x009F)) (& (>= arg2 0x0E01) (<= arg2 0x0E23)) (= arg2 0x0E25) (& (>= arg2 0x0E27) (<= arg2 0x0E2E))) (set ret 1)) ;; next = NON|LV, previous = ~LV, ((| (& (>= arg2 0x0020) (<= arg2 0x007E)) (& (>= arg2 0x00A0) (<= arg2 0x0E00)) (= arg2 0x0E2F) (& (>= arg2 0x0E3F) (<= arg2 0x0E44)) (= arg2 0x0E46) (> arg2 0x0E4E)) (cond ((| (< arg1 0x0E40) (> arg1 0x0E44)) (set ret 1)))) ;; next = FV1, previous = CONS|FV1|FV2|BV1|TONE ((| (= arg2 0x0E30) (= arg2 0x0E32) (= arg2 0x0E33)) (cond ((| (& (>= arg1 0x0E01) (<= arg1 0x0E23)) (= arg1 0x0E25) (& (>= arg1 0x0E27) (<= arg1 0x0E2E)) (= arg1 0x0E30) (= arg1 0x0E32) (= arg1 0x0E33) (= arg1 0x0E45) (= arg1 0x0E38) (& (>= arg1 0x0E48) (<= arg1 0x0E4B))) (set ret 1)))) ;; next = FV2, previous = FV3|TONE ((= arg2 0x0E45) (cond ((| (= arg1 0x0E24) (= arg1 0x0E26) (& (>= arg1 0x0E48) (<= arg1 0x0E4B))) (set ret 1)))) ;; next = FV3, previous = ~LV~FV3 ((| (= arg2 0x0E24) (= arg2 0x0E26)) (cond ((& (| (< arg1 0x0E40) (> arg1 0x0E44)) (! (= arg1 0x0E24)) (! (= arg1 0x0E26))) (set ret 1))))))) (state (init (map (delete @<) (pushback 1) (shift main))) (main (map (set x @-3) (set y @-2) (set z @-1) (set arg1 y) (set arg2 z) (cp) (cond ((= ret 1)) ;; CP(y,z) succeeded. (1 (ac) (cond ((= ret 1)) ;; AC(y,z) succeeded. (1 ;; WTT-based input sequence correction starts here. ;; begin ;; if CP(x,z) then (set arg1 x) (set arg2 z) (cp) (cond ((= ret 1) ;; if CP(z,y) then (set arg1 z) (set arg2 y) (cp) (cond ((= ret 1) ;; reorder(y -> zy) (delete @-2) (insert z) (insert y)) ;; elif CP(x,y) then (1 (set arg1 x) (set arg2 y) (cp) (cond ((= ret 1) ;; replace(y -> z) (delete @-2) (insert z)) ;; elif y is FV1 and z is TONE then ((& (| (= y 0x0E30) (= y 0x0E32) (= y 0x0E33)) (>= z 0x0E48) (<= z 0x0E4B)) ;; reorder(y -> zy) (delete @-2) (insert z) (insert y)) ;; else ;; reject(z) (1 (delete @-1)) ;;endif )))) ;; elif AC(x,z) then (1 (set arg1 x) (set arg2 z) (ac) (cond ((& (= ret 1) ;; Only Thai characters should be replaced. (& (>= y 0x0E01) (<= y 0x0E5B)) (& (>= z 0x0E01) (<= z 0x0E5B))) ;; replace(y -> z) (delete @-2) (insert z)) ;; else ;; reject(z) (1 (delete @-1)) ;; endif ))) ;; end )))) ;; Now we commit the preedit chars that are fixed. (set w @-1) (cond ;; If surrounding text is supported, commit the only char in preedit. ((> @-0 -2) (commit)) ;; If the last char is CTRL or NON, we can commit everything. ((| (& (>= w 0x0000) (<= w 0x0E00)) (= w 0x0E2F) (= w 0x0E3F) (= w 0x0E46) (>= w 0x0E4F)) (commit)) ;; If the last char is CONS, we can commit everything but the last ;; unless the second last is FV3. ((| (& (>= w 0x0E01) (<= w 0x0E23)) (= w 0x0E25) (& (>= w 0x0E27) (<= w 0x0E2E))) (cond ((| (= @-2 0x0E24) (= @-2 0x0E26)) ; not commit yet ) (1 (delete @-1) (commit) (insert w)))) ;; If the last char is LV, FV2 or FV3, we can commit ;; everything but the last. ((| (& (>= w 0x0E40) (<= w 0x0E45)) (= w 0x0E24) (= w 0x0E26)) (delete @-1) (commit) (insert w)) ;; If the last char is FV1 (excluding AM) and ... ((| (= w 0x0E30) (= w 0x0E32)) (delete @-1) (set v @-1) (cond ;; ... the before last is CONS, we can commit other than the ;; last two. ((| (& (>= v 0x0E01) (<= v 0x0E23)) (= v 0x0E25) (& (>= v 0x0E27) (<= v 0x0E2E))) (delete @-1) (commit) (insert v) (insert w)) ;; ... else if the before last is not CONS, we can commit ;; everything but the last. (1 (commit) (insert w)))) )))) ;; Local Variables: ;; coding: utf-8 ;; mode: emacs-lisp ;; End: