;; Author: NIIBE Yutaka <gniibe@chroot.org>
;; KATAYAMA Yoshio <kate@pfu.co.jp>
-;; Maintainer: TOMURA Satoru <tomura@etl.go.jp>
-
;; Keywords: mule, multilingual, input method
;; This file is part of EGG.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc.,
+;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
;;; Commentary:
;;; Code:
-(require 'cl)
+(eval-when-compile
+ (require 'cl))
+
(require 'egg-edep)
(defgroup its nil
- "Input Translation System of Tamagotchy"
+ "Input Translation System of Tamago-tsunagi."
:group 'egg)
(defcustom its-enable-fullwidth-alphabet t
:group 'its :type 'boolean)
(defcustom its-delete-by-keystroke nil
- "*Delete characters as if cancel input keystroke, if nin-NIL."
+ "*Delete characters as if cancel input keystroke, if nin-NIL.
+This variable is overriden by `its-delete-by-character'."
+ :group 'its :type 'boolean)
+
+(defcustom its-delete-by-character nil
+ "*Delete a character as a unit even if just after input, if nin-NIL.
+This variable override `its-delete-by-keystroke'."
:group 'its :type 'boolean)
(defcustom its-fence-invisible nil
(make-variable-buffer-local 'its-previous-select-func)
(put 'its-previous-select-func 'permanent-local t)
-(defvar its-current-language)
+(defvar its-current-language nil)
(make-variable-buffer-local 'its-current-language)
(put 'its-current-language 'permanent-local t)
\f
(defsubst its-kst-p (kst/t)
(not (or (numberp kst/t) (null kst/t))))
-(defsubst its-get-output (syl/state)
- (car syl/state))
+(defun its-get-output (syl/state &optional no-eval)
+ (setq syl/state (car syl/state))
+ (cond ((null (consp syl/state))
+ syl/state)
+ ((and (null no-eval) (eq (car syl/state) 'eval))
+ (eval (mapcar (lambda (s) (if (stringp s) (copy-sequence s) s))
+ (cdr syl/state))))
+ (t
+ (copy-sequence syl/state))))
(defsubst its-set-output (state output)
(setcar state output))
(if (consp (cdr syl))
(cons (its-get-output syl) (its-get-keyseq-syl syl))
syl))
-
+
;;
;;
(define-key map "\M-y" 'its-yank-pop)
(define-key map [backspace] 'its-delete-backward-SYL)
(define-key map [delete] 'its-delete-backward-SYL)
- (define-key map [M-backspace] 'its-delete-backward-SYL-by-keystroke)
- (define-key map [M-delete] 'its-delete-backward-SYL-by-keystroke)
+ (define-key map [(meta backspace)] 'its-delete-backward-SYL-by-keystroke)
+ (define-key map [(meta delete)] 'its-delete-backward-SYL-by-keystroke)
(define-key map [right] 'its-forward-SYL)
(define-key map [left] 'its-backward-SYL)
(while (< i 127)
(define-key map "\M-n" 'its-next-map)
(define-key map "\M-h" 'its-hiragana) ; hiragana-region for input-buffer
(define-key map "\M-k" 'its-katakana)
- (define-key map "\M-<" 'its-hankaku)
- (define-key map "\M->" 'its-zenkaku)
+ (define-key map "\M-<" 'its-half-width)
+ (define-key map "\M->" 'its-full-width)
map)
"Keymap for ITS mode.")
-
(fset 'its-mode-map its-mode-map)
+(defvar its-fence-mode nil)
+(make-variable-buffer-local 'its-fence-mode)
+(put 'its-fence-mode 'permanent-local t)
+
+(defvar egg-sub-mode-map-alist nil)
+(or (assq 'its-fence-mode egg-sub-mode-map-alist)
+ (setq egg-sub-mode-map-alist (cons '(its-fence-mode . its-mode-map)
+ egg-sub-mode-map-alist)))
+
+(defun its-enter/leave-fence (&optional old new)
+ (setq its-fence-mode (its-in-fence-p)))
+
+(add-hook 'egg-enter/leave-fence-hook 'its-enter/leave-fence)
+
(defconst its-setup-fence-before-insert-SYL nil)
(defun its-get-fence-face (lang)
(assq t its-fence-face)))))
(defun its-put-cursor (cursor)
- (if (null (eq its-barf-on-invalid-keyseq 'its-keyseq-test))
- (let ((p (point))
- (str (copy-sequence "!")))
- (set-text-properties 0 1 (list 'local-map 'its-mode-map
- 'read-only t
- 'invisible t
- 'intangible 'its-part-2
- 'its-cursor cursor)
- str)
- (insert str)
- (goto-char p))))
+ (unless (eq its-barf-on-invalid-keyseq 'its-keyseq-test)
+ (let ((p (point))
+ (str (copy-sequence "!")))
+ (set-text-properties 0 1 (list 'read-only t
+ 'invisible 'egg
+ 'intangible 'its-part-2
+ 'its-cursor cursor
+ 'point-entered 'egg-enter/leave-fence
+ 'point-left 'egg-enter/leave-fence
+ 'modification-hooks '(egg-modify-fence))
+ str)
+ (insert str)
+ (goto-char p))))
(defun its-set-cursor-status (cursor)
(delete-region (point) (1+ (point)))
(error "invalid fence"))
;; Put open-fence before inhibit-read-only to detect read-only
(insert (if its-context its-fence-continue its-fence-open))
+ (egg-setup-invisibility-spec)
(let ((inhibit-read-only t))
(setq p1 (point))
(add-text-properties p p1 open-props)
(insert its-fence-close)
(add-text-properties p1 (point) close-props)
(if its-fence-invisible
- (put-text-property p (point) 'invisible t))
+ (put-text-property p (point) 'invisible 'egg))
(put-text-property p (point) 'read-only t)
(goto-char p1)
(its-define-select-keys its-mode-map t)
(defun its-self-insert-char ()
(interactive)
(let ((inhibit-read-only t)
- (key last-command-char)
+ (key last-command-event)
(cursor (get-text-property (point) 'its-cursor))
(syl (get-text-property (1- (point)) 'its-syl)))
(cond
(add-hook hook func t)
(funcall func)
(run-hooks hook)
- (setq hook nil))))
+ (set hook nil))))
;; Data structure for map compaction
;; <node> ::= (<count> <node#> <original node>) ; atom
;; | (<count> <node#> (<node> . <node>)) ; cons cell
;;
;; <count> ::= integer ; 0 or negative - usage count
-;; ; psotive - generated common sub-tree
+;; ; positive - generated common sub-tree
;;
;; <node#> ::= integer ; subject to compaction
;; | nil ; not subject to compaction
`(1- (setq its-compaction-list (cons ,node its-compaction-list)
its-compaction-counter-2 (1+ its-compaction-counter-2))))
+(defmacro its-concat (&rest args)
+ `(concat ,@(mapcar (lambda (arg)
+ (if (stringp arg)
+ arg
+ `(if (numberp ,arg) (number-to-string ,arg) ,arg)))
+ args)))
+
(defmacro its-compaction-hash (name node parent lr type)
(if (null type)
- `(let ((hash (intern (concat ,@name) its-compaction-hash-table)))
+ `(let ((hash (intern (its-concat ,@name) its-compaction-hash-table)))
(if (null (boundp hash))
(car (set hash (list* (its-compaction-new-node) ,parent ,lr)))
(setq hash (symbol-value hash))
(its-compaction-set-lr ,parent ,lr (cdr hash))
(car hash)))
`(let ((hash ,(if (eq type 'integer)
- `(intern (concat ,@name) its-compaction-hash-table)
+ `(intern (its-concat ,@name) its-compaction-hash-table)
`(aref its-compaction-integer-table (+ ,node 10)))))
(if (null ,(if (eq type 'integer) '(boundp hash) 'hash))
(setq hash (,@(if (eq type 'integer)
(its-compaction-set-lr ,parent ,lr (cdr hash))
(car hash))))
-(defun its-map-compaction-internal (map parent lr)
+(defun its-map-compaction-internal (map parent lr &optional force)
(cond
- ((consp map) (let ((candidate (or (null (stringp (car map))) (cdr map)))
- (l (its-map-compaction-internal (car map) map 'car))
- (r (its-map-compaction-internal (cdr map) map 'cdr)))
- (if (and candidate l r)
- (its-compaction-hash (l " " r) map parent lr nil))))
- ((stringp map) (its-compaction-hash ("STR" map) map parent lr nil))
- ((integerp map) (if (and (>= map -10) (< map 128))
- (its-compaction-hash nil map parent lr small-int)
- (its-compaction-hash ("INT" map) map parent lr integer)))
- ((null map) 0)))
+ ((consp map)
+ (let* ((candidate (or (null (stringp (car map))) (cdr map)))
+ (sexp (or force (eq (car map) 'eval)))
+ (l (its-map-compaction-internal (car map) map 'car sexp))
+ (r (its-map-compaction-internal (cdr map) map 'cdr sexp)))
+ (if (or sexp (and candidate l r))
+ (its-compaction-hash (l " " r) map parent lr nil))))
+ ((stringp map)
+ (its-compaction-hash ("STR" map) map parent lr nil))
+ ((integerp map)
+ (if (and (>= map -10) (< map 128))
+ (its-compaction-hash nil map parent lr small-int)
+ (its-compaction-hash ("INT" map) map parent lr integer)))
+ ((null map) 0)
+ ((symbolp map)
+ (its-compaction-hash ("SYM" (symbol-name map)) map parent lr nil))))
(defvar its-map-rebuild-subtrees)
(setq state next-state))
((null build-if-none)
(error "No such state (%s)" input))
- (t
+ (t
(if (not (or brand-new (= i 1) (its-get-kst/t state)))
(its-set-interim-terminal-state state))
(setq state (its-make-next-state state key
state))
(defun its-set-interim-terminal-state (state &optional output)
- (its-make-next-state state -1 (or output (its-get-output state)))
+ (its-make-next-state state -1 (or output (its-get-output state t)))
(its-defrule-otherwise state output))
(defun its-defoutput (input display)
(cursor (get-text-property (point) 'its-cursor)))
(if (null syl)
(signal 'beginning-of-buffer nil)
- (if (eq cursor t)
+ (if (or (eq cursor t) (and cursor its-delete-by-character))
(its-delete-backward-SYL-internal n killflag)
(its-delete-backward-within-SYL syl n killflag)))))
(signal 'beginning-of-buffer nil))
(delete-region p (point))
(if (> len n)
- (its-state-machine-keyseq (substring keyseq 0 (- len n))
+ (its-state-machine-keyseq (substring keyseq 0 (- len n))
'its-buffer-ins/del-SYL)
(its-set-cursor-status
(if (or (null its-delete-by-keystroke)
(setq i 0)
(while (< i len)
(setq lang (get-text-property i 'egg-lang source))
- (if (and
- (or (eq lang 'Chinese-GB) (eq lang 'Chinese-CNS))
- (setq l (egg-chinese-syllable source i)))
- (setq j (+ i l))
+ (if (or (and (or (eq lang 'Chinese-GB) (eq lang 'Chinese-CNS))
+ (setq l (egg-chinese-syllable source i)))
+ (and (setq l (get-text-property i 'composition source))
+ (setq l (if (consp (car l)) (caar l) (cadr l)))
+ (eq (next-single-property-change i 'composition
+ source (length source))
+ l)))
+ (setq j (+ i l))
(setq j (+ i (egg-char-bytes (egg-string-to-char-at source i)))))
(setq syl (substring no-prop-source i j))
(put-text-property i j 'its-syl (cons syl syl) source)
;; TODO: handle overwrite-mode, insertion-hook, fill...
(defun its-exit-mode-internal (&optional proceed-to-conversion n)
- (let (start end s context)
+ (let (start end s context str)
(its-select-previous-mode t)
;; Delete CURSOR
(delete-region (point) (1+ (point)))
(egg-convert-region start end context n)
;; Remove all properties
(goto-char start)
- (insert (prog1
- (buffer-substring-no-properties start end)
- (delete-region start end)))
+ (setq str (buffer-substring start end))
+ (egg-remove-all-text-properties 0 (length str) str)
+ (delete-region start end)
+ (insert str)
(egg-do-auto-fill)
(run-hooks 'input-method-after-insert-chunk-hook))))
(interactive "P")
(let ((syl (and (null (get-text-property (point) 'its-cursor))
(get-text-property (1- (point)) 'its-syl))))
- (if (its-keyseq-acceptable-p (vector last-command-char) syl)
+ (if (its-keyseq-acceptable-p (vector last-command-event) syl)
(its-self-insert-char)
(its-kick-convert-region n))))
(defun its-in-fence-p ()
- (eq (get-text-property (point) 'intangible) 'its-part-2))
+ (and (eq (get-text-property (point) 'intangible) 'its-part-2)
+ (get-text-property (point) 'read-only)))
\f
(defvar its-translation-result "" "")
(defun its-translate-region (start end)
(interactive "r")
(its-translate-region-internal start end)
- (set-text-properties start (point) nil))
+ (egg-remove-all-text-properties start (point)))
(defun its-translate-region-internal (start end)
(setq its-translation-result "")
;;; its-hiragana : hiragana-region for input-buffer
(defun its-hiragana ()
(interactive)
- (let ((inhibit-read-only t))
- (its-input-end)
- (its-set-part-1 (point) (its-search-end))
- (its-convert 'japanese-hiragana (its-search-beginning) (point))
- (its-put-cursor t)))
+ (its-convert (lambda (str lang) (japanese-hiragana str))))
;;; its-katakana : katanaka-region for input-buffer
(defun its-katakana ()
(interactive)
- (let ((inhibit-read-only t))
- (its-input-end)
- (its-set-part-1 (point) (its-search-end))
- (its-convert 'japanese-katakana (its-search-beginning) (point))
- (its-put-cursor t)))
-
-;;; its-hankaku : hankaku-region for input-buffer
-(defun its-hankaku ()
+ (its-convert (lambda (str lang) (japanese-katakana str))))
+
+(defconst its-full-half-table (make-vector 100 nil))
+(defconst its-half-full-table (make-vector 100 nil))
+
+(let ((table '((Japanese
+ (?\e$B!!\e(B . ?\ ) (?\e$B!$\e(B . ?,) (?\e$B!%\e(B . ?.) (?\e$B!"\e(B . ?,) (?\e$B!#\e(B . ?.)
+ (?\e$B!'\e(B . ?:) (?\e$B!(\e(B . ?\;) (?\e$B!)\e(B . ??) (?\e$B!*\e(B . ?!)
+ (?\e$B!-\e(B . ?') (?\e$B!.\e(B . ?`) (?\e$B!0\e(B . ?^) (?\e$B!2\e(B . ?_) (?\e$B!1\e(B . ?~)
+ (?\e$B!<\e(B . ?-) (?\e$B!=\e(B . ?-) (?\e$B!>\e(B . ?-)
+ (?\e$B!?\e(B . ?/) (?\e$B!@\e(B . ?\\) (?\e$B!A\e(B . ?~) (?\e$B!C\e(B . ?|)
+ (?\e$B!F\e(B . ?`) (?\e$B!G\e(B . ?') (?\e$B!H\e(B . ?\") (?\e$B!I\e(B . ?\")
+ (?\e$B!J\e(B . ?\() (?\e$B!K\e(B . ?\)) (?\e$B!N\e(B . ?[) (?\e$B!O\e(B . ?])
+ (?\e$B!P\e(B . ?{) (?\e$B!Q\e(B . ?}) (?\e$B!R\e(B . ?<) (?\e$B!S\e(B . ?>)
+ (?\e$B!\\e(B . ?+) (?\e$B!]\e(B . ?-) (?\e$B!a\e(B . ?=) (?\e$B!c\e(B . ?<) (?\e$B!d\e(B . ?>)
+ (?\e$B!l\e(B . ?') (?\e$B!m\e(B . ?\") (?\e$B!o\e(B . ?\\) (?\e$B!p\e(B . ?$) (?\e$B!s\e(B . ?%)
+ (?\e$B!t\e(B . ?#) (?\e$B!u\e(B . ?&) (?\e$B!v\e(B . ?*) (?\e$B!w\e(B . ?@)
+ (?\e$B#0\e(B . ?0) (?\e$B#1\e(B . ?1) (?\e$B#2\e(B . ?2) (?\e$B#3\e(B . ?3) (?\e$B#4\e(B . ?4)
+ (?\e$B#5\e(B . ?5) (?\e$B#6\e(B . ?6) (?\e$B#7\e(B . ?7) (?\e$B#8\e(B . ?8) (?\e$B#9\e(B . ?9)
+ (?\e$B#A\e(B . ?A) (?\e$B#B\e(B . ?B) (?\e$B#C\e(B . ?C) (?\e$B#D\e(B . ?D) (?\e$B#E\e(B . ?E)
+ (?\e$B#F\e(B . ?F) (?\e$B#G\e(B . ?G) (?\e$B#H\e(B . ?H) (?\e$B#I\e(B . ?I) (?\e$B#J\e(B . ?J)
+ (?\e$B#K\e(B . ?K) (?\e$B#L\e(B . ?L) (?\e$B#M\e(B . ?M) (?\e$B#N\e(B . ?N) (?\e$B#O\e(B . ?O)
+ (?\e$B#P\e(B . ?P) (?\e$B#Q\e(B . ?Q) (?\e$B#R\e(B . ?R) (?\e$B#S\e(B . ?S) (?\e$B#T\e(B . ?T)
+ (?\e$B#U\e(B . ?U) (?\e$B#V\e(B . ?V) (?\e$B#W\e(B . ?W) (?\e$B#X\e(B . ?X) (?\e$B#Y\e(B . ?Y)
+ (?\e$B#Z\e(B . ?Z)
+ (?\e$B#a\e(B . ?a) (?\e$B#b\e(B . ?b) (?\e$B#c\e(B . ?c) (?\e$B#d\e(B . ?d) (?\e$B#e\e(B . ?e)
+ (?\e$B#f\e(B . ?f) (?\e$B#g\e(B . ?g) (?\e$B#h\e(B . ?h) (?\e$B#i\e(B . ?i) (?\e$B#j\e(B . ?j)
+ (?\e$B#k\e(B . ?k) (?\e$B#l\e(B . ?l) (?\e$B#m\e(B . ?m) (?\e$B#n\e(B . ?n) (?\e$B#o\e(B . ?o)
+ (?\e$B#p\e(B . ?p) (?\e$B#q\e(B . ?q) (?\e$B#r\e(B . ?r) (?\e$B#s\e(B . ?s) (?\e$B#t\e(B . ?t)
+ (?\e$B#u\e(B . ?u) (?\e$B#v\e(B . ?v) (?\e$B#w\e(B . ?w) (?\e$B#x\e(B . ?x) (?\e$B#y\e(B . ?y)
+ (?\e$B#z\e(B . ?z))
+ (Chinese-GB
+ (?\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!0\e(B . ?\") (?\e$A!1\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#0\e(B . ?0) (?\e$A#1\e(B . ?1) (?\e$A#2\e(B . ?2) (?\e$A#3\e(B . ?3) (?\e$A#4\e(B . ?4)
+ (?\e$A#5\e(B . ?5) (?\e$A#6\e(B . ?6) (?\e$A#7\e(B . ?7) (?\e$A#8\e(B . ?8) (?\e$A#9\e(B . ?9)
+ (?\e$A#A\e(B . ?A) (?\e$A#B\e(B . ?B) (?\e$A#C\e(B . ?C) (?\e$A#D\e(B . ?D) (?\e$A#E\e(B . ?E)
+ (?\e$A#F\e(B . ?F) (?\e$A#G\e(B . ?G) (?\e$A#H\e(B . ?H) (?\e$A#I\e(B . ?I) (?\e$A#J\e(B . ?J)
+ (?\e$A#K\e(B . ?K) (?\e$A#L\e(B . ?L) (?\e$A#M\e(B . ?M) (?\e$A#N\e(B . ?N) (?\e$A#O\e(B . ?O)
+ (?\e$A#P\e(B . ?P) (?\e$A#Q\e(B . ?Q) (?\e$A#R\e(B . ?R) (?\e$A#S\e(B . ?S) (?\e$A#T\e(B . ?T)
+ (?\e$A#U\e(B . ?U) (?\e$A#V\e(B . ?V) (?\e$A#W\e(B . ?W) (?\e$A#X\e(B . ?X) (?\e$A#Y\e(B . ?Y)
+ (?\e$A#Z\e(B . ?Z)
+ (?\e$A#a\e(B . ?a) (?\e$A#b\e(B . ?b) (?\e$A#c\e(B . ?c) (?\e$A#d\e(B . ?d) (?\e$A#e\e(B . ?e)
+ (?\e$A#f\e(B . ?f) (?\e$A#g\e(B . ?g) (?\e$A#h\e(B . ?h) (?\e$A#i\e(B . ?i) (?\e$A#j\e(B . ?j)
+ (?\e$A#k\e(B . ?k) (?\e$A#l\e(B . ?l) (?\e$A#m\e(B . ?m) (?\e$A#n\e(B . ?n) (?\e$A#o\e(B . ?o)
+ (?\e$A#p\e(B . ?p) (?\e$A#q\e(B . ?q) (?\e$A#r\e(B . ?r) (?\e$A#s\e(B . ?s) (?\e$A#t\e(B . ?t)
+ (?\e$A#u\e(B . ?u) (?\e$A#v\e(B . ?v) (?\e$A#w\e(B . ?w) (?\e$A#x\e(B . ?x) (?\e$A#y\e(B . ?y)
+ (?\e$A#z\e(B . ?z))
+ (Chinese-CNS
+ (?\e$(G!!\e(B . ?\ ) (?\e$(G!"\e(B . ?,) (?\e$(G!%\e(B . ?.) (?\e$(G!#\e(B . ?,) (?\e$(G!$\e(B . ?.)
+ (?\e$(G!(\e(B . ?:) (?\e$(G!'\e(B . ?\;) (?\e$(G!)\e(B . ??) (?\e$(G!*\e(B . ?!)
+ (?\e$(G!k\e(B . ?') (?\e$(G!j\e(B . ?`) (?\e$(G!T\e(B . ?^) (?\e$(G"%\e(B . ?_) (?\e$(G"#\e(B . ?~)
+ (?\e$(G"@\e(B . ?-)
+ (?\e$(G"_\e(B . ?/) (?\e$(G"`\e(B . ?\\) (?\e$(G"a\e(B . ?/) (?\e$(G"b\e(B . ?\\)
+ (?\e$(G"D\e(B . ?~) (?\e$(G"^\e(B . ?|)
+ (?\e$(G!d\e(B . ?`) (?\e$(G!e\e(B . ?')
+ (?\e$(G!h\e(B . ?\") (?\e$(G!i\e(B . ?\") (?\e$(G!f\e(B . ?\") (?\e$(G!g\e(B . ?\")
+ (?\e$(G!>\e(B . ?\() (?\e$(G!?\e(B . ?\))
+ (?\e$(G!F\e(B . ?[) (?\e$(G!G\e(B . ?]) (?\e$(G!b\e(B . ?[) (?\e$(G!c\e(B . ?])
+ (?\e$(G!B\e(B . ?{) (?\e$(G!C\e(B . ?}) (?\e$(G!`\e(B . ?{) (?\e$(G!a\e(B . ?})
+ (?\e$(G!R\e(B . ?<) (?\e$(G!S\e(B . ?>)
+ (?\e$(G"0\e(B . ?+) (?\e$(G"1\e(B . ?-) (?\e$(G"8\e(B . ?=) (?\e$(G"6\e(B . ?<) (?\e$(G"7\e(B . ?>)
+ (?\e$(G"c\e(B . ?$) (?\e$(G"h\e(B . ?%)
+ (?\e$(G!l\e(B . ?#) (?\e$(G!m\e(B . ?&) (?\e$(G!n\e(B . ?*) (?\e$(G"i\e(B . ?@)
+ (?\e$(G$!\e(B . ?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$A\e(B . ?A) (?\e$(G$B\e(B . ?B) (?\e$(G$C\e(B . ?C) (?\e$(G$D\e(B . ?D) (?\e$(G$E\e(B . ?E)
+ (?\e$(G$F\e(B . ?F) (?\e$(G$G\e(B . ?G) (?\e$(G$H\e(B . ?H) (?\e$(G$I\e(B . ?I) (?\e$(G$J\e(B . ?J)
+ (?\e$(G$K\e(B . ?K) (?\e$(G$L\e(B . ?L) (?\e$(G$M\e(B . ?M) (?\e$(G$N\e(B . ?N) (?\e$(G$O\e(B . ?O)
+ (?\e$(G$P\e(B . ?P) (?\e$(G$Q\e(B . ?Q) (?\e$(G$R\e(B . ?R) (?\e$(G$S\e(B . ?S) (?\e$(G$T\e(B . ?T)
+ (?\e$(G$U\e(B . ?U) (?\e$(G$V\e(B . ?V) (?\e$(G$W\e(B . ?W) (?\e$(G$X\e(B . ?X) (?\e$(G$Y\e(B . ?Y)
+ (?\e$(G$Z\e(B . ?Z)
+ (?\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$a\e(B . ?g) (?\e$(G$b\e(B . ?h) (?\e$(G$c\e(B . ?i) (?\e$(G$d\e(B . ?j)
+ (?\e$(G$e\e(B . ?k) (?\e$(G$f\e(B . ?l) (?\e$(G$g\e(B . ?m) (?\e$(G$h\e(B . ?n) (?\e$(G$i\e(B . ?o)
+ (?\e$(G$j\e(B . ?p) (?\e$(G$k\e(B . ?q) (?\e$(G$l\e(B . ?r) (?\e$(G$m\e(B . ?s) (?\e$(G$n\e(B . ?t)
+ (?\e$(G$o\e(B . ?u) (?\e$(G$p\e(B . ?v) (?\e$(G$q\e(B . ?w) (?\e$(G$r\e(B . ?x) (?\e$(G$s\e(B . ?y)
+ (?\e$(G$t\e(B . ?z))
+ (Korean
+ (?\e$(C!!\e(B . ?\ ) (?\e$(C#,\e(B . ?,) (?\e$(C#.\e(B . ?.)
+ (?\e$(C#:\e(B . ?:) (?\e$(C#;\e(B . ?\;) (?\e$(C#?\e(B . ??) (?\e$(C#!\e(B . ?!)
+ (?\e$(C!/\e(B . ?') (?\e$(C!.\e(B . ?`) (?\e$(C#^\e(B . ?^) (?\e$(C#_\e(B . ?_) (?\e$(C#~\e(B . ?~)
+ (?\e$(C!*\e(B . ?-) (?\e$(C!)\e(B . ?-)
+ (?\e$(C#/\e(B . ?/) (?\e$(C!,\e(B . ?\\) (?\e$(C!-\e(B . ?~) (?\e$(C#|\e(B . ?|)
+ (?\e$(C!.\e(B . ?`) (?\e$(C!/\e(B . ?') (?\e$(C!0\e(B . ?\") (?\e$(C!1\e(B . ?\")
+ (?\e$(C#(\e(B . ?\() (?\e$(C#)\e(B . ?\)) (?\e$(C#[\e(B . ?[) (?\e$(C#]\e(B . ?])
+ (?\e$(C#{\e(B . ?{) (?\e$(C#}\e(B . ?}) (?\e$(C!4\e(B . ?<) (?\e$(C!5\e(B . ?>)
+ (?\e$(C#+\e(B . ?+) (?\e$(C#-\e(B . ?-) (?\e$(C#=\e(B . ?=) (?\e$(C#<\e(B . ?<) (?\e$(C#>\e(B . ?>)
+ (?\e$(C#'\e(B . ?') (?\e$(C#"\e(B . ?\") (?\e$(C#\\e(B . ?\\) (?\e$(C#$\e(B . ?$) (?\e$(C#%\e(B . ?%)
+ (?\e$(C##\e(B . ?#) (?\e$(C#&\e(B . ?&) (?\e$(C#*\e(B . ?*) (?\e$(C#@\e(B . ?@)
+ (?\e$(C#0\e(B . ?0) (?\e$(C#1\e(B . ?1) (?\e$(C#2\e(B . ?2) (?\e$(C#3\e(B . ?3) (?\e$(C#4\e(B . ?4)
+ (?\e$(C#5\e(B . ?5) (?\e$(C#6\e(B . ?6) (?\e$(C#7\e(B . ?7) (?\e$(C#8\e(B . ?8) (?\e$(C#9\e(B . ?9)
+ (?\e$(C#A\e(B . ?A) (?\e$(C#B\e(B . ?B) (?\e$(C#C\e(B . ?C) (?\e$(C#D\e(B . ?D) (?\e$(C#E\e(B . ?E)
+ (?\e$(C#F\e(B . ?F) (?\e$(C#G\e(B . ?G) (?\e$(C#H\e(B . ?H) (?\e$(C#I\e(B . ?I) (?\e$(C#J\e(B . ?J)
+ (?\e$(C#K\e(B . ?K) (?\e$(C#L\e(B . ?L) (?\e$(C#M\e(B . ?M) (?\e$(C#N\e(B . ?N) (?\e$(C#O\e(B . ?O)
+ (?\e$(C#P\e(B . ?P) (?\e$(C#Q\e(B . ?Q) (?\e$(C#R\e(B . ?R) (?\e$(C#S\e(B . ?S) (?\e$(C#T\e(B . ?T)
+ (?\e$(C#U\e(B . ?U) (?\e$(C#V\e(B . ?V) (?\e$(C#W\e(B . ?W) (?\e$(C#X\e(B . ?X) (?\e$(C#Y\e(B . ?Y)
+ (?\e$(C#Z\e(B . ?Z)
+ (?\e$(C#a\e(B . ?a) (?\e$(C#b\e(B . ?b) (?\e$(C#c\e(B . ?c) (?\e$(C#d\e(B . ?d) (?\e$(C#e\e(B . ?e)
+ (?\e$(C#f\e(B . ?f) (?\e$(C#g\e(B . ?g) (?\e$(C#h\e(B . ?h) (?\e$(C#i\e(B . ?i) (?\e$(C#j\e(B . ?j)
+ (?\e$(C#k\e(B . ?k) (?\e$(C#l\e(B . ?l) (?\e$(C#m\e(B . ?m) (?\e$(C#n\e(B . ?n) (?\e$(C#o\e(B . ?o)
+ (?\e$(C#p\e(B . ?p) (?\e$(C#q\e(B . ?q) (?\e$(C#r\e(B . ?r) (?\e$(C#s\e(B . ?s) (?\e$(C#t\e(B . ?t)
+ (?\e$(C#u\e(B . ?u) (?\e$(C#v\e(B . ?v) (?\e$(C#w\e(B . ?w) (?\e$(C#x\e(B . ?x) (?\e$(C#y\e(B . ?y)
+ (?\e$(C#z\e(B . ?z))))
+ (hash (make-vector 100 nil))
+ lang pair)
+ (while table
+ (setq lang (caar table)
+ pair (cdar table)
+ table (cdr table))
+ (while pair
+ (set (intern (char-to-string (caar pair)) its-full-half-table)
+ (cdar pair))
+ (set (intern (concat (symbol-name lang) (char-to-string (cdar pair)))
+ its-half-full-table)
+ (caar pair))
+ (setq pair (cdr pair)))
+ hash))
+
+;;; its-half-width : half-width-region for input-buffer
+(defun its-half-width ()
(interactive)
- (let ((inhibit-read-only t))
- (its-input-end)
- (its-set-part-1 (point) (its-search-end))
- (its-convert 'its-japanese-hankaku (its-search-beginning) (point))
- (its-put-cursor t)))
-
-(defun its-japanese-hankaku (obj)
- (japanese-hankaku obj 'ascii-only))
-
-;;; its-zenkaku : zenkaku-region for input-buffer
-(defun its-zenkaku ()
+ (its-convert
+ (lambda (str lang)
+ (concat (mapcar (lambda (c)
+ (or (symbol-value (intern-soft (char-to-string c)
+ its-full-half-table))
+ c))
+ (string-to-sequence str 'list))))))
+
+;;; its-full-width : full-width-region for input-buffer
+(defun its-full-width ()
(interactive)
+ (its-convert
+ (lambda (str lang)
+ (if (egg-chinese-syllable str 0)
+ (copy-sequence str)
+ (concat (mapcar (lambda (c)
+ (or (symbol-value
+ (intern-soft (concat (symbol-name lang)
+ (char-to-string c))
+ its-half-full-table))
+ c))
+ (string-to-sequence str 'list)))))))
+
+(defun its-convert (func)
(let ((inhibit-read-only t))
- (its-input-end)
- (its-set-part-1 (point) (its-search-end))
- (its-convert 'japanese-zenkaku (its-search-beginning) (point))
- (its-put-cursor t)))
-
-(defun its-convert (func start end)
- (let* ((goto-start (eq (point) start))
- (old-str (buffer-substring start end))
- (new-str "")
- (len (length old-str))
- (p 0)
- old new syl q)
- (while (< p len)
- (setq q (next-single-property-change p 'its-syl old-str len)
- old (substring old-str p q)
- new (copy-sequence old))
- (set-text-properties 0 (- q p) nil new)
- (setq new (funcall func new))
- (if (equal new old)
- (setq new-str (concat new-str old))
- (setq syl (cons (copy-sequence new) (copy-sequence new)))
- (set-text-properties 0 (length new) (text-properties-at 0 old) new)
- (put-text-property 0 (length new) 'its-syl syl new)
- (setq new-str (concat new-str new)))
- (setq p q))
- (delete-region start end)
- (insert new-str)
- (if goto-start
- (goto-char start))))
+ (unwind-protect
+ (progn
+ (its-input-end)
+ (let* ((start (its-search-beginning))
+ (end (its-search-end))
+ (old-str (buffer-substring start end))
+ (len (length old-str))
+ (p 0)
+ (new-str ""))
+ (put-text-property 0 len 'intangible 'its-part-1 old-str)
+ (while (< p len)
+ (let* ((prop (text-properties-at p old-str))
+ (cmp (memq 'composition prop))
+ (old (its-get-output (plist-get prop 'its-syl)))
+ (new (funcall func old (plist-get prop 'egg-lang)))
+ (new-len (length new))
+ syl)
+ (unless (equal new old)
+ (when cmp
+ (if (eq prop cmp)
+ (setq prop (cddr prop))
+ (setcdr (nthcdr (- (length prop) (length cmp) 1) prop)
+ (cddr cmp))))
+ (setq syl (copy-sequence new))
+ (plist-put prop 'its-syl (cons syl syl)))
+ (add-text-properties 0 new-len prop new)
+ (setq new-str (concat new-str new)
+ p (+ p (length old)))))
+ (delete-region start end)
+ (insert new-str)))
+ (its-put-cursor t))))
(defun its-mode ()
"\\{its-mode-map}"
(with-output-to-temp-buffer "*Help*"
(princ "ITS mode:\n")
(princ (documentation 'its-mode))
- (help-setup-xref (cons #'help-xref-mode (current-buffer)) (interactive-p))))
+ (help-setup-xref (cons #'help-xref-mode (current-buffer))
+ (called-interactively-p 'interactive))))
+
+;; The `point-left' hook function will never be called in Emacs 21.2.50
+;; when the command `next-line' is used in the last line of a buffer
+;; which isn't terminated with a newline or the command `previous-line'
+;; is used in the first line of a buffer.
+(defun its-next-line (&optional arg)
+ "Go to the end of the line if the line isn't terminated with a newline, otherwise run `next-line' as usual."
+ (interactive "p")
+ (if (= (line-end-position) (point-max))
+ (end-of-line)
+ (next-line arg)))
+
+(defun its-previous-line (&optional arg)
+ "Go to the beginning of the line if it is called in the first line of a buffer, otherwise run `previous-line' as usual."
+ (interactive "p")
+ (if (= (line-beginning-position) (point-min))
+ (beginning-of-line)
+ (previous-line arg)))
+
+(substitute-key-definition 'next-line 'its-next-line
+ its-mode-map global-map)
+(substitute-key-definition 'previous-line 'its-previous-line
+ its-mode-map global-map)
(provide 'its)
-;;; its.el ends here.
+
+;;; its.el ends here