(char-db-coded-charset-priority-list): Add `==adobe-japan1-*',
[chise/xemacs-chise.git.1] / lisp / utf-2000 / char-db-util.el
1 ;;; char-db-util.el --- Character Database utility -*- coding: utf-8-er; -*-
2
3 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
4 ;;   2007, 2008, 2009, 2010, 2011, 2012, 2013 MORIOKA Tomohiko.
5
6 ;; Author: MORIOKA Tomohiko <tomo@kanji.zinbun.kyoto-u.ac.jp>
7 ;; Keywords: CHISE, Character Database, ISO/IEC 10646, UCS, Unicode, MULE.
8
9 ;; This file is part of XEmacs CHISE.
10
11 ;; XEmacs CHISE is free software; you can redistribute it and/or
12 ;; modify it under the terms of the GNU General Public License as
13 ;; published by the Free Software Foundation; either version 2, or (at
14 ;; your option) any later version.
15
16 ;; XEmacs CHISE is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 ;; General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with XEmacs CHISE; see the file COPYING.  If not, write to
23 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
25
26 ;;; Code:
27
28 (require 'chise-subr)
29 (require 'ideograph-subr)
30
31 (defconst unidata-normative-category-alist
32   '(("Lu" letter        uppercase)
33     ("Ll" letter        lowercase)
34     ("Lt" letter        titlecase)
35     ("Mn" mark          non-spacing)
36     ("Mc" mark          spacing-combining)
37     ("Me" mark          enclosing)
38     ("Nd" number        decimal-digit)
39     ("Nl" number        letter)
40     ("No" number        other)
41     ("Zs" separator     space)
42     ("Zl" separator     line)
43     ("Zp" separator     paragraph)
44     ("Cc" other         control)
45     ("Cf" other         format)
46     ("Cs" other         surrogate)
47     ("Co" other         private-use)
48     ("Cn" other         not-assigned)))
49
50 (defconst unidata-informative-category-alist
51   '(("Lm" letter        modifier)
52     ("Lo" letter        other)
53     ("Pc" punctuation   connector)
54     ("Pd" punctuation   dash)
55     ("Ps" punctuation   open)
56     ("Pe" punctuation   close)
57     ("Pi" punctuation   initial-quote)
58     ("Pf" punctuation   final-quote)
59     ("Po" punctuation   other)
60     ("Sm" symbol        math)
61     ("Sc" symbol        currency)
62     ("Sk" symbol        modifier)
63     ("So" symbol        other)
64     ))
65
66 (defconst shuowen-radicals
67   [?一 ?上 ?示 ?三 ?王 ?玉 ?玨 ?气 ?士 ?丨 ; 010
68    ?屮 ?艸 ?蓐 ?茻 ?小 ?八 ?釆 ?半 ?牛 ?犛 ; 020
69    ?告 ?口 ?凵 ?吅 ?哭 ?走 ?止 ?癶 ?步 ?此 ; 030
70    ?正 ?是 ?辵 ?彳 ?廴 ?㢟 ?行 ?齒 ?牙 ?足 ; 040
71    ?疋 ?品 ?龠 ?冊 ?㗊 ?舌 ?干 ?谷 ?只 ?㕯 ; 050
72    ?句 ?丩 ?古 ?十 ?卅 ?言 ?誩 ?音 ?䇂 ?丵 ; 060
73    ?菐 ?𠬞 ?𠬜 ?共 ?異 ?舁 ?𦥑 ?䢅 ?爨 ?革 ; 070
74    ?鬲 ?䰜 ?爪 ?𠃨 ?鬥 ?又 ?𠂇 ?㕜 ?支 ?𦘒 ; 080
75    ?聿 ?畫 ?隶 ?臤 ?臣 ?殳 ?殺 ?𠘧 ?寸 ?皮 ; 090
76    ?㼱 ?攴 ?敎 ?卜 ?用 ?爻 ?㸚 ?𥄎 ?目 ?䀠 ; 100
77    ?眉 ?盾 ?自 ?白 ?鼻 ?皕 ?習 ?羽 ?隹 ?奞 ; 110
78    ?萑 ?𦫳 ?苜 ?羊 ?羴 ?瞿 ?雔 ?雥 ?鳥 ?烏 ; 120
79    ?𠦒 ?冓 ?幺 ?𢆶 ?叀 ?玄 ?予 ?放 ?𠬪 ?𣦼 ; 130
80    ?歺 ?死 ?冎 ?骨 ?肉 ?筋 ?刀 ?刃 ?㓞 ?丰 ; 140
81    ?耒 ?𧢲 ?竹 ?箕 ?丌 ?左 ?工 ?㠭 ?巫 ?甘 ; 150
82    ?曰 ?乃 ?丂 ?可 ?兮 ?号 ?亏 ?旨 ?喜 ?壴 ; 160
83 ;  ?旨 ?曰 ?乃 ?丂 ?可 ?兮 ?号 ?亏 ?喜 ?壴 ; 160
84    ?鼓 ?豈 ?豆 ?豊 ?豐 ?䖒 ?虍 ?虎 ?虤 ?皿 ; 170
85    ?𠙴 ?去 ?血 ?丶 ?丹 ?青 ?井 ?皀 ?鬯 ?食 ; 180
86    ?亼 ?會 ?倉 ?入 ?缶 ?矢 ?高 ?冂 ?𩫏 ?京 ; 190
87    ?亯 ?𣆪 ?畗 ?㐭 ?嗇 ?來 ?麥 ?夊 ?舛 ?䑞 ; 200
88    ?韋 ?弟 ?夂 ?久 ?桀 ?木 ?東 ?林 ?才 ?叒 ; 210
89    ?之 ?帀 ?出 ?𣎵 ?生 ?乇 ?𠂹 ?𠌶 ?華 ?𥝌 ; 220
90    ?稽 ?巢 ?桼 ?束 ?㯻 ?囗 ?員 ?貝 ?邑 ?𨛜 ; 230
91    ?日 ?旦 ?倝 ?㫃 ?冥 ?晶 ?月 ?有 ?明 ?囧 ; 240
92    ?夕 ?多 ?毌 ?𢎘 ?𣐺 ?卣 ?齊 ?朿 ?片 ?鼎 ; 250
93    ?克 ?彔 ?禾 ?秝 ?黍 ?香 ?米 ?毇 ?臼 ?凶 ; 260
94    ?𣎳 ?林 ?麻 ?尗 ?耑 ?韭 ?瓜 ?瓠 ?宀 ?宮 ; 270
95    ?呂 ?穴 ?㝱 ?𤕫 ?冖 ?𠔼 ?冃 ?㒳 ?网 ?襾 ; 280
96    ?巾 ?巿 ?帛 ?白 ?㡀 ?黹 ?人 ?𠤎 ?匕 ?从 ; 290
97    ?比 ?北 ?丘 ?㐺 ?𡈼 ?重 ?臥 ?身 ?㐆 ?衣 ; 300
98    ])
99
100 (defun shuowen-radical (number)
101   (aref shuowen-radicals (1- number)))
102
103 (defvar char-db-file-coding-system 'utf-8-mcs-er)
104
105 (defvar char-db-ignored-attributes '(ideographic-products))
106
107 (defvar char-db-coded-charset-priority-list
108   '(ascii
109     control-1
110     latin-iso8859-1
111     latin-iso8859-2
112     latin-iso8859-3
113     latin-iso8859-4
114     latin-iso8859-9
115     latin-jisx0201
116     cyrillic-iso8859-5
117     greek-iso8859-7
118     thai-tis620
119     =adobe-japan1-0
120     =adobe-japan1-1
121     =adobe-japan1-2
122     =adobe-japan1-3
123     =adobe-japan1-4
124     =adobe-japan1-5
125     =adobe-japan1-6
126     =jis-x0208
127     =jis-x0208@1978
128     =jis-x0208@1983
129     japanese-jisx0212
130     chinese-gb2312
131     =jis-x0208@1990
132     chinese-cns11643-1
133     chinese-cns11643-2
134     chinese-cns11643-3
135     chinese-cns11643-4
136     chinese-cns11643-5
137     chinese-cns11643-6
138     chinese-cns11643-7
139     =jis-x0213-1
140     =jis-x0213-1@2000
141     =jis-x0213-1@2004
142     =jis-x0213-2
143     korean-ksc5601
144     chinese-isoir165
145     katakana-jisx0201
146     hebrew-iso8859-8
147     chinese-gb12345
148     latin-viscii
149     ethiopic-ucs
150     =big5-cdp
151     =hanyo-denshi/ja
152     =hanyo-denshi/jb
153     =hanyo-denshi/jc
154     =hanyo-denshi/jd
155     =hanyo-denshi/ft
156     =hanyo-denshi/ia
157     =hanyo-denshi/ib
158     =hanyo-denshi/hg
159     =hanyo-denshi/jt
160     =hanyo-denshi/ks
161     =gt
162     =gt-k
163     ==adobe-japan1-0
164     ==adobe-japan1-1
165     ==adobe-japan1-2
166     ==adobe-japan1-3
167     ==adobe-japan1-4
168     ==adobe-japan1-5
169     ==adobe-japan1-6
170     ==jis-x0208
171     ==jis-x0213-1
172     ==jis-x0213-2
173     ==hanyo-denshi/ja
174     ==hanyo-denshi/jb
175     ==hanyo-denshi/jc
176     ==hanyo-denshi/ft
177     ==hanyo-denshi/ib
178     ==hanyo-denshi/hg
179     ==hanyo-denshi/jt
180     ==hanyo-denshi/ks
181     =daikanwa
182     =daikanwa@rev2
183     =daikanwa@rev1
184     =cbeta
185     ideograph-hanziku-1
186     ideograph-hanziku-2
187     ideograph-hanziku-3
188     ideograph-hanziku-4
189     ideograph-hanziku-5
190     ideograph-hanziku-6
191     ideograph-hanziku-7
192     ideograph-hanziku-8
193     ideograph-hanziku-9
194     ideograph-hanziku-10
195     ideograph-hanziku-11
196     ideograph-hanziku-12
197     ==gt
198     ==jis-x0208@1990
199     ==ks-x1001
200     ==gt-k
201     =>>>adobe-japan1-0
202     =>>>adobe-japan1-1
203     =>>>adobe-japan1-2
204     =>>>adobe-japan1-3
205     =>>>adobe-japan1-4
206     =>>>adobe-japan1-5
207     =>>>adobe-japan1-6
208     =>>>jis-x0208
209     =>>>jis-x0213-1
210     =>>>jis-x0213-2
211     =>>>hanyo-denshi/ja
212     =>>>hanyo-denshi/jb
213     =>>>hanyo-denshi/jc
214     =>>>hanyo-denshi/ft
215     =>>>hanyo-denshi/ib
216     =>>>hanyo-denshi/hg
217     =>>>hanyo-denshi/jt
218     =>>>hanyo-denshi/ks
219     =>>>gt
220     =>>adobe-japan1-0
221     =>>adobe-japan1-1
222     =>>adobe-japan1-2
223     =>>adobe-japan1-3
224     =>>adobe-japan1-4
225     =>>adobe-japan1-5
226     =>>adobe-japan1-6
227     =>>jis-x0208
228     =>>jis-x0213-1
229     =>>jis-x0213-1@2000
230     =>>jis-x0213-1@2004
231     =>>jis-x0213-2
232     =>>jis-x0208@1978
233     =>>hanyo-denshi/ft
234     =>>hanyo-denshi/jt
235     =>>hanyo-denshi/ks
236     =>>gt
237     =>>daikanwa
238     =+>jis-x0208
239     =+>jis-x0213-1
240     =+>jis-x0213-2
241     =+>adobe-japan1-0
242     =+>adobe-japan1-1
243     =+>adobe-japan1-2
244     =+>adobe-japan1-3
245     =+>adobe-japan1-4
246     =+>adobe-japan1-5
247     =+>adobe-japan1-6
248     =+>jis-x0208@1978
249     =>jis-x0208
250     =>jis-x0208@1997
251     =>jis-x0213-1
252     =>jis-x0213-1@2000
253     =>jis-x0213-1@2004
254     =>jis-x0213-2
255     ==>ucs@bucs
256     =>ucs@iso
257     =>ucs@unicode
258     =>ucs@jis
259     =>ucs@cns
260     =>ucs@ks
261     =+>ucs@iso
262     =+>ucs@unicode
263     =+>ucs@jis
264     =+>ucs@jis/1990
265     =+>ucs@cns
266     =+>ucs@ks
267     =>>ucs@iso
268     =>>ucs@unicode
269     =>>ucs@jis
270     =>>ucs@cns
271     =>>>ucs@iso
272     =>>>ucs@unicode
273     ==ucs@iso
274     ==ucs@unicode
275     =ucs@iso
276     =ucs@unicode
277     =ucs@cns
278     =>>big5-cdp
279     =>>gt-k
280     =+>gt
281     =>gt
282     =>big5-cdp
283     =>daikanwa
284     =>daikanwa/ho
285     =>cns11643-7
286     =big5
287     =big5-eten
288     =>gt-k
289     =zinbun-oracle
290     =>zinbun-oracle
291     =ruimoku-v6
292     =>>ruimoku-v6
293     =jef-china3
294     =shinjigen
295     =big5-cdp-var-3
296     =big5-cdp-var-5))
297
298
299 ;;; @ char-db formatters
300 ;;;
301
302 (defun char-db-make-char-spec (char)
303   (let (ret char-spec)
304     (cond ((characterp char)
305            (cond ((and (setq ret (encode-char char '=ucs 'defined-only))
306                        (not (and (<= #xE000 ret)(<= ret #xF8FF))))
307                   (setq char-spec (list (cons '=ucs ret)))
308                   (cond ((setq ret (get-char-attribute char 'name))
309                          (setq char-spec (cons (cons 'name ret) char-spec))
310                          )
311                         ((setq ret (get-char-attribute char 'name*))
312                          (setq char-spec (cons (cons 'name* ret) char-spec))
313                          ))
314                   )
315                  ((encode-char char '=adobe-japan1 'defined-only)
316                   (setq char-spec nil)
317                   (dolist (ccs (charset-list))
318                     (if (and (or (memq ccs
319                                        '(=adobe-japan1-0
320                                          =adobe-japan1-1
321                                          =adobe-japan1-2
322                                          =adobe-japan1-3
323                                          =adobe-japan1-4
324                                          =adobe-japan1-5
325                                          =adobe-japan1-6
326                                          ))
327                                  ;; (eq (charset-property ccs 'iso-ir) 177)
328                                  (string-match "=ucs@" (symbol-name ccs))
329                                  )
330                              (setq ccs (charset-name ccs))
331                              (null (assq ccs char-spec))
332                              (setq ret (encode-char char ccs 'defined-only)))
333                         (setq char-spec (cons (cons ccs ret) char-spec))))
334                   )
335                  ((encode-char char '==adobe-japan1 'defined-only)
336                   (setq char-spec nil)
337                   (dolist (ccs (charset-list))
338                     (if (and (or (memq ccs
339                                        '(==adobe-japan1-0
340                                          ==adobe-japan1-1
341                                          ==adobe-japan1-2
342                                          ==adobe-japan1-3
343                                          ==adobe-japan1-4
344                                          ==adobe-japan1-5
345                                          ==adobe-japan1-6
346                                          ))
347                                  ;; (eq (charset-property ccs 'iso-ir) 177)
348                                  (string-match "=ucs@" (symbol-name ccs))
349                                  )
350                              (setq ccs (charset-name ccs))
351                              (null (assq ccs char-spec))
352                              (setq ret (encode-char char ccs 'defined-only)))
353                         (setq char-spec (cons (cons ccs ret) char-spec))))
354                   )
355                  ((setq ret
356                         (catch 'tag
357                           (let ((rest char-db-coded-charset-priority-list)
358                                 ccs)
359                             (while rest
360                               (setq ccs (charset-name
361                                          (find-charset (car rest))))
362                               (if (setq ret
363                                         (encode-char char ccs
364                                                      'defined-only))
365                                   (throw 'tag (cons ccs ret)))
366                               (setq rest (cdr rest))))))
367                   (setq char-spec (list ret))
368                   (dolist (ccs (delq (car ret) (charset-list)))
369                     (if (and (or (charset-iso-final-char ccs)
370                                  (memq ccs
371                                        '(=daikanwa
372                                          =daikanwa@rev2
373                                          ;; =gt-k
374                                          =jis-x0208@1997
375                                          ))
376                                  (eq (charset-property ccs 'iso-ir) 177)
377                                  ;; (string-match "=ucs@" (symbol-name ccs))
378                                  )
379                              (setq ccs (charset-name ccs))
380                              (null (assq ccs char-spec))
381                              (setq ret (encode-char char ccs 'defined-only)))
382                         (setq char-spec (cons (cons ccs ret) char-spec))))
383                   (if (null char-spec)
384                       (setq char-spec (split-char char)))
385                   (cond ((setq ret (get-char-attribute char 'name))
386                          (setq char-spec (cons (cons 'name ret) char-spec))
387                          )
388                         ((setq ret (get-char-attribute char 'name*))
389                          (setq char-spec (cons (cons 'name* ret) char-spec))
390                          ))
391                   )
392                  ((setq ret (get-char-attribute
393                              char 'ideographic-combination))
394                   (setq char-spec
395                         (cons (cons 'ideographic-combination ret)
396                               char-spec))
397                   ))
398            char-spec)
399           ((consp char)
400            char))))
401     
402 (defun char-db-insert-char-spec (char &optional readable column
403                                       required-features)
404   (unless column
405     (setq column (current-column)))
406   (let (char-spec temp-char)
407     (setq char-spec (char-db-make-char-spec char))
408     (unless (or (characterp char) ; char
409                 (condition-case nil
410                     (setq char (find-char char-spec))
411                   (error nil)))
412       ;; define temporary character
413       ;;   Current implementation is dirty.
414       (setq temp-char (define-char (cons '(ideograph-daikanwa . 0)
415                                          char-spec)))
416       (remove-char-attribute temp-char 'ideograph-daikanwa)
417       (setq char temp-char))
418     (insert-char-attributes char
419                             readable
420                             (union (mapcar #'car char-spec)
421                                    required-features)
422                             nil 'for-sub-node)
423     (when temp-char
424       ;; undefine temporary character
425       ;;   Current implementation is dirty.
426       (setq char-spec (char-attribute-alist temp-char))
427       (while char-spec
428         (remove-char-attribute temp-char (car (car char-spec)))
429         (setq char-spec (cdr char-spec))))))
430
431 (defun char-db-insert-alist (alist &optional readable column)
432   (unless column
433     (setq column (current-column)))
434   (let ((line-breaking
435          (concat "\n" (make-string (1+ column) ?\ )))
436         name value
437         ret al ; cal
438         key
439         lbs cell rest separator)
440     (insert "(")
441     (while alist
442       (setq name (car (car alist))
443             value (cdr (car alist)))
444       (cond ((eq name 'char)
445              (insert "(char . ")
446              (if (setq ret (condition-case nil
447                                (find-char value)
448                              (error nil)))
449                  (progn
450                    (setq al nil
451                          ;; cal nil
452                          )
453                    (while value
454                      (setq key (car (car value)))
455                      ;; (if (find-charset key)
456                      ;;     (setq cal (cons key cal))
457                      (setq al (cons key al))
458                      ;; )
459                      (setq value (cdr value)))
460                    (insert-char-attributes ret
461                                            readable
462                                            (or al 'none) ; cal
463                                            nil 'for-sub-node))
464                (insert (prin1-to-string value)))
465              (insert ")")
466              (insert line-breaking))
467             ((consp value)
468              (insert (format "(%-18s " name))
469              (setq lbs (concat "\n" (make-string (current-column) ?\ )))
470              (while (consp value)
471                (setq cell (car value))
472                (if (and (consp cell)
473                         (consp (car cell))
474                         (setq ret (condition-case nil
475                                       (find-char cell)
476                                     (error nil)))
477                         )
478                    (progn
479                      (setq rest cell
480                            al nil
481                            ;; cal nil
482                            )
483                      (while rest
484                        (setq key (car (car rest)))
485                        ;; (if (find-charset key)
486                        ;;     (setq cal (cons key cal))
487                        (setq al (cons key al))
488                        ;; )
489                        (setq rest (cdr rest)))
490                      (if separator
491                          (insert lbs))
492                      (insert-char-attributes ret
493                                              readable
494                                              al ; cal
495                                              nil 'for-sub-node)
496                      (setq separator lbs))
497                  (if separator
498                      (insert separator))
499                  (insert (prin1-to-string cell))
500                  (setq separator " "))
501                (setq value (cdr value)))
502              (insert ")")
503              (insert line-breaking))
504             (t
505              (insert (format "(%-18s . %S)%s"
506                              name value
507                              line-breaking))))
508       (setq alist (cdr alist))))
509   (insert ")"))
510
511 (defun char-db-insert-char-reference (plist &optional readable column)
512   (unless column
513     (setq column (current-column)))
514   (let ((line-breaking
515          (concat "\n" (make-string (1+ column) ?\ )))
516         (separator "")
517         name value)
518     (insert "(")
519     (while plist
520       (setq name (pop plist))
521       (setq value (pop plist))
522       (cond ((eq name :char)
523              (insert separator)
524              (insert ":char\t")
525              (cond ((numberp value)
526                     (setq value (decode-char '=ucs value)))
527                    ;; ((consp value)
528                    ;;  (setq value (or (find-char value)
529                    ;;                  value)))
530                    )
531              (char-db-insert-char-spec value readable)
532              (insert line-breaking)
533              (setq separator ""))
534             ((eq name :radical)
535              (insert (format "%s%s\t%d ; %c%s"
536                              separator
537                              name value
538                              (ideographic-radical value)
539                              line-breaking))
540              (setq separator ""))
541             (t
542              (insert (format "%s%s\t%S" separator name value))
543              (setq separator line-breaking)))
544       ))
545   (insert ")"))
546
547 (defun char-db-decode-isolated-char (ccs code-point)
548   (let (ret)
549     (setq ret
550           (cond ((eq ccs 'arabic-iso8859-6)
551                  (decode-char ccs code-point))
552                 ;; ((eq ccs '=gt)
553                 ;;  (decode-builtin-char '==gt code-point))
554                 ((and (memq ccs '(=gt-pj-1
555                                   =gt-pj-2
556                                   =gt-pj-3
557                                   =gt-pj-4
558                                   =gt-pj-5
559                                   =gt-pj-6
560                                   =gt-pj-7
561                                   =gt-pj-8
562                                   =gt-pj-9
563                                   =gt-pj-10
564                                   =gt-pj-11))
565                       (setq ret (decode-char ccs code-point))
566                       (setq ret (encode-char ret '=gt 'defined-only)))
567                  (decode-builtin-char '=gt ret))
568                 (t
569                  (decode-builtin-char ccs code-point))))
570     (cond ((and (<= 0 (char-int ret))
571                 (<= (char-int ret) #x1F))
572            (decode-char '=ucs (+ #x2400 (char-int ret))))
573           ((= (char-int ret) #x7F)
574            ?\u2421)
575           (t ret))))
576
577 (defvar char-db-convert-obsolete-format t)
578
579 (defun char-db-insert-ccs-feature (name value line-breaking)
580   (cond
581    ((integerp value)
582     (insert
583      (format
584       (cond
585        ((memq name '(==shinjigen
586                      =shinjigen
587                      =shinjigen@1ed
588                      =shinjigen@rev =shinjigen/+p@rev
589                      =daikanwa/ho =>>daikanwa/ho =>daikanwa/ho))
590         "(%-18s .  %04d)\t; %c")
591        ((eq name '=shinjigen@1ed/24pr)
592         "(%-18s . %04d)\t; %c")
593        ((or (memq name '(==daikanwa
594                          =daikanwa =>>daikanwa =>daikanwa
595                          =daikanwa@rev1 =daikanwa@rev2
596                          =daikanwa/+p =>>daikanwa/+p
597                          =daikanwa/+2p =>>daikanwa/+2p
598                          =gt ==gt =>>>gt =>>gt =+>gt =>gt
599                          =gt-k ==gt-k =>>gt-k =>gt-k
600                          =adobe-japan1-0 ==adobe-japan1-0 =>>>adobe-japan1-0
601                          =adobe-japan1-1 ==adobe-japan1-1 =>>>adobe-japan1-1
602                          =adobe-japan1-2 ==adobe-japan1-2 =>>>adobe-japan1-2
603                          =adobe-japan1-3 ==adobe-japan1-3 =>>>adobe-japan1-3
604                          =adobe-japan1-4 ==adobe-japan1-4 =>>>adobe-japan1-4
605                          =adobe-japan1-5 ==adobe-japan1-5 =>>>adobe-japan1-5
606                          =adobe-japan1-6 ==adobe-japan1-6 =>>>adobe-japan1-6
607                          =>>adobe-japan1-0 =+>adobe-japan1-0
608                          =>>adobe-japan1-1 =+>adobe-japan1-1
609                          =>>adobe-japan1-2 =+>adobe-japan1-2
610                          =>>adobe-japan1-3 =+>adobe-japan1-3
611                          =>>adobe-japan1-4 =+>adobe-japan1-4
612                          =>>adobe-japan1-5 =+>adobe-japan1-5
613                          =>>adobe-japan1-6 =+>adobe-japan1-6
614                          =cbeta =>>cbeta
615                          =zinbun-oracle =>zinbun-oracle))
616             ;; (string-match "^=adobe-" (symbol-name name))
617             )
618         "(%-18s . %05d)\t; %c")
619        ((memq name '(=hanyo-denshi/ks
620                      ==hanyo-denshi/ks =>>>hanyo-denshi/ks =>>hanyo-denshi/ks
621                      =zihai mojikyo))
622         "(%-18s . %06d)\t; %c")
623        ((>= (charset-dimension name) 2)
624         "(%-18s . #x%04X)\t; %c")
625        (t
626         "(%-18s . #x%02X)\t; %c"))
627       name
628       (if (= (charset-iso-graphic-plane name) 1)
629           (logior value
630                   (cond ((= (charset-dimension name) 1)
631                          #x80)
632                         ((= (charset-dimension name) 2)
633                          #x8080)
634                         ((= (charset-dimension name) 3)
635                          #x808080)
636                         (t 0)))
637         value)
638       (char-db-decode-isolated-char name value)))
639     (if (and (= (charset-chars name) 94)
640              (= (charset-dimension name) 2))
641         (insert (format " [%02d-%02d]"
642                         (- (lsh value -8) 32)
643                         (- (logand value 255) 32))))
644     )
645    (t
646     (insert (format "(%-18s . %s)" name value))
647     ))
648   (insert line-breaking))
649
650 (defun char-db-insert-relation-feature (char name value line-breaking
651                                              ccss readable)
652   (insert (format "(%-18s%s " name line-breaking))
653   (let ((lbs (concat "\n" (make-string (current-column) ?\ )))
654         separator cell sources required-features
655         ret)
656     (while (consp value)
657       (setq cell (car value))
658       (if (integerp cell)
659           (setq cell (decode-char '=ucs cell)))
660       (cond
661        ((eq name '->subsumptive)
662         (when (or (not (some (lambda (atr)
663                                (get-char-attribute cell atr))
664                              char-db-ignored-attributes))
665                   (some (lambda (ccs)
666                           (encode-char cell ccs 'defined-only))
667                         ccss))
668           (if separator
669               (insert lbs))
670           (let ((char-db-ignored-attributes
671                  (cons '<-subsumptive
672                        char-db-ignored-attributes)))
673             (insert-char-attributes cell readable nil nil 'for-sub-node))
674           (setq separator lbs))
675         )
676        ((characterp cell)
677         (setq sources
678               (get-char-attribute
679                char (intern (format "%s*sources" name))))
680         (setq required-features nil)
681         (dolist (source sources)
682           (cond
683            ((memq source '(JP
684                            JP/Jouyou
685                            shinjigen shinjigen@1ed shinjigen@rev))
686             (setq required-features
687                   (union required-features
688                          '(=jis-x0208
689                            =jis-x0208@1990
690                            =jis-x0213-1@2000
691                            =jis-x0213-1@2004
692                            =jis-x0213-2
693                            =jis-x0212
694                            =jis-x0208@1983
695                            =jis-x0208@1978
696                            =shinjigen
697                            =shinjigen@1ed
698                            =shinjigen@rev
699                            =shinjigen/+p@rev))))
700            ((eq source 'CN)
701             (setq required-features
702                   (union required-features
703                          '(=gb2312
704                            =gb12345
705                            =iso-ir165)))))
706           (cond
707            ((find-charset (setq ret (intern (format "=%s" source))))
708             (setq required-features
709                   (cons ret required-features)))
710            (t (setq required-features
711                     (cons source required-features)))))
712         (cond ((string-match "@JP" (symbol-name name))
713                (setq required-features
714                      (union required-features
715                             '(=jis-x0208
716                               =jis-x0208@1990
717                               =jis-x0213-1-2000
718                               =jis-x0213-2-2000
719                               =jis-x0212
720                               =jis-x0208@1983
721                               =jis-x0208@1978))))
722               ((string-match "@CN" (symbol-name name))
723                (setq required-features
724                      (union required-features
725                             '(=gb2312
726                               =gb12345
727                               =iso-ir165)))))
728         (if separator
729             (insert lbs))
730         (if readable
731             (insert (format "%S" cell))
732           (char-db-insert-char-spec cell readable
733                                     nil
734                                     required-features))
735         (setq separator lbs))
736        ((consp cell)
737         (if separator
738             (insert lbs))
739         (if (consp (car cell))
740             (char-db-insert-char-spec cell readable)
741           (char-db-insert-char-reference cell readable))
742         (setq separator lbs))
743        (t
744         (if separator
745             (insert separator))
746         (insert (prin1-to-string cell))
747         (setq separator " ")))
748       (setq value (cdr value)))
749     (insert ")")
750     (insert line-breaking)))
751
752 (defun insert-char-attributes (char &optional readable attributes column
753                                     for-sub-node)
754   (unless column
755     (setq column (current-column)))
756   (let (name value ; has-long-ccs-name
757         rest
758         radical strokes
759         (line-breaking
760          (concat "\n" (make-string (1+ column) ?\ )))
761         lbs cell separator ret
762         key al cal
763         dest-ccss ; sources required-features
764         ccss)
765     (let (atr-d)
766       (setq attributes
767             (sort (if attributes
768                       (if (consp attributes)
769                           (progn
770                             (dolist (name attributes)
771                               (unless (memq name char-db-ignored-attributes)
772                                 (if (find-charset name)
773                                     (push name ccss))
774                                 (push name atr-d)))
775                             atr-d))
776                     (dolist (name (char-attribute-list))
777                       (unless (memq name char-db-ignored-attributes)
778                         (if (find-charset name)
779                             (push name ccss))
780                         (push name atr-d)))
781                     atr-d)
782                   #'char-attribute-name<)))
783     (insert "(")
784     (when (memq '<-subsumptive attributes)
785       (when (or readable (not for-sub-node))
786         (when (setq value (get-char-attribute char '<-subsumptive))
787           (char-db-insert-relation-feature char '<-subsumptive value
788                                            line-breaking
789                                            ccss readable)))
790       (setq attributes (delq '<-subsumptive attributes)))
791     (when (and (memq '<-denotational attributes)
792                (setq value (get-char-attribute char '<-denotational)))
793       (char-db-insert-relation-feature char '<-denotational value
794                                        line-breaking
795                                        ccss readable)
796       (setq attributes (delq '<-denotational attributes)))
797     (when (and (memq 'name attributes)
798                (setq value (get-char-attribute char 'name)))
799       (insert (format
800                (if (> (+ (current-column) (length value)) 48)
801                    "(name . %S)%s"
802                  "(name               . %S)%s")
803                value line-breaking))
804       (setq attributes (delq 'name attributes))
805       )
806     (when (and (memq 'name* attributes)
807                (setq value (get-char-attribute char 'name*)))
808       (insert (format
809                (if (> (+ (current-column) (length value)) 48)
810                    "(name* . %S)%s"
811                  "(name*              . %S)%s")
812                value line-breaking))
813       (setq attributes (delq 'name* attributes))
814       )
815     (when (and (memq 'script attributes)
816                (setq value (get-char-attribute char 'script)))
817       (insert (format "(script\t\t%s)%s"
818                       (mapconcat (function prin1-to-string)
819                                  value " ")
820                       line-breaking))
821       (setq attributes (delq 'script attributes))
822       )
823     (dolist (name '(=>ucs =>ucs*))
824       (when (and (memq name attributes)
825                  (setq value (get-char-attribute char name)))
826         (insert (format "(%-18s . #x%04X)\t; %c%s"
827                         name value (decode-char '=ucs value)
828                         line-breaking))
829         (setq attributes (delq name attributes))))
830     (dolist (name '(=>ucs@gb =>ucs@big5))
831       (when (and (memq name attributes)
832                  (setq value (get-char-attribute char name)))
833         (insert (format "(%-18s . #x%04X)\t; %c%s"
834                         name value
835                         (decode-char (intern
836                                       (concat "="
837                                               (substring
838                                                (symbol-name name) 2)))
839                                      value)
840                         line-breaking))
841         (setq attributes (delq name attributes))
842         ))
843     ;; (dolist (name '(=>daikanwa))
844     ;;   (when (and (memq name attributes)
845     ;;              (setq value (get-char-attribute char name)))
846     ;;     (insert
847     ;;      (if (integerp value)
848     ;;          (format "(%-18s . %05d)\t; %c%s"
849     ;;                  name value (decode-char '=daikanwa value)
850     ;;                  line-breaking)
851     ;;        (format "(%-18s %s)\t; %c%s"
852     ;;                name
853     ;;                (mapconcat (function prin1-to-string)
854     ;;                           value " ")
855     ;;                (char-representative-of-daikanwa char)
856     ;;                line-breaking)))
857     ;;     (setq attributes (delq name attributes))))
858     (when (and (memq 'general-category attributes)
859                (setq value (get-char-attribute char 'general-category)))
860       (insert (format
861                "(general-category\t%s) ; %s%s"
862                (mapconcat (lambda (cell)
863                             (format "%S" cell))
864                           value " ")
865                (cond ((rassoc value unidata-normative-category-alist)
866                       "Normative Category")
867                      ((rassoc value unidata-informative-category-alist)
868                       "Informative Category")
869                      (t
870                       "Unknown Category"))
871                line-breaking))
872       (setq attributes (delq 'general-category attributes))
873       )
874     (when (and (memq 'bidi-category attributes)
875                (setq value (get-char-attribute char 'bidi-category)))
876       (insert (format "(bidi-category\t. %S)%s"
877                       value
878                       line-breaking))
879       (setq attributes (delq 'bidi-category attributes))
880       )
881     (unless (or (not (memq 'mirrored attributes))
882                 (eq (setq value (get-char-attribute char 'mirrored 'empty))
883                     'empty))
884       (insert (format "(mirrored\t\t. %S)%s"
885                       value
886                       line-breaking))
887       (setq attributes (delq 'mirrored attributes))
888       )
889     (cond
890      ((and (memq 'decimal-digit-value attributes)
891            (setq value (get-char-attribute char 'decimal-digit-value)))
892       (insert (format "(decimal-digit-value . %S)%s"
893                       value
894                       line-breaking))
895       (setq attributes (delq 'decimal-digit-value attributes))
896       (when (and (memq 'digit-value attributes)
897                  (setq value (get-char-attribute char 'digit-value)))
898         (insert (format "(digit-value\t . %S)%s"
899                         value
900                         line-breaking))
901         (setq attributes (delq 'digit-value attributes))
902         )
903       (when (and (memq 'numeric-value attributes)
904                  (setq value (get-char-attribute char 'numeric-value)))
905         (insert (format "(numeric-value\t . %S)%s"
906                         value
907                         line-breaking))
908         (setq attributes (delq 'numeric-value attributes))
909         )
910       )
911      (t
912       (when (and (memq 'digit-value attributes)
913                  (setq value (get-char-attribute char 'digit-value)))
914         (insert (format "(digit-value\t. %S)%s"
915                         value
916                         line-breaking))
917         (setq attributes (delq 'digit-value attributes))
918         )
919       (when (and (memq 'numeric-value attributes)
920                  (setq value (get-char-attribute char 'numeric-value)))
921         (insert (format "(numeric-value\t. %S)%s"
922                         value
923                         line-breaking))
924         (setq attributes (delq 'numeric-value attributes))
925         )))
926     (when (and (memq 'iso-10646-comment attributes)
927                (setq value (get-char-attribute char 'iso-10646-comment)))
928       (insert (format "(iso-10646-comment\t. %S)%s"
929                       value
930                       line-breaking))
931       (setq attributes (delq 'iso-10646-comment attributes))
932       )
933     (when (and (memq 'morohashi-daikanwa attributes)
934                (setq value (get-char-attribute char 'morohashi-daikanwa)))
935       (insert (format "(morohashi-daikanwa\t%s)%s"
936                       (mapconcat (function prin1-to-string) value " ")
937                       line-breaking))
938       (setq attributes (delq 'morohashi-daikanwa attributes))
939       )
940     (setq radical nil
941           strokes nil)
942     (when (and (memq 'ideographic-radical attributes)
943                (setq value (get-char-attribute char 'ideographic-radical)))
944       (setq radical value)
945       (insert (format "(ideographic-radical . %S)\t; %c%s"
946                       radical
947                       (ideographic-radical radical)
948                       line-breaking))
949       (setq attributes (delq 'ideographic-radical attributes))
950       )
951     (when (and (memq 'shuowen-radical attributes)
952                (setq value (get-char-attribute char 'shuowen-radical)))
953       (insert (format "(shuowen-radical\t. %S)\t; %c%s"
954                       value
955                       (shuowen-radical value)
956                       line-breaking))
957       (setq attributes (delq 'shuowen-radical attributes))
958       )
959     (let (key)
960       (dolist (domain
961                (append
962                 char-db-feature-domains
963                 (let (dest domain)
964                   (dolist (feature (char-attribute-list))
965                     (setq feature (symbol-name feature))
966                     (when (string-match
967                            "\\(radical\\|strokes\\)@\\([^@*]+\\)\\(\\*\\|$\\)"
968                            feature)
969                       (setq domain (intern (match-string 2 feature)))
970                      (unless (memq domain dest)
971                        (setq dest (cons domain dest)))))
972                   (sort dest #'string<))))
973         (setq key (intern (format "%s@%s" 'ideographic-radical domain)))
974         (when (and (memq key attributes)
975                    (setq value (get-char-attribute char key)))
976           (setq radical value)
977           (insert (format "(%s . %S)\t; %c%s"
978                           key
979                           radical
980                           (ideographic-radical radical)
981                           line-breaking))
982           (setq attributes (delq key attributes))
983           )
984         (setq key (intern (format "%s@%s" 'ideographic-strokes domain)))
985         (when (and (memq key attributes)
986                    (setq value (get-char-attribute char key)))
987           (setq strokes value)
988           (insert (format "(%s . %S)%s"
989                           key
990                           strokes
991                           line-breaking))
992           (setq attributes (delq key attributes))
993           )
994         (setq key (intern (format "%s@%s" 'total-strokes domain)))
995         (when (and (memq key attributes)
996                    (setq value (get-char-attribute char key)))
997           (insert (format "(%s       . %S)%s"
998                           key
999                           value
1000                           line-breaking))
1001           (setq attributes (delq key attributes))
1002           )
1003         (dolist (feature '(ideographic-radical
1004                            ideographic-strokes
1005                            total-strokes))
1006           (setq key (intern (format "%s@%s*sources" feature domain)))
1007           (when (and (memq key attributes)
1008                      (setq value (get-char-attribute char key)))
1009             (insert (format "(%s%s" key line-breaking))
1010             (dolist (cell value)
1011               (insert (format " %s" cell)))
1012             (insert ")")
1013             (insert line-breaking)
1014             (setq attributes (delq key attributes))
1015             ))
1016         ))
1017     (when (and (memq 'ideographic-strokes attributes)
1018                (setq value (get-char-attribute char 'ideographic-strokes)))
1019       (setq strokes value)
1020       (insert (format "(ideographic-strokes . %S)%s"
1021                       strokes
1022                       line-breaking))
1023       (setq attributes (delq 'ideographic-strokes attributes))
1024       )
1025     (when (and (memq 'kangxi-radical attributes)
1026                (setq value (get-char-attribute char 'kangxi-radical)))
1027       (unless (eq value radical)
1028         (insert (format "(kangxi-radical\t . %S)\t; %c%s"
1029                         value
1030                         (ideographic-radical value)
1031                         line-breaking))
1032         (or radical
1033             (setq radical value)))
1034       (setq attributes (delq 'kangxi-radical attributes))
1035       )
1036     (when (and (memq 'kangxi-strokes attributes)
1037                (setq value (get-char-attribute char 'kangxi-strokes)))
1038       (unless (eq value strokes)
1039         (insert (format "(kangxi-strokes\t . %S)%s"
1040                         value
1041                         line-breaking))
1042         (or strokes
1043             (setq strokes value)))
1044       (setq attributes (delq 'kangxi-strokes attributes))
1045       )
1046     (when (and (memq 'japanese-radical attributes)
1047                (setq value (get-char-attribute char 'japanese-radical)))
1048       (unless (eq value radical)
1049         (insert (format "(japanese-radical\t . %S)\t; %c%s"
1050                         value
1051                         (ideographic-radical value)
1052                         line-breaking))
1053         (or radical
1054             (setq radical value)))
1055       (setq attributes (delq 'japanese-radical attributes))
1056       )
1057     (when (and (memq 'japanese-strokes attributes)
1058                (setq value (get-char-attribute char 'japanese-strokes)))
1059       (unless (eq value strokes)
1060         (insert (format "(japanese-strokes\t . %S)%s"
1061                         value
1062                         line-breaking))
1063         (or strokes
1064             (setq strokes value)))
1065       (setq attributes (delq 'japanese-strokes attributes))
1066       )
1067     (when (and (memq 'cns-radical attributes)
1068                (setq value (get-char-attribute char 'cns-radical)))
1069       (insert (format "(cns-radical\t . %S)\t; %c%s"
1070                       value
1071                       (ideographic-radical value)
1072                       line-breaking))
1073       (setq attributes (delq 'cns-radical attributes))
1074       )
1075     (when (and (memq 'cns-strokes attributes)
1076                (setq value (get-char-attribute char 'cns-strokes)))
1077       (unless (eq value strokes)
1078         (insert (format "(cns-strokes\t . %S)%s"
1079                         value
1080                         line-breaking))
1081         (or strokes
1082             (setq strokes value)))
1083       (setq attributes (delq 'cns-strokes attributes))
1084       )
1085     ;; (when (and (memq 'shinjigen-1-radical attributes)
1086     ;;            (setq value (get-char-attribute char 'shinjigen-1-radical)))
1087     ;;   (unless (eq value radical)
1088     ;;     (insert (format "(shinjigen-1-radical . %S)\t; %c%s"
1089     ;;                     value
1090     ;;                     (ideographic-radical value)
1091     ;;                     line-breaking))
1092     ;;     (or radical
1093     ;;         (setq radical value)))
1094     ;;   (setq attributes (delq 'shinjigen-1-radical attributes))
1095     ;;   )
1096     (when (and (memq 'ideographic- attributes)
1097                (setq value (get-char-attribute char 'ideographic-)))
1098       (insert "(ideographic-       ")
1099       (setq lbs (concat "\n" (make-string (current-column) ?\ ))
1100             separator nil)
1101       (while (consp value)
1102         (setq cell (car value))
1103         (if (integerp cell)
1104             (setq cell (decode-char '=ucs cell)))
1105         (cond ((characterp cell)
1106                (if separator
1107                    (insert lbs))
1108                (if readable
1109                    (insert (format "%S" cell))
1110                  (char-db-insert-char-spec cell readable))
1111                (setq separator lbs))
1112               ((consp cell)
1113                (if separator
1114                    (insert lbs))
1115                (if (consp (car cell))
1116                    (char-db-insert-char-spec cell readable)
1117                  (char-db-insert-char-reference cell readable))
1118                (setq separator lbs))
1119               (t
1120                (if separator
1121                    (insert separator))
1122                (insert (prin1-to-string cell))
1123                (setq separator " ")))
1124         (setq value (cdr value)))
1125       (insert ")")
1126       (insert line-breaking)
1127       (setq attributes (delq 'ideographic- attributes)))
1128     (when (and (memq 'total-strokes attributes)
1129                (setq value (get-char-attribute char 'total-strokes)))
1130       (insert (format "(total-strokes       . %S)%s"
1131                       value
1132                       line-breaking))
1133       (setq attributes (delq 'total-strokes attributes))
1134       )
1135     (when (and (memq '->ideograph attributes)
1136                (setq value (get-char-attribute char '->ideograph)))
1137       (insert (format "(->ideograph\t%s)%s"
1138                       (mapconcat (lambda (code)
1139                                    (cond ((symbolp code)
1140                                           (symbol-name code))
1141                                          ((integerp code)
1142                                           (format "#x%04X" code))
1143                                          (t
1144                                           (format "%s %S"
1145                                                   line-breaking code))))
1146                                  value " ")
1147                       line-breaking))
1148       (setq attributes (delq '->ideograph attributes))
1149       )
1150     ;; (when (and (memq '->decomposition attributes)
1151     ;;            (setq value (get-char-attribute char '->decomposition)))
1152     ;;   (insert (format "(->decomposition\t%s)%s"
1153     ;;                   (mapconcat (lambda (code)
1154     ;;                                (cond ((symbolp code)
1155     ;;                                       (symbol-name code))
1156     ;;                                      ((characterp code)
1157     ;;                                       (if readable
1158     ;;                                           (format "%S" code)
1159     ;;                                         (format "#x%04X"
1160     ;;                                                 (char-int code))
1161     ;;                                         ))
1162     ;;                                      ((integerp code)
1163     ;;                                       (format "#x%04X" code))
1164     ;;                                      (t
1165     ;;                                       (format "%s%S" line-breaking code))))
1166     ;;                              value " ")
1167     ;;                   line-breaking))
1168     ;;   (setq attributes (delq '->decomposition attributes))
1169     ;;   )
1170     (if (equal (get-char-attribute char '->titlecase)
1171                (get-char-attribute char '->uppercase))
1172         (setq attributes (delq '->titlecase attributes)))
1173     (when (and (memq '->mojikyo attributes)
1174                (setq value (get-char-attribute char '->mojikyo)))
1175       (insert (format "(->mojikyo\t\t. %06d)\t; %c%s"
1176                       value (decode-char 'mojikyo value)
1177                       line-breaking))
1178       (setq attributes (delq '->mojikyo attributes))
1179       )
1180     (when (and (memq 'hanyu-dazidian-vol attributes)
1181                (setq value (get-char-attribute char 'hanyu-dazidian-vol)))
1182       (insert (format "(hanyu-dazidian-vol  . %d)%s"
1183                       value line-breaking))
1184       (setq attributes (delq 'hanyu-dazidian-vol attributes))
1185       )
1186     (when (and (memq 'hanyu-dazidian-page attributes)
1187                (setq value (get-char-attribute char 'hanyu-dazidian-page)))
1188       (insert (format "(hanyu-dazidian-page . %d)%s"
1189                       value line-breaking))
1190       (setq attributes (delq 'hanyu-dazidian-page attributes))
1191       )
1192     (when (and (memq 'hanyu-dazidian-char attributes)
1193                (setq value (get-char-attribute char 'hanyu-dazidian-char)))
1194       (insert (format "(hanyu-dazidian-char . %d)%s"
1195                       value line-breaking))
1196       (setq attributes (delq 'hanyu-dazidian-char attributes))
1197       )
1198     (unless readable
1199       (dolist (ignored '(composition
1200                          ->denotational <-subsumptive ->ucs-unified
1201                          ->ideographic-component-forms))
1202         (setq attributes (delq ignored attributes))))
1203     (while attributes
1204       (setq name (car attributes))
1205       (unless (eq (setq value (get-char-attribute char name 'value-is-empty))
1206                   'value-is-empty)
1207         (cond ((setq ret (find-charset name))
1208                (setq name (charset-name ret))
1209                (when (not (memq name dest-ccss))
1210                  (setq dest-ccss (cons name dest-ccss))
1211                  (char-db-insert-ccs-feature name value line-breaking))
1212                )
1213               ((string-match "^=>ucs@" (symbol-name name))
1214                (insert (format "(%-18s . #x%04X)\t; %c%s"
1215                                name value (decode-char '=ucs value)
1216                                line-breaking))
1217                )
1218               ((eq name 'jisx0208-1978/4X)
1219                (insert (format "(%-18s . #x%04X)%s"
1220                                name value
1221                                line-breaking))
1222                )
1223               ((and
1224                 (not readable)
1225                 (not (eq name '->subsumptive))
1226                 (not (eq name '->uppercase))
1227                 (not (eq name '->lowercase))
1228                 (not (eq name '->titlecase))
1229                 (not (eq name '->canonical))
1230                 (not (eq name '->Bopomofo))
1231                 (not (eq name '->mistakable))
1232                 (not (eq name '->ideographic-variants))
1233                 (null (get-char-attribute
1234                        char (intern (format "%s*sources" name))))
1235                 (not (string-match "\\*sources$" (symbol-name name)))
1236                 (null (get-char-attribute
1237                        char (intern (format "%s*note" name))))
1238                 (not (string-match "\\*note$" (symbol-name name)))
1239                 (or (eq name '<-identical)
1240                     (eq name '<-uppercase)
1241                     (eq name '<-lowercase)
1242                     (eq name '<-titlecase)
1243                     (eq name '<-canonical)
1244                     (eq name '<-ideographic-variants)
1245                     ;; (eq name '<-synonyms)
1246                     (string-match "^<-synonyms" (symbol-name name))
1247                     (eq name '<-mistakable)
1248                     (when (string-match "^->" (symbol-name name))
1249                       (cond
1250                        ((string-match "^->fullwidth" (symbol-name name))
1251                         (not (and (consp value)
1252                                   (characterp (car value))
1253                                   (encode-char
1254                                    (car value) '=ucs 'defined-only)))
1255                         )
1256                        (t)))
1257                     ))
1258                )
1259               ((or (eq name 'ideographic-structure)
1260                    (eq name 'ideographic-combination)
1261                    (eq name 'ideographic-)
1262                    (eq name '=decomposition)
1263                    (char-feature-base-name= '=decomposition name)
1264                    (char-feature-base-name= '=>decomposition name)
1265                    ;; (string-match "^=>*decomposition\\(@[^*]+\\)?$"
1266                    ;;               (symbol-name name))
1267                    (string-match "^\\(->\\|<-\\)[^*]*$" (symbol-name name))
1268                    (string-match "^\\(->\\|<-\\)[^*]*\\*sources$"
1269                                  (symbol-name name))
1270                    )
1271                (char-db-insert-relation-feature char name value
1272                                                 line-breaking
1273                                                 ccss readable))
1274               ((memq name '(ideograph=
1275                             original-ideograph-of
1276                             ancient-ideograph-of
1277                             vulgar-ideograph-of
1278                             wrong-ideograph-of
1279                             ;; simplified-ideograph-of
1280                             ideographic-variants
1281                             ;; ideographic-different-form-of
1282                             ))
1283                (insert (format "(%-18s%s " name line-breaking))
1284                (setq lbs (concat "\n" (make-string (current-column) ?\ ))
1285                      separator nil)
1286                (while (consp value)
1287                  (setq cell (car value))
1288                  (if (and (consp cell)
1289                           (consp (car cell)))
1290                      (progn
1291                        (if separator
1292                            (insert lbs))
1293                        (char-db-insert-alist cell readable)
1294                        (setq separator lbs))
1295                    (if separator
1296                        (insert separator))
1297                    (insert (prin1-to-string cell))
1298                    (setq separator " "))
1299                  (setq value (cdr value)))
1300                (insert ")")
1301                (insert line-breaking))
1302               ((consp value)
1303                (insert (format "(%-18s " name))
1304                (setq lbs (concat "\n" (make-string (current-column) ?\ ))
1305                      separator nil)
1306                (while (consp value)
1307                  (setq cell (car value))
1308                  (if (and (consp cell)
1309                           (consp (car cell))
1310                           (setq ret (condition-case nil
1311                                         (find-char cell)
1312                                       (error nil))))
1313                      (progn
1314                        (setq rest cell
1315                              al nil
1316                              cal nil)
1317                        (while rest
1318                          (setq key (car (car rest)))
1319                          (if (find-charset key)
1320                              (setq cal (cons key cal))
1321                            (setq al (cons key al)))
1322                          (setq rest (cdr rest)))
1323                        (if separator
1324                            (insert lbs))
1325                        (insert-char-attributes ret
1326                                                readable
1327                                                al ; cal
1328                                                nil 'for-sub-node)
1329                        (setq separator lbs))
1330                    (setq ret (prin1-to-string cell))
1331                    (if separator
1332                        (if (< (+ (current-column)
1333                                  (length ret)
1334                                  (length separator))
1335                               76)
1336                            (insert separator)
1337                          (insert lbs)))
1338                    (insert ret)
1339                    (setq separator " "))
1340                  (setq value (cdr value)))
1341                (insert ")")
1342                (insert line-breaking))
1343               (t
1344                (insert (format "(%-18s" name))
1345                (setq ret (prin1-to-string value))
1346                (unless (< (+ (current-column)
1347                              (length ret)
1348                              3)
1349                           76)
1350                  (insert line-breaking))
1351                (insert " . " ret ")" line-breaking)
1352                ;; (insert (format "(%-18s . %S)%s"
1353                ;;                 name value
1354                ;;                 line-breaking))
1355                )
1356               ))
1357       (setq attributes (cdr attributes)))
1358     (insert ")")))
1359
1360 (defun insert-char-data (char &optional readable
1361                               attributes)
1362   (save-restriction
1363     (narrow-to-region (point)(point))
1364     (insert "(define-char
1365   '")
1366     (insert-char-attributes char readable attributes)
1367     (insert ")\n")
1368     (goto-char (point-min))
1369     (while (re-search-forward "[ \t]+$" nil t)
1370       (replace-match ""))
1371     ;; from tabify.
1372     (goto-char (point-min))
1373     (while (re-search-forward "[ \t][ \t][ \t]*" nil t)
1374       (let ((column (current-column))
1375             (indent-tabs-mode t))
1376         (delete-region (match-beginning 0) (point))
1377         (indent-to column)))
1378     (goto-char (point-max))
1379     ;; (tabify (point-min)(point-max))
1380     ))
1381
1382 (defun insert-char-data-with-variant (char &optional printable
1383                                            no-ucs-unified
1384                                            script excluded-script)
1385   (insert-char-data char printable)
1386   (let ((variants (char-variants char))
1387         rest
1388         variant vs ret)
1389     (setq variants (sort variants #'<))
1390     (setq rest variants)
1391     (setq variants (cons char variants))
1392     (while rest
1393       (setq variant (car rest))
1394       (unless (get-char-attribute variant '<-subsumptive)
1395         (if (and (or (null script)
1396                      (null (setq vs (get-char-attribute variant 'script)))
1397                      (memq script vs))
1398                  (or (null excluded-script)
1399                      (null (setq vs (get-char-attribute variant 'script)))
1400                      (not (memq excluded-script vs))))
1401             (unless (and no-ucs-unified (get-char-attribute variant '=ucs))
1402               (insert-char-data variant printable)
1403               (if (setq ret (char-variants variant))
1404                   (while ret
1405                     (or (memq (car ret) variants)
1406                         ;; (get-char-attribute (car ret) '<-subsumptive)
1407                         (setq rest (nconc rest (list (car ret)))))
1408                     (setq ret (cdr ret)))))))
1409       (setq rest (cdr rest)))))
1410
1411 (defun insert-char-range-data (min max &optional script excluded-script)
1412   (let ((code min)
1413         char)
1414     (while (<= code max)
1415       (setq char (decode-char '=ucs code))
1416       (if (encode-char char '=ucs 'defined-only)
1417           (insert-char-data-with-variant char nil 'no-ucs-unified
1418                                          script excluded-script))
1419       (setq code (1+ code)))))
1420
1421 (defun write-char-range-data-to-file (min max file
1422                                           &optional script excluded-script)
1423   (let ((coding-system-for-write char-db-file-coding-system))
1424     (with-temp-buffer
1425       (insert (format ";; -*- coding: %s -*-\n"
1426                       char-db-file-coding-system))
1427       (insert-char-range-data min max script excluded-script)
1428       (write-region (point-min)(point-max) file))))
1429
1430 (defvar what-character-original-window-configuration)
1431
1432 ;;;###autoload
1433 (defun what-char-definition (char)
1434   (interactive (list (char-after)))
1435   (let ((buf (get-buffer-create "*Character Description*"))
1436         (the-buf (current-buffer))
1437         (win-conf (current-window-configuration)))
1438     (pop-to-buffer buf)
1439     (make-local-variable 'what-character-original-window-configuration)
1440     (setq what-character-original-window-configuration win-conf)
1441     (setq buffer-read-only nil)
1442     (erase-buffer)
1443     (condition-case err
1444         (progn
1445           (insert-char-data-with-variant char 'printable)
1446           (unless (char-attribute-alist char)
1447             (insert (format ";; = %c\n"
1448                             (let* ((rest (split-char char))
1449                                    (ccs (pop rest))
1450                                    (code (pop rest)))
1451                               (while rest
1452                                 (setq code (logior (lsh code 8)
1453                                                    (pop rest))))
1454                               (decode-char ccs code)))))
1455           ;; (char-db-update-comment)
1456           (set-buffer-modified-p nil)
1457           (view-mode the-buf (lambda (buf)
1458                                (set-window-configuration
1459                                 what-character-original-window-configuration)
1460                                ))
1461           (goto-char (point-min)))
1462       (error (progn
1463                (set-window-configuration
1464                 what-character-original-window-configuration)
1465                (signal (car err) (cdr err)))))))
1466
1467
1468 ;;; @ end
1469 ;;;
1470
1471 (provide 'char-db-util)
1472
1473 ;;; char-db-util.el ends here