diff lisp/quail/quail-tit.el @ 70:131b0175ea99 r20-0b30

Import from CVS: tag r20-0b30
author cvs
date Mon, 13 Aug 2007 09:02:59 +0200
parents
children fe104dbd9147
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/quail/quail-tit.el	Mon Aug 13 09:02:59 2007 +0200
@@ -0,0 +1,331 @@
+;; Convert tit format dictionary (of cxterm) to quail-package.
+;; Usage (within mule):
+;;	M-x tit-to-quail<CR>tit-file-name<CR>
+;; Usage (from shell):
+;;	% mule -batch -l quail/tit -f batch-tit-to-quail [dirname|filename] ...
+;;   When you run tit-to-quail within Mule, you are shown lines for setting
+;;   key bindings.  You can modify them as you wish.  After that, save the
+;;   buffer into somewhere under your `load-path'.
+;;   You may also modify the second arg PROMPT of quail-define-pacakge
+;;   to shorter string.
+;; As for Big5 file, Big5-HKU is not supported, you must
+;; at first convert Big5-HKU to Big5-ETen before you run `tit-to-quail'.
+
+(defun tit-value-head ()
+  (skip-chars-forward "^:")
+  (forward-char 1)
+  (skip-chars-forward " \t"))
+
+(defun tit-set-keys ()
+  (let (limit str)
+    (save-excursion
+      (end-of-line)
+      (setq limit (point)))
+    (if (re-search-forward "[^ \t\n]+" limit t)
+	(progn
+	  (setq str
+		(concat "\""
+			(buffer-substring (match-beginning 0) (match-end 0))
+			"\""))
+	  (car (read-from-string str))))))
+
+(defun tit-insert (arg)
+  (let ((pos (point)))
+    (insert arg)
+    (if (or (string-match "\"" arg) (string-match "\\\\" arg))
+	(save-excursion
+	  (while (re-search-backward "\"\\|\\\\" pos t)
+	    (insert "\\")
+	    (forward-char -1))))))
+
+(defun tit-buffer-substring (key)
+  (let ((i 0) ch)
+    (while (and (/= (setq ch (following-char)) ? )
+		(/= ch ?\t)
+		(/= ch ?\n))
+      (aset key i ch)
+      (setq i (1+ i))
+      (forward-char 1))
+    (aset key i 0)))
+
+(defun tit-looking-at (key)
+  (let ((pos (point)) (i 0) ch)
+    (while (eq (char-after (+ pos i)) (aref key i))
+      (setq i (1+ i)))
+    (and (integerp (setq ch (char-after (+ pos i))))
+	 (or (= ch ? ) (= ch ?\t))
+	 (= (aref key i) 0))))
+
+(defun tit-message (&rest args)
+  (if (null noninteractive)
+      (apply 'message args)))
+
+;; make quail-package name (e.g. ZOZY.tit -> .../quail/zozy.el)
+(defun tit-dest-file (file &optional dir)
+  (expand-file-name
+   (concat (if dir "" "quail/")
+	   (downcase (file-name-nondirectory (substring file 0 -4)))
+	   ".el")
+   (or dir (car load-path))))
+
+(defun tit-to-quail (tit-file &optional dest-dir)
+  (interactive "Ftit file: ")
+  (let ((buf (get-buffer-create "*tit-work*"))
+	pos
+	;; tit keywords and default values
+	(encode '*euc-china*)
+	(multichoice t)
+	prompt
+	comment
+	validinputkey
+	(selectkey '["1 " "2" "3" "4" "5" "6" "7" "8" "9" "0"
+		     nil nil nil nil nil nil])
+	(selectkey-idx 0)
+	(backspace "\177")
+	(deleteall "\C-u")
+	(moveright ".>")
+	(moveleft ",<")
+	keyprompt
+	phrase)
+    (save-excursion
+      (set-buffer buf)
+      (erase-buffer)
+      (if (null (string-match "\\.tit$" tit-file))
+	  (setq tit-file (concat tit-file ".tit")))
+      (let ((file-coding-system-for-read '*noconv*))
+	(insert-file-contents tit-file))
+
+      (set-visited-file-name (tit-dest-file tit-file dest-dir))
+      (set-file-coding-system '*junet*unix)
+
+      ;; convert GB or BIG5 to Mule's internal code
+      (save-excursion
+	(if (re-search-forward "^ENCODE:" nil t)
+	    (progn
+	      (skip-chars-forward " \t")
+	      (if (looking-at "GB")
+		  (setq encode '*euc-china*)
+		(setq encode '*big5*)))))
+      (tit-message "Converting %s to Mule's internal code..." encode)
+      (code-convert 1 (point-max) encode '*internal*)
+
+      (goto-char 1)
+      ;; setting headers
+      (insert "(require 'quail)\n")
+
+      (tit-message "Extracting header information...")
+      (while (null (looking-at "BEGINDICTIONARY\\|BEGINPHRASE"))
+	(insert ";; ")
+	(let ((ch (following-char)))
+	  (cond ((= ch ?C)		; COMMENT
+		 (forward-word 1)
+		 (setq pos (point))
+		 (end-of-line)
+		 (setq comment (cons (buffer-substring pos (point)) comment)))
+		((= ch ?M)		; MULTICHOICE, MOVERIGHT, MOVELEFT
+		 (cond ((looking-at "MULTI")
+			(tit-value-head)
+			(setq multichoice (looking-at "YES")))
+		       ((looking-at "MOVERIGHT")
+			(tit-value-head)
+			(setq moveright (tit-set-keys)))
+		       ((looking-at "MOVELEFT")
+			(tit-value-head)
+			(setq moveleft (tit-set-keys)))))
+		((= ch ?P)		; PROMPT
+		 (tit-value-head)
+		 (setq pos (point))
+		 (end-of-line)
+		 (setq comment (cons (buffer-substring pos (point)) comment))
+		 (setq pos (point))
+		 (skip-chars-backward "^ \t")
+		 (setq prompt (buffer-substring (point) pos)))
+		((= ch ?S)		; SELECTKEY
+		 (tit-value-head)
+		 (let (key)
+		   (while (and (< selectkey-idx 16) (setq key (tit-set-keys)))
+		     (aset selectkey selectkey-idx key)
+		     (setq selectkey-idx (1+ selectkey-idx)))))
+		((= ch ?B)		; BACKSPACE
+		 (tit-value-head)
+		 (setq backspace (tit-set-keys)))
+		((= ch ?K)		; KEYPROMPT
+		 (forward-word 1)
+		 (forward-char 1)
+		 (setq pos (point))
+		 (let (key str)
+		   (search-forward ")" nil t)
+		   (setq key (buffer-substring pos (1- (point))))
+		   (skip-chars-forward ": \t")
+		   (setq pos (point))
+		   (forward-char 1)
+		   (setq str (buffer-substring pos (point)))
+		   (setq keyprompt (cons (cons key str) keyprompt))))
+		))
+	(forward-line 1))
+
+      (setq phrase (looking-at "BEGINPHRASE"))
+      ;; comment out the line BEGINDICTIONARY/BEGINPHRASE
+      (insert ";; ")
+      (forward-line 1)
+
+      (tit-message "Defining quail-package...")
+      (insert "(quail-define-package \""
+	      (substring (file-name-nondirectory buffer-file-name) 0 -3)
+	      "\" \"")
+      (if (string-match "[:$A!K$(0!(!J(B]\\(.*\\)[:$A!K$(0!(!K(B]" prompt)
+	  (tit-insert (substring prompt (match-beginning 1) (match-end 1)))
+	(tit-insert prompt))
+      (insert "\"\n")
+      (if multichoice
+	  (insert " t\n")
+	(if keyprompt
+	    (let (key)
+	      (insert " '(")
+	      (while keyprompt
+		(setq key (car keyprompt))
+		(insert "(?")
+		(tit-insert (car key))
+		(insert " . \"")
+		(tit-insert (cdr key))
+		(insert "\")\n   ")
+		(setq keyprompt (cdr keyprompt)))
+	      (setq pos (point))
+	      (forward-char -4)
+	      (delete-region (point) pos)
+	      (insert ")\n"))
+	  (insert " nil\n")))
+      (if comment
+	  (progn
+	    (insert " \"")
+	    (setq comment (nreverse comment))
+	    (while comment
+	      (tit-insert (car comment))
+	      (insert "\n")
+	      (setq comment (cdr comment)))
+	    (forward-char -1)
+	    (insert "\"")
+	    (forward-char 1))
+	(insert " \"\"\n"))
+      (let (i len key)
+	(insert " '(\n")
+	(setq i 0 len (length moveright))
+	(while (< i len)
+	  (setq key (aref moveright i))
+	  (if (and (>= key ? ) (< key 127))
+	      (progn
+		(insert "  (\"")
+		(tit-insert (char-to-string (aref moveright i)))
+		(insert "\" . quail-next-candidate-block)\n")))
+	  (setq i (1+ i)))
+	(setq i 0 len (length moveleft))
+	(while (< i len)
+	  (setq key (aref moveleft i))
+	  (if (and (>= key ? ) (< key 127))
+	      (progn
+		(insert "  (\"")
+		(tit-insert (char-to-string (aref moveleft i)))
+		(insert "\" . quail-prev-candidate-block)\n")))
+	  (setq i (1+ i)))
+	(if (string-match " " (aref selectkey 0))
+	    (insert "  (\" \" . quail-select-current)\n"))
+	(insert "  )\n"))
+      (insert " nil" (if multichoice " nil" " t") ")\n\n")
+
+      (tit-message "Formatting translation rules...")
+      (let ((mc-flag nil)
+	    (key (make-string 30 0)))
+	(while (null (eobp))
+	  (if (or (= (following-char) ?#) (= (following-char) ?\n))
+	      (progn
+		(insert ";; ")
+		(forward-line 1))
+	    (insert (if phrase "(qd \"" "(qdv \""))
+	    (setq pos (point))
+	    (tit-buffer-substring key)
+	    (save-excursion
+	      (while (re-search-backward "\"\\|\\\\[^0-9]" pos t)
+		(insert "\\")
+		(forward-char -1)))
+	    (insert "\"")
+	    (skip-chars-forward " \t")
+	    (if (eolp)
+		(progn
+		  (beginning-of-line)
+		  (setq pos (point))
+		  (forward-line 1)
+		  (delete-region pos (point)))
+	      (insert (if phrase "'(" "\""))
+	      (setq pos (point))
+	      (forward-line 1)
+	      (while (tit-looking-at key)
+		(let (p)
+		  (skip-chars-backward " \t\n")
+		  (if phrase (insert " "))
+		  (setq p (point))
+		  (skip-chars-forward " \t\n")
+		  (skip-chars-forward "^ \t")
+		  (skip-chars-forward " \t")
+		  (delete-region p (point)))
+		(forward-line 1))
+	      (goto-char pos)
+	      (if phrase
+		  (while (null (eolp))
+		    (insert "\"")
+		    (skip-chars-forward "^ \t\n")
+		    (insert "\"")
+		    (skip-chars-forward " \t"))
+		(let ((mc-flag t)) (forward-char 1))
+		(if (= (following-char) ?\n)
+		    (progn
+		      (beginning-of-line)
+		      (forward-char 3)
+		      (delete-char 1))))
+	      (end-of-line)
+	      (insert (if phrase "))" "\")"))
+	      (forward-line 1)))))
+      (insert "\n(quail-setup-current-package)\n")
+      )
+
+    (if noninteractive
+	(save-excursion
+	  (set-buffer buf)
+	  (write-file buffer-file-name))
+      ;; show user the line for keymap definition.
+      (switch-to-buffer buf)
+      (goto-char 1)
+      (search-forward "defconst" nil t)
+      (beginning-of-line)
+      (recenter 1)
+      (tit-message
+       "Modify key bindings or prompt as you wish and save this file.")
+      )
+    ))
+
+(defun batch-tit-to-quail ()
+  "Run `tit-to-quail' on the files remaining on the command line.
+Use this from the command line, with `-batch';
+it won't work in an interactive Emacs.
+For example, invoke \"emacs -batch -f batch-tit-to-quail $emacs/ ~/*.el\""
+  (defvar command-line-args-left)	;Avoid 'free variable' warning
+  (if (not noninteractive)
+      (error "`batch-tit-to-quail' is to be used only with -batch"))
+  (let ((error nil))
+    (while command-line-args-left
+      (if (file-directory-p (expand-file-name (car command-line-args-left)))
+	  (let ((files (directory-files (car command-line-args-left)))
+		file)
+	    (while files
+	      (setq file (expand-file-name (car files)
+					   (car command-line-args-left)))
+	      (if (and (string-match "\\.tit$" file)
+		       (file-newer-than-file-p
+			file
+			(tit-dest-file file default-directory)))
+		  (progn
+		    (message "Converting %s to quail-package..." file)
+		    (tit-to-quail file default-directory)))
+	      (setq files (cdr files))))
+	(tit-to-quail (car command-line-args-left) default-directory))
+      (setq command-line-args-left (cdr command-line-args-left)))
+    (kill-emacs 0)))