root/lang/elisp/pdicv-mode/trunk/pdicv-core.el @ 75

Revision 75, 21.9 kB (checked in by naoya_t, 18 years ago)

case doesn't work well when byte-compiled... so replaced by cond

Line 
1;;; pdicv-core.el --- core functions for PDIC-formatted dictionaries
2;;
3;; Copyright (C) 2005-2009 naoya_t. All Rights Reserved.
4;;
5;; Author: naoya_t <naoya.t@aqua.plala.or.jp>
6;; Maintainer: naoya_t <naoya.t@aqua.plala.or.jp>
7;; Primary distribution site:
8;;   http://lambdarepos.svnrepository.com/svn/share/lang/elisp/pdicv-mode/trunk
9;;
10;; Created: 14 Feb 2005
11;; Last modified: 30 Jan 2009
12;; Version: 0.9.2
13;; Keywords: PDIC dictionary search eijiro
14
15(provide 'pdicv-core)
16;(put 'pdicv-core 'version "0.9.2")
17
18;;; Commentary:
19
20; (pdicv-get-header-info FILENAME)
21;    - ��ؒ�Ò���������ߒ�蒤�
22; (pdicv-get-index-list FILENAME [WORD-ENCODING])
23;    - PDIC��������������뒤���钡���������Ò�������꒥���Ȓ����
24;
25; (pdicv-scan-datablock FILENAME PHYS CRITERIA-FUNC)
26;    - ��ǒ�������֒�풥Ò����򒥹�����㒥�; (pdicv-core-search DICINFO CRITERIA [SIMPLE-MODE-P DONT-CLEAR-P])
27;    - PDIC��������������뒡������
28;
29
30;;; Code:
31(require 'nt-macros)
32(require 'nt-readval)
33(require 'nt-string)
34(require 'nt-bocu)
35(require 'nt-file)
36(require 'nt-english)
37
38; decoder
39(defvar pdicv-null-decoder (lambda (s) s))
40(defvar pdicv-sjis-decoder (lambda (s) (decode-coding-string s 'japanese-shift-jis-dos)))
41(defvar pdicv-latin1-decoder (lambda (s) (decode-coding-string s 'iso-latin-1-dos)))
42(defvar pdicv-bocu-decoder (lambda (s) (nt:bocu-decode s)))
43(defmacro pdicv-create-decoder (encoding)
44  "create a decoder from user-specified encoding"
45  `(lambda (s) (decode-coding-string s ,encoding)))
46
47(defvar pdicv-index-table-list ())
48
49(defvar pdicv-result-height 8)
50;
51; ��ؒ�Ò���������ߒ�蒤�
52(defun pdicv-get-header-info (filename)
53  "[PDIC] Get Header Info"
54  (catch 'pdicv-get-header-info
55    (let* ((header-buf (nt:read-from-file filename 0 256))
56           ;
57           (headername nil); (substring header-buf 1 100))
58           (dictitle nil); (substring header-buf 101 140))
59           (version (nt:read-short header-buf 140))
60           (lword (nt:read-short header-buf 142))
61           (ljapa (nt:read-short header-buf 144))
62           (block-size (nt:read-short header-buf 146))
63           (index-block (nt:read-short header-buf 148))
64           (header-size (nt:read-short header-buf 150))
65           (index-size (nt:read-ushort header-buf 152))
66           (empty-block (nt:read-short header-buf 154))
67           (nindex (nt:read-short header-buf 156))
68           (nblock (nt:read-short header-buf 158))
69           (nword (nt:read-ulong header-buf 160))
70           (dicorder (nt:read-uchar header-buf 164))
71           (dictype (nt:read-uchar header-buf 165)) (dictype* nil)
72           (attrlen (nt:read-uchar header-buf 166))
73                                        ; NEWDIC2-
74           (olenumber 0) (os nil)
75           (lid-word 0) (lid-japa 0) (lid-exp 0) (lid-pron 0) (lid-other 0)
76                                        ; NEWDIC3-
77           (extheader 0) (index-blkbit 0) (cypt nil) (update-count 0)
78           (dicident nil)
79           ;;
80           (major-version (/ version 256))
81           (datablock-size (* nblock block-size))
82           (bocu nil)
83           )
84
85      (setq version
86            (nth major-version '(not-supported not-supported newdic1 newdic2 newdic3 newdic4 unicode-bocu-6)))
87
88      (setq dicorder
89            (nth (nt:read-uchar header-buf 164) '(code-order ignore-case dictionary-order order-descendant)))
90
91      (when (> (logand dictype 128) 0) (setq dictype* (cons 'tree-view-mode dictype*)))
92      (when (> (logand dictype 64) 0) (setq dictype* (cons 'crypted dictype*)))
93;     (when (> (logand dictype 32) 0) (setq dictype* (cons 'multilingual dictype*)))
94      (when (> (logand dictype 16) 0) (setq dictype* (cons 'unicode dictype*)))
95      (when (> (logand dictype 8) 0) (setq dictype* (cons 'bocu dictype*)))
96      (when (> (logand dictype 1) 0) (setq dictype* (cons 'ar-compressed dictype*)))
97
98          ;;(case major-version
99          (cond
100           ((= major-version 6)
101                ;;(6 "Ver 6.xx"
102                   (setq os (nt:read-char header-buf 167))
103                   (setq os (cond ((= os 0) 'sjis-crlf)
104                                                  ((= os 1) 'sjis-cr)
105                                                  ((= os 2) 'sjis-lf)
106                                                  ((= os 3) 'euc-lf)
107                                                  ((= os 4) 'jis-lf)
108                                                  ((= os 32) 'bocu)
109                                                  ))
110                   (when (eq os 'bocu) (setq bocu t))
111                   (setq olenumber (nt:read-long header-buf 168))
112                   ;; dummy_lid, 10 bytes
113                   (setq index-blkbit (if (= (nt:read-uchar header-buf 182) 1) 32 16))
114                   ;; dummy0 @185
115                   (setq extheader (nt:read-ulong header-buf 184))
116                   (setq empty-block (nt:read-long header-buf 188)) ;overwrite
117                   (setq nindex (nt:read-long header-buf 192)) ;overwrite
118                   (setq nblock (nt:read-long header-buf 196)) ;overwrite
119                   (setq datablock-size (* nblock block-size))
120                   (setq cypt (substring header-buf 200 208)) ;- reserved[8]
121                   (setq update-count (nt:read-ulong header-buf 208))
122                                        ; dummy00 @212[4]
123                   (setq dicident (substring header-buf 216 224))
124                                        ;(setq dummy (substring header-buf 224 256))
125                   (setq index-size (* index-block block-size)) ;overwrite
126                   );6
127           ((= major-version 5)
128                ;;(5 "HyperDIC, Ver 5.00"
129                   (setq os (nt:read-char header-buf 167))
130                   (setq os (cond ((= os 0) 'sjis-crlf)
131                                                  ((= os 1) 'sjis-cr)
132                                                  ((= os 2) 'sjis-lf)
133                                                  ((= os 3) 'euc-lf)
134                                                  ((= os 4) 'jis-lf)
135                                                  ((= os 32) 'bocu)
136                                                  ))
137                   (when (eq os 'bocu) (setq bocu t))
138                   (setq olenumber (nt:read-long header-buf 168))
139                   (setq index-blkbit (if (= (nt:read-uchar header-buf 182) 1) 32 16))
140                   ;; dummy0 @185
141                   (setq extheader (nt:read-ulong header-buf 184))
142                   (setq empty-block (nt:read-long header-buf 188)) ;overwrite
143                   (setq nindex (nt:read-long header-buf 192)) ;overwrite
144                   (setq nblock (nt:read-long header-buf 196)) ;overwrite
145                   (setq datablock-size (* nblock block-size))
146                   (setq cypt (substring header-buf 200 208)) ;- reserved[8]
147                   (setq update-count (nt:read-ulong header-buf 208))
148                                        ; dummy00 @212[4]
149                   (setq dicident (substring header-buf 216 224))
150                                        ;(setq dummy (substring header-buf 224 256))
151                   (setq index-size (* index-block block-size)) ;overwrite
152                   );5
153           (t "< 5.0"
154                   (when (>= major-version 3)
155                         "NEWDIC2-"
156                         (setq olenumber (nt:read-long header-buf 167))
157                                        ;(setq os (byte (substring header-buf 172 173)))
158                         (setq os (nth (nt:read-char header-buf 171) '(sjis-crlf)))
159                                        ;(setq lid-word (short header-buf 172))
160                                        ;(setq lid-japa (short header-buf 174))
161                                        ;(setq lid-exp (short header-buf 176))
162                                        ;(setq lid-pron (short header-buf 178))
163                                        ;(setq lid-other (short header-buf 180))
164                         )
165                   (when (>= major-version 4)
166                         "NEWDIC3-"
167                         (setq extheader (nt:read-ulong header-buf 182))
168                         (setq empty-block (nt:read-long header-buf 186)) ;overwrite
169                         (setq nindex (nt:read-long header-buf 190)) ;overwrite
170                         (setq nblock (nt:read-long header-buf 194)) ;overwrite
171                         (setq datablock-size (* nblock block-size))
172                         (setq index-blkbit (if (= (nt:read-uchar header-buf 198) 1) 32 16))
173                         (setq cypt (substring header-buf 200 208))
174                         (setq update-count (nt:read-ulong header-buf 207))
175                                        ;(setq dummy (substring header-buf 212 256))
176                         (setq index-size (* index-block block-size)) ;overwrite
177                         )
178               )); esac
179      (list
180;       (cons 'headername headername)   ;
181;       (cons 'dictitle dictitle)       ;
182       (cons 'version version)         ;
183       (cons 'lword lword)             ;
184       (cons 'ljapa ljapa)             ;
185       (cons 'block-size block-size)   ;
186       (cons 'index-block index-block) ;
187       (cons 'header-size header-size) ;
188       (cons 'index-size index-size)   ;
189       (cons 'empty-block empty-block) ;
190       (cons 'nindex nindex)           ;
191       (cons 'nblock nblock)           ;
192       (cons 'nword nword)             ;
193       (cons 'dicorder dicorder)       ;
194       (cons 'dictype dictype*)        ;
195       (cons 'attrlen attrlen)         ;
196       (cons 'os os)                   ;
197                                        ;       (cons 'lid-word lid-word) ;
198                                        ;       (cons 'lid-japa lid-japa) ;
199                                        ;       (cons 'lid-exp lid-exp) ;
200                                        ;       (cons 'lid-pron lid-pron) ;
201                                        ;       (cons 'lid-other lid-other) ;
202       (cons 'extheader extheader) ;
203       (cons 'index-blkbit index-blkbit) ;(0=16,1=32)
204       (cons 'cypt cypt) ;
205       (cons 'update-count update-count) ;
206       
207       (cons 'index-begins-at (+ header-size extheader))
208       (cons 'datablock-begins-at (+ header-size extheader index-size))
209       (cons 'datablock-ends-at (+ header-size extheader index-size datablock-size))
210       (cons 'datablock-size datablock-size)
211       (cons 'bocu bocu)))))
212
213(defun pdicv-get-index-list (filename &optional word-encoding)
214  "[PDICV] Get the index list from PDIC file"
215  (let* ((header (pdicv-get-header-info filename))
216         (index-buf (nt:read-from-file filename
217                                    (-> header 'index-begins-at) (-> header 'index-size)))
218
219         (32bit-address-mode (if (= (-> header 'index-blkbit) 32) t nil))
220                 (tab-sep-p (eq 'unicode-bocu-6 (-> header 'version)))
221
222         (ix 0) (ix-max (-> header 'nindex))
223         (ofs 0)
224         (index-list ()))
225    (while (< ix ix-max)
226      (let ((phys -1) (word "") (word* nil))
227        (if 32bit-address-mode
228            (progn (setq phys (nt:read-ulong index-buf ofs))
229                                   (setq ofs (+ ofs 4)))
230          (progn (setq phys (nt:read-ushort index-buf ofs))
231                                 (setq ofs (+ ofs 2))))
232        (setq word* (nt:read-cstring index-buf ofs)) (setq ofs (+ ofs (cdr word*) 1))
233        (setq word (car word*))
234
235                (when tab-sep-p
236                  (let ((tsv (split-string word "\t")))
237                        (when (consp tsv)
238                          (setq word (car tsv)))))
239;       (cond
240;        ((eq word-encoding 'bocu)
241;         (setq word (nt:bocu-decode word)))
242;        ((eq word-encoding 'sjis)
243;         (setq word (decode-coding-string word 'japanese-shift-jis-dos)))
244;        (word-encoding
245;         (setq word (decode-coding-string word word-encoding)))
246;        (t nil))
247
248;       (setq index-list (cons (cons phys word) index-list))
249        (push (cons phys word) index-list)
250        (setq ix (1+ ix))
251        ))
252    (nreverse index-list) ))
253
254(defface pdicv-face-dummy
255  '((( (class color) (background light) )
256     (:foreground "green" :background "SlateGray1" :weight bold))
257    (t
258     (:foreground "red" :background "black"))) ; :weight bold
259    "Face for caption")
260(defface pdicv-face-caption-red
261  '((t (:foreground "red" :background "black")))
262  "Face for caption")
263(defface pdicv-face-caption-blue
264  '((t (:foreground "blue" :background "black")))
265  "Face for caption")
266(defface pdicv-face-caption-green
267  '((t (:foreground "green" :background "black")))
268  "Face for caption")
269(defface pdicv-face-gray
270  '((t (:foreground "gray")))
271  "Face for text")
272
273(defvar pdicv-default-inserter
274  (lambda (eword pron jword example)
275        (progn
276          (set-text-properties 0 (length eword) '(face bold) eword)
277                                        ;       (set-text-properties 0 (length eword) '(face pdicv-face-caption-green) eword)
278                                        ;       (set-text-properties 0 (length jword) '(face pdicv-face-caption-gray) jword)
279
280          (setq jword (nt:replace-all jword "������/ "))
281          (setq jword (nt:replace-all jword "\n" "\n  "))
282
283          (let ((buf ""))
284                (setq buf eword)
285                (when (string< "" pron) (setq buf (concat buf " [" pron "]")))
286                                        ;               (setq result (concat result " : " jword))
287                (setq buf (concat buf "\n  " jword))
288                (when (string< "" example) (setq buf (concat buf "\n  - " example)))
289                                        ;             (setq buf (concat buf "\n"))
290;            (setq buf (concat buf "\n\n"))
291                (setq buf (concat buf "\n"))
292
293                (insert buf)))))
294;;
295;;
296;;
297(defun pdicv-scan-datablock (filename phys criteria-func)
298  "[PDICV] scan a datablock"
299  (catch 'pdicv-scan-datablock
300    (let* ((result ()) ;(match-count 0)
301           (header (pdicv-get-header-info filename))
302                   (tab-sep-p (eq 'unicode-bocu-6 (-> header 'version)))
303                   (block-size (-> header 'block-size))
304           (offset (+ (-> header 'datablock-begins-at) (* phys block-size)))
305                   (aligned (and (member (-> header 'version) '(newdic4 unicode-bocu-6)) t))
306                   ;; (bocu (-> header 'bocu))
307           (head-word (nt:read-ushort (nt:read-from-file filename offset 2)))
308           (blocks (logand 32767 head-word))
309           (block-length (- (* blocks block-size) 2))
310           (field-size (if (zerop (logand 32768 head-word)) 2 4))
311           (datablock (nt:read-from-file filename (+ offset 2) block-length))
312                                        ;    (list blocks field-size datablock)
313           (p 0)
314                   (field-length 0)
315           (compress-length 0)
316           (rest nil)
317           (eword "") (eword-attrib 0)
318           )
319
320      (while (< p block-length) ;    (while (< p field-size)
321        (setq field-length
322              (if (= field-size 2) (nt:read-ushort datablock p) (nt:read-ulong datablock p)) )
323        (when (zerop field-length) (throw 'pdicv-scan-datablock (nreverse result))); sfield-list))
324        (setq p (+ p field-size)) ;2��ʒ�����4��В�����        (setq compress-length (nt:read-uchar datablock p)) ; �����̒Ĺ
325        (setq p (1+ p))
326
327        (when aligned
328                  (setq eword-attrib (nt:read-uchar datablock p)) ; �����В��������
329                  (setq p (1+ p)))
330                                        ; �����В����쒰ʒ�ߒ����꒤������� rest ��˒���쒤�       (setq rest (substring datablock p (+ p field-length)))
331        (setq p (+ p field-length))
332                                        ; �����В�����NULL����ü)
333        (let* ((eword-cstr (nt:read-cstring rest))
334               (eword-compressed (car eword-cstr)) (eword-len (cdr eword-cstr))
335               (q 0)
336               (level 0)
337               (extended nil)
338               (jword-cstr nil) (jword "") (jword-len 0)
339               (ext-list nil)
340               (example "") (pron "") (link ""))
341
342          (setq eword (if (zerop compress-length)
343                          eword-compressed
344                        (concat (substring eword 0 compress-length) eword-compressed) ))
345          (setq q (1+ eword-len))
346                  ;; �����В��������
347          (when (not aligned)
348                        (setq eword-attrib (nt:read-uchar rest q))
349                        (setq q (1+ q)))
350
351          (setq level (logand eword-attrib 15))
352;         (insert (format ": %s %d %d\n" eword eword-len eword-attrib))
353;;        (if (zerop (logand eword-attrib 128))
354;;            (throw 'pdicv-scan-datablock ()); 'illegal)
355          (setq eword-attrib (logand eword-attrib 127))
356
357          (setq extended (if (zerop (logand eword-attrib 16)) nil t))
358          (if extended
359              (progn ;��Ȓĥ
360                (setq jword-cstr (nt:read-cstring rest q))
361                (setq jword (car jword-cstr)) (setq jword-len (cdr jword-cstr))
362                (setq q (+ q jword-len 1))
363                (setq ext-list nil)
364                (catch 'while
365                  (while (< q field-length)
366                    (let* ((ex-attrib (nt:read-uchar rest q))
367                           (ex-attrib-sub (logand ex-attrib 15))
368                           (exdata-cstr nil)
369                           (exdata "") (exdata-len 0) )
370                      (when (= (logand ex-attrib 128) 128) (throw 'while t))
371                      (setq q (1+ q))
372                      (setq exdata-cstr (nt:read-cstring rest q))
373                      (setq exdata (car exdata-cstr))
374                      (setq exdata-len (cdr exdata-cstr))
375                      (cond
376                       ((= ex-attrib-sub 1) (setq example exdata))
377                       ((= ex-attrib-sub 2) (setq pron exdata))
378                       ((= ex-attrib-sub 4) (setq link exdata))
379                       (t nil))
380                      (setq q (+ q exdata-len 1))
381                      ) ; let*
382                    ) ; while
383                  ) ; catch while2
384                ) ; progn
385            (progn ;�ɸ���             (setq jword (substring rest q))
386              (setq pron "")
387              (setq example ""))
388            ) ; if extended
389
390                  (if tab-sep-p
391                          (let* ((splitted (split-string eword "\t"))
392                                         (eword (car splitted))
393                                         (entry (cadr splitted)))
394                                (when (funcall criteria-func entry eword pron jword example)
395                                  (push (list entry pron jword example) result)))
396                        (when (funcall criteria-func eword eword pron jword example)
397                          (push (list eword pron jword example) result)))
398                  ;;(when (funcall criteria-func eword pron jword example)
399                  ;;    (push (list eword pron jword example) result))
400          );let
401        ); wend
402      (nreverse result))))
403
404(defun pdicv-core-search (dicinfo criteria &optional simple-mode-p dont-clear-p)
405  "search in PDIC"
406  (let* ((dicname (car dicinfo))
407         (dicfile (nth 1 dicinfo))
408         (encoding-list (nth 2 dicinfo))
409         (decoder-list ())
410         (index-table (-> pdicv-index-table-list dicname)))
411;    (if (null index-table) (setq index-table (pdicv-get-index-list dicfile)))
412
413    (when (atom encoding-list) ;; expand encoding-list
414          (setq encoding-list (list encoding-list encoding-list encoding-list encoding-list)))
415 
416    (while encoding-list ;; build the decoder-list
417      (let ((encoding (car encoding-list)))
418        (cond
419         ((eq encoding 'bocu) (push pdicv-bocu-decoder decoder-list))
420         ((eq encoding 'sjis) (push pdicv-sjis-decoder decoder-list))
421         ((eq encoding 'latin1) (push pdicv-latin1-decoder decoder-list))
422         (encoding (push (pdicv-create-decoder encoding) decoder-list))
423         (t (push pdicv-null-decoder decoder-list))))
424      (setq encoding-list (cdr encoding-list)))
425    (setq decoder-list (nreverse decoder-list))
426
427    (catch 'pdicv-core-search
428;      (if (null original-word-to-search) (setq original-word-to-search word-to-search))
429      (let* (;(buffer-name (generate-new-buffer-name *buffer-name))
430                                        ;               (pdicv-buffer-name "*PDIC Viewer*")
431                                        ;               (dummy (if (get-buffer pdicv-buffer-name) (kill-buffer pdicv-buffer-name)))
432             (pdicv-buffer (get-buffer-create "*PDIC Viewer*"))
433                                        ;criteria
434             (word-to-search (car criteria))
435
436             (index-needles (nth 1 criteria))
437             (needle1 (car index-needles))
438             (needle2 (cdr index-needles))
439
440             (datablock-criteria-func (nth 2 criteria))
441
442             (ix index-table) (index-size (length ix)) (curr-size index-size)
443             (ix+ (cadr ix)); next one
444             (match-count 0))
445
446;         (switch-to-buffer pdicv-buffer-name)
447        (save-current-buffer
448          (set-buffer pdicv-buffer)
449          (when (null dont-clear-p) (erase-buffer))
450
451          (when (not simple-mode-p)
452                                        ;(pop-to-buffer pdicv-buffer-name)
453                                        ;              (set-buffer pdicv-buffer-name)
454                        (insert (format "��������� %s\n" word-to-search))
455                        (insert (format "��������???\n"))
456                        (newline))
457                                        ;(insert "\n"))
458          (when index-needles
459                        (setq ix
460                                  (let ((p ix) (last-p nil))
461                                        (catch 'pdicv-search-in-index
462                                          (while p
463                                                (let* ((elem (car p)) ;(phys (car elem))
464                                                           (word (cdr elem)))
465                                                  (if (string< needle1 word) (throw 'pdicv-search-in-index last-p))
466                                                  ;; (if (string< needle2 word) (throw 'pdicv-search-in-index last-p))
467                            (setq last-p p)
468                            (setq p (cdr p)) ))
469                                          last-p))))
470          (catch 'while
471            (while ix
472              (let* ((curr (car ix))
473                     (phys (car curr)) (word (cdr curr))
474                                         ;; (x (insert (format "* current ix: (%d %s)\n" phys word)))
475                     (result (pdicv-scan-datablock dicfile phys datablock-criteria-func)); decoder-list nil))
476                     (result-count (length result))
477                     (inserter pdicv-default-inserter))
478                (when index-needles
479                                  (when (string>= word needle2) (throw 'while t)))
480                                ;;  (if (not (string< word (cdr index-needles))) (throw 'while t)))
481
482                                        ;               (insert (format "(%s with index %s ... %s)\n"
483                                        ;                               word-to-search
484                                        ;                               (funcall (nth 0 decoder-list) word) result))
485
486                (if result (progn
487                             (while result
488                               (let ((rec (pop result)))
489                                 (funcall inserter
490                                          (funcall (nth 0 decoder-list) (nth 0 rec)); eword
491                                          (funcall (nth 1 decoder-list) (nth 1 rec)); pron
492                                          (funcall (nth 2 decoder-list) (nth 2 rec)); jword
493                                          (funcall (nth 3 decoder-list) (nth 3 rec)); example
494                                          )
495                                 (setq match-count (1+ match-count))
496                                 ))
497                             (message "%5d/%5d:%7d" curr-size index-size match-count)
498                             (sit-for 0))
499                  ;;else
500                                  (when (zerop (% curr-size 128)) ;;128��ϒŬ����ʒ��                      (message "%5d/%5d:%7d" curr-size index-size match-count))))
501              (setq ix (cdr ix))
502              (setq curr-size (1- curr-size))
503              );wend
504            );caught
505
506                  ;;(insert (pdicv-scan-datablock dicfile (car (car ix)) decoder-list nil needle1 needle2))
507          (goto-char 1)
508
509          (when (not simple-mode-p)
510                        (when (re-search-forward ": [?][?][?][?]" nil t nil)
511                          (replace-match (format ": %d" match-count) t t nil 0)))
512          ); save-current-buffer
513
514;      (pop-to-buffer (current-buffer))
515;        (setq split-height-threshold 6)
516        (when (one-window-p)
517                  (set-window-buffer (split-window-vertically (- pdicv-result-height)) pdicv-buffer))
518        ))))
519
520;;; pdicv-core.el ends here
Note: See TracBrowser for help on using the browser.