1 e;;; ndic.el --- Lookup by free dictionaries
2 ;; Copyright (C) 1999 Lookup Development Team <lookup@ring.gr.jp>
4 ;; Author: Keisuke Nishida <kei@psn.net>
5 ;; Version: $Id: ndic.el,v 1.2 1999/05/23 17:27:22 knishida Exp $
7 ;; This file is part of Lookup.
9 ;; Lookup is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2 of the License, or
12 ;; (at your option) any later version.
14 ;; Lookup is distributed in the hope that it will be useful, but
15 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with Lookup; if not, write to the Free Software Foundation,
21 ;; Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 (defconst ndic-version "1.0")
30 ;:: Customizable variables
34 "Lookup by free dictionaries."
35 :group 'lookup-agents)
37 (defcustom ndic-dictzip-program "dictzip"
38 "*Program name of dictzip."
51 ;; DIRECTORY - dictionary directory
53 (defun ndic-agent-directory (agent)
54 (expand-file-name (lookup-agent-location agent)))
56 (put 'ndic ':arranges '(lookup-arrange-default-headings))
57 (put 'ndic ':adjusts '(lookup-adjust-goto-min))
61 ;; CODE - cons of TYPE and OBJ:
62 ;; [SDIC] `sdic' and the sdic object
63 ;; [dictd] `dictd' and the buffer of index file (*.index)
64 ;; NAME - filename without directory and extension
67 ;; ndic-dict - [dictd] dictionary file name (i.e. *.dict[.dz])
69 (defun ndic-make-dictionary (agent type obj name)
70 (lookup-new-dictionary agent (cons type obj) name))
72 (defun ndic-dictionary-type (dictionary)
73 (car (lookup-dictionary-code dictionary)))
75 (defun ndic-dictionary-obj (dictionary)
76 (cdr (lookup-dictionary-code dictionary)))
80 ;; CODE - [SDIC] entry returned by sdic-search
81 ;; [dictd] cons of entry position (START . LENGTH)
86 ;:: Interface functions
89 (put 'ndic 'setup 'ndic-setup)
90 (defun ndic-setup (agent)
91 (mapcar (lambda (file)
92 (let ((name (file-name-sans-extension
93 (file-name-nondirectory file))))
94 (if (string-match "\\.sdic$" name)
95 (setq name (substring name 0 (match-beginning 0))))
96 (if (string-match "\\.sdic\\(.\\(gz\\|bz2\\)\\)?$" file)
97 (ndic-setup-sdic agent file name)
98 (ndic-setup-dictd agent file name))))
99 (directory-files (ndic-agent-directory agent) t
100 "\\.\\(sdic\\(\\.\\(gz\\|bz2\\)\\)?\\|index\\)$")))
102 (defun ndic-setup-sdic (agent file name)
104 (let ((dictionary (ndic-make-dictionary agent 'sdic (sdicf-open file) name)))
105 (lookup-dictionary-set-default
106 dictionary ':methods '(exact prefix suffix regexp text))
109 (defun ndic-setup-dictd (agent file name)
110 (let* ((dict (concat (file-name-sans-extension file) ".dict"))
111 (buffer (get-buffer-create (concat " *ndic " file "*")))
112 (dictionary (ndic-make-dictionary agent 'dictd buffer name)))
113 (unless (file-exists-p dict)
114 (setq dict (concat dict ".dz"))
115 (unless (file-exists-p dict)
116 (error "No .dict file for %s" dict)))
117 (lookup-dictionary-put-property dictionary 'ndic-dict dict)
118 (with-current-buffer buffer
119 (insert-file-contents file)
120 (goto-char (point-min))
121 (when (re-search-forward "^00-database-short\t\\([^\t]+\\)\t\\(.*\\)" nil t)
122 (let* ((code (cons (match-string 1) (match-string 2)))
123 (entry (lookup-make-entry dictionary code nil))
124 (title (ndic-dictionary-content dictionary entry)))
125 (if (string-match "\n *\\(.*\\)\n" title)
126 (setq title (match-string 1 title)))
127 (lookup-dictionary-set-default dictionary ':title title))))
128 (lookup-dictionary-set-default
129 dictionary ':methods '(exact prefix suffix substring regexp keyword))
132 (put 'ndic 'clear 'ndic-clear)
133 (defun ndic-clear (agent)
134 (lookup-foreach (lambda (dictionary)
135 (let ((type (ndic-dictionary-type dictionary)))
136 (cond ((eq type 'sdic)
137 (sdicf-close (ndic-dictionary-obj dictionary)))
139 (kill-buffer (ndic-dictionary-obj dictionary))))))
140 (lookup-agent-dictionaries agent)))
142 (put 'ndic 'search 'ndic-dictionary-search)
143 (defun ndic-dictionary-search (dictionary query)
144 (let ((type (ndic-dictionary-type dictionary)))
145 (cond ((eq type 'sdic) (ndic-search-sdic dictionary query))
146 ((eq type 'dictd) (ndic-search-dictd dictionary query)))))
148 (defun ndic-search-sdic (dictionary query)
149 (mapcar (lambda (entry)
150 (lookup-make-entry dictionary entry (sdicf-entry-headword entry)))
151 (sdicf-search (ndic-dictionary-obj dictionary)
152 (lookup-query-method query)
153 (lookup-query-string query))))
155 (defun ndic-search-dictd (dictionary query)
156 (let* ((method (lookup-query-method query))
157 (string (lookup-query-string query))
158 (regexp (regexp-quote string)))
160 (cond ((eq method 'keyword) (concat "^[^\t]*\\<" regexp "\\>"))
161 ((eq method 'prefix) (concat "^[^\t]*\\<" regexp))
162 ((eq method 'suffix) (concat "^[^\t]*" regexp "\\>"))
163 ((eq method 'exact) (concat "^" regexp "\t"))
164 ((eq method 'substring) (concat "^[^\t]*" regexp))
165 ((eq method 'regexp) string)))
166 (let ((case-fold-search t) entries)
167 (with-current-buffer (ndic-dictionary-obj dictionary)
168 (goto-char (point-min))
169 (while (re-search-forward regexp nil t)
170 (setq string (buffer-substring (progn (beginning-of-line) (point))
171 (1- (search-forward "\t"))))
172 (if (looking-at "\\([^\t]+\\)\t\\(.*\\)")
173 (setq entries (cons (lookup-make-entry dictionary
174 (cons (match-string 1)
178 (nreverse entries)))))
180 (put 'ndic 'content 'ndic-dictionary-content)
181 (defun ndic-dictionary-content (dictionary entry)
182 (let ((type (ndic-dictionary-type dictionary)))
183 (cond ((eq type 'sdic) (ndic-content-sdic dictionary entry))
184 ((eq type 'dictd) (ndic-content-dictd dictionary entry)))))
186 (defun ndic-content-sdic (dictionary entry)
187 (setq entry (lookup-entry-code entry))
188 (format "%s\n\n %s\n" (sdicf-entry-headword entry)
189 (sdicf-entry-text entry)))
191 (defun ndic-content-dictd (dictionary entry)
192 (let ((code (lookup-entry-code entry))
193 (dict (lookup-dictionary-get-property dictionary 'ndic-dict)))
195 (if (string-match "\\.dz$" dict)
196 (call-process ndic-dictzip-program nil t nil
197 "-cdk" "-S" (car code) "-E" (cdr code) dict)
198 (let ((offset (ndic-b64-decode (car code)))
199 (length (ndic-b64-decode (cdr code))))
200 (insert-file-contents dict nil offset (+ offset length))))
205 ;:: Internal functions
208 (defconst ndic-b64-table
209 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
211 (defun ndic-b64-decode (code)
212 (let ((n 0) (len (length code)) (value 0)
213 (case-fold-search nil))
215 (if (string-match (substring code n (1+ n)) ndic-b64-table)
216 (setq value (+ (* value 64) (match-beginning 0))))
222 ;;; ndic.el ends here