5e7b76fe2b671acaa9e250ab730d2d129c1cee96
[chise/xemacs-chise.git] / lisp / utf-2000 / char-db-util.el
1 ;;; char-db-util.el --- Character Database utility
2
3 ;; Copyright (C) 1998, 1999 MORIOKA Tomohiko.
4
5 ;; Author: MORIOKA Tomohiko <tomo@m17n.org>
6 ;; Keywords: UTF-2000, ISO/IEC 10646, Unicode, UCS-4, MULE.
7
8 ;; This file is part of UTF-2000.
9
10 ;; UTF-2000 is free software; you can redistribute it and/or modify it
11 ;; under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; UTF-2000 is distributed in the hope that it will be useful, but
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 ;; General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with XEmacs; see the file COPYING.  If not, write to the Free
22 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23 ;; 02111-1307, USA.
24
25 ;;; Code:
26
27 (require 'alist)
28
29 (defconst unidata-normative-category-alist
30   '(("Lu" letter        uppercase)
31     ("Ll" letter        lowercase)
32     ("Lt" letter        titlecase)
33     ("Mn" mark          non-spacing)
34     ("Mc" mark          spacing-combining)
35     ("Me" mark          enclosing)
36     ("Nd" number        decimal-digit)
37     ("Nl" number        letter)
38     ("No" number        other)
39     ("Zs" separator     space)
40     ("Zl" separator     line)
41     ("Zp" separator     paragraph)
42     ("Cc" other         control)
43     ("Cf" other         format)
44     ("Cs" other         surrogate)
45     ("Co" other         private-use)
46     ("Cn" other         not-assigned)))
47
48 (defconst unidata-informative-category-alist
49   '(("Lm" letter        modifier)
50     ("Lo" letter        other)
51     ("Pc" punctuation   connector)
52     ("Pd" punctuation   dash)
53     ("Ps" punctuation   open)
54     ("Pe" punctuation   close)
55     ("Pi" punctuation   initial-quote)
56     ("Pf" punctuation   final-quote)
57     ("Po" punctuation   other)
58     ("Sm" symbol        math)
59     ("Sc" symbol        currency)
60     ("Sk" symbol        modifier)
61     ("So" symbol        other)
62     ))
63
64 (defconst ideographic-radicals
65   (let ((v (make-vector 215 nil))
66         (i 1))
67     (while (< i 215)
68       (aset v i (int-char (+ #x2EFF i)))
69       (setq i (1+ i)))
70     (if (< (charset-iso-final-char (car (split-char (aref v 34)))) ?0)
71         (aset v 34 (make-char 'chinese-gb2312 #x62 #x3A)))
72     v))
73
74 (defun char-attribute-name< (ka kb)
75   (cond
76    ((find-charset ka)
77     (cond
78      ((find-charset kb)
79       (cond
80        ((= (charset-dimension ka)
81            (charset-dimension kb))
82         (cond ((= (charset-chars ka)(charset-chars kb))
83                (cond
84                 ((>= (charset-final ka) ?@)
85                  (if (>= (charset-final kb) ?@)
86                      (< (charset-final ka)
87                         (charset-final kb))
88                    t))
89                 ((>= (charset-final ka) ?0)
90                  (cond
91                   ((>= (charset-final kb) ?@)
92                    nil)
93                   ((>= (charset-final kb) ?0)
94                    (< (charset-final ka)
95                       (charset-final kb)))
96                   (t)))))
97               ((<= (charset-chars ka)(charset-chars kb)))))
98        (t
99         (< (charset-dimension ka)
100            (charset-dimension kb))
101         )))
102      (t)))
103    ((find-charset kb)
104     t)
105    ((symbolp ka)
106     (cond ((symbolp kb)
107            (string< (symbol-name ka)
108                     (symbol-name kb)))
109           (t)))
110    ((symbolp kb)
111     nil)))
112
113 (defun insert-char-data (char)
114   (let ((data (char-attribute-alist char))
115         cell ret name has-long-ccs-name rest)
116     (when data
117       (save-restriction
118         (narrow-to-region (point)(point))
119         (insert "(define-char
120   '(")
121         (when (setq cell (assq 'name data))
122           (setq cell (cdr cell))
123           (insert (format
124                    (if (> (length cell) 47)
125                        "(name . %S)
126     "
127                      "(name\t\t. %S)
128     ")
129                    cell))
130           (setq data (del-alist 'name data))
131           )
132         (when (setq cell (assq 'name data))
133           (setq cell (cdr cell))
134           (insert (format
135                    (if (> (length cell) 47)
136                        "(name . %S)
137     "
138                      "(name\t\t. %S)
139     ")
140                    cell))
141           (setq data (del-alist 'name data))
142           )
143         (when (setq cell (assq 'ucs data))
144           (setq cell (cdr cell))
145           (insert (format "(ucs\t\t. #x%04X)
146     "
147                           cell))
148           (setq data (del-alist 'ucs data))
149           )
150         (when (setq cell (assq '->ucs data))
151           (setq cell (cdr cell))
152           (insert (format "(->ucs\t\t. #x%04X)
153     "
154                           cell))
155           (setq data (del-alist '->ucs data))
156           )
157         (when (setq cell (assq 'general-category data))
158           (setq ret (cdr cell))
159           (insert (format
160                    "(general-category\t%s) ; %s
161     "
162                    (mapconcat (lambda (cell)
163                                 (format "%S" cell))
164                               ret " ")
165                    (cond ((rassoc (cdr cell)
166                                   unidata-normative-category-alist)
167                           "Normative Category")
168                          ((rassoc (cdr cell)
169                                   unidata-informative-category-alist)
170                           "Informative Category")
171                          (t
172                           "Unknown Category"))))
173           (setq data (del-alist 'general-category data))
174           )
175         (when (setq cell (assq 'bidi-category data))
176           (setq cell (cdr cell))
177           (insert (format "(bidi-category\t. %S)
178     "
179                           cell))
180           (setq data (del-alist 'bidi-category data))
181           )
182         (when (setq cell (assq 'mirrored data))
183           (setq cell (cdr cell))
184           (insert (format "(mirrored\t\t. %S)
185     "
186                           cell))
187           (setq data (del-alist 'mirrored data))
188           )
189         (cond
190          ((setq cell (assq 'decimal-digit-value data))
191           (setq cell (cdr cell))
192           (insert (format "(decimal-digit-value . %S)
193     "
194                           cell))
195           (setq data (del-alist 'decimal-digit-value data))
196           (when (setq cell (assq 'digit-value data))
197             (setq cell (cdr cell))
198             (insert (format "(digit-value\t . %S)
199     "
200                             cell))
201             (setq data (del-alist 'digit-value data))
202             )
203           (when (setq cell (assq 'numeric-value data))
204             (setq cell (cdr cell))
205             (insert (format "(numeric-value\t . %S)
206     "
207                             cell))
208             (setq data (del-alist 'numeric-value data))
209             )
210           )
211          (t
212           (when (setq cell (assq 'digit-value data))
213             (setq cell (cdr cell))
214             (insert (format "(digit-value\t. %S)
215     "
216                             cell))
217             (setq data (del-alist 'digit-value data))
218             )
219           (when (setq cell (assq 'numeric-value data))
220             (setq cell (cdr cell))
221             (insert (format "(numeric-value\t. %S)
222     "
223                             cell))
224             (setq data (del-alist 'numeric-value data))
225             )))
226         (when (setq cell (assq 'iso-10646-comment data))
227           (setq cell (cdr cell))
228           (insert (format "(iso-10646-comment\t. %S)
229     "
230                           cell))
231           (setq data (del-alist 'iso-10646-comment data))
232           )
233         (when (setq cell (assq 'ideographic-radical data))
234           (setq cell (cdr cell))
235           (insert (format "(ideographic-radical . %S)\t; %c
236     "
237                           cell
238                           (aref ideographic-radicals cell)))
239           (setq data (del-alist 'ideographic-radical data))
240           )
241         (cond
242          ((setq cell (assq 'ideographic-strokes data))
243           (setq cell (cdr cell))
244           (insert (format "(ideographic-strokes . %S)
245     "
246                           cell))
247           (setq data (del-alist 'ideographic-strokes data))
248           (when (setq cell (assq 'total-strokes data))
249             (setq cell (cdr cell))
250             (insert (format "(total-strokes\t . %S)
251     "
252                             cell))
253             (setq data (del-alist 'total-strokes data))
254             ))
255          ((setq cell (assq 'total-strokes data))
256           (setq cell (cdr cell))
257           (insert (format "(total-strokes\t. %S)
258     "
259                           cell))
260           (setq data (del-alist 'total-strokes data))
261           ))
262         (when (setq cell (assq '->decomposition data))
263           (setq cell (cdr cell))
264           (insert (format "(->decomposition\t%s)
265     "
266                           (mapconcat (lambda (code)
267                                        (cond ((symbolp code)
268                                               (symbol-name code))
269                                              ((integerp code)
270                                               (format "#x%04X" code))
271                                              (t
272                                               (format "\n     %S" code))))
273                                      cell " ")))
274           (setq data (del-alist '->decomposition data))
275           )
276         (when (setq cell (assq '->uppercase data))
277           (setq cell (cdr cell))
278           (insert (format "(->uppercase\t%s)
279     "
280                           (mapconcat (lambda (code)
281                                        (cond ((symbolp code)
282                                               (symbol-name code))
283                                              ((integerp code)
284                                               (format "#x%04X" code))
285                                              (t
286                                               (format "\n     %S" code))))
287                                      cell " ")))
288           (setq data (del-alist '->uppercase data))
289           )
290         (when (setq cell (assq '->lowercase data))
291           (setq cell (cdr cell))
292           (insert (format "(->lowercase\t%s)
293     "
294                           (mapconcat (lambda (code)
295                                        (cond ((symbolp code)
296                                               (symbol-name code))
297                                              ((integerp code)
298                                               (format "#x%04X" code))
299                                              (t
300                                               (format "\n     %S" code))))
301                                      cell " ")))
302           (setq data (del-alist '->lowercase data))
303           )
304         (when (setq cell (assq '->titlecase data))
305           (setq cell (cdr cell))
306           (insert (format "(->titlecase\t%s)
307     "
308                           (mapconcat (lambda (code)
309                                        (cond ((symbolp code)
310                                               (symbol-name code))
311                                              ((integerp code)
312                                               (format "#x%04X" code))
313                                              (t
314                                               (format "\n     %S" code))))
315                                      cell " ")))
316           (setq data (del-alist '->titlecase data))
317           )
318         (setq data
319               (sort data
320                     (lambda (a b)
321                       (char-attribute-name< (car a)(car b)))))
322         (setq rest data)
323         (while (and rest
324                     (progn
325                       (setq cell (car rest))
326                       (if (setq ret (find-charset (car cell)))
327                           (if (>= (length (symbol-name (charset-name ret))) 19)
328                               (progn
329                                 (setq has-long-ccs-name t)
330                                 nil)
331                             t)
332                         t)))
333           (setq rest (cdr rest)))
334         (while data
335           (setq cell (car data))
336           (cond ((setq ret (find-charset (car cell)))
337                  (insert (format (if has-long-ccs-name
338                                      "(%-26s %s)
339     "
340                                    "(%-18s %s)
341     "
342                                    )
343                                  (charset-name ret)
344                                  (mapconcat
345                                   (lambda (b)
346                                     (format "#x%02X"
347                                             (if (= (charset-graphic ret) 1)
348                                                 (logior b #x80)
349                                               b)))
350                                   (cdr cell) " "))))
351                 ((string-match "^->" (symbol-name (car cell)))
352                  (insert
353                   (format "(%-18s %s)
354     "
355                           (car cell)
356                           (mapconcat (lambda (code)
357                                        (cond ((symbolp code)
358                                               (symbol-name code))
359                                              ((integerp code)
360                                               (format "#x%04X" code))
361                                              (t
362                                               (format "\n     %S" code))))
363                                      (cdr cell) " "))))
364                 ((consp (cdr cell))
365                  (insert (format "(%-18s %s)
366     "
367                                  (car cell)
368                                  (mapconcat (function prin1-to-string)
369                                             (cdr cell) " "))))
370                 (t
371                  (insert (format "(%-18s . %S)
372     "
373                                  (car cell)(cdr cell)))
374                  ))
375           (setq data (cdr data)))
376         (insert "))\n")
377         (goto-char (point-min))
378         (while (re-search-forward "[ \t]+$" nil t)
379           (replace-match ""))
380         (goto-char (point-max))
381         (tabify (point-min)(point-max))
382         ))))
383
384 ;;;###autoload
385 (defun char-db-update-comment ()
386   (interactive)
387   (save-excursion
388     (goto-char (point-min))
389     (let (cdef table char)
390       (while (re-search-forward "^[ \t]*\\(([^.()]+)\\)" nil t)
391         (goto-char (match-beginning 1))
392         (setq cdef (read (current-buffer)))
393         (when (find-charset (car cdef))
394           (goto-char (match-end 0))
395           (setq char
396                 (if (or (memq (car cdef) '(ascii latin-viscii-upper
397                                                  latin-viscii-lower
398                                                  arabic-iso8859-6))
399                         (= (char-int (charset-final (car cdef))) 0))
400                     (apply (function make-char) cdef)
401                   (if (setq table (charset-mapping-table (car cdef)))
402                       (set-charset-mapping-table (car cdef) nil))
403                   (prog1
404                       (apply (function make-char) cdef)
405                     (if table
406                         (set-charset-mapping-table (car cdef) table)))))
407           (when (not (or (< (char-int char) 32)
408                          (and (<= 128 (char-int char))
409                               (< (char-int char) 160))))
410             (delete-region (point) (point-at-eol))
411             (insert (format "\t; %c" char)))
412           )))))
413
414 (defun insert-char-data-with-variant (char)
415   (insert-char-data char)
416   (let ((variants (char-variants char)))
417     (while variants
418       (insert-char-data (car variants))
419       (setq variants (cdr variants))
420       )))
421
422 (defun insert-char-range-data (min max)
423   (let ((code min)
424         char
425         variants)
426     (while (<= code max)
427       (setq char (int-char code))
428       (insert-char-data-with-variant char)
429       (setq code (1+ code))
430       )))
431
432 (defun write-char-range-data-to-file (min max file)
433   (with-temp-buffer
434     (insert-char-range-data min max)
435     (write-region (point-min)(point-max) file)))
436
437 ;;;###autoload
438 (defun what-char-definition (char)
439   (interactive (list (char-after)))
440   (let ((buf (get-buffer-create "*Character Description*"))
441         (the-buf (current-buffer))
442         (win-conf (current-window-configuration)))
443     (pop-to-buffer buf)
444     (make-local-variable 'what-character-original-window-configuration)
445     (setq what-character-original-window-configuration win-conf)
446     (setq buffer-read-only nil)
447     (erase-buffer)
448     (condition-case err
449         (progn
450           (insert-char-data-with-variant char)
451           (char-db-update-comment)
452           (set-buffer-modified-p nil)
453           (view-mode the-buf (lambda (buf)
454                                (set-window-configuration
455                                 what-character-original-window-configuration)
456                                ))
457           (goto-char (point-min)))
458       (error (progn
459                (set-window-configuration
460                 what-character-original-window-configuration)
461                (signal (car err) (cdr err)))))))
462
463 (provide 'char-db-util)
464
465 ;;; char-db-util.el ends here