Add `(provide 'egg/sj3)'.
[elisp/egg.git] / egg / sj3.el
1 ;;; egg/sj3.el --- SJ3 Support (high level interface) in Egg
2 ;;;                Input Method Architecture
3
4 ;; Copyright (C) 1997 Mule Project, Powered by Electrotechnical
5 ;; Laboratory, JAPAN.
6 ;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
7
8 ;; Author: NIIBE Yutaka <gniibe@mri.co.jp>
9 ;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
10
11 ;; This file will be part of GNU Emacs (in future).
12
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)
16 ;; any later version.
17
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.
22
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.
27
28 ;;; Commentary:
29
30 ;;; Code:
31
32 (defconst sj3-conversion-backend
33   [ sj3-init
34
35     sj3-start-conversion
36       sj3-get-bunsetsu-converted
37       sj3-get-bunsetsu-source
38       sj3-list-candidates
39           sj3-get-number-of-candidates
40           sj3-get-current-candidate-number
41           sj3-get-all-candidates
42           sj3-decide-candidate
43       sj3-change-bunsetsu-length
44     sj3-end-conversion
45
46     sj3-fini
47  ])
48
49 (defconst sj3-server-port 3000 "Port number of SJ3 server")
50 (defvar sj3-stdy-size 0 "STDYSIZE of SJ3 server")
51 (defvar sj3-hostname "localhost"
52   "Hostname of SJ3 server")
53
54 (defun sj3-open (hostname)
55   "Establish the connection to SJ3 server.  Return process object."
56   (let* ((buf (generate-new-buffer " *SJ3*"))
57          (proc (open-network-stream "SJ3" buf hostname sj3-server-port))
58          result)
59     (process-kill-without-query proc)
60     (set-process-coding-system proc 'no-conversion 'no-conversion)
61     (set-marker-insertion-type (process-mark proc) t)
62     (save-excursion
63       (set-buffer buf)
64       (erase-buffer)
65       (buffer-disable-undo)
66       (setq enable-multibyte-characters nil))
67     ;; Initialize dictionaries
68     (setq sj3-sys-dict-list nil)
69     (setq sj3-user-dict-list nil)
70     (setq result (sj3rpc-open proc (system-name) (user-login-name)))
71     (if (< result 0)
72         (let ((msg (sj3rpc-get-error-message (- result))))
73           (delete-process proc)
74           (kill-buffer buf)
75           (error "Can't open SJ3 session (%s): %s" hostname msg)))
76     (setq result (sj3rpc-get-stdy-size proc))
77     (if (< result 0)
78         (let ((msg (sj3rpc-get-error-message (- result))))
79           (delete-process proc)
80           (kill-buffer buf)
81           (error "Can't get SJ3 STDYSIZE: %s"msg)))
82     (setq sj3-stdy-size result)
83     proc))
84
85 ;; <env> ::= [ <proc> <dictionary-list> ]
86 (defvar sj3-environment nil
87   "Environment for SJ3 kana-kanji conversion")
88
89 (defsubst sj3env-get-proc (env)
90   (aref env 0))
91 (defsubst sj3env-get-dictionary-list (env)
92   (aref env 1))
93
94 ;; <bunsetsu> ::=
95 ;;  [ <env> <source> <converted> <rest>
96 ;;    <stdy> <zenkouho> <zenkouho-pos> <stdy-down> ]
97 (defsubst sj3-make-bunsetsu (env source converted rest stdy)
98   (vector env source converted rest stdy nil nil nil))
99
100 (defsubst sj3bunsetsu-get-env (b)
101   (aref b 0))
102 (defsubst sj3bunsetsu-get-source (b)
103   (aref b 1))
104 (defsubst sj3bunsetsu-get-converted (b)
105   (aref b 2))
106 (defsubst sj3bunsetsu-get-rest (b)
107   (aref b 3))
108 (defsubst sj3bunsetsu-get-stdy (b)
109   (aref b 4))
110 (defsubst sj3bunsetsu-get-zenkouho (b)
111   (aref b 5))
112 (defsubst sj3bunsetsu-set-zenkouho (b z)
113   (aset b 5 z))
114 (defsubst sj3bunsetsu-get-zenkouho-pos (b)
115   (aref b 6))
116 (defsubst sj3bunsetsu-set-zenkouho-pos (b p)
117   (aset b 6 p))
118 (defsubst sj3bunsetsu-get-stdydown (b)
119   (aref b 7))
120 (defsubst sj3bunsetsu-set-stdydown (b s)
121   (aset b 7 s))
122
123 (defun sj3-get-bunsetsu-source (b)
124   (sj3bunsetsu-get-source b))
125 (defun sj3-get-bunsetsu-converted (b)
126   (concat (sj3bunsetsu-get-converted b)
127           (sj3bunsetsu-get-rest b)))
128 (defun sj3-get-bunsetsu-stdy (b)
129   (sj3bunsetsu-get-stdy b))
130
131 (defvar sj3-dictionary-specification
132   '(("study.dat")
133     ["sj3main.dic" ""]
134     [("private.dic") ""])
135   "Dictionary specification of SJ3.")
136
137 (defvar sj3-usr-dic-dir (concat "user/" (user-login-name))
138   "*Directory of user dictionary for SJ3.")
139
140 (defun sj3-filename (p)
141   ""
142   (cond ((consp p) (concat sj3-usr-dic-dir "/" (car p)))
143         (t p)))
144
145 (defun sj3-get-environment ()
146   (if sj3-environment
147       sj3-environment
148     (let* ((proc (sj3-open sj3-hostname))
149            (stdy (sj3-filename (car sj3-dictionary-specification)))
150            (l (cdr sj3-dictionary-specification))
151            dict-list)
152       (if (/= (sj3rpc-open-stdy proc stdy) 0)
153           (error "Dame1")               ; XXX
154         (while l
155           (let ((dic (car l))
156                 dic-id)
157             (setq dic-id
158                   (sj3rpc-open-dictionary proc (sj3-filename (aref dic 0))
159                                           (aref dic 1)))
160             (if (< dic-id 0)
161                 (error "Dame2")         ; XXX
162               (setq dict-list (cons dic-id dict-list)
163                     l (cdr l))))))
164         (setq sj3-environment (vector proc dict-list)))))
165
166 (defun sj3-init ()
167   )
168
169 (defun sj3-start-conversion (yomi)
170   "Convert YOMI string to kanji, and enter conversion mode.
171 Return the list of bunsetsu."
172   (let ((env (sj3-get-environment)))
173     (sj3rpc-begin env yomi)))
174
175 ;; XXX: not implemented yet
176 (defun sj3-end-conversion (bunsetsu-list)
177   )
178
179 (defun sj3-list-candidates (bunsetsu prev-bunsetsu)
180   (let* ((env (sj3bunsetsu-get-env bunsetsu))
181          (yomi (sj3bunsetsu-get-source bunsetsu))
182          (z (sj3rpc-get-bunsetsu-candidates env yomi)))
183     (sj3bunsetsu-set-zenkouho bunsetsu z)
184     (sj3bunsetsu-set-zenkouho-pos bunsetsu 0)
185     0))
186
187 (defun sj3-get-number-of-candidates (bunsetsu)
188   (let ((l (sj3bunsetsu-get-zenkouho bunsetsu)))
189     (if l
190         (length l)
191       nil)))
192
193 (defun sj3-decide-candidate (bunsetsu candidate-pos)
194   (let* ((candidate-list (sj3bunsetsu-get-zenkouho bunsetsu))
195          (candidate (nth candidate-pos candidate-list)))
196     (sj3bunsetsu-set-zenkouho candidate candidate-list)
197     (sj3bunsetsu-set-zenkouho-pos candidate candidate-pos)
198     candidate))
199
200 (defun sj3-get-current-candidate-number (bunsetsu)
201   (sj3bunsetsu-get-zenkouho-pos bunsetsu))
202
203 (defun sj3-get-all-candidates (bunsetsu)
204   (let* ((l (sj3bunsetsu-get-zenkouho bunsetsu))
205          (result (cons nil nil))
206          (r result))
207     (catch 'break
208       (while t
209         (let ((candidate (car l)))
210           (setcar r (sj3bunsetsu-get-converted candidate))
211           (if (null (setq l (cdr l)))
212               (throw 'break nil)
213             (setq r (setcdr r (cons nil nil)))))))
214     result))
215
216 (defun sj3-change-bunsetsu-length (b0 b1 b2 len)
217   (let ((yomi (concat
218                (sj3bunsetsu-get-source b1)
219                (if b2 (sj3bunsetsu-get-source b2))))
220         (env (sj3bunsetsu-get-env b1))
221         yomi1 yomi2
222         bunsetsu1 bunsetsu2)
223     (save-match-data
224       (string-match (concat "^\\(" (make-string len ?.) "\\)\\(.*$\\)") yomi)
225       (setq yomi1 (match-string 1 yomi))
226       (setq yomi2 (match-string 2 yomi)))
227     (setq bunsetsu1
228           (sj3rpc-tanbunsetsu-conversion env yomi1))
229     ;; Only set once.
230     (sj3bunsetsu-set-stdydown bunsetsu1
231                               (or (sj3bunsetsu-get-stdydown b1)
232                                   (if b2
233                                       (list b1 b2)
234                                     (list b1))))
235     (if (< 0 (length yomi2))
236         (setq bunsetsu2 (sj3rpc-tanbunsetsu-conversion env yomi2))
237       (setq bunsetsu2 nil))
238     (if bunsetsu2
239         (list bunsetsu1 bunsetsu2)
240       (list bunsetsu1))))
241
242 ;; XXX: Not implemented yet
243 (defun sj3-fini ()
244   )
245
246 (provide 'egg/sj3)
247
248 ;;; egg/sj3.el ends here.