egg-980217.
[elisp/egg.git] / its / pinyin.el
diff --git a/its/pinyin.el b/its/pinyin.el
new file mode 100644 (file)
index 0000000..9d3505d
--- /dev/null
@@ -0,0 +1,347 @@
+(eval-when-compile
+  (require 'its)
+  (require 'cl))
+
+(defvar its-pinyin-cn-open-braket  "\e$A!8\e(B" "*[") ; "\e$A#[\e(B"
+(defvar its-pinyin-cn-close-braket "\e$A!9\e(B" "*]") ; "\e$A#]\e(B"
+
+(defvar its-pinyin-tw-open-braket  "\e$(G!V\e(B" "*[") ; "\e$(G!b\e(B "
+(defvar its-pinyin-tw-close-braket "\e$(G!W\e(B" "*]") ; "\e$(G!c\e(B"
+
+(eval-when-compile
+  (defvar its-quanjiao-escape "Z")
+  (defvar its-banjiao-escape  "X")
+
+  (defconst its-pinyin-term
+    (char-to-string (make-char 'chinese-sisheng ?@)))
+
+  (defsubst its-defoutput* (input display)
+    (its-set-output (its-goto-state input nil t) display))
+
+  (defun its-prev-terminal-state (input)
+    (let ((len (length input))
+         (state (its-get-start-state its-current-map))
+         (i 0) (ret nil) kst ks)
+      (while (and (< i len)
+                 (setq state (its-get-next-state state (aref input i))))
+       (if (or (null (its-kst-p (setq kst (its-get-kst/t state))))
+               (mapcan (lambda (eob) (if (eq (its-eob-back eob) -1) (list t)))
+                       (cdr kst))
+               (and (setq ks (assq -1 (car kst)))
+                    (null (its-get-kst/t (cdr ks)))))
+           (setq ret state))
+       (setq i (1+ i)))
+      ret))
+
+  (defun its-define-qingsheng (shengmu yunmu &optional s y)
+    (let ((input (concat shengmu yunmu))
+         (output (concat (if s s (capitalize shengmu))
+                         (if y y yunmu)
+                         its-pinyin-term))
+         state term kst i len c+b)
+      (setq state (its-goto-state input nil t))
+      (its-make-next-state state -1 input output)
+      (its-make-next-state state ?  (concat input " ") output)
+      (its-make-next-state state ?0 (concat input "0") output)
+      (its-define-otherwise
+       state (its-make-otherwise output its-otherwise-back-one))
+      (setq term (its-prev-terminal-state (substring input 0 -1)))
+      (if term
+         (progn
+           (setq len (length (its-get-keyseq term))
+                 i len
+                 output (car (rassoc '(nil . -1) (cdr (its-get-kst/t term)))))
+           (while (null
+                   (eq (setq term (its-get-next-state term (aref input i)))
+                       state))
+             (setq i (1+ i) kst (its-get-kst/t term))
+             (if (null (assq -1 (car kst)))
+                 (its-make-next-state term -1
+                                      (its-get-keyseq term) output (- len i)))
+             (setq c+b (its-make-class+back nil (1- (- len i))))
+             (if (null (rassoc c+b (cdr kst)))
+                 (its-define-otherwise term
+                                       (its-make-otherwise output c+b))))))
+      state))
+
+  (defmacro its-do-sisheng-table (list)
+    `(progn ,@(mapcar (lambda (syl)
+                       `(its-define-sisheng ,(car syl) ,(cdr syl)))
+                     list)))
+
+  (defmacro its-define-sisheng (shengmu yunmu)
+    `(let ((qing (nth 5 ,yunmu)) (y (car ,yunmu))
+          (ss (list ,@shengmu)) s cs state i)
+       (while ss
+        (setq s (car ss)
+              cs (capitalize s)
+              state (its-define-qingsheng s y cs qing))
+        (setq i 1)
+        (while (<= i 4)
+          (its-make-next-state state (+ ?0 i)
+                               (concat s y i)
+                               (concat cs (nth i ,yunmu) its-pinyin-term))
+          (setq i (1+ i)))
+        (setq ss (cdr ss)))))
+
+  (defmacro its-define-pinyin-table ()
+    '(let ((- "")  (B "b") (C "c") (D "d") (F "f") (G "g") (H "h")
+          (J "j") (K "k") (L "l") (M "m") (N "n") (P "p") (Q "q")
+          (R "r") (S "s") (T "t") (W "w") (X "x") (Y "y") (Z "z")
+          (CH "ch") (SH "sh") (ZH "zh")
+
+          (A    '("a"    "\e(0!\e(B"    "\e(0"\e(B"    "\e(0#\e(B"    "\e(0$\e(B"    "a"   ))
+          (AI   '("ai"   "\e(0!\e(Bi"   "\e(0"\e(Bi"   "\e(0#\e(Bi"   "\e(0$\e(Bi"   "ai"  ))
+          (AN   '("an"   "\e(0!\e(Bn"   "\e(0"\e(Bn"   "\e(0#\e(Bn"   "\e(0$\e(Bn"   "an"  ))
+          (ANG  '("ang"  "\e(0!\e(Bng"  "\e(0"\e(Bng"  "\e(0#\e(Bng"  "\e(0$\e(Bng"  "ang" ))
+          (AO   '("ao"   "\e(0!\e(Bo"   "\e(0"\e(Bo"   "\e(0#\e(Bo"   "\e(0$\e(Bo"   "ao"  ))
+          (E    '("e"    "\e(0%\e(B"    "\e(0&\e(B"    "\e(0'\e(B"    "\e(0(\e(B"    "e"   ))
+          (EI   '("ei"   "\e(0%\e(Bi"   "\e(0&\e(Bi"   "\e(0'\e(Bi"   "\e(0(\e(Bi"   "ei"  ))
+          (EN   '("en"   "\e(0%\e(Bn"   "\e(0&\e(Bn"   "\e(0'\e(Bn"   "\e(0(\e(Bn"   "en"  ))
+          (ENG  '("eng"  "\e(0%\e(Bng"  "\e(0&\e(Bng"  "\e(0'\e(Bng"  "\e(0(\e(Bng"  "eng" ))
+          (ER   '("er"   "\e(0%\e(Br"   "\e(0&\e(Br"   "\e(0'\e(Br"   "\e(0(\e(Br"   "er"  ))
+          (I    '("i"    "\e(0)\e(B"    "\e(0*\e(B"    "\e(0+\e(B"    "\e(0,\e(B"    "i"   ))
+          (IA   '("ia"   "i\e(0!\e(B"   "i\e(0"\e(B"   "i\e(0#\e(B"   "i\e(0$\e(B"   "ia"  ))
+          (IAN  '("ian"  "i\e(0!\e(Bn"  "i\e(0"\e(Bn"  "i\e(0#\e(Bn"  "i\e(0$\e(Bn"  "ian" ))
+          (IANG '("iang" "i\e(0!\e(Bng" "i\e(0"\e(Bng" "i\e(0#\e(Bng" "i\e(0$\e(Bng" "iang"))
+          (IAO  '("iao"  "i\e(0!\e(Bo"  "i\e(0"\e(Bo"  "i\e(0#\e(Bo"  "i\e(0$\e(Bo"  "iao" ))
+          (IE   '("ie"   "i\e(0%\e(B"   "i\e(0&\e(B"   "i\e(0'\e(B"   "i\e(0(\e(B"   "ie"  ))
+          (IN   '("in"   "\e(0)\e(Bn"   "\e(0*\e(Bn"   "\e(0+\e(Bn"   "\e(0,\e(Bn"   "in"  ))
+          (ING  '("ing"  "\e(0)\e(Bng"  "\e(0*\e(Bng"  "\e(0+\e(Bng"  "\e(0,\e(Bng"  "ing" ))
+          (IONG '("iong" "i\e(0-\e(Bng" "i\e(0.\e(Bng" "i\e(0/\e(Bng" "i\e(00\e(Bng" "iong"))
+          (IU   '("iu"   "i\e(01\e(B"   "i\e(02\e(B"   "i\e(03\e(B"   "i\e(04\e(B"   "iu"  ))
+          (O    '("o"    "\e(0-\e(B"    "\e(0.\e(B"    "\e(0/\e(B"    "\e(00\e(B"    "o"   ))
+          (ONG  '("ong"  "\e(0-\e(Bng"  "\e(0.\e(Bng"  "\e(0/\e(Bng"  "\e(00\e(Bng"  "ong" ))
+          (OU   '("ou"   "\e(0-\e(Bu"   "\e(0.\e(Bu"   "\e(0/\e(Bu"   "\e(00\e(Bu"   "ou"  ))
+          (U    '("u"    "\e(01\e(B"    "\e(02\e(B"    "\e(03\e(B"    "\e(04\e(B"    "u"   ))
+          (V    '("v"    "\e(05\e(B"    "\e(06\e(B"    "\e(07\e(B"    "\e(08\e(B"    "\e(09\e(B"   ))
+          (UA   '("ua"   "u\e(0!\e(B"   "u\e(0"\e(B"   "u\e(0#\e(B"   "u\e(0$\e(B"   "ua"  ))
+          (UAI  '("uai"  "u\e(0!\e(Bi"  "u\e(0"\e(Bi"  "u\e(0#\e(Bi"  "u\e(0$\e(Bi"  "uai" ))
+          (UAN  '("uan"  "u\e(0!\e(Bn"  "u\e(0"\e(Bn"  "u\e(0#\e(Bn"  "u\e(0$\e(Bn"  "uan" ))
+          (UANG '("uang" "u\e(0!\e(Bng" "u\e(0"\e(Bng" "u\e(0#\e(Bng" "u\e(0$\e(Bng" "uang"))
+          (UE   '("ue"   "u\e(0%\e(B"   "u\e(0&\e(B"   "u\e(0'\e(B"   "u\e(0(\e(B"   "ue"  ))
+          (VE   '("ve"   "\e(09%\e(B"   "\e(09&\e(B"   "\e(09'\e(B"   "\e(09(\e(B"   "\e(09\e(Be"  ))
+          (UI   '("ui"   "u\e(0)\e(B"   "u\e(0*\e(B"   "u\e(0+\e(B"   "u\e(0,\e(B"   "ui"  ))
+          (UN   '("un"   "\e(01\e(Bn"   "\e(02\e(Bn"   "\e(03\e(Bn"   "\e(04\e(Bn"   "un"  ))
+          (UO   '("uo"   "u\e(0-\e(B"   "u\e(0.\e(B"   "u\e(0/\e(B"   "u\e(00\e(B"   "uo"  )))
+
+       (its-do-sisheng-table
+       (((- B C D F G H   K L M N P     S T W   Y Z CH SH ZH ) . A)
+        ((- B C D   G H   K L M N P     S T W     Z CH SH ZH ) . AI)
+        ((- B C D F G H   K L M N P   R S T W   Y Z CH SH ZH ) . AN)
+        ((- B C D F G H   K L M N P   R S T W   Y Z CH SH ZH ) . ANG)
+        ((- B C D   G H   K L M N P   R S T     Y Z CH SH ZH ) . AO)
+        ((-   C D   G H   K L M N     R S T     Y Z CH SH ZH ) . E)
+        ((- B C D F G H   K L M N P       T W     Z    SH ZH ) . EI)
+        ((- B C D F G H   K   M N P   R S   W     Z CH SH ZH ) . EN)
+        ((- B C D F G H   K L M N P   R S T W     Z CH SH ZH ) . ENG)
+        ((-                                                  ) . ER)
+        ((  B C D       J   L M N P Q R S T   X Y Z CH SH ZH ) . I)
+        ((      D       J   L       Q         X              ) . IA)
+        ((  B   D       J   L M N P Q     T   X              ) . IAN)
+        ((              J   L   N   Q         X              ) . IANG)
+        ((  B   D       J   L M N P Q     T   X              ) . IAO)
+        ((  B   D       J   L M N P Q     T   X              ) . IE)
+        ((  B           J   L M N P Q         X Y            ) . IN)
+        ((  B   D       J   L M N P Q     T   X Y            ) . ING)
+        ((              J           Q         X              ) . IONG)
+        ((      D       J   L M N   Q         X              ) . IU)
+        ((- B     F         L M   P         W   Y            ) . O)
+        ((    C D   G H   K L   N     R S T     Y Z CH    ZH ) . ONG)
+        ((-   C D F G H   K L M N P   R S T     Y Z CH SH ZH ) . OU)
+        ((  B C D F G H J K L M N P Q R S T W X Y Z CH SH ZH ) . U)
+        ((                  L   N                            ) . V)
+        ((          G H   K           R             CH SH ZH ) . UA)
+        ((          G H   K                         CH SH ZH ) . UAI)
+        ((    C D   G H J K L   N   Q R S T   X Y Z CH SH ZH ) . UAN)
+        ((          G H   K                         CH SH ZH ) . UANG)
+        ((              J           Q         X Y            ) . UE)
+        ((                  L   N                            ) . VE)
+        ((    C D   G H   K           R S T       Z CH SH ZH ) . UI)
+        ((    C D   G H J K L       Q R S T   X Y Z CH SH ZH ) . UN)
+        ((    C D   G H   K L   N     R S T       Z CH SH ZH ) . UO)
+
+        ((J Q X) . (cons "a"   (cdr IA  )))
+        ((J Q X) . (cons "ai"  (cdr IA  )))
+        ((J Q X) . (cons "an"  (cdr IAN )))
+        ((J Q X) . (cons "ang" (cdr IANG)))
+        ((J Q X) . (cons "ao"  (cdr IAO )))
+        ((J Q X) . (cons "e"   (cdr IE  )))
+        ((J Q X) . (cons "ei"  (cdr IE  )))
+        ((J Q X) . (cons "en"  (cdr IN  )))
+        ((J Q X) . (cons "eng" (cdr ING )))
+        ((J Q X) . (cons "ou"  (cdr IU  )))))
+
+       (its-define-qingsheng   "hm"    "")
+       (its-define-qingsheng   "hng"   "")
+       (its-define-qingsheng   ""      "ng")
+
+       (its-define-qingsheng   ""      "m")
+       (its-define-qingsheng   ""      "n")
+       (its-defrule    "n2"    "\e(0=@\e(B")
+       (its-defrule    "n3"    "\e(0>@\e(B")
+       (its-defrule    "n4"    "\e(0?@\e(B"))))
+
+(define-its-state-machine its-pinyin-cn-map
+  "pinyin-cn" "\e$AF4\e(BG" "Chinese-GB"
+  "Map for Pinyin input. (Chinese-GB)"
+  (its-define-pinyin-table)
+  (its-defoutput*      "b "    "\e$A2;\e(B")
+  (its-defoutput*      "c "    "\e$A2E\e(B")
+  (its-defoutput*      "ch "   "\e$A3v\e(B")
+  (its-defoutput*      "d "    "\e$A5D\e(B")
+  (its-defoutput*      "f "    "\e$A74\e(B")
+  (its-defoutput*      "g "    "\e$A8v\e(B")
+  (its-defoutput*      "h "    "\e$A:M\e(B")
+  (its-defoutput*      "i "    "\e$AR;\e(B")
+  (its-defoutput*      "j "    "\e$A>M\e(B")
+  (its-defoutput*      "k "    "\e$A?I\e(B")
+  (its-defoutput*      "l "    "\e$AAK\e(B")
+  (its-defoutput*      "m "    "\e$AC?\e(B")
+  (its-defoutput*      "n "    "\e$ADj\e(B")
+  (its-defoutput*      "p "    "\e$AEz\e(B")
+  (its-defoutput*      "q "    "\e$AH%\e(B")
+  (its-defoutput*      "r "    "\e$AHU\e(B")
+  (its-defoutput*      "s "    "\e$AJG\e(B")
+  (its-defoutput*      "sh "   "\e$AIO\e(B")
+  (its-defoutput*      "t "    "\e$AK{\e(B")
+  (its-defoutput*      "w "    "\e$ANR\e(B")
+  (its-defoutput*      "x "    "\e$AOr\e(B")
+  (its-defoutput*      "y "    "\e$ASV\e(B")
+  (its-defoutput*      "z "    "\e$ATZ\e(B")
+  (its-defoutput*      "zh "   "\e$AWE\e(B")
+
+  (dolist (ascii '(("0" . "\e$A#0\e(B")  ("1" . "\e$A#1\e(B")  ("2" . "\e$A#2\e(B")  ("3" . "\e$A#3\e(B")
+                  ("4" . "\e$A#4\e(B")  ("5" . "\e$A#5\e(B")  ("6" . "\e$A#6\e(B")  ("7" . "\e$A#7\e(B")
+                  ("8" . "\e$A#8\e(B")  ("9" . "\e$A#9\e(B") 
+                  (" " . "\e$A!!\e(B")  ("!" . "\e$A#!\e(B")  ("@" . "\e$A#@\e(B")  ("#" . "\e$A##\e(B")
+                  ("$" . "\e$A!g\e(B")  ("%" . "\e$A#%\e(B")  ("^" . "\e$A#^\e(B")  ("&" . "\e$A#&\e(B")
+                  ("*" . "\e$A#*\e(B")  ("(" . "\e$A#(\e(B")  (")" . "\e$A#)\e(B")
+                  ("-" . "\e$A#-\e(B")  ("=" . "\e$A#=\e(B")  ("`" . "\e$A#`\e(B")  ("\\" . "\e$A#\\e(B")
+                  ("|" . "\e$A#|\e(B")  ("_" . "\e$A#_\e(B")  ("+" . "\e$A#+\e(B")  ("~" . "\e$A!+\e(B")
+                  ("[" . "\e$A#[\e(B")  ("]" . "\e$A#]\e(B")  ("{" . "\e$A#{\e(B")  ("}" . "\e$A#}\e(B")
+                  (":" . "\e$A#:\e(B")  (";" . "\e$A#;\e(B")  ("\"" . "\e$A#"\e(B") ("'" . "\e$A#'\e(B")
+                  ("<" . "\e$A#<\e(B")  (">" . "\e$A#>\e(B")  ("?" . "\e$A#?\e(B")  ("/" . "\e$A#/\e(B")
+                  ("," . "\e$A#,\e(B")  ("." . "\e$A#.\e(B")
+                  ("a" . "\e$A#a\e(B")  ("b" . "\e$A#b\e(B")  ("c" . "\e$A#c\e(B")  ("d" . "\e$A#d\e(B")
+                  ("e" . "\e$A#e\e(B")  ("f" . "\e$A#f\e(B")  ("g" . "\e$A#g\e(B")  ("h" . "\e$A#h\e(B")
+                  ("i" . "\e$A#i\e(B")  ("j" . "\e$A#j\e(B")  ("k" . "\e$A#k\e(B")  ("l" . "\e$A#l\e(B")
+                  ("m" . "\e$A#m\e(B")  ("n" . "\e$A#n\e(B")  ("o" . "\e$A#o\e(B")  ("p" . "\e$A#p\e(B")
+                  ("q" . "\e$A#q\e(B")  ("r" . "\e$A#r\e(B")  ("s" . "\e$A#s\e(B")  ("t" . "\e$A#t\e(B")
+                  ("u" . "\e$A#u\e(B")  ("v" . "\e$A#v\e(B")  ("w" . "\e$A#w\e(B")  ("x" . "\e$A#x\e(B")
+                  ("y" . "\e$A#y\e(B")  ("z" . "\e$A#z\e(B")
+                  ("A" . "\e$A#A\e(B")  ("B" . "\e$A#B\e(B")  ("C" . "\e$A#C\e(B")  ("D" . "\e$A#D\e(B")
+                  ("E" . "\e$A#E\e(B")  ("F" . "\e$A#F\e(B")  ("G" . "\e$A#G\e(B")  ("H" . "\e$A#H\e(B")
+                  ("I" . "\e$A#I\e(B")  ("J" . "\e$A#J\e(B")  ("K" . "\e$A#K\e(B")  ("L" . "\e$A#L\e(B")
+                  ("M" . "\e$A#M\e(B")  ("N" . "\e$A#N\e(B")  ("O" . "\e$A#O\e(B")  ("P" . "\e$A#P\e(B")
+                  ("Q" . "\e$A#Q\e(B")  ("R" . "\e$A#R\e(B")  ("S" . "\e$A#S\e(B")  ("T" . "\e$A#T\e(B")
+                  ("U" . "\e$A#U\e(B")  ("V" . "\e$A#V\e(B")  ("W" . "\e$A#W\e(B")  ("X" . "\e$A#X\e(B")
+                  ("Y" . "\e$A#Y\e(B")  ("Z" . "\e$A#Z\e(B")))
+    (let ((in (car ascii)) (out (cdr ascii)))
+      (if (and (or (string< in "a") (string< "z" in))
+              (null (equal in " "))
+              (null (equal in its-banjiao-escape))
+              (null (equal in its-quanjiao-escape)))
+         (progn
+           (its-defrule in in)
+           (its-defrule (concat (downcase its-banjiao-escape) in) in)
+           (its-defrule (concat (downcase its-quanjiao-escape) in) out)))
+      (its-defrule (concat its-banjiao-escape in) in)
+      (its-defrule (concat its-quanjiao-escape in) out)))
+
+  (its-defrule ","     "\e$A#,\e(B"      nil t)
+  (its-defrule "."     "\e$A!#\e(B"      nil t)
+  (its-defrule "/"     "\e$A!"\e(B"      nil t)
+  (its-defrule ":"     "\e$A#:\e(B"      nil t)
+  (its-defrule ";"     "\e$A#;\e(B"      nil t)
+  (its-defrule "?"     "\e$A#?\e(B"      nil t)
+  (its-defrule "!"     "\e$A#!\e(B"      nil t)
+  (its-defrule "-"     "\e$A!*\e(B"      nil t))
+
+(define-its-state-machine its-pinyin-tw-map
+  "pinyin-tw" "\e$(GQ;\e(BC" "Chinese-CNS"
+  "Map for Pinyin input."
+  (its-define-pinyin-table)
+  (its-defoutput*      "b "    "\e$(GDb\e(B")
+  (its-defoutput*      "c "    "\e$(GD_\e(B")
+  (its-defoutput*      "ch "   "\e$(GEx\e(B")
+  (its-defoutput*      "d "    "\e$(GN{\e(B")
+  (its-defoutput*      "f "    "\e$(GE0\e(B")
+  (its-defoutput*      "g "    "\e$(GT6\e(B")
+  (its-defoutput*      "h "    "\e$(GLO\e(B")
+  (its-defoutput*      "i "    "\e$(GD!\e(B")
+  (its-defoutput*      "j "    "\e$(G^s\e(B")
+  (its-defoutput*      "k "    "\e$(GF+\e(B")
+  (its-defoutput*      "l "    "\e$(GD'\e(B")
+  (its-defoutput*      "m "    "\e$(GJd\e(B")
+  (its-defoutput*      "n "    "\e$(GH!\e(B")
+  (its-defoutput*      "p "    "\e$(GJG\e(B")
+  (its-defoutput*      "q "    "\e$(GF*\e(B")
+  (its-defoutput*      "r "    "\e$(GEJ\e(B")
+  (its-defoutput*      "s "    "\e$(GQR\e(B")
+  (its-defoutput*      "sh "   "\e$(GD8\e(B")
+  (its-defoutput*      "t "    "\e$(GEl\e(B")
+  (its-defoutput*      "w "    "\e$(GJ<\e(B")
+  (its-defoutput*      "x "    "\e$(GGW\e(B")
+  (its-defoutput*      "y "    "\e$(GD4\e(B")
+  (its-defoutput*      "z "    "\e$(GGc\e(B")
+  (its-defoutput*      "zh "   "\e$(Gaa\e(B")
+
+  (dolist (ascii '(("0" . "\e$(G$!\e(B")  ("1" . "\e$(G$"\e(B")  ("2" . "\e$(G$#\e(B")  ("3" . "\e$(G$$\e(B")
+                  ("4" . "\e$(G$%\e(B")  ("5" . "\e$(G$&\e(B")  ("6" . "\e$(G$'\e(B")  ("7" . "\e$(G$(\e(B")
+                  ("8" . "\e$(G$)\e(B")  ("9" . "\e$(G$*\e(B") 
+                  (" " . "\e$(G!!\e(B")  ("!" . "\e$(G!*\e(B")  ("@" . "\e$(G"i\e(B")  ("#" . "\e$(G!l\e(B")
+                  ("$" . "\e$(G"c\e(B")  ("%" . "\e$(G"h\e(B")  ("^" . "\e$(G!T\e(B")  ("&" . "\e$(G!m\e(B")
+                  ("*" . "\e$(G!n\e(B")  ("(" . "\e$(G!>\e(B")  (")" . "\e$(G!?\e(B")
+                  ("-" . "\e$(G"1\e(B")  ("=" . "\e$(G"8\e(B")  ("`" . "\e$(G!j\e(B")  ("\\" . "\e$(G"b\e(B")
+                  ("|" . "\e$(G"^\e(B")  ("_" . "\e$(G"%\e(B")  ("+" . "\e$(G"0\e(B")  ("~" . "\e$(G"D\e(B")
+                  ("[" . "\e$(G!b\e(B")  ("]" . "\e$(G!c\e(B")  ("{" . "\e$A#{\e(B")  ("}" . "\e$(G!a\e(B")
+                  (":" . "\e$(G!(\e(B")  (";" . "\e$(G!'\e(B")  ("\"" . "\e$(G!i\e(B") ("'" . "\e$(G!k\e(B")
+                  ("<" . "\e$(G"6\e(B")  (">" . "\e$(G"7\e(B")  ("?" . "\e$(G!)\e(B")  ("/" . "\e$(G"a\e(B")
+                  ("," . "\e$(G!"\e(B")  ("." . "\e$(G!%\e(B")
+                  ("a" . "\e$(G$[\e(B")  ("b" . "\e$(G$\\e(B")  ("c" . "\e$(G$]\e(B")  ("d" . "\e$(G$^\e(B")
+                  ("e" . "\e$(G$_\e(B")  ("f" . "\e$(G$`\e(B")  ("g" . "\e$(G$a\e(B")  ("h" . "\e$(G$b\e(B")
+                  ("i" . "\e$(G$c\e(B")  ("j" . "\e$(G$d\e(B")  ("k" . "\e$(G$e\e(B")  ("l" . "\e$(G$f\e(B")
+                  ("m" . "\e$(G$g\e(B")  ("n" . "\e$(G$h\e(B")  ("o" . "\e$(G$i\e(B")  ("p" . "\e$(G$j\e(B")
+                  ("q" . "\e$(G$k\e(B")  ("r" . "\e$(G$l\e(B")  ("s" . "\e$(G$m\e(B")  ("t" . "\e$(G$n\e(B")
+                  ("u" . "\e$(G$o\e(B")  ("v" . "\e$(G$p\e(B")  ("w" . "\e$(G$q\e(B")  ("x" . "\e$(G$r\e(B")
+                  ("y" . "\e$(G$s\e(B")  ("z" . "\e$(G$t\e(B")
+                  ("A" . "\e$(G$A\e(B")  ("B" . "\e$(G$B\e(B")  ("C" . "\e$(G$C\e(B")  ("D" . "\e$(G$D\e(B")
+                  ("E" . "\e$(G$E\e(B")  ("F" . "\e$(G$F\e(B")  ("G" . "\e$(G$G\e(B")  ("H" . "\e$(G$H\e(B")
+                  ("I" . "\e$(G$I\e(B")  ("J" . "\e$(G$J\e(B")  ("K" . "\e$(G$K\e(B")  ("L" . "\e$(G$L\e(B")
+                  ("M" . "\e$(G$M\e(B")  ("N" . "\e$(G$N\e(B")  ("O" . "\e$(G$O\e(B")  ("P" . "\e$(G$P\e(B")
+                  ("Q" . "\e$(G$Q\e(B")  ("R" . "\e$(G$R\e(B")  ("S" . "\e$(G$S\e(B")  ("T" . "\e$(G$T\e(B")
+                  ("U" . "\e$(G$U\e(B")  ("V" . "\e$(G$V\e(B")  ("W" . "\e$(G$W\e(B")  ("X" . "\e$(G$X\e(B")
+                  ("Y" . "\e$(G$Y\e(B")  ("Z" . "\e$(G$Z\e(B")))
+    (let ((in (car ascii)) (out (cdr ascii)))
+      (if (and (or (string< in "a") (string< "z" in))
+              (null (equal in " "))
+              (null (equal in its-banjiao-escape))
+              (null (equal in its-quanjiao-escape)))
+         (progn
+           (its-defrule in in)
+           (its-defrule (concat (downcase its-banjiao-escape) in) in)
+           (its-defrule (concat (downcase its-quanjiao-escape) in) out)))
+      (its-defrule (concat its-banjiao-escape in) in)
+      (its-defrule (concat its-quanjiao-escape in) out)))
+
+  (its-defrule ","     "\e$(G!"\e(B"     nil t)
+  (its-defrule "."     "\e$(G!$\e(B"     nil t)
+  (its-defrule "/"     "\e$(G!#\e(B"     nil t)
+  (its-defrule ":"     "\e$(G!(\e(B"     nil t)
+  (its-defrule ";"     "\e$(G!'\e(B"     nil t)
+  (its-defrule "?"     "\e$(G!)\e(B"     nil t)
+  (its-defrule "!"     "\e$(G!*\e(B"     nil t)
+  (its-defrule "-"     "\e$(G"1\e(B"     nil t)
+  (its-defrule "["     "\e$(G!V\e(B"     nil t)
+  (its-defrule "]"     "\e$(G!W\e(B"     nil t))
+
+(define-its-state-machine-append its-pinyin-cn-map
+  (its-defrule "[" its-pinyin-cn-open-braket  nil t)
+  (its-defrule "]" its-pinyin-cn-close-braket nil t))
+
+(define-its-state-machine-append its-pinyin-tw-map
+  (its-defrule "[" its-pinyin-tw-open-braket  nil t)
+  (its-defrule "]" its-pinyin-tw-close-braket nil t))
+
+(provide 'its/pinyin)