1 ;;; egg-cnv.el --- Conversion Backend in Egg Input Method Architecture
3 ;; Copyright (C) 1997 Mule Project,
4 ;; Powered by Electrotechnical Laboratory, JAPAN.
5 ;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
7 ;; Author: NIIBE Yutaka <gniibe@mri.co.jp>
8 ;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
9 ;; Keywords: mule, multilingual, input method
11 ;; This file will be part of GNU Emacs (in future).
13 ;; GNU Emacs is free software; you can redistribute it and/or modify
14 ;; it under the terms of the GNU General Public License as published by
15 ;; the Free Software Foundation; either version 2, or (at your option)
18 ;; GNU Emacs is distributed in the hope that it will be useful,
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ;; GNU General Public License for more details.
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with GNU Emacs; see the file COPYING. If not, write to the
25 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 ;; Boston, MA 02111-1307, USA.
33 (defsubst egg-bunsetsu-info () 'intangible)
36 (defvar egg-conversion-backend nil)
38 (defun egg-initialize-backend ()
39 (funcall (aref egg-conversion-backend 0)))
41 (defun egg-start-conversion (yomi-string)
42 (funcall (aref egg-conversion-backend 1) yomi-string))
43 (defun egg-get-bunsetsu-converted (bunsetsu-info)
44 (funcall (aref egg-conversion-backend 2) bunsetsu-info))
45 (defun egg-get-bunsetsu-source (bunsetsu-info)
46 (funcall (aref egg-conversion-backend 3) bunsetsu-info))
47 (defun egg-list-candidates (bunsetsu-info prev-bunsetsu-info)
48 (funcall (aref egg-conversion-backend 4) bunsetsu-info prev-bunsetsu-info))
49 (defun egg-get-number-of-candidates (bunsetsu-info)
50 (funcall (aref egg-conversion-backend 5) bunsetsu-info))
51 (defun egg-get-current-candidate-number (bunsetsu-info)
52 (funcall (aref egg-conversion-backend 6) bunsetsu-info))
53 (defun egg-get-all-candidates (bunsetsu-info)
54 (funcall (aref egg-conversion-backend 7) bunsetsu-info))
55 (defun egg-decide-candidate (bunsetsu-info candidate-pos)
56 (funcall (aref egg-conversion-backend 8) bunsetsu-info candidate-pos))
57 (defun egg-change-bunsetsu-length (b0 b1 b2 len)
58 (funcall (aref egg-conversion-backend 9) b0 b1 b2 len))
59 (defun egg-end-conversion (bunsetsu-info-list)
60 (funcall (aref egg-conversion-backend 10) bunsetsu-info-list))
62 (defun egg-finalize-backend ()
63 (funcall (aref egg-conversion-backend 11)))
65 (defvar egg-conversion-open "|")
66 (defvar egg-conversion-close "|")
67 (defvar egg-conversion-separator " ")
70 (defun egg-convert-region (start end)
72 (let ((bunsetsu-info-list
73 (egg-start-conversion (buffer-substring start end)))
75 (delete-region start end)
77 (insert egg-conversion-open)
78 (put-text-property p (point) 'egg-start t)
79 (if egg-conversion-face
80 (put-text-property p (point) 'invisible t))
82 (egg-insert-bunsetsu-list bunsetsu-info-list)
85 (insert egg-conversion-close)
86 (put-text-property p (point) 'egg-end t)
87 (if egg-conversion-face
88 (put-text-property p (point) 'invisible t))
89 (goto-char (1+ start))))
91 (defvar egg-conversion-face nil)
92 (defvar egg-conversion-map
93 (let ((map (make-sparse-keymap))
96 (define-key map (vector i) 'egg-exit-conversion-unread-char)
98 (define-key map "\C-@" 'egg-decide-first-char)
99 (define-key map [?\C-\ ] 'egg-decide-first-char)
100 (define-key map "\C-a" 'egg-beginning-of-conversion-buffer)
101 (define-key map "\C-b" 'egg-backward-bunsetsu)
102 (define-key map "\C-e" 'egg-end-of-conversion-buffer)
103 (define-key map "\C-f" 'egg-forward-bunsetsu)
104 (define-key map "\C-h" 'egg-help-command)
105 (define-key map "\C-i" 'egg-shrink-bunsetsu)
106 (define-key map "\C-k" 'egg-decide-before-point)
107 ;; (define-key map "\C-l" 'egg-exit-conversion) ; Don't override C-L
108 (define-key map "\C-m" 'egg-exit-conversion)
109 (define-key map "\C-n" 'egg-next-candidate)
110 (define-key map "\C-o" 'egg-enlarge-bunsetsu)
111 (define-key map "\C-p" 'egg-previous-candidate)
112 (define-key map "\M-s" 'egg-select-candidate)
113 (define-key map [return] 'egg-exit-conversion)
114 ;; (define-key map "\C-\\" 'egg-exit-mode-no-egg)
115 (define-key map [right] 'egg-forward-bunsetsu)
116 (define-key map [left] 'egg-backward-bunsetsu)
117 (define-key map " " 'egg-next-candidate)
118 (define-key map "/" 'egg-exit-conversion)
120 "Keymap for EGG Conversion mode.")
122 (defun egg-exit-conversion-unread-char ()
124 (setq unread-command-events (list last-command-event))
125 (egg-exit-conversion))
127 (defun egg-insert-bunsetsu (bunsetsu-info last)
128 (let ((bunsetsu (egg-get-bunsetsu-converted bunsetsu-info))
132 (insert egg-conversion-separator))
133 (add-text-properties p (point)
134 (list 'face egg-conversion-face
135 'local-map egg-conversion-map
136 (egg-bunsetsu-info) bunsetsu-info
137 'egg-bunsetsu-last last))))
139 (defun egg-insert-bunsetsu-list (bunsetsu-info-list &optional contin)
140 (let ((l bunsetsu-info-list)
141 bunsetsu-info bunsetsu p)
143 (setq bunsetsu-info (car l)
146 (egg-insert-bunsetsu bunsetsu-info (and (null l) (null contin))))))
148 (defun egg-backward-bunsetsu (n)
151 (while (and (null start) (> n 0))
153 (if (setq start (get-text-property (point) 'egg-start))
157 (signal 'beginning-of-buffer nil))))
159 (defun egg-forward-bunsetsu (n)
162 (while (and (null end) (> n 0))
164 (if (setq end (get-text-property (point) 'egg-end))
168 (signal 'end-of-buffer nil))))
170 (defun egg-get-previous-bunsetsu (p)
171 (if (get-text-property (1- p) 'egg-start)
173 (get-text-property (- p 2) (egg-bunsetsu-info))))
175 (defun egg-shrink-bunsetsu (n)
177 (let* ((b0 (egg-get-previous-bunsetsu (point)))
178 (b1 (get-text-property (point) (egg-bunsetsu-info)))
179 (last (get-text-property (point) 'egg-bunsetsu-last))
180 (slen (chars-in-string (egg-get-bunsetsu-source b1)))
182 b2 bunsetsu-info-list beep)
187 (let ((p2 (save-excursion (forward-char) (point))))
188 (setq b2 (get-text-property p2 (egg-bunsetsu-info))
189 last (get-text-property p2 'egg-bunsetsu-last))))
190 (setq bunsetsu-info-list (egg-change-bunsetsu-length b0 b1 b2 newlen))
191 (delete-region (point)
192 (progn (forward-char) (if b2 (forward-char)) (point)))
194 (egg-insert-bunsetsu-list bunsetsu-info-list (not last))
199 (defun egg-enlarge-bunsetsu (n)
201 (let* ((b0 (egg-get-previous-bunsetsu (point)))
202 (b1 (get-text-property (point) (egg-bunsetsu-info)))
203 (last (get-text-property (point) 'egg-bunsetsu-last))
204 (slen (chars-in-string (egg-get-bunsetsu-source b1)))
206 b2 maxlen bunsetsu-info-list beep)
208 (let ((p2 (save-excursion (forward-char) (point))))
209 (setq b2 (get-text-property p2 (egg-bunsetsu-info))
210 last (get-text-property p2 'egg-bunsetsu-last))))
213 (chars-in-string (egg-get-bunsetsu-source b2))
215 (if (> newlen maxlen)
218 (setq bunsetsu-info-list (egg-change-bunsetsu-length b0 b1 b2 newlen))
219 (delete-region (point)
220 (progn (forward-char) (if b2 (forward-char)) (point)))
222 (egg-insert-bunsetsu-list bunsetsu-info-list (not last))
227 (defun egg-next-candidate (n)
229 (let ((last (get-text-property (point) 'egg-bunsetsu-last))
230 (b (get-text-property (point) (egg-bunsetsu-info)))
232 (setq max+ (egg-get-number-of-candidates b))
234 (let ((prev-b (egg-get-previous-bunsetsu (point))))
235 (setq i (egg-list-candidates b prev-b)) ; there is a case I=/=0
236 (if (or (> n 1) (< n 0)) ; with N=/=1, start with I
237 (setq i (+ n i)) ; or else (N==1),
238 (setq i (if (= i 0) 1 0))) ; I:=1 when I was 0, or else I:=0
239 (setq max+ (egg-get-number-of-candidates b)))
240 (setq i (egg-get-current-candidate-number b))
242 (if (< i 0) ; go backward as if it is ring
244 (setq i (+ i max+))))
245 (if (>= i max+) ; don't go forward
248 (setq new (egg-decide-candidate b i))
250 (delete-region p (progn (forward-char) (point)))
251 (egg-insert-bunsetsu new last)
256 (defun egg-previous-candidate (n)
258 (egg-next-candidate (- n)))
260 (defun egg-decide-bunsetsu (&optional end-marker)
262 p bunsetsu-info-list bl)
265 (let ((bl1 (cons (get-text-property p (egg-bunsetsu-info)) nil)))
267 (setq bl (setcdr bl bl1))
268 (setq bunsetsu-info-list (setq bl bl1))))
270 (remove-text-properties p (point) '(face nil
273 egg-bunsetsu-last nil))
275 (if (or (and end-marker (= p end-marker))
276 (get-text-property p 'egg-end))
279 (delete-region p (1+ p)))) ; Delete bunsetsu separator
282 (defun egg-decide-before-point ()
284 (let ((m (make-marker))
285 all start bunsetsu-list)
286 (if (get-text-property (1- (point)) 'egg-start)
287 (signal 'beginning-of-buffer nil)
288 (setq start (1- (previous-single-property-change (point) 'egg-start))))
289 (set-marker m (point))
291 ;; Delete open marker
292 (delete-region start (1+ start))
293 (setq bunsetsu-list (egg-decide-bunsetsu m))
295 (delete-region (1- (point)) (point))
296 ;; insert open marker
297 (insert egg-conversion-open)
298 (put-text-property m (point) 'egg-start t)
299 (if egg-conversion-face
300 (put-text-property p (point) 'invisible t))
301 (egg-end-conversion bunsetsu-list)
304 (defun egg-exit-conversion ()
306 (let (start bunsetsu-list)
307 (if (get-text-property (1- (point)) 'egg-start)
308 (setq start (1- (point)))
309 (setq start (1- (previous-single-property-change (point) 'egg-start))))
311 ;; Delete open marker
312 (delete-region start (1+ start))
313 (setq bunsetsu-list (egg-decide-bunsetsu))
314 ;; Delete close marker
315 (delete-region (point) (1+ (point)))
317 (egg-end-conversion bunsetsu-list)
318 (run-hooks 'input-method-after-insert-chunk-hook)))
320 (defun egg-select-candidate ()
322 (let ((last (get-text-property (point) 'egg-bunsetsu-last))
323 (b (get-text-property (point) (egg-bunsetsu-info)))
326 (setq max+ (egg-get-number-of-candidates b))
328 (let ((prev-b (egg-get-previous-bunsetsu (point))))
329 (setq i (egg-list-candidates b prev-b))
330 (setq max+ (egg-get-number-of-candidates b)))
331 (setq i (egg-get-current-candidate-number b)))
332 (let* ((candidate-list (egg-get-all-candidates b))
334 (candidate (menudiag-select (list 'menu "
\e$B8uJd
\e(B:" l) (list (nth i l)))))
337 (if (eq candidate (car l))
341 (setq new (egg-decide-candidate b i))
343 (delete-region p (progn (forward-char) (point)))
344 (egg-insert-bunsetsu new last)
348 ;;; egg-cnv.el ends here.