File: //usr/share/m17n/th-kesmanee.mim
;; th-kesmanee.mim -- Thai input method with Kesmanee keyboard layout
;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
;; 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
<http://linux.thai.net/~thep/th-xim/>
")
(title "ท")
(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))
(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)))))))
(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
(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: