;;; egg/wnn.el --- WNN Support (high level interface) in Egg
;;; Input Method Architecture
-;; Copyright (C) 1997 Mule Project, Powered by Electrotechnical
+;; Copyright (C) 1997, 1998 Mule Project, Powered by Electrotechnical
;; Laboratory, JAPAN.
;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
;; Author: NIIBE Yutaka <gniibe@mri.co.jp>
+;; KATAYAMA Yoshio <kate@pfu.co.jp> ; Korean, Chinese support.
+;;
;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
-;; This file will be part of GNU Emacs (in future).
+;; This file will be part of EGG (in future).
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; EGG is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
-;; GNU Emacs is distributed in the hope that it will be useful,
+;; EGG is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;; Commentary:
;;; Code:
+(defgroup wnn nil
+ "Wnn interface for Tamagotchy"
+ :group 'egg)
+
+(defconst wnn-support-languages
+ '("Japanese" "Chinese-GB" "Chinese-CNS" "Korean"))
(eval-when-compile
(defmacro WNN-const (c)
wnn-fini
])
-;; <env> ::= [ <proc> <env-id> <daibunsetsu-info> ]
+;; <env> ::= [ <proc> <env-id> <server-type> <dic-set> <rev-flag>
+;; <daibunsetsu-info> ]
-(defsubst wnnenv-create (proc env-id)
- (vector proc env-id nil))
+(defsubst wnnenv-create (proc env-id server-type dic-set rev-flag)
+ (vector proc env-id server-type dic-set rev-flag nil))
(defsubst wnnenv-get-proc (env)
(aref env 0))
(defsubst wnnenv-get-env-id (env)
(aref env 1))
-(defsubst wnnenv-get-daibunsetsu-info (env)
+(defsubst wnnenv-get-server-type (env)
(aref env 2))
+
+(defsubst wnnenv-get-dictionary-set (env)
+ (aref env 3))
+
+(defsubst wnnenv-get-reverse-flag (env)
+ (aref env 4))
+
+(defsubst wnnenv-get-daibunsetsu-info (env)
+ (aref env 5))
(defsubst wnnenv-set-daibunsetsu-info (env d)
- (aset env 2 d))
+ (aset env 5 d))
;; <bunsetsu> ::= [ <env> <end> <start> <jiritsugo-end> <dic-no>
;; <entry> <freq> <right-now> <hinshi> <status>
(defsubst wnn-bunsetsu-set-zenkouho-pos (bunsetsu zp)
(aset bunsetsu 18 zp))
\f
-(defvar wnn-server "localhost"
- "Hostname of wnn server")
-
-(defvar wnn-environment nil
+(defvar wnn-environments nil
"Environment for WNN kana-kanji conversion")
+(defcustom wnn-jserver "localhost" "jserver host" :group 'wnn :type 'string)
+(defcustom wnn-cserver "localhost" "cserver host" :group 'wnn :type 'string)
+(defcustom wnn-tserver "localhost" "tserver host" :group 'wnn :type 'string)
+(defcustom wnn-kserver "localhost" "kserver host" :group 'wnn :type 'string)
+
+;; The port number should be initialized from $WNNLIB/serverdefs by wnn-init
+(defconst wnn-server-info-list
+ ;; language locale server port stream coding-system hostname
+ '(("Japanese" "ja_JP" jserver 22273 "Wnn" fixed-euc-jp wnn-jserver)
+ ("Chinese-GB" "zh_CN" cserver 22289 "cWnn" fixed-euc-cn wnn-cserver)
+ ("Chinese-CNS" "zh_TW" tserver 22321 "tWnn" fixed-euc-tw wnn-tserver)
+ ("Korean" "ko_KR" kserver 22305 "kWnn" fixed-euc-kr wnn-kserver)))
+
+(defun wnn-get-server-info (lang)
+ (let (info)
+ (if (null lang)
+ (setq lang its-current-language))
+ (if (setq info (assoc lang wnn-server-info-list)) info
+ (assoc "Japanese" wnn-server-info-list))))
+
+(defsubst wnn-server-locale (info)
+ (nth 1 info))
+
+(defsubst wnn-server-type (info)
+ (nth 2 info))
+
+(defsubst wnn-server-port (info)
+ (nth 3 info))
+
+(defsubst wnn-server-stream-name (info)
+ (nth 4 info))
+
+(defsubst wnn-server-buffer-name (info)
+ (concat " *" (wnn-server-stream-name info) "*"))
+
+(defsubst wnn-server-coding-system (info)
+ (nth 5 info))
+
+(defsubst wnn-server-hostname (info)
+ (symbol-value (nth 6 info)))
+
(defun wnn-init ()
)
-(defun wnn-start-conversion (yomi)
+(defun wnn-start-conversion (yomi &optional language dic-set reverse)
"Convert YOMI string to kanji, and enter conversion mode.
Return the list of bunsetsu."
- (let* ((env (wnn-get-environment wnn-dictionary-specification))
+ (let* ((server-info (wnn-get-server-info language))
+ (env (wnn-get-environment server-info dic-set reverse))
(result (wnnrpc-renbunsetsu-conversion env yomi
(WNN-const BUN_SENTOU) "")))
(wnnenv-set-daibunsetsu-info env (car result))
(let ((hash-table (make-vector 31 0)) ; XXX why 31?
(l bunsetsu-list)
(i 0)
- n sym0 result p b sym)
+ (n 0) sym0 result p b sym)
(setq sym0 (intern (wnn-get-bunsetsu-converted bunsetsu) hash-table))
(while l
(setq b (car l)
prev-fuzokugo "")
(setq prev-hinshi (wnn-bunsetsu-get-hinshi b0)
prev-fuzokugo (wnn-bunsetsu-get-fuzokugo b0)))
- (save-match-data
- (string-match (concat "^\\(" (make-string len ?.) "\\)\\(.*$\\)") yomi)
- (setq yomi1 (match-string 1 yomi))
- (setq yomi2 (match-string 2 yomi)))
+ (setq yomi1 (substring yomi 0 len)
+ yomi2 (substring yomi len))
(setq bunsetsu1
(car (wnnrpc-tanbunsetsu-conversion env yomi1
prev-hinshi prev-fuzokugo)))
(list b1 b2)
(list b1))))
(if (< 0 (length yomi2))
- ;; RENBUNSETSU? XXX
(setq bunsetsu2
- (car (wnnrpc-tanbunsetsu-conversion
+ (cdr (wnnrpc-renbunsetsu-conversion
env yomi2
(wnn-bunsetsu-get-hinshi bunsetsu1)
(wnn-bunsetsu-get-fuzokugo bunsetsu1))))
(setq bunsetsu2 nil))
(if bunsetsu2
- (list bunsetsu1 bunsetsu2)
+ (append (list bunsetsu1) bunsetsu2)
(list bunsetsu1))))
(defvar wnn-sticky-environment-flag nil
"*Flag which specifies sticky environment.")
-(defun wnn-fini () ; XXX
- (if (null wnn-environment)
- nil
- (condition-case nil
- (progn
- (if wnn-sticky-environment-flag
- (wnnrpc-make-env-sticky wnn-environment)
- (wnnrpc-make-env-unsticky wnn-environment))
- (wnnrpc-disconnect wnn-environment))
- (error nil))
- (let ((proc (wnnenv-get-proc wnn-environment)))
- (if (eq (process-status proc) 'open)
- (progn
- (wnnrpc-close proc)
- (kill-buffer (process-buffer proc))
- (delete-process proc))))
- (setq wnn-environment nil)))
+(defun wnn-fini (lang) ; XXX
+ ; tamago-971009 version
+ ; argument LANG is still dummy
+ (if wnn-environments
+ (let ((l wnn-environments))
+ (condition-case nil
+ (while l
+ (let ((env (car l)))
+ (if wnn-sticky-environment-flag
+ (wnnrpc-make-env-sticky env)
+ (wnnrpc-make-env-unsticky env))
+ (wnnrpc-disconnect env)
+ (setq l (cdr l))))
+ (error nil))
+ (setq l wnn-environments)
+ (while l
+ (let ((proc (wnnenv-get-proc (car l))))
+ (if (eq (process-status proc) 'open)
+ (progn
+ (wnnrpc-close proc)
+ (kill-buffer (process-buffer proc)))
+ (setq l (cdr l)))))
+ (setq wnn-environments nil))))
\f
-;; XXX should be array (index: server) of {C,J,K}server
-(defconst wnn-jserver-port 22273)
;;
(defun wnn-comm-sentinel (proc reason) ; assume it is close
- (kill-buffer (process-buffer proc))
- (delete-process proc)
- (setq wnn-environment nil)
- (message "WNN: connection closed"))
+ ; tamago-971009 version
+ (let ((l wnn-environments)
+ env l1)
+ (kill-buffer (process-buffer proc))
+ ;; delete env from the list.
+ (while l
+ (setq env (car l))
+ (if (eq proc (wnnenv-get-proc env))
+ (progn
+ (if l1
+ (setcdr l1 (cdr l))
+ (setq wnn-environments (cdr l)))
+ (setq l (cdr l)))
+ (setq l1 l
+ l (cdr l))))))
;;
-(defun wnn-open (hostname language)
+(defun wnn-open (server-info)
"Establish the connection to WNN server. Return process object."
- ;; Specifying language (jserver/cserver/kserver),
- ;; open the session to WNN server,
- (let ((buf (generate-new-buffer " *WNN*"))
- proc result)
+ ;; Open the session to WNN server,
+ (let ((buf (generate-new-buffer (wnn-server-buffer-name server-info)))
+ (hostname (wnn-server-hostname server-info))
+ proc result)
(condition-case result
- (setq proc (open-network-stream "WNN" buf hostname wnn-jserver-port))
+ (setq proc (open-network-stream (wnn-server-stream-name server-info)
+ buf
+ hostname
+ (wnn-server-port server-info)))
(error (progn
(kill-buffer buf)
(signal (car result) (cdr result)))))
(set-buffer buf)
(erase-buffer)
(buffer-disable-undo)
- (setq enable-multibyte-characters nil))
- (setq result (wnnrpc-open proc (system-name) (user-login-name)))
+ (setq enable-multibyte-characters nil
+ egg-fixed-euc (wnn-server-coding-system server-info)))
+ (setq result (wnnrpc-open proc
+ (if (equal hostname "localhost")
+ "unix"
+ (system-name))
+ (user-login-name)))
(if (< result 0)
(let ((msg (wnnrpc-get-error-message (- result))))
(delete-process proc)
(kill-buffer buf)
- (error "Can't open WNN session (%s %s): %s" hostname language msg))
+ (error "Can't open WNN session (%s %S): %s"
+ hostname
+ (wnn-server-type server-info) msg))
proc)))
-(defvar wnn-dictionary-specification
- '([2 10 2 45 100 200 5 1 40 0 -100 200 -100 200 80 200 200]
- "pubdic/full.fzk"
- ["pubdic/kihon.dic" ("kihon.h") 5 nil t]
- ["pubdic/setsuji.dic" ("setsuji.h") 5 nil t]
- ["pubdic/koyuu.dic" ("koyuu.h") 1 nil t]
- ["pubdic/chimei.dic" ("chimei.h") 1 nil t]
- ["pubdic/jinmei.dic" ("jinmei.h") 1 nil t]
- ["pubdic/special.dic" ("special.h") 5 nil t]
- ["pubdic/computer.dic" ("computer.h") 5 nil t]
- ["pubdic/symbol.dic" ("symbol.h") 1 nil t]
- ["pubdic/tankan.dic" ("tankan.h") 1 nil t]
- ["pubdic/bio.dic" ("bio.h") 1 nil t]
- ["gerodic/g-jinmei.dic" ("g-jinmei.h") 1 nil t]
- ["wnncons/tankan2.dic" ("tankan2.h") 1 nil t]
- ["wnncons/tankan3.dic" ("tankan3.h") 1 nil t]
- [("ud") nil 5 t t])
- "")
-
-(defvar wnn-usr-dic-dir (concat "usr/" (user-login-name))
- "*Directory of user dictionary for Wnn.")
+(defvar wnn-dictionary-specification-list
+ '((jserver
+ (nil nil ""
+ [2 10 2 45 100 200 5 1 40 -100 200 -100 200 80 200 200 200]
+ "pubdic/full.fzk"
+ ["pubdic/kihon.dic" ("kihon.h") 5 nil t]
+ ["pubdic/setsuji.dic" ("setsuji.h") 5 nil t]
+ ["pubdic/koyuu.dic" ("koyuu.h") 1 nil t]
+ ["pubdic/chimei.dic" ("chimei.h") 1 nil t]
+ ["pubdic/jinmei.dic" ("jinmei.h") 1 nil t]
+ ["pubdic/special.dic" ("special.h") 5 nil t]
+ ["pubdic/computer.dic" ("computer.h") 5 nil t]
+ ["pubdic/symbol.dic" ("symbol.h") 1 nil t]
+ ["pubdic/tankan.dic" nil 1 nil nil]
+ ["pubdic/bio.dic" ("bio.h") 1 nil t]
+ ["gerodic/g-jinmei.dic" ("g-jinmei.h") 1 nil t]
+ ["wnncons/tankan2.dic" nil 1 nil nil]
+ ["wnncons/tankan3.dic" nil 1 nil nil]
+ [("ud") nil 5 t t])
+ (nil t "R"
+ [2 10 2 45 1 80 5 1 50 -20 400 -10 100 -100 200 0 200]
+ "pubdic/full.fzk"
+ ["pubdic/kihon.dic" ("kihon.h") 5 nil t]
+ ["pubdic/setsuji.dic" ("setsuji.h") 5 nil t]
+ ["pubdic/koyuu.dic" ("koyuu.h") 1 nil t]
+ ["pubdic/chimei.dic" ("chimei.h") 1 nil t]
+ ["pubdic/jinmei.dic" ("jinmei.h") 1 nil t]
+ ["pubdic/special.dic" ("special.h") 5 nil t]
+ ["pubdic/computer.dic" ("computer.h") 5 nil t]
+ ["pubdic/symbol.dic" ("symbol.h") 1 nil t]
+ ["pubdic/tankan.dic" nil 1 nil nil]
+ ["pubdic/bio.dic" ("bio.h") 1 nil t]
+ ["gerodic/g-jinmei.dic" ("g-jinmei.h") 1 nil t]
+ ["wnncons/tankan2.dic" nil 1 nil nil]
+ ["wnncons/tankan3.dic" nil 1 nil nil]
+ [("ud") nil 5 t t]))
+ (cserver
+ (Q nil "Q"
+ nil
+ "sys/full.con"
+ ["sys/QianMa.dic" nil 1 nil nil])
+ (W nil "W"
+ nil
+ "sys/full.con"
+ ["sys/WuBi.dic" nil 1 nil nil])
+ (nil nil "PZ"
+ [1 5 2 750 10 80 10 5 1000 50 0 -200 0 0 0 16 0]
+ "sys/full.con"
+ ["sys/level_1.dic" ("level_1.h") 4 nil t]
+ ["sys/level_2.dic" ("level_2.h") 1 nil t]
+ ["sys/basic.dic" ("basic.h") 7 nil t]
+ ["sys/computer.dic" ("computer.h") 4 nil t]
+ ["sys/cwnn.dic" ("cwnn.h") 4 nil t]
+ [("ud") nil 5 t t])
+ (Q t "QR"
+ nil
+ "sys/full.conR"
+ ["sys/QianMa.dic" nil 1 nil nil])
+ (W t "WR"
+ nil
+ "sys/full.conR"
+ ["sys/WuBi.dic" nil 1 nil nil])
+ (nil t "PZR"
+ [1 5 2 750 10 80 10 5 1000 50 0 -200 0 0 0 16 0]
+ "sys/full.conR"
+ ["sys/level_1.dic" ("level_1.h") 4 nil t]
+ ["sys/level_2.dic" ("level_2.h") 1 nil t]
+ ["sys/basic.dic" ("basic.h") 7 nil t]
+ ["sys/computer.dic" ("computer.h") 4 nil t]
+ ["sys/cwnn.dic" ("cwnn.h") 4 nil t]
+ [("ud") nil 5 t t]))
+ (tserver
+ (nil nil ""
+ [1 5 2 750 10 80 10 5 1000 50 0 -200 0 0 0 16 0]
+ "sys/full.con"
+ ["sys/cns_ch.dic" ("cns_ch.h") 4 nil t]
+ ["sys/cns_wd.dic" ("cns_wd.h") 1 nil t]
+ [("ud") nil 5 t t])
+ (nil t "R"
+ [1 5 2 750 10 80 10 5 1000 50 0 -200 0 0 0 16 0]
+ "sys/full.conR"
+ ["sys/cns_ch.dic" ("cns_ch.h") 4 nil t]
+ ["sys/cns_wd.dic" ("cns_wd.h") 1 nil t]
+ [("ud") nil 5 t t]))
+ (kserver
+ (nil nil ""
+ [2 5 2 45 200 80 5 1 40 0 400 -100 400 80 200 2 200]
+ "sys/full.fzk"
+ ["sys/hword.dic" ("hword.h") 5 nil t]
+ ["sys/single.dic" ("single.h") 1 nil t]
+ [("ud") nil 2 t t])
+ (nil t "R"
+ [2 10 2 45 1 80 5 1 50 -20 400 -10 100 -100 200 0 200]
+ "sys/full.fzk"
+ ["sys/hword.dic" ("hword.h") 5 nil t]
+ ["sys/single.dic" ("single.h") 1 nil t]
+ [("ud") nil 2 t t]))))
+
+(defsubst wnn-get-dic-spec (server)
+ (cdr (assoc server wnn-dictionary-specification-list)))
+
+(defsubst wnn-dic-spec-dic-set (spec)
+ (nth 0 spec))
+
+(defsubst wnn-dic-spec-reverse (spec)
+ (nth 1 spec))
+
+(defsubst wnn-dic-spec-name (spec)
+ (nth 2 spec))
+
+(defsubst wnn-dic-spec-param (spec)
+ (nth 3 spec))
+
+(defsubst wnn-dic-spec-fuzokugo (spec)
+ (nth 4 spec))
+
+(defsubst wnn-dic-spec-dic-list (spec)
+ (nthcdr 5 spec))
+
+
+(defcustom wnn-usr-dic-dir (concat "usr/" (user-login-name))
+ "*Directory of user dictionary for Wnn."
+ :group 'wnn
+ :type 'string)
(defun wnn-filename (p)
""
(wnnrpc-open-file proc env-id freqname)) ; XXX: error?
-1))
-(defun wnn-get-environment (dic-spec)
- "Return WNN Environemt. If none, create new environment.
-Take one argument DIC-SPEC for dictionary specification."
- (if wnn-environment
- wnn-environment
- (let ((username (user-login-name))
- (proc (wnn-open wnn-server "ja_JP")))
- (setq wnn-environment
- (wnn-create-environment proc username nil dic-spec)))))
-
-(defun wnn-create-environment (proc username reverse-flag spec)
+(defun wnn-get-environment (server-info &optional dic-set reverse)
+ "Return WNN Environemt for the conversion server specified
+by SERVER-INFO. If none, create new environment. Optional
+argument DIC-SET specifies dictionary set. Optional argument
+REVERSE specifies reverse conversion, if non nil."
+ (let ((server-type (wnn-server-type server-info))
+ (env wnn-environments)
+ proc spec e s)
+ (setq reverse (null (null reverse)))
+ (if (catch 'found
+ (while env
+ (setq e (car env))
+ (if (and (eq (wnnenv-get-server-type e) server-type)
+ (eq (wnnenv-get-dictionary-set e) dic-set)
+ (eq (wnnenv-get-reverse-flag e) reverse))
+ (throw 'found t))
+ (setq env (cdr env))))
+ e
+ (setq proc (wnn-open server-info)
+ spec (wnn-get-dic-spec server-type))
+ (while spec
+ (setq s (car spec)
+ e (wnn-create-environment proc server-type s)
+ wnn-environments (cons e wnn-environments))
+ (if (and (eq (wnn-dic-spec-dic-set s) dic-set)
+ (eq (wnn-dic-spec-reverse s) reverse))
+ (setq env e))
+ (setq spec (cdr spec)))
+ env)))
+
+(defun wnn-create-environment (proc server-type spec)
""
;; Create new data structure: something like wnn_buf
;; Process, Environment-ID and Daibunsetsu-info.
- (let (env env-id parameters)
- (setq env-id (wnnrpc-connect proc username))
+ (let (env-id parameters filename fuzokugo-fid ret dic-set reverse)
+ (setq env-id (wnnrpc-connect proc (wnn-make-env-name spec)))
(if (< env-id 0)
- (let ((msg (wnnrpc-get-error-message (- env-id))))
- (error "Can't connect new WNN environment: %s" msg)))
- (setq parameters (car spec))
- (setq spec (cdr spec))
- (let ((filename (wnn-filename (car spec)))
- fuzokugo-fid ret)
- (setq fuzokugo-fid (wnn-open-file proc env-id filename))
- (if (null fuzokugo-fid)
- (setq fuzokugo-fid -1)
- (if (< fuzokugo-fid 0)
- (let ((msg (wnnrpc-get-error-message (- fuzokugo-fid))))
- (message "WNN: Can't open fuzokugo file (%s): %s" filename msg)
- (setq fuzokugo-fid -1))))
- (setq ret (wnnrpc-set-fuzokugo-file proc env-id fuzokugo-fid))
- (if (< ret 0)
- (let ((msg (wnnrpc-get-error-message (- ret))))
- (message "WNN: Error on setting fuzokugo (%s): %s" filename msg))))
- (setq spec (cdr spec))
+ (error "Can't connect new WNN environment: %s"
+ (wnnrpc-get-error-message (- env-id))))
+ (setq dic-set (wnn-dic-spec-dic-set spec)
+ reverse (wnn-dic-spec-reverse spec)
+ parameters (wnn-dic-spec-param spec)
+ filename (wnn-filename (wnn-dic-spec-fuzokugo spec))
+ fuzokugo-fid (wnn-open-file proc env-id filename))
+ (if (null fuzokugo-fid)
+ (setq fuzokugo-fid -1)
+ (if (< fuzokugo-fid 0)
+ (progn
+ (message "WNN: Can't open fuzokugo file (%s): %s"
+ filename
+ (wnnrpc-get-error-message (- fuzokugo-fid)))
+ (setq fuzokugo-fid -1))))
+ (setq ret (wnnrpc-set-fuzokugo-file proc env-id fuzokugo-fid))
+ (if (< ret 0)
+ (let ((msg (wnnrpc-get-error-message (- ret))))
+ (message "WNN: Error on setting fuzokugo (%s): %s" filename msg)))
+ (setq spec (wnn-dic-spec-dic-list spec))
(while spec
- (let ((dic-spec (car spec)))
- (wnn-set-dictionary proc env-id reverse-flag dic-spec)
- (setq spec (cdr spec))))
- (wnnrpc-set-conversion-parameters proc env-id parameters)
- (setq env (wnnenv-create proc env-id))
- env))
+ (wnn-set-dictionary proc env-id reverse (car spec))
+ (setq spec (cdr spec)))
+ (if parameters
+ (wnnrpc-set-conversion-parameters proc env-id parameters))
+ (wnnenv-create proc env-id server-type dic-set reverse)))
+
+(defvar wnn-user-name nil)
+
+(defun wnn-make-env-name (spec)
+ (or wnn-user-name
+ (setq wnn-user-name (getenv "WNNUSER"))
+ (setq wnn-user-name (user-login-name)))
+ (concat wnn-user-name (wnn-dic-spec-name spec)))
(defun wnn-update-frequency (env bunsetsu-info-list)
(let ((l bunsetsu-info-list))
(wnnrpc-add-word env dic-number yomi kanji comment
hinshi-id initial-freq)))
+;;; setup
+
+(require 'egg)
+(load "egg/wnnrpc")
+
+;;;###autoload
+(defun egg-activate-wnn (&optional arg)
+ "Activate Wnn backend of Tamagotchy."
+ (egg-set-support-languages wnn-support-languages)
+ (egg-set-conversion-backend wnn-conversion-backend
+ (list (nth 2 arg))
+ wnn-support-languages)
+ (apply 'egg-mode arg))
+
;;; egg/wnn.el ends here.