;;; suikyo.el --- Romaji-Hiragana conversion library for Emacs ;; $Id: suikyo.el,v 1.4 2005/01/16 13:59:53 komatsu Exp $ ;; ;; Copyright (C) 2002 Hiroyuki Komatsu ;; All rights reserved. ;; This is free software with ABSOLUTELY NO WARRANTY. ;; ;; You can redistribute it and/or modify it under the terms of ;; the GNU General Public License version 2. ;; (load "suikyo-config") ;(defvar suikyo-table-path "/usr/local/share/suikyo/conv-table") (defvar suikyo-buffer " *suikyo*") (defvar suikyo-table-romaji-kana nil) (defvar suikyo-table-kana-romaji nil) (defun suikyo-convert-romaji-kana (string) (or suikyo-table-romaji-kana (setq suikyo-table-romaji-kana (suikyo-table-loadfile (list nil) "romaji-kana")) ) (suikyo-convert suikyo-table-romaji-kana (downcase string)) ) (defun suikyo-convert-kana-romaji (string) (or suikyo-table-kana-romaji (setq suikyo-table-kana-romaji (suikyo-table-loadfile (list nil) "kana-romaji")) ) (suikyo-convert suikyo-table-kana-romaji (downcase string)) ) (defun suikyo-convert-romaji-refine (string) (suikyo-convert-kana-romaji (suikyo-convert-romaji-kana string)) ) (defun suikyo-convert (table string) (let ((conv-str "") (original-table (list nil nil table))) (while (> (length string) 0) (let ((tmp-str "") (table original-table) conv-data head-char) (while (and (nth 2 table) (> (length string) 0)) (setq head-char (substring string 0 1)) (setq table (assoc head-char (nth 2 table))) (and (or table (string= tmp-str "")) (or (string= head-char " ") (setq tmp-str (concat tmp-str head-char))) (setq conv-data (nth 1 table) string (substring string 1))) ) (cond ((nth 2 table) (setq conv-str (concat conv-str tmp-str))) ((null conv-data) (setq conv-str (concat conv-str tmp-str))) ((consp conv-data) (setq conv-str (concat conv-str (car conv-data)) string (concat (cdr conv-data) string))) (t (setq conv-str (concat conv-str conv-data))) ) )) conv-str )) (defun suikyo-table-loadfile (table filename &optional table-path) (or (string-match "^/" filename) (setq filename (expand-file-name (concat (or table-path suikyo-table-path) "/" filename)))) (if (not (file-readable-p filename)) table (save-excursion (get-buffer-create suikyo-buffer) (set-buffer suikyo-buffer) (erase-buffer) (insert-file filename) (beginning-of-buffer) (let ((bol (point)) next-bol data comment-flag) (while (not (eobp)) (forward-line 1) (setq next-bol (point)) (setq line (buffer-substring bol (1- next-bol))) (setq bol next-bol) (and (string-match "^/\\*" line) (setq comment-flag t)) (cond ((not (or comment-flag (string-match "^#\\|^[ \\t]*$" line))) (setq table (apply 'suikyo-table-modify table (suikyo-split-string line)))) ((and comment-flag (string-match "\\*/" line)) (setq comment-flag nil)) ))) table))) (defun suikyo-table-modify (table conv-from &optional conv-to pendency) (if conv-to (suikyo-table-set table conv-from &optional conv-to pendency) (suikyo-table-unset table conv-from))) (defun suikyo-table-set (table conv-from &optional conv-to pendency) (if (= (length conv-from) 1) ;; Terminal of recursive execution (setcar (nthcdr 1 (suikyo-table-set-internal table conv-from)) (if pendency (cons conv-to pendency) conv-to)) (let ((sub-table (suikyo-table-set-internal table (substring conv-from 0 1)))) (if (= (length sub-table) 2) (nconc sub-table (list (list nil)))) (suikyo-table-set (nth 2 sub-table) (substring conv-from 1) conv-to pendency) )) table) (defun suikyo-table-set-internal (table char) (or (assoc char table) (if (equal table '(nil)) (setcar table (list char nil)) (car (last (nconc table (list (list char nil))))) ))) (defun suikyo-table-unset (table key) "Delete the conversion of the KEY from the TABLE." (let* ((head (substring key 0 1)) (rest (substring key 1)) (word-data (assoc head table))) (if (= (length rest) 0) (if (= (length (nth 2 word-data)) 0) ;; Checking the child tree. (mell-list-delete word-data table) (setcar (cdr word-data) nil)) (let ((new-subtable (suikyo-table-unset (nth 2 word-data) rest))) (if new-subtable (setcdr (cdr word-data) (list new-subtable)) (mell-list-delete word-data table)))) table)) (defun mell-list-delete (key list) "This deletes the KEY from the LIST. The original list is also modified." (let ((list-cdr (member key list))) (cond ((= (length list-cdr) 1) (setcar (nthcdr (- (length list) 1) list) nil) (setcdr (nthcdr (- (length list) 2) list) nil)) (list-cdr (setcar list-cdr (nth 1 list-cdr)) (setcdr list-cdr (nthcdr 2 list-cdr)))))) (defun suikyo-split-string (line) (mapcar 'suikyo-unescape (split-string line "\t") )) (defun suikyo-unescape (string) "Unescape string of kpdef format (canna format)." (let ((unescaped-string "")) (while (string-match "\\\\" string) (let ((beg (match-beginning 0)) (end (match-end 0)) (len (length string)) next-char) (setq next-char (substring string end (min (1+ end) len))) (cond ((string= next-char "x") (setq next-char (char-to-string (string-to-int (substring string (1+ end) (min (+ end 3) len)) 16 ))) (setq end (min (+ end 2) len)) ) ((string= next-char "0") (setq next-char "") )) (setq unescaped-string (concat unescaped-string (substring string 0 beg) next-char)) (setq string (substring string (min (1+ end) len))) )) (concat unescaped-string string) )) (provide 'suikyo)