changeset 26881:cd1cb9bf30e1

Rewritten for new composition.
author Kenichi Handa <handa@m17n.org>
date Wed, 15 Dec 1999 00:32:16 +0000
parents 98564c5250e4
children 5b331ff3b477
files leim/quail/lao.el leim/quail/lrt.el leim/quail/thai.el leim/quail/tibetan.el
diffstat 4 files changed, 497 insertions(+), 1274 deletions(-) [+]
line wrap: on
line diff
--- a/leim/quail/lao.el	Wed Dec 15 00:28:11 1999 +0000
+++ b/leim/quail/lao.el	Wed Dec 15 00:32:16 1999 +0000
@@ -27,240 +27,172 @@
 (require 'quail)
 (require 'lao-util)
 
-(eval-and-compile
-
-(defconst lao-keyboard-mapping
-  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0	; control codes
-   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0	; control codes
-   0 "1" "=" "3" "4" "(1l(B" "5" "(1'(B"          ; SPC .. '
-   "7" "8" "6" "(1mh(B" "(1A(B" "(1*(B" "(1c(B" "(1=(B"	; ( .. /
-   "(1"(B" "(1B(B" "(1?(B" "(1b(B" "(16(B" "(1X(B" "(1Y(B" "(1$(B"	; 0 .. 7
-   "(15(B" "(1((B" "%" "(1G(B" "(1}(B" "(1m(B" "$" "\)"	; 8 .. ?
-   "2" "(1Qi(B" "(1Vi(B" "(1O(B" "." "(1Si(B" "," ":"	; @ .. G
-   "(1j(B" "(1N(B" "(1k(B" "!" "?" "(1f(B" "(1Wi(B" "(1|(B" 	; H .. O
-   "(1](B" "(1[i(B" "_" ";" "+" "(1Ui(B" "x" "0"	; P .. W
-   "\(" "(1Ti(B" "\"" "(1:(B" 0 "(1E(B" "(1\(B" "9"     ; X .. _
-   "(1'(B" "(1Q(B" "(1V(B" "(1a(B" "(1!(B" "(1S(B" "(14(B" "(1`(B"	; ` .. g
-   "(1i(B" "(1C(B" "(1h(B" "(1R(B" "(1J(B" "(17(B" "(1W(B" "(19(B"	; h .. o
-   "(1-(B" "(1[(B" "(1>(B" "(1K(B" "(1P(B" "(1U(B" "(1M(B" "(1d(B"	; p .. w
-   "(1;(B" "(1T(B" "(1<(B" "-" "(1K\(B" "/" "~" 0]    	; x .. DEL
-  "A table which maps ASCII key codes to corresponding Lao characters."
-  )
-
-)
-
-;; Template of a cdr part of a Quail map when a consonant is entered.
-(defvar lao-consonant-alist nil)
-;; Template of a cdr part of a Quail map when a vowel upper is entered.
-(defvar lao-vowel-upper-alist nil)
-;; Template of a cdr part of a Quail map when a vowel lower is entered.
-(defvar lao-vowel-lower-alist nil)
-;; Template of a cdr part of a Quail map when a semivowel lower is entered.
-(defvar lao-semivowel-lower-alist nil)
+(defun quail-lao-update-translation (control-flag)
+  (if (integerp control-flag)
+      ;; Non-composable character typed.
+      (setq quail-current-str
+	    (buffer-substring (overlay-start quail-overlay)
+			      (overlay-end quail-overlay))
+	    unread-command-events
+	    (string-to-list
+	     (substring quail-current-key control-flag)))
+    (setq quail-current-str
+	  (compose-string (quail-lookup-map-and-concat quail-current-key))))
+  control-flag)
 
-;; Return a Quail map corresponding to KEY of length LEN.
-;; The car part of the map is a translation generated automatically.
-;; The cdr part of the map is a copy of ALIST.
-(defun lao-generate-quail-map (key len alist)
-  (let ((str "")
-	(idx 0))
-    (while (< idx len)
-      (setq str (concat str (aref lao-keyboard-mapping (aref key idx)))
-	    idx (1+ idx)))
-    (cons (string-to-char (compose-string str)) (copy-alist alist))))
-
-;; Return a Quail map corresponding to KEY of length LEN when Lao
-;; tone mark is entered.
-(defun lao-tone-input (key len)
-  (lao-generate-quail-map key len nil))
+(defconst lao-key-alist
+  '(("!" . "1")
+    ("\"" . "=")
+    ("#" . "3")
+    ("$" . "4")
+    ("&" . "5")
+    ("%" . "(1l(B")
+    ("'" . "(1'(B")
+    ("(" . "7")
+    (")" . "8")
+    ("*" . "6")
+    ("+" . ["(1mh(B"])
+    ("," . "(1A(B")
+    ("-" . "(1*(B")
+    ("." . "(1c(B")
+    ("/" . "(1=(B")
+    ("0" . "(1"(B")
+    ("1" . "(1B(B")
+    ("2" . "(1?(B")
+    ("3" . "(1b(B")
+    ("4" . "(16(B")
+    ("5" . "(1X(B")
+    ("6" . "(1Y(B")
+    ("7" . "(1$(B")
+    ("8" . "(15(B")
+    ("9" . "(1((B")
+    (":" . "%")
+    (";" . "(1G(B")
+    ("<" . "(1}(B")
+    ("=" . "(1m(B")
+    (">" . "$")
+    ("?" . ")")
+    ("@" . "2")
+    ("A" . ["(1Qi(B"])
+    ("B" . ["(1Vi(B"])
+    ("C" . "(1O(B")
+    ("D" . ".")
+    ("E" . ["(1Si(B"])
+    ("F" . ",")
+    ("G" . ":")
+    ("H" . "(1j(B")
+    ("I" . "(1N(B")
+    ("J" . "(1k(B")
+    ("K" . "!")
+    ("L" . "?")
+    ("M" . "(1f(B")
+    ("N" . ["(1Wi(B"])
+    ("O" . "(1|(B")
+    ("P" . "(1](B")
+    ("Q" . ["(1[i(B"])
+    ("R" . "_")
+    ("S" . ";")
+    ("T" . "+")
+    ("U" . ["(1Ui(B"])
+    ("V" . "x")
+    ("W" . "0")
+    ("X" . "(")
+    ("Y" . ["(1Ti(B"])
+    ("Z" . "\"")
+    ("[" . "(1:(B")
+    ("]" . "(1E(B")
+    ("^" . "(1\(B")
+    ("_" . "9")
+    ("`" . "(1'(B")
+    ("a" . "(1Q(B")
+    ("b" . "(1V(B")
+    ("c" . "(1a(B")
+    ("d" . "(1!(B")
+    ("e" . "(1S(B")
+    ("f" . "(14(B")
+    ("g" . "(1`(B")
+    ("h" . "(1i(B")
+    ("i" . "(1C(B")
+    ("j" . "(1h(B")
+    ("k" . "(1R(B")
+    ("l" . "(1J(B")
+    ("m" . "(17(B")
+    ("n" . "(1W(B")
+    ("o" . "(19(B")
+    ("p" . "(1-(B")
+    ("q" . "(1[(B")
+    ("r" . "(1>(B")
+    ("s" . "(1K(B")
+    ("t" . "(1P(B")
+    ("u" . "(1U(B")
+    ("v" . "(1M(B")
+    ("w" . "(1d(B")
+    ("x" . "(1;(B")
+    ("y" . "(1T(B")
+    ("z" . "(1<(B")
+    ("{" . "-")
+    ("|" . ["(1K\(B"])
+    ("}" . "/")
+    ("~" . "(1l(B")
+    ("\\0" . "(1p(B")
+    ("\\1" . "(1q(B")
+    ("\\2" . "(1r(B")
+    ("\\3" . "(1s(B")
+    ("\\4" . "(1t(B")
+    ("\\5" . "(1u(B")
+    ("\\6" . "(1v(B")
+    ("\\7" . "(1w(B")
+    ("\\8" . "(1x(B")
+    ("\\9" . "(1y(B")
+    ))
 
-;; Return a Quail map corresponding to KEY of length LEN when Lao
-;; vowel upper is entered.
-(defun lao-vowel-upper-input (key len)
-  (lao-generate-quail-map key len lao-vowel-upper-alist))
-
-;; Return a Quail map corresponding to KEY of length LEN when Lao
-;; vowel lower is entered.
-(defun lao-vowel-lower-input (key len)
-  (lao-generate-quail-map key len lao-vowel-lower-alist))
+(defconst lao-consonant-key-alist nil)
+(defconst lao-semivowel-key-alist nil)
+(defconst lao-vowel-key-alist nil)
+(defconst lao-voweltone-key-alist nil)
+(defconst lao-tone-key-alist nil)
+(defconst lao-other-key-alist nil)
 
-;; Return a Quail map corresponding to KEY of length LEN when Lao
-;; semivowel lower is entered.
-(defun lao-semivowel-lower-input (key len)
-  (lao-generate-quail-map key len lao-semivowel-lower-alist))
-
-;; Return an alist which can be a cdr part of a Quail map
-;; corresponding to the current key when Lao consonant is entered.
-(defun lao-consonant-input (key len)
-  (copy-alist lao-consonant-alist))
+(let ((tail lao-key-alist)
+      elt phonetic-type)
+  (while tail
+    (setq elt (car tail) tail (cdr tail))
+    (if (stringp (cdr elt))
+	(setq phonetic-type (get-char-code-property (aref (cdr elt) 0)
+						    'phonetic-type))
+      (setq phonetic-type (get-char-code-property (aref (aref (cdr elt) 0) 0)
+						  'phonetic-type))
+      (aset (cdr elt) 0 (compose-string (aref (cdr elt) 0))))
+    (cond ((eq phonetic-type 'consonant)
+	   (setq lao-consonant-key-alist (cons elt lao-consonant-key-alist)))
+	  ((memq phonetic-type '(vowel-upper vowel-lower))
+	   (if (stringp (cdr elt))
+	       (setq lao-vowel-key-alist (cons elt lao-vowel-key-alist))
+	     (setq lao-voweltone-key-alist
+		   (cons elt lao-voweltone-key-alist))))
+	  ((eq  phonetic-type 'tone)
+	   (setq lao-tone-key-alist (cons elt lao-tone-key-alist)))
+	  ((eq phonetic-type 'semivowel-lower)
+	   (setq lao-semivowel-key-alist (cons elt lao-semivowel-key-alist)))
+	  (t
+	   (setq lao-other-key-alist (cons elt lao-other-key-alist))))))
 
 (quail-define-package
  "lao" "Lao" "(1E(B" t
  "Lao input method simulating Lao keyboard layout based on Thai TIS620"
- nil t t t t nil nil nil nil nil t)
-
-(defmacro lao-quail-define-rules (&rest rules)
-  (let ((l rules)
-	consonant-alist
-	vowel-upper-alist
-	vowel-lower-alist
-	semivowel-lower-alist
-	rule trans ch c-set)
-    (while l
-      (setq rule (car l))
-      (setq trans (nth 1 rule))
-      (if (consp trans)
-	  (setq trans (car trans)))
-      (setq c-set (char-category-set (string-to-char trans)))
-      (cond ((aref c-set ?2)		; vowel upper
-	     (setq consonant-alist
-		   (cons (cons (string-to-char (car rule))
-			       'lao-vowel-upper-input)
-			 consonant-alist)))
-	    ((aref c-set ?3)		; vowel lower
-	     (setq consonant-alist
-		   (cons (cons (string-to-char (car rule))
-			       'lao-vowel-lower-input)
-			 consonant-alist)
-		   semivowel-lower-alist
-		   (cons (cons (string-to-char (car rule))
-			       'lao-vowel-lower-input)
-			 semivowel-lower-alist)))
-	    ((aref c-set ?4)		; tone
-	     (setq consonant-alist
-		   (cons (cons (string-to-char (car rule))
-			       'lao-tone-input)
-			 consonant-alist)
-		   vowel-upper-alist
-		   (cons (cons (string-to-char (car rule))
-			       'lao-tone-input)
-			 vowel-upper-alist)
-		   vowel-lower-alist
-		   (cons (cons (string-to-char (car rule))
-			       'lao-tone-input)
-			 vowel-lower-alist)))
-	    ((aref c-set ?9)		; semivowel lower
-	     (setq consonant-alist
-		   (cons (cons (string-to-char (car rule))
-			       'lao-semivowel-lower-input)
-			 consonant-alist)
-		   vowel-upper-alist
-		   (cons (cons (string-to-char (car rule))
-			       'lao-semivowel-lower-input)
-			 vowel-upper-alist))))
-      (setq l (cdr l)))
-    (list 'progn
-	  (cons 'quail-define-rules rules)
-	  `(setq lao-consonant-alist ',consonant-alist
-		 lao-vowel-upper-alist ',vowel-upper-alist
-		 lao-vowel-lower-alist ',vowel-lower-alist
-		 lao-semivowel-lower-alist ',semivowel-lower-alist))))
+ nil t t t t nil nil nil 'quail-lao-update-translation nil t)
 
-(lao-quail-define-rules
- ("!" "1")
- ("\"" "=")
- ("#" "3")
- ("$" "4")
- ("&" "5")
- ("%" "(1l(B")
- ("'" ("(1'(B" . lao-consonant-input))
- ("(" "7")
- (")" "8")
- ("*" "6")
- ("+" "0(1mh1(B")
- ("," ("(1A(B" . lao-consonant-input))
- ("-" ("(1*(B" . lao-consonant-input))
- ("." "(1c(B")
- ("/" ("(1=(B" . lao-consonant-input))
- ("0" ("(1"(B" . lao-consonant-input))
- ("1" ("(1B(B" . lao-consonant-input))
- ("2" ("(1?(B" . lao-consonant-input))
- ("3" "(1b(B")
- ("4" ("(16(B" . lao-consonant-input))
- ("5" "(1X(B")
- ("6" "(1Y(B")
- ("7" ("(1$(B" . lao-consonant-input))
- ("8" ("(15(B" . lao-consonant-input))
- ("9" ("(1((B" . lao-consonant-input))
- (":" "%")
- (";" ("(1G(B" . lao-consonant-input))
- ("<" ("(1}(B" . lao-consonant-input))
- ("=" "(1m(B")
- (">" "$")
- ("?" ")")
- ("@" "2")
- ("A" "0(1Qi1(B")
- ("B" "0(1Vi1(B")
- ("C" "(1O(B")
- ("D" ".")
- ("E" "0(1Si1(B")
- ("F" ",")
- ("G" ":")
- ("H" "(1j(B")
- ("I" ("(1N(B" . lao-consonant-input))
- ("J" "(1k(B")
- ("K" "!")
- ("L" "?")
- ("M" "(1f(B")
- ("N" "0(1Wi1(B")
- ("O" ("(1|(B" . lao-consonant-input))
- ("P" "(1](B")
- ("Q" "0(1[i1(B")
- ("R" "_")
- ("S" ";")
- ("T" "+")
- ("U" "0(1Ui1(B")
- ("V" "x")
- ("W" "0")
- ("X" "(")
- ("Y" "0(1Ti1(B")
- ("Z" "\"")
- ("[" ("(1:(B" . lao-consonant-input))
- ("]" ("(1E(B" . lao-consonant-input))
- ("^" "(1\(B")
- ("_" "9")
- ("`" ("(1'(B" . lao-consonant-input))
- ("a" "(1Q(B")
- ("b" "(1V(B")
- ("c" "(1a(B")
- ("d" ("(1!(B" . lao-consonant-input))
- ("e" "(1S(B")
- ("f" ("(14(B" . lao-consonant-input))
- ("g" "(1`(B")
- ("h" "(1i(B")
- ("i" ("(1C(B" . lao-consonant-input))
- ("j" "(1h(B")
- ("k" "(1R(B")
- ("l" ("(1J(B" . lao-consonant-input))
- ("m" ("(17(B" . lao-consonant-input))
- ("n" "(1W(B")
- ("o" ("(19(B" . lao-consonant-input))
- ("p" ("(1-(B" . lao-consonant-input))
- ("q" "(1[(B")
- ("r" ("(1>(B" . lao-consonant-input))
- ("s" ("(1K(B" . lao-consonant-input))
- ("t" "(1P(B")
- ("u" "(1U(B")
- ("v" ("(1M(B" . lao-consonant-input))
- ("w" "(1d(B")
- ("x" ("(1;(B" . lao-consonant-input))
- ("y" "(1T(B")
- ("z" ("(1<(B" . lao-consonant-input))
- ("{" "-")
- ("|" ("0(1K\1(B" . lao-consonant-input))
- ("}" "/")
- ("~" "(1l(B")
- ("\\0" "(1p(B")
- ("\\1" "(1q(B")
- ("\\2" "(1r(B")
- ("\\3" "(1s(B")
- ("\\4" "(1t(B")
- ("\\5" "(1u(B")
- ("\\6" "(1v(B")
- ("\\7" "(1w(B")
- ("\\8" "(1x(B")
- ("\\9" "(1y(B")
- )
-
+(quail-install-map
+ (quail-map-from-table
+  '((base-state (lao-consonant-key-alist . svt-state)
+		lao-vowel-key-alist
+		lao-voweltone-key-alist
+		lao-tone-key-alist
+		lao-other-key-alist)
+    (svt-state (lao-semivowel-key-alist . v-state)
+	      (lao-vowel-key-alist . t-state)
+	      lao-voweltone-key-alist)
+    (v-state (lao-vowel-key-alist . t-state))
+    (t-state lao-tone-key-alist))))
 
 ;;; quail/lao.el ends here
--- a/leim/quail/lrt.el	Wed Dec 15 00:28:11 1999 +0000
+++ b/leim/quail/lrt.el	Wed Dec 15 00:32:16 1999 +0000
@@ -31,353 +31,22 @@
 ;; key sequence:
 ;;	consonant [+ semi-vowel-sign-lo ] + vowel [+ maa-sakod ] [+ tone-mark ]
 
-(eval-and-compile
-
-;; Upper vowels and tone-marks are put on the letter.
-;; Semi-vowel-sign-lo and lower vowels are put under the letter.
-(defconst lrt-single-consonant-table
-  `(("k" . ?(1!(B)
-    ("kh" . ?(1"(B)
-    ("qh" . ?(1$(B)
-    ("ng" . ?(1'(B)
-    ("j" . ?(1((B)
-    ("s" . ?(1J(B)
-    ("x" . ?(1*(B)
-    ("y" . ?(1-(B)
-    ("d" . ?(14(B)
-    ("t" . ?(15(B)
-    ("th" . ?(16(B)
-    ("dh" . ?(17(B)
-    ("n" . ?(19(B)
-    ("b" . ?(1:(B)
-    ("p" . ?(1;(B)
-    ("hp" . ?(1<(B)
-    ("fh" . ?(1=(B)
-    ("ph" . ?(1>(B)
-    ("f" . ?(1?(B)
-    ("m" . ?(1A(B)
-    ("gn" . ?(1B(B)
-    ("l" . ?(1E(B)
-    ("r" . ?(1C(B)
-    ("v" . ?(1G(B)
-    ("w" . ?(1G(B)
-    ("hh" . ?(1K(B)
-    ("O" . ?(1M(B)
-    ("h" . ?(1N(B)
-    ("nh" . ?(1|(B)
-    ("mh" . ?(1}(B)
-    ("lh" . "0(1K\(B1")
-    ))
-
-;; Semi-vowel-sign-lo is put under the first letter.
-;; Lower vowels are put under the last letter.
-;; Upper vowels and tone-marks are put on the last letter.
-(defconst lrt-double-consonant-table
-  '(("ngh" . "(1K'(B")
-    ("yh" . "(1K](B")
-    ("wh" . "(1KG(B")
-    ("hl" . "(1KE(B")
-    ("hy" . "(1K-(B")         
-    ("hn" . "(1K9(B")
-    ("hm" . "(1KA(B")
-    ))
-
-(defconst lrt-semi-vowel-sign-lo
-  '("r" . ?(1\(B))
-
-(defconst lrt-vowel-table
-  '(("a" "(1P(B" (0 ?(1P(B) (0 ?(1Q(B))
-    ("ar" "(1R(B" (0 ?(1R(B))
-    ("i" "(1T(B" (0 ?(1T(B))
-    ("ii" "(1U(B" (0 ?(1U(B))
-    ("eu" "(1V(B" (0 ?(1V(B))
-    ("ur" "(1W(B" (0 ?(1W(B))
-    ("u" "(1X(B" (0 ?(1X(B))
-    ("uu" "(1Y(B" (0 ?(1Y(B))
-    ("e" "(1`(B (1P(B" (?(1`(B 0 ?(1P(B) (?(1`(B 0 ?(1Q(B))
-    ("ee" "(1`(B" (?(1`(B 0))
-    ("ae" "(1a(B (1P(B" (?(1a(B 0 ?(1P(B) (?(1a(B 0 ?(1Q(B))
-    ("aa" "(1a(B" (?(1a(B 0))
-    ("o" "(1b(B (1P(B" (?(1b(B 0 ?(1P(B) (0 ?(1[(B) (?(1-(B ?(1b(B 0 ?(1Q(B) (?(1G(B ?(1b(B 0 ?(1Q(B))
-    ("oo" "(1b(B" (?(1b(B 0))
-    ("oe" "(1`(B (1RP(B" (?(1`(B 0 ?(1R(B ?(1P(B) (0 ?(1Q(B ?(1M(B))
-    ("or" "(1m(B" (0 ?(1m(B) (0 ?(1M(B))
-    ("er" "(1`(B (1T(B" (?(1`(B 0 ?(1T(B))
-    ("ir" "(1`(B (1U(B" (?(1`(B 0 ?(1U(B))
-    ("ua" "(1[GP(B" (0 ?(1[(B ?(1G(B ?(1P(B) (0 ?(1Q(B ?(1G(B))
-    ("uaa" "(1[G(B" (0 ?(1[(B ?(1G(B) (0 ?(1G(B))
-    ("ie" "(1`Q]P(B" (?(1`(B 0 ?(1Q(B ?(1](B ?(1P(B) (0 ?(1Q(B ?(1](B))
-    ("ia" "(1`Q](B" (?(1`(B 0 ?(1Q(B ?(1](B) (0 ?(1](B))
-    ("ea" "(1`VM(B" (?(1`(B 0 ?(1V(B ?(1M(B))
-    ("eaa" "(1`WM(B" (?(1`(B 0 ?(1W(B ?(1M(B))
-    ("ai" "(1d(B" (?(1d(B 0))
-    ("ei" "(1c(B" (?(1c(B 0))
-    ("ao" "(1`[R(B" (?(1`(B 0 ?(1[(B ?(1R(B))
-    ("aM" "(1S(B" (0 ?(1S(B))))
-
-;; Maa-sakod is put at the tail.
-(defconst lrt-maa-sakod-table
-  '((?k . ?(1!(B)
-    (?g . ?(1'(B)
-    (?y . ?(1-(B)
-    (?d . ?(14(B)
-    (?n . ?(19(B)
-    (?b . ?(1:(B)
-    (?m . ?(1A(B)
-    (?v . ?(1G(B)
-    (?w . ?(1G(B)
-    ))
-
-(defconst lrt-tone-mark-table
-  '(("'" . ?(1h(B)
-    ("\"" . ?(1i(B)
-    ("^" . ?(1j(B)
-    ("+" . ?(1k(B)
-    ("~" . ?(1l(B)))
-
-;; Return list of composing patterns for normal (without maa-sakod)
-;; key sequence and with-maa-sakod key sequence starting with single
-;; consonant C and optional SEMI-VOWEL.
-(defun lrt-composing-pattern-single-c (c semi-vowel vowel-pattern)
-  (let* ((patterns (copy-sequence vowel-pattern))
-	 (tail patterns)
-	 place)
-    ;; Embed C and SEMI-VOWEL (if any) at the place of 0.
-    (while tail
-      ;; At first, make a copy.
-      (setcar tail (copy-sequence (car tail)))
-      ;; Then, do embedding.
-      (setq place (memq 0 (car tail)))
-      (setcar place c)
-      (if semi-vowel
-	  (setcdr place (cons semi-vowel (cdr place))))
-      (setq tail (cdr tail)))
-    patterns))
-
-;; Return list of composing patterns for normal (without maa-sakod)
-;; key sequence and with-maa-sakod key sequence starting with double
-;; consonant STR and optional SEMI-VOWEL.
-(defun lrt-composing-pattern-double-c (str semi-vowel vowel-pattern)
-  (let* ((patterns (copy-sequence vowel-pattern))
-	 (tail patterns)
-	 (chars (string-to-list
-		 (if (= (length str) 1)
-		     (decompose-string str)
-		   str)))
-	 place)
-    ;; Embed C and SEMI-VOWEL (if any) at the place of 0.
-    (while tail
-      ;; At first, make a copy.
-      (setcar tail (copy-sequence (car tail)))
-      ;; Then, do embedding.
-      (setq place (memq 0 (car tail)))
-      (setcar place (car chars))
-      (setcdr place (cons (nth 1 chars) (cdr place)))
-      (if semi-vowel
-	  ;; Embed SEMI-VOWEL in between CHARS.
-	  (setcdr place (cons semi-vowel (cdr place))))
-      (setq tail (cdr tail)))
-    patterns))
-
-;; Return a string made of characters in CHAR-LIST while composing
-;; such characters as vowel-upper, vowel-lower, semi-vowel(lower),
-;; and tone-mark with the preceding base character.
-(defun lrt-compose-string (char-list)
-  ;; Make a copy because the following work alters it.
-  (setq char-list (copy-sequence char-list))
-  (let ((i -1)
-	(l char-list))
-    (while l
-      (if (memq (get-char-code-property (car l) 'phonetic-type)
-		'(vowel-upper vowel-lower semivowel-lower tone))
-	  (let (composed-char)
-	    (if (< i 0)
-		;; No preceding base character.
-		(error "Invalid CHAR-LIST: %s" char-list))
-	    (setq composed-char
-		  (string-to-char (compose-chars (nth i char-list) (car l))))
-	    (setcar (nthcdr i char-list) composed-char)
-	    (setq l (cdr l))
-	    (setcdr (nthcdr i char-list) l))
-	(setq l (cdr l))
-	(setq i (1+ i))))
-    (concat (apply 'vector char-list))))
+(defun quail-lao-update-translation (control-flag)
+  (if (integerp control-flag)
+      ;; Non-composable character typed.
+      (setq quail-current-str
+	    (buffer-substring (overlay-start quail-overlay)
+			      (overlay-end quail-overlay))
+	    unread-command-events
+	    (string-to-list
+	     (substring quail-current-key control-flag)))
+    (let ((lao-str (lao-transcribe-roman-to-lao-string quail-current-key)))
+      (if (> (aref lao-str 0) 255)
+	  (setq quail-current-str lao-str)
+	(or quail-current-str
+	    (setq quail-current-str quail-current-key)))))
+  control-flag)
 
-(defun lrt-compose-c-s-v (consonant semi-vowel vowel-pattern)
-  (let ((pattern-list
-	 (if (integerp consonant)
-	     (lrt-composing-pattern-single-c
-	      consonant semi-vowel vowel-pattern)
-	   (lrt-composing-pattern-double-c
-	    consonant semi-vowel vowel-pattern))))
-    (cons (vector (lrt-compose-string (car pattern-list)))
-	  (cons t pattern-list))))
-
-)
-
-(defun lrt-handle-maa-sakod ()
-  (interactive)
-  (if (or (= (length quail-current-key) 0)
-	  (not quail-current-data))
-      (quail-self-insert-command)
-    (if (not (car quail-current-data))
-	(progn
-	  (setq quail-current-data nil)
-	  (setq unread-command-events
-		(cons last-command-event unread-command-events))
-	  (quail-terminate-translation))
-      (if (not (integerp last-command-event))
-	  (error "Bogus calling sequence"))
-      (let* ((maa-sakod (cdr (assq last-command-event lrt-maa-sakod-table)))
-	     (maa-sakod-pattern (append
-				 (or (cdr (assq maa-sakod
-						(nthcdr 3 quail-current-data)))
-				     (nth 2 quail-current-data)
-				     (nth 1 quail-current-data))
-				 (list maa-sakod))))
-	(quail-delete-region)
-	(setq quail-current-str (lrt-compose-string maa-sakod-pattern))
-	(insert quail-current-str)
-	(quail-show-translations)
-	(setq quail-current-data (list nil maa-sakod-pattern))))))
-
-(defun lrt-handle-tone-mark ()
-  (interactive)
-  (if (= (length quail-current-key) 0)
-      (quail-self-insert-command)
-    (if (not quail-current-data)
-	(progn
-	  (setq unread-command-events
-		(cons last-command-event unread-command-events))
-	  (quail-terminate-translation))
-      (if (not (integerp last-command-event))
-	  (error "Bogus calling sequence"))
-      (let* ((tone-mark (cdr (assoc (char-to-string last-command-event)
-				    lrt-tone-mark-table)))
-	     (tone-mark-pattern
-	      (if (car quail-current-data)
-		  (copy-sequence (nth 1 quail-current-data))
-		;; No need of copy because lrt-handle-maa-sakod should
-		;; have already done it.
-		(nth 1 quail-current-data)))
-	     (tail tone-mark-pattern)
-	     (double-consonant-keys lrt-double-consonant-table)
-	     (double-consonant-flag nil)
-	     place)
-
-	;; Set DOUBLE-CONSONANT-FLAG to t if a user entered a double
-	;; consonant.
-	(while (and double-consonant-keys (not double-consonant-flag))
-	  (setq double-consonant-flag
-		(eq (string-match (car (car double-consonant-keys))
-				  quail-current-key)
-		    0)
-		double-consonant-keys (cdr double-consonant-keys)))
-
-	;; Find a place to embed TONE-MARK.  It should be after a
-	;; single or double consonant and following upper or lower vowels.
-	(while (and tail (not place))
-	  (if (and
-	       (eq (get-char-code-property (car tail) 'phonetic-type)
-		   'consonant)
-	       ;; Skip `(1K(B' if it is the first letter of double consonant.
-	       (or (not double-consonant-flag)
-		   (/= (car tail) ?(1K(B)))
-	      (progn
-		(setq place tail)
-		(setq tail (cdr tail))
-		(while (and tail
-			    (memq (get-char-code-property (car tail)
-							  'phonetic-type)
-				  '(vowel-upper vowel-lower semivowel-lower)))
-		  (setq place tail tail (cdr tail))))
-	    (setq tail (cdr tail))))
-	;; Embed TONE-MARK.
-	(setcdr place (cons tone-mark (cdr place)))
-	(quail-delete-region)
-	(insert (lrt-compose-string tone-mark-pattern))
-	(setq quail-current-data nil)
-	(quail-terminate-translation)))))
-
-(defmacro lrt-generate-quail-map ()
-  `(quail-install-map
-    ',(let ((map (list nil))
-	    (semi-vowel-key (car lrt-semi-vowel-sign-lo))
-	    (semi-vowel-char (cdr lrt-semi-vowel-sign-lo))
-	    l1 e1 l2 e2 pattern key)
-	;; Single consonants.
-	(setq l1 lrt-single-consonant-table)
-	(while l1
-	  (setq e1 (car l1))
-	  (quail-defrule-internal (car e1) (vector (cdr e1)) map)
-	  (quail-defrule-internal
-	   (concat (car e1) semi-vowel-key)
-	   (if (stringp (cdr e1))
-	       (compose-string (format "%s%c" (cdr e1) semi-vowel-char))
-	     (compose-string (format "%c%c" (cdr e1) semi-vowel-char)))
-	   map)
-	  (setq l2 lrt-vowel-table)
-	  (while l2
-	    (setq e2 (car l2))
-	    (setq key (concat (car e1) (car e2))
-		  pattern (lrt-compose-c-s-v (cdr e1) nil (nthcdr 2 e2)))
-	    (quail-defrule-internal key pattern map)
-	    (quail-defrule-internal
-	     (concat key " ")
-	     (vector (concat (aref (car pattern) 0) " "))  map)
-	    (setq key (concat (car e1) semi-vowel-key (car e2))
-		  pattern (lrt-compose-c-s-v (cdr e1) semi-vowel-char
-					     (nthcdr 2 e2)))
-	    (quail-defrule-internal key pattern map)
-	    (quail-defrule-internal
-	     (concat key " ")
-	     (vector (concat (aref (car pattern) 0) " "))  map)
-	    (setq l2 (cdr l2)))
-	  (setq l1 (cdr l1)))
-
-	;; Double consonants.
-	(setq l1 lrt-double-consonant-table)
-	(while l1
-	  (setq e1 (car l1))
-	  (quail-defrule-internal (car e1) (vector (cdr e1)) map)
-	  (quail-defrule-internal
-	   (concat (car e1) semi-vowel-key)
-	   (vector (concat (compose-string
-			    (format "%c%c" (aref (cdr e1) 0) semi-vowel-char))
-			   (substring (cdr e1) 1)))
-	   map)
-	  (setq l2 lrt-vowel-table)
-	  (while l2
-	    (setq e2 (car l2))
-	    (setq key (concat (car e1) (car e2))
-		  pattern (lrt-compose-c-s-v (cdr e1) nil (nthcdr 2 e2)))
-	    (quail-defrule-internal key pattern map)
-	    (quail-defrule-internal
-	     (concat key " ")
-	     (vector (concat (aref (car pattern) 0) " "))  map)
-	    (setq key (concat (car e1) semi-vowel-key (car e2))
-		  pattern (lrt-compose-c-s-v (cdr e1) semi-vowel-char
-					     (nthcdr 2 e2)))
-	    (quail-defrule-internal key pattern map)
-	    (quail-defrule-internal
-	     (concat key " ")
-	     (vector (concat (aref (car pattern) 0) " "))  map)
-	    (setq l2 (cdr l2)))
-	  (setq l1 (cdr l1)))
-
-	;; Vowels.
-	(setq l1 lrt-vowel-table)
-	(while l1
-	  (setq e1 (car l1) l1 (cdr l1))
-	  (quail-defrule-internal (car e1) (vector (nth 1 e1)) map))
-
-	;; Tone-marks.
-	(setq l1 lrt-tone-mark-table)
-	(while l1
-	  (setq e1 (car l1) l1 (cdr l1))
-	  (quail-defrule-internal (car e1) (cdr e1) map))
-
-	map)))
 
 (quail-define-package
  "lao-lrt" "Lao" "(1E(BR" t
@@ -386,38 +55,23 @@
 `\\' (backslash) + `\\'		=> (1f(B		LAO KO LA (REPETITION)
 `\\' (backslash) + `$'		=> (1O(B		LAO ELLIPSIS
 "
- '(("k" . lrt-handle-maa-sakod)
-   ("g" . lrt-handle-maa-sakod)
-   ("y" . lrt-handle-maa-sakod)
-   ("d" . lrt-handle-maa-sakod)
-   ("n" . lrt-handle-maa-sakod)
-   ("b" . lrt-handle-maa-sakod)
-   ("m" . lrt-handle-maa-sakod)
-   ("v" . lrt-handle-maa-sakod)
-   ("w" . lrt-handle-maa-sakod)
-   ("'" . lrt-handle-tone-mark)
-   ("\"" . lrt-handle-tone-mark)
-   ("^" . lrt-handle-tone-mark)
-   ("+" . lrt-handle-tone-mark)
-   ("~" . lrt-handle-tone-mark))
- 'forget-last-selection 'deterministic 'kbd-translate 'show-layout
-  nil nil nil nil nil t)
+ nil 'forget-last-selection 'deterministic 'kbd-translate 'show-layout
+  nil nil nil 'quail-lao-update-translation nil t)
+
+;; LRT (Lao Roman Transcription) input method accepts the following
+;; key sequence:
+;;	consonant [ semi-vowel-sign-lo ] vowel [ maa-sakod ] [ tone-mark ]
 
-(lrt-generate-quail-map)
-
-;; Additional key definitions for Lao digits.
-
-(quail-defrule "\\0" ?(1p(B)
-(quail-defrule "\\1" ?(1q(B)
-(quail-defrule "\\2" ?(1r(B)
-(quail-defrule "\\3" ?(1s(B)
-(quail-defrule "\\4" ?(1t(B)
-(quail-defrule "\\5" ?(1u(B)
-(quail-defrule "\\6" ?(1v(B)
-(quail-defrule "\\7" ?(1w(B)
-(quail-defrule "\\8" ?(1x(B)
-(quail-defrule "\\9" ?(1y(B)
-(quail-defrule "\\\\" ?(1f(B)
-(quail-defrule "\\$" ?(1O(B)
+(quail-install-map
+ (quail-map-from-table
+  '((base-state (lao-transcription-consonant-alist . sv-state)
+		lao-transcription-vowel-alist
+		lao-transcription-tone-alist)
+    (sv-state (lao-transcription-semi-vowel-alist . v-state) 
+	      (lao-transcription-vowel-alist . mt-state))
+    (v-state (lao-transcription-vowel-alist . mt-state))
+    (mt-state (lao-transcription-maa-sakod-alist . t-state) 
+	      lao-transcription-tone-alist)
+    (t-state lao-transcription-tone-alist))))
 
 ;;; quail/lrt.el ends here
--- a/leim/quail/thai.el	Wed Dec 15 00:28:11 1999 +0000
+++ b/leim/quail/thai.el	Wed Dec 15 00:32:16 1999 +0000
@@ -27,158 +27,47 @@
 (require 'quail)
 (require 'thai-util)
 
-(eval-and-compile
-
-(defvar thai-keyboard-mapping-alist
-  '((kesmanee
-     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0	; control codes
-      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0	; control codes
-      0 "#" ",TF(B" ",Tr(B" ",Ts(B" ",Tt(B" "0,TQi1(B" ",T'(B"	; SPC .. '
-      ",Tv(B" ",Tw(B" ",Tu(B" ",Ty(B" ",TA(B" ",T"(B" ",Tc(B" ",T=(B"	; ( .. /
-      ",T((B" ",TE(B" "/" "_" ",T@(B" ",T6(B" ",TX(B" ",TV(B"	; 0 .. 7
-      ",T$(B" ",T5(B" ",T+(B" ",TG(B" ",T2(B" ",T*(B" ",TL(B" ",TF(B"	; 8 .. ?
-      ",Tq(B" ",TD(B" ",TZ(B" ",T)(B" ",T/(B" ",T.(B" ",Tb(B" ",T,(B"	; @ .. G
-      ",Tg(B" ",T3(B" ",Tk(B" ",TI(B" ",TH(B" ",Tn(B" ",Tl(B" ",TO(B"	; H .. O
-      ",T-(B" ",Tp(B" ",T1(B" ",T&(B" ",T8(B" ",Tj(B" ",TN(B" "\""	; P .. W
-      ")" ",Tm(B" "(" ",T:(B" ",T_(B" ",TE(B" ",TY(B" ",Tx(B"	; X .. _
-      ",T#(B" ",T?(B" ",TT(B" ",Ta(B" ",T!(B" ",TS(B" ",T4(B" ",T`(B"	; ` .. g
-      ",Ti(B" ",TC(B" ",Th(B" ",TR(B" ",TJ(B" ",T7(B" ",TW(B" ",T9(B"	; h .. o
-      ",TB(B" ",Tf(B" ",T>(B" ",TK(B" ",TP(B" ",TU(B" ",TM(B" ",Td(B"	; p .. w
-      ",T;(B" ",TQ(B" ",T<(B" ",T0(B" ",To(B" "." ",T%(B" 0]	; x .. DEL
-     nil nil)
-
-    (pattachote
-     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0	; control codes
-      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0	; control codes
-      0 "+" ",T1(B" "/" "," "?" "_" ",T"(B"	; SPC .. '
-      "(" ")" "." "%" ",TP(B" ",Tq(B" ",T((B" ",T>(B"	; ( .. /
-      ",Tp(B" "=" ",Tr(B" ",Ts(B" ",Tt(B" ",Tu(B" ",TY(B" ",Tw(B"	; 0 .. 7
-      ",Tx(B" ",Ty(B" ",T&(B" ",Td(B" ",T?(B" ",Tv(B" ",T2(B" ",TL(B"	; 8 .. ?
-      "\"" ",Tk(B" ",TQ(B" ",T0(B" ",TS(B" ",Tf(B" ",T3(B" ",Tl(B"	; @ .. G
-      ",TW(B" ",T+(B" ",T<(B" ",T*(B" ",Tb(B" ",TN(B" ",TH(B" ",T6(B"	; H .. O
-      ",T2(B" ",Tj(B" ",T-(B" ",T8(B" ",TI(B" ",T=(B" ",T@(B" ",TD(B"	; P .. W
-      ",T.(B" ",TV(B" ",T.(B" ",Tc(B" ",TZ(B" ",T2(B" ",TX(B" "-"	; X .. _
-      ",T#(B" ",Ti(B" ",TT(B" ",TE(B" ",T'(B" ",TB(B" ",T!(B" ",TQ(B"	; ` .. g
-      ",TU(B" ",TA(B" ",TR(B" ",T9(B" ",T`(B" ",TJ(B" ",T$(B" ",TG(B"	; h .. o
-      ",Ta(B" ",Tg(B" ",TM(B" ",T7(B" ",TC(B" ",T4(B" ",TK(B" ",T5(B"	; p .. w
-      ",T;(B" ",Th(B" ",T:(B" ",TO(B" ",Tm(B" ",TF(B" ",T%(B" 0]	; x .. DEL
-     nil nil)
-    )
-  "Alist of Thai keyboard types vs. corresponding mapping tables.
-Each element is a list of:
-  KEYBOARD-TYPE, ASCII-THAI-TABLE, CONSONANT-MAP-TEMPLATE,
-  and VOWEL-UPPER-LOWER-TEMPLATE.
-
-KEYBOARD-TYPE is a symbol, one of kesmanee or pattachote.
-
-ASCII-THAI-TABLE is a vector indexed by an ASCII key code
-and the value is the one-char string of Thai character
-assigned at the location of ASCII key on the specific Thai keyboard.
-The value is 0 if no Thai character is assigned at the location.
-
-CONSONANT-MAP-TEMPLATE is a template of a cdr part of a Quail map when
-a consonant is entered.
-
-VOWEL-UPPER-LOWER-TEMPLATE is a template of a cdr part of a Quail map
-when a vowel upper or a vowel lower is entered.")
-
-(defmacro thai-keyboard-info (keyboard-type)
-  `(assq ,keyboard-type thai-keyboard-mapping-alist))
-
-)
-
-(defvar thai-current-keyboard-type nil
-  "Thai Keyboard type which Quail is assuming currently.
-This variable is used in Quail internally only.")
-
-;; Template of a cdr part of a Quail map when a consonant is entered.
-(defvar thai-consonant-alist nil)
-;; Template of a cdr part of a Quail map when a vowel upper or a vowel
-;; lower is entered.
-(defvar thai-vowel-upper-lower-alist nil)
+(defun quail-thai-update-translation (control-flag)
+  (if (integerp control-flag)
+      ;; Non-composable character typed.
+      (setq quail-current-str
+	    (buffer-substring (overlay-start quail-overlay)
+			      (overlay-end quail-overlay))
+	    unread-command-events
+	    (string-to-list
+	     (substring quail-current-key control-flag)))
+    (setq quail-current-str
+	  (compose-string (quail-lookup-map-and-concat quail-current-key))))
+  control-flag)
 
-;; Return a Quail map corresponding to KEY of length LEN.
-;; The car part of the map is a translation generated automatically.
-;; The cdr part of the map is a copy of ALIST.
-(defun thai-generate-quail-map (key len alist)
-  (let ((str "")
-	(idx 0))
-    (while (< idx len)
-      (setq str (concat str (aref (nth 1 (thai-keyboard-info
-					  thai-current-keyboard-type))
-				  (aref key idx)))
-	    idx (1+ idx)))
-    (cons (string-to-char (compose-string str)) (copy-alist alist))))
-
-;; Return a Quail map corresponding to KEY of length LEN when Thai
-;; tone mark is entered.
-(defun thai-tone-input (key len)
-  (thai-generate-quail-map key len nil))
-
-;; Return a Quail map corresponding to KEY of length LEN when Thai
-;; vowel upper or vowel lower is entered.
-(defun thai-vowel-upper-lower-input (key len)
-  (thai-generate-quail-map
-   key len
-   (nth 3 (thai-keyboard-info thai-current-keyboard-type))))
-
-;; Define RULES in Quail map.  In addition, create
-;; `thai-consonant-alist-KEYBOARD-TYPE' and
-;; `thai-vowel-upper-lower-alist-KEYBOARD-TYPE'.
-
-;; The general composing rules are as follows:
-;;
-;;                          T
-;;       V        T         V                  T
-;; CV -> C, CT -> C, CVT -> C, Cv -> C, CvT -> C
-;;                                   v         v
-;;
-;; where C: consonant, V: vowel upper, v: vowel lower, T: tone mark.
+(defun thai-generate-quail-map (translation-table)
+  (let ((i 0)
+	consonant vowel tone voweltone others)
+    ;; Categorize Thai characters into one of above.
+    (while (< i 128)
+      (let ((trans (aref translation-table i))
+	    ptype)
+	(if (eq trans 0)
+	    nil
+	  (if (> (length trans) 1)
+	      (setq ptype 'voweltone
+		    trans (vector trans))
+	    (setq ptype (get-char-code-property (aref trans 0) 'phonetic-type))
+	    (cond ((memq ptype '(vowel-upper vowel-lower))
+		   (setq ptype 'vowel))
+		  ((not (memq ptype '(consonant tone)))
+		   (setq ptype 'others))))
+	  (set ptype (cons (cons (char-to-string i) trans)
+			   (symbol-value ptype)))))
+      (setq i (1+ i)))
 
-(defmacro thai-quail-define-rules (keyboard-type &rest rules)
-  (let ((l rules)
-	consonant-alist
-	vowel-upper-lower-alist
-	rule trans ch c-set)
-    (while l
-      (setq rule (car l))
-      (setq trans (nth 1 rule))
-      (if (consp trans)
-	  (setq trans (car trans)))
-      (setq c-set (char-category-set (string-to-char trans)))
-      (cond ((or (aref c-set ?2)
-		 (aref c-set ?3))
-	     (setq consonant-alist
-		   (cons (cons (string-to-char (car rule))
-			       'thai-vowel-upper-lower-input)
-			 consonant-alist)))
-	    ((aref c-set ?4)
-	     (setq consonant-alist
-		   (cons (cons (string-to-char (car rule))
-			       'thai-tone-input)
-			 consonant-alist)
-		   vowel-upper-lower-alist
-		   (cons (cons (string-to-char (car rule))
-			       'thai-tone-input)
-			 vowel-upper-lower-alist))))
-      (setq l (cdr l)))
-    `(progn
-	  (quail-define-rules ,@rules)
-	  (setcar (nthcdr 2 (thai-keyboard-info ,keyboard-type))
-		  ',consonant-alist)
-	  (setcar (nthcdr 3 (thai-keyboard-info ,keyboard-type))
-		  ',vowel-upper-lower-alist))))
+    (quail-map-from-table
+     '((base-state (consonant . vt-state)
+		   vowel tone voweltone others)
+       (vt-state (vowel . t-state)
+		 voweltone tone)
+       (t-state tone)))))
 
-;; Return an alist which can be a cdr part of a Quail map
-;; corresponding to the current key when Thai consonant is entered.
-(defun thai-consonant-input (key len)
-  (let ((quail-package-name (quail-name)))
-    (setq thai-current-keyboard-type
-	  (cond ((string= quail-package-name "thai-pattachote") 'pattachote)
-		((string= quail-package-name "thai-kesmanee") 'kesmanee)
-		(t (error "Invalid Quail package %s" quail-package-name))))
-    (copy-alist (nth 2 (thai-keyboard-info thai-current-keyboard-type)))))
-
 ;; Thai Kesmanee keyboard support.
 
 (quail-define-package
@@ -189,106 +78,27 @@
     ',T_(B' and ',To(B' are assigned to '\\' and '|' respectively,
     ',T#(B' and ',T%(B' are assigned to '`' and '~' respectively,
     Don't know where to assign characters ',Tz(B' and ',T{(B'."
- nil t t nil t nil nil nil nil nil t)
+ nil t t nil t nil nil nil 'quail-thai-update-translation nil t)
 
-(thai-quail-define-rules 'kesmanee
- ("1" (",TE(B" . thai-consonant-input))
- ("!" "#")
- ("2" "/")
- ("@" ",Tq(B")
- ("3" "_")
- ("#" ",Tr(B")
- ("4" (",T@(B" . thai-consonant-input))
- ("$" ",Ts(B")
- ("5" (",T6(B" . thai-consonant-input))
- ("%" ",Tt(B")
- ("6" ",TX(B")
- ("^" ",TY(B")
- ("7" ",TV(B")
- ("&" "0,TQi1(B")
- ("8" (",T$(B" . thai-consonant-input))
- ("*" ",Tu(B")
- ("9" (",T5(B" . thai-consonant-input))
- ("\(" ",Tv(B")
- ("0" (",T((B" . thai-consonant-input))
- ("\)" ",Tw(B")
- ("-" (",T"(B" . thai-consonant-input))
- ("_" ",Tx(B")
- ("=" (",T*(B" . thai-consonant-input))
- ("+" ",Ty(B")
- ("\\" ",T_(B")
- ("|" ",To(B")
- ("`" (",T#(B" . thai-consonant-input))
- ("~" (",T%(B" . thai-consonant-input))
- ("q" ",Tf(B")
- ("Q" ",Tp(B")
- ("w" ",Td(B")
- ("W" "\"")
- ("e" ",TS(B")
- ("E" (",T.(B" . thai-consonant-input))
- ("r" (",T>(B" . thai-consonant-input))
- ("R" (",T1(B" . thai-consonant-input))
- ("t" ",TP(B")
- ("T" (",T8(B" . thai-consonant-input))
- ("y" ",TQ(B")
- ("Y" ",Tm(B")
- ("u" ",TU(B")
- ("U" ",Tj(B")
- ("i" (",TC(B" . thai-consonant-input))
- ("I" (",T3(B" . thai-consonant-input))
- ("o" (",T9(B" . thai-consonant-input))
- ("O" ",TO(B")
- ("p" (",TB(B" . thai-consonant-input))
- ("P" (",T-(B" . thai-consonant-input))
- ("\[" (",T:(B" . thai-consonant-input))
- ("{" (",T0(B" . thai-consonant-input))
- ("\]" (",TE(B" . thai-consonant-input))
- ("}" ",")
+(quail-install-map 
+ (thai-generate-quail-map
+  [
+   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0	; control codes
+   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0	; control codes
+   0   "#" ",TF(B" ",Tr(B" ",Ts(B" ",Tt(B" ",TQi(B" ",T'(B"	; SPC .. '
+   ",Tv(B" ",Tw(B" ",Tu(B" ",Ty(B" ",TA(B" ",T"(B" ",Tc(B" ",T=(B"	; ( .. /
+   ",T((B" ",TE(B" "/" "_" ",T@(B" ",T6(B" ",TX(B" ",TV(B"	; 0 .. 7
+   ",T$(B" ",T5(B" ",T+(B" ",TG(B" ",T2(B" ",T*(B" ",TL(B" ",TF(B"	; 8 .. ?
+   ",Tq(B" ",TD(B" ",TZ(B" ",T)(B" ",T/(B" ",T.(B" ",Tb(B" ",T,(B"	; @ .. G
+   ",Tg(B" ",T3(B" ",Tk(B" ",TI(B" ",TH(B" ",Tn(B" ",Tl(B" ",TO(B"	; H .. O
+   ",T-(B" ",Tp(B" ",T1(B" ",T&(B" ",T8(B" ",Tj(B" ",TN(B" "\""	; P .. W
+   ")" ",Tm(B" "(" ",T:(B" ",T_(B" ",TE(B" ",TY(B" ",Tx(B"	; X .. _
+   ",T#(B" ",T?(B" ",TT(B" ",Ta(B" ",T!(B" ",TS(B" ",T4(B" ",T`(B"	; ` .. g
+   ",Ti(B" ",TC(B" ",Th(B" ",TR(B" ",TJ(B" ",T7(B" ",TW(B" ",T9(B"	; h .. o
+   ",TB(B" ",Tf(B" ",T>(B" ",TK(B" ",TP(B" ",TU(B" ",TM(B" ",Td(B"	; p .. w
+   ",T;(B" ",TQ(B" ",T<(B" ",T0(B" ",To(B" "." ",T%(B" 0	; x .. DEL
+   ]))
 
- ("a" (",T?(B" . thai-consonant-input))
- ("A" ",TD(B")
- ("s" (",TK(B" . thai-consonant-input))
- ("S" (",T&(B" . thai-consonant-input))
- ("d" (",T!(B" . thai-consonant-input))
- ("D" (",T/(B" . thai-consonant-input))
- ("f" (",T4(B" . thai-consonant-input))
- ("F" ",Tb(B")
- ("g" ",T`(B")
- ("G" (",T,(B" . thai-consonant-input))
- ("h" ",Ti(B")
- ("H" ",Tg(B")
- ("j" ",Th(B")
- ("J" ",Tk(B")
- ("k" ",TR(B")
- ("K" (",TI(B" . thai-consonant-input))
- ("l" (",TJ(B" . thai-consonant-input))
- ("L" (",TH(B" . thai-consonant-input))
- ("\;" (",TG(B" . thai-consonant-input))
- (":" (",T+(B" . thai-consonant-input))
- ("'" (",T'(B" . thai-consonant-input))
- ("\"" ".")
-
- ("z" (",T<(B" . thai-consonant-input))
- ("Z" "(")
- ("x" (",T;(B" . thai-consonant-input))
- ("X" ")")
- ("c" ",Ta(B")
- ("C" (",T)(B" . thai-consonant-input))
- ("v" (",TM(B" . thai-consonant-input))
- ("V" (",TN(B" . thai-consonant-input))
- ("b" ",TT(B")
- ("B" ",TZ(B")
- ("n" ",TW(B")
- ("N" ",Tl(B")
- ("m" (",T7(B" . thai-consonant-input))
- ("M" ",Tn(B")
- ("," (",TA(B" . thai-consonant-input))
- ("<" (",T2(B" . thai-consonant-input))
- ("." ",Tc(B")
- (">" (",TL(B" . thai-consonant-input))
- ("/" (",T=(B" . thai-consonant-input))
- ("?" ",TF(B")
- )
 
 
 ;; Thai Pattachote keyboard support.
@@ -296,106 +106,22 @@
 (quail-define-package
  "thai-pattachote" "Thai" ",T!;(B>" t
  "Thai Pattachote input method with TIS620 keyboard layout"
- nil t t nil t nil nil nil nil nil t)
-
-(thai-quail-define-rules 'pattachote
- ("1" "=")
- ("!" "+")
- ("2" ",Tr(B")
- ("@" "\"")
- ("3" ",Ts(B")
- ("#" "/")
- ("4" ",Tt(B")
- ("$" ",")
- ("5" ",Tu(B")
- ("%" "?")
- ("6" ",TY(B")
- ("^" ",TX(B")
- ("7" ",Tw(B")
- ("&" "_")
- ("8" ",Tx(B")
- ("*" ".")
- ("9" ",Ty(B")
- ("(" "(")
- ("0" ",Tp(B")
- (")" ")")
- ("-" ",Tq(B")
- ("_" "-")
- ("=" ",Tv(B")
- ("+" "%")
- ("\\" ",TZ(B")
- ("|" ",Tm(B")
- ("`" (",T#(B" . thai-consonant-input))
- ("~" (",T%(B" . thai-consonant-input))
+ nil t t nil t nil nil nil 'quail-thai-update-translation nil t)
 
- ("q" ",Tg(B")
- ("Q" ",Tj(B")
- ("w" (",T5(B" . thai-consonant-input))
- ("W" ",TD(B")
- ("e" (",TB(B" . thai-consonant-input))
- ("E" ",Tf(B")
- ("r" (",TM(B" . thai-consonant-input))
- ("R" (",T-(B" . thai-consonant-input))
- ("t" (",TC(B" . thai-consonant-input))
- ("T" (",TI(B" . thai-consonant-input))
- ("y" ",Th(B")
- ("Y" ",TV(B")
- ("u" (",T4(B" . thai-consonant-input))
- ("U" (",T=(B" . thai-consonant-input))
- ("i" (",TA(B" . thai-consonant-input))
- ("I" (",T+(B" . thai-consonant-input))
- ("o" (",TG(B" . thai-consonant-input))
- ("O" (",T6(B" . thai-consonant-input))
- ("p" ",Ta(B")
- ("P" (",T2(B" . thai-consonant-input))
- ("\[" ",Tc(B")
- ("{" ",TO(B")
- ("\]" (",T2(B" . thai-consonant-input))
- ("}" ",TF(B")
-
- ("a" ",Ti(B")
- ("A" ",Tk(B")
- ("s" (",T7(B" . thai-consonant-input))
- ("S" (",T8(B" . thai-consonant-input))
- ("d" (",T'(B" . thai-consonant-input))
- ("D" ",TS(B")
- ("f" (",T!(B" . thai-consonant-input))
- ("F" (",T3(B" . thai-consonant-input))
- ("g" ",TQ(B")
- ("G" ",Tl(B")
- ("h" ",TU(B")
- ("H" ",TW(B")
- ("j" ",TR(B")
- ("J" (",T<(B" . thai-consonant-input))
- ("k" (",T9(B" . thai-consonant-input))
- ("K" (",T*(B" . thai-consonant-input))
- ("l" ",T`(B")
- ("L" ",Tb(B")
- (";" ",Td(B")
- (":" (",T&(B" . thai-consonant-input))
- ("'" (",T"(B" . thai-consonant-input))
- ("\"" (",T1(B" . thai-consonant-input))
-
- ("z" (",T:(B" . thai-consonant-input))
- ("Z" (",T.(B" . thai-consonant-input))
- ("x" (",T;(B" . thai-consonant-input))
- ("X" (",T.(B" . thai-consonant-input))
- ("c" (",TE(B" . thai-consonant-input))
- ("C" (",T0(B" . thai-consonant-input))
- ("v" (",TK(B" . thai-consonant-input))
- ("V" (",T@(B" . thai-consonant-input))
- ("b" ",TT(B")
- ("B" ",TQ(B")
- ("n" (",T$(B" . thai-consonant-input))
- ("N" (",TH(B" . thai-consonant-input))
- ("m" (",TJ(B" . thai-consonant-input))
- ("M" (",TN(B" . thai-consonant-input))
- ("," ",TP(B")
- ("<" (",T?(B" . thai-consonant-input))
- ("." (",T((B" . thai-consonant-input))
- (">" (",T2(B" . thai-consonant-input))
- ("/" (",T>(B" . thai-consonant-input))
- ("?" (",TL(B" . thai-consonant-input))
- )
-
-;;; quail/thai.el ends here
+(quail-install-map 
+ (thai-generate-quail-map
+  [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0	; control codes
+    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0	; control codes
+    0 "+" ",T1(B" "/" "," "?" "_" ",T"(B"	; SPC .. '
+    "(" ")" "." "%" ",TP(B" ",Tq(B" ",T((B" ",T>(B"	; ( .. /
+    ",Tp(B" "=" ",Tr(B" ",Ts(B" ",Tt(B" ",Tu(B" ",TY(B" ",Tw(B"	; 0 .. 7
+    ",Tx(B" ",Ty(B" ",T&(B" ",Td(B" ",T?(B" ",Tv(B" ",T2(B" ",TL(B"	; 8 .. ?
+    "\"" ",Tk(B" ",TQ(B" ",T0(B" ",TS(B" ",Tf(B" ",T3(B" ",Tl(B"	; @ .. G
+    ",TW(B" ",T+(B" ",T<(B" ",T*(B" ",Tb(B" ",TN(B" ",TH(B" ",T6(B"	; H .. O
+    ",T2(B" ",Tj(B" ",T-(B" ",T8(B" ",TI(B" ",T=(B" ",T@(B" ",TD(B"	; P .. W
+    ",T.(B" ",TV(B" ",T.(B" ",Tc(B" ",TZ(B" ",T2(B" ",TX(B" "-"	; X .. _
+    ",T#(B" ",Ti(B" ",TT(B" ",TE(B" ",T'(B" ",TB(B" ",T!(B" ",TQ(B"	; ` .. g
+    ",TU(B" ",TA(B" ",TR(B" ",T9(B" ",T`(B" ",TJ(B" ",T$(B" ",TG(B"	; h .. o
+    ",Ta(B" ",Tg(B" ",TM(B" ",T7(B" ",TC(B" ",T4(B" ",TK(B" ",T5(B"	; p .. w
+    ",T;(B" ",Th(B" ",T:(B" ",TO(B" ",Tm(B" ",TF(B" ",T%(B" 0	; x .. DEL
+    ]))
--- a/leim/quail/tibetan.el	Wed Dec 15 00:28:11 1999 +0000
+++ b/leim/quail/tibetan.el	Wed Dec 15 00:32:16 1999 +0000
@@ -32,80 +32,109 @@
 ;;; Code:
 
 (require 'quail)
-
-;;;
-;;; Functions for making some composite punctuations.
-;;;
+(require 'tibet-util)
 
-(defun tibetan-quail-bzhi-shad (&rest ignore)
-  (quail-delete-region)
-  (quail-delete-overlays)
-  (insert (compose-chars ?$(7!>(B '(mr . ml) ?\x20 '(mr . ml) ?$(7!>(B))
-  (throw 'quail-tag nil))
+;; Now quail-current-key is set to Tibetan-Roman transcription.  We
+;; set quail-current-str to the corresponding Tibetan string (composed
+;; if necessary).  Both Wylie and TibKey input methods use this
+;; function.
 
-(defun tibetan-quail-nyi-zla (&rest ignore)
-  (quail-delete-region)
-  (quail-delete-overlays)
-  (insert (compose-chars ?$(7#R(B '(mr . ml) ?$(7#S(B))
-  (throw 'quail-tag nil))
+(defun quail-tibetan-update-translation (control-flag)
+  (if (numberp control-flag)
+      ;; Non-composable-character typed.
+      (setq quail-current-str
+	    (buffer-substring (overlay-start quail-overlay)
+			      (overlay-end quail-overlay))
+	    unread-command-events
+	    (string-to-list
+	     (substring quail-current-key control-flag)))
+    ;; Special treatment of "-d..." and "-y...".
+    (if (string-match "^-[dy]" quail-current-key)
+	(setq quail-current-key (substring quail-current-key 1)))
+    (let ((str (tibetan-transcription-to-tibetan quail-current-key)))
+      ;; If quail-current-key is for punctuations, it can't be
+      ;; transcribed by tibetan-transcription-to-tibetan, thus STR
+      ;; contains ASCII string now.  In that case, use the current
+      ;; characters set in quail-current-str.
+      (if (> (aref str 0) 255)
+	  (setq quail-current-str (tibetan-compose-string str))
+	(or quail-current-str
+	    (setq quail-current-str quail-current-key)))))
+  control-flag)
 
-(defun tibetan-quail-nyi-zla-phur-shad (&rest ignore)
-  (quail-delete-region)
-  (quail-delete-overlays)
-  (insert (compose-chars ?$(7#R(B '(mr . ml) ?$(7#S(B '(bc . tl) ?$(7!I(B))
-  (throw 'quail-tag nil))
+;;; Wylie transcription based input methods.
+
+;; Special alist for `$(7"A(B'.  It must be treated as a subjoined
+;; consonant if it follows a consonant.
+(defconst tibetan-wylie-quote-alist '(("'" . ?$(7"A(B)))
+
+;; Special alist to avoid default stacking.
+(defconst tibetan-wylie-non-stacking-alist
+  '(("-d" . "$(7"2(B")
+    ("-y" . "$(7"B(B")))
 
-(defun tibetan-quail-nyi-zla-double (&rest ignore)
-  (quail-delete-region)
-  (quail-delete-overlays)
-  (insert (compose-chars ?$(7#R(B '(mr . ml) ?$(7#S(B '(mr . ml) ?$(7#S(B))
-  (throw 'quail-tag nil))
-
-(defun tibetan-quail-nyi-zla-triple (&rest ignore)
-  (quail-delete-region)
-  (quail-delete-overlays)
-  (insert (compose-chars ?$(7#R(B '(mr . ml) ?$(7#S(B '(mr . ml) ?$(7#S(B '(mr . ml) ?$(7#S(B))
-  (throw 'quail-tag nil))
-
-;;;
-;;; Setting-ups for Extended Wylie input.
-;;;
+;; Punctuations are not transcribed.
 
-(defun quail-tibetan-input-wylie (key &rest ignore)
-  (let (pc)
-    (quail-delete-region)
-    (quail-delete-overlays)
-    (setq pc (char-before (overlay-start quail-overlay))
-	  quail-current-str (tibetan-composition pc key))
-    (if (not (bobp))
-	(progn
-	  (delete-char -1)
-	  (insert (aref quail-current-str 0))
-	  (setq quail-current-str (substring quail-current-str 1))))
-    (move-overlay quail-overlay (point) (point))
-    (insert quail-current-str)
-    (throw 'quail-tag nil)))
-
+(defconst tibetan-wylie-punctuation-alist
+   '(("."  . " ")
+     (":"  . "$(8"`(B")
+     (" "  . "$(8!;(B")
+     ("/"  . "$(8!=(B")
+     ("//" . "$(7!>(B")
+     ("////" . ["$(7!>(B $(7!>(B"])
+     ("$"  . "$(8!?(B")
+     ("/\"" . "$(8!@(B")			; Not defined in Ext. Wylie.
+     ("&"  . "$(8!@(B")
+     (";"  . "$(8!A(B")
+     ("%"  . "$(8!D(B")
+     ("!"  . "$(7!8(B")
+     ("<"  . "$(7!l(B")
+     (">"  . "$(7!m(B")
+     ("@"  . "$(7"f(B")
+     ("*"  . ["$(7!4!5(B"])
+     ("#"  . ["$(7!4!5!5(B"])
+     ("^"  . "$(7!6(B")
+     ("0" . "$(7!P(B")
+     ("1" . "$(7!Q(B")
+     ("2" . "$(7!R(B")
+     ("3" . "$(7!S(B")
+     ("4" . "$(7!T(B")
+     ("5" . "$(7!U(B")
+     ("6" . "$(7!V(B")
+     ("7" . "$(7!W(B")
+     ("8" . "$(7!X(B")
+     ("9" . "$(7!Y(B")
+     ("-0" . "$(7!c(B")
+     ("-1" . "$(7!Z(B")
+     ("-2" . "$(7![(B")
+     ("-3" . "$(7!\(B")
+     ("-4" . "$(7!](B")
+     ("-5" . "$(7!^(B")
+     ("-6" . "$(7!_(B")
+     ("-7" . "$(7!`(B")
+     ("-8" . "$(7!a(B")
+     ("-9" . "$(7!b(B")
+     ("|"  . "$(7!1!2!3!9!:!B!C!E!F!G!H!I!J!K!L!M!N!O!d!f!h!j!k!n!o(B")))
 
 (quail-define-package "tibetan-wylie" "Tibetan" "TIBw" t
 "Tibetan character input by Extended Wylie key assignment.
 
     +-------------------------------------+
-    |2$(7"!`#T(B1$(8!;(B k |2$(7""`#T(B1$(8!;(B kh |2$(7"#`#T(B1$(8!;(B g  |2$(7"$`#T(B1$(8!;(B gh |2$(7"%`#T(B1$(8!;(B ng|   $(7"S(B i          $(8!=(B        /
-    |2$(7"&`#T(B1$(8!;(B c |2$(7"'`#T(B1$(8!;(B ch |2$(7"(`#T(B1$(8!;(B j  |       |$(7"*$(8!;(B ny|   $(7"U(B u          $(7!>(B       //
-    |$(7"+$(8!;(B T |$(7",$(8!;(B TH |$(7"-$(8!;(B D  |$(7".$(8!;(B DH |$(7"/$(8!;(B N |   $(7"[(B e          2$(7!>P(B P$(7!>(B1    ////
+    |$(7"!$(8!;(B k |$(7""$(8!;(B kh |$(7"#$(8!;(B g  |$(7"$$(8!;(B gh |$(7"%$(8!;(B ng|   $(7"S(B i          $(8!=(B        /
+    |$(7"&$(8!;(B c |$(7"'$(8!;(B ch |$(7"($(8!;(B j  |       |$(7"*$(8!;(B ny|   $(7"U(B u          $(7!>(B       //
+    |$(7"+$(8!;(B T |$(7",$(8!;(B TH |$(7"-$(8!;(B D  |$(7".$(8!;(B DH |$(7"/$(8!;(B N |   $(7"[(B e          $(7!>(B $(7!>(B    ////
     |$(7"0$(8!;(B t |$(7"1$(8!;(B th |$(7"2$(8!;(B d  |$(7"3$(8!;(B dh |$(7"4$(8!;(B n |   $(7"](B o          $(7!A(B       ;
     |$(7"5$(8!;(B p |$(7"6$(8!;(B ph |$(7"7$(8!;(B b  |$(7"8$(8!;(B bh |$(7"9$(8!;(B m |   $(7"\(B ai (ee, E) $(8!?(B        $
     |$(7":$(8!;(B ts|$(7";$(8!;(B tsh|$(7"<$(8!;(B dz |$(7"=$(8!;(B dzh|$(7">$(8!;(B w |   $(7"^(B au (oo, O) $(8!@(B        &
-    |$(7"?$(8!;(B zh|$(7"@$(8!;(B z  |$(7"A$(8!;(B '  |       |$(7"B$(8!;(B y |   $(7"a(B I          2$(7#RP#SP#S(B1   *
-    |$(7"C$(8!;(B r |$(7"D$(8!;(B l  |$(7"E$(8!;(B sh |$(7"F$(8!;(B SH |$(7"G$(8!;(B s |   $(7"`(B :          2$(7#RP#SP#SP#S(B1 #
+    |$(7"?$(8!;(B zh|$(7"@$(8!;(B z  |$(7"A$(8!;(B '  |       |$(7"B$(8!;(B y |   $(7"a(B I          $(7#R#S#S(B   *
+    |$(7"C$(8!;(B r |$(7"D$(8!;(B l  |$(7"E$(8!;(B sh |$(7"F$(8!;(B SH |$(7"G$(8!;(B s |   $(7"`(B :          $(7#R#S#S#S(B #
     |$(7"H$(8!;(B h |$(7"I$(8!;(B A  |$(7"J$(8!;(B kSH|       |      |   $(7"_(B M           $(7!l(B $(7!m(B   < >
     +-------------------------------------+   $(8!D(B  %
     (The consonant $(7"I$(8!;(B must be typed explicitly.)
 
   NOT SPECIFIED IN EXT. WYLIE:
     +--------------------------------------------------------+
-    |$(7"c(B = ~ |$(7"d(B = ` |$(7"e(B = , |$(7"f(B = @ |$(7!g(B = _o|$(7!e(B = _O|2$(7#RP#S_!I(B1 = ^|
+    |$(7"c(B = ~ |$(7"d(B = ` |$(7"e(B = , |$(7"f(B = @ |$(7!g(B = _o|$(7!e(B = _O|$(7#R#S!I(B = ^|
     +--------------------------------------------------------+
     |$(7"i(B = x |$(7"j(B = X |$(7"g(B = v |$(7"h(B = V |$(7"k(B = q |$(7"l(B = Q |
     +-----------------------------------------------+
@@ -120,127 +149,40 @@
 
   Tsheg is assigned to SPC. Space is assigned to period '.'.
 "
- nil nil nil)
+ nil nil nil nil nil nil nil nil
+ 'quail-tibetan-update-translation)
+
+;; Here we build up a Quail map for a Tibtan sequence the whole of
+;; which can be one composition.
+;;
+;; A Tibetan syllable is typically structured as follows:
+;;      [P] C [c+] V [M] [S [s]]
+;;          ^^^^^^^^^^^^
+;; where P:prefix, C:base consonant, c:subjoined consonant,
+;; V:vowel, M:vowel modifier, S:suffix, s:post suffix.
+;; In this pattern, the part indicated by "^^^" can be one composition.
 
-(quail-define-rules
- ("."    ?\x20)
- ("k"    quail-tibetan-input-wylie)
- ("g"    quail-tibetan-input-wylie)
- ("c"    quail-tibetan-input-wylie)
- ("j"    quail-tibetan-input-wylie)
- ("T"    quail-tibetan-input-wylie)
- ("D"    quail-tibetan-input-wylie)
- ("N"    quail-tibetan-input-wylie)
- ("t"    quail-tibetan-input-wylie)
- ("d"    quail-tibetan-input-wylie)
- ("n"    quail-tibetan-input-wylie)
- ("p"    quail-tibetan-input-wylie)
- ("b"    quail-tibetan-input-wylie)
- ("m"    quail-tibetan-input-wylie)
- ("w"    quail-tibetan-input-wylie)
- ("z"    quail-tibetan-input-wylie)
- ("'"    quail-tibetan-input-wylie)
- ("y"    quail-tibetan-input-wylie)
- ("r"    quail-tibetan-input-wylie)
- ("l"    quail-tibetan-input-wylie)
- ("SH"   quail-tibetan-input-wylie)
- ("s"    quail-tibetan-input-wylie)
- ("h"    quail-tibetan-input-wylie)
- ("H"    quail-tibetan-input-wylie)
- ("A"    quail-tibetan-input-wylie)
- ("+k"   quail-tibetan-input-wylie)
- ("+g"   quail-tibetan-input-wylie)
- ("+c"   quail-tibetan-input-wylie)
- ("+j"   quail-tibetan-input-wylie)
- ("+T"   quail-tibetan-input-wylie)
- ("+D"   quail-tibetan-input-wylie)
- ("+N"   quail-tibetan-input-wylie)
- ("+t"   quail-tibetan-input-wylie)
- ("+d"   quail-tibetan-input-wylie)
- ("+n"   quail-tibetan-input-wylie)
- ("+p"   quail-tibetan-input-wylie)
- ("+b"   quail-tibetan-input-wylie)
- ("+m"   quail-tibetan-input-wylie)
- ("+w"   quail-tibetan-input-wylie)
- ("+z"   quail-tibetan-input-wylie)
- ("+'"   quail-tibetan-input-wylie)
- ("+y"   quail-tibetan-input-wylie)
- ("+r"   quail-tibetan-input-wylie)
- ("+l"   quail-tibetan-input-wylie)
- ("+SH"  quail-tibetan-input-wylie)
- ("+s"   quail-tibetan-input-wylie)
- ("+h"   quail-tibetan-input-wylie)
- ("+H"   quail-tibetan-input-wylie)
- ("+A"   quail-tibetan-input-wylie)
- ("-d"  ?$(7"2(B)				; To avoid default stacking
- ("-y"  ?$(7"B(B)				; Idem.
- ("a"    quail-tibetan-input-wylie)	; invisible vowel sign
- ("i"    quail-tibetan-input-wylie)
- ("u"    quail-tibetan-input-wylie)
- ("e"    quail-tibetan-input-wylie)
- ("o"    quail-tibetan-input-wylie)
- ("I"    quail-tibetan-input-wylie)
- ("E"    quail-tibetan-input-wylie)
- ("O"    quail-tibetan-input-wylie)
- ("M"    quail-tibetan-input-wylie)
- ("~"    quail-tibetan-input-wylie)
- ("`"    quail-tibetan-input-wylie)
- (","    quail-tibetan-input-wylie)
- ("x"    quail-tibetan-input-wylie)
- ("X"    quail-tibetan-input-wylie)
- ("v"    quail-tibetan-input-wylie)
- ("V"    quail-tibetan-input-wylie)
- ("q"    quail-tibetan-input-wylie)
- ("Q"    quail-tibetan-input-wylie)
- ("_o"    quail-tibetan-input-wylie)
- ("_O"    quail-tibetan-input-wylie)
-;;; ("_/"    quail-tibetan-input-wylie)
- (":"   ?$(8"`(B)
- (" "   ?$(8!;(B)
- ("/"   ?$(8!=(B)
- ("//"  ?$(7!>(B)
- ("////" tibetan-quail-bzhi-shad)
- ("$"   ?$(8!?(B)
- ("/\"" ?$(8!@(B)				; Not defined in Ext. Wylie.
- ("&"   ?$(8!@(B)
- (";"   ?$(8!A(B)
- ("%"   ?$(8!D(B)
- ("!"   ?$(7!8(B)
- ("<"   ?$(7!l(B)
- (">"   ?$(7!m(B)
- ("@"   ?$(7"f(B)
- ("*" tibetan-quail-nyi-zla-double)
- ("#" tibetan-quail-nyi-zla-triple)
- ("^" tibetan-quail-nyi-zla-phur-shad)
- ("0" ?$(7!P(B)
- ("1" ?$(7!Q(B)
- ("2" ?$(7!R(B)
- ("3" ?$(7!S(B)
- ("4" ?$(7!T(B)
- ("5" ?$(7!U(B)
- ("6" ?$(7!V(B)
- ("7" ?$(7!W(B)
- ("8" ?$(7!X(B)
- ("9" ?$(7!Y(B)
- ("-0" ?$(7!c(B)
- ("-1" ?$(7!Z(B)
- ("-2" ?$(7![(B)
- ("-3" ?$(7!\(B)
- ("-4" ?$(7!](B)
- ("-5" ?$(7!^(B)
- ("-6" ?$(7!_(B)
- ("-7" ?$(7!`(B)
- ("-8" ?$(7!a(B)
- ("-9" ?$(7!b(B)
- ("|"  "$(7!1!2!3!9!:!B!C!E!F!G!H!I!J!K!L!M!N!O!d!f!h!j!k!n!o(B")
- )
+(quail-install-map
+ (quail-map-from-table
+  '((base-state (tibetan-consonant-transcription-alist . sq-state)
+		(tibetan-precomposed-transcription-alist . s-state)
+		(tibetan-wylie-non-stacking-alist . sq-state)
+		tibetan-subjoined-transcription-alist
+		tibetan-vowel-transcription-alist
+		tibetan-modifier-transcription-alist
+		tibetan-wylie-punctuation-alist)
+    (sq-state (tibetan-wylie-quote-alist . s-state)
+	      (tibetan-subjoined-transcription-alist . s-state))
+    (s-state (tibetan-subjoined-transcription-alist . s-state)
+	     (tibetan-vowel-transcription-alist . m-state))
+    (m-state tibetan-modifier-transcription-alist))))
 
 ;;;
-;;; Setting-ups for TibKey input
+;;; TibKey key alignment based input method
 ;;;
 
 (defconst tibetan-tibkey-to-transcription-alist
-  '(
+  '(;; consonant
     ("`" . "`")				; sna ldan
     ("~" . "~")				; sna ldan + nada
     ("q" . "k")				; ka
@@ -292,7 +234,7 @@
     ("," . "s")				; sa
     ("." . "h")				; ha
     ("/" . "A")				; Aa
-    ;;subjoined
+    ;; subjoined
     ("hq" . "+k")			; ka
     ("hQ" ."+kSH")			; kSHa
     ("hw" . "+kh")			; kha
@@ -329,30 +271,118 @@
     ("h," . "+s")			; sa
     ("h." . "+h")			; ha
     ("h/" . "+A")			; Aa
+    ;; Special rule for `$(7"B(B' to avoid stacking.
+    ("E" . "-y")
     ))
 
-(defun quail-tibetan-input-tibkey (key &rest ignore)
-  (let (trans pc)
-    (setq trans (cdr (assoc key tibetan-tibkey-to-transcription-alist)))
-    (quail-delete-region)
-    (quail-delete-overlays)
-    (setq pc (char-before (overlay-start quail-overlay))
-	  quail-current-str (tibetan-composition pc trans))
-    (if (not (bobp))
-	(progn
-	  (delete-char -1)
-	  (insert (aref quail-current-str 0))
-	  (setq quail-current-str (substring quail-current-str 1))))
-    (move-overlay quail-overlay (point) (point))
-    (insert quail-current-str)
-    (throw 'quail-tag nil)))
+(defconst tibetan-consonant-tibkey-alist nil)
+(defconst tibetan-subjoined-tibkey-alist nil)
+(defconst tibetan-vowel-tibkey-alist nil)
+(defconst tibetan-modifier-tibkey-alist nil)
+(defconst tibetan-non-stacking-tibkey-alist nil)
+
+(let ((type-list '("consonant" "subjoined" "vowel" "modifier" "non-stacking"))
+      (tail tibetan-tibkey-to-transcription-alist)
+      elt)
+  (while tail
+    (setq elt (car tail) tail (cdr tail))
+    (let ((types type-list)
+	  type transcription trans-alist tibkey-alist)
+      (while types
+	(setq type (car types) types (cdr types))
+	(setq trans-alist
+	      (if (string= type "non-stacking")
+		  'tibetan-wylie-non-stacking-alist
+		(intern (format "tibetan-%s-transcription-alist" type)))
+	      transcription
+	      (cdr (assoc (cdr elt) (symbol-value trans-alist))))
+	(when transcription
+	  (setq tibkey-alist (intern (format "tibetan-%s-tibkey-alist" type)))
+	  (set tibkey-alist
+	       (cons (cons (car elt) transcription)
+		     (symbol-value tibkey-alist)))))
+      (or tibkey-alist
+	  (error "No Tibetan transcription for %s" (cdr elt))))))
 
+(defconst tibetan-punctuation-tibkey-alist
+  '(("1" . "$(7!Q(B")
+    ("!" . ["$(7#R#S#S#S(B"])		; nyi zla long
+    ("2" . "$(7!R(B")
+    ("@" . "$(7#S(B")			; nyi zla simple
+    ("3" . "$(7!S(B")
+;;; ("#" )
+    ("4" . "$(7!T(B")
+;;; ("$" )
+    ("5" . "$(7!U(B")
+    ("%" . "$(8!D(B")
+    ("6" . "$(7!V(B")
+    ("^" . "$(7!1(B")
+    ("7" . "$(7!W(B")
+    ("8" . "$(7!X(B")
+;;; ("*" ) ; avagraha, not supported yet
+    ("9" . "$(7!Y(B")
+    ("(" . "$(7!l(B")
+    ("0" . "$(7!P(B")
+    (")" . "$(7!m(B")
+;;; ("-" ) ; enphatic, not yet supported 
+;;; ("_" ) ; id.
+;;; ("=" ) ; special sign, not yet supported
+    ("+" . "$(8!A(B")
+    ("\\" . "$(8!?(B")
+    ("|" . "$(7!8(B")
+    ("I" . "$(7"f(B")				; avagraha
+    (":" . "$(8"`(B")
+;;; (">" ?$(8!;(B) ; to be assigned to SPC
+    (">" . " ")
+    ("?" . "$(8!=(B")
+    ("??" . "$(7!>(B")
+    ("????" . ["$(7!>(B $(7!>(B"])
+    (" " . "$(8!;(B")
+    ))
 
+;; Convert TibKey string to Tibetan-Roman transcription string.
+;; If there's no proper conversion, return nil.
+(defun quail-tibkey-to-transcription (tibkey)
+  (let ((len (length tibkey))
+	(i 0)
+	(trans-list nil))
+    (while (< i len)
+      (let ((last len)
+	    trans)
+	(while (and (not trans) (> last i))
+	  (or (setq trans (cdr (assoc (substring tibkey i last)
+				      tibetan-tibkey-to-transcription-alist)))
+	      (setq last (1- last))))
+	(if trans
+	    (setq trans-list (cons trans trans-list)
+		  i last)
+	  (setq trans-list nil i len))))
+    (apply 'concat (nreverse trans-list))))
+
+(defvar quail-tibkey-characters nil)
+
+(defun quail-tibkey-update-translation (control-flag)
+  (if (integerp control-flag)
+      ;; Non-composable-character typed.
+      (setq quail-current-str
+	    (buffer-substring (overlay-start quail-overlay)
+			      (overlay-end quail-overlay))
+	    unread-command-events
+	    (string-to-list
+	     (substring quail-current-key control-flag)))
+    (let ((transcription (quail-tibkey-to-transcription quail-current-key)))
+      (if (> (length transcription) 0)
+	  (let ((quail-current-key transcription))
+	    (setq control-flag
+		  (quail-tibetan-update-translation control-flag)))
+	(or quail-current-str
+	    (setq quail-current-str quail-current-key)))))
+  control-flag)
 
 (quail-define-package "tibetan-tibkey" "Tibetan" "TIBt" t
 "Tibetan character input by TibKey key assignment.
 
-(This implementation is still incomplete.
+\(This implementation is still incomplete.
  Therefore, the following key assignment is a provisional one.)
 
   [NOT SHIFTED]
@@ -371,7 +401,7 @@
   [SHIFTED]
 
   +----------------------------------------------------------+
-  |~$(7"c(B|!2$(7#RP#S(B1|@$(7#S(B|#  |$  |%$(8!D(B |^$(7!1(B|&  |*  |($(7!l(B|)$(7!m(B|_  |+$(7!A(B| |$(7!8(B|
+  |~$(7"c(B|!$(7#R#S(B|@$(7#S(B|#  |$  |%$(8!D(B |^$(7!1(B|&  |*  |($(7!l(B|)$(7!m(B|_  |+$(7!A(B| |$(7!8(B|
   +----------------------------------------------------------+
      |Q$(7"J(B|W$(7#T(B|E  |R  |T$(7"a(B|Y  |U  |I$(7"f(B|O$(7"+(B|P$(7",(B|{$(7"-(B|}$(7"/(B|
      +-----------------------------------------------+
@@ -394,136 +424,17 @@
        current implementation (especially special signs). I hope
        I'll complete in a future revision.
 "
- nil t)
+ nil nil nil nil nil nil nil nil
+ 'quail-tibkey-update-translation)
 
-(quail-define-rules
- ("`" quail-tibetan-input-tibkey)	; sna ldan, not supported yet
- ("~" quail-tibetan-input-tibkey)	; sna ldan + nada
- ("1" ?$(7!Q(B)
- ("!" tibetan-quail-nyi-zla)		; nyi zla long
- ("2" ?$(7!R(B)
- ("@" ?$(7#S(B)				; nyi zla simple
- ("3" ?$(7!S(B)
-;;; ("#" )
- ("4" ?$(7!T(B)
-;;; ("$" )
- ("5" ?$(7!U(B)
- ("%" ?$(8!D(B)
- ("6" ?$(7!V(B)
- ("^" ?$(7!1(B)
- ("7" ?$(7!W(B)
- ("8" ?$(7!X(B)
-;;; ("*" ) ; avagraha, not supported yet
- ("9" ?$(7!Y(B)
- ("(" ?$(7!l(B)
- ("0" ?$(7!P(B)
- (")" ?$(7!m(B)
-;;; ("-" ) ; enphatic, not yet supported 
-;;; ("_" ) ; id.
-;;; ("=" ) ; special sign, not yet supported
- ("+" ?$(8!A(B)
- ("\\" ?$(8!?(B)
- ("|" ?$(7!8(B)
- ("q" quail-tibetan-input-tibkey)	; ka
- ("Q" quail-tibetan-input-tibkey)	; kSHa
- ("w" quail-tibetan-input-tibkey)	; kha
- ("e" quail-tibetan-input-tibkey)	; ga
- ("E" ?$(7"B(B)
- ("r" quail-tibetan-input-tibkey)	; nga
- ("t" quail-tibetan-input-tibkey)	; ca
- ("T" quail-tibetan-input-tibkey)	; gi gu log
- ("y" quail-tibetan-input-tibkey)	; cha
- ("u" quail-tibetan-input-tibkey)	; ja
- ("i" quail-tibetan-input-tibkey)	; nya
- ("I" ?$(7"f(B)				; avagraha
- ("o" quail-tibetan-input-tibkey)	; ta
- ("O" quail-tibetan-input-tibkey)	; Ta
- ("p" quail-tibetan-input-tibkey)	; tha
- ("P" quail-tibetan-input-tibkey)	; THa
- ("[" quail-tibetan-input-tibkey)	; da 
- ("{" quail-tibetan-input-tibkey)	; Da
- ("]" quail-tibetan-input-tibkey)	; na
- ("}" quail-tibetan-input-tibkey)	; Na
- ("a" quail-tibetan-input-tibkey)	; pa 
- ("A" quail-tibetan-input-tibkey)	; Vowel sign a
- ("s" quail-tibetan-input-tibkey)	; pha
- ("d" quail-tibetan-input-tibkey)	; ba
-;;; ("D" ) ; special sign, not supported yet
- ("f" quail-tibetan-input-tibkey)	; ma
- ("F" quail-tibetan-input-tibkey)	; anusvara
- ("g" quail-tibetan-input-tibkey)	; zhabs kyu
- ("G" quail-tibetan-input-tibkey)	; gi gu
- ("H" quail-tibetan-input-tibkey)	; viraama
- ("j" quail-tibetan-input-tibkey)	; naro
- ("J" quail-tibetan-input-tibkey)	; 'greng bu
- ("k" quail-tibetan-input-tibkey);;tsa
-;;; ("K" ) ; tsadru, not supported yet
- ("l" quail-tibetan-input-tibkey)	; tsha
- (";" quail-tibetan-input-tibkey)       ; dza
- (":" ?$(8"`(B)
- ("'" quail-tibetan-input-tibkey)	; wa
- ("\"" quail-tibetan-input-tibkey)	; wa zur
- ("z" quail-tibetan-input-tibkey)	; zha
- ("x" quail-tibetan-input-tibkey)	; za
- ("c" quail-tibetan-input-tibkey)	; 'a
- ("C" quail-tibetan-input-tibkey)	; 'a chung
- ("v" quail-tibetan-input-tibkey)	; ya
- ("V" quail-tibetan-input-tibkey)	; ya btags
- ("b" quail-tibetan-input-tibkey)	; ra
- ("B" quail-tibetan-input-tibkey)	; ra btags
- ("n" quail-tibetan-input-tibkey)	; la
- ("N" quail-tibetan-input-tibkey)	; la btags
- ("m" quail-tibetan-input-tibkey)	; sha
- ("M" quail-tibetan-input-tibkey)	; SHa
- ("," quail-tibetan-input-tibkey)	; sa
- ("." quail-tibetan-input-tibkey)	; ha
-;;; (">" ?$(8!;(B) ; to be assigned to SPC
- (">" ?\x20)
- ("/" quail-tibetan-input-tibkey)	; Aa
- ("?" ?$(8!=(B)
- ("??" ?$(7!>(B)
- ("????" tibetan-quail-bzhi-shad)
- (" " ?$(8!;(B)
- ;;subjoined
- ("hq" quail-tibetan-input-tibkey)	; ka
- ("hQ" quail-tibetan-input-tibkey)	; kSHa
- ("hw" quail-tibetan-input-tibkey)	; kha
- ("he" quail-tibetan-input-tibkey)	; ga
- ("hr" quail-tibetan-input-tibkey)	; nga
- ("ht" quail-tibetan-input-tibkey)	; ca
- ("hy" quail-tibetan-input-tibkey)	; cha
- ("hu" quail-tibetan-input-tibkey)	; ja
- ("hi" quail-tibetan-input-tibkey)	; nya
- ("ho" quail-tibetan-input-tibkey)	; ta
- ("hO" quail-tibetan-input-tibkey)	; Ta
- ("hp" quail-tibetan-input-tibkey)	; tha
- ("hP" quail-tibetan-input-tibkey)	; THa
- ("h[" quail-tibetan-input-tibkey)	; da 
- ("h{" quail-tibetan-input-tibkey)	; Da
- ("h]" quail-tibetan-input-tibkey)	; na
- ("h}" quail-tibetan-input-tibkey)	; Na
- ("ha" quail-tibetan-input-tibkey)	; pa 
- ("hs" quail-tibetan-input-tibkey)	; pha
- ("hd" quail-tibetan-input-tibkey)	; ba
- ("hf" quail-tibetan-input-tibkey)	; ma
- ("hk" quail-tibetan-input-tibkey)	; tsa
- ("hl" quail-tibetan-input-tibkey)	; tsha
- ("h;" quail-tibetan-input-tibkey)      ; dza
- ("h'" quail-tibetan-input-tibkey)	; wa
- ("hz" quail-tibetan-input-tibkey)	; zha
- ("hx" quail-tibetan-input-tibkey)	; za
- ("hc" quail-tibetan-input-tibkey)	; 'a
- ("hv" quail-tibetan-input-tibkey)	; ya
- ("hb" quail-tibetan-input-tibkey)	; ra
- ("hn" quail-tibetan-input-tibkey)	; la
- ("hm" quail-tibetan-input-tibkey)	; sha
- ("hM" quail-tibetan-input-tibkey)	; SHa
- ("h," quail-tibetan-input-tibkey)	; sa
- ("h." quail-tibetan-input-tibkey)	; ha
- ("h/" quail-tibetan-input-tibkey)	; Aa
- )
-
-;;; quail/tibetan.el ends here.
-
-
-
+(quail-install-map
+ (quail-map-from-table
+  '((base-state (tibetan-consonant-tibkey-alist . s-state)
+		(tibetan-non-stacking-tibkey-alist . s-state)
+		tibetan-subjoined-tibkey-alist
+		tibetan-vowel-tibkey-alist
+		tibetan-modifier-tibkey-alist
+		tibetan-punctuation-tibkey-alist)
+    (s-state (tibetan-subjoined-tibkey-alist . s-state)
+	     (tibetan-vowel-tibkey-alist . m-state))
+    (m-state tibetan-modifier-tibkey-alist))))