Tamagotchy snapshot. egg-971106
authormorioka <morioka>
Thu, 20 Nov 1997 15:09:22 +0000 (15:09 +0000)
committermorioka <morioka>
Thu, 20 Nov 1997 15:09:22 +0000 (15:09 +0000)
19 files changed:
AUTHORS [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
Makefile [new file with mode: 0644]
README [new file with mode: 0644]
TODO [new file with mode: 0644]
docomp.el [new file with mode: 0644]
egg-cnv.el [new file with mode: 0644]
egg-com.el [new file with mode: 0644]
egg-mlh.el [new file with mode: 0644]
egg.el [new file with mode: 0644]
egg/sj3.el [new file with mode: 0644]
egg/sj3rpc.el [new file with mode: 0644]
egg/wnn.el [new file with mode: 0644]
egg/wnnrpc.el [new file with mode: 0644]
euc-cn.el [new file with mode: 0644]
its.el [new file with mode: 0644]
its/hira.el [new file with mode: 0644]
leim-list-egg.el [new file with mode: 0644]
menudiag.el [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..162e024
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,22 @@
+NIIBE Yutaka <gniibe@mri.co.jp>
+       Design a part of ITS programming.
+       Wrote ITS:
+           its.el
+           its/hira.el
+       Wrote tamago.el, menudiag.el, tamago-cnv.el, tamago-comm.el,
+       and tamago-mlh.el.
+       Wrote backend conversion engine interface:
+           SJ3: tamago-lib/sj3.el, tamago-lib/sj3rpc.el,
+           WNN: tamago-lib/wnn.el, and tamago-lib/wnnrpc.el.
+
+KATAYAMA Yoshio <kate@pfu.co.jp>
+       Design ITS programming.
+       Wrote its/hangul.el, its/erpin.el, its/pinyin.el, its/zhuyin.el.
+
+Satoru Tomura <tomura@etl.go.jp>
+       Designer/Implementor/Maintainer of EGG through V3.0.
+       Discussion/Design around ITS.
+       Suggestion around how to write code in LISP.
+
+Hisashi Miyashita <himi@bird.scphys.kyoto-u.ac.jp>
+       Wrote CCL routines in tamago-com.el.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..832d252
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,1531 @@
+1997-11-03  KATAYAMA Yoshio <kate@pfu.co.jp>
+
+       * euc-cn.el: New file.  Original name was yincoding.el.
+       Adopted by NIIBE Yutaka  <gniibe@mri.co.jp>.
+       
+1997-11-03  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its.el (its-start): Add INVISIBLE property if ITS-FENCE-FACE.
+       * egg-cnv.el (egg-decide-before-point): Ditto.
+       Based on patch by Kenichi HANDA <handa@etl.go.jp>.
+
+       Once, I thought that we need many environments which correspond to
+       outstanding CONVERSION buffre.  However, I've learned that WNN4
+       protocol is completely independent.  It's no use to maintain each
+       environment.  Share the one environment.
+       * egg/wnn.el (wnn-environments): Removed.  
+       (wnn-environment): New variable.
+       (wnn-comm-sentinel): Follow the change.  Let users know the close.
+       (wnn-fini): Likewise.
+
+       <env>: Remove the member <in-use>.
+       (wnnenv-create): Follow the structure change.
+       (wnn-end-conversion): Likewise.
+       (wnnenv-get-in-use-flag, wnnenv-set-in-use-flag): Removed.
+       (wnn-find-env-not-in-use): Removed.
+       (wnn-get-environment): Use wnn-environment instead of wnn-environments.
+       Take one argument.
+
+       * egg-cnv.el (egg-decide-before-point): Signal error on first SYL.
+       Reported by KATAYAMA Yoshio <kate@pfu.co.jp>.  Changes of 1997-09-07
+       was not enough.
+       Set-marker M to NIL after PUT-TEXT-PROPERTY.
+
+       Because the name of identifier begins egg-*, change the file names.
+       * tamago: Rename from tamago.
+       * egg.el, egg-mlh.el, egg-com.el, egg-cnv.el: Rename from tamago-*.el
+       * Makefile: Follow the changes.
+
+1997-10-05  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * tamago/wnn.el (wnn-uniq-candidates): Add new argument BUNSETSU.
+       Call WNN-BUNSETSU-SET-ZENKOUHO-POS, WNN-BUNSETSU-SET-ZENKOUHO in
+       this function.  Handle the case where BUNSETSU is not the first
+       element of BUNSETSU-LIST.
+       (wnn-list-candidates): Use new API of WNN-UNIQ-CANDIDATES.
+
+       * tamago-cnv.el (egg-next-candidate): Handle the case where
+       EGG-LIST-CANDIDATES returns non zero value.
+
+1997-10-04  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * Makefile (install): Install to SITEDIR.
+
+1997-09-26  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its/hira.el (its-hira-enable-zenkaku-alphabet): New variable.
+       (its-hira-map): Use it.
+
+1997-09-19  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       Arrange for LEIM.  Use tamago/ subdirectory.
+       * tamago/: Rename from tamago-lib.
+
+1997-09-18  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * tamago-cnv.el (egg-select-candidate): menu-select -->
+       menudiag-select. 
+       * tamago.el (egg-toroku-region, egg-hinshi-select): Likewise.
+
+       * tamago-cnv.el (egg-exit-conversion): Run hook of
+       input-method-after-insert-chunk-hook.
+       * its.el (its-exit-mode-internal): Ditto.
+
+       * tamago-mlh.el (mlh-comma-period-style): Deleted.
+
+       * its/, tamago-lib/: New directory.
+       * its/: Move its-*.el files here.
+       * tamago-lib/: Move sj3.el, sj3rpc.el, wnn.el and wnnrpc.el here.
+
+       * tamago-com.el: Rename from comm.el.
+       * tamago-mlh.el: Rename from mlh.el.
+       * tamago-cnv.el: Rename from convert.el.
+
+       * menudiag.el: Rename from menu.el.
+       (Throughout): Rename menu-* to menudiag-*.
+
+1997-09-07  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * egg.el (egg-insert-after-hook, egg-exit-hook): Removed.
+       (egg-sai-henkan-start, egg-sai-henkan-end, egg-old-bunsetu-suu):
+       Removed.
+
+       * wnn.el (WNN-const): New macro.
+       (wnn-start-conversion, wnn-open-dictionary, wnn-open-frequency,
+       wnn-set-dictionary-sub, wnn-update-frequency): Use it.
+
+       * wnnrpc.el (wnn-const): New macro.
+       Throughout: Use wnn-const.
+
+       * convert.el (egg-decide-before-point): Bug fix.  Handle the case
+       where all bunsetsu are decided.
+       Reported by KATAYAMA Yoshio <kate@pfu.co.jp>.
+
+       * convert.el (egg-exit-conversion): Call egg-end-conversion at end.
+       (egg-decide-before-point): Ditto.
+
+       * wnn.el (wnn-environments): Change the structure of enviromnents.
+       (wnn-fini): Handle errors.
+       (wnn-open): Set sentinel.  Delete buffer on failure.
+       (wnn-comm-sentinel): New function.
+       (wnn-find-env-not-in-use): Return nil when not found.
+
+       (wnn-create-environment): Take username as argument.
+       (wnn-get-environment): Follow the change.
+
+       (wnnenv-create): Remove useless serial no.
+       (wnnenv-get-in-use-flag, wnnenv-set-in-use-flag): Follow the change.
+       (wnnenv-get-daibunsetsu-info, wnnenv-set-daibunsetsu-info): Likewise.
+       (wnn-create-environment, wnn-get-environment): Likewise.
+
+1997-09-04  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its.el (its-state-machine-keyseq): Bug fix.  Handle VSYL.
+
+       * sj3.el, sj3rpc.el: New files.
+
+       * comm.el (comm-call-with-proc, comm-call-with-proc-1): New macros.
+       * wnnrpc.el (wnnrpc-call-with-proc, wnnrpc-call-with-proc-1): Deleted.
+       Throughout: Use comm-call-with-proc and comm-call-with-proc-1.
+
+1997-09-03  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnnrpc.el (wnnrpc-call-with-proc-1): Bug fix.  let --> progn.
+
+       * convert.el (egg-conversion-backend): Initail value is NIL.
+
+       * wnn.el (wnn-conversion-backend): New constant.
+
+       * comm.el (comm-format,comm-unpack): Support multibyte string.
+       (comm-format-mb-string): New substitution.
+       (comm-unpack-mb-string): New substitution.
+
+       * wnn.el (wnn-fini): Handle the case where wnn-environments is nil.
+       Reported by Hisashi Miyashita <himi@bird.scphys.kyoto-u.ac.jp>.
+
+1997-09-03  Hiroshi Ogata <hiroshi@nereid.rim.or.jp>
+
+       * mlh.el (mlh-zenkaku): Use new API of Emacs-20,
+       japanese-zenkaku-region.
+
+1997-09-02  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * egg.el (egg-toroku-region): New function.
+
+       * wnn.el (wnn-list-dictionaries): New function.
+       (wnnenv-get-proc): New function.
+
+       * wnnrpc.el (wnndic-get-id, wnndic-get-comment, wnndic-get-dictname): 
+       New substitution.
+       (wnnrpc-get-writable-dictionary-id-list): Rename from
+       wnnrpc-get-writable-dictionary-list.
+
+1997-09-01  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * convert.el (egg-decide-bunsetsu): New function.
+       (egg-decide-before-point): New command.
+       (egg-exit-conversion): Use egg-decide-bunsetsu.
+
+       * its.el (its-start): Divide the fence buffer into two parts and
+       make them intangible, so that point goes appropriate position.
+       (its-put-cursor): The cursor belongs to part-2.
+       (its-buffer-ins/del-SYL): The new SYL belongs to part-1.
+       (its-exit-mode-internal): Remove the property on exit.
+       (its-beginning-of-input-buffer): Make SYLs have property of "part 2".
+       (its-backward-SYL): Likewise.
+       (its-forward-SYL): Make SYLs have property of "part 1".
+       (its-end-of-input-buffer): Likewise.
+
+       (its-input-end): Delete useless argument.
+       (its-beginning-of-input-buffer, its-exit-mode,
+       its-exit-mode-off-input-method, its-kick-convert-region,
+       its-end-of-input-buffer, its-backward-SYL, its-forward-SYL,
+       its-delete-SYL): Follow the change.
+
+1997-08-31  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       For egg-mode, don't use minor mode, override local map instead.
+       For its-mode and egg-conversion-mode, don't use minor mode,
+       instead use local-map of text property.
+
+       Although overriding local map is not good, using local-map of
+       property is natural thing.  Besides, point-left/point-entered
+       don't work as I expected (yet).
+
+       * egg.el (egg-mode: variable): Removed.
+       * egg.el (egg-modefull-map, egg-modeless-map): Make them functions.
+       Generate overriding local map.
+       * egg.el (egg-mode): use overriding local map.
+
+       * its.el, convert.el: Undo changes of 1997-08-28 for minor mode
+       and local map of text properties.
+
+       * its.el (its-exit-mode-off-input-method): New function.
+
+1997-08-29  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       Let Undo work correctly.
+       * its.el (its-self-insert-char): Delete/Insert cursor.
+
+       * its.el (its-put-cursor): Remove useless first argument.
+       (its-start, its-beginning-of-input-buffer, its-end-of-input-buffer,
+       its-backward-SYL, its-forward-SYL, its-delete-SYL, its-delete-SYL,
+       its-delete-backward-SYL-internal, its-delete-backward-within-SYL): 
+       Follow the change.
+
+1997-08-28  KATAYAMA Yoshio <kate@pfu.co.jp>
+
+       * its-erpin.el: New file.
+       * its-pinyin.el: New file.
+       * its-zhuyin.el: New file.
+
+1997-08-28  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its.el (its-exit-mode-no-egg): Removed.
+       (its-exit-mode-internal): Remove first argument.
+       (its-kick-convert-region, its-delete-SYL,
+       its-delete-backward-SYL-internal, its-delete-backward-within-SYL):
+       Follow the change.
+
+       Don't use local map of text properties, instead use minor mode.
+       * convert.el (egg-conversion-mode): New minor mode.
+       (egg-conversion-left, egg-conversion-enter): New functions.
+       (egg-insert-bunsetsu): remove local-map, add point-entered and
+       point-left properties.
+       (egg-exit-conversion): Likewise.
+       (egg-exit-conversion): Exit minor mode.
+
+       * its.el (its-put-cursor): remove local-map, add point-entered and
+       point-left properties.
+       (its-enter, its-left): New functions.
+       (its-mode): New variable.  New minor mode.
+
+1997-08-27  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * convert.el (egg-exit-conversion-no-egg): Removed.
+       (egg-exit-conversion): No argument, no egg-mode.
+
+       * convert.el (egg-convert-region): No egg-flag.
+       * its.el (its-exit-mode-internal): Follow it.
+       * mlh.el (mlh-space-bar-backward-henkan): Ditto.
+
+1997-08-26  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnn.el (wnn-change-bunsetsu-length): Don't use magic #3.
+
+       * convert.el (egg-insert-bunsetsu-list): Add optional argument
+       CONTIN.
+
+1997-08-25  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * convert.el (egg-insert-bunsetsu): Include seperator.  Add
+       intangible property to bunsetsu.
+       (egg-insert-bunsetsu-list): Follow the change.
+       (egg-backward-bunsetsu, egg-forward-bunsetsu, 
+       egg-select-candidate, egg-next-candidate, 
+       egg-shrink-bunsetsu, egg-enlarge-bunsetsu, 
+       egg-exit-conversion): Ditto.
+
+       * mlh.el (mlh-space-bar-backward-henkan): Call egg-convert-region
+       with last argument t.  Turn of egg-mode.
+
+1997-08-24  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its.el (its-exit-mode-internal): Inactivate input method.
+
+       * wnn.el (wnn-end-conversion): Change the interface.
+       (wnn-update-frequency): Follow the change.
+       * convert.el (egg-exit-conversion): Follow the change.
+
+       * wnn.el (wnn-start-conversion): Change the return value interface.
+       * convert.el (egg-convert-region): Follow the change.
+
+       * wnn.el (wnnenv-get-bunsetsu-pos, wnnenv-set-bunsetsu-pos): Removed.
+       (wnn-get-bunsetsu-source-afterwards): Removed.
+       (wnn-get-number-of-bunsetsu, wnn-get-bunsetsu-info): Removed.
+       (wnnenv-get-bunsetsu-list, wnnenv-set-bunsetsu-list): Removed.
+       (wnn-start-conversion): Don't call wnnenv-set-bunsetsu-list.
+       (wnn-end-conversion): Ditto.
+
+1997-08-23  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * convert.el (egg-change-bunsetsu-length): Change the interface.
+       (egg-shrink-bunsetsu,egg-enlarge-bunsetsu): Follow it.
+
+       (egg-source-maxlen-from-here): Removed.
+       (egg-get-previous-bunsetsu): New function.
+       (egg-select-candidate, egg-shrink-bunsetsu, egg-enlarge-bunsetsu,
+       egg-next-candidate): Use egg-get-previous-bunsetsu.
+
+1997-08-20  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * egg.el (minor-mode-alist): Don't show " EGG" in mode line.
+       (egg-mode): Use input method indicator instead.
+
+1997-07-20  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * convert.el (egg-next-candidate): Rename from egg-next-conversion.
+       (egg-previous-candidate): Rename from egg-previous-conversion.
+       (egg-select-candidate): Follow the change of new interface.
+       (egg-source-maxlen-from-here): Likewise.
+
+1997-07-19  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnn.el (wnn-start-conversion): Change the interface.  Return ENV
+       and the list of bunsetsu.  Fix the documentation string too.
+       * convert.el (egg-convert-region): Follow the change.
+       (egg-insert-converted-result): Change the argument.
+       (egg-insert-bunsetsu-list): Rename from egg-insert-converted-result.
+       (egg-insert-bunsetsu): New function.
+       (egg-get-number-of-bunsetsu,egg-get-bunsetsu-info): Removed.
+       (egg-backward-bunsetsu): Don't use bunsetsu-pos.
+
+       * wnn.el (wnn-get-bunsetsu-converted): Change the interface.  Take
+       BUNSETSU as the argument instead of ENV and POS.
+       * convert.el (egg-get-bunsetsu-converted): Follow the change.
+
+       * wnn.el (wnn-bunsetsu-create): Take ENV as the first argument.
+       (wnn-list-candidates): Dont take ENV.
+       (wnn-bunsetsu-get-env): New substitution.
+
+       * wnnrpc.el (wnnrpc-receive-sho-bunsetsu-list-sub): Take the argument
+       for ENV, and use it for the argument of wnn-bunsetsu-create.
+       (wnnrpc-receive-sho-bunsetsu-list): Take ENV as the first argument.
+       (wnnrpc-renbunsetsu-conversion): Follow the change.
+
+1997-07-17  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * convert.el (egg-decide-candidate):  Change the interface.
+       Take the argument bunsetsu-info instead of conversion-engine.
+
+       * wnn.el (wnn-get-candidate): Deleted.
+
+       * convert.el (egg-get-all-candidates): Change the interface.
+       Take an argument bunsetsu-info instead of conversion-engine.
+       (egg-select-candidate): Follow the change.
+
+       * convert.el (egg-set-bunsetsu-pos,egg-get-bunsetsu-pos): Deleted.
+       (egg-list-candidates,egg-get-current-candidate-number): New stub.
+       * wnn.el (wnn-bunsetsu-create): Add new member zenkouho-pos.
+       (wnn-bunsetsu-get-zenkouho-pos,wnn-bunsetsu-set-zenkouho-pos): New
+       functions.
+       (wnn-list-candidates,wnn-get-current-candidate-number): New functions.
+       (wnn-set-bunsetsu-pos,wnn-get-bunsetsu-pos): Deleted.
+
+       * convert.el (egg-get-number-of-candidates): Change the interface.
+       Take an argument bunsetsu-info instead of conversion-engine.
+       (egg-next-conversion,egg-select-candidate): Follow the change.
+       * wnn.el (wnn-get-number-of-candidates): Follow the change.
+
+       * wnn.el (wnn-get-bunsetsu-source-afterwards): New function.
+       (wnn-change-bunsetsu-length): Use it.
+
+       * convert.el (egg-get-bunsetsu-source): Change the interface.
+       Take an argument bunsetsu-info instead of conversion-engine.
+       (egg-enlarge-bunsetsu,egg-shrink-bunsetsu,egg-source-maxlen-from-here):
+       Follow the change.
+       * wnn.el (wnn-get-bunsetsu-source): Follow the change.
+
+       Put bunsetsu information on text property.
+       * wnn.el (wnn-get-bunsetsu-info): New function.
+
+       * convert.el (egg-insert-converted-result): Put it on text property.
+       (egg-conversion-backend): Add new interface
+       wnn-get-bunsetsu-info.
+       (egg-get-bunsetsu-info): New stub.
+
+1997-07-17  KATAYAMA Yoshio <kate@pfu.co.jp>
+
+       * its.el (its-state-machine-keyseq, its-state-machine): Handle
+       end-of-input correctly when going backward.
+
+1997-07-16  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnn.el (wnn-create-directory): Bug fix.  Really make directory.
+
+1997-07-15  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its-hangul.el (its-define-hangul): Use its-defrule-otherwise.
+
+1997-07-15  KATAYAMA Yoshio <kate@pfu.co.jp>
+
+       * its-hangul.el: Updated.
+
+1997-06-19  NIIBE Yutaka  <gniibe@akebono.etl.go.jp>
+
+       * its-hira.el: its-hira-hankaku-escape --> its-hankaku-escape.
+       its-hira-zenkaku-escape --> its-zenkaku-escape.
+
+1997-06-14  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its.el: Change the data structure of <expr-output-back-list> so
+       that it can encourage sharing same structure and it can use same
+       structure of SYL.
+       (its-ins/del-SYL-batch): Follow the change of data structure.
+       (its-define-otherwise): Change the argument.
+       (its-defrule-otherwise): New function.
+       (its-eob-keyexpr, its-eob-back, its-make-class+back,
+       its-make-otherwise): New substitutions.
+
+1997-06-13  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its-kana.el: New file.  Taken from its/kanainput.el of Mule-2.3.
+
+       * its-hira.el: Use `define-its-state-machine'.
+
+       * its.el (its-zenkaku-escape, its-hankaku-escape): Make them
+       defconst.
+       (define-its-state-machine, define-its-state-machine-append): New
+       macro.
+
+1997-06-13  NIIBE Yutaka  <gniibe@akebono.etl.go.jp>
+
+       * its-hira.el ("n'"): Added.
+
+1997-06-12  NIIBE Yutaka  <gniibe@akebono.etl.go.jp>
+
+       its-zenkaku-escape and its-hankaku-escape are also used in hangul.
+       * its.el (its-zenkaku-escape, its-hankaku-escape): Moved to here
+       and rename them.
+       * its-hira.el (its-hira-hankaku-escape, its-hira-zenkaku-escape): 
+       Removed.
+
+       * its.el (its-read-current-its-string): Removed.  There's the
+       function `read-multilingual-string' already.
+
+1997-06-12  KATAYAMA Yoshio <kate@pfu.co.jp>
+
+       * its-hangul.el: New file.
+
+1997-06-10  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       Miscellaneous cosmetic changes.
+       * comm.el: New file.  Move communication related funcitons from
+       wnnrpc.el.
+       (comm-format-u32c, and others): Rename from wnnrpc-*.
+       * wnnrpc.el (Throughout): Follow the rename.
+
+       * wnn.el (wnnenv-get-in-use-flag): Rename from wnn-e-get-in-use.
+       (wnnenv-set-in-use-flag): Rename from wnn-e-set-in-use.
+       (Others): Rename from wnn-e-*.
+       (wnn-bunsetsu-*): Rename from wnnrpc-b-*, and moved from wnnrpc.el.
+
+       * convert.el (egg-exit-conversion): Call egg-do-auto-fill.
+
+       * its.el (its-translate-region): Bug fix.  End of input.
+       (its-state-machine): Bug fix.  Generate error if
+       its-barf-on-invalid-keyseq.
+       (its-exit-mode-internal): Call egg-do-auto-fill.
+
+       * wnnrpc.el (ccl-decode-fixed-euc-jp): Bug fix for ASCII.
+
+       * mlh.el (mlh-space-bar-backward-henkan): Call egg-do-auto-fill.
+
+       * egg.el: Comment out definition of C-\ in global-map.
+
+1997-06-09  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its.el (its-kick-convert-region): Rename from its-convert-region.
+       (its-mode-map): Follow the change.
+
+       (its-make-next-state): Use list instead of cons.
+
+       (its-get-kst/t): Make it substitution.
+       (its-set-kst, its-get-keyseq, its-set-keyseq, its-kst-p, 
+       its-get-output, its-set-output, its-get-keyseq-syl): Likewise.
+       (its-new-state, its-new-map, its-get-indicator, its-set-indicator,  
+       its-get-start-state, its-reset-start-state): Likewise.
+
+       (its-get-next-state): Use assq instead of assoc.
+
+       (its-goto-state): Tune up.
+
+1997-06-08  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * mlh.el: Merge mlh-nihongo.el.
+       * mlh-nihongo.el: Removed.
+
+       * its-hira.el: Moved from its/hira.el.  Move comments to HISTORY.
+       (its-hira-enable-double-n, its-hira-period, its-hira-comma,
+       its-hira-open-bracket, its-hira-close-bracket,
+       its-hira-horizontal): New variables.
+       Use the variables to define the state-machine.
+
+       Implement non-interactive translation in ITS.
+       * its.el (its-translate-region): New function.
+       (its-latest-SYL): New Variable.
+       (its-state-machine-keyseq): Use it.
+       (its-update-latest-SYL): New function.
+       (its-buffer-ins/del-SYL): Use it.
+       (its-translation-result): New variable.
+       (its-ins/del-SYL-batch): New function.
+       (its-enable-double-n-syntax, its-use-kuten-for-period,
+       its-use-touten-for-comma, its-zenkaku-escape, its-hankaku-escape):
+       Removed.
+
+       Use ITS, delete mlh's own implementation of automata.
+       * mlh.el (mlh-start-state, mlh-set-of-chars, mlh-start-state-sym,
+       mlh-set-of-chars-sym, mlh-define-automata, mlh-end-of-definition,
+       mlh-defrule, mlh-next-state, mlh-roma-kana-backward): Removed.
+       (mlh-cause-error-when-unknown-romaji-sequence): Removed.
+       (mlh-atoi): Removed.
+       (mlh-white-space, mlh-zenkaku-white): Use string-to-int.
+       * mlh-nihongo.el (mlh-hira-start-state, mlh-hira-chars, and all
+       rules of definition which defines the automaton): Removed.
+       (mlh-kanji-with-henkan-region-function): Use its-translate-region.
+       (mlh-hiragana, mlh-katakana): Likewise.
+
+       Fix of CCL.
+       * wnnrpc.el (ccl-decode-fixed-euc-jp): Bug fix for jisx0212.
+       Add missing parens.
+
+       Speed up of unpacking.
+       * wnnrpc.el (wnnrpc-following-char-or-wait): Tune up.
+       (wnnrpc-following+forward-char): New function.
+       (wnnrpc-unpack-u32c, wnnrpc-unpack-u32, wnnrpc-unpack-u16,
+       wnnrpc-unpack-u8): Use it.
+       (wnnrpc-accept-process-output): New function.
+       (wnnrpc-unpack-u16-string, wnnrpc-unpack-u8-string,
+       wnnrpc-unpack-bytes): Use it.  Use search-forward.
+       (wnnrpc-unpack-u16-string): Use decode-coding-region.
+
+1997-06-07  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnn.el (wnn-get-all-candidates): New function.
+       (wnn-set-bunsetsu-pos): Return 0 (instead of -1).
+
+       * convert.el (egg-get-candidate): Removed.
+       (egg-get-all-candidates): New entry function.
+       (egg-conversion-backend): Entry for egg-get-all-candidates.
+       (egg-select-candidate): New function.
+       (egg-conversion-map): Bind "\M-s" and egg-select-candidate.
+
+1997-06-05  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * bushu.el: Renamed from busyu.el.
+       (bushu-break-string, etc): Renamed from busyu*.
+
+       * menu.el: Completely rewritten.
+
+1997-06-03  NIIBE Yutaka  <gniibe@akebono.etl.go.jp>
+
+       * its.el (its-reset-start-state): Bug fix.  Delete a CDR.
+
+       Implement "class of key" transition.
+       Change the structure of <state>, the last member is
+       <key-state-table/terminal> instead of <key-state-alist/terminal>.
+       * its.el (its-kst-p): Rename from its-ksa-p.
+       (its-get-next-state): Follow the change of the data structure.
+       (its-state-machine): Likewise.
+       (its-make-next-state): Likewise.
+       (its-set-kst): New function.
+       (its-get-otherwise): New function.
+       (its-otherwise-match): New function.
+       (its-define-otherwise-terminate-here): Removed.
+       (its-define-otherwise): New function.
+       (its-defrule*): Use its-define-otherwise.
+
+       * its/hira.el (n): Use its-define-otherwise.
+
+1997-06-02  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnnrpc.el (wnnrpc-receive-sho-bunsetsu-list-sub,
+       wnnrpc-receive-sho-bunsetsu-list-sub-2): Splited from
+       wnnrpc-receive-sho-bunsetsu-list.
+       (wnnrpc-receive-dai-bunsetsu-list): New function.
+       (wnnrpc-daibunsetsu-conversion, wnnrpc-get-daibunsetsu-candidate): 
+       New function.
+
+1997-06-01  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnnrpc.el (ccl-decode-fixed-euc-jp): Clean it up.
+       (wnnrpc-file-attribute): Rename from wnnrpc-stat-file.
+       (wnnrpc-get-dictionary-list-with-environment): Rename from
+       wnnrpc-get-dictionary-list-with-environment.
+
+       Implement RPC more.
+       * wnnrpc.el (wnnrpc-who, wnnrpc-get-env-list, wnnrpc-kill,
+       wnnrpc-delete-dictionary, wnnrpc-set-flag-on-dictionary,
+       wnnrpc-get-dictionary-list, wnnrpc-delete-word,
+       wnnrpc-receive-word, wnnrpc-search-word,
+       wnnrpc-search-word-in-dictionary, wnnrpc-get-word-info,
+       wnnrpc-set-comment-on-word, wnnrpc-get-dictionary-info,
+       wnnrpc-set-file-comment, wnnrpc-hinshi-name,
+       wnnrpc-set-file-password, wnnrpc-set-hinshi-table): New functions.
+
+1997-05-31  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnnrpc.el (wnnrpc-format-u32c, wnnrpc-unpack-u32c): New
+       substitutions.  Support 32-bit number represented in cons cell of
+       a pair of 16-bit integer.
+       (wnnrpc-format, wnnrpc-unpack): Handle u32c (U).
+
+       (wnnrpc-format-bytes, wnnrpc-unpack-bytes): New substitutions.
+       Support byte stream end with 255(-1).
+       (wnnrpc-format, wnnrpc-unpack):  Handle bytes (B).
+
+       (wnnrpc-local-file-loaded): New function.
+       (wnnrpc-call-with-proc-1): New macro.  Assume the buffer is the one
+       of process.
+
+1997-05-29  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnnrpc.el (wnnrpc-get-conversion-parameters, wnnrpc-file-loaded,
+       wnnrpc-write-file, wnnrpc-get-fuzokugo-file, wnnrpc-get-file-list,
+       wnnrpc-get-file-list-with-env, wnnrpc-stat-file,
+       wnnrpc-get-file-info): New functions.
+       wnnrpc-receive-file-list): New subst.
+
+1997-05-29  Kenichi Handa  <handa@etl.go.jp>
+
+       * wnnrpc.el (ccl-decode-fixed-euc-jp): Tune it up.
+
+1997-05-29  Hisashi Miyashita  <himi@bird.scphys.kyoto-u.ac.jp>
+
+       * wnnrpc.el (fixed-euc-jp, ccl-decode-fixed-euc-jp,
+       ccl-encode-fixed-euc): New private coding system.  Encode/decode
+       CCL for it.
+
+1997-05-27  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnnrpc.el (wnnrpc-tanbunsetsu-conversion): Change the argument.
+       (wnnrpc-get-bunsetsu-candidates): Likewise.
+       (wnnrpc-renbunsetsu-conversion): Likewise.
+
+       * wnn.el (wnn-change-bunsetsu-length): Follow the change.
+       (wnn-set-bunsetsu-pos): Likewise.
+       (wnn-change-bunsetsu-length, wnn-start-conversion): Likewise.
+
+1997-05-25  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnnrpc.el (wnnrpc-add-word, wnnrpc-get-dictionary-list,
+       wnnrpc-receive-dictionary-list, wnnrpc-get-writable-dictionary-list,
+       wnnrpc-get-hinshi-list, wnnrpc-hinshi-number): New functions.
+       (wnnrpc-unpack-u16-string): Bug fix for the case of ASCII string.
+
+       * wnn.el (wnn-dictionary-specification): Add dictionaries of
+       gerodic and ones of WNN consortium.
+
+       Implement a false path.
+       * wnnrpc.el (wnnrpc-renbunsetsu-conversion): Generate an error on
+       failure.
+       (wnnrpc-get-bunsetsu-candidates): Ditto.
+       (wnnrpc-tanbunsetsu-conversion): Ditto.
+
+       Implement a false path.  Error recovery.
+       * wnn.el (wnn-create-directory, wnn-open-dictionary,
+       wnn-open-frequency, wnn-query-del/create-frequency): New function.
+       (wnn-set-dictionary-sub): New function.
+
+1997-05-24  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnnrpc.el (wnnrpc-version, wnnrpc-access, wnnrpc-mkdir,
+       wnnrpc-create-dictionary, wnnrpc-create-frequency, 
+       wnnrpc-discard-file, wnnrpc-remove-file): New functions.
+       (wnnrpc-test-result-and-get-error): New subst.
+
+       Implement a false path from wnnrpc-set-fuzokugo-file.
+       * wnnrpc.el (wnnrpc-set-fuzokugo-file): Return negate-encoded
+       error code on failure.
+       * wnn.el (wnn-create-environment): Generate an error message.
+
+       Implement a false path from wnnrpc-open-file.
+       * wnnrpc.el (wnnrpc-open-file): Change the interface.  Return
+       negate-encoded error code on failure.
+       * wnn.el (wnn-open-file): New function.
+       (wnn-create-environment): Handle return value, and generate
+       an error message for wnnrpc-set-fuzokugo-file on failure.
+       (wnn-set-dictionary): Handle return value.
+
+1997-05-17  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnnrpc.el (wnnrpc-error-message): Error strings taken from
+       Wnn-4.2 distribution.
+       (wnnrpc-errono): Removed.
+
+       Implement a false path from wnnrpc-open.
+       * wnnrpc.el (wnnrpc-open): Change the interface.  Return NIL on
+       success, error code on failure.
+       * wnn.el (wnn-open): Delete process and buffer.
+       Generate an error on failure.
+       (wnn-get-environment): Follow the change (none).
+       (wnn-start-conversion): Follow the change (none).
+       * convert.el (egg-convert-region): Follow the change.  Call
+       delete-region after egg-start-conversion.
+
+       Implement a false path from wnnrpc-connect.
+       * wnnrpc.el (wnnrpc-connect): Change the interface.  Return
+       negate-encoded error code on failure.
+       * wnn.el (wnn-create-environment): Generate an error on failure.
+       (wnn-get-environment): Follow the change.  On failure, don't
+       register the environment to wnn-environments.
+
+1997-05-16  NIIBE Yutaka  <gniibe@akebono.etl.go.jp>
+
+       Dynamically allocate environment arbitrarily.
+       * wnn.el (wnn-create-environment): Change the structure of ENV.
+       (wnn-e-get-in-use, wnn-e-set-in-use): New subst.
+       (wnn-end-conversion): Call wnn-e-set-in-use.
+       (wnn-get-environment, wnn-find-env-not-in-use): New function.
+       (wnn-start-conversion): Call wnn-get-environment.
+
+       * wnn.el (wnn-fini): Implemented.
+
+1997-05-15  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * convert.el (egg-start-conversion): Change the interface.
+       (egg-convert-region): Follow the change.
+       (egg-open-if-not): Removed.
+       * wnn.el (wnn-start-conversion): Follow the change.
+
+       * wnn.el (wnn-environment-list): Removed.
+       (wnn-environment-serial): Removed.
+       (wnn-connect-and-init): Removed.
+       (wnn-environments): New variable which holds all environments.
+
+1997-05-15  NIIBE Yutaka  <gniibe@akebono.etl.go.jp>
+
+       * wnn.el (wnn-change-bunsetsu-length): Bug fix.  Last argument to
+       wnnrpc-b-set-freq-down is list of bunsetsu.
+
+       * mlh.el (mlh-do-spacing): Emacs 20 related changes.  
+       Use category-set-mnemonics, and char-category-set.
+       According to suggestion by Kenichi Handa <handa@etl.go.jp>.
+
+1997-05-15  MORIOKA Tomohiko <morioka@jaist.ac.jp>
+
+       * wnn.el (wnn-usr-dic-dir): New variable.
+       (wnn-filename): Use wnn-usr-dic-dir.
+
+       * its.el (its-defrule): New argument `enable-overwrite'.
+
+1997-05-14  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * convert.el (egg-exit-conversion-unread-char): Use newer variable
+       unread-command-events, as unread-command-char is obsolete.
+       (egg-shrink-bunsetsu, egg-source-maxlen-from-here,
+       egg-enlarge-bunsetsu, egg-next-conversion, egg-exit-conversion,
+       egg-exit-conversion, egg-insert-converted-result): New property
+       EGG-CONVERSION-ENGINE, which specifis backend.
+
+       (egg-start-conversion, egg-get-number-of-bunsetsu,
+       egg-get-bunsetsu-converted, egg-set-bunsetsu-pos,
+       egg-get-bunsetsu-pos, egg-get-number-of-candidates,
+       egg-get-candidate, egg-decide-candidate,
+       egg-change-bunsetsu-length, egg-get-bunsetsu-source,
+       egg-end-conversion): Change the interface, new argument c.
+       * wnn.el (wnn-start-conversion, wnn-get-number-of-bunsetsu,
+       wnn-get-bunsetsu-converted, wnn-set-bunsetsu-pos, 
+       wnn-get-bunsetsu-pos, wnn-get-number-of-candidates, 
+       wnn-get-candidate, wnn-decide-candidate, 
+       wnn-change-bunsetsu-length, wnn-get-bunsetsu-source, 
+       wnn-end-conversion): Likewise.
+
+       * convert.el (egg-open-if-not): Change the interface.  Return
+       conversion backend.
+
+       * wnnrpc.el (wnnrpc-following-char-or-wait, wnnrpc-unpack-u32,
+       wnnrpc-unpack-u16, wnnrpc-unpack-u8, wnnrpc-unpack-u16-string,
+       wnnrpc-unpack-u8-string): Change the interface to avoid
+       compilation warnings.
+       (wnnrpc-unpack): Use new interface.
+
+       * wnn.el (wnn-open): Change the name of WNN buffer as debug has
+       been done.
+
+1997-05-11  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnnrpc.el (wnnrpc-following-char-or-wait): Rename from
+       wnn-following-char-or-wait.
+       (wnnrpc-following-char-or-wait): Declare with DEFUN instead of
+       DEFSUBST.
+
+1997-05-10  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * Throughout: Use JUNET coding system for file format.
+
+       * mlh.el: Move some comments to HISTORY.
+       (mlh-version): Removed.
+       Remove all autoload entries.
+       (henkan-region-function): Removed.
+       (member): Don't need any more.
+
+       * mlh-nihongo.el: Renamed from nihongo.el.
+
+       * mlh.el (mlh-space-bar-backward-henkan): call egg-convert-region
+       directly.
+       (mlh-space-bar-backward-henkan): Fix for Emacs 20.
+       Don't call egg:do-auto-fill.
+       (mlh-backward-henkan): Use set-marker-insertion-type.
+       (mlh-do-spacing): Char-category.
+
+       * mlh.el, nihongo.el: Taken from mlh-1.002 distribution.
+
+1997-05-07  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * convert.el (egg-update-frequency): Removed.
+       (egg-conversion-backend): Remove entry for update-frequency.
+
+       * wnn.el (wnn-dictionary-specification): Change parameters
+       according to suggestion by Tomoko Yoshida in mule-jp@etl.go.jp.
+       Original had been taken from wnn-4.2.
+
+1997-05-06  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * convert.el (egg-next-conversion): Bug fix.  It's max+ instead of n.
+
+1997-05-05  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnnfns.c (Fwnn_get_bunsetsu_converted): Rename from
+       get-converted-bunsetsu.
+       (Fwnn_get_bunsetsu_source): Ditto.
+       * convert.el (egg-get-bunsetsu-converted): Ditto.
+       (egg-get-bunsetsu-source): Ditto.
+
+       * wnn.el (wnn-create-environment): New file which mimics API of
+       wnnfns.c.
+
+1997-04-29  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnnrpc.el: New file which implements Remote Procedure Calls of WNN.
+
+1997-04-16  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its/kanainput.el (normal-pair): Use its-defrule*.
+
+       * its.el (its-defrule*): Rewritten.
+
+       * its/hira.el ("n"): Alternative implementation using 'otherwise'.
+
+       * its.el (its-processing-map): Removed.
+       (its-register-map): Rename from its-set-map.
+       (its-register-map): Remove first argumet NAME.
+       (its-defrule): Remove last optional argument END.
+       (its-define-otherwise-terminate-here): New function.
+       (its-goto-state): New function.
+       (its-defrule, its-defoutput): Use its-goto-state.
+
+1997-04-12  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its.el: Enhance meaning of ITS state machine.  Now, <key>
+       includes representation of "ANY of key stroke" (-2).
+       (its-defrule): New feature end=='otherwise.
+       (its-defrule*): New function.
+       (its-state-machine): Implement otherwise-terminate-before-this-key.
+
+       * its/kanainput.el (its-k-zenkaku-escape, its-k-hankaku-escape,
+       its-k-symbols-escape): Add prefix its-.  Let them defconst.
+       "W": Move the definition beginning to avoid error.
+
+1997-03-26  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * convert.el (egg-next-conversion): -1 goes to end of bunsetsu.
+
+1997-03-25  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * egg.el (egg-mode-on, egg-input-mode, egg-in-fence-mode): Deleted.
+       (egg-fence-face-on, egg-fence-face-off): Deleted.
+       (egg-region-start, egg-region-end): Deleted.
+
+1997-03-24  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its/hira.el ("n"): Add "z" and "?" for prefetch char of "n".
+
+       Implement conversion mode.
+       * convert.el: New file.
+
+1997-03-23  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its.el (its-mode-map): As "\C-g" is used in global-map, use
+       "\C-]" instead (for its-cancel-input).
+
+1997-03-22  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       Introduce new scheme to specify server.
+       * wnnfns.c (Qjserver, Qcserver, Qtserver, Qkserver): Removed.
+       (Vwnn_server_type): Integer variable.
+       (wnn_get_server_type): Renamed from wnn_check_server_type.
+       (charset_wnn_server_type): Renamed from lc_wnn_server_type.
+
+       Introduce new scheme to specify uniqueness.
+       * wnnfns.c (Qwnn_no_uniq, Qwnn_uniq, Qwnn_uniq_kanji): Removed.
+       (Vwnn_uniqueness_specifier): Integer variable.  Renamed from
+       wnn_uniq_level.
+
+1997-03-21  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       Cosmetic changes.
+       * wnnfnc.c (Throughout): Change Lisp function name to follow the
+       format of wnn-VERB-OBJECT.
+       Use XFASTINT instead of XINT, if appropriate.
+       
+       * wnnfns.c (Fwnn_fuzokugo_set): Merged with wnn-set-fuzokugo of
+       wnn-egg.el.
+
+       * wnn-egg.el (wnn-set-fuzokugo): Deleted.
+
+       * wnnfns.c (Fwnn_dict_add): Merged with wnn-add-dict of wnn-egg.el.
+       * wnn-egg.el (wnn-add-dict): Deleted.
+
+       * wnn-egg-msg.el (wnn-msg-get): Renamed from egg-msg-get.
+       (wnn-message-alist): Renamed from egg-message-alist.
+       Use defconst.
+
+       * wnnfns.c (wnn_check_server_type): Renemed from
+       check_wnn_server_type.
+
+       * wnn-egg-msg.el (egg-error): Deleted.  Not useful enough.
+       * wnn-egg.el (Throughout): Replace egg-error by error.
+
+       * egg.el (egg-sai-henkan-start, egg-sai-henkan-end,
+       egg-old-bunsetu-suu): Moved from wnn-egg.el.
+
+       * wnn-egg.el (Throughout): Change variable name and function name.
+       Added wnn- prefix, egg- prefix.
+       * wnn-egg.el: Delete historical defaliases.  Only support 
+       wnn-set-[cjk]server-hostname.
+
+       * wnn6.el: New file.  Discriminate Wnn6 related functions.
+       * eggrc-wnn6: New file.  Discriminate Wnn6 related setting.
+
+       * egg-fence.el: Removed.
+
+1997-03-20  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       Distingush continuation of egg-mode and turn off of egg-mode.
+       * its.el (its-mode-map): Bind "\C-\\" to its-exit-mode-no-egg.
+       (its-exit-mode-internal): New argument egg-mode-flag.
+       (its-exit-mode-no-egg): New Function.
+
+       Rethink about keymap.  Once, the intention of egg-mode-map has
+       been to override ALL of the keymap.  That's so selfish, and not
+       friendly to other parts of Emacs.  This implementation intend to
+       be more friendly with other keymaps.
+       * its.el (its-mode-map): Remove definition of "\C-c" for
+       its-cancel-input, as C-c has special meaning in Emacs.  We should
+       not re-define it.  
+       Remove definition of "\C-q" for its-select-previous-map.  
+       Remove definition of "\C-_" for egg-jis-code-input.  
+       Remove definition of "\C-w", "\C-@", [?\C-\ ] for
+       egg-henkan-fence-region.
+
+       Implement START/CURSOR/END scheme.
+       * its.el (its-input-to-vsyl): New function.
+       (its-beginning-of-input-buffer): New function.
+       (its-end-of-input-buffer): New function.
+       (its-backward-SYL): New function.
+       (its-forward-SYL): New function.
+       (its-delete-SYL): New function.
+       (its-delete-backward-SYL): New function.
+       (its-delete-backward-SYL-internal): New function.
+       (its-delete-backward-within-SYL): New function.
+       (its-delete-by-keystroke): New Variable.
+       (its-exit-mode): New function.
+       (its-exit-mode-internal): New function.
+
+       * its.el (its-standard-map-list, its-find, its-next-map,
+       its-previous-map): Deleted.
+       (its-get-indicator): Delete duplicated definition.  Leave one which
+       takes <map> argument.
+       (its-input): Rename from its-input-subsubsub.
+
+       * egg.el (egg-mode-map): Don't include SPACE.
+
+       Introduce CURSOR.
+       * its.el (its-state-machine): Add new argument EMIT.  Return CURSOR.
+       (its-state-machine-keyseq): Likewise.
+       (its-input-subsubsub): Return CURSOR.
+       (its-input-subsub): Deleted.
+       (its-DSYL-p): Deleted.
+       (its-buffer-insert-SYL-list): Deleted.
+       (its-buffer-ins/del-SYL): New function.
+       (its-input-end): Change the argument to P of point, and return VOID.
+
+       Change structure of <map>.  <start-state> is normal <state>.
+       (its-new-map): Follow the change of structure.
+       (its-get-indicator, its-set-indicator, its-reset-start-state): 
+       Likewise.
+       (its-reset-start-state): Renamed from its-reset-start.
+
+       Don't use <input-buffer>, but introduce new scheme of SYL property.
+       (its-change-t-to-nil, its-nil-index, its-bytes-between,
+       its-delete-between, its-move-nil--->, its-move-nil-<--,
+       its-move-nil-<--sub, its-move-nil-to-last, its-move-nil-to-first):
+       Deleted.
+
+1997-03-19  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its.el: Change the structure of DSYL.  Same as <state>.
+       (its-input-subsub): Follow the change of structure.
+       (its-make-DSYL): Deleted.
+       (its-get-keyseq-cooked): New function.
+
+       Swap the meaning of T/NIL of <SYL>.
+
+       Delete the structure of <input-buffer>.
+       (its-new-input-buffer): Deleted.
+       (its-input-subsub): Remove the argument SYLP.
+       (its-input, its-input-sub, its-init-text-properties): Deleted.
+
+       Introduce START, END and CURSOR.
+
+1997-03-19  NIIBE Yutaka  <gniibe@akebono.etl.go.jp>
+
+       Global-map should be used, for key sequence not defined by
+       its-mode-map and/or egg-mode-map.   Don't mask other maps.
+       * its.el (its-mode-esc-map): Deleted.
+       (its-mode-map): Include define-key of the esc-map here.
+       * egg.el (egg-mode-esc-map): Deleted.
+       (egg-mode-map): Include define-key of the esc-map here.
+       
+1997-03-18  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its.el (its-input): Rename from its-input-input-buffer.
+       (its-state-machine): Handle END of input (key == -1).
+
+       ITS minor mode deleted.  It's implemented by local-map of text
+       properties.
+       (its-mode): Remove the variable.
+       (its-mode): Remove the function.
+
+       * its.el (<input-buffer>): Change the order of <SYL> list.  
+       (car sylp) is last entry of the list.
+       (its-input-buffer): Deleted.  It's now a member of text
+       properties.
+       (<map>): Change the structure.  Start state should have "" for keyseq.
+       (its-get-start-state): Follow chage of the <map> structure.
+       (its-reset-start, its-set-indicator, its-get-indicator): Likewise.
+       (its-new-state, its-new-map): Split from its-new-state/map.
+       (its-make-map): Deleted.
+
+1997-03-17  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its.el (its-buffer-insert-SYL-list): Use insert-and-inherit to
+       inherit properties.
+       (its-fence-overlay): Removed. Don't use overlay, as it has no
+       information in undo-list.
+
+1997-03-16  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its/hira.el ("n"): Use new feature END.
+       ("ppy", "bby", "ddy", "jjy", "zzy", "ggy", "lly", "rry", "hhy",
+       "cch", "tts", "tty", "ssh", "ssy", "kky"): its-defoutput.
+
+       * its.el (its-defrule): Add argument END.
+       (its-buffer-delete-SYL): Bug fix. Use length instead of string-width.
+
+1997-03-15  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its.el (its-input-input-buffer): Implement the case of DSYL.
+
+1997-03-14  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its.el (its-buffer-delete-SYL): Handle the case of NIL.
+
+       * its/hira.el: Implement "kka" and others.  Implemlement "N".
+       (digit-characters, symbol-characters, downcase-alphabets,
+       upcase-alphabets): Delete useless defvar-s.  
+
+1997-03-14  NIIBE Yutaka  <gniibe@akebono.etl.go.jp>
+
+       * its/hira.el ("roma-kana"): Follow change of implementation of
+       state machine.
+
+       Correct the abuse of the word "MODE".  It seems that it's direct
+       influence of "mode" in Emacs, but it's not mode at all.
+       * its.el (its-map-alist): Renamed from its-mode-alist.
+       (its-get-map): Renamed from its-get-mode-map.
+       (its-set-map): Renamed from its-set-mode-map.
+       (its-define-state-machine): Renamed from its-define-mode.
+       (its-select-map-menu): Renamed from its-select-mode-menu.
+       (its-select-map-from-menu): Renamed from its-select-mode-from-menu.
+       (its-standard-map-list): Renamed from its-standard-modes.
+       (its-next-map): Renamed from its-next-mode.
+       (its-previous-map): Renamed from its-previous-mode.
+       (its-select-map): Renamed from its-select-mode.
+       (its-get-indicator): Renamed from its-get-mode-indicator.
+
+       (its-select-map-from-menu): As it's not mode, don't need offer hooks.
+       (its-next-map): Likewise.
+       (its-previous-map): Likewise.
+       (its-select-map): Likewise.
+
+       Change the implementation of its-mode-alist.  Name is in <map> now.
+       * its.el (its-get-mode-map): Just do assoc.
+       (its-set-mode-map): Simplified.
+
+       * its.el (its-get-indicator): Renamed from its-map-indicator.
+       (its-set-indicator): Renamed from its-map-set-indicator.
+       (its-get-start-state): Renamed from its-map-start.
+       (its-new-state): Change the argunents.
+       (its-map-set-start): Removed.
+       (its-reset-start): New function.
+
+       Remove old implemantation of translator.
+       * its.el (its-resize, its-maps, its-actions, its-inputs,
+       its-level, its-maxlevel, its-char-from-buff, its-interactive):
+       Removed.
+       (its-make-action, its-reset-maps, its-current-map,
+       its-previous-map, its-level, its-enter-newlevel, its-reset-input,
+       its-flush-input-before-point, its-peek-char, its-read-char):
+       Removed.
+       (its-push-char, its-ordinal-charp, its-delete-charp): Removed.
+       (its-translate-region): Removed.
+       (its-buff-s, its-buff-e): Removed.
+       (its-state-terminalp): Removed.
+
+       Remove selection of candidates in map, it's questionable to
+       implement this feature with SYL.  Might rethink in future.
+       (its-make-menu-from-map-result, its-make-alist-from-map-result):
+       Removed.
+       (its-make-menu-from-map, its-make-menu-from-map*): Removed.
+       (its-make-alist-from-map, its-make-alist-from-map*): Removed.
+       (its-completing-read): Removed.
+       (its-minibuffer-local-must-match-map,
+       its-minibuffer-local-completion-map): Removed.
+       (its-minibuffer-completion-help, car-string-lessp,
+       its-temp-echo-area-contents): Removed.
+
+       Implement SYL-based state machine.
+       * its.el (its-input-buffer, its-barf-on-invalid-keyseq): New variables.
+       (its-new-input-buffer): New function.
+       (its-self-insert-char): New command.
+       (its-initial-ISYL, its-make-DSYL, its-make-VSYL,
+       its-input-input-buffer, its-input-input-buffer-sub,
+       its-state-machine, its-state-machine-keyseq, 
+       its-buffer-delete-SYL, its-buffer-insert-SYL-list,
+       its-get-next-state, its-get-ksa/b, its-get-keyseq, its-ksa-p,
+       its-get-output): New function.
+       (its-get-KAS): Removed.
+       (its-get-state, its-get-action, its-set-action): Removed.
+       (its-make-KAS, its-get-KAS): Removed.
+
+       * its.el (its-defrule-sub): Merged into its-defrule.
+
+1997-03-13  NIIBE Yutaka  <gniibe@akebono.etl.go.jp>
+
+       * its.el: (its-define-mode): Change the arguments.
+       * its/zhuyin.el ("zhuyin"): Follow the changes of its-define-mode.
+       * its/zenkaku.el ("zenkaku-downcase"): Likewise.
+       * its/pinyin.el ("PinYin"): Likewise.
+       * its/kata.el ("roma-kata"): Likewise.
+       * its/kanainput.el ("kanainput"): Likewise.
+       * its/hira.el ("roma-kana"): Likewise.
+       * its/hankaku.el ("downcase"): Likewise.
+       * its/hangul.el ("hangul"): Likewise.
+       * its/han-kata.el ("roma-han-kata"): Likewise.
+
+       * its.el (its-action-output, its-action-next, its-get-next-map,
+       its-set-next-map): Removed.
+       (its-make-next-state): New function.
+       (its-make-state): Removed.
+
+       * its.el (its-defrule-sub): Renamed from `its-defrule**'.
+
+       * wnnfns.h: New file.  Macros for WNN6 are defined here.
+       * wnn6fns.c: New file.  Moved from wnnfns.c for WNN6 specific
+       functions.
+
+1997-03-12  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnnfns.c: cosmetic changes (indentation, commenting-out-style,
+       and compare to Qnil, etc).
+       Get rid of "register" qualifier.
+
+1997-03-05  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its.el (its-define-mode): Change internal structure.  Completely
+       rewritten.
+       (its-make-map): Function to make map.
+       (its-make-state): New function.  Make new state.
+       (its-make-KAS): New function.  Make Key-Action-State triad.
+       (its-state-terminalp): New function.  True when the state is
+       terminal.
+       (its-map-indicator, its-map-set-indicator,): Changed.
+       (its-map-terminalp, its-map-incrementalp,
+       its-map-set-incrementalp, its-map-alist, its-map-set-alist,
+       its-map-action, its-map-set-action): Removed.
+
+       (its-defrule-verbose): Deleted.  Seems debug purpose variable.
+
+       (its-make-map): Removed <state>.  It was useless space eater.
+       (its-map-indicator, its-map-set-indicator, its-map-alist,
+       its-map-set-alist, its-map-action, its-map-set-action): Follow the
+       change.
+       (its-define-mode): Likewise.
+       (its-defrule**): Change the argument.  Delete STATE.
+       (its-defrule): Likewise.
+       (its-map-state, its-map-set-state): Removed.
+
+       <topmap>: Changed the structure.  Introduce <incrementalp>, which
+       is t on hangul-map, zhuyin-map, and kanainput-map.
+       (its-define-mode): Change the arguments.  INDICATOR and RESET is 
+       always required.  Add new argument INCREMENTALP.
+       * its/kanainput.el ("kanainput"): Use new API of its-define-mode.
+       * its/hangul.el ("hangul"): Likewise.
+       * its/zhuyin.el ("zhuyin"): Likewise.
+       * its.el (its-make-terminal-state-sofar): Removed.
+       (its-default-make-terminal-state): Removed.
+       (its-make-terminal-state): Removed
+       (its-make-non-terminal-state): Removed.  Not used.
+       (its-map-incrementalp, its-map-set-incrementalp): New functions.
+       
+1997-03-04  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * its.el (its-defrule-conditional, its-defrule-conditional*):
+       Removed.  Evaluating cond clause at runtime is stupid.  Rules
+       should be determined at compile time, not at run time.
+       (its-get-action): Simplified.  It's always standard.
+       (its-make-terminal-state-sofar): Likewise.
+       (its-make-action): Renamed from its-make-standard-action.
+       (its-standard-actionp): Removed.  No use.
+       (its-translate-region): Simplified.
+
+       (its-map-topmap-p): Removed.  No use.
+
+       (its-simple-actionp, its-collect-simple-action): Removed. No use.
+
+       (its-insert-output-string, its-display-status-string): Removed.
+       It seemd these variables is to debug ITS itself.
+       (its-translate-region): Simplified.
+       
+       * its/hira.el (".", ",", "n", "nn"): Rules should be determined at
+       compile time.
+       * its/han-kata.el: Likewise.
+       * its/kata.el: Likewise.
+
+       * its.el (its-make-standard-action): Simplified.
+       (its-make-standard-action): Remove alternative output.
+       (its-standard-actionp): Simplified.
+       (its-action-next): Simplified.
+       (its-select-alternative-output-menu): Removed.  Not used at all.
+       (its-select-alternative-output): Ditto.
+
+       * its/han-kata.el, its/zenkaku.el, its/kata.el, its/kanainput.el,
+       its/hira.el, its/hankaku.el: Add (require cl).
+
+       * its.el (its-enable-double-n-syntax, its-use-kuten-for-period,
+       its-use-touten-for-comma, its-zenkaku-escape, its-hankaku-escape):
+       Declare here.  Add prefix `its-'.  ):
+
+       (its-defrule, its-defrule*): Remove MAP argument.
+       Merged into its-defrule.
+
+1997-03-04  NIIBE Yutaka  <gniibe@akebono.etl.go.jp>
+
+       * its.el (its-completing-input-menu): Removed.  Not used.
+       (its-completing-input): Ditto.
+       (its-translate-region): Remove (null action) clause.  It's identical
+       to 't' case.
+
+       (its-map-supers): Deleted.
+       (its-map-set-supers): Ditto.
+       (its-get-next-map-locally): Deleted.
+
+       (its-define-mode): Remove supers.
+       (its-make-map): Likewise.
+
+       (its-simulate-input): sref -> aref. add char-bytes -> +1.
+       (its-defrule**): Likewise.
+
+       (its-flush-input-before-point): Delete useless save-excursion.
+       (its-push-char): Likewise.
+       (its-translate-region): Likewise.
+
+       * its/zhuyin.el (its-make-terminal-state):
+       * its/kanainput.el (its-make-terminal-state):
+       * its/hangul.el (its-make-terminal-state):
+       Use its-make-terminal-state-sofar.
+
+       * its/kanainput.el (its-make-terminal-state-kanainput): Removed.
+
+       * its.el (its-make-terminal-state-sofar): Renamed.
+       (was: its-make-terminal-state-hangul)
+
+       * its/han-kata.el (its-select-hankaku-katakana): Renamed.
+       (was: its:select-hankaku-katakana).
+
+       * its.el (its-map-topmap-p, its-map-supers, its-map-set-supers,
+       its-map-terminalp, its-map-state, its-map-set-state,
+       its-map-indicator, its-map-set-indicator, its-map-action,
+       its-map-set-action, its-map-alist, its-map-set-alist,
+       its-get-action, its-action-output, its-action-next,
+       its-get-next-map, its-get-next-map-locally, its-set-next-map,
+       its-collect-simple-action, its-read-current-its-string,
+       its-make-map): Add prefix 'its-'.
+
+       * its.el (its-defrule-select-mode-temporally): Deleted.
+       (its-select-mode-temporally): Deleted.
+       (its-select-previous-mode): Deleted.
+
+       * its/hira.el ("q", "Q"): Removed.
+
+       * its.el (its-defrule**): Don't call coerce-internal-string.
+       (map-state-string): Removed.
+       (its-default-make-standard-non-terminal-state): Don't call
+       map-state-string.
+
+       * egg.el (characterp, coerce-internal-string, coerce-string): Removed.
+
+       * its.el (its-insert-char): Deleted.
+       (its-internal-mode-alist): Removed.
+       (its-set-mode-map, its-define-mode): Remove internalp.
+       (its-set-mode-indicator): Removed.
+
+       * egg-fence.el (egg-fence-self-insert-command): Add prefix 'egg-'.
+
+       * its.el (fence-self-insert-command): Move to egg-fence.el.
+
+       * egg-fence.el (egg-exit-fence-mode): Renamed (egg-fence-exit-mode).
+       (egg-enter-fence-mode-and-self-insert): Deleted.
+
+       * egg.el (egg-quit-egg-mode): Deleted.
+
+       * egg-misc.el (egg-fence-toggle-egg-mode): Add prefix 'egg-'.
+       (egg-fence-toggle-egg-mode): beep -> ding.
+       (global-map): bind C-\ to egg-enter-fence-mode.
+
+1997-03-02  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * egg-henkan.el: New file.
+
+       Use new API (egg-get-bunsetu-kanji, egg-get-bunsetu-yomi,
+       egg-is-dai-bunsetu, bunsetu-suu, egg-hindo-update,
+       egg-get-bunsetu-end).
+
+       * wnn-egg.el: Move egg-henkan-* to egg-henkan.el.
+
+       * wnn-egg.el (egg-startup-file-search-path): Remove current
+       directory.
+       (egg-open-wnn): Renamed from EGG-open-wnn.
+       (bunsetu-suu): New function.
+       (egg-get-bunsetu-kanji, egg-get-bunsetu-yomi): New function.
+       (egg-is-dai-bunsetu): New function.
+       (egg-hindo-update): New function.
+       (egg-get-bunsetu-end): New function.
+       
+       (egg-henkan-region, egg-gyaku-henkan-region,
+       egg-henkan-region-internal, egg-henkan-paragraph,
+       egg-gyaku-henkan-paragraph, egg-henkan-sentence,
+       egg-gyaku-henkan-sentence, egg-henkan-word, egg-gyaku-henkan-word,
+       egg-henkan-insert-kouho, egg-henkan-kakutei,
+       egg-henkan-kakutei-first-char, egg-henkan-kakutei-before-point,
+       egg-sai-henkan, egg-henkan-goto-bunsetu,
+       egg-henkan-forward-bunsetu, egg-henkan-backward-bunsetu,
+       egg-henkan-first-bunsetu, egg-henkan-last-bunsetu,
+       egg-henkan-hiragana, egg-henkan-katakana, egg-henkan-next-kouho,
+       egg-henkan-next-kouho-dai, egg-henkan-next-kouho-sho,
+       egg-henkan-previous-kouho, egg-henkan-previous-kouho-dai,
+       egg-henkan-previous-kouho-sho, egg-henkan-goto-kouho,
+       egg-henkan-bunsetu-chijime-dai, egg-henkan-bunsetu-chijime-sho,
+       egg-henkan-bunsetu-nobasi-dai, egg-henkan-saishou-bunsetu,
+       egg-henkan-saichou-bunsetu, egg-bunsetu-length-henko,
+       egg-henkan-quit, egg-henkan-select-kouho,
+       egg-henkan-select-kouho-dai, egg-henkan-select-kouho-sho,
+       egg-henkan-word-off, egg-henkan-kakutei-and-self-insert,
+       egg-henkan-mode-map, egg-henkan-mode-esc-prefix,
+       egg-henkan-help-command, egg-henkan-inspect-bunsetu):
+       Add prefix `egg-'.
+
+       (egg-henkan-mode-in-use): Deleted.
+       (set-egg-henkan-mode-format): Deleted.  Don't need.
+
+       (disconnect-wnn): Let it be normal function, instead of command.
+       (close-wnn): Ditto.
+
+       (set-jserver-host-name, set-kserver-host-name,
+       set-cserver-host-name): Use defalias.
+
+       (close-wnn): Take an argument of wnn-server-type.
+       (wnn-egg-kill-emacs-function, set-wnn-host-name,
+       set-cwnn-host-name, set-kwnn-host-name): Likewise.
+
+       * egg.el (egg-global-map-backup): Deleted.
+       (egg-local-map-backup): Deleted.
+       (egg-insert-after-hook): it's global variable, nod buffer-local.
+
+       * egg-fence.el (egg-henkan-fence-region, egg-enter-fence-mode,
+       egg-fence-katakana, egg-fence-hiragana, egg-fence-hankaku,
+       egg-fence-zenkaku, egg-fence-backward-char,
+       egg-fence-forward-char, egg-fence-beginning-of-line,
+       egg-fence-end-of-line, egg-fence-transpose-chars,
+       egg-fence-delete-char, egg-fence-backward-delete-char,
+       egg-fence-kill-line, egg-fence-exit-mode, egg-fence-cancel-input,
+       egg-fence-mode-help-command): Add Prefix `egg-'.
+
+       (egg-fence-mode-map): Remove binding to eval-expression (C-z).
+
+       (egg-self-insert-non-undo-count): Removed.
+       (egg-self-insert-command): Removed.
+
+       (egg-fence-backward-char, egg-fence-forward-char,
+       egg-fence-transpose-chars, egg-fence-delete-char,
+       egg-fence-backward-delete-char): beep -> ding.
+       wnn-egg.el (egg-henkan-select-kouho): Likewise.
+
+1997-02-27  NIIBE Yutaka  <gniibe@mri.co.jp>
+
+       * wnn-egg.el (push-end, push-end-internal): Removed.
+
+       * its.el (dolist): Removed.  It's in CL package.
+       (for-each, for-each*): Removed.
+
+       * egg-keymap.el: Removed.  I guess noone use it.
+
+       * egg-jsymbol.el (*-alist): Declare by defconst.
+
+       * egg-misc.el (toggle-egg-mode): Removed.
+
+       * All files: Change the identifier XXX:YYYY --> XXX-YYYY,
+       and *YYY* ---> YYY.
+
+       * egg-fence.el (enter-fence-mode): Use new API for marker
+       insertion `set-marker-insertion-type'.
+       * its.el (its-*buff-e*): Likewise.
+
+       * egg-jsymbol.el: lc-jp --> (charset-id 'japanese-jisx0208)
+       lc-jp2 --> (charset-id 'japanese-jisx0212).
+
+1997-02-26  NIIBE Yutaka  <gniibe@akebono.etl.go.jp>
+
+       * egg-fence.el (egg:fence-mode-map): Renamed from fence-mode-map.
+       (egg:fence-mode-esc-prefix): Renamed from egg:fence-mode-esc-map.
+       (henkan-fence-region-or-single-space): Removed.
+
+       * egg-misc.el (toggle-egg-mode): mc-flag
+               -> enable-multibyte-characters.
+
+       * its.el (read-current-its-string): New function.  Moved from
+       wnn-egg-misc.el.
+       (In meny functions): beep --> ding.
+
+       * egg-misc.el (read-hiragana-string): Removed.
+       (read-kanji-string): Removed.
+       (egg:special-symbol-input): Renamed from special-symbol-input.
+       (egg:special-symbol-input-point): Renamed from
+       special-symbol-input-point.
+       (si:*global-map*): Remeved.
+       Removed 'Changes on Global map'.
+       (its-mode-map): Renamed from mule-keymap.
+
+       * wnn-egg.el (henkan-region-internal): Use new API for undo.
+       (henkan-kakutei): Likewise.
+       (henkan-kakutei-first-char): Likewise.
+       (henkan-kakutei-before-point): Likewise.
+       (sai-henkan): Likewise.
+       * egg.el (egg:quit-egg-mode): Likewise.
+
+       * egg-fence.el (egg:*fence-open*, egg:*fence-close*,
+       egg:*fence-face*): Let them be declared by defvar.
+       (egg:*fence-open-in-cont*, egg:*fence-close-in-cont*,
+       egg:*fence-face-in-cont*): Likewise.
+
+       (set-egg-fence-mode-format): Removed.  Useless.  Don't need to be
+       interactive.
+       (set-egg-fence-mode-format-in-cont): Removed.
+       (egg:*face-alist*): Removed.
+
+       * wnn-egg-misc.el (its:select-mode, its:select-mode-from-menu,
+       its:next-mode, its:previous-mode): 
+       Removed (Merged into its.el).  
+
+       * its.el (its:select-mode, its:select-mode-from-menu,
+       its:next-mode, its:previous-mode): Call hook of
+       `its:select-mode-hook'.
+
+       * diced.el: Removed.  This depends on wnn.  Functions are moved to
+       wnn-egg-dict.el.
+
+       * wnn-egg-dict.el (remove-regexp-in-string): Removed.
+       (toroku-region): Don't call `remove-regexp-in-string'.  Removing
+       invalid sequence (TAB?) automatically is not good idea.  It should
+       notify user.  Currently, just don't remove.
+
+       * busyu.el (busyu-table): defconst instead of defvar.
+       (busyu-kaku-alist): defconst instead of defvar.
+
+       * its.el (egg:member): Removed.  Not used.
+
+       * wnn-egg-msg.el (*egg-message-alist*): Include asking string in
+       register-notify and remove-notify.  Should also change Korean and
+       Chinese.
+
+       * egg.el: Removed "Tamago Notification System".
+       It is useless, as we have *Messages* buffer in GNU Emacs 19.
+
+       * diced.el (diced-execute): Don't use `notify' but `message'.
+       (set-dict-comment): Likewise.
+       * its.el (its-defrule**): Likewise.
+       * wnn-egg-dict.el (egg:toroku-word): Likewise.
+       * wnn-egg-msg.el (egg:error): Likewise.
+       * wnn-egg.el (set-wnn-param): Likewise.
+       (EGG:open-wnn): Likewise.
+       (close-wnn): Likewise.
+       (henkan-word-off): Likewise.
+       (henkan-inspect-bunsetu): Likewise.
+
+       * diced.el (diced-execute): Don't use `notify-yes-or-no-p' but use
+       plain `yes-or-no-p' and format.
+       * wnn-egg-dict.el (egg:toroku-word): Likewise.
+
+       * egg.el (notify-yes-or-no-p-internal): IIDESUKA is not good.
+       it should get the message through egg:get-msg.  Currently, use
+       "OK?".
+       (notify-y-or-n-p-internal): Likewise.
+
+       * wnn-egg.el: Split into wnn-egg-dict.el, wnn-egg-misc.el, and
+       wnn-egg-msg.el.
+       (many functions): remove commented out line of
+               (open-wnn-if-disconnected).
+
+       * egg.el: Split into egg.el, egg-fence.el, egg-misc.el,
+       jis-input.el, and modeline.el.
+
+       * wnn-egg.el (egg-default-startup-file): change to eggrc-wnn from
+       eggrc.
+       (henkan-region-internal): Use new API for marker insertion
+       `set-marker-insertion-type'.
+
+1997-02-13  NIIBE Yutaka  <gniibe@akebono.etl.go.jp>
+
+       * menu.el (menu:select-from-menu): Rewritten.
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..62dd094
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,90 @@
+# Makefile --- Makefile of EGG V4.0
+
+# Copyright (C) 1997 Mule Project,
+# Powered by ElectrotechnicalLaboratory, JAPAN.
+# Project Leader: Satoru Tomura <tomura@etl.go.jp>
+
+DOTEMACS=/home/niibe/.emacs
+LEIMDIR=/usr/local/share/emacs/20.1/leim
+SITEDIR=/usr/local/share/emacs/site-lisp
+
+INSTALL=/usr/bin/install
+######
+
+DEPS = -l ./docomp.el
+BATCHFLAGS = -batch -q -no-site-file
+EMACS = emacs
+
+.SUFFIXES: .el .elc
+
+ETCS = Makefile leim-list-egg.el AUTHORS ChangeLog README TODO docomp.el
+
+SRCS = menudiag.el its.el egg.el \
+       its/hira.el \
+       egg-mlh.el egg-cnv.el egg-com.el \
+       euc-cn.el \
+       egg/sj3.el egg/sj3rpc.el \
+       egg/wnn.el egg/wnnrpc.el
+
+ELCS = ${SRCS:.el=.elc}
+
+DIST = ${ETCS} ${SRCS}
+
+.el.elc:
+       ${EMACS} ${BATCHFLAGS} ${DEPS} -f batch-byte-compile $<
+
+all: ${ELCS}
+
+clean: 
+       rm -f ${ELCS} leim-list.el
+
+dotemacs:
+       @if (grep "^;;; Emacs/Egg Configuration" $(DOTEMACS) 2>&1) >/dev/null; then \
+               echo Emacs/Egg setup already exists in $(DOTEMACS);     \
+       else                                                            \
+               (echo >> $(DOTEMACS)); \
+               (echo ";;; Emacs/Egg Configuration" >> $(DOTEMACS)); \
+               (echo "(require 'egg)" >> $(DOTEMACS)); \
+               echo "Added Emacs/Egg setup to $(DOTEMACS)"; \
+       fi
+
+leim-list.el:
+       @if (grep ";;; Egg" ${LEIMDIR}/leim-list.el 2>&1) >/dev/null; then \
+         echo Egg setup already exists in ${LEIMDIR}/leim-list.el; \
+         cat ${LEIMDIR}/leim-list.el  >leim-list.el; \
+       else                                                            \
+         cat ${LEIMDIR}/leim-list.el leim-list-egg.el >leim-list.el; \
+       fi
+
+install-dirs:
+       for d in its egg; do \
+         if [ ! -d ${SITEDIR}/$$d ]; then mkdir -p ${SITEDIR}/$$d; fi; \
+        done
+
+install: all dotemacs leim-list.el install-dirs
+       for x in ${SRCS} ${ELCS}; do $(INSTALL) -m 644 $$x ${SITEDIR}/`dirname $$x`; done
+       $(INSTALL) -m 644 leim-list.el ${SITEDIR}
+
+egg/sj3rpc.elc: egg-com.elc egg/sj3.elc
+egg/wnnrpc.elc: egg-com.elc egg/wnn.elc
+
+distclean:
+       rm -f ${ELCS} leim-list.el *~
+
+###  Source code maintainance
+DATE=$(shell date "+%y%m%d")
+
+dist: distclean
+       rm -rf ../egg-${DATE}
+       mkdir ../egg-${DATE}
+       tar -c -f - ${DIST} | tar Cxf ../egg-${DATE} -
+       (cd ../egg-${DATE}; \
+        sed "/^### Source code maintainance/,\$$d" <Makefile >Makefile.dist; \
+        mv -f Makefile.dist Makefile)
+       (cd ..; tar cvzf egg-${DATE}.tar.gz egg-${DATE})
+
+working-ss: distclean
+       rm -rf ../egg-snap-${DATE}
+       mkdir ../egg-snap-${DATE}
+       tar -c -f - . | tar Cxf ../egg-snap-${DATE} -
+       (cd ..; tar cvzf egg-snap-${DATE}.tar.gz egg-snap-${DATE})
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..c9bafcd
--- /dev/null
+++ b/README
@@ -0,0 +1,14 @@
+
+             EGG Versio 4.0 --- Code name "Tamagotchy"
+
+               NIIBE Yutaka <gniibe@mri.co.jp>
+               Mitsubishi Research Institute, Inc.
+
+We've started this project with the code of EGG V3.0 in the beginning.
+However, we chose to rewrite whole of them, while referring the design
+and interface of EGG V3.0.
+
+In original version of EGG (to V3.0), it seems for me that there's no
+copyright notice.  But it has been widely distributed on the Internet
+under the licence of GPL:
+    <URL:ftp://etlport.etl.go.jp/pub/mule/mule-2.3.tar.gz>
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..964a332
--- /dev/null
+++ b/TODO
@@ -0,0 +1,74 @@
+(1) Use customize.
+(2) Implement user entries which were defined in EGG V3.
+(3) Packaging
+(4) Modeless Framework
+(5) LEIM
+(7) Portability (Implementation)
+       Event/Char/Integer is different.
+(8) Quail Integration
+
+Something like egg-use-backend, its-use-package
+
+MENU:
+       Incrementally generate <selection-list>.
+       Provide programming interface of the data structure <menu>.
+
+MLH:
+       Rewrite & clean up.
+
+Emacs/Quail Interface:
+       Restrict switching language
+       Synchronize backend/frontend language
+
+ITS:
+       Kill, yank, delete with kill-ring in INPUT-BUFFER.
+       Editing within a VSYL.
+       transpose-chars
+       Use of macro/subst.
+
+       Implement following functions.
+       its-cancel-input
+       its-mode-help-command
+       its-kill-line
+       its-hiragana (input-buffer)
+       its-katakana
+       its-hankaku
+       its-zenkaku
+
+       its-read-current-its-string
+
+       overwrite-mode, fill, vi emulator
+
+       The way of customizing its-mode-map.
+
+       Help-command
+
+       muhenkan
+
+EGG/ITS:
+       Katakana input support.
+       Kanainput support.
+       Chinese/Korean support.
+       map change --> server select.
+       Consider about API
+
+CONVERT:
+       Semantics of open and close
+
+       decide-first-char
+
+       Consistency with other commands (delete, yank...)
+
+       Help command
+
+WNN:
+       Support Wnn6 when it becomes Free Software.
+
+WNNRPC:
+       Chinese/Korean support.
+
+BUG:
+       convert.el
+
+       |xxxxxxx|
+               ^---- when cursor comes on this fence-end.
diff --git a/docomp.el b/docomp.el
new file mode 100644 (file)
index 0000000..49058f2
--- /dev/null
+++ b/docomp.el
@@ -0,0 +1,12 @@
+(setq load-path (append (list (expand-file-name "./") )
+                       load-path))
+
+(setq max-specpdl-size (* 10 max-specpdl-size)
+      max-lisp-eval-depth (* 10 max-lisp-eval-depth))
+
+(load "bytecomp" t t nil)
+(setq byte-compile-warnings '(obsolete redefine callargs); free-vars unresolved
+      byte-optimize t
+      )
+
+(require 'cl)
diff --git a/egg-cnv.el b/egg-cnv.el
new file mode 100644 (file)
index 0000000..249ff9d
--- /dev/null
@@ -0,0 +1,348 @@
+;;; egg-cnv.el --- Conversion Backend in Egg Input Method Architecture
+
+;; Copyright (C) 1997 Mule Project,
+;; Powered by Electrotechnical Laboratory, JAPAN.
+;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
+
+;; Author: NIIBE Yutaka <gniibe@mri.co.jp>
+;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
+;; Keywords: mule, multilingual, input method
+
+;; This file will be part of GNU Emacs (in future).
+
+;; GNU Emacs 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,
+;; 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.
+
+;; 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.
+
+;;; Commentary:
+
+
+;;; Code:
+
+(defsubst egg-bunsetsu-info () 'intangible)
+;;
+
+(defvar egg-conversion-backend nil)
+
+(defun egg-initialize-backend ()
+  (funcall (aref egg-conversion-backend 0)))
+
+(defun egg-start-conversion (yomi-string)
+  (funcall (aref egg-conversion-backend 1) yomi-string))
+(defun egg-get-bunsetsu-converted (bunsetsu-info)
+  (funcall (aref egg-conversion-backend 2) bunsetsu-info))
+(defun egg-get-bunsetsu-source (bunsetsu-info)
+  (funcall (aref egg-conversion-backend 3) bunsetsu-info))
+(defun egg-list-candidates (bunsetsu-info prev-bunsetsu-info)
+  (funcall (aref egg-conversion-backend 4) bunsetsu-info prev-bunsetsu-info))
+(defun egg-get-number-of-candidates (bunsetsu-info)
+  (funcall (aref egg-conversion-backend 5) bunsetsu-info))
+(defun egg-get-current-candidate-number (bunsetsu-info)
+  (funcall (aref egg-conversion-backend 6) bunsetsu-info))
+(defun egg-get-all-candidates (bunsetsu-info)
+  (funcall (aref egg-conversion-backend 7) bunsetsu-info))
+(defun egg-decide-candidate (bunsetsu-info candidate-pos)
+  (funcall (aref egg-conversion-backend 8) bunsetsu-info candidate-pos))
+(defun egg-change-bunsetsu-length (b0 b1 b2 len)
+  (funcall (aref egg-conversion-backend 9) b0 b1 b2 len))
+(defun egg-end-conversion (bunsetsu-info-list)
+  (funcall (aref egg-conversion-backend 10) bunsetsu-info-list))
+
+(defun egg-finalize-backend ()
+  (funcall (aref egg-conversion-backend 11)))
+\f
+(defvar egg-conversion-open "|")
+(defvar egg-conversion-close "|")
+(defvar egg-conversion-separator " ")
+
+;;
+(defun egg-convert-region (start end)
+  (interactive "r")
+  (let ((bunsetsu-info-list
+        (egg-start-conversion (buffer-substring start end)))
+       p)
+    (delete-region start end)
+    (setq p (point))
+    (insert egg-conversion-open)
+    (put-text-property p (point) 'egg-start t)
+    (if egg-conversion-face
+       (put-text-property p (point) 'invisible t))
+    ;;
+    (egg-insert-bunsetsu-list bunsetsu-info-list)
+    ;;
+    (setq p (point))
+    (insert egg-conversion-close)
+    (put-text-property p (point) 'egg-end t)
+    (if egg-conversion-face
+       (put-text-property p (point) 'invisible t))
+    (goto-char (1+ start))))
+
+(defvar egg-conversion-face nil)
+(defvar egg-conversion-map
+  (let ((map (make-sparse-keymap))
+       (i 33))
+    (while (< i 127)
+      (define-key map (vector i) 'egg-exit-conversion-unread-char)
+      (setq i (1+ i)))
+    (define-key map "\C-@" 'egg-decide-first-char)
+    (define-key map [?\C-\ ] 'egg-decide-first-char)
+    (define-key map "\C-a"   'egg-beginning-of-conversion-buffer)
+    (define-key map "\C-b"   'egg-backward-bunsetsu)
+    (define-key map "\C-e"   'egg-end-of-conversion-buffer)
+    (define-key map "\C-f"   'egg-forward-bunsetsu)
+    (define-key map "\C-h"   'egg-help-command)
+    (define-key map "\C-i"   'egg-shrink-bunsetsu)
+    (define-key map "\C-k"   'egg-decide-before-point)
+;;    (define-key map "\C-l"   'egg-exit-conversion)  ; Don't override C-L
+    (define-key map "\C-m"   'egg-exit-conversion)
+    (define-key map "\C-n"   'egg-next-candidate)
+    (define-key map "\C-o"   'egg-enlarge-bunsetsu)
+    (define-key map "\C-p"   'egg-previous-candidate)
+    (define-key map "\M-s"   'egg-select-candidate)
+    (define-key map [return] 'egg-exit-conversion)
+;;    (define-key map "\C-\\"  'egg-exit-mode-no-egg)
+    (define-key map [right]  'egg-forward-bunsetsu)
+    (define-key map [left]   'egg-backward-bunsetsu)
+    (define-key map " "      'egg-next-candidate)
+    (define-key map "/"      'egg-exit-conversion)
+    map)
+  "Keymap for EGG Conversion mode.")
+
+(defun egg-exit-conversion-unread-char ()
+  (interactive)
+  (setq unread-command-events (list last-command-event))
+  (egg-exit-conversion))
+
+(defun egg-insert-bunsetsu (bunsetsu-info last)
+  (let ((bunsetsu (egg-get-bunsetsu-converted bunsetsu-info))
+       (p (point)))
+    (insert bunsetsu)
+    (if (not last)
+       (insert egg-conversion-separator))
+    (add-text-properties p (point)
+                        (list 'face      egg-conversion-face
+                              'local-map egg-conversion-map
+                              (egg-bunsetsu-info) bunsetsu-info
+                              'egg-bunsetsu-last last))))
+
+(defun egg-insert-bunsetsu-list (bunsetsu-info-list &optional contin)
+  (let ((l bunsetsu-info-list)
+       bunsetsu-info bunsetsu p)
+    (while l
+      (setq bunsetsu-info (car l)
+           l (cdr l)
+           p (point))
+      (egg-insert-bunsetsu bunsetsu-info (and (null l) (null contin))))))
+
+(defun egg-backward-bunsetsu (n)
+  (interactive "p")
+  (let (start)
+    (while (and (null start) (> n 0))
+      (backward-char)
+      (if (setq start (get-text-property (point) 'egg-start))
+         (forward-char)
+       (setq n (1- n))))
+    (if (> n 0)
+       (signal 'beginning-of-buffer nil))))
+
+(defun egg-forward-bunsetsu (n)
+  (interactive "p")
+  (let (end)
+    (while (and (null end) (> n 0))
+      (forward-char)
+      (if (setq end (get-text-property (point) 'egg-end))
+         (backward-char)
+       (setq n (1- n))))
+    (if (> n 0)
+       (signal 'end-of-buffer nil))))
+
+(defun egg-get-previous-bunsetsu (p)
+  (if (get-text-property (1- p) 'egg-start)
+      nil
+    (get-text-property (- p 2) (egg-bunsetsu-info))))
+
+(defun egg-shrink-bunsetsu (n)
+  (interactive "p")
+  (let* ((b0 (egg-get-previous-bunsetsu (point)))
+        (b1 (get-text-property (point) (egg-bunsetsu-info)))
+        (last (get-text-property (point) 'egg-bunsetsu-last))
+        (slen (chars-in-string (egg-get-bunsetsu-source b1)))
+        (newlen (- slen n))
+        b2 bunsetsu-info-list beep)
+    (if (< newlen 1)
+       (setq beep t
+             newlen 1))
+    (if (not last)
+       (let ((p2 (save-excursion (forward-char) (point))))
+         (setq b2 (get-text-property p2 (egg-bunsetsu-info))
+               last (get-text-property p2 'egg-bunsetsu-last))))
+    (setq bunsetsu-info-list (egg-change-bunsetsu-length b0 b1 b2 newlen))
+    (delete-region (point)
+                  (progn (forward-char) (if b2 (forward-char)) (point)))
+    (let ((p (point)))
+      (egg-insert-bunsetsu-list bunsetsu-info-list (not last))
+      (goto-char p))
+    (if beep
+       (ding))))
+
+(defun egg-enlarge-bunsetsu (n)
+  (interactive "p")
+  (let* ((b0 (egg-get-previous-bunsetsu (point)))
+        (b1 (get-text-property (point) (egg-bunsetsu-info)))
+        (last (get-text-property (point) 'egg-bunsetsu-last))
+        (slen (chars-in-string (egg-get-bunsetsu-source b1)))
+        (newlen (+ slen n))
+        b2 maxlen bunsetsu-info-list beep)
+    (if (not last)
+       (let ((p2 (save-excursion (forward-char) (point))))
+         (setq b2 (get-text-property p2 (egg-bunsetsu-info))
+               last (get-text-property p2 'egg-bunsetsu-last))))
+    (setq maxlen (+ slen
+                   (if b2
+                       (chars-in-string (egg-get-bunsetsu-source b2))
+                     0)))
+    (if (> newlen maxlen)
+       (setq beep t
+             newlen maxlen))
+    (setq bunsetsu-info-list (egg-change-bunsetsu-length b0 b1 b2 newlen))
+    (delete-region (point)
+                  (progn (forward-char) (if b2 (forward-char)) (point)))
+    (let ((p (point)))
+      (egg-insert-bunsetsu-list bunsetsu-info-list (not last))
+      (goto-char p))
+    (if beep
+       (ding))))
+
+(defun egg-next-candidate (n)
+  (interactive "p")
+  (let ((last (get-text-property (point) 'egg-bunsetsu-last))
+       (b (get-text-property (point) (egg-bunsetsu-info)))
+       new i max+ p beep)
+    (setq max+ (egg-get-number-of-candidates b))
+    (if (null max+)
+       (let ((prev-b (egg-get-previous-bunsetsu (point))))
+         (setq i (egg-list-candidates b prev-b)) ; there is a case I=/=0
+         (if (or (> n 1) (< n 0))      ; with N=/=1, start with I
+             (setq i (+ n i))          ; or else (N==1),
+           (setq i (if (= i 0) 1 0)))  ;   I:=1 when I was 0, or else I:=0
+         (setq max+ (egg-get-number-of-candidates b)))
+      (setq i (egg-get-current-candidate-number b))
+      (setq i (+ n i)))
+    (if (< i 0)                                ; go backward as if it is ring
+       (while (< i 0)
+         (setq i (+ i max+))))
+    (if (>= i max+)                    ; don't go forward 
+       (setq i (1- max+)
+             beep t))
+    (setq new (egg-decide-candidate b i))
+    (setq p (point))
+    (delete-region p (progn (forward-char) (point)))
+    (egg-insert-bunsetsu new last)
+    (goto-char p)
+    (if beep
+       (ding))))
+
+(defun egg-previous-candidate (n)
+  (interactive "p")
+  (egg-next-candidate (- n)))
+
+(defun egg-decide-bunsetsu (&optional end-marker)
+  (let ((in-loop t)
+       p bunsetsu-info-list bl)
+    (setq p (point))
+    (while in-loop
+      (let ((bl1 (cons (get-text-property p (egg-bunsetsu-info)) nil)))
+       (if bl
+           (setq bl (setcdr bl bl1))
+         (setq bunsetsu-info-list (setq bl bl1))))
+      (forward-char)
+      (remove-text-properties p (point) '(face nil
+                                         intangible nil
+                                         local-map nil
+                                         egg-bunsetsu-last nil))
+      (setq p (point))
+      (if (or (and end-marker (= p end-marker))
+             (get-text-property p 'egg-end))
+         (setq in-loop nil)
+       (setq p (1- p))
+       (delete-region p (1+ p))))      ; Delete bunsetsu separator
+    bunsetsu-info-list))
+
+(defun egg-decide-before-point ()
+  (interactive)
+  (let ((m (make-marker))
+       all start bunsetsu-list)
+    (if (get-text-property (1- (point)) 'egg-start)
+       (signal 'beginning-of-buffer nil)
+      (setq start (1- (previous-single-property-change (point) 'egg-start))))
+    (set-marker m (point))
+    (goto-char start)
+    ;; Delete open marker
+    (delete-region start (1+ start))
+    (setq bunsetsu-list (egg-decide-bunsetsu m))
+    ;; delete separator
+    (delete-region (1- (point)) (point))
+    ;; insert open marker
+    (insert egg-conversion-open)
+    (put-text-property m (point) 'egg-start t)
+    (if egg-conversion-face
+       (put-text-property p (point) 'invisible t))
+    (egg-end-conversion bunsetsu-list)
+    (set-marker m nil)))
+
+(defun egg-exit-conversion ()
+  (interactive)
+  (let (start bunsetsu-list)
+    (if (get-text-property (1- (point)) 'egg-start)
+       (setq start (1- (point)))
+      (setq start (1- (previous-single-property-change (point) 'egg-start))))
+    (goto-char start)
+    ;; Delete open marker
+    (delete-region start (1+ start))
+    (setq bunsetsu-list (egg-decide-bunsetsu))
+    ;; Delete close marker
+    (delete-region (point) (1+ (point)))
+    (egg-do-auto-fill)
+    (egg-end-conversion bunsetsu-list)
+    (run-hooks 'input-method-after-insert-chunk-hook)))
+
+(defun egg-select-candidate ()
+  (interactive)
+  (let ((last (get-text-property (point) 'egg-bunsetsu-last))
+       (b (get-text-property (point) (egg-bunsetsu-info)))
+       (in-loop t)
+       new i max+ p)
+    (setq max+ (egg-get-number-of-candidates b))
+    (if (null max+)
+       (let ((prev-b (egg-get-previous-bunsetsu (point))))
+         (setq i (egg-list-candidates b prev-b))
+         (setq max+ (egg-get-number-of-candidates b)))
+      (setq i (egg-get-current-candidate-number b)))
+    (let* ((candidate-list (egg-get-all-candidates b))
+          (l candidate-list)
+          (candidate (menudiag-select (list 'menu "\e$B8uJd\e(B:" l) (list (nth i l)))))
+      (setq i 0)
+      (while in-loop
+       (if (eq candidate (car l))
+           (setq in-loop nil)
+         (setq l (cdr l)
+               i (1+ i))))
+      (setq new (egg-decide-candidate b i))
+      (setq p (point))
+      (delete-region p (progn (forward-char) (point)))
+      (egg-insert-bunsetsu new last)
+      (goto-char p))))
+
+(provide 'egg-cnv)
+;;; egg-cnv.el ends here.
diff --git a/egg-com.el b/egg-com.el
new file mode 100644 (file)
index 0000000..9604fe9
--- /dev/null
@@ -0,0 +1,334 @@
+;;; egg-com.el --- Communication Routines in Egg Input
+;;;                   Method Architecture
+
+;; Copyright (C) 1997 Mule Project, Powered by Electrotechnical
+;; Laboratory, JAPAN.
+;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
+
+;; Author: Hisashi Miyashita <himi@bird.scphys.kyoto-u.ac.jp>
+;;         NIIBE Yutaka <gniibe@mri.co.jp>
+;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
+
+;; This file will be part of GNU Emacs (in future).
+
+;; GNU Emacs 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,
+;; 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.
+
+;; 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.
+
+;;; Commentary:
+
+;;; Code:
+
+(eval-and-compile
+(define-ccl-program ccl-decode-fixed-euc-jp
+  `(2
+    ((r2 = ,(charset-id 'japanese-jisx0208))
+     (r3 = ,(charset-id 'japanese-jisx0212))
+     (r4 = ,(charset-id 'katakana-jisx0201))
+     (read r0)
+     (loop
+      (read r1)
+      (if (r0 < ?\x80)
+         ((r0 = r1)
+          (if (r1 < ?\x80)
+              (write-read-repeat r0))
+          (write r4)
+          (write-read-repeat r0))
+       ((if (r1 > ?\x80)
+            ((write r2 r0)
+             (r0 = r1)
+             (write-read-repeat r0))
+          ((write r3 r0)
+           (r0 = (r1 | ?\x80))
+           (write-read-repeat r0)))))))))
+
+(define-ccl-program ccl-encode-fixed-euc
+  `(2
+    ((read r0)
+     (loop
+;      (if (r0 < ?\x20)
+;        (write-read-repeat r0))
+      (if (r0 == ,(charset-id 'latin-jisx0201))                 ; Unify
+         ((read r0)
+          (r0 &= ?\x7f)))
+      (if (r0 < ?\x80)
+         ((write 0)
+          (write-read-repeat r0)))
+      (r6 = (r0 == ,(charset-id 'japanese-jisx0208)))
+      (r6 |= (r0 == ,(charset-id 'japanese-jisx0208-1978)))
+      (r6 |= (r0 == ,(charset-id 'chinese-gb2312)))
+      (r6 |= (r0 == ,(charset-id 'korean-ksc5601)))
+      (if r6                                                      ;G1
+         ((read r0)
+          (write r0)
+          (read r0)
+          (write-read-repeat r0)))
+      (r6 = (r0 == ,(charset-id 'katakana-jisx0201)))
+      (r6 |= (r0 == ,(charset-id 'chinese-sisheng)))
+      (if r6                                                      ;G2
+         ((read r0)
+          (write 0)
+          (write-read-repeat r0)))
+      (if (r0 == ,(charset-id 'japanese-jisx0212))                ;G3
+         ((read r0)
+          (write r0)
+          (read r0)
+          (r0 &= ?\x7f)
+          (write-read-repeat r0)))
+      (read r0)
+      (repeat)))))
+)
+
+(make-coding-system 'fixed-euc-jp 4 ?W "Coding System for fixed EUC Japanese"
+                   (cons ccl-decode-fixed-euc-jp ccl-encode-fixed-euc))
+\f
+(defsubst comm-format-u32c (uint32c)
+  (let ((h0 (car uint32c))
+       (h1 (cdr uint32c)))
+    (let ((b0 (logand (lsh h0 -8) 255))
+         (b1 (logand h0 255))
+         (b2 (logand (lsh h1 -8) 255))
+         (b3 (logand h1 255)))
+      (insert-char b0 1)
+      (insert-char b1 1)
+      (insert-char b2 1)
+      (insert-char b3 1))))
+
+(defsubst comm-format-u32 (uint32)
+  (let ((b0 (logand (lsh uint32 -24) 255))
+       (b1 (logand (lsh uint32 -16) 255))
+       (b2 (logand (lsh uint32 -8) 255))
+       (b3 (logand uint32 255)))
+    (insert-char b0 1)
+    (insert-char b1 1)
+    (insert-char b2 1)
+    (insert-char b3 1)))
+
+(defsubst comm-format-i32 (int32)
+  (let ((b0 (logand (ash int32 -24) 255))
+       (b1 (logand (ash int32 -16) 255))
+       (b2 (logand (ash int32 -8) 255))
+       (b3 (logand int32 255)))
+    (insert-char b0 1)
+    (insert-char b1 1)
+    (insert-char b2 1)
+    (insert-char b3 1)))
+
+(defsubst comm-format-u16 (uint16)
+  (let ((b0 (logand (lsh uint16 -8) 255))
+       (b1 (logand uint16 255)))
+    (insert-char b0 1)
+    (insert-char b1 1)))
+
+(defsubst comm-format-u8 (uint8)
+  (let ((b0 (logand uint8 255)))
+    (insert-char b0 1)))
+
+;;; XXX should support other code conversion
+(defsubst comm-format-u16-string (s)
+  (let ((euc-string (encode-coding-string s 'fixed-euc-jp)))
+    (insert euc-string)
+    (insert-char 0 1)
+    (insert-char 0 1)))
+
+;;; XXX should support other code conversion
+(defsubst comm-format-mb-string (s)
+  (let ((euc-string (encode-coding-string s 'euc-japan)))
+    (insert euc-string)
+    (insert-char 0 1)))
+
+(defsubst comm-format-u8-string (s)
+  (insert s)
+  (insert-char 0 1))
+
+(defsubst comm-format-bytes (s)
+  (insert s)
+  (insert-char 255 1))
+
+(defmacro comm-format (format &rest args)
+  "Format a string out of a control-list and arguments into the buffer.
+u means unsigned 32-bit in big endian.
+i means unsigned 32-bit in big endian.
+w means unsigned 16-bit in big endian.
+b means unsigned  8-bit.
+S means 16-bit(big endian) wide-character string (0x0000 terminated).
+E means multibyte string (0x00 terminated).
+s means 8-bit string (0x00 terminated)."
+  (let ((p args) result arg f)
+    (while format
+      (setq arg (car p))
+      (setq f (car format))
+      (setq result
+           (append result
+                   (list
+                    (cond ((eq f 'U) (list 'comm-format-u32c arg))
+                          ((eq f 'u) (list 'comm-format-u32 arg))
+                          ((eq f 'i) (list 'comm-format-i32 arg))
+                          ((eq f 'w) (list 'comm-format-u16 arg))
+                          ((eq f 'b) (list 'comm-format-u8 arg))
+                          ((eq f 'S) (list 'comm-format-u16-string arg))
+                          ((eq f 'E) (list 'comm-format-mb-string arg))
+                          ((eq f 's) (list 'comm-format-u8-string arg))
+                          ((eq f 'B) (list 'comm-format-bytes arg))))))
+      (setq p (cdr p))
+      (setq format (cdr format)))
+    (cons
+     'progn
+     result)))
+\f
+;; Do not move the point, leave it where it was.
+(defun comm-accept-process-output (proc)
+  (let ((p (point)))
+    (accept-process-output proc)
+    (goto-char p)))
+
+;; Assume PROC is bound to the process of current buffer
+(defsubst comm-following-char-or-wait (proc)
+  (if (eobp)
+      (let ((p (point)))
+       (while (= p (point-max))
+         (accept-process-output proc))
+       (goto-char p)))
+  (following-char))
+
+(defun comm-following+forward-char (proc)
+  (prog1
+      (comm-following-char-or-wait proc)
+    (forward-char 1)))
+
+(defsubst comm-unpack-u32c (proc uint32c)
+  (let (h0 h1)
+    (setq h0
+        (+
+         (lsh (comm-following+forward-char proc) 8)
+         (comm-following+forward-char proc)))
+    (setq h1
+        (+
+         (lsh (comm-following+forward-char proc) 8)
+         (comm-following+forward-char proc)))
+    (set uint32c (cons h0 h1))))
+
+(defsubst comm-unpack-u32 (proc uint32)
+  (set uint32
+       (+
+       (lsh (comm-following+forward-char proc) 24)
+       (lsh (comm-following+forward-char proc) 16)
+       (lsh (comm-following+forward-char proc) 8)
+       (comm-following+forward-char proc))))
+
+(defsubst comm-unpack-u16 (proc uint16)
+  (set uint16
+       (+
+       (lsh (comm-following+forward-char proc) 8)
+       (comm-following+forward-char proc))))
+
+(defsubst comm-unpack-u8 (proc uint8)
+  (set uint8
+       (comm-following+forward-char proc)))
+
+;;; XXX should support other conversion (euc-kr, cns)
+(defsubst comm-unpack-u16-string (proc s)
+  (let ((start (point)))
+    (while (not (search-forward "\0\0" nil t))
+      (comm-accept-process-output proc))
+    (set s (buffer-substring start
+                            (+ start
+                               (decode-coding-region start (- (point) 2)
+                                                     'fixed-euc-jp))))))
+
+;;; XXX should support other conversion (euc-kr, cns)
+(defsubst comm-unpack-mb-string (proc s)
+  (let ((start (point)))
+    (while (not (search-forward "\0" nil t))
+      (comm-accept-process-output proc))
+    (set s (buffer-substring start
+                            (+ start
+                               (decode-coding-region start (- (point) 1)
+                                                     'euc-japan))))))
+
+(defsubst comm-unpack-u8-string (proc s)
+  (let ((start (point)))
+    (while (not (search-forward "\0" nil 1))
+      (comm-accept-process-output proc))
+    (set s (buffer-substring start (1- (point))))))
+
+(defsubst comm-unpack-bytes (proc s)
+  (let ((start (point)))
+    (while (not (search-forward "\377" nil 1))
+      (comm-accept-process-output proc))
+    (set s (buffer-substring start (1- (point))))))
+
+(defmacro comm-unpack (format &rest args)
+  "Unpack a string out of a control-string and set arguments.
+u means unsigned 32-bit in big endian.
+w means unsigned 16-bit in big endian.
+b means unsigned  8-bit.
+S means 16-bit(big endian) string (0x0000 terminated).
+E means multibyte string (0x00 terminated).
+s means 8-bit string (0x00 terminated).
+"
+  (let ((p args) result arg f)
+    (while format
+      (setq arg (car p))
+      (setq f (car format))
+      (setq result
+           (append result
+                   (list
+                    (cond ((eq f 'U) (list 'comm-unpack-u32c
+                                           'proc (list 'quote arg)))
+                          ((eq f 'u) (list 'comm-unpack-u32
+                                           'proc (list 'quote arg)))
+                          ((eq f 'w) (list 'comm-unpack-u16
+                                           'proc (list 'quote arg)))
+                          ((eq f 'b) (list 'comm-unpack-u8
+                                           'proc (list 'quote arg)))
+                          ((eq f 'S) (list 'comm-unpack-u16-string
+                                           'proc (list 'quote arg)))
+                          ((eq f 'E) (list 'comm-unpack-mb-string
+                                           'proc (list 'quote arg)))
+                          ((eq f 's) (list 'comm-unpack-u8-string
+                                           'proc (list 'quote arg)))
+                          ((eq f 'B) (list 'comm-unpack-u8-string
+                                           'proc (list 'quote arg)))))))
+      (setq p (cdr p))
+      (setq format (cdr format)))
+    (cons
+     'progn
+     result)))
+\f
+(defmacro comm-call-with-proc (proc vlist send-expr &rest receive-exprs)
+  (list
+   'let vlist
+   (append
+    `(save-excursion
+       (set-buffer (process-buffer proc))
+       (erase-buffer)
+       ,send-expr
+       (process-send-region proc (point-min) (point-max))
+       (goto-char (prog1 (point) (accept-process-output proc))))
+    receive-exprs)))
+
+(defmacro comm-call-with-proc-1 (proc vlist send-expr &rest receive-exprs)
+  (list
+   'let vlist
+   (append
+    `(progn
+       (erase-buffer)
+       ,send-expr
+       (process-send-region proc (point-min) (point-max))
+       (goto-char (prog1 (point) (accept-process-output proc))))
+    receive-exprs)))
+
+(provide 'egg-com)
+;;; egg-com.el ends here.
diff --git a/egg-mlh.el b/egg-mlh.el
new file mode 100644 (file)
index 0000000..d68bcdc
--- /dev/null
@@ -0,0 +1,510 @@
+;;; egg-mlh.el --- Modeless Conversion Facility in Egg Input
+;;;                   Method Architecture
+
+;; Copyright (C) 1997 Mule Project, Powered by Electrotechnical
+;; Laboratory, JAPAN.
+;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
+
+;; Author: NIIBE Yutaka <gniibe@mri.co.jp>
+;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
+;; Keywords: mule, multilingual, input method
+
+;; This file will be part of GNU Emacs (in future).
+
+;; GNU Emacs 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,
+;; 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.
+
+;; 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.
+
+;;; Commentary:
+;; Once written by NIIBE Yutaka in mlh-1.002 distribution.
+;; Then, assigned to Mule Project.
+
+;;; Code:
+
+(defun mlh-space-bar-backward-henkan ()
+  "If the character preceding point is / (slash),
+Do `mlh-backward-henkan'.  Then, invoke appropriate conversion, if needed.
+Or else, execute command that space-bar invokes usually."
+  (interactive)
+  (let ((henkan-begin nil)
+        (inhibit-henkan t))
+    (mlh-backward-henkan)
+    (if henkan-begin
+        (if (or inhibit-henkan (= henkan-begin (point)))
+            (egg-do-auto-fill)
+          (progn
+            (message "Converting...")
+            (sit-for 0)
+           (egg-convert-region henkan-begin (point))
+            (message "") ))
+      (setq this-command 'self-insert-command)
+      (call-interactively 'self-insert-command))))
+
+(defvar mlh-punctuations nil)
+(if mlh-punctuations
+    ()
+  (setq mlh-punctuations "!()?;:"))
+
+(defvar mlh-conversion-scheme-table
+  '(
+    (?- . mlh-kanji)
+;    (?` . mlh-ltn)
+;    (?' . mlh-ltn)
+;    (?, . mlh-ltn)
+    (?, . mlh-kanji)
+    (?. . mlh-kanji)
+;    (?^ . mlh-ltn)
+;    (?~ . mlh-ltn)
+;    (?\". mlh-ltn)
+;    (?@ . mlh-ltn)
+;    (?< . mlh-ltn)
+;    (?> . mlh-ltn)
+    (?a . mlh-kanji)
+;    (?b . mlh-)
+    (?c . mlh-capitalize)
+    (?d . mlh-user-defined-conversion)
+    (?e . mlh-kanji)
+    (?f . mlh-hiragana)
+    (?g . mlh-greek)
+    (?h . mlh-hangul)
+    (?i . mlh-kanji)
+    (?j . mlh-jis-code)
+    (?k . mlh-katakana)
+;    (?l . mlh-ligature)
+;    (?m . mlh-)
+    (?n . mlh-kanji)
+;    (?n . mlh-no-conversion)
+    (?o . mlh-kanji)
+    (?p . mlh-upcase-letter)
+    (?q . mlh-quit)
+;    (?r . mlh-)
+    (?s . mlh-small-letter)
+;    (?t . mlh-)
+    (?u . mlh-kanji)
+;    (?v . mlh-)
+    (?w . mlh-white-space)
+    (?x . mlh-execute)
+;    (?y . mlh-)
+    (?z . mlh-zhongwen)
+    (?H . mlh-hiragana-to-kanji)
+    (?L . mlh-lisp-expression)
+    (?W . mlh-zenkaku-white)
+    (?X . mlh-exit)
+    (?Z . mlh-zenkaku)
+))
+\f
+(defun mlh-zenkaku-white ()
+  (forward-char -1)
+  (skip-chars-backward "0-9")
+  (mlh-backward-henkan)
+  (setq beg (point))
+  (goto-char end-marker)
+  (backward-delete-char 2)
+  (let* ((str (buffer-substring beg (point)))
+         (val (string-to-int str)))
+    (delete-region beg (point))
+    (if (= val 0)
+        (setq val 1))
+    (while (> val 0)
+      (insert "\e$B!!\e(B")
+      (setq val (1- val))))
+  (if (null henkan-begin)
+      (setq henkan-begin beg)))
+
+(defun mlh-exit ()
+  (goto-char end-marker)
+  (backward-delete-char 2)
+  (insert " ")
+  (setq henkan-begin (point)))
+
+(defun mlh-upcase-letter ()
+  (forward-char -1)
+  (skip-chars-backward "a-zA-Z0-9")
+  (mlh-backward-henkan)
+  (setq beg (point))
+  (goto-char end-marker)
+  (backward-delete-char 2)
+  (upcase-region beg (point))
+  (if (null henkan-begin)
+      (setq henkan-begin beg)))
+
+(defun mlh-capitalize ()
+  (forward-char -1)
+  (skip-chars-backward "a-zA-Z1-9")
+  (mlh-backward-henkan)
+  (setq beg (point))
+  (goto-char end-marker)
+  (backward-delete-char 2)
+  (capitalize-region beg (point))
+  (if (null henkan-begin)
+      (setq henkan-begin beg)))
+
+(defun mlh-jis-code ()
+  (forward-char -1)
+  (skip-chars-backward "0-9a-fA-F")
+  (mlh-backward-henkan)
+  (setq beg (point))
+  (goto-char end-marker)
+  (backward-delete-char 2)
+  (let* ((str (buffer-substring beg (point)))
+         (val (read-jis-code-from-string str)))
+    ;;         ^--- this function is in egg.el
+    (delete-region beg (point))
+    (if val
+        (insert (make-character lc-jp (car val) (cdr val)))
+      (insert "?jis?")))
+  (if (null henkan-begin)
+      (setq henkan-begin beg)))
+
+(defun mlh-lisp-expression ()
+  (forward-char -1)
+  (let ((stab (syntax-table)))
+    (unwind-protect
+        (progn
+          (set-syntax-table emacs-lisp-mode-syntax-table)
+          (forward-sexp -1))
+      (set-syntax-table stab)))
+  (mlh-backward-henkan)
+  (setq beg (point))
+  (goto-char end-marker)
+  (backward-delete-char 2)
+  (let* ((exp-str
+          (buffer-substring beg (point)))
+         (exp (car (read-from-string exp-str)))
+         (result (eval exp)))
+    (delete-region beg (point))
+    (insert (format "%s" result)))
+  (if (null henkan-begin)
+      (setq henkan-begin beg)))
+
+(defun mlh-quit ()
+  (goto-char end-marker)
+  (backward-delete-char 2)
+  (setq henkan-begin (point)))
+  
+(defun mlh-no-conversion ()
+  (forward-char -1)
+  (skip-chars-backward "\041-\056\060-\176")
+  (mlh-backward-henkan)
+  (setq beg (point))
+  (goto-char end-marker)
+  (backward-delete-char 2)
+  (if (null henkan-begin)
+      (setq henkan-begin beg)))
+
+(fset 'mlh-small-letter (symbol-function 'mlh-no-conversion))
+
+(defun mlh-white-space ()
+  (forward-char -1)
+  (skip-chars-backward "0-9")
+  (mlh-backward-henkan)
+  (setq beg (point))
+  (goto-char end-marker)
+  (backward-delete-char 2)
+  (let* ((str (buffer-substring beg (point)))
+         (val (string-to-int str)))
+    (delete-region beg (point))
+    (if (= val 0)
+        (setq val 1))
+    (insert (make-string val ?\ )))
+  (if (null henkan-begin)
+      (setq henkan-begin beg)))
+
+(defun mlh-execute ()
+  (forward-char -1)
+  (if (fboundp 'mlh-userdef-function)
+      (mlh-userdef-function)
+    (mlh-backward-henkan)
+    (setq beg (point))
+    (goto-char end-marker)
+    (backward-delete-char 2)
+    (if (null henkan-begin)
+        (setq henkan-begin beg))))
+\f
+(defun mlh-backward-henkan ()
+  "For each words seperated by / (slash), do conversion.
+Accoding to a character preceding slash, conversion scheme are selected.
+
+CHAR.  MNEMONIC             CONVERSION SCHEME
+
+  H    Hiragana to kanji    Convert Hiragana to Kanji
+  L    Lisp                 Evaluate as Emacs-Lisp expression
+  W    zenkaku White space  Insert Zenkaku spaces
+  X    eXit                 Quit going backward, insert space
+  Z    Zenkaku              Convert to Zenkaku
+  c    Capitalize           Capitalize
+  d    user Definition      Convert with user definition table
+  f    Firagana ??          Convert to Hiragana
+  g    Greek letter         Convert to single greek letter
+  h    Hangul               Convert to Hangul
+  j    Jis-code             Convert to character which has code
+  k    Katakana             Convert to Katakana
+  l    Ligature             Ligature (not implemented yet)
+  p    uPcase letter        uPcase
+  q    Quit                 Quit going backward
+  s    Small letter         No conversion
+  w    White space          Insert spaces
+  x    eXecute              Call user defined function
+  z    Zhongwen             Convert to Zhongwen
+    OTHERWISE               Convert to KANJI
+"
+  (if (eq (preceding-char) ?/)
+      (let ((end-marker (point-marker))
+            (char nil)
+            (beg nil))
+        (set-marker-insertion-type end-marker t)
+        (unwind-protect
+            (let (scheme)
+              (backward-char 1)
+              (setq char (preceding-char))
+              (cond 
+               ((setq scheme (assq char mlh-conversion-scheme-table))
+                (funcall (cdr scheme)))
+               (t
+                (goto-char end-marker)))
+              (if beg
+                  (progn
+                    (goto-char beg)
+                    (mlh-do-spacing)
+                    (goto-char end-marker))))
+          (set-marker end-marker nil)))))
+
+\f
+(defvar mlh-syntax-table nil
+  "Syntax table of mlh, which are used to determine spacing.")
+(if mlh-syntax-table
+    ()
+  (setq mlh-syntax-table (copy-syntax-table emacs-lisp-mode-syntax-table))
+  (modify-syntax-entry ?! "." mlh-syntax-table)
+  (modify-syntax-entry ?$ "'" mlh-syntax-table)
+  (modify-syntax-entry ?% "'" mlh-syntax-table)
+  (modify-syntax-entry ?& "'" mlh-syntax-table)
+  (modify-syntax-entry ?{ "(}" mlh-syntax-table)
+  (modify-syntax-entry ?} "){" mlh-syntax-table)
+)
+
+;;; XXX RTFM, gniibe!
+(defvar mlh-space-control
+  '(
+    (("al".?w).("al".?w))
+    (("al".?w).("al".?_))
+    (("al".?w).("Hj|".?e))
+    (("al".?w).("Cj|".?e))
+    (("al".?_).("al".?w))
+    (("al".?_).("al".?_))
+    (("al".?_).("Hj|".?e))
+    (("al".?_).("Cj|".?e))
+    (("al".?.).("al".?w))
+    (("al".?.).("al".?_))
+    (("al".?_).("Hj|".?e))
+    (("al".?_).("Cj|".?e))
+    (("Hj|".?e).("al".?w))
+    (("Cj|".?e).("al".?w))
+    (("Hj|".?e).("al".?_))
+    (("Cj|".?e).("al".?_))
+    )
+  "Alist that determines inserting space.")
+
+(defun mlh-do-spacing ()
+  "Arrange spacing as you like."
+  (if (bobp)
+      ()
+    (let ((s-tab (syntax-table))
+          s-pc s-fc
+          c-pc c-fc)
+      (unwind-protect
+          (progn
+            (set-syntax-table mlh-syntax-table)
+            (setq s-pc (char-syntax (preceding-char))
+                  s-fc (char-syntax (following-char))))
+        (set-syntax-table s-tab))
+      (setq c-pc (category-set-mnemonics (char-category-set (preceding-char)))
+           c-fc (category-set-mnemonics (char-category-set (following-char))))
+      (if (member (cons (cons c-pc s-pc) (cons c-fc s-fc)) mlh-space-control)
+          (progn
+            (and henkan-begin
+                 (>= henkan-begin (point))
+                 (setq henkan-begin (1+ henkan-begin)))
+            (insert " "))))))
+\f
+(defvar mlh-select-mode-map (make-keymap))
+
+;;; acutually this map is not necessary now. for future extention
+(defvar mlh-select-mode-esc-map (make-keymap))
+
+(define-key mlh-select-mode-map [t] 'undefined)
+(define-key mlh-select-mode-esc-map [t] 'undefined)
+
+(let ((ch 32))
+  (while (< ch 127)
+    (define-key mlh-select-mode-map (char-to-string ch)
+      'mlh-select-kakutei-and-self-insert)
+    (setq ch (1+ ch))))
+
+(define-key mlh-select-mode-map "\C-m" 'mlh-select-kakutei-and-self-insert)
+(define-key mlh-select-mode-map "\C-b" 'mlh-select-prev-candidate)
+(define-key mlh-select-mode-map "\C-f" 'mlh-select-next-candidate)
+(define-key mlh-select-mode-map "\177" 'mlh-select-prev-candidate)
+(define-key mlh-select-mode-map " " 'mlh-select-next-candidate)
+(define-key mlh-select-mode-map "/" 'mlh-select-kakutei)
+
+(if (eq window-system 'x)
+    (let ()
+      (define-key mlh-select-mode-map [return] 'mlh-select-kakutei-and-self-insert)
+      (define-key mlh-select-mode-map [delete] 'mlh-select-prev-candidate)
+      ))
+
+(defun mlh-select-insert-candidate (n)
+  (delete-region beg (point))
+  (insert (nth n candidates)))
+
+(defun mlh-select-prev-candidate ()
+  (interactive)
+  (setq current-candidate (1- current-candidate))
+  (if (< current-candidate 0)
+      (setq current-candidate (1- number-of-candidates)))
+  (mlh-select-insert-candidate current-candidate))
+
+(defun mlh-select-next-candidate ()
+  (interactive)
+  (setq current-candidate (1+ current-candidate))
+  (if (>= current-candidate number-of-candidates)
+      (setq current-candidate 0))
+  (mlh-select-insert-candidate current-candidate))
+
+(defun mlh-recursive-edit-select (beg end candidates)
+  (mlh-select-insert-candidate 0)
+  (and (boundp 'disable-undo) (setq disable-undo t))
+  (let ((old-local-map (current-local-map))
+       (number-of-candidates (length candidates))
+       (current-candidate 0))
+    (use-local-map mlh-select-mode-map)
+    (recursive-edit)
+    (use-local-map old-local-map)))
+
+(defun mlh-select-kakutei-and-self-insert ()
+  (interactive)
+  (setq unread-command-events (list last-command-event))
+  (mlh-select-kakutei))
+
+(defun mlh-select-kakutei ()
+  (interactive)
+  (and (boundp 'disable-undo) (setq disable-undo nil))
+  (exit-recursive-edit))
+\f
+(defun mlh-user-defined-conversion ()
+  (forward-char -1)
+  (skip-chars-backward "-a-zA-Z")
+  (mlh-backward-henkan)
+  (setq beg (point))
+  (goto-char end-marker)
+  (backward-delete-char 2)
+  (let* ((str (buffer-substring beg (point)))
+         (userdef (mlh-userdef<==string str)))
+    (cond ((stringp userdef)
+          (delete-region beg (point))
+          (insert userdef))
+         ((null userdef)
+          (delete-region beg (point))
+          ;; (add-userdef) (insert new-userdef)
+          (insert "?udef?"))
+         ((consp userdef)
+          (mlh-recursive-edit-select beg (point) userdef))))
+  (if (null henkan-begin)
+      (setq henkan-begin beg)))
+
+(defvar mlh-userdef-table nil
+  "Convertion table of words(string) to another words(string).")
+
+(defun mlh-userdef<==string (str)
+  "Convert string to another string with `mlh-userdef-table'"
+  (cdr (assoc str mlh-userdef-table)))
+\f
+(defvar mlh-kanji-function 'mlh-kanji-with-henkan-region-function)
+
+(defun mlh-kanji ()
+  (funcall mlh-kanji-function))
+
+(defun mlh-kanji-with-henkan-region-function ()
+  (skip-chars-backward "-a-z,.'N[]")
+  (mlh-backward-henkan)
+  (setq inhibit-henkan nil)
+  (setq beg (point))
+  (goto-char end-marker)
+  (forward-char -1)
+  (its-translate-region beg (point))
+  (delete-region (point) end-marker)
+  (if (null henkan-begin)
+      (setq henkan-begin beg)))
+
+(defun mlh-hiragana ()
+  (forward-char -1)
+  (skip-chars-backward "-a-z,.'N[]")
+  (mlh-backward-henkan)
+  (setq beg (point))
+  (goto-char end-marker)
+  (forward-char -2)
+  (its-translate-region beg (point))
+  (delete-region (point) end-marker)
+  (setq henkan-begin (point)))
+
+(defun mlh-hiragana-to-kanji ()
+  (forward-char -1)
+  (skip-chars-backward "\e$B$!\e(B-\e$B$s!<\e(B")
+  (mlh-backward-henkan)
+  (setq beg (point))
+  (setq inhibit-henkan nil)
+  (goto-char end-marker)
+  (backward-delete-char 2)
+  (if (null henkan-begin)
+      (setq henkan-begin beg)))
+
+(defun mlh-katakana ()
+  (forward-char -1)
+  (skip-chars-backward "-a-z,.'N[]")
+  (mlh-backward-henkan)
+  (setq beg (point))
+  (goto-char end-marker)
+  (forward-char -2)
+  (its-translate-region beg (point))
+  (insert (mlh-hira-to-kata
+          (prog1
+              (buffer-substring beg (point))
+            (delete-region beg (point)))))
+  (delete-region (point) end-marker)
+  (if (null henkan-begin)
+      (setq henkan-begin beg)))
+
+(defun mlh-zenkaku ()
+  (forward-char -1)
+  (skip-chars-backward "\041-\056\060-\176")
+  (mlh-backward-henkan)
+  (setq beg (point))
+  (goto-char end-marker)
+  (backward-delete-char 2)
+  (japanese-zenkaku-region beg (point))
+  (if (null henkan-begin)
+      (setq henkan-begin beg)))
+
+(defun mlh-hira-to-kata (str)
+  "Convert hiragana to katakana in STR."
+  (let ((result (copy-sequence str))
+        (i 0))
+    (while (setq i (string-match "[\e$B$!\e(B-\e$B$s\e(B]" str i))
+      (aset result (1+ i) ?\245)
+      (setq i (+ i 3)))
+    result))
+
+(provide 'egg-mlh)
+;;; egg-mlh.el ends here.
diff --git a/egg.el b/egg.el
new file mode 100644 (file)
index 0000000..c386176
--- /dev/null
+++ b/egg.el
@@ -0,0 +1,167 @@
+;;; egg.el --- EGG Input Method Architecture
+
+;; Copyright (C) 1997 Mule Project, Powered by Electrotechnical
+;; Laboratory, JAPAN.
+;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
+
+;; Author: NIIBE Yutaka <gniibe@mri.co.jp>
+;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
+;; Keywords: mule, multilingual, input method
+
+;; This file will be part of GNU Emacs (in future).
+
+;; GNU Emacs 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,
+;; 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.
+
+;; 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.
+
+;;; Commentary:
+
+;;; Code:
+(defvar egg-mode-preference t
+  "Non-nil if modefull.")
+
+;;;###autoload
+(defun egg-mode (&optional arg)
+  "Toggle EGG  mode.
+\\[describe-bindings]
+"
+  (interactive "P")
+  (if (null arg)
+      ;; Turn off
+      (progn
+       (setq describe-current-input-method-function nil)
+       (setq current-input-method nil)
+       (let ((orig-local-map (keymap-parent (current-local-map))))
+         (use-local-map orig-local-map))
+       (run-hooks 'input-method-inactivate-hook))
+    ;; Turn on
+    (use-local-map (if egg-mode-preference
+                      (egg-modefull-map)
+                    (egg-modeless-map)))
+    (setq inactivate-current-input-method-function 'egg-mode)
+    (setq describe-current-input-method-function 'egg-help)
+    (run-hooks 'input-method-activate-hook))
+  (force-mode-line-update))
+
+(defun egg-modefull-map ()
+  "Generate modefull keymap for EGG mode."  
+  (let ((map (make-sparse-keymap))
+       (i 33))
+    (define-key map "\C-_" 'egg-jis-code-input)
+    (while (< i 127)
+      (define-key map (vector i) 'egg-self-insert-char)
+      (setq i (1+ i)))
+    (set-keymap-parent map (current-local-map))
+    map))
+
+(defun egg-modeless-map ()
+  "Generate modeless keymap for EGG mode."
+  (let ((map (make-sparse-keymap)))
+    (define-key map " " 'mlh-space-bar-backward-henkan)
+    (define-key map "\C-_" 'egg-jis-code-input)
+    (set-keymap-parent map (current-local-map))
+    map))
+
+(defun egg-self-insert-char ()
+  (interactive)
+  (its-start last-command-char))
+\f
+(defun egg-hinshi-select ()
+ (menudiag-select ; Should generate at initialization time
+  '(menu  "\e$BIJ;lL>\e(B:"
+         (("\e$BIaDLL>;l\e(B" .
+           (menu  "\e$BIJ;lL>\e(B[\e$BIaDLL>;l\e(B]:"
+                  ("\e$BL>;l\e(B" "\e$B%59T\e(B(\e$B$9$k\e(B)&\e$BL>;l\e(B" "\e$B0lCJ\e(B&\e$BL>;l\e(B"
+                   "\e$B7AMFF0;l\e(B&\e$BL>;l\e(B" "\e$B?t;l\e(B")))
+          ("\e$B8GM-L>;l\e(B" .
+           (menu  "\e$BIJ;lL>\e(B[\e$B8GM-L>;l\e(B]:"
+                  ("\e$B?ML>\e(B" "\e$BCOL>\e(B" "\e$B?ML>\e(B&\e$BCOL>\e(B" "\e$B8GM-L>;l\e(B")))
+          ("\e$BF0;l\e(B" .
+           (menu  "\e$BIJ;lL>\e(B[\e$BF0;l\e(B]:"
+                  ("\e$B0lCJ\e(B" "\e$B0lCJ\e(B&\e$BL>;l\e(B" "\e$B%+9T8^CJ\e(B" "\e$B%,9T8^CJ\e(B"
+                   "\e$B%59T8^CJ\e(B" "\e$B%?9T8^CJ\e(B")))
+          ("\e$BFC<l$JF0;l\e(B" .
+           (menu  "\e$BIJ;lL>\e(B[\e$BFC<l$JF0;l\e(B]:"
+                  ("\e$B%+9T\e(B(\e$B9T$/\e(B)" "\e$B%i9T\e(B(\e$B2<$5$$\e(B)" "\e$BMh\e(B(\e$B$3\e(B)"
+                   "\e$BMh\e(B(\e$B$-\e(B)" "\e$BMh\e(B(\e$B$/\e(B)" "\e$B0Y\e(B(\e$B$7\e(B)")))
+          ("\e$BF0;l0J30$NMQ8@\e(B" .
+           (menu  "\e$BIJ;lL>\e(B[\e$BF0;l0J30$NMQ8@\e(B]:"
+                  ("\e$B7AMF;l\e(B" "\e$B7AMFF0;l\e(B" "\e$B7AMFF0;l\e(B&\e$BL>;l\e(B"
+                   "\e$B7AMFF0;l\e(B(\e$B$?$k\e(B)")))))))
+
+;; XXX: Should use backend interface
+(defun egg-toroku-region (start end)
+  (interactive "r")
+  (let* ((env (wnn-get-environment))   ; XXX
+        (kanji (buffer-substring start end))
+        (yomi (read-multilingual-string 
+               (format "\e$B<-=qEPO?!X\e(B%s\e$B!Y\e(B  \e$BFI$_\e(B:" kanji)))
+        (dic (menudiag-select (list 'menu "\e$BEPO?<-=qL>\e(B:"
+                                ;; XXX
+                                (wnn-list-writable-dictionaries-byname env))))
+        (dic-name (wnn-dict-name dic))
+        (hinshi (egg-hinshi-select))
+        (hinshi-id (wnn-hinshi-number env hinshi)))
+    (if (y-or-n-p
+        (format "\e$B<-=q9`L\!X\e(B%s\e$B!Y\e(B(%s: %s)\e$B$r\e(B %s \e$B$KEPO?$7$^$9\e(B"
+                kanji yomi hinshi dic-name))
+       (let ((r (wnn-add-word env dic yomi kanji "" hinshi-id 0)))
+         (if (< r 0)
+           (error "\e$B<-=qEPO?!X\e(B%s\e$B!Y\e(B(%s: %s) %s \e$B$K<:GT$7$^$7$?\e(B: %s"
+                  kanji yomi hinshi dic-name
+                  (wnnrpc-get-error-message (- r)))
+           (message 
+            "\e$B<-=q9`L\!X\e(B%s\e$B!Y\e(B(%s: %s)\e$B$r\e(B %s \e$B$KEPO?$7$^$7$?\e(B" 
+            kanji yomi hinshi dic-name))))))
+\f
+;;;
+;;; auto fill controll
+;;;
+
+(defun egg-do-auto-fill ()
+  (if (and auto-fill-function (> (current-column) fill-column))
+      (let ((ocolumn (current-column)))
+       (funcall auto-fill-function)
+       (while (and (< fill-column (current-column))
+                   (< (current-column) ocolumn))
+         (setq ocolumn (current-column))
+         (funcall auto-fill-function)))))
+
+(setq its-hira-period "\e$B!#\e(B")    ; ". " "\e$B!%\e(B" "\e$B!#\e(B"
+(setq its-hira-comma  ", ")    ; ", " "\e$B!$\e(B" "\e$B!"\e(B"
+
+(require 'its)
+(require 'menudiag)
+(require 'egg-mlh)
+(require 'egg-cnv)
+(require 'egg-com)
+
+(load-library "its/hira")
+(setq-default its-current-map its-hira-map)
+
+(load-library "egg/wnn")
+(load-library "egg/wnnrpc")
+(setq egg-conversion-backend wnn-conversion-backend)
+
+;;(load-library "egg/sj3rpc")
+;;(load-library "egg/sj3")
+;;(setq egg-conversion-backend sj3-conversion-backend)
+
+(add-hook 'kill-emacs-hook 'egg-kill-emacs-function)
+(defun egg-kill-emacs-function ()
+  (egg-finalize-backend))
+
+(provide 'egg)
+
+;;; egg.el ends here
diff --git a/egg/sj3.el b/egg/sj3.el
new file mode 100644 (file)
index 0000000..c5ad963
--- /dev/null
@@ -0,0 +1,246 @@
+;;; egg/sj3.el --- SJ3 Support (high level interface) in Egg
+;;;                Input Method Architecture
+
+;; Copyright (C) 1997 Mule Project, Powered by Electrotechnical
+;; Laboratory, JAPAN.
+;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
+
+;; Author: NIIBE Yutaka <gniibe@mri.co.jp>
+;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
+
+;; This file will be part of GNU Emacs (in future).
+
+;; GNU Emacs 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,
+;; 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.
+
+;; 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.
+
+;;; Commentary:
+
+;;; Code:
+
+(defconst sj3-conversion-backend
+  [ sj3-init
+
+    sj3-start-conversion
+      sj3-get-bunsetsu-converted
+      sj3-get-bunsetsu-source
+      sj3-list-candidates
+          sj3-get-number-of-candidates
+          sj3-get-current-candidate-number
+          sj3-get-all-candidates
+          sj3-decide-candidate
+      sj3-change-bunsetsu-length
+    sj3-end-conversion
+
+    sj3-fini
+ ])
+
+(defconst sj3-server-port 3000 "Port number of SJ3 server")
+(defvar sj3-stdy-size 0 "STDYSIZE of SJ3 server")
+(defvar sj3-hostname "localhost"
+  "Hostname of SJ3 server")
+
+(defun sj3-open (hostname)
+  "Establish the connection to SJ3 server.  Return process object."
+  (let* ((buf (generate-new-buffer " *SJ3*"))
+        (proc (open-network-stream "SJ3" buf hostname sj3-server-port))
+        result)
+    (process-kill-without-query proc)
+    (set-process-coding-system proc 'no-conversion 'no-conversion)
+    (set-marker-insertion-type (process-mark proc) t)
+    (save-excursion
+      (set-buffer buf)
+      (erase-buffer)
+      (buffer-disable-undo)
+      (setq enable-multibyte-characters nil))
+    ;; Initialize dictionaries
+    (setq sj3-sys-dict-list nil)
+    (setq sj3-user-dict-list nil)
+    (setq result (sj3rpc-open proc (system-name) (user-login-name)))
+    (if (< result 0)
+       (let ((msg (sj3rpc-get-error-message (- result))))
+         (delete-process proc)
+         (kill-buffer buf)
+         (error "Can't open SJ3 session (%s): %s" hostname msg)))
+    (setq result (sj3rpc-get-stdy-size proc))
+    (if (< result 0)
+       (let ((msg (sj3rpc-get-error-message (- result))))
+         (delete-process proc)
+         (kill-buffer buf)
+         (error "Can't get SJ3 STDYSIZE: %s"msg)))
+    (setq sj3-stdy-size result)
+    proc))
+
+;; <env> ::= [ <proc> <dictionary-list> ]
+(defvar sj3-environment nil
+  "Environment for SJ3 kana-kanji conversion")
+
+(defsubst sj3env-get-proc (env)
+  (aref env 0))
+(defsubst sj3env-get-dictionary-list (env)
+  (aref env 1))
+
+;; <bunsetsu> ::=
+;;  [ <env> <source> <converted> <rest>
+;;    <stdy> <zenkouho> <zenkouho-pos> <stdy-down> ]
+(defsubst sj3-make-bunsetsu (env source converted rest stdy)
+  (vector env source converted rest stdy nil nil nil))
+
+(defsubst sj3bunsetsu-get-env (b)
+  (aref b 0))
+(defsubst sj3bunsetsu-get-source (b)
+  (aref b 1))
+(defsubst sj3bunsetsu-get-converted (b)
+  (aref b 2))
+(defsubst sj3bunsetsu-get-rest (b)
+  (aref b 3))
+(defsubst sj3bunsetsu-get-stdy (b)
+  (aref b 4))
+(defsubst sj3bunsetsu-get-zenkouho (b)
+  (aref b 5))
+(defsubst sj3bunsetsu-set-zenkouho (b z)
+  (aset b 5 z))
+(defsubst sj3bunsetsu-get-zenkouho-pos (b)
+  (aref b 6))
+(defsubst sj3bunsetsu-set-zenkouho-pos (b p)
+  (aset b 6 p))
+(defsubst sj3bunsetsu-get-stdydown (b)
+  (aref b 7))
+(defsubst sj3bunsetsu-set-stdydown (b s)
+  (aset b 7 s))
+
+(defun sj3-get-bunsetsu-source (b)
+  (sj3bunsetsu-get-source b))
+(defun sj3-get-bunsetsu-converted (b)
+  (concat (sj3bunsetsu-get-converted b)
+         (sj3bunsetsu-get-rest b)))
+(defun sj3-get-bunsetsu-stdy (b)
+  (sj3bunsetsu-get-stdy b))
+
+(defvar sj3-dictionary-specification
+  '(("study.dat")
+    ["sj3main.dic" ""]
+    [("private.dic") ""])
+  "Dictionary specification of SJ3.")
+
+(defvar sj3-usr-dic-dir (concat "user/" (user-login-name))
+  "*Directory of user dictionary for SJ3.")
+
+(defun sj3-filename (p)
+  ""
+  (cond ((consp p) (concat sj3-usr-dic-dir "/" (car p)))
+       (t p)))
+
+(defun sj3-get-environment ()
+  (if sj3-environment
+      sj3-environment
+    (let* ((proc (sj3-open sj3-hostname))
+          (stdy (sj3-filename (car sj3-dictionary-specification)))
+          (l (cdr sj3-dictionary-specification))
+          dict-list)
+      (if (/= (sj3rpc-open-stdy proc stdy) 0)
+         (error "Dame1")               ; XXX
+       (while l
+         (let ((dic (car l))
+               dic-id)
+           (setq dic-id
+                 (sj3rpc-open-dictionary proc (sj3-filename (aref dic 0))
+                                         (aref dic 1)))
+           (if (< dic-id 0)
+               (error "Dame2")         ; XXX
+             (setq dict-list (cons dic-id dict-list)
+                   l (cdr l))))))
+       (setq sj3-environment (vector proc dict-list)))))
+
+(defun sj3-init ()
+  )
+
+(defun sj3-start-conversion (yomi)
+  "Convert YOMI string to kanji, and enter conversion mode.
+Return the list of bunsetsu."
+  (let ((env (sj3-get-environment)))
+    (sj3rpc-begin env yomi)))
+
+;; XXX: not implemented yet
+(defun sj3-end-conversion (bunsetsu-list)
+  )
+
+(defun sj3-list-candidates (bunsetsu prev-bunsetsu)
+  (let* ((env (sj3bunsetsu-get-env bunsetsu))
+        (yomi (sj3bunsetsu-get-source bunsetsu))
+        (z (sj3rpc-get-bunsetsu-candidates env yomi)))
+    (sj3bunsetsu-set-zenkouho bunsetsu z)
+    (sj3bunsetsu-set-zenkouho-pos bunsetsu 0)
+    0))
+
+(defun sj3-get-number-of-candidates (bunsetsu)
+  (let ((l (sj3bunsetsu-get-zenkouho bunsetsu)))
+    (if l
+       (length l)
+      nil)))
+
+(defun sj3-decide-candidate (bunsetsu candidate-pos)
+  (let* ((candidate-list (sj3bunsetsu-get-zenkouho bunsetsu))
+        (candidate (nth candidate-pos candidate-list)))
+    (sj3bunsetsu-set-zenkouho candidate candidate-list)
+    (sj3bunsetsu-set-zenkouho-pos candidate candidate-pos)
+    candidate))
+
+(defun sj3-get-current-candidate-number (bunsetsu)
+  (sj3bunsetsu-get-zenkouho-pos bunsetsu))
+
+(defun sj3-get-all-candidates (bunsetsu)
+  (let* ((l (sj3bunsetsu-get-zenkouho bunsetsu))
+        (result (cons nil nil))
+        (r result))
+    (catch 'break
+      (while t
+       (let ((candidate (car l)))
+         (setcar r (sj3bunsetsu-get-converted candidate))
+         (if (null (setq l (cdr l)))
+             (throw 'break nil)
+           (setq r (setcdr r (cons nil nil)))))))
+    result))
+
+(defun sj3-change-bunsetsu-length (b0 b1 b2 len)
+  (let ((yomi (concat
+              (sj3bunsetsu-get-source b1)
+              (if b2 (sj3bunsetsu-get-source b2))))
+       (env (sj3bunsetsu-get-env b1))
+       yomi1 yomi2
+       bunsetsu1 bunsetsu2)
+    (save-match-data
+      (string-match (concat "^\\(" (make-string len ?.) "\\)\\(.*$\\)") yomi)
+      (setq yomi1 (match-string 1 yomi))
+      (setq yomi2 (match-string 2 yomi)))
+    (setq bunsetsu1
+         (sj3rpc-tanbunsetsu-conversion env yomi1))
+    ;; Only set once.
+    (sj3bunsetsu-set-stdydown bunsetsu1
+                             (or (sj3bunsetsu-get-stdydown b1)
+                                 (if b2
+                                     (list b1 b2)
+                                   (list b1))))
+    (if (< 0 (length yomi2))
+       (setq bunsetsu2 (sj3rpc-tanbunsetsu-conversion env yomi2))
+      (setq bunsetsu2 nil))
+    (if bunsetsu2
+       (list bunsetsu1 bunsetsu2)
+      (list bunsetsu1))))
+
+;; XXX: Not implemented yet
+(defun sj3-fini ()
+  )
+
+;;; egg/sj3.el ends here.
diff --git a/egg/sj3rpc.el b/egg/sj3rpc.el
new file mode 100644 (file)
index 0000000..6ae09aa
--- /dev/null
@@ -0,0 +1,244 @@
+;;; egg/sj3.el --- SJ3 Support (low level interface) in Egg
+;;;                Input Method Architecture
+
+;; Copyright (C) 1997 Mule Project, Powered by Electrotechnical
+;; Laboratory, JAPAN.
+;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
+
+;; Author: NIIBE Yutaka <gniibe@mri.co.jp>
+;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
+
+;; This file will be part of GNU Emacs (in future).
+
+;; GNU Emacs 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,
+;; 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.
+
+;; 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.
+
+;;; Commentary:
+
+;;; Code:
+
+;; Only support SJ3 version 2.
+
+(eval-when-compile
+  (require 'egg-com)
+  (load-library "egg/sj3")
+  (defmacro sj3-const (c)
+    (cond ((eq c 'OPEN)            1)
+         ((eq c 'CLOSE)           2)
+         ((eq c 'DICADD)         11)
+         ((eq c 'DICDEL)         12)
+         ((eq c 'OPENSTDY)       21)
+         ((eq c 'CLOSESTDY)      22)
+         ((eq c 'STDYSIZE)       23)
+         ((eq c 'LOCK)           31)
+         ((eq c 'UNLOCK)         32)
+         ((eq c 'BEGIN)          41)
+         ((eq c 'BEGIN_EUC)     111)
+         ((eq c 'TANCONV)        51)
+         ((eq c 'TANCONV_EUC)   112)
+         ((eq c 'KOUHO)          54)
+         ((eq c 'KOUHO_EUC)     115)
+         ((eq c 'KOUHOSU)        55)
+         ((eq c 'KOUHOSU_EUC)   116)
+         ((eq c 'STDY)           61)
+         ((eq c 'END)            62)
+         ((eq c 'END_EUC)       117)
+         ((eq c 'WREG)           71)
+         ((eq c 'WREG_EUC)      118)
+         ((eq c 'WDEL)           72)
+         ((eq c 'WDEL_EUC)      119)
+         ((eq c 'MKDIC)          81)
+         ((eq c 'MKSTDY)         82)
+         ((eq c 'MKDIR)          83)
+         ((eq c 'ACCESS)         84)
+         ((eq c 'WSCH)           91)
+         ((eq c 'WSCH_EUC)      120)
+         ((eq c 'WNSCH)          92)
+         ((eq c 'WNSCH_EUC)     121)
+         ((eq c 'VERSION)       103)
+         (t (error "No such constant")))))
+
+(defun sj3rpc-get-error-message (errno)
+  (or (aref sj3rpc-error-message errno) (format "#%d" errno)))
+
+(defmacro sj3rpc-call-with-environment (e vlist send-expr &rest receive-exprs)
+  (let ((v (append
+           `((proc (sj3env-get-proc ,e)))
+           vlist)))
+    (list
+     'let v
+     (append
+       `(save-excursion
+          (set-buffer (process-buffer proc))
+          (erase-buffer)
+          ,send-expr
+          (process-send-region proc (point-min) (point-max))
+          (goto-char (prog1 (point) (accept-process-output proc))))
+       receive-exprs))))
+\f
+(defun sj3rpc-open (proc myhostname username)
+  "Open the session.  Return 0 on success, error code on failure."
+  (comm-call-with-proc proc (result)
+    (comm-format (u u s s s) (sj3-const OPEN) 2 ; Server version
+                myhostname username
+                ;; program name
+                (format "%d.emacs-egg" (emacs-pid)))
+    (comm-unpack (u) result)
+    (if (= result -2)
+       0
+      result)))
+
+(defun sj3rpc-get-stdy-size (proc)
+  "Return STDYSIZE of SJ3 server.  On failure, return error code."
+  (comm-call-with-proc proc (result)
+    (comm-format (u) (sj3-const STDYSIZE))
+    (comm-unpack (u) result)
+    (if (/= result 0)
+       (- result)                      ; failure
+      (comm-unpack (u) result)
+      result)))
+
+(defsubst sj3rpc-get-stdy (proc)
+  (let ((n 0)
+       (stdy (make-vector sj3-stdy-size 0)))
+    (while (< n sj3-stdy-size)
+      (comm-unpack (b) r)
+      (aset stdy n r)
+      (setq n (1+ n)))
+    stdy))
+
+(defun sj3rpc-begin (env yomi)
+  "Begin conversion."
+  (let ((yomi-ext (encode-coding-string yomi 'euc-japan))
+       (p 0)
+       len source converted stdy bunsetsu-list bl)
+    (sj3rpc-call-with-environment env (result)
+      (comm-format (u s) (sj3-const BEGIN_EUC) yomi-ext)
+      (comm-unpack (u) result)
+      (if (/= result 0)
+         (- result)                    ; failure
+       (comm-unpack (u) result)        ; skip
+       (while (progn
+                (comm-unpack (b) len)
+                (> len 0))
+         (setq stdy (sj3rpc-get-stdy proc))
+         (comm-unpack (E) converted)
+         (setq source
+               (decode-coding-string (substring yomi-ext p (+ p len))
+                                     'euc-japan)
+               p (+ p len))
+         (let ((bl1 (cons (sj3-make-bunsetsu env
+                                             source converted nil stdy) nil)))
+           (if bl
+               (setq bl (setcdr bl bl1))
+             (setq bunsetsu-list (setq bl bl1)))))
+       bunsetsu-list))))
+
+(defun sj3rpc-open-dictionary (proc dict-file-name password)
+  (comm-call-with-proc proc (result)
+    (comm-format (u s s) (sj3-const DICADD) dict-file-name password)
+    (comm-unpack (u) result)
+    (if (/= result 0)
+       (- result)                      ; failure
+      (comm-unpack (u) result)
+      result)))
+
+(defun sj3rpc-close-dictionary (proc dict-no)
+  (comm-call-with-proc proc (result)
+    (comm-format (u u) (sj3-const DICDEL) dict-no)
+    (comm-unpack (u) result)
+    result))
+
+(defun sj3rpc-make-dictionary (proc dict-name)
+  (comm-call-with-proc proc (result)
+    (comm-format (u s u u u) (sj3-const MKDIC) dict-name
+                2048  ; Index length
+                2048  ; Length
+                256   ; Number
+    (comm-unpack (u) result)
+    result)))
+
+(defun sj3rpc-open-stdy (proc stdy-name)
+  (comm-call-with-proc proc (result)
+    (comm-format (u s s) (sj3-const OPENSTDY) stdy-name "")
+    (comm-unpack (u) result)
+    result))
+
+(defun sj3rpc-close-stdy (proc)
+  (comm-call-with-proc proc (result)
+    (comm-format (u) (sj3-const CLOSESTDY))
+    (comm-unpack (u) result)
+    result))
+
+(defun sj3rpc-make-stdy (proc stdy-name)
+  (comm-call-with-proc proc (result)
+    (comm-format (u) (sj3-const MKSTDY) stdy-name "")
+                2048  ; Number
+                1     ; Step
+                2048  ; Length
+    (comm-unpack (u) result)
+    result))
+
+(defun sj3rpc-get-bunsetsu-candidates-sub (proc env yomi yomi-ext len n)
+  (let ((i 0)
+       stdy converted bunsetsu bl bunsetsu-list cylen rest)
+    (comm-call-with-proc-1 proc (result)
+      (comm-format (u u s) (sj3-const KOUHO_EUC) len yomi-ext)
+      (comm-unpack (u) result)
+      (if (/= result 0)
+         (- result)                    ; failure
+       (while (< i n)
+         (comm-unpack (u) cylen)
+         (setq stdy (sj3rpc-get-stdy proc))
+         (comm-unpack (E) converted)
+         (setq rest (decode-coding-string
+                     (substring yomi-ext cylen) 'euc-japan))
+         (setq bunsetsu (sj3-make-bunsetsu env yomi converted rest stdy))
+         (if bl
+             (setq bl (setcdr bl (cons bunsetsu nil)))
+           (setq bunsetsu-list (setq bl (cons bunsetsu nil))))
+         (setq i (1+ i)))
+       bunsetsu-list))))
+
+(defun sj3rpc-get-bunsetsu-candidates (env yomi)
+  (let* ((yomi-ext (encode-coding-string yomi 'euc-japan))
+        (len (length yomi-ext)))
+    (sj3rpc-call-with-environment env (result)
+      (comm-format (u u s) (sj3-const KOUHOSU_EUC) len yomi-ext)
+      (comm-unpack (u) result)
+      (if (/= result 0)
+         (- result)                    ; failure
+       (comm-unpack (u) result)
+       (if (= result 0)
+           (list (sj3-make-bunsetsu env yomi yomi nil nil)) ; XXX
+         (sj3rpc-get-bunsetsu-candidates-sub proc env
+                                             yomi yomi-ext len result))))))
+
+(defun sj3rpc-tanbunsetsu-conversion (env yomi)
+  (let* ((yomi-ext (encode-coding-string yomi 'euc-japan))
+        (len (length yomi-ext)) cylen stdy converted rest)
+    (sj3rpc-call-with-environment env (result)
+      (comm-format (u u s) (sj3-const TANCONV_EUC) len yomi-ext)
+      (comm-unpack (u) result)
+      (if (/= result 0)
+         (- result)
+       (comm-unpack (u) cylen)
+       (setq stdy (sj3rpc-get-stdy proc))
+       (comm-unpack (E) converted)
+       (setq rest (decode-coding-string
+                   (substring yomi-ext cylen) 'euc-japan))
+       (setq bunsetsu (sj3-make-bunsetsu env yomi converted rest stdy))))))
+
+;;; egg/sj3rpc.el ends here.
diff --git a/egg/wnn.el b/egg/wnn.el
new file mode 100644 (file)
index 0000000..6474eb9
--- /dev/null
@@ -0,0 +1,666 @@
+;;; egg/wnn.el --- WNN Support (high level interface) in Egg
+;;;                Input Method Architecture
+
+;; Copyright (C) 1997 Mule Project, Powered by Electrotechnical
+;; Laboratory, JAPAN.
+;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
+
+;; Author: NIIBE Yutaka <gniibe@mri.co.jp>
+;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
+
+;; This file will be part of GNU Emacs (in future).
+
+;; GNU Emacs 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,
+;; 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.
+
+;; 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.
+
+;;; Commentary:
+
+;;; Code:
+
+(eval-when-compile
+  (defmacro WNN-const (c)
+    (cond ((eq c 'BUN_SENTOU) -1)
+         ((eq c 'NO_EXIST)  1)
+         ((eq c 'NO_MATCH) 10)
+         ((eq c 'IMA_OFF)   -4)
+         ((eq c 'IMA_ON)    -3)
+         ((eq c 'HINDO_NOP) -2)
+         ((eq c 'HINDO_INC) -3))))
+
+(defconst wnn-conversion-backend
+  [ wnn-init
+
+    wnn-start-conversion
+      wnn-get-bunsetsu-converted
+      wnn-get-bunsetsu-source
+      wnn-list-candidates
+          wnn-get-number-of-candidates
+          wnn-get-current-candidate-number
+          wnn-get-all-candidates
+          wnn-decide-candidate
+      wnn-change-bunsetsu-length
+    wnn-end-conversion
+
+    wnn-fini
+ ])
+
+;; <env> ::= [ <proc> <env-id> <daibunsetsu-info> ]
+
+(defsubst wnnenv-create (proc env-id)
+  (vector proc env-id nil))
+
+(defsubst wnnenv-get-proc (env)
+  (aref env 0))
+
+(defsubst wnnenv-get-env-id (env)
+  (aref env 1))
+
+(defsubst wnnenv-get-daibunsetsu-info (env)
+  (aref env 2))
+(defsubst wnnenv-set-daibunsetsu-info (env d)
+  (aset env 2 d))
+
+;; <bunsetsu> ::= [ <env> <end> <start> <jiritsugo-end> <dic-no>
+;;                  <entry> <freq> <right-now> <hinshi> <status>
+;;                  <status-backward> <kangovect> <evaluation>
+;;
+;;                  <converted> <yomi> <fuzokugo>
+;;                 <zenkouho> <freq-down>
+;;                  <zenkouho-pos> ]
+;;
+(defsubst wnn-bunsetsu-create (e end start jiritsugo-end dic-no entry freq
+                              right-now hinshi status status-backward
+                              kangovect evaluation)
+  (vector e end start jiritsugo-end dic-no entry freq right-now
+         hinshi status status-backward kangovect evaluation
+         nil nil nil nil nil nil))
+
+(defsubst wnn-bunsetsu-get-env (bunsetsu)
+  (aref bunsetsu 0))
+
+(defsubst wnn-bunsetsu-get-converted (bunsetsu)
+  (aref bunsetsu 13))
+(defsubst wnn-bunsetsu-set-converted (bunsetsu converted)
+  (aset bunsetsu 13 converted))
+
+(defsubst wnn-bunsetsu-get-hinshi (bunsetsu)
+  (aref bunsetsu 8))
+
+(defsubst wnn-bunsetsu-get-dic-no (bunsetsu)
+  (aref bunsetsu 4))
+
+(defsubst wnn-bunsetsu-get-entry (bunsetsu)
+  (aref bunsetsu 5))
+
+(defsubst wnn-bunsetsu-get-right-now (bunsetsu)
+  (aref bunsetsu 7))
+
+(defsubst wnn-bunsetsu-get-yomi (bunsetsu)
+  (aref bunsetsu 14))
+(defsubst wnn-bunsetsu-set-yomi (bunsetsu yomi)
+  (aset bunsetsu 14 yomi))
+
+(defsubst wnn-bunsetsu-get-fuzokugo (bunsetsu)
+  (aref bunsetsu 15))
+(defsubst wnn-bunsetsu-set-fuzokugo (bunsetsu fuzokugo)
+  (aset bunsetsu 15 fuzokugo))
+
+(defsubst wnn-bunsetsu-get-zenkouho (bunsetsu)
+  (aref bunsetsu 16))
+(defsubst wnn-bunsetsu-set-zenkouho (bunsetsu z)
+  (aset bunsetsu 16 z))
+
+(defsubst wnn-bunsetsu-get-freq-down (bunsetsu)
+  (aref bunsetsu 17))
+(defsubst wnn-bunsetsu-set-freq-down (bunsetsu d)
+  (aset bunsetsu 17 d))
+
+(defsubst wnn-bunsetsu-get-zenkouho-pos (bunsetsu)
+  (aref bunsetsu 18))
+(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
+  "Environment for WNN kana-kanji conversion")
+
+(defun wnn-init ()
+  )
+
+(defun wnn-start-conversion (yomi)
+  "Convert YOMI string to kanji, and enter conversion mode.
+Return the list of bunsetsu."
+  (let* ((env (wnn-get-environment wnn-dictionary-specification))
+        (result (wnnrpc-renbunsetsu-conversion env yomi
+                                               (WNN-const BUN_SENTOU) "")))
+    (wnnenv-set-daibunsetsu-info env (car result))
+    (cdr result)))
+
+(defun wnn-get-bunsetsu-converted (bunsetsu)
+  (concat (wnn-bunsetsu-get-converted bunsetsu)
+         (wnn-bunsetsu-get-fuzokugo  bunsetsu)))
+
+;; WNN-UNIQ-CANDIDATES
+;;
+;; Here, IMNSHO, WNN is broken.
+;; WNN must/should return unique one.  The word is representative
+;; among possible words with same string literal.
+;;
+;; With no bunsetsu information to users, users have to chose
+;; the word based on the string literal only.
+;; How we could update frequency?
+;;
+;; We'll modify WNN in future.
+;;
+;; 
+(defun wnn-uniq-candidates (bunsetsu bunsetsu-list)
+  (let ((hash-table (make-vector 31 0)) ; XXX why 31?
+       (l bunsetsu-list)
+       (i 0)
+       n sym0 result p b sym)
+    (setq sym0 (intern (wnn-get-bunsetsu-converted bunsetsu) hash-table))
+    (while l
+      (setq b (car l)
+           l (cdr l)
+           sym (intern (wnn-get-bunsetsu-converted b) hash-table))
+      (if (null (boundp sym))          ; new one
+         (let ((bl (cons b nil)))
+           (set sym b)
+           (if (eq sym0 sym)
+               (wnn-bunsetsu-set-zenkouho-pos bunsetsu (setq n i)))
+           (if p
+               (setq p (setcdr p bl))
+             (setq result (setq p bl)))
+           (setq i (1+ i)))))
+    (wnn-bunsetsu-set-zenkouho bunsetsu result)
+    n))
+
+(defun wnn-list-candidates (bunsetsu prev-bunsetsu)
+  (let* ((candidates (wnn-bunsetsu-get-zenkouho bunsetsu))
+        (yomi (concat (wnn-bunsetsu-get-yomi bunsetsu)
+                      (wnn-bunsetsu-get-fuzokugo bunsetsu)))
+        (converted (concat (wnn-bunsetsu-get-converted bunsetsu)
+                           (wnn-bunsetsu-get-fuzokugo bunsetsu)))
+        (env (wnn-bunsetsu-get-env bunsetsu))
+        prev-hinshi
+        prev-fuzokugo)
+    (if candidates
+       ;; We have the candidates already.  Return the current position.
+       (wnn-bunsetsu-get-zenkouho-pos bunsetsu)
+      (if (null prev-bunsetsu)
+         (setq prev-hinshi -1
+               prev-fuzokugo "")
+       (setq prev-hinshi (wnn-bunsetsu-get-hinshi prev-bunsetsu)
+             prev-fuzokugo (wnn-bunsetsu-get-fuzokugo prev-bunsetsu)))
+      (setq candidates
+           (wnnrpc-get-bunsetsu-candidates env yomi
+                                           prev-hinshi prev-fuzokugo))
+      (wnn-uniq-candidates bunsetsu candidates))))
+
+(defun wnn-get-number-of-candidates (bunsetsu)
+  (let ((l (wnn-bunsetsu-get-zenkouho bunsetsu)))
+    (if l
+       (length l)
+      nil)))
+
+(defun wnn-get-current-candidate-number (bunsetsu)
+  (wnn-bunsetsu-get-zenkouho-pos bunsetsu))
+
+(defun wnn-get-all-candidates (bunsetsu)
+  (let* ((l (wnn-bunsetsu-get-zenkouho bunsetsu))
+        (result (cons nil nil))
+        (r result))
+    (catch 'break
+      (while t
+       (let ((candidate (car l)))
+         (setcar r (concat (wnn-bunsetsu-get-converted candidate)
+                           (wnn-bunsetsu-get-fuzokugo candidate)))
+         (if (null (setq l (cdr l)))
+             (throw 'break nil)
+           (setq r (setcdr r (cons nil nil)))))))
+    result))
+
+(defun wnn-decide-candidate (bunsetsu candidate-pos)
+  (let* ((candidate-list (wnn-bunsetsu-get-zenkouho bunsetsu))
+        (candidate (nth candidate-pos candidate-list)))
+    (wnn-bunsetsu-set-zenkouho candidate candidate-list)
+    (wnn-bunsetsu-set-zenkouho-pos candidate candidate-pos)
+    candidate))
+
+;;
+;;
+(defun wnn-change-bunsetsu-length (b0 b1 b2 len)
+  (let ((yomi (concat
+              (wnn-get-bunsetsu-source b1)
+              (if b2 (wnn-get-bunsetsu-source b2))))
+       (env (wnn-bunsetsu-get-env b1))
+       yomi1 yomi2 prev-hinshi prev-fuzokugo
+       bunsetsu1 bunsetsu2)
+    (if (null b0)
+       (setq prev-hinshi -1
+             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 bunsetsu1
+         (car (wnnrpc-tanbunsetsu-conversion env yomi1
+                                             prev-hinshi prev-fuzokugo)))
+    ;; Only set once.
+    (wnn-bunsetsu-set-freq-down bunsetsu1
+                               (or (wnn-bunsetsu-get-freq-down b1)
+                                   (if b2
+                                       (list b1 b2)
+                                     (list b1))))
+    (if (< 0 (length yomi2))
+       ;; RENBUNSETSU? XXX
+       (setq bunsetsu2
+             (car (wnnrpc-tanbunsetsu-conversion
+                   env yomi2
+                   (wnn-bunsetsu-get-hinshi bunsetsu1)
+                   (wnn-bunsetsu-get-fuzokugo bunsetsu1))))
+      (setq bunsetsu2 nil))
+    (if bunsetsu2
+       (list bunsetsu1 bunsetsu2)
+      (list bunsetsu1))))
+
+
+(defun wnn-get-bunsetsu-source (bunsetsu)
+  (concat (wnn-bunsetsu-get-yomi bunsetsu)
+         (wnn-bunsetsu-get-fuzokugo bunsetsu)))
+
+(defun wnn-end-conversion (bunsetsu-info-list)
+  (let ((env (wnn-bunsetsu-get-env (car bunsetsu-info-list))))
+    (wnn-update-frequency env bunsetsu-info-list)
+    (wnnenv-set-daibunsetsu-info env nil)))
+
+(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)))
+\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"))
+
+;;
+(defun wnn-open (hostname language)
+  "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)
+    (condition-case result
+       (setq proc (open-network-stream "WNN" buf hostname wnn-jserver-port))
+      (error (progn
+              (kill-buffer buf)
+              (signal (car result) (cdr result)))))
+    (process-kill-without-query proc)
+    (set-process-coding-system proc 'no-conversion 'no-conversion)
+    (set-process-sentinel proc 'wnn-comm-sentinel)
+    (set-marker-insertion-type (process-mark proc) t)
+    (save-excursion
+      (set-buffer buf)
+      (erase-buffer)
+      (buffer-disable-undo)
+      (setq enable-multibyte-characters nil))
+    (setq result (wnnrpc-open proc (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))
+      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.")
+
+(defun wnn-filename (p)
+  ""
+  (cond ((consp p) (concat wnn-usr-dic-dir "/" (car p)))
+       (t p)))
+
+(defun wnn-open-file (proc env-id filename)
+  "Open the file FILENAME on the environment ENV-ID on server process PROC.
+Return file descripter.  NIL means NO-file.
+On failure, return negate-encoded error code."
+  (if filename
+      (wnnrpc-open-file proc env-id filename)
+    nil))
+
+(defun wnn-create-directory (proc env-id path)
+  "Create directory to the path."
+  (let ((dir (directory-file-name path))
+       create-list)
+    (while (and dir (/= (wnnrpc-access proc env-id 0 dir) 0))
+      (setq create-list (cons dir create-list)
+           dir (file-name-directory dir))
+      (if dir
+         (setq dir (directory-file-name dir))))
+    (if (null create-list)
+       t                               ; Already exist.
+      ;; Only query once.
+      (if (y-or-n-p (format "\e$B%G%#%l%/%H%j\e(B(%s)\e$B$,M-$j$^$;$s!#:n$j$^$9$+\e(B? " path))
+         (catch 'return
+           (while create-list
+             (let* ((dir (car create-list))
+                    (ret (wnnrpc-mkdir proc env-id dir)))
+               (if (< ret 0)
+                   (progn
+                     (message "\e$B%G%#%l%/%H%j\e(B(%s)\e$B$N:n@.$K<:GT$7$^$7$?\e(B" dir)
+                     (throw 'return nil))))
+             (setq create-list (cdr create-list)))
+           ;; Success
+           (message "\e$B%G%#%l%/%H%j\e(B(%s)\e$B$r:n$j$^$7$?\e(B" path)
+           t)
+       ;; Failure
+       nil))))
+
+(defun wnn-open-dictionary (proc env-id dicname mode)
+  (let ((dictionary (wnn-open-file proc env-id dicname)))
+    (if (null dictionary)
+       (throw 'wnn-set-dictionary-tag nil)
+      (while (< dictionary 0)
+       (let ((err-code (- dictionary)))
+         (if (or (null mode) (/= err-code (WNN-const NO_EXIST)))
+             (let ((msg (wnnrpc-get-error-message err-code)))
+               (message "\e$B<-=q%U%!%$%k\e(B(%s)\e$B$,$"$j$^$;$s\e(B: %s" dicname msg)
+               (throw 'wnn-set-dictionary-tag nil)) ; Failure
+           ;; Try to create new one
+           (if (and (y-or-n-p
+                     (format "\e$B<-=q%U%!%$%k\e(B(%s)\e$B$,$"$j$^$;$s!#:n$j$^$9$+\e(B? "
+                             dicname))
+                    (wnn-create-directory proc env-id
+                                          (file-name-directory dicname))
+                    (= (wnnrpc-create-dictionary proc env-id dicname) 0))
+               (progn
+                 (message "\e$B<-=q%U%!%$%k\e(B(%s)\e$B$r:n$j$^$7$?\e(B" dicname)
+                 (setq dictionary
+                       (wnnrpc-open-file proc env-id dicname)))
+             (throw 'wnn-set-dictionary-tag nil)))))
+      dictionary)))
+
+(defun wnn-open-frequency (proc env-id freqname mode dic)
+  (let ((frequency (wnn-open-file proc env-id freqname)))
+    (if (null frequency)
+       (setq frequency -1)
+      (while (< frequency 0)
+       (let ((err-code (- frequency)))
+         (if (or (null mode) (/= err-code (WNN-const NO_EXIST)))
+             (let ((msg (wnnrpc-get-error-message err-code)))
+               (message "\e$BIQEY%U%!%$%k\e(B(%s)\e$B$,$"$j$^$;$s\e(B: %s" freqname msg)
+               (throw 'wnn-set-dictionary-tag nil)) ; Failure
+           ;; Try to create new one
+           (if (and (y-or-n-p
+                     (format "\e$BIQEY%U%!%$%k\e(B(%s)\e$B$,$"$j$^$;$s!#:n$j$^$9$+\e(B? "
+                             freqname))
+                    (wnn-create-directory proc env-id
+                                          (file-name-directory freqname))
+                    (= (wnnrpc-create-frequency proc env-id freqname dic) 0))
+               (progn
+                 (message "\e$BIQEY%U%!%$%k\e(B(%s)\e$B$r:n$j$^$7$?\e(B" freqname)
+                 (setq frequency
+                       (wnnrpc-open-file proc env-id freqname)))
+             (throw 'wnn-set-dictionary-tag nil))))))
+      frequency))
+
+;; Using local file (uploading/downloading) is not supported yet.
+;; Password is not supported (Password is questionable feature, anyway)
+(defun wnn-set-dictionary (proc env-id reverse-flag dic-spec)
+  ""
+  (catch 'wnn-set-dictionary-tag
+    (let ((dicname (wnn-filename (aref dic-spec 0)))
+         (freqname (wnn-filename (aref dic-spec 1)))
+         (priority  (aref dic-spec 2))
+         (dic-mode  (aref dic-spec 3))
+         (freq-mode (aref dic-spec 4))
+         dictionary frequency)
+      (setq dictionary (wnn-open-dictionary proc env-id dicname dic-mode))
+      (setq frequency
+           (wnn-open-frequency proc env-id freqname freq-mode dictionary))
+      (wnn-set-dictionary-sub proc env-id reverse-flag
+                             dictionary frequency priority dic-mode
+                             freq-mode dicname freqname))))
+
+(defun wnn-set-dictionary-sub (proc env-id reverse-flag
+                              dictionary frequency priority dic-mode
+                              freq-mode dicname freqname)
+  (let ((trying t))
+    (while trying
+      (let ((ret (wnnrpc-set-dictionary proc env-id reverse-flag
+                                       dictionary frequency
+                                       priority dic-mode freq-mode)))
+       (if (< ret 0)
+           (let ((err-code (- ret)))
+             (if (or (null freq-mode) (/= err-code (WNN-const NO_MATCH)))
+                 (let ((msg (wnnrpc-get-error-message (- ret))))
+                   (message "WNN: Error on setting dictionary (%s, %s): %s"
+                            dicname freqname msg)
+                   (setq trying nil))  ; done
+               ;; No-match: Create new frequency and try it again
+               (wnnrpc-discard-file proc env-id frequency) ; XXX: error?
+               (setq frequency
+                     (wnn-query-del/create-frequency proc env-id freqname
+                                                     dictionary))))
+         ;; done sucessfully
+         (setq trying nil))))))
+
+(defun wnn-query-del/create-frequency (proc env-id freqname dictionary)
+  (if (y-or-n-p
+       (format "\e$B<-=q$HIQEY\e(B(%s)\e$B$N@09g@-$,$"$j$^$;$s!#:n$jD>$7$^$9$+\e(B? "
+              freqname))
+      (progn
+       (wnnrpc-remove-file proc freqname) ; XXX: error?
+       (wnnrpc-create-frequency proc env-id freqname dictionary) ; XXX: error?
+       (message "\e$BIQEY%U%!%$%k\e(B(%s)\e$B$r:n$j$^$7$?\e(B" freqname)
+       (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)
+  ""
+  ;; 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))
+    (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))
+    (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))
+
+(defun wnn-update-frequency (env bunsetsu-info-list)
+  (let ((l bunsetsu-info-list))
+    (while l
+      (let* ((b (car l))
+            (fd (wnn-bunsetsu-get-freq-down b))
+            (z (wnn-bunsetsu-get-zenkouho b)))
+       (while fd
+         (let* ((fdb (car fd))
+                (dic-no (wnn-bunsetsu-get-dic-no fdb))
+                (entry (wnn-bunsetsu-get-entry fdb)))
+           (wnnrpc-set-frequency env dic-no entry
+                                 (WNN-const IMA_OFF) (WNN-const HINDO_NOP))
+           (setq fd (cdr fd))))
+       (while z
+         (let* ((zb (car z))
+                (right-now (wnn-bunsetsu-get-right-now zb))
+                (dic-no (wnn-bunsetsu-get-dic-no zb))
+                (entry (wnn-bunsetsu-get-entry zb)))
+           (if (and (/= right-now 0) (/= dic-no -1))
+               (wnnrpc-set-frequency env dic-no entry (WNN-const IMA_OFF)
+                                     (WNN-const HINDO_NOP)))
+           (setq z (cdr z))))
+       (let ((dic-no (wnn-bunsetsu-get-dic-no b))
+             (entry (wnn-bunsetsu-get-entry b)))
+         (if (/= dic-no -1)
+             (wnnrpc-set-frequency env dic-no entry 
+                                   (WNN-const IMA_ON)
+                                   (WNN-const HINDO_INC))))
+       (setq l (cdr l))))))
+\f
+;;; XXX Need alternative implementation
+;(defun wnn-set-conversion-mode ()
+;  (jl-set-environment))
+
+(defun wnn-save-dictionaries ()
+  (for-each-environment
+   js-dic-list
+   (while (< i count)
+     dic => id
+     js-file-write
+     hindo => id
+     js-file-write)))
+
+(defun wnn-version (proc)
+  "Return version number string of WNN server."
+  (format "%x" (wnnrpc-version proc)))
+
+(defun wnn-dai-bunsetsu-p ()
+  (jl-dai-top ))
+
+(defun wnn-next-dai-bunsetsu-pos ()
+  XXX)
+\f
+;;; not implemented yet (NIY)
+(defun wnn-delete-dictionary ()
+  (dj-delete-dic XXX))
+
+;;; NIY, might never be implemented
+(defun wnn-server-inspect ())
+
+;;; NIY
+(defun wnn-list-dictionaries ()
+  (jl-dic-list))
+
+;;; NIY
+(defun wnn-get-conversion-parameters ()
+  (js-get-parameters))
+
+;;; Dictionary management (word registration) is not implemented yet.
+
+;; XXX: local file loaded into the server: Not supported yet
+;(defun wnn-list-dictionaries (env)
+;  (wnnrpc-get-dictionary-list-with-environment env))
+
+(defun wnn-find-dictionary-by-id (id dic-list)
+  (catch 'return
+    (while dic-list
+      (let ((dic (car dic-list)))
+       (if (= (wnndic-get-id dic) id)
+           (throw 'return dic)
+         (setq dic-list (cdr dic-list)))))))
+
+(defun wnn-dict-name (dic)
+  (let ((name (wnndic-get-comment dic)))
+    (if (string= name "")
+       (file-name-nondirectory (wnndic-get-dictname dic))
+      name)))
+
+(defun wnn-list-writable-dictionaries-byname (env)
+  (let ((dic-list (wnnrpc-get-dictionary-list-with-environment env))
+       (w-id-list (wnnrpc-get-writable-dictionary-id-list env)))
+    (mapcar (function (lambda (id)
+                       (let ((dic (wnn-find-dictionary-by-id id dic-list)))
+                         (cons (wnn-dict-name dic) dic))))
+           w-id-list)))
+
+(defun wnn-hinshi-list (env dic name)
+  (let ((dic-number (wnndic-get-id dic)))
+    (wnnrpc-get-hinshi-list env dic-number name)))
+
+(defun wnn-hinshi-number (env hinshi-name)
+  (wnnrpc-hinshi-number (wnnenv-get-proc env) hinshi-name))
+
+(defun wnn-add-word (env dic yomi kanji comment hinshi-id initial-freq)
+  (let ((dic-number (wnndic-get-id dic)))
+    (wnnrpc-add-word env dic-number yomi kanji comment
+                    hinshi-id initial-freq)))
+
+;;; egg/wnn.el ends here.
diff --git a/egg/wnnrpc.el b/egg/wnnrpc.el
new file mode 100644 (file)
index 0000000..901d088
--- /dev/null
@@ -0,0 +1,1078 @@
+;;; egg/wnnrpc.el --- WNN Support (low level interface) in Egg
+;;;                   Input Method Architecture
+
+;; Copyright (C) 1997 Mule Project, Powered by Electrotechnical
+;; Laboratory, JAPAN.
+;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
+
+;; Author: NIIBE Yutaka <gniibe@mri.co.jp>
+;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
+
+;; This file will be part of GNU Emacs (in future).
+
+;; GNU Emacs 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,
+;; 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.
+
+;; 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.
+
+;;; Commentary:
+
+;;; Code:
+
+(eval-when-compile
+  (require 'egg-com)
+  (load-library "egg/wnn")
+  (defmacro wnn-const (c)
+    "Macro for WNN constants."
+    (cond ((eq c 'JS_VERSION)             0)
+         ((eq c 'JS_OPEN)                1)
+          ((eq c 'JS_CLOSE)               3)
+          ((eq c 'JS_CONNECT)             5)
+          ((eq c 'JS_DISCONNECT)          6)
+          ((eq c 'JS_ENV_EXIST)           7)
+          ((eq c 'JS_ENV_STICKY)          8)
+          ((eq c 'JS_ENV_UNSTICKY)        9)
+          ((eq c 'JS_KANREN)             17)
+          ((eq c 'JS_KANTAN_SHO)         18)
+          ((eq c 'JS_KANZEN_SHO)         19)
+          ((eq c 'JS_KANTAN_DAI)         20)
+          ((eq c 'JS_KANZEN_DAI)         21)
+          ((eq c 'JS_HINDO_SET)          24)
+          ((eq c 'JS_DIC_ADD)            33)
+          ((eq c 'JS_DIC_DELETE)         34)
+          ((eq c 'JS_DIC_USE)            35)
+          ((eq c 'JS_DIC_LIST)           36)
+          ((eq c 'JS_DIC_INFO)           37)
+          ((eq c 'JS_FUZOKUGO_SET)       41)
+          ((eq c 'JS_FUZOKUGO_GET)       48)
+          ((eq c 'JS_WORD_ADD)           49)
+          ((eq c 'JS_WORD_DELETE)        50)
+          ((eq c 'JS_WORD_SEARCH)        51)
+          ((eq c 'JS_WORD_SEARCH_BY_ENV) 52)
+          ((eq c 'JS_WORD_INFO)          53)
+          ((eq c 'JS_WORD_COMMENT_SET)   54)
+          ((eq c 'JS_PARAM_SET)          65)
+          ((eq c 'JS_PARAM_GET)          66)
+          ((eq c 'JS_MKDIR)              81)
+          ((eq c 'JS_ACCESS)             82)
+          ((eq c 'JS_WHO)                83)
+          ((eq c 'JS_ENV_LIST)           85)
+          ((eq c 'JS_FILE_LIST_ALL)      86)
+          ((eq c 'JS_DIC_LIST_ALL)       87)
+          ((eq c 'JS_FILE_READ)          97)
+          ((eq c 'JS_FILE_WRITE)         98)
+          ((eq c 'JS_FILE_SEND)          99)
+          ((eq c 'JS_FILE_RECEIVE)      100)
+          ((eq c 'JS_HINDO_FILE_CREATE) 101)
+          ((eq c 'JS_DIC_FILE_CREATE)   102)
+          ((eq c 'JS_FILE_REMOVE)       103)
+          ((eq c 'JS_FILE_LIST)         104)
+          ((eq c 'JS_FILE_INFO)         105)
+          ((eq c 'JS_FILE_LOADED)       106)
+          ((eq c 'JS_FILE_LOADED_LOCAL) 107)
+          ((eq c 'JS_FILE_DISCARD)      108)
+          ((eq c 'JS_FILE_COMMENT_SET)  109)
+          ((eq c 'JS_FILE_PASSWORD)     110)
+          ((eq c 'JS_FILE_STAT)         111)
+          ((eq c 'JS_KILL)              112)
+          ((eq c 'JS_HINSI_LIST)        114)
+          ((eq c 'JS_HINSI_NAME)        115)
+          ((eq c 'JS_HINSI_NUMBER)      116)
+          ((eq c 'JS_HINSI_DICTS)       117)
+          ((eq c 'JS_HINSI_TABLE_SET)   118)
+
+         ((eq c 'JLIB_VERSION) 16387)  ; 0x4003
+
+         ((eq c 'WNN_REV_DICT) 3)
+         ((eq c 'WNN_VECT_NO)      -1)
+         ((eq c 'WNN_VECT_BUNSETSU) 2)
+         ((eq c 'WNN_VECT_KANREN) 0)
+         ((eq c 'WNN_VECT_KANZEN) 1)
+         ((eq c 'WNN_VECT_KANTAN) 1)
+         ((eq c 'WNN_MAX_ENV_OF_A_CLIENT) 32)
+         ((eq c 'WNN_MAX_DIC_OF_AN_ENV)   30)
+         ((eq c 'WNN_MAX_FILE_OF_AN_ENV)  60))))
+
+(defconst wnnrpc-error-message
+  [
+   nil
+   "\e$B%U%!%$%k$,B8:_$7$^$;$s\e(B"
+   nil
+   "\e$B%a%b%j\e(B allocation \e$B$G<:GT$7$^$7$?\e(B"
+   nil
+   "\e$B<-=q$G$O$"$j$^$;$s\e(B"
+   "\e$BIQEY%U%!%$%k$G$O$"$j$^$;$s\e(B"
+   "\e$BIUB08l%U%!%$%k$G$O$"$j$^$;$s\e(B"
+   nil
+   "\e$B<-=q%F!<%V%k$,0lGU$G$9\e(B"
+   "\e$BIQEY%U%!%$%k$,;XDj$5$l$?<-=q$NIQEY%U%!%$%k$G$O$"$j$^$;$s\e(B"
+   nil
+   nil
+   nil
+   nil
+   nil
+   "\e$B%U%!%$%k$,%*!<%W%s$G$-$^$;$s\e(B"
+   "\e$B@5$7$$IQEY%U%!%$%k$G$O$"$j$^$;$s\e(B"
+   "\e$B@5$7$$IUB08l%U%!%$%k$G$O$"$j$^$;$s\e(B"
+   "\e$BIUB08l$N8D?t\e(B, \e$B%Y%/%?D9$5$J$I$,B?2a$.$^$9\e(B"
+   "\e$B$=$NHV9f$N<-=q$O;H$o$l$F$$$^$;$s\e(B"
+   nil
+   nil
+   nil
+   "\e$BIUB08l%U%!%$%k$NFbMF$,@5$7$/$"$j$^$;$s\e(B"
+   "\e$B5?;wIJ;lHV9f$,0[>o$G$9\e(B(hinsi.data \e$B$,@5$7$/$"$j$^$;$s\e(B)"
+   "\e$BL$Dj5A$NIJ;l$,A0C<IJ;l$H$7$FDj5A$5$l$F$$$^$9\e(B"
+   "\e$BIUB08l%U%!%$%k$,FI$_9~$^$l$F$$$^$;$s\e(B"
+   nil
+   nil
+   "\e$B<-=q$N%(%$%s%H%j$,B?2a$.$^$9\e(B"
+   "\e$BJQ49$7$h$&$H$9$kJ8;zNs$,D92a$.$^$9\e(B"
+   "\e$BIUB08l2r@ONN0h$,ITB-$7$F$$$^$9\e(B"
+   nil
+   "\e$B<!8uJdNN0h$,ITB-$7$F$$$^$9\e(B"
+   "\e$B8uJd$,\e(B 1 \e$B$D$b:n$l$^$;$s$G$7$?\e(B"
+   nil
+   nil
+   nil
+   nil
+   "\e$BFI$_$,D92a$.$^$9\e(B"
+   "\e$B4A;z$,D92a$.$^$9\e(B"
+   "\e$B;XDj$5$l$?<-=q$OEPO?2DG=$G$O$"$j$^$;$s\e(B"
+   "\e$BFI$_$ND9$5$,\e(B 0 \e$B$G$9\e(B"
+   "\e$B;XDj$5$l$?<-=q$O5U0z$-2DG=$G$O$"$j$^$;$s\e(B"
+   "\e$B%j!<%I%*%s%j!<$N<-=q$KEPO?\e(B/\e$B:o=|$7$h$&$H$7$^$7$?\e(B"
+   "\e$B4D6-$KB8:_$7$J$$<-=q$KEPO?$7$h$&$H$7$^$7$?\e(B"
+   nil
+   nil
+   "\e$B%j!<%I%*%s%j!<$NIQEY$rJQ99$7$h$&$H$7$^$7$?\e(B"
+   "\e$B;XDj$5$l$?C18l$,B8:_$7$^$;$s\e(B"
+   nil
+   nil
+   nil
+   nil
+   nil
+   nil
+   nil
+   nil
+   nil
+   "\e$B%a%b%j\e(B allocation \e$B$G<:GT$7$^$7$?\e(B"
+   nil
+   nil
+   nil
+   nil
+   nil
+   nil
+   nil
+   "\e$B2?$+$N%(%i!<$,5/$3$j$^$7$?\e(B"
+   "\e$B%P%0$,H/@8$7$F$$$kLOMM$G$9\e(B"
+   "\e$B%5!<%P$,;`$s$G$$$^$9\e(B"
+   "allocation \e$B$K<:GT$7$^$7$?\e(B"
+   "\e$B%5!<%P$H@\B3$G$-$^$;$s$G$7$?\e(B"
+   "\e$BDL?.%W%m%H%3%k$N%P!<%8%g%s$,9g$C$F$$$^$;$s\e(B"
+   "\e$B%/%i%$%"%s%H$N@8@.$7$?4D6-$G$O$"$j$^$;$s\e(B"
+   nil
+   nil
+   nil
+   nil
+   nil
+   "\e$B%G%#%l%/%H%j$r:n$k$3$H$,$G$-$^$;$s\e(B"
+   nil
+   nil
+   nil
+   nil
+   nil
+   nil
+   nil
+   nil
+   nil
+   "\e$B%U%!%$%k$rFI$_9~$`$3$H$,$G$-$^$;$s\e(B"
+   "\e$B%U%!%$%k$r=q$-=P$9$3$H$,$G$-$^$;$s\e(B"
+   "\e$B%/%i%$%"%s%H$NFI$_9~$s$@%U%!%$%k$G$O$"$j$^$;$s\e(B"
+   "\e$B$3$l0J>e%U%!%$%k$rFI$_9~$`$3$H$,$G$-$^$;$s\e(B"
+   "\e$B%Q%9%o!<%I$,4V0c$C$F$$$^$9\e(B"
+   "\e$B%U%!%$%k$,FI$_9~$^$l$F$$$^$9\e(B"
+   "\e$B%U%!%$%k$,:o=|$G$-$^$;$s\e(B"
+   "\e$B%U%!%$%k$,:n@.=PMh$^$;$s\e(B"
+   "WNN \e$B$N%U%!%$%k$G$"$j$^$;$s\e(B"
+   "\e$B%U%!%$%k$N\e(B inode \e$B$H\e(B FILE_UNIQ \e$B$r0lCW$5$;$k;v$,$G$-$^$;$s\e(B"
+   "\e$BIJ;l%U%!%$%k$,Bg$-2a$.$^$9\e(B"
+   "\e$BIJ;l%U%!%$%k$,Bg$-2a$.$^$9\e(B"
+   "\e$BIJ;l%U%!%$%k$,B8:_$7$^$;$s\e(B"
+   "\e$BIJ;l%U%!%$%k$NFbMF$,4V0c$C$F$$$^$9\e(B"
+   nil
+   "\e$BIJ;l%U%!%$%k$,FI$_9~$^$l$F$$$^$;$s\e(B"
+   "\e$BIJ;lL>$,4V0c$C$F$$$^$9\e(B"
+   "\e$BIJ;lHV9f$,4V0c$C$F$$$^$9\e(B"
+   nil
+   "\e$B$=$NA`:n$O%5%]!<%H$5$l$F$$$^$;$s\e(B"
+   "\e$B%Q%9%o!<%I$NF~$C$F$$$k%U%!%$%k$,%*!<%W%s$G$-$^$;$s\e(B"
+   "uumrc \e$B%U%!%$%k$,B8:_$7$^$;$s\e(B"
+   "uumrc \e$B%U%!%$%k$N7A<0$,8m$C$F$$$^$9\e(B"
+   "\e$B$3$l0J>e4D6-$r:n$k$3$H$O$G$-$^$;$s\e(B"
+   "\e$B$3$N%/%i%$%"%s%H$,FI$_9~$s$@%U%!%$%k$G$"$j$^$;$s\e(B"
+   "\e$B<-=q$KIQEY%U%!%$%k$,$D$$$F$$$^$;$s\e(B"
+   "\e$B%Q%9%o!<%I$N%U%!%$%k$,:n@.=PMh$^$;$s\e(B"
+]
+  "Array of WNN error messages.  Indexed by error code.")
+
+(defun wnnrpc-get-error-message (errno)
+  "Return error message string specified by ERRNO."
+  (or (aref wnnrpc-error-message errno) (format "#%d" errno)))
+
+(defmacro wnnrpc-call-with-environment (e vlist send-expr &rest receive-exprs)
+  (let ((v (append
+           `((proc (wnnenv-get-proc ,e))
+             (env-id (wnnenv-get-env-id ,e)))
+           vlist)))
+    (list
+     'let v
+     (append
+       `(save-excursion
+          (set-buffer (process-buffer proc))
+          (erase-buffer)
+          ,send-expr
+          (process-send-region proc (point-min) (point-max))
+          (goto-char (prog1 (point) (accept-process-output proc))))
+       receive-exprs))))
+
+(defsubst wnnrpc-test-result-and-get-error (proc result)
+  (if (< result 0)                     ; Get error # (XXX: Bad protocol)
+      (let (error)
+       (comm-unpack (u) error)
+       (- error))
+    result))
+\f
+(defun wnnrpc-open (proc myhostname username)
+  "Open the session.  Return 0 on success, error code on failure."
+  (comm-call-with-proc proc (result)
+    (comm-format (u u s s)
+                (wnn-const JS_OPEN)
+                (wnn-const JLIB_VERSION)
+                myhostname username)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-connect (proc envname)
+  "Establish new `connection' and make an environment.
+Return the identitifation of the environment on success, 
+negate-encoded error code on failure."
+  (comm-call-with-proc proc (result)
+    (comm-format (u s) (wnn-const JS_CONNECT) envname)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-open-file (proc env-id filename)
+  "Open the file FILENAME on the environment ENV-ID on server process PROC.
+Return file descripter on success, negate-encoded error code on failure."
+  (comm-call-with-proc proc (result)
+    (comm-format (u u s) (wnn-const JS_FILE_READ) env-id filename)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-set-fuzokugo-file (proc env-id fid)
+  "For PROC, on environment ENV-ID, 
+Set Fuzokugo file specified by FID.
+Return 0 on success, negate-encoded error code on failure."
+  (comm-call-with-proc proc (result)
+    (comm-format (u u i) (wnn-const JS_FUZOKUGO_SET) env-id fid)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-set-dictionary (proc env-id rev dic freq pri dic-mode freq-mode)
+  "Set dictionary on server.
+Return 0 on success, negate-encoded error code on faiulure."
+  (comm-call-with-proc proc (result)
+    (comm-format (u u i i i u u s s u) (wnn-const JS_DIC_ADD)
+                env-id dic freq pri
+                (if dic-mode 0 1)
+                (if freq-mode 0 1)
+                "" ""          ; XXX: No password
+                (if rev 1 0))
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-version (proc)
+  "Return the version number of WNN server."
+  (comm-call-with-proc proc (result)
+    (comm-format (u) (wnn-const JS_VERSION))
+    (comm-unpack (u) result)
+    result))
+
+(defun wnnrpc-access (proc env-id mode path) 
+  "On the server connected by PROC, check the accessibility of file in
+the environment ENV-ID.  Return 0 when the remote file
+(dictionary/frequency) of PATH can be accessed in mode MODE.  Return
+Non-zero otherwise."
+  (comm-call-with-proc proc (result)
+    (comm-format (u u u s) (wnn-const JS_ACCESS) env-id mode path)
+    (comm-unpack (u) result)
+    result))
+
+(defun wnnrpc-mkdir (proc env-id path)
+  "Create directory specified by PATH."
+  (comm-call-with-proc proc (result)
+    (comm-format (u u s) (wnn-const JS_MKDIR) env-id path)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-create-dictionary (proc env-id dicname)
+  "Create dictionary on server."
+  (comm-call-with-proc proc (result)
+    (comm-format (u u s S s s u) (wnn-const JS_DIC_FILE_CREATE)
+                env-id dicname ""      ; XXX: No comment
+                "" ""          ; XXX: No passwd
+                (wnn-const WNN_REV_DICT))
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-create-frequency (proc env-id freqname dictionary)
+  "Create frequency file on server."
+  (comm-call-with-proc proc (result)
+    (comm-format (u u u s S s) (wnn-const JS_HINDO_FILE_CREATE)
+                env-id dictionary freqname "" ; XXX: No comment
+                "")                    ; XXX: No password
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-discard-file (proc env-id fid)
+  "Discard a file specified by FID.  Call this for already-opened file
+before remove and create new file."
+  (comm-call-with-proc proc (result)
+    (comm-format (u u u) (wnn-const JS_FILE_DISCARD)
+                env-id fid)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-remove-file (proc filename)
+  "Remove the file."
+  (comm-call-with-proc proc (result)
+    (comm-format (u s s) (wnn-const JS_FILE_REMOVE) filename "") ; No passwd
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-set-conversion-parameters (proc env-id v)
+  "Set conversion parameters."
+  (comm-call-with-proc proc (result)
+    (comm-format  (u u i i i i i i i i i i i i i i i i i)
+                 (wnn-const JS_PARAM_SET)
+                 env-id
+                 (aref v  0) (aref v  1) (aref v  2) (aref v  3)
+                 (aref v  4) (aref v  5) (aref v  6) (aref v  7)
+                 (aref v  8) (aref v  9) (aref v 10) (aref v 11)
+                 (aref v 12) (aref v 13) (aref v 14) (aref v 15)
+                 (aref v 16) (aref v 17))
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defsubst wnnrpc-receive-sho-bunsetsu-list-sub (e proc number-of-sho-bunsetsu)
+  (let ((i 0)
+       slist
+       end start jiritsugo-end dic-no entry freq right-now
+       hinshi status status-backward kangovect evaluation)
+    (while (< i number-of-sho-bunsetsu)
+      (comm-unpack (u u u u u u u u u u u u)
+                  end start jiritsugo-end dic-no entry freq right-now
+                  hinshi status status-backward kangovect evaluation)
+      (setq slist
+           (cons
+            (wnn-bunsetsu-create e
+             end start jiritsugo-end dic-no entry freq right-now
+             hinshi status status-backward kangovect evaluation)
+            slist))
+      (setq i (1+ i)))
+    (reverse slist)))
+
+(defsubst wnnrpc-receive-sho-bunsetsu-list-sub-2 (proc slist)
+  (let ((l slist)
+       result origin fuzokugo b)
+    (while l
+      (setq b (car l))
+      (comm-unpack (S S S) result origin fuzokugo)
+      (wnn-bunsetsu-set-converted b result)
+      (wnn-bunsetsu-set-yomi b origin)
+      (wnn-bunsetsu-set-fuzokugo b fuzokugo)
+      (setq l (cdr l)))
+    slist))
+
+(defun wnnrpc-receive-sho-bunsetsu-list (e proc number-of-sho-bunsetsu)
+  (let ((slist (wnnrpc-receive-sho-bunsetsu-list-sub e proc
+                                                    number-of-sho-bunsetsu)))
+    (wnnrpc-receive-sho-bunsetsu-list-sub-2 proc slist)))
+
+(defun wnnrpc-renbunsetsu-conversion (e yomi hinshi fuzoku &optional v)
+  "Convert YOMI string into Kanji.
+HINSHI and FUZOKU are information of preceding bunsetsu."
+  (let (v0 v1)
+    (if v
+       (setq v0 v
+             v1 (wnn-const WNN_VECT_KANREN))
+      (setq v0 (wnn-const WNN_VECT_KANREN)
+           v1 (wnn-const WNN_VECT_NO)))
+    (wnnrpc-call-with-environment e (number-of-dai-bunsetsu kanji-length error
+                                    number-of-sho-bunsetsu dlist)
+      (comm-format (u u S i S i i i) (wnn-const JS_KANREN)
+                  env-id yomi hinshi fuzoku v0 v1
+                  (wnn-const WNN_VECT_BUNSETSU))
+      (comm-unpack (u) number-of-dai-bunsetsu)
+      (if (< number-of-dai-bunsetsu 0)
+         (let (error)
+           (comm-unpack (u) error)
+           (error "WNN Error on renbunsetsu conversion: %s"
+                  (wnnrpc-get-error-message error)))
+       (comm-unpack (u u) number-of-sho-bunsetsu kanji-length)
+       (setq dlist (cons nil nil))
+       (let ((i 0)
+             (d dlist)
+             end start count evaluation)
+         (catch 'break
+           (while t
+             (comm-unpack (u u u u) end start count evaluation)
+             (setcar d (vector end start count evaluation))
+             (if (< (setq i (1+ i)) number-of-dai-bunsetsu)
+                 (setq d (setcdr d (cons nil nil)))
+               (throw 'break nil))))
+         (cons dlist
+               (wnnrpc-receive-sho-bunsetsu-list e proc
+                                                 number-of-sho-bunsetsu)))))))
+
+(defun wnnrpc-get-bunsetsu-candidates (e yomi hinshi fuzoku &optional v)
+  ""
+  (let (v0 v1)
+    (if v
+       (setq v0 v
+             v1 (wnn-const WNN_VECT_KANZEN))
+      (setq v0 (wnn-const WNN_VECT_KANZEN)
+           v1 (wnn-const WNN_VECT_NO)))
+    (wnnrpc-call-with-environment e (number-of-sho-bunsetsu kanji-length slist)
+      (comm-format (u u S i S i i) (wnn-const JS_KANZEN_SHO)
+                    env-id yomi hinshi fuzoku v0 v1)
+      (comm-unpack (u) number-of-sho-bunsetsu)
+      (if (< number-of-sho-bunsetsu 0)
+         (let (error)
+           (comm-unpack (u) error)
+           (error "WNN Error on getting candidates: %s"
+                  (wnnrpc-get-error-message error)))
+       (comm-unpack (u) kanji-length)
+       (wnnrpc-receive-sho-bunsetsu-list e proc number-of-sho-bunsetsu)))))
+
+(defun wnnrpc-tanbunsetsu-conversion (e yomi hinshi fuzoku &optional v)
+  ""
+  (let (v0 v1)
+    (if v
+       (setq v0 v
+             v1 (wnn-const WNN_VECT_KANTAN))
+      (setq v0 (wnn-const WNN_VECT_KANTAN)
+           v1 (wnn-const WNN_VECT_NO)))
+    (wnnrpc-call-with-environment e (number-of-sho-bunsetsu kanji-length slist)
+      (comm-format (u u S i S i i) (wnn-const JS_KANTAN_SHO)
+                    env-id yomi hinshi fuzoku v0 v1)
+      (comm-unpack (u) number-of-sho-bunsetsu)
+      (if (< number-of-sho-bunsetsu 0) ; Get error # (XXX: Bad protocol)
+         (let (error)
+           (comm-unpack (u) error)
+           (error "WNN Error on tanbunsetsu conversion: %s"
+                  (wnnrpc-get-error-message error)))
+       (comm-unpack (u) kanji-length)
+       (wnnrpc-receive-sho-bunsetsu-list e proc number-of-sho-bunsetsu)))))
+
+(defun wnnrpc-set-frequency (e dicno entry ima hindo)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u i i i i) (wnn-const JS_HINDO_SET)
+                env-id dicno entry ima hindo)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-close (proc)
+  ""
+  (comm-call-with-proc proc (result)
+    (comm-format (u) (wnn-const JS_CLOSE))
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-env-exist (proc envname)
+  ""
+  (comm-call-with-proc proc (result)
+    (comm-format (u s) (wnn-const JS_ENV_EXIST) envname)
+    (comm-unpack (u) result)
+    result))
+
+(defun wnnrpc-make-env-sticky (e)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u) (wnn-const JS_ENV_STICKY) env-id)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-make-env-unsticky (e)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u) (wnn-const JS_ENV_UNSTICKY) env-id)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-disconnect (e)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u) (wnn-const JS_DISCONNECT) env-id)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-add-word (e dictionary yomi kanji comment hinshi initial-freq)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u u S S S u u) (wnn-const JS_WORD_ADD)
+                env-id
+                dictionary yomi kanji comment
+                hinshi initial-freq)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-get-dictionary-list-with-environment (e)
+  ""
+  (wnnrpc-call-with-environment e (number-of-dic)
+    (comm-format (u u) (wnn-const JS_DIC_LIST) env-id)
+    (comm-unpack (u) number-of-dic)
+    (if (< number-of-dic 0)
+       (let (error)                    ; XXX js.c is correct?
+         (comm-unpack (u) error)
+         (error "WNN Error on listing dictionaries: %s"
+                (wnnrpc-get-error-message error)))
+      (wnnrpc-receive-dictionary-list proc number-of-dic))))
+
+(defun wnnrpc-receive-dictionary-list (proc number-of-dic)
+  (let (dic-entry dic freq dic-mode freq-mode enable-flag nice
+       rev comment dicname freqname dic-passwd freq-passwd
+       type gosuu dic-local-flag freq-local-flag)
+    (if (= number-of-dic 0)
+       nil
+      (comm-unpack (u u u u u u u u S s s s s u u u u)
+                  dic-entry dic freq dic-mode freq-mode enable-flag nice
+                  rev comment dicname freqname dic-passwd freq-passwd
+                  type gosuu dic-local-flag freq-local-flag)
+      (cons 
+       (vector dic-entry dic freq dic-mode freq-mode enable-flag nice
+              rev comment dicname freqname dic-passwd freq-passwd
+              type gosuu dic-local-flag freq-local-flag)
+       (wnnrpc-receive-dictionary-list proc (1- number-of-dic))))))
+
+(defsubst wnndic-get-id (dic)
+  (aref dic 0))
+
+(defsubst wnndic-get-comment (dic)
+  (aref dic 8))
+
+(defsubst wnndic-get-dictname (dic)
+  (aref dic 9))
+
+(defun wnnrpc-get-writable-dictionary-id-list (e)
+  ""
+  (wnnrpc-call-with-environment e (number-of-dic result)
+    (comm-format (u u i) (wnn-const JS_HINSI_DICTS) env-id -1)
+    (comm-unpack (u) number-of-dic)
+    (if (> number-of-dic 0)
+       (let ((l (cons nil nil))
+             (i 0)
+             dic)
+         (setq result l)
+         (catch 'break
+           (while t
+             (comm-unpack (u) dic)
+             (setcar l dic)
+             (if (< (setq i (1+ i)) number-of-dic)
+                 (setq l (setcdr l (cons nil nil)))
+               (throw 'break nil))))
+         result)
+      (if (= number-of-dic 0)
+         nil
+       (let (error)
+         (comm-unpack (u) error)
+         (error "WNN Error on listing dictionaries: %s"
+                (wnnrpc-get-error-message error)))))))
+
+(defun wnnrpc-get-hinshi-list (e dic name)
+  ""
+  (wnnrpc-call-with-environment e (number-of-hinshi size result)
+    (comm-format (u u u S) (wnn-const JS_HINSI_LIST) env-id dic name)
+    (comm-unpack (u u) number-of-hinshi size)
+    (if (> number-of-hinshi 0)
+       (let ((l (cons nil nil))
+             (i 0)
+             hinshi)
+         (setq result l)
+         (catch 'break
+           (while t
+             (comm-unpack (S) hinshi)
+             (setcar l hinshi)
+             (if (< (setq i (1+ i)) number-of-hinshi)
+                 (setq l (setcdr l (cons nil nil)))
+               (throw 'break nil))))
+         result)
+      (if (= number-of-hinshi 0)
+         nil
+       (let (error)
+         (comm-unpack (u) error)
+         (error "WNN Error on listing HINSHI: %s"
+                (wnnrpc-get-error-message error)))))))
+
+(defun wnnrpc-hinshi-number (proc name)
+  ""
+  (comm-call-with-proc proc (result)
+    (comm-format (u S) (wnn-const JS_HINSI_NUMBER) name)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-get-conversion-parameters (e)
+  ""
+  (wnnrpc-call-with-environment e (result
+                                  n nsho p1 p2 p3 p4 p5 p6 p7 p8 p9
+                                  p10 p11 p12 p13 p14 p15)
+    (comm-format (u u) (wnn-const JS_PARAM_GET) env-id)
+    (comm-unpack (u) result)
+    (if (< result 0)
+       (let (error)
+         (comm-unpack (u) error)
+         (- error))
+      (comm-unpack  (u u u u u  u u u u u  u u u u u u u)
+                   n nsho p1 p2 p3 p4 p5 p6 p7 p8 p9
+                   p10 p11 p12 p13 p14 p15)
+      (vector n nsho p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15))))
+
+(defun wnnrpc-file-loaded (proc path)
+  ""
+  (comm-call-with-proc proc (result)
+    (comm-format (u s) (wnn-const JS_FILE_LOADED) path)
+    (comm-unpack (u) result)
+    result))
+
+(defun wnnrpc-write-file (e fid filename)
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u u s) (wnn-const JS_FILE_WRITE) env-id fid filename)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-get-fuzokugo-file (e)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u u) (wnn-const JS_FUZOKUGO_GET) env-id)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defsubst wnnrpc-receive-file-list (proc)
+  (let ((i 0)
+       flist
+       number-of-files fid local-flag ref-count type name)
+    (comm-unpack (u) number-of-files)
+    (if (< number-of-files 0)
+       (error "WNN: wnnrpc-receive-file-list")
+      (while (< i number-of-files)
+       (comm-unpack (u u u u s) fid local-flag ref-count type name)
+       (setq flist (cons (vector fid local-flag ref-count type name) flist))
+       (setq i (1+ i)))
+      flist)))
+
+(defun wnnrpc-get-file-list (proc)
+  ""
+  (comm-call-with-proc proc (result)
+    (comm-format (u) (wnn-const JS_FILE_LIST_ALL))
+    (wnnrpc-receive-file-list proc)))
+
+(defun wnnrpc-get-file-list-with-env (e)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u) (wnn-const JS_FILE_LIST) env-id)
+    (wnnrpc-receive-file-list proc)))
+
+(defun wnnrpc-file-attribute (e path)
+  "3: dictionary, 4: hindo file, 5: fuzokugo-file"
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u s) (wnn-const JS_FILE_STAT) env-id path)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-get-file-info (e fid)
+  ""
+  (wnnrpc-call-with-environment e (result name local-flag ref-count type)
+    (comm-format (u u u) (wnn-const JS_FILE_INFO) env-id fid)
+    (comm-unpack (u) result)
+    (if (< result 0)
+       (let (error)
+         (comm-unpack (u) error)
+         (- error))
+      (comm-unpack (s u u u) name local-flag ref-count type)
+      (vector name local-flag ref-count type))))
+
+(defun wnnrpc-who (proc)
+  ""
+  (comm-call-with-proc proc (number-of-entry w)
+    (comm-format (u) (wnn-const JS_WHO))
+    (comm-unpack (u) number-of-entry)
+    (if (< number-of-entry 0)
+       (let (error)
+         (comm-unpack (u) error)
+         (- error))
+      (let ((i 0)
+           sd username hostname e-array)
+       (while (< i number-of-entry)
+         (comm-unpack (u s s) sd username hostname)
+         (setq e-array (make-vector 32 nil))
+         (let ((j 0) e)
+           (while (< j (wnn-const WNN_MAX_ENV_OF_A_CLIENT))
+             (comm-unpack (u) e)
+             (aset e-array j e)
+             (setq j (1+ j))))
+         (setq w (cons (vector sd username hostname e-array) w))
+         (setq i (1+ i)))
+       (reverse w)))))
+
+(defun wnnrpc-get-env-list (proc)
+  (comm-call-with-proc proc (number-of-entry l)
+    (comm-format (u) (wnn-const JS_ENV_LIST))
+    (comm-unpack (u) number-of-entry)
+    (if (< number-of-entry 0)
+       (let (error)
+         (comm-unpack (u) error)
+         (- error))
+      (let ((i 0)
+           env-id env-name ref-count fuzokugo-fid dic-max
+           dic-array file-array)
+       (while (< i number-of-entry)
+         (comm-unpack (u s u u u) env-id env-name ref-count
+                        fuzokugo-fid dic-max)
+         (setq dic-array (make-vector 30 nil))
+         (setq file-array (make-vector 60 nil))
+         (let ((j 0) d)
+           (while (< j (wnn-const WNN_MAX_DIC_OF_AN_ENV))
+             (comm-unpack (u) d)
+             (aset dic-array j d)
+             (setq j (1+ j))))
+         (let ((j 0) f)
+           (while (< j (wnn-const WNN_MAX_FILE_OF_AN_ENV))
+             (comm-unpack (u) f)
+             (aset file-array j f)
+             (setq j (1+ j))))
+         (setq l (cons (vector env-id env-name ref-count fuzokugo-fid dic-max
+                               dic-array file-array) l))
+         (setq i (1+ i)))
+       (reverse l)))))
+
+(defun wnnrpc-kill (proc)
+  ""
+  (comm-call-with-proc proc (result)
+    (comm-format (u) (wnn-const JS_KILL))
+    (comm-unpack (u) result)
+    result))                           ; XXX: Bad protocol: error?
+
+(defun wnnrpc-delete-dictionary (e dic)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u u) (wnn-const JS_DIC_DELETE) env-id dic)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-set-flag-on-dictionary (e dic flag)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u u u) (wnn-const JS_DIC_USE) env-id dic flag)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-get-dictionary-list (proc)
+  ""
+  (comm-call-with-proc proc (number-of-dic)
+    (comm-format (u) (wnn-const JS_DIC_LIST_ALL))
+    (comm-unpack (u) number-of-dic)
+    (wnnrpc-receive-dictionary-list proc number-of-dic)))
+
+(defun wnnrpc-delete-word (e dic entry)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u u u) (wnn-const JS_WORD_DELETE) env-id dic entry)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-receive-word (proc yomi)
+  (let ((loop t)
+       dic serial hinshi hindo right-now internal-hindo internal-right-now
+       l l1 kanji comment)
+    (while loop
+      (comm-unpack (u) dic)
+      (if (< dic 0)
+         (setq loop nil)
+       (comm-unpack (u u u u u u) serial hinshi hindo right-now
+                    internal-hindo internal-right-now)
+       (setq l (cons (vector dic serial hinshi hindo right-now
+                             internal-hindo internal-right-now
+                             yomi nil nil) l) )))
+    (setq l (reverse l)
+         l1 l)
+    (while l1
+      (comm-unpack (S S) kanji comment)
+      (aset (car l1) 8 kanji)
+      (aset (car l1) 9 comment)
+      (setq l1 (cdr l1)))
+    l))
+
+(defun wnnrpc-search-word-in-dictionary (e dic yomi)
+  ""
+  (wnnrpc-call-with-environment e (c0 c1)
+    (comm-format (u u u S) (wnn-const JS_WORD_SEARCH) env-id dic yomi)
+    ;; XXX Bad protocol: error?
+    (comm-unpack (u u) c0 c1)          ; ignored
+    (wnnrpc-receive-word proc yomi)))
+
+(defun wnnrpc-search-word (e yomi)
+  ""
+  (wnnrpc-call-with-environment e (c0 c1)
+    (comm-format (u u S) (wnn-const JS_WORD_SEARCH_BY_ENV) env-id yomi)
+    ;; XXX Bad protocol: error?
+    (comm-unpack (u u) c0 c1)          ; ignored
+    (wnnrpc-receive-word proc yomi)))
+
+(defun wnnrpc-get-word-info (e dic entry)
+  ""
+  (wnnrpc-call-with-environment e (result c0 c1 yomi)
+    (comm-format (u u u u) (wnn-const JS_WORD_INFO) env-id dic entry)
+    (comm-unpack (u) result)
+    (if (< result 0)
+       (let (error)
+         (comm-unpack (u) error)
+         (- error))
+      (comm-unpack (S) yomi)           ; XXX: reversed string
+      (comm-unpack (u u) c0 c1)        ; ignored
+      (wnnrpc-receive-word proc yomi))))
+
+(defun wnnrpc-set-comment-on-word (e dic entry comment)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u u u S) (wnn-const JS_WORD_COMMENT_SET)
+                env-id dic entry comment)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-get-dictionary-info (e dic)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u u) (wnn-const JS_DIC_INFO) env-id dic)
+    (comm-unpack (u) result)
+    (if (< result 0)
+       (let (error)
+         (comm-unpack (u) error)
+         (- error))
+      (wnnrpc-receive-dictionary-list proc 1))))
+
+(defun wnnrpc-set-file-comment (e fid comment)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u u S) (wnn-const JS_FILE_COMMENT_SET) env-id fid comment)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-hinshi-name (proc hinshi)
+  ""
+  (comm-call-with-proc proc (result)
+    (comm-format (u u) (wnn-const JS_HINSI_NAME) hinshi)
+    (comm-unpack (u) result)
+    (if (< result 0)
+       (let (error)
+         (comm-unpack (u) error)
+         (- error))
+      (comm-unpack (S) result)
+      result)))
+
+;;; WHICH: 1: DIC, 2: HINDO, 3(0): Both
+(defun wnnrpc-set-file-password (e fid which old new)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u u u s s) (wnn-const JS_FILE_PASSWORD)
+                env-id fid which old new)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-set-hinshi-table (e dic hinshi-table)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u u S) (wnn-const JS_HINSI_TABLE_SET)
+                env-id dic hinshi-table)
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defsubst wnnrpc-receive-dai-bunsetsu-list (proc number-of-bunsetsu)
+  (let ((i 0)
+       slist
+       end start number-of-sho-bunsetsu evaluation v)
+    (while (< i number-of-bunsetsu)
+      (comm-unpack (u u u u)
+                  end start number-of-sho-bunsetsu evaluation)
+      (setq slist
+           (cons (vector end start number-of-sho-bunsetsu evaluation nil)
+                 slist))
+      (setq i (1+ i)))
+    (setq slist (reverse slist))
+    (let ((s slist)
+         result)
+      (while s
+       (setq v (car s))
+       (setq result (wnnrpc-receive-sho-bunsetsu-list-sub-2 proc (aref v 2)))
+       (aset v 4 result)
+       (setq s (cdr s)))
+      (setq s slist)
+      (while s
+       (setq v (car s))
+       (wnnrpc-receive-sho-bunsetsu-list-sub-2 proc (aref v 4))
+       (setq s (cdr s)))
+      slist)))
+
+(defun wnnrpc-daibunsetsu-conversion (e yomi hinshi fuzoku &optional v)
+  ""
+  (let (v0 v1)
+    (if v
+       (setq v0 v
+             v1 (wnn-const WNN_VECT_KANTAN))
+      (setq v0 (wnn-const WNN_VECT_KANTAN)
+           v1 (wnn-const WNN_VECT_NO)))
+    (wnnrpc-call-with-environment e (number-of-bunsetsu sho-size kanji-size)
+      (comm-format (u u S i S i i) (wnn-const JS_KANTAN_DAI)
+                  env-id yomi hinshi fuzoku v0 v1)
+      (comm-unpack (u) number-of-bunsetsu)
+      (if (< number-of-bunsetsu 0)     ; Get error # (XXX: Bad protocol)
+         (let (error)
+           (comm-unpack (u) error)
+           (error "WNN Error on daibunsetsu conversion: %s"
+                  (wnnrpc-get-error-message error)))
+       (comm-unpack (u u) sho-size kanji-size)
+       (wnnrpc-receive-dai-bunsetsu-list proc number-of-bunsetsu)))))
+
+(defun wnnrpc-get-daibunsetsu-candidate (e yomi hinshi fuzoku &optional v)
+  ""
+  (let (v0 v1)
+    (if v
+       (setq v0 v
+             v1 (wnn-const WNN_VECT_KANZEN))
+      (setq v0 (wnn-const WNN_VECT_KANZEN)
+           v1 (wnn-const WNN_VECT_NO)))
+    (wnnrpc-call-with-environment e (number-of-bunsetsu sho-size kanji-size)
+      (comm-format (u u S i S i i) (wnn-const JS_KANZEN_DAI)
+                  env-id yomi hinshi fuzoku v0 v1)
+      (comm-unpack (u) number-of-bunsetsu)
+      (if (< number-of-bunsetsu 0)     ; Get error # (XXX: Bad protocol)
+         (let (error)
+           (comm-unpack (u) error)
+           (error "WNN Error on daibunsetsu conversion: %s"
+                  (wnnrpc-get-error-message error)))
+       (comm-unpack (u u) sho-size kanji-size)
+       (wnnrpc-receive-dai-bunsetsu-list proc number-of-bunsetsu)))))
+\f
+;; XXX: NIY: check in the file contents
+;; 16
+(defun wnnrpc-local-file-loaded (proc path)
+  ""
+  (let ((attr (file-attributes path)))
+    (let ((time (cons (car (nth 6 attr)) (car (cdr (nth 6 attr)))))
+         (inode (nth 10 attr))
+         (dev (nth 11 attr))
+         (padded-hostname
+          (substring 
+           (concat (system-name)
+                   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") 0 16)))
+      (comm-call-with-proc proc (result)
+        (comm-format (u U U U s) (wnn-const JS_FILE_LOADED_LOCAL)
+                    time dev inode padded-hostname)
+       (comm-unpack (u) result)
+       result))))
+
+(defun wnnrpc-file-receive (e fid local-filename)
+  ""
+  (wnnrpc-call-with-environment e (filename)
+    (comm-format (u u u) (wnn-const JS_FILE_RECEIVE)
+                env-id fid)
+    (comm-unpack (s) filename)
+    (if (null local-filename)
+       (setq local-filename (substring filename
+                                       (1+ (string-match "!" filename)))))
+    (wnnrpc-file-receive-sub proc local-filename)))
+
+(defun wnnrpc-file-receive-sub (proc local-filename)
+  ;; XXX check file header
+  (let ((attr (file-attributes local-filename)))
+    (let ((time (cons (car (nth 6 attr)) (car (cdr (nth 6 attr)))))
+         (inode (nth 10 attr))
+         (dev (nth 11 attr))
+         (padded-hostname
+          (substring 
+           (concat (system-name)
+                   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") 0 16)))
+    (comm-call-with-proc-1 proc (result)
+      (comm-format (u U U U s) 0 ; ACK
+                  time dev inode padded-hostname)
+      (comm-unpack (s) result)
+      (cond ((< result 0)
+            (let (error)
+              (comm-unpack (u) error)
+              (- error)))
+           ((= result 0)
+            )          ; done
+           ((or (= result 1) (= result 3) (= result 2))
+             ;; XXX distingush creation...
+            (comm-call-with-proc-1 proc (contents result)
+              (comm-format (u) 0)      ; ACK
+              (comm-unpack (B u) contents result)
+              ;; XXX XXXXXXXXXXXXXXXXX save the contents...
+              (wnnrpc-test-result-and-get-error proc result))))))))
+
+(defun wnnrpc-file-send (e filename)
+  ""
+  (wnnrpc-call-with-environment e (result)
+    (comm-format (u u U U U s) (wnn-const JS_FILE_SEND)
+                env-id time dev inode padded-hostname)
+    (comm-unpack (u) result)
+    (if (/= result -1)
+       (progn
+         (comm-unpack (u) result)
+         (if (< result 0)
+             (let (error)
+               (comm-unpack (u) error)
+               (- error))
+           result))
+      (comm-unpack (u) result)
+      (if (< result 0)
+         (let (error)
+           (comm-unpack (u) error)
+           (- error))
+       (let ((path (concat (system-name) "!" filename)))
+         (wnnrpc-send-file-sub proc path))))))
+
+(defun wnnrpc-send-file-sub (proc path)
+  (comm-call-with-proc-1 proc (result)
+    (progn
+      (comm-format (s) path)
+      ;; XXXXXXXXXXXXXX send the contents of file...
+      (while xxx
+       (if (= c 255)
+           (comm-format (b b) 255 0)
+         (comm-format (b) c)))
+      (comm-format (b b) 255 255))
+    (comm-unpack (u) result)
+    (wnnrpc-test-result-and-get-error proc result)))
+
+(defun wnnrpc-file-remove-client ()
+)
+
+(defun wnnrpc-dic-file-create-client ()
+)
+
+(defun wnnrpc-hindo-file-create-client ()
+113
+)
+
+;;; egg/wnnrpc.el ends here.
diff --git a/euc-cn.el b/euc-cn.el
new file mode 100644 (file)
index 0000000..e001daa
--- /dev/null
+++ b/euc-cn.el
@@ -0,0 +1,449 @@
+;;; euc-cn.el --- Fixed EUC-CN handling routines.
+
+;; Copyright (C) 1997 Mule Project,
+;; Powered by Electrotechnical Laboratory, JAPAN.
+;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
+
+;; Author: KATAYAMA Yoshio <kate@pfu.co.jp>
+;; Maintainer: KATAYAMA Yoshio <kate@pfu.co.jp>
+;; Keywords: mule, multilingual, input method, chinese
+
+;; This file will be part of GNU Emacs (in future).
+
+;; GNU Emacs 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,
+;; 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.
+
+;; 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.
+
+;;; Commentary:
+
+
+;;; Code:
+
+(defvar cwnn-zhuyin nil)
+
+(defconst chinese-sisheng-leading-chars
+  (concat (char-to-string (aref (charset-info 'chinese-sisheng) 6))
+         (char-to-string (aref (charset-info 'chinese-sisheng) 7))))
+(defconst yincoding-pinyin-shengmu
+  '((""  . 0)  ("B" . 1)  ("C"  . 2)  ("Ch" . 3)  ("D" . 4)
+    ("F" . 5)  ("G" . 6)  ("H"  . 7)  ("J"  . 8)  ("K" . 9)
+    ("L" . 10) ("M" . 11) ("N"  . 12) ("P"  . 13) ("Q" . 14)
+    ("R" . 15) ("S" . 16) ("Sh" . 17) ("T"  . 18) ("W" . 19)
+    ("X" . 20) ("Y" . 21) ("Z"  . 22) ("Zh" . 23)))
+
+(defconst yincoding-pinyin-yunmu
+  '(("\e(0@\e(B"      0) ("\e(0@\e(B"      0 0) ("\e(0@\e(B"      0 1) ("\e(0@\e(B"      0 2) ("\e(0@\e(B"      0 3)
+    ("a\e(0@\e(B"     1) ("\e(0!@\e(B"     1 0) ("\e(0"@\e(B"     1 1) ("\e(0#@\e(B"     1 2) ("\e(0$@\e(B"     1 3)
+    ("ai\e(0@\e(B"    2) ("\e(0!\e(Bi\e(0@\e(B"    2 0) ("\e(0"\e(Bi\e(0@\e(B"    2 1) ("\e(0#\e(Bi\e(0@\e(B"    2 2) ("\e(0$\e(Bi\e(0@\e(B"    2 3)
+    ("an\e(0@\e(B"    3) ("\e(0!\e(Bn\e(0@\e(B"    3 0) ("\e(0"\e(Bn\e(0@\e(B"    3 1) ("\e(0#\e(Bn\e(0@\e(B"    3 2) ("\e(0$\e(Bn\e(0@\e(B"    3 3)
+    ("ang\e(0@\e(B"   4) ("\e(0!\e(Bng\e(0@\e(B"   4 0) ("\e(0"\e(Bng\e(0@\e(B"   4 1) ("\e(0#\e(Bng\e(0@\e(B"   4 2) ("\e(0$\e(Bng\e(0@\e(B"   4 3)
+    ("ao\e(0@\e(B"    5) ("\e(0!\e(Bo\e(0@\e(B"    5 0) ("\e(0"\e(Bo\e(0@\e(B"    5 1) ("\e(0#\e(Bo\e(0@\e(B"    5 2) ("\e(0$\e(Bo\e(0@\e(B"    5 3)
+    ("e\e(0@\e(B"     6) ("\e(0%@\e(B"     6 0) ("\e(0&@\e(B"     6 1) ("\e(0'@\e(B"     6 2) ("\e(0(@\e(B"     6 3)
+    ("ei\e(0@\e(B"    7) ("\e(0%\e(Bi\e(0@\e(B"    7 0) ("\e(0&\e(Bi\e(0@\e(B"    7 1) ("\e(0'\e(Bi\e(0@\e(B"    7 2) ("\e(0(\e(Bi\e(0@\e(B"    7 3)
+    ("en\e(0@\e(B"    8) ("\e(0%\e(Bn\e(0@\e(B"    8 0) ("\e(0&\e(Bn\e(0@\e(B"    8 1) ("\e(0'\e(Bn\e(0@\e(B"    8 2) ("\e(0(\e(Bn\e(0@\e(B"    8 3)
+    ("eng\e(0@\e(B"   9) ("\e(0%\e(Bng\e(0@\e(B"   9 0) ("\e(0&\e(Bng\e(0@\e(B"   9 1) ("\e(0'\e(Bng\e(0@\e(B"   9 2) ("\e(0(\e(Bng\e(0@\e(B"   9 3)
+    ("er\e(0@\e(B"   10) ("\e(0%\e(Br\e(0@\e(B"   10 0) ("\e(0&\e(Br\e(0@\e(B"   10 1) ("\e(0'\e(Br\e(0@\e(B"   10 2) ("\e(0(\e(Br\e(0@\e(B"   10 3)
+    ("i\e(0@\e(B"    11) ("\e(0)@\e(B"    11 0) ("\e(0*@\e(B"    11 1) ("\e(0+@\e(B"    11 2) ("\e(0,@\e(B"    11 3)
+    ("ia\e(0@\e(B"   12) ("i\e(0!@\e(B"   12 0) ("i\e(0"@\e(B"   12 1) ("i\e(0#@\e(B"   12 2) ("i\e(0$@\e(B"   12 3)
+    ("ian\e(0@\e(B"  13) ("i\e(0!\e(Bn\e(0@\e(B"  13 0) ("i\e(0"\e(Bn\e(0@\e(B"  13 1) ("i\e(0#\e(Bn\e(0@\e(B"  13 2) ("i\e(0$\e(Bn\e(0@\e(B"  13 3)
+    ("iang\e(0@\e(B" 14) ("i\e(0!\e(Bng\e(0@\e(B" 14 0) ("i\e(0"\e(Bng\e(0@\e(B" 14 1) ("i\e(0#\e(Bng\e(0@\e(B" 14 2) ("i\e(0$\e(Bng\e(0@\e(B" 14 3)
+    ("iao\e(0@\e(B"  15) ("i\e(0!\e(Bo\e(0@\e(B"  15 0) ("i\e(0"\e(Bo\e(0@\e(B"  15 1) ("i\e(0#\e(Bo\e(0@\e(B"  15 2) ("i\e(0$\e(Bo\e(0@\e(B"  15 3)
+    ("ie\e(0@\e(B"   16) ("i\e(0%@\e(B"   16 0) ("i\e(0&@\e(B"   16 1) ("i\e(0'@\e(B"   16 2) ("i\e(0(@\e(B"   16 3)
+    ("in\e(0@\e(B"   17) ("\e(0)\e(Bn\e(0@\e(B"   17 0) ("\e(0*\e(Bn\e(0@\e(B"   17 1) ("\e(0+\e(Bn\e(0@\e(B"   17 2) ("\e(0,\e(Bn\e(0@\e(B"   17 3)
+    ("ing\e(0@\e(B"  18) ("\e(0)\e(Bng\e(0@\e(B"  18 0) ("\e(0*\e(Bng\e(0@\e(B"  18 1) ("\e(0+\e(Bng\e(0@\e(B"  18 2) ("\e(0,\e(Bng\e(0@\e(B"  18 3)
+    ("iong\e(0@\e(B" 19) ("i\e(0-\e(Bng\e(0@\e(B" 19 0) ("i\e(0.\e(Bng\e(0@\e(B" 19 1) ("i\e(0/\e(Bng\e(0@\e(B" 19 2) ("i\e(00\e(Bng\e(0@\e(B" 19 3)
+    ("iu\e(0@\e(B"   20) ("i\e(01@\e(B"   20 0) ("i\e(02@\e(B"   20 1) ("i\e(03@\e(B"   20 2) ("i\e(04@\e(B"   20 3)
+    ("m\e(0@\e(B"    21) ("m\e(0@\e(B"    21 0) ("m\e(0@\e(B"    21 1) ("m\e(0@\e(B"    21 2) ("m\e(0@\e(B"    21 3)
+    ("n\e(0@\e(B"    22) ("n\e(0@\e(B"    22 0) ("\e(0=@\e(B"    22 1) ("\e(0>@\e(B"    22 2) ("\e(0?@\e(B"    22 3)
+    ("ng\e(0@\e(B"   23) ("ng\e(0@\e(B"   23 0) ("ng\e(0@\e(B"   23 1) ("ng\e(0@\e(B"   23 2) ("ng\e(0@\e(B"   23 3)
+    ("o\e(0@\e(B"    24) ("\e(0-@\e(B"    24 0) ("\e(0.@\e(B"    24 1) ("\e(0/@\e(B"    24 2) ("\e(00@\e(B"    24 3)
+    ("ong\e(0@\e(B"  25) ("\e(0-\e(Bng\e(0@\e(B"  25 0) ("\e(0.\e(Bng\e(0@\e(B"  25 1) ("\e(0/\e(Bng\e(0@\e(B"  25 2) ("\e(00\e(Bng\e(0@\e(B"  25 3)
+    ("ou\e(0@\e(B"   26) ("\e(0-\e(Bu\e(0@\e(B"   26 0) ("\e(0.\e(Bu\e(0@\e(B"   26 1) ("\e(0/\e(Bu\e(0@\e(B"   26 2) ("\e(00\e(Bu\e(0@\e(B"   26 3)
+    ("u\e(0@\e(B"    27) ("\e(01@\e(B"    27 0) ("\e(02@\e(B"    27 1) ("\e(03@\e(B"    27 2) ("\e(04@\e(B"    27 3)
+    ("ua\e(0@\e(B"   28) ("u\e(0!@\e(B"   28 0) ("u\e(0"@\e(B"   28 1) ("u\e(0#@\e(B"   28 2) ("u\e(0$@\e(B"   28 3)
+    ("uai\e(0@\e(B"  29) ("u\e(0!\e(Bi\e(0@\e(B"  29 0) ("u\e(0"\e(Bi\e(0@\e(B"  29 1) ("u\e(0#\e(Bi\e(0@\e(B"  29 2) ("u\e(0$\e(Bi\e(0@\e(B"  29 3)
+    ("uan\e(0@\e(B"  30) ("u\e(0!\e(Bn\e(0@\e(B"  30 0) ("u\e(0"\e(Bn\e(0@\e(B"  30 1) ("u\e(0#\e(Bn\e(0@\e(B"  30 2) ("u\e(0$\e(Bn\e(0@\e(B"  30 3)
+    ("uang\e(0@\e(B" 31) ("u\e(0!\e(Bng\e(0@\e(B" 31 0) ("u\e(0"\e(Bng\e(0@\e(B" 31 1) ("u\e(0#\e(Bng\e(0@\e(B" 31 2) ("u\e(0$\e(Bng\e(0@\e(B" 31 3)
+    ("ue\e(0@\e(B"   32) ("u\e(0%@\e(B"   32 0) ("u\e(0&@\e(B"   32 1) ("u\e(0'@\e(B"   32 2) ("u\e(0(@\e(B"   32 3)
+    ("ui\e(0@\e(B"   33) ("u\e(0)@\e(B"   33 0) ("u\e(0*@\e(B"   33 1) ("u\e(0+@\e(B"   33 2) ("u\e(0,@\e(B"   33 3)
+    ("un\e(0@\e(B"   34) ("\e(01\e(Bn\e(0@\e(B"   34 0) ("\e(02\e(Bn\e(0@\e(B"   34 1) ("\e(03\e(Bn\e(0@\e(B"   34 2) ("\e(04\e(Bn\e(0@\e(B"   34 3)
+    ("uo\e(0@\e(B"   35) ("u\e(0-@\e(B"   35 0) ("u\e(0.@\e(B"   35 1) ("u\e(0/@\e(B"   35 2) ("u\e(00@\e(B"   35 3)
+    ("\e(09@\e(B"    36) ("\e(05@\e(B"    36 0) ("\e(06@\e(B"    36 1) ("\e(07@\e(B"    36 2) ("\e(08@\e(B"    36 3)
+    ("\e(09\e(Be\e(0@\e(B"   37) ("\e(09%@\e(B"   37 0) ("\e(09&@\e(B"   37 1) ("\e(09'@\e(B"   37 2) ("\e(09(@\e(B"   37 3)
+    ("0\e(0@\e(B"    38) ("1\e(0@\e(B"    38 0) ("2\e(0@\e(B"    38 1) ("3\e(0@\e(B"    38 2) ("4\e(0@\e(B"    38 3)))
+
+(defconst yincoding-pinyin-table
+  [
+   0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
+   0 1 1 1 1 1 0 1 1 1 0 1 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1
+   0 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1
+   0 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1
+   0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 0 1 0 1 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1
+   0 1 0 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1
+   0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1
+   0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1
+   0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1
+   0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1
+   0 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 0 1 0 0 0 1 1 1 1 0 0 1 0 0 0 1 1 1 1 1
+   0 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 1 1 1 0 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1
+   0 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 0 1 0 0 0 0 1 1 1 0 0 1 0 0 0 0 1 1 1 1
+   0 1 1 1 1 1 0 1 1 1 0 1 0 1 0 1 1 1 1 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1
+   0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1
+   0 0 0 1 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 0 1 1 1 0 0 1
+   0 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1
+   0 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 1 1 1 0 0 1
+   0 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 0 1 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1
+   0 1 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1
+   0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1
+   0 1 0 1 1 1 1 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 0 0 1 0 1 0 1 0 0 0 1
+   0 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 1 1 0 0 1
+   0 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 0 1
+   ])
+
+(defconst yincoding-zhuyin-length (charset-bytes 'chinese-sisheng))
+
+(defconst yincoding-zhuyin-shengmu
+  '((""  .  0) ("\e(0E\e(B" .  1) ("\e(0X\e(B" .  2) ("\e(0T\e(B" .  3) ("\e(0I\e(B" .  4)
+    ("\e(0H\e(B" .  5) ("\e(0M\e(B" .  6) ("\e(0O\e(B" .  7) ("\e(0P\e(B" .  8) ("\e(0N\e(B" .  9)
+    ("\e(0L\e(B" . 10) ("\e(0G\e(B" . 11) ("\e(0K\e(B" . 12) ("\e(0F\e(B" . 13) ("\e(0Q\e(B" . 14)
+    ("\e(0V\e(B" . 15) ("\e(0Y\e(B" . 16) ("\e(0U\e(B" . 17) ("\e(0J\e(B" . 18) ("\e(0h\e(B" . 19)
+    ("\e(0R\e(B" . 20) ("\e(0g\e(B" . 21) ("\e(0W\e(B" . 22) ("\e(0S\e(B" . 23)))
+
+(defconst yincoding-zhuyin-yunmu
+  '(("\e(0@\e(B"    0) ("\e(0A\e(B"    0 0) ("\e(0B\e(B"    0 1) ("\e(0C\e(B"    0 2) ("\e(0D\e(B"    0 3) ; i
+    ("\e(0Z@\e(B"   1) ("\e(0ZA\e(B"   1 0) ("\e(0ZB\e(B"   1 1) ("\e(0ZC\e(B"   1 2) ("\e(0ZD\e(B"   1 3) ; a
+    ("\e(0^@\e(B"   2) ("\e(0^A\e(B"   2 0) ("\e(0^B\e(B"   2 1) ("\e(0^C\e(B"   2 2) ("\e(0^D\e(B"   2 3) ; ai
+    ("\e(0b@\e(B"   3) ("\e(0bA\e(B"   3 0) ("\e(0bB\e(B"   3 1) ("\e(0bC\e(B"   3 2) ("\e(0bD\e(B"   3 3) ; an
+    ("\e(0d@\e(B"   4) ("\e(0dA\e(B"   4 0) ("\e(0dB\e(B"   4 1) ("\e(0dC\e(B"   4 2) ("\e(0dD\e(B"   4 3) ; ang
+    ("\e(0`@\e(B"   5) ("\e(0`A\e(B"   5 0) ("\e(0`B\e(B"   5 1) ("\e(0`C\e(B"   5 2) ("\e(0`D\e(B"   5 3) ; ao
+    ("\e(0\@\e(B"   6) ("\e(0\A\e(B"   6 0) ("\e(0\B\e(B"   6 1) ("\e(0\C\e(B"   6 2) ("\e(0\D\e(B"   6 3) ; e
+    ("\e(0_@\e(B"   7) ("\e(0_A\e(B"   7 0) ("\e(0_B\e(B"   7 1) ("\e(0_C\e(B"   7 2) ("\e(0_D\e(B"   7 3) ; ei
+    ("\e(0c@\e(B"   8) ("\e(0cA\e(B"   8 0) ("\e(0cB\e(B"   8 1) ("\e(0cC\e(B"   8 2) ("\e(0cD\e(B"   8 3) ; en
+    ("\e(0e@\e(B"   9) ("\e(0eA\e(B"   9 0) ("\e(0eB\e(B"   9 1) ("\e(0eC\e(B"   9 2) ("\e(0eD\e(B"   9 3) ; eng
+    ("\e(0f@\e(B"  10) ("\e(0fA\e(B"  10 0) ("\e(0fB\e(B"  10 1) ("\e(0fC\e(B"  10 2) ("\e(0fD\e(B"  10 3) ; er
+    ("\e(0g@\e(B"  11) ("\e(0gA\e(B"  11 0) ("\e(0gB\e(B"  11 1) ("\e(0gC\e(B"  11 2) ("\e(0gD\e(B"  11 3) ; i
+    ("\e(0gZ@\e(B" 12) ("\e(0gZA\e(B" 12 0) ("\e(0gZB\e(B" 12 1) ("\e(0gZC\e(B" 12 2) ("\e(0gZD\e(B" 12 3) ; ia
+    ("\e(0gb@\e(B" 13) ("\e(0gbA\e(B" 13 0) ("\e(0gbB\e(B" 13 1) ("\e(0gbC\e(B" 13 2) ("\e(0gbD\e(B" 13 3) ; ian
+    ("\e(0gd@\e(B" 14) ("\e(0gdA\e(B" 14 0) ("\e(0gdB\e(B" 14 1) ("\e(0gdC\e(B" 14 2) ("\e(0gdD\e(B" 14 3) ; iang
+    ("\e(0g`@\e(B" 15) ("\e(0g`A\e(B" 15 0) ("\e(0g`B\e(B" 15 1) ("\e(0g`C\e(B" 15 2) ("\e(0g`D\e(B" 15 3) ; iao
+    ("\e(0g]@\e(B" 16) ("\e(0g]A\e(B" 16 0) ("\e(0g]B\e(B" 16 1) ("\e(0g]C\e(B" 16 2) ("\e(0g]D\e(B" 16 3) ; ie
+    ("\e(0gc@\e(B" 17) ("\e(0gcA\e(B" 17 0) ("\e(0gcB\e(B" 17 1) ("\e(0gcC\e(B" 17 2) ("\e(0gcD\e(B" 17 3) ; in
+    ("\e(0ge@\e(B" 18) ("\e(0geA\e(B" 18 0) ("\e(0geB\e(B" 18 1) ("\e(0geC\e(B" 18 2) ("\e(0geD\e(B" 18 3) ; ing
+    ("\e(0ie@\e(B" 19) ("\e(0ieA\e(B" 19 0) ("\e(0ieB\e(B" 19 1) ("\e(0ieC\e(B" 19 2) ("\e(0ieD\e(B" 19 3) ; iong
+    ("\e(0ga@\e(B" 20) ("\e(0gaA\e(B" 20 0) ("\e(0gaB\e(B" 20 1) ("\e(0gaC\e(B" 20 2) ("\e(0gaD\e(B" 20 3) ; iu
+    ("\e(0G@\e(B"  21) ("\e(0GA\e(B"  21 0) ("\e(0GB\e(B"  21 1) ("\e(0GC\e(B"  21 2) ("\e(0GD\e(B"  21 3) ; m
+    ("\e(0K@\e(B"  22) ("\e(0KA\e(B"  22 0) ("\e(0KB\e(B"  22 1) ("\e(0KC\e(B"  22 2) ("\e(0KD\e(B"  22 3) ; n
+    ("@\e(0@\e(B"  23) ("@\e(0A\e(B"  23 0) ("@\e(0B\e(B"  23 1) ("@\e(0C\e(B"  23 2) ("@\e(0D\e(B"  23 3) ; ng
+    ("\e(0[@\e(B"  24) ("\e(0[A\e(B"  24 0) ("\e(0[B\e(B"  24 1) ("\e(0[C\e(B"  24 2) ("\e(0[D\e(B"  24 3) ; o
+    ("\e(0he@\e(B" 25) ("\e(0heA\e(B" 25 0) ("\e(0heB\e(B" 25 1) ("\e(0heC\e(B" 25 2) ("\e(0heD\e(B" 25 3) ; ong
+    ("\e(0a@\e(B"  26) ("\e(0aA\e(B"  26 0) ("\e(0aB\e(B"  26 1) ("\e(0aC\e(B"  26 2) ("\e(0aD\e(B"  26 3) ; ou
+    ("\e(0h@\e(B"  27) ("\e(0hA\e(B"  27 0) ("\e(0hB\e(B"  27 1) ("\e(0hC\e(B"  27 2) ("\e(0hD\e(B"  27 3) ; u
+    ("\e(0hZ@\e(B" 28) ("\e(0hZA\e(B" 28 0) ("\e(0hZB\e(B" 28 1) ("\e(0hZC\e(B" 28 2) ("\e(0hZD\e(B" 28 3) ; ua
+    ("\e(0h^@\e(B" 29) ("\e(0h^A\e(B" 29 0) ("\e(0h^B\e(B" 29 1) ("\e(0h^C\e(B" 29 2) ("\e(0h^D\e(B" 29 3) ; uai
+    ("\e(0hb@\e(B" 30) ("\e(0hbA\e(B" 30 0) ("\e(0hbB\e(B" 30 1) ("\e(0hbC\e(B" 30 2) ("\e(0hbD\e(B" 30 3) ; uan
+    ("\e(0hd@\e(B" 31) ("\e(0hdA\e(B" 31 0) ("\e(0hdB\e(B" 31 1) ("\e(0hdC\e(B" 31 2) ("\e(0hdD\e(B" 31 3) ; uang
+    ("\e(0i]@\e(B" 37) ("\e(0i]A\e(B" 37 0) ("\e(0i]B\e(B" 37 1) ("\e(0i]C\e(B" 37 2) ("\e(0i]D\e(B" 37 3) ; ue
+    ("\e(0h_@\e(B" 33) ("\e(0h_A\e(B" 33 0) ("\e(0h_B\e(B" 33 1) ("\e(0h_C\e(B" 33 2) ("\e(0h_D\e(B" 33 3) ; ui
+    ("\e(0hc@\e(B" 34) ("\e(0hcA\e(B" 34 0) ("\e(0hcB\e(B" 34 1) ("\e(0hcC\e(B" 34 2) ("\e(0hcD\e(B" 34 3) ; un
+    ("\e(0h[@\e(B" 35) ("\e(0h[A\e(B" 35 0) ("\e(0h[B\e(B" 35 1) ("\e(0h[C\e(B" 35 2) ("\e(0h[D\e(B" 35 3) ; uo
+    ("\e(0i@\e(B"  36) ("\e(0iA\e(B"  36 0) ("\e(0iB\e(B"  36 1) ("\e(0iC\e(B"  36 2) ("\e(0iD\e(B"  36 3) ; \e(09\e(B
+    ("\e(0i]@\e(B" 37) ("\e(0i]A\e(B" 37 0) ("\e(0i]B\e(B" 37 1) ("\e(0i]C\e(B" 37 2) ("\e(0i]D\e(B" 37 3) ; \e(09\e(Be
+    ("0\e(0@\e(B"  38) ("1\e(0A\e(B"  38 0) ("2\e(0B\e(B"  38 1) ("3\e(0C\e(B"  38 2) ("4\e(0D\e(B"  38 3) ; undefined YunMu
+    ("\e(0ib@\e(B" 39) ("\e(0ibA\e(B" 39 0) ("\e(0ibB\e(B" 39 1) ("\e(0ibC\e(B" 39 2) ("\e(0ibD\e(B" 39 3) ; \e(09\e(Ban
+    ("\e(0ic@\e(B" 40) ("\e(0icA\e(B" 40 0) ("\e(0icB\e(B" 40 1) ("\e(0icC\e(B" 40 2) ("\e(0icD\e(B" 40 3) ; \e(09\e(Bn
+    ))
+
+(defconst yincoding-zhuyin-table
+  [
+   ;; empty ShengMu
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x9586 ?\x0000 ?\x9592 ?\x9599
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x959b ?\x95a0 ?\x0000 ?\x959e
+   ?\x95a2
+   ;; ShengMu B
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000
+   ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu C
+   ?\x828b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x0000 ?\x0280 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
+   ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu Ch
+   ?\x838b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000
+   ?\x0000 ?\x0380 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu D
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x0000
+   ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
+   ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu F
+   ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu G
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu H
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu J
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x08a4 ?\x0000 ?\x0000
+   ?\x08a7 ?\x0000 ?\x08a5 ?\x0000 ?\x08a8 ?\x0000 ?\x889b ?\x88a0 ?\x8000 ?\x889e
+   ?\x88a2
+   ;; ShengMu K
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu L
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
+   ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
+   ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu M
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
+   ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu N
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
+   ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
+   ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu P
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000
+   ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000 
+   ;; ShengMu Q
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0ea4 ?\x0000 ?\x0000
+   ?\x0ea7 ?\x0000 ?\x0ea5 ?\x0000 ?\x0ea8 ?\x0000 ?\x8e9b ?\x8ea0 ?\x8000 ?\x8e9e
+   ?\x8ea2
+   ;; ShengMu R
+   ?\x8f8b ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000
+   ?\x0000 ?\x0f80 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000
+   ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu S
+   ?\x908b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000
+   ?\x0000 ?\x1080 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
+   ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu Sh
+   ?\x918b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x0000 ?\x1180 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu T
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x8000
+   ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
+   ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu W
+   ?\x939b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000 ?\x0000 ?\x1380 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu X
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x8000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x14a4 ?\x0000 ?\x0000
+   ?\x14a7 ?\x0000 ?\x14a5 ?\x0000 ?\x14a8 ?\x0000 ?\x949b ?\x94a0 ?\x8000 ?\x949e
+   ?\x94a2
+   ;; ShengMu Y 
+   ?\x958b ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0090 ?\x0000 ?\x9591 ?\x9592
+   ?\x0000 ?\x1580 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x1588 ?\x1589 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0093 ?\x8000 ?\x00a4 ?\x0000 ?\x0000
+   ?\x00a7 ?\x0000 ?\x00a5 ?\x0000 ?\x00a8 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu Z
+   ?\x968b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x0000 ?\x1680 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000
+   ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ;; ShengMu Zh 
+   ?\x978b ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x0000 ?\x1780 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000
+   ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x8000 ?\x8000
+   ?\x8000 ?\x8000 ?\x0000 ?\x8000 ?\x8000 ?\x8000 ?\x0000 ?\x0000 ?\x8000 ?\x0000
+   ?\x0000
+   ])
+
+(defun encode-euc-cwnn-region (beg end)
+  "Encode the text in the current region to EUC-cWnn.
+Return the length of resulting text."
+  (interactive "r")
+  (let (sylend s y z (enable-multibyte-characters t))
+    (save-excursion
+      (save-restriction
+       (narrow-to-region beg end)
+       (goto-char (point-min))
+       (while (< (point) (point-max))
+         (cond
+          ((looking-at "[A-Za-z\e(0!\e(B-\e(0?\e(B]+\e(0@\e(B")
+           ;; PinYin
+           (setq sylend (match-end 0))
+           (if (and (looking-at "[B-Z]h?")
+                    (setq s (assoc (buffer-substring (match-beginning 0) (match-end 0))
+                                   yincoding-pinyin-shengmu)))
+               (setq s (cdr s) y (buffer-substring (match-end 0) sylend))
+             (setq s 0 y (buffer-substring (point) sylend)))
+           (if (and (setq y (assoc y yincoding-pinyin-yunmu))
+                    (= (aref yincoding-pinyin-table (+ (* 39 s) (nth 1 y))) 1))
+               (progn
+                 (delete-region (point) sylend)
+                 (insert (char-to-string (+ (* 2 (nth 1 y)) 32 (if (nth 2 y) 1 0)))
+                         (char-to-string (+ (* 4 (if (= s 0) 20 s)) 156 (if (nth 2 y) (nth 2 y) 0)))))
+             (encode-euc-cwnn-1-char)))
+          ((looking-at "[\e(0E\e(B-\e(0i\e(B@0-4]+[\e(0@ABCD\e(B]")
+           ;; ZhuYin
+            (setq sylend (match-end 0))
+            (if (setq y (assoc (buffer-substring (point) sylend) yincoding-zhuyin-yunmu))
+                (setq s 0)
+              (if (setq s (assoc (char-to-string (following-char)) yincoding-zhuyin-shengmu))
+                  (setq s (cdr s) y (buffer-substring (+ (point) yincoding-zhuyin-length) sylend))
+                (setq s 0 y (buffer-substring (point) sylend)))
+              (setq y (assoc y yincoding-zhuyin-yunmu)))
+           (if (and y
+                    (/= (logand (setq z (aref yincoding-zhuyin-table (+ (* 41 s) (nth 1 y)))) ?\x8000) 0))
+               (progn
+                 (delete-region (point) sylend)
+                 (if (/= (logand z ?\x80) 0)
+                     (setq s (logand (lsh z -8) 127) y (list nil (logand z 127) (nth 2 y))))
+                 (insert (+ (* 2 (nth 1 y)) 32 (if (nth 2 y) 1 0))
+                         (+ (* 4 (if (= s 0) 20 s)) 156 (if (nth 2 y) (nth 2 y) 0))))
+             (encode-euc-cwnn-1-char)))
+          (t (encode-euc-cwnn-1-char))))
+       (- (point-max) (point-min))))))
+
+(defun encode-euc-cwnn-1-char ()
+  (let ((enable-multibyte-characters nil))
+    (cond
+     ((eq (following-char) (charset-id 'chinese-gb2312))
+      (delete-char 1)
+      (forward-char 2))
+     ((looking-at chinese-sisheng-leading-chars)
+      (delete-region (match-beginning 0) (match-end 0))
+      (insert 0)
+      (forward-char))
+     (t
+      (insert 0)
+      (forward-char)))))
+
+(defun pre-write-encode-euc-cwnn (from to)
+  (let ((buf (current-buffer))
+       (work (get-buffer-create " *pre-write-encoding-work*")))
+    (set-buffer work)
+    (erase-buffer)
+    (if (stringp from)
+       (insert from)
+      (insert-buffer-substring buf from to))
+    (encode-euc-cwnn-region 1 (point-max))
+    nil))
+
+(defun decode-euc-cwnn-region (beg end)
+  "Decode EUC-cWnn encoded text in the current region.
+Return the length of resulting text."
+  (interactive "r")
+  (prog1
+      (let (c cc s y ss (enable-multibyte-characters nil))
+       (save-restriction
+         (narrow-to-region beg end)
+         (goto-char (point-min))
+         (while (< (point) (point-max))
+           (setq c (following-char))
+           (cond
+            ((eq c 0)
+             (delete-char 1)
+             (if (>= (following-char) 128)
+                 (insert chinese-sisheng-leading-chars))
+             (forward-char))
+            ((>= c 128)
+             (insert (charset-id 'chinese-gb2312))
+             (forward-char 2)
+             (if (< (setq c (preceding-char)) 128)
+                 (progn
+                   (delete-char -1)
+                   (insert (+ c 128))
+                   (forward-char))))
+            (t
+             (delete-char 1)
+             (setq cc (logand (following-char) 127))
+             (delete-char 1)
+             (setq s (+ (lsh (- cc 32) -2) 1)
+                   y (lsh (- c 32) -1)
+                   ss (+ (logand c 1) (logand cc 3)))
+             (if cwnn-zhuyin
+                  (progn
+                   (setq c (aref yincoding-zhuyin-table (+ (* 41 s) y)))
+                    (if (eq (logand c ?\x8080) ?\x80)
+                        (setq s (lsh c -8)
+                              y (logand c 127)))
+                    (if (and (eq s 20)
+                             (eq (aref yincoding-pinyin-table (+ (* 39 s) y)) 0))
+                        (setq s 0))
+                    (insert (car (nth s yincoding-zhuyin-shengmu))
+                            (car (nth (+ (* 5 y) ss) yincoding-zhuyin-yunmu))))
+                (if (and (eq s 20)
+                         (eq (aref yincoding-pinyin-table (+ (* 39 s) y)) 0))
+                    (setq s 0))
+               (insert (car (nth s yincoding-pinyin-shengmu))
+                       (car (nth (+ (* 5 y) ss) yincoding-pinyin-yunmu)))))))
+         (- (point-max) (point-min))))
+    (if (looking-at "\0\0") (forward-char 2))))
+
+(defun post-read-decode-euc-cwnn (len)
+  (let ((pos (point))
+       (buffer-modified-p (buffer-modified-p)))
+    (prog1
+       (decode-euc-cwnn-region pos (+ pos len))
+      (set-buffer-modified-p buffer-modified-p))))
+
+(make-coding-system 'fixed-euc-cn 5 ?W "Coding System for fixed EUC Japanese")
+(put 'fixed-euc-cn 'post-read-conversion 'post-read-decode-euc-cwnn)
+(put 'fixed-euc-cn 'pre-write-conversion 'pre-write-encode-euc-cwnn)
+
+;;; euc-cn.el ends here.
diff --git a/its.el b/its.el
new file mode 100644 (file)
index 0000000..6a19430
--- /dev/null
+++ b/its.el
@@ -0,0 +1,789 @@
+;;; its.el --- Input Translation Systam AKA "ITS(uDekirunDa!)"
+
+;; Copyright (C) 1997 Mule Project, Powered by Electrotechnical
+;; Laboratory, JAPAN.
+;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
+
+;; Author: NIIBE Yutaka <gniibe@mri.co.jp>
+;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
+;; Keywords: mule, multilingual, input method
+
+;; This file will be part of GNU Emacs (in future).
+
+;; GNU Emacs 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,
+;; 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.
+
+;; 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.
+
+;;; Commentary:
+
+;;; Code:
+
+;; Data structure in ITS
+;; (1) SYL and CURSOR
+;;
+;; "SYL" stands for something like a syllable.
+;;
+;; <SYL> ::= ( <output> . ( <keyseq> . <terminal> ))   ; Determined:   DSYL
+;;        |  <state>                            ; Intermediate: ISYL
+;;        |  ( <output> . <point> )             ; Verbatim:     VSYL
+;;        |  nil                                ; None
+;;
+;; ;<state> ::=
+;; ;          ( <output> . ( <keyseq> . <key-state-table/terminal> ))
+;;
+;; <keyseq> ::= "string" of key sequence
+;; <output> ::= "string"
+;;
+;; <point> ::= integer which specifies point
+;;
+;; <cursor> ::= nil        ; Previous SYL is active (input will go that SYL)
+;;           |  t          ; input makes new SYL.  DEL deletes previous SYL
+;;           |  its-cursor ; DEL breaks previous SYL, input makes new SYL
+
+;; Data structures in ITS
+;; (2) State machine which recognizes SYL
+;;
+;; <state> ::= ( <output> <keyseq> . <key-state-table/terminal> )
+;;
+;; <key-state-table/terminal> ::= <key-state-table> ; intermediate state
+;;                             |  <terminal>        ; terminal state
+;;
+;; <key-state-table> ::= ( <key-state-alist> . <expr-output-back-list> )
+;; <key-state-alist> ::= ( <key-state> ... )
+;; <key-state> ::= ( <key> . <state> )
+;; <key> ::= Positive INTEGER which specifies KEY STROKE
+;;        |  -1 ; means END of key stroke
+;;
+;; Only applicable for last transition.
+;; <expr-output-back-list> ::= ( (<output> . (<keyexpr> . <howmanyback>))... )
+;; <keyexpr> ::= something like "[a-z]" which specifies class of key.
+;;            |  NIL; means ANY of key (except END of the key stroke)
+;;
+;;
+;; <keyseq> ::= "string"
+;;
+;; <terminal> ::= nil
+;;             |  <howmanyback>
+;;
+;; <howmanyback> ::= integer which specifies how many key strokes we go back
+;;
+;; <output> ::= "string"
+
+;; Data structure in ITS (3) Map
+;;
+;; <map>         ::= ( <name> . ( <indicator> . <start-state> ) )
+;; <start-state> ::= <state>
+;; <name>        ::= "string"
+;; <indicator>   ::= "string"
+;;
+\f
+(defsubst its-new-state (output keyseq back)
+  (cons output (cons keyseq back)))
+
+(defsubst its-new-map (name indicator)
+  (cons name (cons indicator (its-new-state "" "" nil))))
+
+(defsubst its-get-indicator (map)
+  (car (cdr map)))
+
+(defsubst its-set-indicator (map indicator)
+  (setcar (cdr map) indicator))
+
+(defsubst its-get-start-state (map)
+  (cdr (cdr map)))
+
+(defsubst its-reset-start-state (map)
+  (setcdr (cdr map) (its-new-state "" "" nil))
+  map)
+
+(defsubst its-get-kst/t (state)
+  (cdr (cdr state)))
+
+(defsubst its-set-kst (state kst)
+  (setcdr (cdr state) kst))
+
+(defsubst its-get-keyseq (state)
+  (car (cdr state)))
+
+(defsubst its-set-keyseq (state keyseq)
+  (setcar (cdr state) keyseq))
+(defun its-get-keyseq-cooked (state)
+  (let ((keyseq (its-get-keyseq state))
+       (back (its-get-kst/t state)))
+    (if back
+       (substring keyseq 0 back)
+      keyseq)))
+
+(defsubst its-kst-p (kst/t)
+  (not (or (numberp kst/t) (null kst/t))))
+
+(defsubst its-get-output (syl/state)
+  (car syl/state))
+
+(defsubst its-set-output (state output)
+  (setcar state output))
+
+(defsubst its-get-keyseq-syl (syl)
+  (let ((l (cdr syl)))
+    (cond ((stringp l)                 ; DSYL
+          l)
+         ((numberp l)                  ; VSYL
+          (car syl))
+         (t
+          (car (cdr syl))))))
+
+(defsubst its-eob-keyexpr (eob)
+  (car (cdr eob)))
+(defsubst its-eob-back (eob)
+  (cdr (cdr eob)))
+
+(defsubst its-make-class+back (class back)
+  (cons class back))
+(defsubst its-make-otherwise (output class+back)
+  (cons output class+back))
+;;
+;;
+
+(defvar its-mode-map
+  (let ((map (make-sparse-keymap))
+       (i 33))
+    (define-key map "\C-a" 'its-beginning-of-input-buffer)
+    (define-key map "\C-b" 'its-backward-SYL)
+    (define-key map "\C-d" 'its-delete-SYL)
+    (define-key map "\C-e" 'its-end-of-input-buffer)
+    (define-key map "\C-f" 'its-forward-SYL)
+    (define-key map "\C-]" 'its-cancel-input)
+    (define-key map "\C-h" 'its-mode-help-command)
+    (define-key map "\C-k" 'its-kill-line)
+;;    (define-key map "\C-l" 'its-exit-mode)
+    (define-key map "\C-m" 'its-exit-mode)     ; RET
+    (define-key map [return] 'its-exit-mode)
+    (define-key map "\C-t" 'its-transpose-chars)
+    (define-key map [delete] 'its-delete-backward-SYL)
+    (define-key map [right] 'its-forward-SYL)
+    (define-key map [left] 'its-backward-SYL)
+    (define-key map "\C-\\" 'its-exit-mode-off-input-method)
+    (while (< i 127)
+      (define-key map (vector i) 'its-self-insert-char)
+      (setq i (1+ i)))
+    (define-key map " "    'its-kick-convert-region)
+    (define-key map "\177" 'its-delete-backward-SYL)
+    ;;
+    (define-key map "\C-p" 'its-previous-map)
+    (define-key map "\C-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-\C-h" 'its-select-hiragana)
+;   (define-key map "\M-\C-k" 'its-select-katakana)
+;;;    (define-key map "\M-q"    'its-select-downcase) ; 
+;   (define-key map "\M-Q"    'its-select-upcase)
+;   (define-key map "\M-z"    'its-select-zenkaku-downcase)
+;   (define-key map "\M-Z"    'its-select-zenkaku-upcase)
+    map)
+  "Keymap for ITS mode.")
+
+(defvar its-fence-open   "|" "*\e$B%U%'%s%9$N;OE@$r<($9J8;zNs\e(B (1 \e$BJ8;z\e(B)")
+(defvar its-fence-close  "|" "*\e$B%U%'%s%9$N=*E@$r<($9J8;zNs\e(B (1 \e$BJ8;z\e(B)")
+(defvar its-fence-face nil  "*\e$B%U%'%s%9I=<($KMQ$$$k\e(B face \e$B$^$?$O\e(B nil")
+
+(defun its-put-cursor (cursor)
+  (let ((p (point)))
+    (insert "!")
+    (add-text-properties p (point) (list 'local-map its-mode-map
+                                        'invisible t
+                                        'intangible 'its-part-2
+                                        'its-cursor cursor))
+    (goto-char p)))
+;;
+;;  +-- START property
+;;  |          --- CURSOR Property
+;;  |         /
+;;  v        v    v-- END Property
+;;  |SYL SYL ^ SYL|
+;;   ^^^ ^^^   ^^^------ SYL Property
+;;  <-------><---->
+;; intangible intangible
+;;     1       2
+;;
+(defun its-start (key)
+  (let (p cursor)
+    (setq p (point))
+    (insert its-fence-open)
+    (add-text-properties p (point) 
+                        (let ((props '(its-start t intangible its-part-1)))
+                          (if its-fence-face
+                              (append '(invisible t) props)
+                            props)))
+    (setq p (point))
+    (setq cursor (its-input nil key))
+    (its-put-cursor cursor)
+    (forward-char 1)
+    (setq p (point))
+    (insert its-fence-close)
+    (add-text-properties p (point) 
+                        (let ((props '(its-end t intangible its-part-2)))
+                          (if its-fence-face
+                              (append '(invisible t) props)
+                            props)))
+    (forward-char -2)
+    (force-mode-line-update)))
+
+(defun its-self-insert-char ()
+  (interactive)
+  (let ((key last-command-char)
+       (cursor (get-text-property (point) 'its-cursor))
+       (syl nil))
+    (if (null cursor)
+       (setq syl (get-text-property (1- (point)) 'its-syl)))
+    ;; delete cursor
+    (delete-region (point) (1+ (point)))
+    (setq cursor (its-input syl key))
+    (its-put-cursor cursor)))
+
+(defvar its-current-map nil)
+(make-variable-buffer-local 'its-current-map)
+(put 'its-current-map 'permanent-local t)
+
+(defun its-initial-ISYL ()
+  (its-get-start-state its-current-map))
+
+(defun its-make-VSYL (keyseq)
+  (cons keyseq (length keyseq)))
+
+;; Return CURSOR
+(defun its-input (syl key)
+  (if (null syl)
+      (setq syl (its-initial-ISYL)))
+  (let ((output (car syl))
+       (k/kk/s (cdr syl)))
+    (if (numberp k/kk/s)
+       ;; k/kk/s is "point in keyseq"
+       (its-input-to-vsyl syl key k/kk/s output)
+      ;; It's ISYL
+      (its-state-machine syl key 'its-buffer-ins/del-SYL))))
+
+(defun its-input-to-vsyl (syl key point output)
+  (if (< key 0)
+      t
+    (let ((len (length output)))
+      (if (= len point)
+         ;; point is at end of VSYL.  Don't need to call state machine.
+         (progn
+           (its-buffer-ins/del-SYL
+            (its-make-VSYL (concat output (vector key))) syl)
+           nil)
+       ;; point is at middle of VSYL.
+       (let ((new-keyseq (concat (substring output 0 point)
+                                 (vector key)
+                                 (substring output point))))
+         (its-state-machine-keyseq new-keyseq 'its-buffer-ins/del-SYL))))))
+
+(defvar its-barf-on-invalid-keyseq nil
+  "T means don't allow invalid key sequence in input buffer.")
+\f
+;;;
+;;; ITS State Machine
+;;;
+
+;; Return CURSOR
+(defun its-state-machine (state key emit)
+  (let ((next-state (its-get-next-state state key))
+       expr-output-back)
+    (if next-state
+       (let ((kst/t (its-get-kst/t next-state)))
+         (funcall emit next-state state)
+         (if (not (its-kst-p kst/t))
+             ;; Here we arrive to a terminal state.
+             ;; Emit a DSYL, and go ahead.
+             (let ((output (its-get-output next-state))
+                   (keyseq (its-get-keyseq next-state))
+                   (back kst/t))
+               (if back
+                   ;; It's negative integer which specifies how many
+                   ;; characters we go backwards
+                   (its-state-machine-keyseq (substring keyseq back)
+                                             emit (< key 0))
+                 'its-cursor))
+           ;; Still, it's a intermediate state.
+           nil))
+      (if (and (>= key 0)
+              (setq expr-output-back (its-get-otherwise state key)))
+         (let ((keyseq (concat (its-get-keyseq state) (char-to-string key))))
+           (funcall emit expr-output-back state)
+           (its-state-machine-keyseq
+            (substring keyseq (its-eob-back expr-output-back)) emit))
+       ;; No next state for KEY.  It's invalid sequence.
+       (if (< key 0)           ; no next state for END of keystroke
+           ;; ISYL --> DSYL   XXX
+           (if its-barf-on-invalid-keyseq
+               (error its-barf-on-invalid-keyseq)
+             (funcall emit (cons (car state)
+                                 (list (its-get-keyseq state))) state)
+             t)
+         (if its-barf-on-invalid-keyseq
+             (error its-barf-on-invalid-keyseq)
+           ;; XXX Should make DSYL (instead of VSYL)?
+           (let ((keyseq (concat (its-get-keyseq state) (vector key))))
+             (funcall emit (its-make-VSYL keyseq) state)
+             nil)))))))
+
+(defvar its-latest-SYL nil
+  "The latest SYL inserted.")
+(defsubst its-update-latest-SYL (syl)
+  (setq its-latest-SYL syl))
+
+;; Return CURSOR
+(defun its-state-machine-keyseq (keyseq emit &optional eol)
+  (let ((i 0)
+       (len (length keyseq))
+       (its-barf-on-invalid-keyseq nil) ; temporally disable DING
+       (syl (its-initial-ISYL))
+       cursor)
+    (while (< i len)
+      (let ((key (aref keyseq i)))
+       (setq cursor 
+             (if (numberp (cdr syl))           ; VSYL
+                 (progn
+                   (funcall emit
+                            (its-make-VSYL (concat (car syl) (vector key)))
+                            syl)
+                   nil)
+               (its-state-machine syl key emit)))
+       (setq i (1+ i))
+       (if cursor
+           (setq syl (its-initial-ISYL))
+         (setq syl its-latest-SYL))))
+    (if eol
+       (its-state-machine syl -1 emit)
+      cursor)))
+
+(defun its-buffer-ins/del-SYL (newsyl oldsyl)
+  (its-buffer-delete-SYL oldsyl)
+  (its-update-latest-SYL newsyl)
+  (let ((p (point)))
+    (insert (its-get-output newsyl))
+    (add-text-properties p (point)
+                        (list 'its-syl newsyl
+                              'intangible 'its-part-1))
+    (if its-fence-face
+       (put-text-property p (point) 'face its-fence-face))))
+
+(defun its-buffer-delete-SYL (syl)
+  (let ((len (length (its-get-output syl))))
+    (delete-region (- (point) len) (point))))
+
+(defun its-get-next-state (state key)
+  (let ((kst/t (its-get-kst/t state)))
+    (cdr (assq key (car kst/t)))))
+
+;; XXX XXX XXX
+(defun its-otherwise-match (expr key)
+  (or (null expr)                      ; <expr>::= NIL means "ANY"
+      (let ((case-fold-search nil))
+       (string-match expr (char-to-string key)))))
+
+(defun its-get-otherwise (state key)
+  (let* ((kst/t (its-get-kst/t state))
+        (ebl (cdr kst/t))
+        expr-output-back)
+      (while ebl
+       (setq expr-output-back (car ebl))
+       (let ((expr (its-eob-keyexpr expr-output-back)))
+         (if (its-otherwise-match expr key)
+             (setq ebl nil)
+           (setq ebl (cdr ebl)))))
+      expr-output-back))
+\f
+;;;
+;;; Name --> map
+;;;
+;;; ITS name: string
+
+(defvar its-map-alist nil)
+
+(defun its-get-map (name)
+  (assoc name its-map-alist))
+
+(defun its-register-map (map)
+  (let* ((name (car map))
+        (place (assoc name its-map-alist)))
+    (if place
+       (setcdr place (cdr map))
+      (setq its-map-alist (cons map its-map-alist)))
+    map))
+
+(defun its-define-state-machine (name indicator &optional continue)
+  "NAME \e$B$G;XDj$5$l$?\e(B State Machine \e$B$NDj5A$r3+;O$9$k!#\e(B
+INDICATOR \e$B$O\e(B mode line \e$B$KI=<($9$k\e(B indicator \e$B$r;XDj$9$k!#\e(B
+CONTINUE \e$B$,\e(B nil \e$B$N;~$K$O\e(B State Machine \e$B$NDj5A$r6u$K$9$k!#\e(Bits-defrule 
+\e$B$r;2>H!#\e(B"
+  (setq its-current-map
+       (if (null (its-get-map name))
+           (its-register-map (its-new-map name indicator))
+         (let ((map (its-get-map name)))
+           (its-set-indicator map indicator)
+           (if continue
+               map
+             (its-reset-start-state map))))))
+
+(defmacro define-its-state-machine (map name indicator doc &rest exprs)
+  `(let ((its-current-map (its-new-map ,name ,indicator)))
+     ,(cons 'progn exprs)
+     (defconst ,map its-current-map ,doc)))
+
+;;(defmacro define-its-state-machine (map name indicator doc &rest exprs)
+;;  (let ((its-current-map (its-new-map name indicator)))
+;;    (eval (cons 'progn exprs))
+;;    `(defconst ,map ',its-current-map ,doc)))
+
+(defmacro define-its-state-machine-append (map &rest exprs)
+  (append
+   `(let ((its-current-map ,map)))
+   exprs
+   (list `(setq ,map its-current-map))))
+
+;;
+;; Construct State Machine
+;;
+(defun its-defrule (input output &optional back enable-overwrite)
+  "\e$BF~NO\e(B INPUT \e$B$rG'<1$7\e(B, OUTPUT \e$B$r=PNO$9$k$h$&$K%9%F!<%H%^%7%s$r9=@.$9$k!#\e(B
+BACK \e$B$,\e(B(\e$BIi$N\e(B)\e$B@0?t$N;~$O\e(B, OUTPUT \e$B$r=PNO$7$?8e\e(B, BACK \e$B$NJ,\e(B key stroke \e$B$r\e(B
+\e$BLa$C$FF0$/$b$N$H$9$k!#JQ495,B'$O$b$C$H$b:G6a$K\e(B its-define-state-machine
+\e$B$5$l$?JQ49I=$KEPO?$5$l$k!#\e(B
+Return last state."
+  (let ((state (its-goto-state (substring input 0 -1) nil t))
+       (key (aref input (1- (length input)))))
+    (if (and (its-get-next-state state key) (not enable-overwrite))
+       (error "Duplicated definition (%s)" input)
+      (its-make-next-state state key input output back))))
+
+(defun its-goto-state (input &optional initial-state build-if-none)
+  (let ((len (length input))
+       (i 0)
+       (state (or initial-state (its-get-start-state its-current-map))))
+    (while (< i len)
+      (setq state
+           (or (its-get-next-state state (aref input i))
+               (if build-if-none
+                   (let ((keyseq (substring input 0 (1+ i))))
+                     (its-make-next-state state (aref input i) keyseq keyseq))
+                  (error "No such state (%s)" input)))
+           i (1+ i)))
+    state))
+
+(defun its-defoutput (input display)
+  (let ((state (its-goto-state input)))
+    (its-set-output state display)))
+
+(defun its-define-otherwise (state otherwise)
+  (let ((kst (its-get-kst/t state)))
+    (if kst
+       (setcdr kst (cons otherwise (cdr kst)))
+      (its-set-kst state (cons nil (cons otherwise nil))))))
+
+(defconst its-otherwise-back-one
+  (its-make-class+back nil -1))
+
+(defun its-defrule-otherwise (state output &optional class back)
+  (let (class+back)
+    (if (null back)
+       (setq class+back its-otherwise-back-one)
+      (setq class+back (its-make-class+back class back)))
+    (its-define-otherwise state
+                         (its-make-otherwise output class+back))))
+
+(defun its-defrule* (input output)
+  (let ((state (its-defrule input output)))
+    (its-defrule-otherwise state output)))
+
+(defun its-make-next-state (state key keyseq output &optional back)
+  (let ((next-state (its-new-state output keyseq back))
+       (kst (its-get-kst/t state)))
+    (if kst
+       (setcar kst (cons (cons key next-state) (car kst)))
+      (its-set-kst state (list (list (cons key next-state)))))
+    next-state))
+\f
+;;;
+(defun its-beginning-of-input-buffer ()
+  (interactive)
+  (its-input-end)
+  (if (not (get-text-property (1- (point)) 'its-start))
+      (let ((begpos (previous-single-property-change (point) 'its-start)))
+       ;; Make SYLs have property of "part 2"
+       (put-text-property begpos (point) 'intangible 'its-part-2)
+       (goto-char begpos)
+       (its-put-cursor t))))
+
+(defun its-end-of-input-buffer ()
+  (interactive)
+  (its-input-end)
+  (if (not (get-text-property (point) 'its-end))
+      (let ((endpos (next-single-property-change (point) 'its-end)))
+       ;; Make SYLs have property of "part 1"
+       (put-text-property (point) endpos 'intangible 'its-part-1)
+       (goto-char endpos)
+       (its-put-cursor t))))
+
+;; TODO: move in VSYL
+(defun its-backward-SYL (n)
+  (interactive "p")
+  (its-input-end)
+  (let ((syl (get-text-property (1- (point)) 'its-syl))
+       (p (point))
+       (old-point (point)))
+    (while (and syl (> n 0))
+      (setq p (- p (length (its-get-output syl))))
+      (setq syl (get-text-property (1- p) 'its-syl))
+      (setq n (1- n)))
+    ;; Make SYLs have property of "part 2"
+    (put-text-property p old-point 'intangible 'its-part-2)
+    (goto-char p)
+    (its-put-cursor t)
+    (if (> n 0)
+       (signal 'beginning-of-buffer nil))))
+
+;; TODO: move in VSYL
+(defun its-forward-SYL (n)
+  (interactive "p")
+  (its-input-end)
+  (let ((syl (get-text-property (point) 'its-syl))
+       (p (point))
+       (old-point (point)))
+    (while (and syl (> n 0))
+      (setq p (+ p (length (its-get-output syl))))
+      (setq syl (get-text-property p 'its-syl))
+      (setq n (1- n)))
+    ;; Make SYLs have property of "part 1"
+    (put-text-property p old-point'intangible 'its-part-1)
+    (goto-char p)
+    (its-put-cursor t)
+    (if (> n 0)
+       (signal 'end-of-buffer nil))))
+
+;; TODO: handle VSYL.  KILLFLAG
+(defun its-delete-SYL (n killflag)
+  (interactive "p\nP")
+  (its-input-end)
+  (let ((syl (get-text-property (point) 'its-syl))
+       (p (point)))
+    (while (and syl (> n 0))
+      (setq p (+ p (length (its-get-output syl))))
+      (setq syl (get-text-property p 'its-syl))
+      (setq n (1- n)))
+    (if (> n 0)
+       (progn
+         (its-put-cursor t)
+         (signal 'args-out-of-range (list p n)))
+      (delete-region (point) p)
+      ;; Check if empty
+      (let ((s (get-text-property (1- (point)) 'its-start))
+           (e (get-text-property (point) 'its-end)))
+       (if (and s e)
+           (its-exit-mode-internal)
+         (its-put-cursor t))))))
+
+;; TODO: killflag
+(defun its-delete-backward-SYL (n killflag)
+  (interactive "p\nP")
+  (let ((syl (get-text-property (1- (point)) 'its-syl))
+       (cursor (get-text-property (point) 'its-cursor)))
+    (if (null syl)
+       (signal 'beginning-of-buffer nil)
+      (if (eq cursor t)
+         (its-delete-backward-SYL-internal n killflag)
+       (its-delete-backward-within-SYL syl n killflag)))))
+
+;; TODO: killflag
+(defun its-delete-backward-SYL-internal (n killflag)
+  (let ((syl (get-text-property (1- (point)) 'its-syl))
+       (p (point)))
+    (while (and syl (> n 0))
+      (setq p (- p (length (its-get-output syl))))
+      (setq syl (get-text-property (1- p) 'its-syl))
+      (setq n (1- n)))
+    (if (> n 0)
+       (signal 'args-out-of-range (list p n))
+      (delete-region p (1+ (point)))   ; also delete cursor
+      ;; Check if empty
+      (let ((s (get-text-property (1- (point)) 'its-start))
+           (e (get-text-property (point) 'its-end)))
+       (if (and s e)
+           (its-exit-mode-internal)
+         (its-put-cursor t))))))
+
+(defvar its-delete-by-keystroke nil)
+
+;; TODO: killflag
+(defun its-delete-backward-within-SYL (syl n killflag)
+  (let* ((keyseq (its-get-keyseq-syl syl))
+        (len (length keyseq))
+        (p (point)))
+    (if (> n len)
+       (signal 'args-out-of-range (list p n)))
+    ;; Delete CURSOR
+    (delete-region p (1+ p))
+    (its-buffer-delete-SYL syl)
+    (if (= n len)
+       ;; Check if empty
+       (let ((s (get-text-property (1- (point)) 'its-start))
+             (e (get-text-property (point) 'its-end)))
+         (if (and s e)
+             (its-exit-mode-internal)
+           (its-put-cursor (not its-delete-by-keystroke))))
+      (setq keyseq (substring keyseq 0 (- len n)))
+      (let ((r (its-state-machine-keyseq keyseq 'its-buffer-ins/del-SYL)))
+       (its-put-cursor r)))))
+
+;; XXX: NIY
+(defun its-transpose-chars (n)
+  (interactive)
+  (let ((syl (get-text-property (1- (point)) 'its-syl))
+       (cursor (get-text-property (point) 'its-cursor)))
+    (if (null syl)
+       (signal 'beginning-of-buffer nil)
+      (if (eq cursor t)
+         (its-delete-backward-SYL-internal n nil)
+       (its-delete-backward-within-SYL syl 2 nil)))))
+
+;; Return VOID
+(defun its-input-end ()
+  (let ((cursor (get-text-property (point) 'its-cursor)))
+    ;; key "END"
+    (if (null cursor)
+       (its-input (get-text-property (1- (point)) 'its-syl) -1))
+    (delete-region (point) (1+ (point)))))
+
+(defun its-exit-mode ()
+  "Exit ITS mode."
+  (interactive)
+  (its-input-end)
+  (its-exit-mode-internal))
+
+(defun its-exit-mode-off-input-method ()
+  "Exit ITS mode."
+  (interactive)
+  (its-input-end)
+  (its-exit-mode-internal)
+  (inactivate-input-method))
+
+;; TODO: handle overwrite-mode, insertion-hook, fill...
+(defun its-exit-mode-internal (&optional proceed-to-conversion)
+  (let (start end)
+    ;; Delete open fence
+    (if (get-text-property (1- (point)) 'its-start)
+       (setq start (1- (point)))
+      (setq start (1- (previous-single-property-change (point) 'its-start))))
+    (delete-region start (1+ start))
+    ;; Delete close fence
+    (if (get-text-property (point) 'its-end)
+       (setq end (point))
+      (setq end (next-single-property-change (point) 'its-end)))
+    (delete-region end (1+ end))
+    ;; Remove all properties added by ITS
+    (remove-text-properties start end '(its-syl nil
+                                       face nil
+                                       intangible nil))
+    (if proceed-to-conversion
+       (egg-convert-region start end)
+      (egg-do-auto-fill)
+      (run-hooks 'input-method-after-insert-chunk-hook))))
+
+(defun its-kick-convert-region ()
+  (interactive)
+  (its-input-end)
+  (its-exit-mode-internal t))
+\f
+(defvar its-translation-result nil "")
+
+(defun its-ins/del-SYL-batch (newsyl oldsyl)
+  (its-update-latest-SYL newsyl)
+  (if (and newsyl
+          (consp (cdr newsyl))
+          (not (its-kst-p (its-get-kst/t newsyl))))
+      ;; DSYL
+      (setq its-translation-result
+           (cons (its-get-output newsyl) its-translation-result))))
+
+(defun its-translate-region (start end &optional map)
+  (interactive "r")
+  (setq its-translation-result nil)
+  (goto-char start)
+  (let ((i 0)
+       (syl (its-initial-ISYL))
+       ;; temporally enable DING
+       (its-barf-on-invalid-keyseq "Invalid Romaji Sequence")
+       cursor)
+    (while (< (point) end)
+      (let ((key (following-char)))
+       (setq cursor (its-state-machine syl key 'its-ins/del-SYL-batch))
+       (forward-char 1)
+       (if cursor
+           (setq syl (its-initial-ISYL))
+         (setq syl its-latest-SYL))))
+    (if (eq syl its-latest-SYL)
+       (its-state-machine syl -1 'its-ins/del-SYL-batch))
+    (delete-region start end)
+    (apply 'insert (reverse its-translation-result))))
+\f
+(defvar its-select-map-menu '(menu "Map:" nil))
+
+(defun its-select-map-from-menu ()
+  (interactive)
+  (setcar (nthcdr 2 its-select-map-menu) its-map-alist)
+  (setq its-current-map (menudiag-select its-select-map-menu))
+  (force-mode-line-update))
+
+(defun its-select-hiragana ()
+  (interactive)
+  (its-select-map "roma-kana"))
+
+(defun its-select-katakana ()
+  (interactive)
+  (its-select-map "roma-kata"))
+
+(defun its-select-downcase ()
+  (interactive)
+  (its-select-map "downcase"))
+
+(defun its-select-upcase ()
+  (interactive)
+  (its-select-map "upcase"))
+
+(defun its-select-zenkaku-downcase ()
+  (interactive)
+  (its-select-map "zenkaku-downcase"))
+
+(defun its-select-zenkaku-upcase ()
+  (interactive)
+  (its-select-map "zenkaku-upcase"))
+
+(defun its-select-map (name)
+  (interactive (list (completing-read "ITS map: " its-map-alist)))
+  (if (its-get-map name)
+      (progn
+       (setq its-current-map (its-get-map name))
+       (force-mode-line-update))
+    (ding)))
+\f
+;; Escape character to Zenkaku inputs
+(defconst its-zenkaku-escape "Z")
+
+;; Escape character to Hankaku inputs
+(defconst its-hankaku-escape "~")
+
+(provide 'its)
+;;; its.el ends here.
diff --git a/its/hira.el b/its/hira.el
new file mode 100644 (file)
index 0000000..617ee50
--- /dev/null
@@ -0,0 +1,485 @@
+;;; its/hira.el --- Hiragana Input in Egg Input Method Architecture
+
+;; Copyright (C) 1997 Mule Project,
+;; Powered by Electrotechnical Laboratory, JAPAN.
+;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
+
+;; Author: Satoru Tomura <tomura@etl.go.jp>
+;;         jiro@math.keio.ac.jp (TANAKA Jiro)
+
+;; This file will be part of GNU Emacs (in future).
+
+;; GNU Emacs 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,
+;; 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.
+
+;; 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.
+
+;;; Commentary:
+;;
+;; Symbol input is desined by jiro@math.keio.ac.jp (TANAKA Jiro)
+;; This file is based on the rules of its/hira.el in Mule-2.3 distribution.
+;;
+
+;;; Code:
+
+(eval-when-compile
+  (require 'its)
+  (require 'cl))
+
+(defvar its-hira-enable-double-n nil "*Enable \"nn\" input for \"\e$B$s\e(B\" ")
+(defvar its-hira-enable-zenkaku-alphabet t "*Enable Zenkaku alphabet")
+(defvar its-hira-period "\e$B!#\e(B" "*\e$B%T%j%*%I\e(B")  ; ". " "\e$B!%\e(B"
+(defvar its-hira-comma  "\e$B!"\e(B" "*\e$B%3%s%^\e(B")    ; ", " "\e$B!$\e(B"
+(defvar its-hira-open-bracket  "\e$B!V\e(B" "*[")  ; "\e$B!N\e(B"
+(defvar its-hira-close-bracket  "\e$B!W\e(B" "*]") ; "\e$B!O\e(B"
+(defvar its-hira-horizontal  "\e$B!<\e(B" "*-")    ; "\e$B!]\e(B"
+
+(define-its-state-machine its-hira-map
+  "roma-kana" "\e$B$"\e(B"
+  "Map for Romaji-Hiragana translation. (Japanese)"
+;;; k      k
+;;; kk     \e$B$C\e(Bk
+;;; kka    \e$B$C$+\e(B
+;;;
+;;; kkk    \e$B$C\e(Bk DING!
+
+  (its-defrule "tch"  "\e$B$C\e(B" -2)
+
+;;; \e$B!V$s!W$NF~NO\e(B
+
+  (dolist (q1 '("b" "m" "p"))
+    (its-defrule (concat "m" q1) "\e$B$s\e(B" -1))
+
+  (its-defrule "N" "\e$B$s\e(B")
+
+  (let ((state (its-goto-state "n" nil t)))
+    (its-make-next-state state -1 "n" "\e$B$s\e(B")
+    (its-make-next-state state ?' "n" "\e$B$s\e(B")
+    (its-defrule-otherwise state "\e$B$s\e(B"))
+
+  (let ((small '"x" ))
+    (its-defrule (concat small "a") "\e$B$!\e(B")
+    (its-defrule (concat small "i") "\e$B$#\e(B")
+    (its-defrule (concat small "u") "\e$B$%\e(B")
+    (its-defrule (concat small "e") "\e$B$'\e(B")
+    (its-defrule (concat small "o") "\e$B$)\e(B")
+    (its-defrule (concat small "ya") "\e$B$c\e(B")
+    (its-defrule (concat small "yu") "\e$B$e\e(B")
+    (its-defrule (concat small "yo") "\e$B$g\e(B")
+    (its-defrule (concat small "tu") "\e$B$C\e(B")
+    (its-defrule (concat small "tsu") "\e$B$C\e(B")
+    (its-defrule (concat small "wa") "\e$B$n\e(B")
+    )
+
+  (its-defrule   "a"    "\e$B$"\e(B")
+  (its-defrule   "i"    "\e$B$$\e(B")
+  (its-defrule   "u"    "\e$B$&\e(B")
+  (its-defrule   "e"    "\e$B$(\e(B")
+  (its-defrule   "o"    "\e$B$*\e(B")
+
+  (dolist (k '(("ka"  "\e$B$+\e(B") ("ki"  "\e$B$-\e(B") ("ku"  "\e$B$/\e(B") ("ke"  "\e$B$1\e(B") ("ko"  "\e$B$3\e(B")
+              ("kya" "\e$B$-$c\e(B") ("kyu"  "\e$B$-$e\e(B") ("kye"  "\e$B$-$'\e(B") ("kyo"  "\e$B$-$g\e(B")))
+    (its-defrule (car k) (cadr k))
+    (its-defrule (concat "k" (car k)) (concat "\e$B$C\e(B" (cadr k))))
+  (its-defoutput "kk" "\e$B$C\e(Bk")
+  (its-defoutput "kky" "\e$B$C\e(Bky")
+
+  (dolist (s '(("sa"  "\e$B$5\e(B") ("si"  "\e$B$7\e(B") ("su"  "\e$B$9\e(B") ("se"  "\e$B$;\e(B") ("so"  "\e$B$=\e(B")
+              ("sya"  "\e$B$7$c\e(B") ("syu"  "\e$B$7$e\e(B") ("sye"  "\e$B$7$'\e(B") ("syo"  "\e$B$7$g\e(B")
+              ("sha"  "\e$B$7$c\e(B") ("shi"  "\e$B$7\e(B") ("shu"  "\e$B$7$e\e(B") ("she"  "\e$B$7$'\e(B")
+              ("sho"  "\e$B$7$g\e(B")))
+    (its-defrule (car s) (cadr s))
+    (its-defrule (concat "s" (car s)) (concat "\e$B$C\e(B" (cadr s))))
+  (its-defoutput "ss" "\e$B$C\e(Bs")
+  (its-defoutput "ssy" "\e$B$C\e(Bsy")
+  (its-defoutput "ssh" "\e$B$C\e(Bsh")
+
+  (dolist (T '(("ta"  "\e$B$?\e(B") ("ti"  "\e$B$A\e(B") ("tu"  "\e$B$D\e(B") ("te"  "\e$B$F\e(B") ("to"  "\e$B$H\e(B")
+              ("tya"  "\e$B$A$c\e(B") ("tyi"  "\e$B$F$#\e(B") ("tyu"  "\e$B$A$e\e(B") ("tye"  "\e$B$A$'\e(B")
+              ("tyo"  "\e$B$A$g\e(B") ("tsu"  "\e$B$D\e(B")))
+    (its-defrule (car T) (cadr T))
+    (its-defrule (concat "t" (car T)) (concat "\e$B$C\e(B" (cadr T))))
+  (its-defoutput "tt" "\e$B$C\e(Bt")
+  (its-defoutput "tty" "\e$B$C\e(Bty")
+  (its-defoutput "tts" "\e$B$C\e(Bts")
+
+  (dolist (c '(("cha"  "\e$B$A$c\e(B") ("chi"  "\e$B$A\e(B") ("chu"  "\e$B$A$e\e(B")
+              ("che"  "\e$B$A$'\e(B") ("cho"  "\e$B$A$g\e(B")))
+    (its-defrule (car c) (cadr c))
+    (its-defrule (concat "c" (car c)) (concat "\e$B$C\e(B" (cadr c))))
+  (its-defoutput "cc" "\e$B$C\e(Bc")
+  (its-defoutput "cch" "\e$B$C\e(Bch")
+
+  (dolist (h '(("ha"  "\e$B$O\e(B") ("hi"  "\e$B$R\e(B") ("hu"  "\e$B$U\e(B") ("he"  "\e$B$X\e(B") ("ho"  "\e$B$[\e(B")
+              ("hya"  "\e$B$R$c\e(B") ("hyu"  "\e$B$R$e\e(B") ("hye"  "\e$B$R$'\e(B") ("hyo"  "\e$B$R$g\e(B")))
+    (its-defrule (car h) (cadr h))
+    (its-defrule (concat "h" (car h)) (concat "\e$B$C\e(B" (cadr h))))
+  (its-defoutput "hh" "\e$B$C\e(Bh")
+  (its-defoutput "hhy" "\e$B$C\e(Bhy")
+
+  (dolist (f '(("fa"  "\e$B$U$!\e(B") ("fi"  "\e$B$U$#\e(B") ("fu"  "\e$B$U\e(B") ("fe"  "\e$B$U$'\e(B")
+              ("fo"  "\e$B$U$)\e(B")))
+    (its-defrule (car f) (cadr f))
+    (its-defrule (concat "f" (car f)) (concat "\e$B$C\e(B" (cadr f))))
+  (its-defoutput "ff" "\e$B$C\e(Bf")
+
+  (dolist (r '(("ra"  "\e$B$i\e(B") ("ri"  "\e$B$j\e(B") ("ru"  "\e$B$k\e(B") ("re"  "\e$B$l\e(B") ("ro"  "\e$B$m\e(B")
+              ("rya"  "\e$B$j$c\e(B") ("ryu"  "\e$B$j$e\e(B") ("rye"  "\e$B$j$'\e(B") ("ryo"  "\e$B$j$g\e(B")))
+    (its-defrule (car r) (cadr r))
+    (its-defrule (concat "r" (car r)) (concat "\e$B$C\e(B" (cadr r))))
+  (its-defoutput "rr" "\e$B$C\e(Br")
+  (its-defoutput "rry" "\e$B$C\e(Bry")
+
+  (dolist (l '(("la"  "\e$B$i\e(B") ("li"  "\e$B$j\e(B") ("lu"  "\e$B$k\e(B") ("le"  "\e$B$l\e(B") ("lo"  "\e$B$m\e(B")
+              ("lya"  "\e$B$j$c\e(B") ("lyu"  "\e$B$j$e\e(B") ("lye"  "\e$B$j$'\e(B") ("lyo"  "\e$B$j$g\e(B")))
+    (its-defrule (car l) (cadr l))
+    (its-defrule (concat "l" (car l)) (concat "\e$B$C\e(B" (cadr l))))
+  (its-defoutput "ll" "\e$B$C\e(Bl")
+  (its-defoutput "lly" "\e$B$C\e(Bly")
+
+  (dolist (g '(("ga"  "\e$B$,\e(B") ("gi"  "\e$B$.\e(B") ("gu"  "\e$B$0\e(B") ("ge"  "\e$B$2\e(B") ("go"  "\e$B$4\e(B")
+              ("gya"  "\e$B$.$c\e(B") ("gyu"  "\e$B$.$e\e(B") ("gye"  "\e$B$.$'\e(B") ("gyo"  "\e$B$.$g\e(B")))
+    (its-defrule (car g) (cadr g))
+    (its-defrule (concat "g" (car g)) (concat "\e$B$C\e(B" (cadr g))))
+  (its-defoutput "gg" "\e$B$C\e(Bg")
+  (its-defoutput "ggy" "\e$B$C\e(Bgy")
+
+  (dolist (z '(("za"  "\e$B$6\e(B") ("zi"  "\e$B$8\e(B") ("zu"  "\e$B$:\e(B") ("ze"  "\e$B$<\e(B") ("zo"  "\e$B$>\e(B")
+              ("zya"  "\e$B$8$c\e(B") ("zyu"  "\e$B$8$e\e(B") ("zye"  "\e$B$8$'\e(B") ("zyo"  "\e$B$8$g\e(B")))
+    (its-defrule (car z) (cadr z))
+    (its-defrule (concat "z" (car z)) (concat "\e$B$C\e(B" (cadr z))))
+  (its-defoutput "zz" "\e$B$C\e(Bz")
+  (its-defoutput "zzy" "\e$B$C\e(Bzy")
+
+  (dolist (j '(("ja"  "\e$B$8$c\e(B") ("ji"  "\e$B$8\e(B") ("ju"  "\e$B$8$e\e(B") ("je"  "\e$B$8$'\e(B")
+              ("jo"  "\e$B$8$g\e(B") ("jya"  "\e$B$8$c\e(B") ("jyu"  "\e$B$8$e\e(B") ("jye"  "\e$B$8$'\e(B")
+              ("jyo"  "\e$B$8$g\e(B")))
+    (its-defrule (car j) (cadr j))
+    (its-defrule (concat "j" (car j)) (concat "\e$B$C\e(B" (cadr j))))
+  (its-defoutput "jj" "\e$B$C\e(Bj")
+  (its-defoutput "jjy" "\e$B$C\e(Bjy")
+
+  (dolist (d '(("da"  "\e$B$@\e(B") ("di"  "\e$B$B\e(B") ("du"  "\e$B$E\e(B") ("de"  "\e$B$G\e(B") ("do"  "\e$B$I\e(B")
+              ("dya"  "\e$B$B$c\e(B") ("dyi"  "\e$B$G$#\e(B") ("dyu"  "\e$B$B$e\e(B") ("dye"  "\e$B$B$'\e(B")
+              ("dyo"  "\e$B$B$g\e(B")))
+    (its-defrule (car d) (cadr d))
+    (its-defrule (concat "d" (car d)) (concat "\e$B$C\e(B" (cadr d))))
+  (its-defoutput "dd" "\e$B$C\e(Bd")
+  (its-defoutput "ddy" "\e$B$C\e(Bdy")
+
+  (dolist (b '(("ba"  "\e$B$P\e(B") ("bi"  "\e$B$S\e(B") ("bu"  "\e$B$V\e(B") ("be"  "\e$B$Y\e(B") ("bo"  "\e$B$\\e(B")
+              ("bya"  "\e$B$S$c\e(B") ("byu"  "\e$B$S$e\e(B") ("bye"  "\e$B$S$'\e(B") ("byo"  "\e$B$S$g\e(B")))
+    (its-defrule (car b) (cadr b))
+    (its-defrule (concat "b" (car b)) (concat "\e$B$C\e(B" (cadr b))))
+  (its-defoutput "bb" "\e$B$C\e(Bb")
+  (its-defoutput "bby" "\e$B$C\e(Bby")
+
+  (dolist (p '(("pa"  "\e$B$Q\e(B") ("pi"  "\e$B$T\e(B") ("pu"  "\e$B$W\e(B") ("pe"  "\e$B$Z\e(B") ("po"   "\e$B$]\e(B")
+              ("pya"  "\e$B$T$c\e(B") ("pyu"  "\e$B$T$e\e(B") ("pye"  "\e$B$T$'\e(B") ("pyo"  "\e$B$T$g\e(B")))
+    (its-defrule (car p) (cadr p))
+    (its-defrule (concat "p" (car p)) (concat "\e$B$C\e(B" (cadr p))))
+  (its-defoutput "pp" "\e$B$C\e(Bp")
+  (its-defoutput "ppy" "\e$B$C\e(Bpy")
+
+  (dolist (v '(("va" "\e$B%t$!\e(B") ("vi" "\e$B%t$#\e(B") ("vu" "\e$B%t\e(B") ("ve" "\e$B%t$'\e(B")
+              ("vo" "\e$B%t$)\e(B")))
+    (its-defrule (car v) (cadr v))
+    (its-defrule (concat "v" (car v)) (concat "\e$B$C\e(B" (cadr v))))
+  (its-defoutput "vv" "\e$B$C\e(Bv")
+
+  (its-defrule   "ma"   "\e$B$^\e(B")
+  (its-defrule   "mi"   "\e$B$_\e(B")
+  (its-defrule   "mu"   "\e$B$`\e(B")
+  (its-defrule   "me"   "\e$B$a\e(B")
+  (its-defrule   "mo"   "\e$B$b\e(B")
+  (its-defrule   "mya"  "\e$B$_$c\e(B")
+  (its-defrule   "myu"  "\e$B$_$e\e(B")
+  (its-defrule   "mye"  "\e$B$_$'\e(B")
+  (its-defrule   "myo"  "\e$B$_$g\e(B")
+  (its-defrule   "ya"   "\e$B$d\e(B")
+  (its-defrule   "yi"   "\e$B$$\e(B")
+  (its-defrule   "yu"   "\e$B$f\e(B")
+  (its-defrule   "yo"   "\e$B$h\e(B")
+  (its-defrule   "ye"   "\e$B$$$'\e(B")
+  (its-defrule   "wa"   "\e$B$o\e(B")
+  (its-defrule   "wi"   "\e$B$p\e(B")
+  (its-defrule   "wu"   "\e$B$&\e(B")
+  (its-defrule   "we"   "\e$B$q\e(B")
+  (its-defrule   "wo"   "\e$B$r\e(B")
+
+  (its-defrule   "kwa"  "\e$B$/$n\e(B")
+  (its-defrule   "kwi"  "\e$B$/$#\e(B")
+  (its-defrule   "kwu"  "\e$B$/\e(B")
+  (its-defrule   "kwe"  "\e$B$/$'\e(B")
+  (its-defrule   "kwo"  "\e$B$/$)\e(B")
+  (its-defrule   "gwa"  "\e$B$0$n\e(B")
+  (its-defrule   "gwi"  "\e$B$0$#\e(B")
+  (its-defrule   "gwu"  "\e$B$0\e(B")
+  (its-defrule   "gwe"  "\e$B$0$'\e(B")
+  (its-defrule   "gwo"  "\e$B$0$)\e(B")
+  (its-defrule   "tsa"  "\e$B$D$!\e(B")
+  (its-defrule   "tsi"  "\e$B$D$#\e(B")
+  (its-defrule   "tse"  "\e$B$D$'\e(B")
+  (its-defrule   "tso"  "\e$B$D$)\e(B")
+
+  (its-defrule   "na"   "\e$B$J\e(B")
+  (its-defrule   "ni"   "\e$B$K\e(B")
+  (its-defrule   "nu"   "\e$B$L\e(B")
+  (its-defrule   "ne"   "\e$B$M\e(B")
+  (its-defrule   "no"   "\e$B$N\e(B")
+  (its-defrule   "nya"  "\e$B$K$c\e(B")
+  (its-defrule   "nyu"  "\e$B$K$e\e(B")
+  (its-defrule   "nye"  "\e$B$K$'\e(B")
+  (its-defrule   "nyo"  "\e$B$K$g\e(B")
+
+  (its-defrule   "xka"  "\e$B%u\e(B")
+  (its-defrule   "xke"  "\e$B%v\e(B")
+  (its-defrule   "xti"  "\e$B$F$#\e(B")
+  (its-defrule   "xdi"  "\e$B$G$#\e(B")
+  (its-defrule   "xdu"  "\e$B$I$%\e(B")
+  (its-defrule   "xde"  "\e$B$G$'\e(B")
+  (its-defrule   "xdo"  "\e$B$I$)\e(B")
+  (its-defrule   "xwi"  "\e$B$&$#\e(B")
+  (its-defrule   "xwe"  "\e$B$&$'\e(B")
+  (its-defrule   "xwo"  "\e$B$&$)\e(B")
+
+;;;
+;;; Zenkaku inputs
+;;;
+
+  (its-defrule (concat its-zenkaku-escape "0") "\e$B#0\e(B")
+  (its-defrule (concat its-zenkaku-escape "1") "\e$B#1\e(B")
+  (its-defrule (concat its-zenkaku-escape "2") "\e$B#2\e(B")
+  (its-defrule (concat its-zenkaku-escape "3") "\e$B#3\e(B")
+  (its-defrule (concat its-zenkaku-escape "4") "\e$B#4\e(B")
+  (its-defrule (concat its-zenkaku-escape "5") "\e$B#5\e(B")
+  (its-defrule (concat its-zenkaku-escape "6") "\e$B#6\e(B")
+  (its-defrule (concat its-zenkaku-escape "7") "\e$B#7\e(B")
+  (its-defrule (concat its-zenkaku-escape "8") "\e$B#8\e(B")
+  (its-defrule (concat its-zenkaku-escape "9") "\e$B#9\e(B")
+
+  (its-defrule (concat its-zenkaku-escape "A") "\e$B#A\e(B")
+  (its-defrule (concat its-zenkaku-escape "B") "\e$B#B\e(B")
+  (its-defrule (concat its-zenkaku-escape "C") "\e$B#C\e(B")
+  (its-defrule (concat its-zenkaku-escape "D") "\e$B#D\e(B")
+  (its-defrule (concat its-zenkaku-escape "E") "\e$B#E\e(B")
+  (its-defrule (concat its-zenkaku-escape "F") "\e$B#F\e(B")
+  (its-defrule (concat its-zenkaku-escape "G") "\e$B#G\e(B")
+  (its-defrule (concat its-zenkaku-escape "H") "\e$B#H\e(B")
+  (its-defrule (concat its-zenkaku-escape "I") "\e$B#I\e(B")
+  (its-defrule (concat its-zenkaku-escape "J") "\e$B#J\e(B")
+  (its-defrule (concat its-zenkaku-escape "K") "\e$B#K\e(B")
+  (its-defrule (concat its-zenkaku-escape "L") "\e$B#L\e(B")
+  (its-defrule (concat its-zenkaku-escape "M") "\e$B#M\e(B")
+  (its-defrule (concat its-zenkaku-escape "N") "\e$B#N\e(B")
+  (its-defrule (concat its-zenkaku-escape "O") "\e$B#O\e(B")
+  (its-defrule (concat its-zenkaku-escape "P") "\e$B#P\e(B")
+  (its-defrule (concat its-zenkaku-escape "Q") "\e$B#Q\e(B")
+  (its-defrule (concat its-zenkaku-escape "R") "\e$B#R\e(B")
+  (its-defrule (concat its-zenkaku-escape "S") "\e$B#S\e(B")
+  (its-defrule (concat its-zenkaku-escape "T") "\e$B#T\e(B")
+  (its-defrule (concat its-zenkaku-escape "U") "\e$B#U\e(B")
+  (its-defrule (concat its-zenkaku-escape "V") "\e$B#V\e(B")
+  (its-defrule (concat its-zenkaku-escape "W") "\e$B#W\e(B")
+  (its-defrule (concat its-zenkaku-escape "X") "\e$B#X\e(B")
+  (its-defrule (concat its-zenkaku-escape "Y") "\e$B#Y\e(B")
+  (its-defrule (concat its-zenkaku-escape "Z") "\e$B#Z\e(B")
+
+  (its-defrule (concat its-zenkaku-escape "a") "\e$B#a\e(B")
+  (its-defrule (concat its-zenkaku-escape "b") "\e$B#b\e(B")
+  (its-defrule (concat its-zenkaku-escape "c") "\e$B#c\e(B")
+  (its-defrule (concat its-zenkaku-escape "d") "\e$B#d\e(B")
+  (its-defrule (concat its-zenkaku-escape "e") "\e$B#e\e(B")
+  (its-defrule (concat its-zenkaku-escape "f") "\e$B#f\e(B")
+  (its-defrule (concat its-zenkaku-escape "g") "\e$B#g\e(B")
+  (its-defrule (concat its-zenkaku-escape "h") "\e$B#h\e(B")
+  (its-defrule (concat its-zenkaku-escape "i") "\e$B#i\e(B")
+  (its-defrule (concat its-zenkaku-escape "j") "\e$B#j\e(B")
+  (its-defrule (concat its-zenkaku-escape "k") "\e$B#k\e(B")
+  (its-defrule (concat its-zenkaku-escape "l") "\e$B#l\e(B")
+  (its-defrule (concat its-zenkaku-escape "m") "\e$B#m\e(B")
+  (its-defrule (concat its-zenkaku-escape "n") "\e$B#n\e(B")
+  (its-defrule (concat its-zenkaku-escape "o") "\e$B#o\e(B")
+  (its-defrule (concat its-zenkaku-escape "p") "\e$B#p\e(B")
+  (its-defrule (concat its-zenkaku-escape "q") "\e$B#q\e(B")
+  (its-defrule (concat its-zenkaku-escape "r") "\e$B#r\e(B")
+  (its-defrule (concat its-zenkaku-escape "s") "\e$B#s\e(B")
+  (its-defrule (concat its-zenkaku-escape "t") "\e$B#t\e(B")
+  (its-defrule (concat its-zenkaku-escape "u") "\e$B#u\e(B")
+  (its-defrule (concat its-zenkaku-escape "v") "\e$B#v\e(B")
+  (its-defrule (concat its-zenkaku-escape "w") "\e$B#w\e(B")
+  (its-defrule (concat its-zenkaku-escape "x") "\e$B#x\e(B")
+  (its-defrule (concat its-zenkaku-escape "y") "\e$B#y\e(B")
+  (its-defrule (concat its-zenkaku-escape "z") "\e$B#z\e(B")
+
+  (its-defrule (concat its-zenkaku-escape " ")  "\e$B!!\e(B")
+  (its-defrule (concat its-zenkaku-escape "!")  "\e$B!*\e(B")
+  (its-defrule (concat its-zenkaku-escape "@")  "\e$B!w\e(B")
+  (its-defrule (concat its-zenkaku-escape "#")  "\e$B!t\e(B")
+  (its-defrule (concat its-zenkaku-escape "$")  "\e$B!p\e(B")
+  (its-defrule (concat its-zenkaku-escape "%")  "\e$B!s\e(B")
+  (its-defrule (concat its-zenkaku-escape "^")  "\e$B!0\e(B")
+  (its-defrule (concat its-zenkaku-escape "&")  "\e$B!u\e(B")
+  (its-defrule (concat its-zenkaku-escape "*")  "\e$B!v\e(B")
+  (its-defrule (concat its-zenkaku-escape "(")  "\e$B!J\e(B")
+  (its-defrule (concat its-zenkaku-escape ")")  "\e$B!K\e(B")
+  (its-defrule (concat its-zenkaku-escape "-")  "\e$B!]\e(B")
+  (its-defrule (concat its-zenkaku-escape "=")  "\e$B!a\e(B")
+  (its-defrule (concat its-zenkaku-escape "`")  "\e$B!.\e(B")
+  (its-defrule (concat its-zenkaku-escape "\\") "\e$B!o\e(B")
+  (its-defrule (concat its-zenkaku-escape "|")  "\e$B!C\e(B")
+  (its-defrule (concat its-zenkaku-escape "_")  "\e$B!2\e(B")
+  (its-defrule (concat its-zenkaku-escape "+")  "\e$B!\\e(B")
+  (its-defrule (concat its-zenkaku-escape "~")  "\e$B!1\e(B")
+  (its-defrule (concat its-zenkaku-escape "[")  "\e$B!N\e(B")
+  (its-defrule (concat its-zenkaku-escape "]")  "\e$B!O\e(B")
+  (its-defrule (concat its-zenkaku-escape "{")  "\e$B!P\e(B")
+  (its-defrule (concat its-zenkaku-escape "}")  "\e$B!Q\e(B")
+  (its-defrule (concat its-zenkaku-escape ":")  "\e$B!'\e(B")
+  (its-defrule (concat its-zenkaku-escape ";")  "\e$B!(\e(B")
+  (its-defrule (concat its-zenkaku-escape "\"") "\e$B!I\e(B")
+  (its-defrule (concat its-zenkaku-escape "'")  "\e$B!G\e(B")
+  (its-defrule (concat its-zenkaku-escape "<")  "\e$B!c\e(B")
+  (its-defrule (concat its-zenkaku-escape ">")  "\e$B!d\e(B")
+  (its-defrule (concat its-zenkaku-escape "?")  "\e$B!)\e(B")
+  (its-defrule (concat its-zenkaku-escape "/")  "\e$B!?\e(B")
+  (its-defrule (concat its-zenkaku-escape ",")  "\e$B!$\e(B")
+  (its-defrule (concat its-zenkaku-escape ".")  "\e$B!%\e(B")
+
+;;;
+;;; Hankaku inputs
+;;;
+
+  (dolist (digit '( "1"  "2"  "3"  "4" "5"  "6"  "7"  "8"  "9"  "0" ))
+    (its-defrule (concat its-hankaku-escape digit)  digit))
+
+  (dolist (symbol '( " "  "!"  "@"  "#"  "$"  "%"  "^"  "&"  "*"  "("  ")"
+                    "-"  "="  "`"  "\\" "|"  "_"  "+"  "~" "["  "]"  "{"  "}"
+                    ":"  ";"  "\"" "'"  "<"  ">"  "?"  "/"  ","  "." ))
+    (its-defrule (concat its-hankaku-escape symbol) symbol))
+
+  (dolist (downcase '("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n"
+                     "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"))
+    (its-defrule (concat its-hankaku-escape downcase) downcase))
+
+  (dolist (upcase    '("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N"
+                      "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"))
+    (its-defrule (concat its-hankaku-escape upcase) upcase))
+
+;; SYMBOL Input
+  (its-defrule   "z1"   "\e$B!{\e(B")    (its-defrule   "z!"   "\e$B!|\e(B")
+  (its-defrule   "z2"   "\e$B"&\e(B")    (its-defrule   "z@"   "\e$B"'\e(B")
+  (its-defrule   "z3"   "\e$B"$\e(B")    (its-defrule   "z#"   "\e$B"%\e(B")
+  (its-defrule   "z4"   "\e$B""\e(B")    (its-defrule   "z$"   "\e$B"#\e(B")
+  (its-defrule   "z5"   "\e$B!~\e(B")    (its-defrule   "z%"   "\e$B"!\e(B")
+  (its-defrule   "z6"   "\e$B!y\e(B")    (its-defrule   "z^"   "\e$B!z\e(B")
+  (its-defrule   "z7"   "\e$B!}\e(B")    (its-defrule   "z&"   "\e$B!r\e(B")
+  (its-defrule   "z8"   "\e$B!q\e(B")    (its-defrule   "z*"   "\e$B!_\e(B")
+  (its-defrule   "z9"   "\e$B!i\e(B")    (its-defrule   "z("   "\e$B!Z\e(B")
+  (its-defrule   "z0"   "\e$B!j\e(B")    (its-defrule   "z)"   "\e$B![\e(B")
+  (its-defrule   "z-"   "\e$B!A\e(B")    (its-defrule   "z_"   "\e$B!h\e(B")
+  (its-defrule   "z="   "\e$B!b\e(B")    (its-defrule   "z+"   "\e$B!^\e(B")
+  (its-defrule   "z\\"  "\e$B!@\e(B")    (its-defrule   "z|"   "\e$B!B\e(B")
+  (its-defrule   "z`"   "\e$B!-\e(B")    (its-defrule   "z~"   "\e$B!/\e(B")
+
+  (its-defrule   "zq"   "\e$B!T\e(B")    (its-defrule   "zQ"   "\e$B!R\e(B")
+  (its-defrule   "zw"   "\e$B!U\e(B")    (its-defrule   "zW"   "\e$B!S\e(B")
+                                       ; e
+  (its-defrule   "zr"   "\e$B!9\e(B")    (its-defrule   "zR"   "\e$B!8\e(B")
+  (its-defrule   "zt"   "\e$B!:\e(B")    (its-defrule   "zT"   "\e$B!x\e(B")
+                                       ; y u i o
+  (its-defrule   "zp"   "\e$B")\e(B")    (its-defrule   "zP"   "\e$B",\e(B")
+  (its-defrule   "z["   "\e$B!X\e(B")    (its-defrule   "z{"   "\e$B!L\e(B")
+  (its-defrule   "z]"   "\e$B!Y\e(B")    (its-defrule   "z}"   "\e$B!M\e(B")
+
+                                       ; a
+  (its-defrule   "zs"   "\e$B!3\e(B")    (its-defrule   "zS"   "\e$B!4\e(B")
+  (its-defrule   "zd"   "\e$B!5\e(B")    (its-defrule   "zD"   "\e$B!6\e(B")
+  (its-defrule   "zf"   "\e$B!7\e(B")    (its-defrule   "zF"   "\e$B"*\e(B")
+  (its-defrule   "zg"   "\e$B!>\e(B")    (its-defrule   "zG"   "\e$B!=\e(B")
+  (its-defrule   "zh"   "\e$B"+\e(B")
+  (its-defrule   "zj"   "\e$B"-\e(B")
+  (its-defrule   "zk"   "\e$B",\e(B")
+  (its-defrule   "zl"   "\e$B"*\e(B")
+  (its-defrule   "z;"   "\e$B!+\e(B")    (its-defrule   "z:"   "\e$B!,\e(B")
+  (its-defrule   "z\'"  "\e$B!F\e(B")    (its-defrule   "z\""  "\e$B!H\e(B")
+
+                                       ; z
+  (its-defrule   "zx"   ":-")  (its-defrule   "zX"   ":-)")
+  (its-defrule   "zc"   "\e$B!;\e(B")    (its-defrule   "zC"   "\e$B!n\e(B")
+  (its-defrule   "zv"   "\e$B"(\e(B")    (its-defrule   "zV"   "\e$B!`\e(B")
+  (its-defrule   "zb"   "\e$B!k\e(B")    (its-defrule   "zB"   "\e$B"+\e(B")
+  (its-defrule   "zn"   "\e$B!l\e(B")    (its-defrule   "zN"   "\e$B"-\e(B")
+  (its-defrule   "zm"   "\e$B!m\e(B")    (its-defrule   "zM"   "\e$B".\e(B")
+  (its-defrule   "z,"   "\e$B!E\e(B")    (its-defrule   "z<"   "\e$B!e\e(B")
+  (its-defrule   "z."   "\e$B!D\e(B")    (its-defrule   "z>"   "\e$B!f\e(B")
+  (its-defrule   "z/"   "\e$B!&\e(B")    (its-defrule   "z?"   "\e$B!g\e(B")
+  )
+
+(define-its-state-machine-append its-hira-map
+  (if its-hira-enable-double-n
+      (its-defrule "nn" "\e$B$s\e(B")
+    (its-defrule "nn" "\e$B$s\e(B" -1))
+
+  (its-defrule "-"   its-hira-horizontal)
+  (its-defrule "["    its-hira-open-bracket)
+  (its-defrule "]"    its-hira-close-bracket)
+  (its-defrule "." its-hira-period)
+  (its-defrule "," its-hira-comma)
+
+  (if its-hira-enable-zenkaku-alphabet
+      (progn
+       (its-defrule   "1"   "\e$B#1\e(B")  (its-defrule   "2"   "\e$B#2\e(B")
+       (its-defrule   "3"   "\e$B#3\e(B")  (its-defrule   "4"   "\e$B#4\e(B")
+       (its-defrule   "5"   "\e$B#5\e(B")  (its-defrule   "6"   "\e$B#6\e(B")
+       (its-defrule   "7"   "\e$B#7\e(B")  (its-defrule   "8"   "\e$B#8\e(B")
+       (its-defrule   "9"   "\e$B#9\e(B")  (its-defrule   "0"   "\e$B#0\e(B")
+       (its-defrule   "!"   "\e$B!*\e(B")  (its-defrule   "@"   "\e$B!w\e(B")
+       (its-defrule   "#"   "\e$B!t\e(B")  (its-defrule   "$"   "\e$B!p\e(B")
+       (its-defrule   "%"   "\e$B!s\e(B")  (its-defrule   "^"   "\e$B!0\e(B")
+       (its-defrule   "&"   "\e$B!u\e(B")  (its-defrule   "*"   "\e$B!v\e(B")
+       (its-defrule   "("   "\e$B!J\e(B")  (its-defrule   ")"   "\e$B!K\e(B")
+       (its-defrule   "="   "\e$B!a\e(B")  (its-defrule   "`"   "\e$B!.\e(B")
+       (its-defrule   "\\"  "\e$B!o\e(B")  (its-defrule   "|"   "\e$B!C\e(B")
+       (its-defrule   "_"   "\e$B!2\e(B")  (its-defrule   "+"   "\e$B!\\e(B")
+       (its-defrule   "~"   "\e$B!1\e(B" nil t)
+       (its-defrule   "{"   "\e$B!P\e(B")
+       (its-defrule   "}"   "\e$B!Q\e(B")  (its-defrule   ":"   "\e$B!'\e(B")
+       (its-defrule   ";"   "\e$B!(\e(B")  (its-defrule   "\""  "\e$B!I\e(B")
+       (its-defrule   "'"   "\e$B!G\e(B")  (its-defrule   "<"   "\e$B!c\e(B")
+       (its-defrule   ">"   "\e$B!d\e(B")  (its-defrule   "?"   "\e$B!)\e(B")
+       (its-defrule   "/"   "\e$B!?\e(B"))
+    (progn
+      (its-defrule   "1"   "1")  (its-defrule   "2"   "2")
+      (its-defrule   "3"   "3")  (its-defrule   "4"   "4")
+      (its-defrule   "5"   "5")  (its-defrule   "6"   "6")
+      (its-defrule   "7"   "7")  (its-defrule   "8"   "8")
+      (its-defrule   "9"   "9")  (its-defrule   "0"   "0")
+      (its-defrule   "!"   "!")  (its-defrule   "@"   "@")
+      (its-defrule   "#"   "#")  (its-defrule   "$"   "$")
+      (its-defrule   "%"   "%")  (its-defrule   "^"   "^")
+      (its-defrule   "&"   "&")  (its-defrule   "*"   "*")
+      (its-defrule   "("   "(")  (its-defrule   ")"   ")")
+      (its-defrule   "="   "=")  (its-defrule   "`"   "`")
+      (its-defrule   "\\"  "\\")  (its-defrule   "|"   "|")
+      (its-defrule   "_"   "_")  (its-defrule   "+"   "+")
+      (its-defrule   "~"   "~" nil t)
+      (its-defrule   "{"   "{")
+      (its-defrule   "}"   "}")  (its-defrule   ":"   ":")
+      (its-defrule   ";"   ";")  (its-defrule   "\""  "\"")
+      (its-defrule   "'"   "'")  (its-defrule   "<"   "<")
+      (its-defrule   ">"   ">")  (its-defrule   "?"   "?")
+      (its-defrule   "/"   "/")))
+  )
+
+;;; its/hira.el ends here.
diff --git a/leim-list-egg.el b/leim-list-egg.el
new file mode 100644 (file)
index 0000000..d360439
--- /dev/null
@@ -0,0 +1,4 @@
+;;; Tamago
+(register-input-method
+ "egg-ja" "Japanese" 'egg-mode
+ "A\e$(B$"\e(B"  "Romaji -> Hiragana -> Kanji&Kana")
diff --git a/menudiag.el b/menudiag.el
new file mode 100644 (file)
index 0000000..f9caf06
--- /dev/null
@@ -0,0 +1,285 @@
+;;; menudiag.el --- Minibuffer Menu System
+
+;; Copyright (C) 1997 Mule Project, Powered by Electrotechnical
+;; Laboratory, JAPAN.
+;; Project Leader: Satoru Tomura <tomura@etl.go.jp>
+
+;; Author: NIIBE Yutaka <gniibe@mri.co.jp>
+;; Maintainer: NIIBE Yutaka <gniibe@mri.co.jp>
+
+;; This file will be part of GNU Emacs (in future).
+
+;; GNU Emacs 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,
+;; 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.
+
+;; 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.
+
+;;; Commentary:
+;; Inspired by the menu subsystem of EGG V3.0
+;;
+;; Completely different implementation, using keymap and recursive edit.
+
+;;; Code:
+
+;;
+;; Data structure of MENU
+;;
+;; <menu> ::= ( menu <prompt> <item-list> )
+;; <prompt> ::= STRING
+;; <item-list> ::= ( <item> ... )
+;; <item> ::= <string> | ( <string> . <value> )
+;;
+;; <value> ::=  <menu> | INTEGER | STRING  (Must *NOT* cons cell)
+;;
+;;
+;
+;;
+;; <selection-list> ::= ( <line>... )
+;; <line>  ::= ( <item>... )
+;;
+
+(defvar menudiag-mode-map
+  (let ((map (make-keymap))
+       (ch 0))
+    (while (< ch 127)
+      (define-key map (char-to-string ch) 'undefined)
+      (setq ch (1+ ch)))
+    (setq ch ?0)
+    (while (< ch ?9)
+      (define-key map (char-to-string ch) 'menudiag-goto-item)
+      (setq ch (1+ ch)))
+    (setq ch ?a)
+    (while (< ch ?z)
+      (define-key map (char-to-string ch) 'menudiag-goto-item)
+      (setq ch (1+ ch)))
+    (setq ch ?A)
+    (while (< ch ?Z)
+      (define-key map (char-to-string ch) 'menudiag-goto-item)
+      (setq ch (1+ ch)))
+    (define-key map "\C-a" 'menudiag-beginning-of-line)
+    (define-key map "\C-e" 'menudiag-end-of-line)
+    (define-key map "\C-f" 'menudiag-forward-item)
+    (define-key map "\C-b" 'menudiag-backward-item)
+    (define-key map "\C-n" 'menudiag-next-line)
+    (define-key map "\C-p" 'menudiag-previous-line)
+    (define-key map "\C-]" 'menudiag-exit)
+    (define-key map "\C-g" 'menudiag-exit-one-level)
+    (define-key map "\C-l" 'menudiag-redraw)
+    (define-key map "\C-m" 'menudiag-select-this-item)
+    (define-key map [return] 'menudiag-select-this-item)
+    (define-key map [left] 'menudiag-forward-item)
+    (define-key map [right] 'menudiag-backward-item)
+    (define-key map [up] 'menudiag-previous-line)
+    (define-key map [down] 'menudiag-next-line)
+    (define-key map [menudiag-continuation] 'menudiag-follow-continuation)
+    map)
+  "Keymap for MENU.")
+
+(defun menudiag-menu-p (item)
+  (and (consp item) (eq 'menu (car item))))
+
+(defun menudiag-item-string (item)
+  (if (stringp item)
+      item
+    (format "%s" (car item))))
+
+(defun menudiag-item-value (item)
+  (if (stringp item)
+      item
+    (cdr item)))
+
+(defsubst menudiag-item-width (item)
+  (+ 4 (string-width (menudiag-item-string item))))
+
+(defun menudiag-make-selection-list (item-list line-width)
+  (let ((l nil)
+       (line nil)
+       (width 0))
+    (while item-list
+      (let* ((item (car item-list))
+            (item-width (menudiag-item-width item)))
+       (if (and line (>= (+ width item-width) line-width))
+           (setq l (cons (reverse line) l)
+                 line nil
+                 width 0))
+       (setq line (cons item line)
+             width (+ width (menudiag-item-width item))
+             item-list (cdr item-list))))
+    (if line
+       (reverse (cons (reverse line) l))
+      (reverse l))))
+
+;; Entry function
+(defun menudiag-select (menu &optional menudiag-continuation return-contin)
+  (let (value)
+    (if menudiag-continuation
+       (setq unread-command-events (cons 'menudiag-continuation
+                                         unread-command-events)))
+    (if (not return-contin)
+       (setq value t))
+    (if (catch 'menudiag-exit
+         (menudiag-select-internal menu))
+       (signal 'quit "")
+      value)))
+
+;; Entry function
+(defun menudiag-get-value (continuation)
+  (menudiag-item-value (nth (1- (length continuation)) continuation)))
+
+(defun menudiag-follow-continuation ()
+  (interactive)
+  (let ((item (car menudiag-continuation)))
+    (setq menudiag-continuation (cdr menudiag-continuation))
+    (if menudiag-continuation
+       (setq unread-command-events (cons 'menudiag-continuation
+                                         unread-command-events)))
+    (let ((in-loop t))
+      (while in-loop
+       (if (eq item (nth pos-in-line line))
+           (setq in-loop nil)
+         (menudiag-forward-item))))
+    (let ((v (menudiag-item-value item)))
+      (if (menudiag-menu-p v)
+         (unwind-protect
+             (progn
+               (menudiag-select-internal v)
+               (menudiag-redraw))
+           (if (consp value)
+               (setq value (cons item value))))))))
+
+(defun menudiag-select-internal (menu)
+  (let* ((minibuf-prompt (nth 1 menu))
+        (selection-list
+         (menudiag-make-selection-list (nth 2 menu)
+                                   (- (window-width (minibuffer-window))
+                                      (string-width minibuf-prompt))))
+        (line (car selection-list))
+        (minibuf-contents
+         (menudiag-make-menu-formatted-string line)))
+    (let ((linepos 0)
+         (pos-in-line 0))
+      (read-from-minibuffer minibuf-prompt
+                           (cons minibuf-contents 3)
+                           menudiag-mode-map))))
+
+(defun menudiag-make-menu-formatted-string (item-list)
+  (let ((i -1))
+    (mapconcat
+     (function (lambda (item)
+                (setq i (1+ i))
+                (format "  %x.%s" i (menudiag-item-string item))))
+     item-list "")))
+
+(defun menudiag-goto-item ()
+  (interactive)
+  (let ((ch last-command-char)
+       (n 0))
+    (cond ((and (<= ?0 ch) (<= ch ?9))
+          (setq n (- ch ?0)))
+         ((and (<= ?a ch) (<= ch ?z))
+          (setq n (+ 10 (- ch ?a))))
+         ((and (<= ?A ch) (<= ch ?Z))
+          (setq n (+ 10 (- ch ?A)))))
+    (if (>= n (length line))
+       (error "No such item")
+      (menudiag-goto-item-internal n))))
+
+(defun menudiag-goto-item-internal (n)
+  (let ((old-pos-in-line pos-in-line)
+       (p 3)
+       (i 0))
+    (setq pos-in-line n)
+    (while (< i pos-in-line)
+      (setq p (+ p (length (menudiag-item-string (nth i line))) 4))
+      (setq i (1+ i)))
+    (goto-char p)))
+
+(defun menudiag-beginning-of-line ()
+  (interactive)
+  (menudiag-goto-item-internal 0))
+
+(defun menudiag-end-of-line ()
+  (interactive)
+  (menudiag-goto-item-internal (1- (length line))))
+
+(defun menudiag-forward-item ()
+  (interactive)
+  (if (< pos-in-line (1- (length line)))
+      (menudiag-goto-item-internal (1+ pos-in-line))
+    (if (>= linepos (1- (length selection-list)))
+       (signal 'end-of-buffer "")
+      (menudiag-goto-line (1+ linepos))
+      (menudiag-beginning-of-line))))
+
+(defun menudiag-backward-item ()
+  (interactive)
+  (if (< 0 pos-in-line)
+      (menudiag-goto-item-internal (1- pos-in-line))
+    (if (< linepos 1)
+       (signal 'beginning-of-buffer "")
+      (menudiag-goto-line (1- linepos))
+      (menudiag-end-of-line))))
+
+(defun menudiag-goto-line (n)
+  (if (or (>= n (length selection-list)) (< n 0))
+      (ding)
+    (setq line (nth n selection-list)
+         linepos n)
+    (delete-region (point-min) (point-max))
+    (insert (menudiag-make-menu-formatted-string line))))
+
+(defun menudiag-next-line ()
+  (interactive)
+  (menudiag-goto-line (1+ linepos))
+  (if (< pos-in-line (length line))
+      (menudiag-goto-item-internal pos-in-line)
+    (menudiag-end-of-line)))
+
+(defun menudiag-previous-line ()
+  (interactive)
+  (menudiag-goto-line (1- linepos))
+  (if (< pos-in-line (length line))
+      (menudiag-goto-item-internal pos-in-line)
+    (menudiag-end-of-line)))
+
+(defun menudiag-redraw ()
+  (interactive)
+  (menudiag-goto-line linepos)
+  (menudiag-goto-item-internal pos-in-line))
+
+(defun menudiag-exit-one-level ()
+  (interactive)
+  (exit-minibuffer))
+
+(defun menudiag-exit ()
+  (interactive)
+  (throw 'menudiag-exit t))
+
+(defun menudiag-select-this-item ()
+  (interactive)
+  (let* ((item (nth pos-in-line line))
+        (v (menudiag-item-value item)))
+    (if (menudiag-menu-p v)
+       (unwind-protect
+           (progn
+             (menudiag-select-internal v)
+             (menudiag-redraw))
+         (if (consp value)
+             (setq value (cons item value))))
+      (if (eq value t)
+         (setq value (menudiag-item-value item))
+       (setq value (cons item nil)))
+      (throw 'menudiag-exit nil))))
+
+(provide 'menudiag)
+;;; menudiag.el ends here.