(char-db-coded-charset-priority-list): Delete `=>>>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
599                          =>>gt =+>gt =>gt
600                          =gt-k ==gt-k =>>gt-k =>gt-k
601                          =adobe-japan1-0 ==adobe-japan1-0 ; =>>>adobe-japan1-0
602                          =adobe-japan1-1 ==adobe-japan1-1 ; =>>>adobe-japan1-1
603                          =adobe-japan1-2 ==adobe-japan1-2 ; =>>>adobe-japan1-2
604                          =adobe-japan1-3 ==adobe-japan1-3 ; =>>>adobe-japan1-3
605                          =adobe-japan1-4 ==adobe-japan1-4 ; =>>>adobe-japan1-4
606                          =adobe-japan1-5 ==adobe-japan1-5 ; =>>>adobe-japan1-5
607                          =adobe-japan1-6 ==adobe-japan1-6 ; =>>>adobe-japan1-6
608                          =>>adobe-japan1-0 =+>adobe-japan1-0
609                          =>>adobe-japan1-1 =+>adobe-japan1-1
610                          =>>adobe-japan1-2 =+>adobe-japan1-2
611                          =>>adobe-japan1-3 =+>adobe-japan1-3
612                          =>>adobe-japan1-4 =+>adobe-japan1-4
613                          =>>adobe-japan1-5 =+>adobe-japan1-5
614                          =>>adobe-japan1-6 =+>adobe-japan1-6
615                          =cbeta =>>cbeta
616                          =zinbun-oracle =>zinbun-oracle))
617             ;; (string-match "^=adobe-" (symbol-name name))
618             )
619         "(%-18s . %05d)\t; %c")
620        ((memq name '(=hanyo-denshi/ks
621                      ==hanyo-denshi/ks ; =>>>hanyo-denshi/ks
622                      =>>hanyo-denshi/ks
623                      =zihai mojikyo))
624         "(%-18s . %06d)\t; %c")
625        ((>= (charset-dimension name) 2)
626         "(%-18s . #x%04X)\t; %c")
627        (t
628         "(%-18s . #x%02X)\t; %c"))
629       name
630       (if (= (charset-iso-graphic-plane name) 1)
631           (logior value
632                   (cond ((= (charset-dimension name) 1)
633                          #x80)
634                         ((= (charset-dimension name) 2)
635                          #x8080)
636                         ((= (charset-dimension name) 3)
637                          #x808080)
638                         (t 0)))
639         value)
640       (char-db-decode-isolated-char name value)))
641     (if (and (= (charset-chars name) 94)
642              (= (charset-dimension name) 2))
643         (insert (format " [%02d-%02d]"
644                         (- (lsh value -8) 32)
645                         (- (logand value 255) 32))))
646     )
647    (t
648     (insert (format "(%-18s . %s)" name value))
649     ))
650   (insert line-breaking))
651
652 (defun char-db-insert-relation-feature (char name value line-breaking
653                                              ccss readable)
654   (insert (format "(%-18s%s " name line-breaking))
655   (let ((lbs (concat "\n" (make-string (current-column) ?\ )))
656         separator cell sources required-features
657         ret)
658     (while (consp value)
659       (setq cell (car value))
660       (if (integerp cell)
661           (setq cell (decode-char '=ucs cell)))
662       (cond
663        ((eq name '->subsumptive)
664         (when (or (not (some (lambda (atr)
665                                (get-char-attribute cell atr))
666                              char-db-ignored-attributes))
667                   (some (lambda (ccs)
668                           (encode-char cell ccs 'defined-only))
669                         ccss))
670           (if separator
671               (insert lbs))
672           (let ((char-db-ignored-attributes
673                  (cons '<-subsumptive
674                        char-db-ignored-attributes)))
675             (insert-char-attributes cell readable nil nil 'for-sub-node))
676           (setq separator lbs))
677         )
678        ((characterp cell)
679         (setq sources
680               (get-char-attribute
681                char (intern (format "%s*sources" name))))
682         (setq required-features nil)
683         (dolist (source sources)
684           (cond
685            ((memq source '(JP
686                            JP/Jouyou
687                            shinjigen shinjigen@1ed shinjigen@rev))
688             (setq required-features
689                   (union required-features
690                          '(=jis-x0208
691                            =jis-x0208@1990
692                            =jis-x0213-1@2000
693                            =jis-x0213-1@2004
694                            =jis-x0213-2
695                            =jis-x0212
696                            =jis-x0208@1983
697                            =jis-x0208@1978
698                            =shinjigen
699                            =shinjigen@1ed
700                            =shinjigen@rev
701                            =shinjigen/+p@rev))))
702            ((eq source 'CN)
703             (setq required-features
704                   (union required-features
705                          '(=gb2312
706                            =gb12345
707                            =iso-ir165)))))
708           (cond
709            ((find-charset (setq ret (intern (format "=%s" source))))
710             (setq required-features
711                   (cons ret required-features)))
712            (t (setq required-features
713                     (cons source required-features)))))
714         (cond ((string-match "@JP" (symbol-name name))
715                (setq required-features
716                      (union required-features
717                             '(=jis-x0208
718                               =jis-x0208@1990
719                               =jis-x0213-1-2000
720                               =jis-x0213-2-2000
721                               =jis-x0212
722                               =jis-x0208@1983
723                               =jis-x0208@1978))))
724               ((string-match "@CN" (symbol-name name))
725                (setq required-features
726                      (union required-features
727                             '(=gb2312
728                               =gb12345
729                               =iso-ir165)))))
730         (if separator
731             (insert lbs))
732         (if readable
733             (insert (format "%S" cell))
734           (char-db-insert-char-spec cell readable
735                                     nil
736                                     required-features))
737         (setq separator lbs))
738        ((consp cell)
739         (if separator
740             (insert lbs))
741         (if (consp (car cell))
742             (char-db-insert-char-spec cell readable)
743           (char-db-insert-char-reference cell readable))
744         (setq separator lbs))
745        (t
746         (if separator
747             (insert separator))
748         (insert (prin1-to-string cell))
749         (setq separator " ")))
750       (setq value (cdr value)))
751     (insert ")")
752     (insert line-breaking)))
753
754 (defun insert-char-attributes (char &optional readable attributes column
755                                     for-sub-node)
756   (unless column
757     (setq column (current-column)))
758   (let (name value ; has-long-ccs-name
759         rest
760         radical strokes
761         (line-breaking
762          (concat "\n" (make-string (1+ column) ?\ )))
763         lbs cell separator ret
764         key al cal
765         dest-ccss ; sources required-features
766         ccss)
767     (let (atr-d)
768       (setq attributes
769             (sort (if attributes
770                       (if (consp attributes)
771                           (progn
772                             (dolist (name attributes)
773                               (unless (memq name char-db-ignored-attributes)
774                                 (if (find-charset name)
775                                     (push name ccss))
776                                 (push name atr-d)))
777                             atr-d))
778                     (dolist (name (char-attribute-list))
779                       (unless (memq name char-db-ignored-attributes)
780                         (if (find-charset name)
781                             (push name ccss))
782                         (push name atr-d)))
783                     atr-d)
784                   #'char-attribute-name<)))
785     (insert "(")
786     (when (memq '<-subsumptive attributes)
787       (when (or readable (not for-sub-node))
788         (when (setq value (get-char-attribute char '<-subsumptive))
789           (char-db-insert-relation-feature char '<-subsumptive value
790                                            line-breaking
791                                            ccss readable)))
792       (setq attributes (delq '<-subsumptive attributes)))
793     (when (and (memq '<-denotational attributes)
794                (setq value (get-char-attribute char '<-denotational)))
795       (char-db-insert-relation-feature char '<-denotational value
796                                        line-breaking
797                                        ccss readable)
798       (setq attributes (delq '<-denotational attributes)))
799     (when (and (memq 'name attributes)
800                (setq value (get-char-attribute char 'name)))
801       (insert (format
802                (if (> (+ (current-column) (length value)) 48)
803                    "(name . %S)%s"
804                  "(name               . %S)%s")
805                value line-breaking))
806       (setq attributes (delq 'name attributes))
807       )
808     (when (and (memq 'name* attributes)
809                (setq value (get-char-attribute char 'name*)))
810       (insert (format
811                (if (> (+ (current-column) (length value)) 48)
812                    "(name* . %S)%s"
813                  "(name*              . %S)%s")
814                value line-breaking))
815       (setq attributes (delq 'name* attributes))
816       )
817     (when (and (memq 'script attributes)
818                (setq value (get-char-attribute char 'script)))
819       (insert (format "(script\t\t%s)%s"
820                       (mapconcat (function prin1-to-string)
821                                  value " ")
822                       line-breaking))
823       (setq attributes (delq 'script attributes))
824       )
825     (dolist (name '(=>ucs =>ucs*))
826       (when (and (memq name attributes)
827                  (setq value (get-char-attribute char name)))
828         (insert (format "(%-18s . #x%04X)\t; %c%s"
829                         name value (decode-char '=ucs value)
830                         line-breaking))
831         (setq attributes (delq name attributes))))
832     (dolist (name '(=>ucs@gb =>ucs@big5))
833       (when (and (memq name attributes)
834                  (setq value (get-char-attribute char name)))
835         (insert (format "(%-18s . #x%04X)\t; %c%s"
836                         name value
837                         (decode-char (intern
838                                       (concat "="
839                                               (substring
840                                                (symbol-name name) 2)))
841                                      value)
842                         line-breaking))
843         (setq attributes (delq name attributes))
844         ))
845     ;; (dolist (name '(=>daikanwa))
846     ;;   (when (and (memq name attributes)
847     ;;              (setq value (get-char-attribute char name)))
848     ;;     (insert
849     ;;      (if (integerp value)
850     ;;          (format "(%-18s . %05d)\t; %c%s"
851     ;;                  name value (decode-char '=daikanwa value)
852     ;;                  line-breaking)
853     ;;        (format "(%-18s %s)\t; %c%s"
854     ;;                name
855     ;;                (mapconcat (function prin1-to-string)
856     ;;                           value " ")
857     ;;                (char-representative-of-daikanwa char)
858     ;;                line-breaking)))
859     ;;     (setq attributes (delq name attributes))))
860     (when (and (memq 'general-category attributes)
861                (setq value (get-char-attribute char 'general-category)))
862       (insert (format
863                "(general-category\t%s) ; %s%s"
864                (mapconcat (lambda (cell)
865                             (format "%S" cell))
866                           value " ")
867                (cond ((rassoc value unidata-normative-category-alist)
868                       "Normative Category")
869                      ((rassoc value unidata-informative-category-alist)
870                       "Informative Category")
871                      (t
872                       "Unknown Category"))
873                line-breaking))
874       (setq attributes (delq 'general-category attributes))
875       )
876     (when (and (memq 'bidi-category attributes)
877                (setq value (get-char-attribute char 'bidi-category)))
878       (insert (format "(bidi-category\t. %S)%s"
879                       value
880                       line-breaking))
881       (setq attributes (delq 'bidi-category attributes))
882       )
883     (unless (or (not (memq 'mirrored attributes))
884                 (eq (setq value (get-char-attribute char 'mirrored 'empty))
885                     'empty))
886       (insert (format "(mirrored\t\t. %S)%s"
887                       value
888                       line-breaking))
889       (setq attributes (delq 'mirrored attributes))
890       )
891     (cond
892      ((and (memq 'decimal-digit-value attributes)
893            (setq value (get-char-attribute char 'decimal-digit-value)))
894       (insert (format "(decimal-digit-value . %S)%s"
895                       value
896                       line-breaking))
897       (setq attributes (delq 'decimal-digit-value attributes))
898       (when (and (memq 'digit-value attributes)
899                  (setq value (get-char-attribute char 'digit-value)))
900         (insert (format "(digit-value\t . %S)%s"
901                         value
902                         line-breaking))
903         (setq attributes (delq 'digit-value attributes))
904         )
905       (when (and (memq 'numeric-value attributes)
906                  (setq value (get-char-attribute char 'numeric-value)))
907         (insert (format "(numeric-value\t . %S)%s"
908                         value
909                         line-breaking))
910         (setq attributes (delq 'numeric-value attributes))
911         )
912       )
913      (t
914       (when (and (memq 'digit-value attributes)
915                  (setq value (get-char-attribute char 'digit-value)))
916         (insert (format "(digit-value\t. %S)%s"
917                         value
918                         line-breaking))
919         (setq attributes (delq 'digit-value attributes))
920         )
921       (when (and (memq 'numeric-value attributes)
922                  (setq value (get-char-attribute char 'numeric-value)))
923         (insert (format "(numeric-value\t. %S)%s"
924                         value
925                         line-breaking))
926         (setq attributes (delq 'numeric-value attributes))
927         )))
928     (when (and (memq 'iso-10646-comment attributes)
929                (setq value (get-char-attribute char 'iso-10646-comment)))
930       (insert (format "(iso-10646-comment\t. %S)%s"
931                       value
932                       line-breaking))
933       (setq attributes (delq 'iso-10646-comment attributes))
934       )
935     (when (and (memq 'morohashi-daikanwa attributes)
936                (setq value (get-char-attribute char 'morohashi-daikanwa)))
937       (insert (format "(morohashi-daikanwa\t%s)%s"
938                       (mapconcat (function prin1-to-string) value " ")
939                       line-breaking))
940       (setq attributes (delq 'morohashi-daikanwa attributes))
941       )
942     (setq radical nil
943           strokes nil)
944     (when (and (memq 'ideographic-radical attributes)
945                (setq value (get-char-attribute char 'ideographic-radical)))
946       (setq radical value)
947       (insert (format "(ideographic-radical . %S)\t; %c%s"
948                       radical
949                       (ideographic-radical radical)
950                       line-breaking))
951       (setq attributes (delq 'ideographic-radical attributes))
952       )
953     (when (and (memq 'shuowen-radical attributes)
954                (setq value (get-char-attribute char 'shuowen-radical)))
955       (insert (format "(shuowen-radical\t. %S)\t; %c%s"
956                       value
957                       (shuowen-radical value)
958                       line-breaking))
959       (setq attributes (delq 'shuowen-radical attributes))
960       )
961     (let (key)
962       (dolist (domain
963                (append
964                 char-db-feature-domains
965                 (let (dest domain)
966                   (dolist (feature (char-attribute-list))
967                     (setq feature (symbol-name feature))
968                     (when (string-match
969                            "\\(radical\\|strokes\\)@\\([^@*]+\\)\\(\\*\\|$\\)"
970                            feature)
971                       (setq domain (intern (match-string 2 feature)))
972                      (unless (memq domain dest)
973                        (setq dest (cons domain dest)))))
974                   (sort dest #'string<))))
975         (setq key (intern (format "%s@%s" 'ideographic-radical domain)))
976         (when (and (memq key attributes)
977                    (setq value (get-char-attribute char key)))
978           (setq radical value)
979           (insert (format "(%s . %S)\t; %c%s"
980                           key
981                           radical
982                           (ideographic-radical radical)
983                           line-breaking))
984           (setq attributes (delq key attributes))
985           )
986         (setq key (intern (format "%s@%s" 'ideographic-strokes domain)))
987         (when (and (memq key attributes)
988                    (setq value (get-char-attribute char key)))
989           (setq strokes value)
990           (insert (format "(%s . %S)%s"
991                           key
992                           strokes
993                           line-breaking))
994           (setq attributes (delq key attributes))
995           )
996         (setq key (intern (format "%s@%s" 'total-strokes domain)))
997         (when (and (memq key attributes)
998                    (setq value (get-char-attribute char key)))
999           (insert (format "(%s       . %S)%s"
1000                           key
1001                           value
1002                           line-breaking))
1003           (setq attributes (delq key attributes))
1004           )
1005         (dolist (feature '(ideographic-radical
1006                            ideographic-strokes
1007                            total-strokes))
1008           (setq key (intern (format "%s@%s*sources" feature domain)))
1009           (when (and (memq key attributes)
1010                      (setq value (get-char-attribute char key)))
1011             (insert (format "(%s%s" key line-breaking))
1012             (dolist (cell value)
1013               (insert (format " %s" cell)))
1014             (insert ")")
1015             (insert line-breaking)
1016             (setq attributes (delq key attributes))
1017             ))
1018         ))
1019     (when (and (memq 'ideographic-strokes attributes)
1020                (setq value (get-char-attribute char 'ideographic-strokes)))
1021       (setq strokes value)
1022       (insert (format "(ideographic-strokes . %S)%s"
1023                       strokes
1024                       line-breaking))
1025       (setq attributes (delq 'ideographic-strokes attributes))
1026       )
1027     (when (and (memq 'kangxi-radical attributes)
1028                (setq value (get-char-attribute char 'kangxi-radical)))
1029       (unless (eq value radical)
1030         (insert (format "(kangxi-radical\t . %S)\t; %c%s"
1031                         value
1032                         (ideographic-radical value)
1033                         line-breaking))
1034         (or radical
1035             (setq radical value)))
1036       (setq attributes (delq 'kangxi-radical attributes))
1037       )
1038     (when (and (memq 'kangxi-strokes attributes)
1039                (setq value (get-char-attribute char 'kangxi-strokes)))
1040       (unless (eq value strokes)
1041         (insert (format "(kangxi-strokes\t . %S)%s"
1042                         value
1043                         line-breaking))
1044         (or strokes
1045             (setq strokes value)))
1046       (setq attributes (delq 'kangxi-strokes attributes))
1047       )
1048     (when (and (memq 'japanese-radical attributes)
1049                (setq value (get-char-attribute char 'japanese-radical)))
1050       (unless (eq value radical)
1051         (insert (format "(japanese-radical\t . %S)\t; %c%s"
1052                         value
1053                         (ideographic-radical value)
1054                         line-breaking))
1055         (or radical
1056             (setq radical value)))
1057       (setq attributes (delq 'japanese-radical attributes))
1058       )
1059     (when (and (memq 'japanese-strokes attributes)
1060                (setq value (get-char-attribute char 'japanese-strokes)))
1061       (unless (eq value strokes)
1062         (insert (format "(japanese-strokes\t . %S)%s"
1063                         value
1064                         line-breaking))
1065         (or strokes
1066             (setq strokes value)))
1067       (setq attributes (delq 'japanese-strokes attributes))
1068       )
1069     (when (and (memq 'cns-radical attributes)
1070                (setq value (get-char-attribute char 'cns-radical)))
1071       (insert (format "(cns-radical\t . %S)\t; %c%s"
1072                       value
1073                       (ideographic-radical value)
1074                       line-breaking))
1075       (setq attributes (delq 'cns-radical attributes))
1076       )
1077     (when (and (memq 'cns-strokes attributes)
1078                (setq value (get-char-attribute char 'cns-strokes)))
1079       (unless (eq value strokes)
1080         (insert (format "(cns-strokes\t . %S)%s"
1081                         value
1082                         line-breaking))
1083         (or strokes
1084             (setq strokes value)))
1085       (setq attributes (delq 'cns-strokes attributes))
1086       )
1087     ;; (when (and (memq 'shinjigen-1-radical attributes)
1088     ;;            (setq value (get-char-attribute char 'shinjigen-1-radical)))
1089     ;;   (unless (eq value radical)
1090     ;;     (insert (format "(shinjigen-1-radical . %S)\t; %c%s"
1091     ;;                     value
1092     ;;                     (ideographic-radical value)
1093     ;;                     line-breaking))
1094     ;;     (or radical
1095     ;;         (setq radical value)))
1096     ;;   (setq attributes (delq 'shinjigen-1-radical attributes))
1097     ;;   )
1098     (when (and (memq 'ideographic- attributes)
1099                (setq value (get-char-attribute char 'ideographic-)))
1100       (insert "(ideographic-       ")
1101       (setq lbs (concat "\n" (make-string (current-column) ?\ ))
1102             separator nil)
1103       (while (consp value)
1104         (setq cell (car value))
1105         (if (integerp cell)
1106             (setq cell (decode-char '=ucs cell)))
1107         (cond ((characterp cell)
1108                (if separator
1109                    (insert lbs))
1110                (if readable
1111                    (insert (format "%S" cell))
1112                  (char-db-insert-char-spec cell readable))
1113                (setq separator lbs))
1114               ((consp cell)
1115                (if separator
1116                    (insert lbs))
1117                (if (consp (car cell))
1118                    (char-db-insert-char-spec cell readable)
1119                  (char-db-insert-char-reference cell readable))
1120                (setq separator lbs))
1121               (t
1122                (if separator
1123                    (insert separator))
1124                (insert (prin1-to-string cell))
1125                (setq separator " ")))
1126         (setq value (cdr value)))
1127       (insert ")")
1128       (insert line-breaking)
1129       (setq attributes (delq 'ideographic- attributes)))
1130     (when (and (memq 'total-strokes attributes)
1131                (setq value (get-char-attribute char 'total-strokes)))
1132       (insert (format "(total-strokes       . %S)%s"
1133                       value
1134                       line-breaking))
1135       (setq attributes (delq 'total-strokes attributes))
1136       )
1137     (when (and (memq '->ideograph attributes)
1138                (setq value (get-char-attribute char '->ideograph)))
1139       (insert (format "(->ideograph\t%s)%s"
1140                       (mapconcat (lambda (code)
1141                                    (cond ((symbolp code)
1142                                           (symbol-name code))
1143                                          ((integerp code)
1144                                           (format "#x%04X" code))
1145                                          (t
1146                                           (format "%s %S"
1147                                                   line-breaking code))))
1148                                  value " ")
1149                       line-breaking))
1150       (setq attributes (delq '->ideograph attributes))
1151       )
1152     ;; (when (and (memq '->decomposition attributes)
1153     ;;            (setq value (get-char-attribute char '->decomposition)))
1154     ;;   (insert (format "(->decomposition\t%s)%s"
1155     ;;                   (mapconcat (lambda (code)
1156     ;;                                (cond ((symbolp code)
1157     ;;                                       (symbol-name code))
1158     ;;                                      ((characterp code)
1159     ;;                                       (if readable
1160     ;;                                           (format "%S" code)
1161     ;;                                         (format "#x%04X"
1162     ;;                                                 (char-int code))
1163     ;;                                         ))
1164     ;;                                      ((integerp code)
1165     ;;                                       (format "#x%04X" code))
1166     ;;                                      (t
1167     ;;                                       (format "%s%S" line-breaking code))))
1168     ;;                              value " ")
1169     ;;                   line-breaking))
1170     ;;   (setq attributes (delq '->decomposition attributes))
1171     ;;   )
1172     (if (equal (get-char-attribute char '->titlecase)
1173                (get-char-attribute char '->uppercase))
1174         (setq attributes (delq '->titlecase attributes)))
1175     (when (and (memq '->mojikyo attributes)
1176                (setq value (get-char-attribute char '->mojikyo)))
1177       (insert (format "(->mojikyo\t\t. %06d)\t; %c%s"
1178                       value (decode-char 'mojikyo value)
1179                       line-breaking))
1180       (setq attributes (delq '->mojikyo attributes))
1181       )
1182     (when (and (memq 'hanyu-dazidian-vol attributes)
1183                (setq value (get-char-attribute char 'hanyu-dazidian-vol)))
1184       (insert (format "(hanyu-dazidian-vol  . %d)%s"
1185                       value line-breaking))
1186       (setq attributes (delq 'hanyu-dazidian-vol attributes))
1187       )
1188     (when (and (memq 'hanyu-dazidian-page attributes)
1189                (setq value (get-char-attribute char 'hanyu-dazidian-page)))
1190       (insert (format "(hanyu-dazidian-page . %d)%s"
1191                       value line-breaking))
1192       (setq attributes (delq 'hanyu-dazidian-page attributes))
1193       )
1194     (when (and (memq 'hanyu-dazidian-char attributes)
1195                (setq value (get-char-attribute char 'hanyu-dazidian-char)))
1196       (insert (format "(hanyu-dazidian-char . %d)%s"
1197                       value line-breaking))
1198       (setq attributes (delq 'hanyu-dazidian-char attributes))
1199       )
1200     (unless readable
1201       (dolist (ignored '(composition
1202                          ->denotational <-subsumptive ->ucs-unified
1203                          ->ideographic-component-forms))
1204         (setq attributes (delq ignored attributes))))
1205     (while attributes
1206       (setq name (car attributes))
1207       (unless (eq (setq value (get-char-attribute char name 'value-is-empty))
1208                   'value-is-empty)
1209         (cond ((setq ret (find-charset name))
1210                (setq name (charset-name ret))
1211                (when (not (memq name dest-ccss))
1212                  (setq dest-ccss (cons name dest-ccss))
1213                  (char-db-insert-ccs-feature name value line-breaking))
1214                )
1215               ((string-match "^=>ucs@" (symbol-name name))
1216                (insert (format "(%-18s . #x%04X)\t; %c%s"
1217                                name value (decode-char '=ucs value)
1218                                line-breaking))
1219                )
1220               ((eq name 'jisx0208-1978/4X)
1221                (insert (format "(%-18s . #x%04X)%s"
1222                                name value
1223                                line-breaking))
1224                )
1225               ((and
1226                 (not readable)
1227                 (not (eq name '->subsumptive))
1228                 (not (eq name '->uppercase))
1229                 (not (eq name '->lowercase))
1230                 (not (eq name '->titlecase))
1231                 (not (eq name '->canonical))
1232                 (not (eq name '->Bopomofo))
1233                 (not (eq name '->mistakable))
1234                 (not (eq name '->ideographic-variants))
1235                 (null (get-char-attribute
1236                        char (intern (format "%s*sources" name))))
1237                 (not (string-match "\\*sources$" (symbol-name name)))
1238                 (null (get-char-attribute
1239                        char (intern (format "%s*note" name))))
1240                 (not (string-match "\\*note$" (symbol-name name)))
1241                 (or (eq name '<-identical)
1242                     (eq name '<-uppercase)
1243                     (eq name '<-lowercase)
1244                     (eq name '<-titlecase)
1245                     (eq name '<-canonical)
1246                     (eq name '<-ideographic-variants)
1247                     ;; (eq name '<-synonyms)
1248                     (string-match "^<-synonyms" (symbol-name name))
1249                     (eq name '<-mistakable)
1250                     (when (string-match "^->" (symbol-name name))
1251                       (cond
1252                        ((string-match "^->fullwidth" (symbol-name name))
1253                         (not (and (consp value)
1254                                   (characterp (car value))
1255                                   (encode-char
1256                                    (car value) '=ucs 'defined-only)))
1257                         )
1258                        (t)))
1259                     ))
1260                )
1261               ((or (eq name 'ideographic-structure)
1262                    (eq name 'ideographic-combination)
1263                    (eq name 'ideographic-)
1264                    (eq name '=decomposition)
1265                    (char-feature-base-name= '=decomposition name)
1266                    (char-feature-base-name= '=>decomposition name)
1267                    ;; (string-match "^=>*decomposition\\(@[^*]+\\)?$"
1268                    ;;               (symbol-name name))
1269                    (string-match "^\\(->\\|<-\\)[^*]*$" (symbol-name name))
1270                    (string-match "^\\(->\\|<-\\)[^*]*\\*sources$"
1271                                  (symbol-name name))
1272                    )
1273                (char-db-insert-relation-feature char name value
1274                                                 line-breaking
1275                                                 ccss readable))
1276               ((memq name '(ideograph=
1277                             original-ideograph-of
1278                             ancient-ideograph-of
1279                             vulgar-ideograph-of
1280                             wrong-ideograph-of
1281                             ;; simplified-ideograph-of
1282                             ideographic-variants
1283                             ;; ideographic-different-form-of
1284                             ))
1285                (insert (format "(%-18s%s " name line-breaking))
1286                (setq lbs (concat "\n" (make-string (current-column) ?\ ))
1287                      separator nil)
1288                (while (consp value)
1289                  (setq cell (car value))
1290                  (if (and (consp cell)
1291                           (consp (car cell)))
1292                      (progn
1293                        (if separator
1294                            (insert lbs))
1295                        (char-db-insert-alist cell readable)
1296                        (setq separator lbs))
1297                    (if separator
1298                        (insert separator))
1299                    (insert (prin1-to-string cell))
1300                    (setq separator " "))
1301                  (setq value (cdr value)))
1302                (insert ")")
1303                (insert line-breaking))
1304               ((consp value)
1305                (insert (format "(%-18s " name))
1306                (setq lbs (concat "\n" (make-string (current-column) ?\ ))
1307                      separator nil)
1308                (while (consp value)
1309                  (setq cell (car value))
1310                  (if (and (consp cell)
1311                           (consp (car cell))
1312                           (setq ret (condition-case nil
1313                                         (find-char cell)
1314                                       (error nil))))
1315                      (progn
1316                        (setq rest cell
1317                              al nil
1318                              cal nil)
1319                        (while rest
1320                          (setq key (car (car rest)))
1321                          (if (find-charset key)
1322                              (setq cal (cons key cal))
1323                            (setq al (cons key al)))
1324                          (setq rest (cdr rest)))
1325                        (if separator
1326                            (insert lbs))
1327                        (insert-char-attributes ret
1328                                                readable
1329                                                al ; cal
1330                                                nil 'for-sub-node)
1331                        (setq separator lbs))
1332                    (setq ret (prin1-to-string cell))
1333                    (if separator
1334                        (if (< (+ (current-column)
1335                                  (length ret)
1336                                  (length separator))
1337                               76)
1338                            (insert separator)
1339                          (insert lbs)))
1340                    (insert ret)
1341                    (setq separator " "))
1342                  (setq value (cdr value)))
1343                (insert ")")
1344                (insert line-breaking))
1345               (t
1346                (insert (format "(%-18s" name))
1347                (setq ret (prin1-to-string value))
1348                (unless (< (+ (current-column)
1349                              (length ret)
1350                              3)
1351                           76)
1352                  (insert line-breaking))
1353                (insert " . " ret ")" line-breaking)
1354                ;; (insert (format "(%-18s . %S)%s"
1355                ;;                 name value
1356                ;;                 line-breaking))
1357                )
1358               ))
1359       (setq attributes (cdr attributes)))
1360     (insert ")")))
1361
1362 (defun insert-char-data (char &optional readable
1363                               attributes)
1364   (save-restriction
1365     (narrow-to-region (point)(point))
1366     (insert "(define-char
1367   '")
1368     (insert-char-attributes char readable attributes)
1369     (insert ")\n")
1370     (goto-char (point-min))
1371     (while (re-search-forward "[ \t]+$" nil t)
1372       (replace-match ""))
1373     ;; from tabify.
1374     (goto-char (point-min))
1375     (while (re-search-forward "[ \t][ \t][ \t]*" nil t)
1376       (let ((column (current-column))
1377             (indent-tabs-mode t))
1378         (delete-region (match-beginning 0) (point))
1379         (indent-to column)))
1380     (goto-char (point-max))
1381     ;; (tabify (point-min)(point-max))
1382     ))
1383
1384 (defun insert-char-data-with-variant (char &optional printable
1385                                            no-ucs-unified
1386                                            script excluded-script)
1387   (insert-char-data char printable)
1388   (let ((variants (char-variants char))
1389         rest
1390         variant vs ret)
1391     (setq variants (sort variants #'<))
1392     (setq rest variants)
1393     (setq variants (cons char variants))
1394     (while rest
1395       (setq variant (car rest))
1396       (unless (get-char-attribute variant '<-subsumptive)
1397         (if (and (or (null script)
1398                      (null (setq vs (get-char-attribute variant 'script)))
1399                      (memq script vs))
1400                  (or (null excluded-script)
1401                      (null (setq vs (get-char-attribute variant 'script)))
1402                      (not (memq excluded-script vs))))
1403             (unless (and no-ucs-unified (get-char-attribute variant '=ucs))
1404               (insert-char-data variant printable)
1405               (if (setq ret (char-variants variant))
1406                   (while ret
1407                     (or (memq (car ret) variants)
1408                         ;; (get-char-attribute (car ret) '<-subsumptive)
1409                         (setq rest (nconc rest (list (car ret)))))
1410                     (setq ret (cdr ret)))))))
1411       (setq rest (cdr rest)))))
1412
1413 (defun insert-char-range-data (min max &optional script excluded-script)
1414   (let ((code min)
1415         char)
1416     (while (<= code max)
1417       (setq char (decode-char '=ucs code))
1418       (if (encode-char char '=ucs 'defined-only)
1419           (insert-char-data-with-variant char nil 'no-ucs-unified
1420                                          script excluded-script))
1421       (setq code (1+ code)))))
1422
1423 (defun write-char-range-data-to-file (min max file
1424                                           &optional script excluded-script)
1425   (let ((coding-system-for-write char-db-file-coding-system))
1426     (with-temp-buffer
1427       (insert (format ";; -*- coding: %s -*-\n"
1428                       char-db-file-coding-system))
1429       (insert-char-range-data min max script excluded-script)
1430       (write-region (point-min)(point-max) file))))
1431
1432 (defvar what-character-original-window-configuration)
1433
1434 ;;;###autoload
1435 (defun what-char-definition (char)
1436   (interactive (list (char-after)))
1437   (let ((buf (get-buffer-create "*Character Description*"))
1438         (the-buf (current-buffer))
1439         (win-conf (current-window-configuration)))
1440     (pop-to-buffer buf)
1441     (make-local-variable 'what-character-original-window-configuration)
1442     (setq what-character-original-window-configuration win-conf)
1443     (setq buffer-read-only nil)
1444     (erase-buffer)
1445     (condition-case err
1446         (progn
1447           (insert-char-data-with-variant char 'printable)
1448           (unless (char-attribute-alist char)
1449             (insert (format ";; = %c\n"
1450                             (let* ((rest (split-char char))
1451                                    (ccs (pop rest))
1452                                    (code (pop rest)))
1453                               (while rest
1454                                 (setq code (logior (lsh code 8)
1455                                                    (pop rest))))
1456                               (decode-char ccs code)))))
1457           ;; (char-db-update-comment)
1458           (set-buffer-modified-p nil)
1459           (view-mode the-buf (lambda (buf)
1460                                (set-window-configuration
1461                                 what-character-original-window-configuration)
1462                                ))
1463           (goto-char (point-min)))
1464       (error (progn
1465                (set-window-configuration
1466                 what-character-original-window-configuration)
1467                (signal (car err) (cdr err)))))))
1468
1469
1470 ;;; @ end
1471 ;;;
1472
1473 (provide 'char-db-util)
1474
1475 ;;; char-db-util.el ends here