SKK の環境をいろいろと整備してみる

最近、SKK 周りの設定をいろいろと弄ってみたのでそのあたりのメモ。

作業前のサーバ環境は

rskkserv ┬ SKK-JISYO.L
         ├ skkserv2
         └ mecab-skkserv

yaskkserv (サーバコンプリーション用)
bskk (ベイジアン学習サーバ)

となっていて、rskkserv で SKK-JISYO.L の他に skkserv2 と mecab-skkserv の複合語辞書サーバを串刺しにして使っていた。

`skk-search-prog-list' の設定はこんな感じ。

((skk-search-jisyo-file skk-jisyo 0 t)	; 個人辞書
 (skk-search-server skk-aux-large-jisyo 10000) ; rskkserv
 (skk-abbrev-search)
 (skk-look)
 ...
 (skk-server-completion-search))	; サーバコンプリーション

これでずっと使っていたのだが、それなりに不満な点もあった。

複合語が候補として出てくるのが早い
複合語はあくまでも補完的な位置付けにしたいので後のほうに出てきてほしい。
その変換候補を誰が出してきたのか一見して判らない
候補が SKK-JISYO.L 由来のものならもちろん問題ない。複合語辞書サーバの返答ならば眉に唾つけて見ないといけないのだが、そのあたりの区別がつかないので簡単に信用できない。
個人辞書に変なのが混ざるかも
そういった信用ならない候補を間違って確定してしまった場合も個人辞書に登録される。その場で取り消せばいいのだが、見逃すと後の祭りとなる。

要は複合語辞書サーバ絡み。使うのを止めればいいのではあるが、激しく便利なときもあるのでそうもいかず。

そこでこれらを改善すべく対処していく。

rskkserv での串刺しをやめる

とにかく rskkserv で抱え込んでしまってるとどうにもならないので各サーバは別建てにして個別にアクセスすることにする。

複製のサーバを検索できるように

現在の SKK には複数の辞書サーバにアクセスする仕組は用意されていないので自力でやる必要がある。

以前やったのと似たようなことをやればいい訳だが、面倒なのでマクロをでっちあげる。

(defmacro my-define-skk-search-server (name host port &optional id)
  "HOST, PORT を変更した `skk-search-server' を NAME の名前で定義する。"
  `(defun ,name (file limit &optional nomsg id)
     (let* ((server (or ,host ,skk-server-host))
	    (port (or ,port ,skk-server-portnum))
	    (name (symbol-name ',name))
	    (skkserv-working-buffer (get-buffer-create
				     (concat " *" name "*")))
	    (proc (get-buffer-process skkserv-working-buffer))
	    (skkserv-process (or (and (skk-server-live-p proc) proc)
				 (open-network-stream name
						      skkserv-working-buffer
						      server port))))
       ;; emacs21 hasn't `set-process-query-on-exit-flag'
       (when (fboundp 'set-process-query-on-exit-flag)
	 (set-process-query-on-exit-flag skkserv-process nil))
       ;; don't work if default coding system is utf-8
       (set-process-coding-system skkserv-process 'euc-japan 'euc-japan)
       (my-skk-add-dictid-to-annotation
	(skk-search-server file limit nomsg) ,id))))

ついでにこんなのも作ってみる。

(defun my-skk-add-dic (list)
  "`skk-search-prog-list' の末尾に list を追加する。"
  (add-to-list 'skk-search-prog-list list t))

こうやっておいて、

;; 複合語サーバ (skkserv2, mecab-skkserv) を加える
(my-define-skk-search-server my-skk-server-skkserv2 nil 1179 "<skkserv2>")
(my-skk-add-dic '(my-skk-server-skkserv2 nil nil))
(my-define-skk-search-server my-skk-server-mecab nil 1180 "<MeCab>")
(my-skk-add-dic '(my-skk-server-mecab nil nil))

とやると、`skk-server-host' のポート1179, 1180 に上げてあるサーバにアクセス出来るようになる。ID 引数については次項。

複合語サーバの検索結果にはアノテーションを付ける

skkserv2 と mecab-skkserv の検索結果には注意喚起としてアノテーションを追加することにする。

(defun my-skk-add-dictid-to-annotation (list id)
  "LIST の各要素に ID をアノテーションとして付加する。"
  (if (and id list)
      (let (cand)
	(mapcar (lambda (x)
		  (setq cand (skk-treat-strip-note-from-word x))
		  (concat (car cand)
			  (if (cdr cand)
			      (concat ";" (cdr cand) " " id)
			    (concat ";" id))))
		list))
    list))

こんなんを追記。これで `my-skk-server-skkserv2' の第4引数に指定した文字列がそのサーバの返した候補全てにアノテーションとして付加される。元々アノテーションがついている場合にはその後に。


といったことで、現在のところサーバ側は

rskkserv ┬ SKK-JISYO.L+
         ├ SKK-JISYO.jinmei
         └ SKK-JISYO.fullname

skkserv2
mecab-skkserv
yaskkserv (サーバコンプリーション用)
bskk (ベイジアン学習サーバ)

こうなった。各サーバは単独に。ついでに rskkserv には SKK-JISYO.L の変わりに SKK-JISYO.L+ を喰わせてみるとともに、jinmei と fullname も加えてみた。

`skk-search-prog-list' はこう。

((skk-search-jisyo-file skk-jisyo 0 t)	; 個人辞書
 (skk-search-server skk-aux-large-jisyo 10000) ; rskkserv
 (skk-abbrev-search)
 (skk-look)
 ...
 (my-skk-server-skkserv2 nil nil)	; skkserv2
 (my-skk-server-mecab nil nil)		; mecab-skkserv
 ...
 (skk-server-completion-search))	; サーバコンプリーション

複合語サーバは後のほうにもってきたので候補は後半に出てくるし、アノテーションも付くので一見して候補の出自が判る。うっかり個人辞書に登録してもアノテーションに指定した ID を grep すればいいだけなので後から探すのも容易になった。