;; cedictlookup.el version 1.2.1 July 2005 ;; This performs chinese vocabulary lookup, and provides a ;; simple major mode "cedictlookup-mode" to go with it. ;; ;; Copyright (c) 1998,1999,2002,2005 David Hiebeler ;; Dept of Mathematics and Statistics ;; University of Maine ;; Orono, ME 04469-5752 ;; http://www.math.umaine.edu/faculty/hiebeler ;; ;; This program 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 of the License, or ;; (at your option) any later version. ;; ;; This program 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 this program; if not, write to the Free Software ;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ;; ;; ;; File: cedictlookup.el, version 1.2 (formerly known as chnvlookup.el) ;; By: David Hiebeler ;; Dept of Mathematics and Statistics ;; University of Maine ;; Orono, ME 04469-5752 ;; http://www.math.umaine.edu/faculty/hiebeler ;; ;; Version 1.2: June 2005 ;; Version 1.1.1: July 2002 ;; Version 1.1: June 1999 ;; Version 1.0: August 1998 ;; Any comments about this software are appreciated. ;; ;; This package provides a few routines to do Chinese vocabulary lookup, ;; via Chinese, pinyin, or English, by calling the "cedictlookup" Perl script ;; as a sub-process under emacs. It also provides a simple major mode ;; "cedictlookup-mode" for added convenience. See below ("HOW TO MAKE THIS ;; THING WORK") for things to put in your .emacs and/or .cshrc files to make ;; this work. ;; ;; The original version of this code was adapted from "cchelp.el" by ;; Stephen G. Simpson . The cedictlookup-mode part ;; was written by following text-mode.el supplied with emacs, and basically ;; ripping out everything I was pretty sure I wouldn't need. ;; ;; This has only been tested with cemacs.el under GNU Emacs Release 21.2.1. ;; It should work with both GB and BIG5 Chinese encodings, as long as ;; you point it at the right vocabulary files. ;; It has not been tested using UTF-8 encoding, and has been reported ;; not to work in that setting. ;; ;; History: ;; July 2005: verison 1.2.1 ;; Just renumberings to stay synchronized with the whole package. ;; June 2005: version 1.2 ;; Updated my address info, and labelled this as version 1.2 ;; for public release. ;; July 2002: version 1.1.1 ;; Added "cedictlookup-backward" function ;; at user's request. Updated for use with newer versions of emacs ;; with mule where each Chinese character counts as a single character ;; in emacs, rather than as two characters. (I had to do this when I ;; started using emacs 21.2.1, which came with RedHat Linux 7.3). This ;; version was never publically released though. ;; 10 June 1999: version 1.1 ;; Just added the trivial "cedictlookup" ;; function which doesn't do anything, except force the file to be ;; loaded (if you set up autoload), so you can start a cedictlookup ;; process without actually looking anything up. Also, renamed ;; everything from "chnvlookup" to "cedictlookup". ;; August 1998: original version, 1.0 ;; ;; A few functions for doing Chinese lookups are provided below. In addition, ;; you can type Chinese, pinyin, or English in the CEDICTLookup buffer that ;; cedictlookup creates, and when you hit RETURN, the text on that line will ;; be sent to the cedictlookup process. So you can look up words, or even ;; send special command strings to cedictlookup e.g. to change its lookup modes ;; (see cedictlookupdoc.txt for more info on cedictlookup and its modes). ;; ;; ;; ;; HOW TO MAKE THIS THING RUN ;; ========================== ;; ;; NOTE: if you are running an older version of emacs (I'm not sure exactly ;; how old, but I think version 20 or older), then Chinese characters were ;; encoded in a way that emacs perceived them as two characters each. This ;; code tries to switch between old and new behavior based on the version of ;; emacs it detects. If it seems to be doing the wrong thing, you could ;; try to manually set the value of the "oldcedict" variable below. ;; Note that I haven't test this on older version of emacs; I just merged ;; in the code from an older version of this file. If you're running an ;; old version of emacs without MULE and keep having trouble, you could ;; try the older version of this file, version 1.1.01. ;; ;; First, you should put this file somewhere in your emacs load path. ;; I'll also refer to the emacs startup file. My emacs startup file is ;; in the default place, the file ".emacs" in my home directory. ;; In my emacs startup file, I have the line: ;; (setq load-path (append '("~/emacs") load-path)) ;; That means emacs will see files I put under the "emacs" directory in ;; my home directory. ;; ;; I suggest putting the following (everything between the big lines of ;; semicolons) in your emacs startup file (feel free to change the key ;; definitions if you like): ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;(autoload 'cedictlookup-forward "cedictlookup" ;; "Lookup Chinese character(s) after point.\n" t) ;;(autoload 'cedictlookup-backward "cedictlookup" ;; "Lookup Chinese character(s) before point.\n" t) ;;(autoload 'cedictlookup-mode "cedictlookup" ;; "Mode for looking up Chinese character(s).\n" t) ;;(autoload 'cedictlookup-region "cedictlookup" ;; "Lookup Chinese character(s) in region.\n" t) ;;(autoload 'cedictlookup-line "cedictlookup" ;; "Lookup Chinese character(s) on current line.\n" t) ;;(autoload 'cedictlookup "cedictlookup" ;; "Start a cedictlookup process (without actually looking up anything).\n" t) ;; ;;(global-set-key "\C-c\C-zf" 'cedictlookup-forward) ; I use \C-c\C-z ("z" for ;; ; "zhong1 wen2") as the general ;; ; prefix for cedictlookup ;;(global-set-key "\C-c\C-zb" 'cedictlookup-backward) ;;(global-set-key "\C-c\C-zl" 'cedictlookup-line) ;;(global-set-key "\C-c\C-zr" 'cedictlookup-region) ;;(global-set-key "\C-cj" 'cedictlookup-region) ; I use cedictlookup-region a ;; ; lot, so I also made a key which is ;; ; easier (and faster) to type ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Next, I found that at least in RedHat 8, the LANG environment ;; variable contained UTF8, which was causing problems with doing Chinese ;; in emacs. So I put the following into my .cshrc (I use the tcsh shell) ;; to solve this problem: ;; setenv LANG en_US ;; If you use sh or bash, I believe this should be: ;; LANG=en_US ; export LANG ;; I don't know if this caused problems with later versions of RedHat/Fedora; ;; I've carried along the above line in my .cshrc since RedHat 8. ;; ;; Next, I set up a shell command alias, so that the command "cemacsgb" ;; actually runs: ;; emacs -name cxterm -fn 9x15 -geometry 80x24+5+5 -l cemacsgb ;; I also made a "cemacsgb-big" alias to run it with bigger fonts: ;; emacs -name cxterm -fn 12x24 -geometry 80x24+5+5 -l cemacsgb ;; ;; Those commands tell emacs to run, and to call the cemacsgb function. ;; That depends on the cemacsgb.el file being around somewhere in your emacs ;; load path, say in your ~/emacs directory. For me, this file contains ;; the following: ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; (set-language-environment "Chinese-GB") ;; (set-input-method "chinese-tonepy-punct") ;; ; use "chinese-qj" to input Western characters ;; (global-set-key [f4] '(lambda () (interactive) ;; (set-input-method "chinese-tonepy-punct"))) ;; (global-set-key [f3] '(lambda () (interactive) ;; (set-input-method "chinese-qj"))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Now, you can invoke cedictlookup either manually by doing ;; "M-x cedictlookup" in emacs, or just by using one of the keys that ;; trigger it (usually "C-c j" for me). ;; ;; ;; ;; ;; A few routines are provided here: ;; ;; cedictlookup-mode: Switch the current buffer into cedictlookup-mode. ;; All this mode does is redefine the RETURN key, so that when you ;; press RETURN, the contents of the current line are sent to the ;; the cedictlookup process (and a newline is also inserted at the end ;; of the line). ;; cedictlookup-forward: Look up character(s) after point. ;; (By the way, if you are not familiar with emacs terminology, "point" ;; refers to the current location of the cursor in the current buffer.) ;; If you give a numerical argument, that many Chinese characters after ;; point are sent to cedictlookup. If you don't give an argument, you are ;; prompted for the number of characters following point to use in the ;; lookup. ;; cedictlookup-backward: Look up character(s) before point. ;; If you give a numerical argument, that many Chinse characters before ;; point are sent to cedictlookup. If you don't give an argument, you are ;; prompted for the number of characters before point to use in the ;; lookup. ;; cedictlookup-region: Look up character(s) in the region. Set a region ;; (between mark and point) in the current buffer, then call this routine ;; to invoke cedictlookup on the characters in the region. ;; cedictlookup-line: Look up character(s) on the current line. This is ;; most useful in conjunction with cedictlookup-mode, which is the default ;; major mode of the CEDICTLookup buffer created by cedictlookup. In that ;; mode, the RETURN key calls cedictlookup-line, which means you can just ;; type something on a line, and it will be sent to cedictlookup (in fact, ;; you can either type some words to look up, or some commands for ;; cedictlookup, e.g. to change the Match Mode or Anchor Mode -- see the ;; cedictlookup.doc file for more information about cedictlookup and its ;; modes). ;; Note that this routine will work with Chinese, pinyin, or English. ;; The other two functions above only work with Chinese. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; First the code for cedictlookup-mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar cedictlookup-mode-hook nil "Normal hook run when entering Cedictlookup mode.") (defvar cedictlookup-mode-abbrev-table nil "Abbrev table used while in cedictlookup mode.") (define-abbrev-table 'cedictlookup-mode-abbrev-table ()) (defvar cedictlookup-mode-map nil "Keymap for Cedictlookup mode.") (if cedictlookup-mode-map () ; do nothing if the map already has something ; otherwise, make "return" call cedictlookup-line-with-newline (setq cedictlookup-mode-map (make-sparse-keymap)) (define-key cedictlookup-mode-map "\C-m" 'cedictlookup-line-with-newline)) (defun cedictlookup-mode () "Major mode for Chinese vocabulary lookups. A simple mode based on text-mode. \\{cedictlookup-mode-map} Turning on Cedictlookup mode runs the normal hook `cedictlookup-mode-hook'." (interactive) (kill-all-local-variables) (use-local-map cedictlookup-mode-map) (setq local-abbrev-table cedictlookup-mode-abbrev-table) (setq mode-name "Chinese Vocab Lookup") (setq major-mode 'cedictlookup-mode) (run-hooks 'cedictlookup-mode-hook)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Ok, that's the end of the cedictlookup-mode code. ;; Now for the actual cedictlookup stuff. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar cedictlookup-dir "/home/hiebeler/chinese/words/vocab" "*Chinese vocabular directory, containing vocabulary files.\n") (defvar cedictlookup-file "vocabulary.gb:cedict.gb:yuyan.gb:yuwen5.gb" "*Chinese vocabulary file(s), as a string of colon-separated filenames.\n") (if (>= emacs-major-version 21) (setq oldcedict nil) (setq oldcedict t)) (message "Starting up chinese cedictlookup process..."); (let ((process-connection-type nil)) (start-process "cedictlookup" "CEDICTLookup" "cedictlookup" "-emacs" "-mm" "s" "-am" "n" "-vd" cedictlookup-dir "-vf" cedictlookup-file)) (message nil) ; Go set the mode in the CEDICTLookup buffer to cedictlookup-mode (save-excursion (set-buffer "CEDICTLookup") (cedictlookup-mode) ) ; Tell emacs that when the user quits emacs, the cedictlookup process ; can be quietly blown away. (process-kill-without-query (get-process "cedictlookup")) ; Set filter for process. (set-process-filter (get-process "cedictlookup") 'cedictlookup-filter) ; Look up character(s) after the cursor. It includes the character ; currently under the cursor. ; If a prefix argument is given (via \C-u), that many characters after ; the point are sent to the cedictlookup process to look up. ; If no prefix argument is given, the user is prompted for how many characters ; forward to use. (defun cedictlookup-forward (numchars) "Look up Chinese character(s) after point. The help information accumulates in the CEDICTLookup buffer.\n" (interactive "NHow many chars:") (let ((cedictlookup-end-pos (if oldcedict (min (+ (point) (* numchars 2)) (point-max)) (min (+ (point) numchars) (point-max)) ) )) (if (>= (following-char) 160) (process-send-string "cedictlookup" (concat (buffer-substring-no-properties (point) cedictlookup-end-pos) "\n")) (message "not a Chinese character")))) ; Look up character(s) before the cursor. It does not include the ; character currently under the cursor. ; If a prefix argument is given (via \C-u), that many characters in ; front of point are sent to the cedictlookup process to look up. ; If no prefix argument is given, the user is prompted for how many characters ; back to use. (defun cedictlookup-backward (numchars) "Look up Chinese character(s) before point. The help information accumulates in the CEDICTLookup buffer.\n" (interactive "NHow many chars:") (let ((cedictlookup-start-pos (if oldcedict (max (- (point) (* numchars 2)) 1) (max (- (point) numchars) 1) ) )) (if (>= (following-char) 160) (process-send-string "cedictlookup" (concat (buffer-substring-no-properties cedictlookup-start-pos (point)) "\n")) (message "not a Chinese character")))) ; Look up character(s) in region in the current buffer. (defun cedictlookup-region (start end) "Look up Chinese character(s) in region. The help information accumulates in the CEDICTLookup buffer.\n" (interactive "r") (if (= start end) (message "Region is empty") (if (>= (char-after start) 160) (process-send-string "cedictlookup" (concat (buffer-substring-no-properties start end) "\n")) (message "not a Chinese character")) ) ) ; A little dummy function that doesn't do anything, but you can call ; it to start up a cedictlookup process without actually looking up any ; words, if you have set cedictlookup to autoload this file. (defun cedictlookup () "Start cedictlookup process\n"; (interactive) ) ; Look up the character(s) (or words) on the current line. ; This is most useful with cedictlookup-mode, so that you can type ; in a Chinese, pinyin, or English phrase and hit return, and cedictlookup ; will look up the word(s). (defun cedictlookup-line () "Look up Chinese character(s) on this line. The help information accumulates in the CEDICTLookup buffer.\n"; (interactive) (save-excursion (beginning-of-line) (let ((beginning-point (point)) (ending-point)) (progn (end-of-line) (setq ending-point (point)) (process-send-string "cedictlookup" (concat (buffer-substring-no-properties beginning-point ending-point) "\n")) ) ) ) ) ; Same as cedictlookup-line, but also calls newline function at end of ; line, to emulate typical behavior of hitting the "return" key. (defun cedictlookup-line-with-newline () "Look up Chinese character(s) on this line, and call (newline) function. The help information accumulates in the CEDICTLookup buffer.\n"; (interactive) (cedictlookup-line) (end-of-line) (newline) ) ; filter process for cedictlookup process. This just sends the output ; to the CEDICTLookup buffer for now, and also displays the buffer if ; it's not already being displayed. (defun cedictlookup-filter (proc str) (let* ((old-buffer (current-buffer)) (old-window (selected-window))) (display-buffer (process-buffer proc)) (progn (set-buffer (process-buffer proc)) (select-window (get-buffer-window (process-buffer proc))) (goto-char (point-max)) (insert str) ) (set-buffer old-buffer) (select-window old-window) )) ;; ;; end of cedictlookup.el ;;