(char-db-insert-ccs-feature): Add setting for `=+>adobe-japan1'; don't
[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 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    ?鼓 ?豈 ?豆 ?豊 ?豐 ?䖒 ?虍 ?虎 ?虤 ?皿 ; 170
84    ?𠙴 ?去 ?血 ?丶 ?丹 ?青 ?井 ?皀 ?鬯 ?食 ; 180
85    ?亼 ?會 ?倉 ?入 ?缶 ?矢 ?高 ?冂 ?𩫏 ?京 ; 190
86    ?亯 ?𣆪 ?畗 ?㐭 ?嗇 ?來 ?麥 ?夊 ?舛 ?䑞 ; 200
87    ?韋 ?弟 ?夂 ?久 ?桀 ?木 ?東 ?林 ?才 ?叒 ; 210
88    ?之 ?帀 ?出 ?𣎵 ?生 ?乇 ?𠂹 ?𠌶 ?華 ?𥝌 ; 220
89    ?稽 ?巢 ?桼 ?束 ?㯻 ?囗 ?員 ?貝 ?邑 ?𨛜 ; 230
90    ?日 ?旦 ?倝 ?㫃 ?冥 ?晶 ?月 ?有 ?明 ?囧 ; 240
91    ?夕 ?多 ?毌 ?𢎘 ?𣐺 ?卣 ?齊 ?朿 ?片 ?鼎 ; 250
92    ?克 ?彔 ?禾 ?秝 ?黍 ?香 ?米 ?毇 ?臼 ?凶 ; 260
93    ?𣎳 ?林 ?麻 ?尗 ?耑 ?韭 ?瓜 ?瓠 ?宀 ?宮 ; 270
94    ?呂 ?穴 ?㝱 ?𤕫 ?冖 ?𠔼 ?冃 ?㒳 ?网 ?襾 ; 280
95    ?巾 ?巿 ?帛 ?白 ?㡀 ?黹 ?人 ?𠤎 ?匕 ?从 ; 290
96    ])
97
98 (defun shuowen-radical (number)
99   (aref shuowen-radicals (1- number)))
100
101 (defvar char-db-file-coding-system 'utf-8-mcs-er)
102
103 (defvar char-db-ignored-attributes '(ideographic-products))
104
105 (defvar char-db-coded-charset-priority-list
106   '(ascii
107     control-1
108     latin-iso8859-1
109     latin-iso8859-2
110     latin-iso8859-3
111     latin-iso8859-4
112     latin-iso8859-9
113     latin-jisx0201
114     cyrillic-iso8859-5
115     greek-iso8859-7
116     thai-tis620
117     =jis-x0208
118     =jis-x0208@1978
119     =jis-x0208@1983
120     japanese-jisx0212
121     chinese-gb2312
122     =jis-x0208@1990
123     chinese-cns11643-1
124     chinese-cns11643-2
125     chinese-cns11643-3
126     chinese-cns11643-4
127     chinese-cns11643-5
128     chinese-cns11643-6
129     chinese-cns11643-7
130     =jis-x0213-1
131     =jis-x0213-1@2000
132     =jis-x0213-1@2004
133     =jis-x0213-2
134     korean-ksc5601
135     chinese-isoir165
136     katakana-jisx0201
137     hebrew-iso8859-8
138     chinese-gb12345
139     latin-viscii
140     ethiopic-ucs
141     =big5-cdp
142     =gt
143     =adobe-japan1-0
144     =adobe-japan1-1
145     =adobe-japan1-2
146     =adobe-japan1-3
147     =adobe-japan1-4
148     =adobe-japan1-5
149     =adobe-japan1-6
150     =hanyo-denshi/ja
151     =hanyo-denshi/jb
152     =hanyo-denshi/jc
153     =hanyo-denshi/jd
154     =hanyo-denshi/ft
155     =hanyo-denshi/ia
156     =hanyo-denshi/ib
157     =hanyo-denshi/hg
158     =hanyo-denshi/jt
159     =hanyo-denshi/ks
160     =daikanwa
161     =daikanwa@rev2
162     =daikanwa@rev1
163     =cbeta
164     =gt-k
165     ideograph-hanziku-1
166     ideograph-hanziku-2
167     ideograph-hanziku-3
168     ideograph-hanziku-4
169     ideograph-hanziku-5
170     ideograph-hanziku-6
171     ideograph-hanziku-7
172     ideograph-hanziku-8
173     ideograph-hanziku-9
174     ideograph-hanziku-10
175     ideograph-hanziku-11
176     ideograph-hanziku-12
177     =>>>jis-x0208
178     =>>>jis-x0213-1
179     =>>>jis-x0213-2
180     =>>jis-x0208
181     =>>jis-x0213-1
182     =>>jis-x0213-1@2000
183     =>>jis-x0213-1@2004
184     =>>jis-x0213-2
185     =>>jis-x0208@1978
186     =>>hanyo-denshi/ft
187     =>>hanyo-denshi/ks
188     =>>gt
189     =>>daikanwa
190     =+>jis-x0208
191     =+>jis-x0213-1
192     =+>jis-x0213-2
193     =+>jis-x0208@1978
194     =>jis-x0208
195     =>jis-x0208@1997
196     =>jis-x0213-1
197     =>jis-x0213-1@2000
198     =>jis-x0213-1@2004
199     =>jis-x0213-2
200     ==>ucs@bucs
201     =>ucs@iso
202     =>ucs@unicode
203     =>ucs@jis
204     =>ucs@cns
205     =>ucs@ks
206     =+>ucs@unicode
207     =+>ucs@jis
208     =+>ucs@jis/1990
209     =+>ucs@cns
210     =+>ucs@ks
211     =>>ucs@iso
212     =>>ucs@unicode
213     =>>ucs@jis
214     =>>ucs@cns
215     =>>>ucs@iso
216     =>>>ucs@unicode
217     =ucs@iso
218     =ucs@unicode
219     =>>big5-cdp
220     =>>gt-k
221     =+>gt
222     =>gt
223     =>big5-cdp
224     =>daikanwa
225     =big5
226     =big5-eten
227     =>gt-k
228     =zinbun-oracle
229     =>zinbun-oracle
230     =ruimoku-v6
231     =>>ruimoku-v6
232     =jef-china3
233     =shinjigen))
234
235
236 ;;; @ char-db formatters
237 ;;;
238
239 (defun char-db-make-char-spec (char)
240   (let (ret char-spec)
241     (cond ((characterp char)
242            (cond ((and (setq ret (encode-char char '=ucs 'defined-only))
243                        (not (and (<= #xE000 ret)(<= ret #xF8FF))))
244                   (setq char-spec (list (cons '=ucs ret)))
245                   (cond ((setq ret (get-char-attribute char 'name))
246                          (setq char-spec (cons (cons 'name ret) char-spec))
247                          )
248                         ((setq ret (get-char-attribute char 'name*))
249                          (setq char-spec (cons (cons 'name* ret) char-spec))
250                          ))
251                   )
252                  ((setq ret
253                         (catch 'tag
254                           (let ((rest char-db-coded-charset-priority-list)
255                                 ccs)
256                             (while rest
257                               (setq ccs (charset-name
258                                          (find-charset (car rest))))
259                               (if (setq ret
260                                         (encode-char char ccs
261                                                      'defined-only))
262                                   (throw 'tag (cons ccs ret)))
263                               (setq rest (cdr rest))))))
264                   (setq char-spec (list ret))
265                   (dolist (ccs (delq (car ret) (charset-list)))
266                     (if (and (or (charset-iso-final-char ccs)
267                                  (memq ccs
268                                        '(=daikanwa
269                                          =daikanwa@rev2
270                                          ;; =gt-k
271                                          =jis-x0208@1997
272                                          ))
273                                  (string-match "=ucs@" (symbol-name ccs)))
274                              (setq ccs (charset-name ccs))
275                              (null (assq ccs char-spec))
276                              (setq ret (encode-char char ccs 'defined-only)))
277                         (setq char-spec (cons (cons ccs ret) char-spec))))
278                   (if (null char-spec)
279                       (setq char-spec (split-char char)))
280                   (cond ((setq ret (get-char-attribute char 'name))
281                          (setq char-spec (cons (cons 'name ret) char-spec))
282                          )
283                         ((setq ret (get-char-attribute char 'name*))
284                          (setq char-spec (cons (cons 'name* ret) char-spec))
285                          ))
286                   )
287                  ((setq ret (get-char-attribute
288                              char 'ideographic-combination))
289                   (setq char-spec
290                         (cons (cons 'ideographic-combination ret)
291                               char-spec))
292                   ))
293            char-spec)
294           ((consp char)
295            char))))
296     
297 (defun char-db-insert-char-spec (char &optional readable column
298                                       required-features)
299   (unless column
300     (setq column (current-column)))
301   (let (char-spec temp-char)
302     (setq char-spec (char-db-make-char-spec char))
303     (unless (or (characterp char) ; char
304                 (condition-case nil
305                     (setq char (find-char char-spec))
306                   (error nil)))
307       ;; define temporary character
308       ;;   Current implementation is dirty.
309       (setq temp-char (define-char (cons '(ideograph-daikanwa . 0)
310                                          char-spec)))
311       (remove-char-attribute temp-char 'ideograph-daikanwa)
312       (setq char temp-char))
313     (insert-char-attributes char
314                             readable
315                             (union (mapcar #'car char-spec)
316                                    required-features)
317                             nil 'for-sub-node)
318     (when temp-char
319       ;; undefine temporary character
320       ;;   Current implementation is dirty.
321       (setq char-spec (char-attribute-alist temp-char))
322       (while char-spec
323         (remove-char-attribute temp-char (car (car char-spec)))
324         (setq char-spec (cdr char-spec))))))
325
326 (defun char-db-insert-alist (alist &optional readable column)
327   (unless column
328     (setq column (current-column)))
329   (let ((line-breaking
330          (concat "\n" (make-string (1+ column) ?\ )))
331         name value
332         ret al ; cal
333         key
334         lbs cell rest separator)
335     (insert "(")
336     (while alist
337       (setq name (car (car alist))
338             value (cdr (car alist)))
339       (cond ((eq name 'char)
340              (insert "(char . ")
341              (if (setq ret (condition-case nil
342                                (find-char value)
343                              (error nil)))
344                  (progn
345                    (setq al nil
346                          ;; cal nil
347                          )
348                    (while value
349                      (setq key (car (car value)))
350                      ;; (if (find-charset key)
351                      ;;     (setq cal (cons key cal))
352                      (setq al (cons key al))
353                      ;; )
354                      (setq value (cdr value)))
355                    (insert-char-attributes ret
356                                            readable
357                                            (or al 'none) ; cal
358                                            nil 'for-sub-node))
359                (insert (prin1-to-string value)))
360              (insert ")")
361              (insert line-breaking))
362             ((consp value)
363              (insert (format "(%-18s " name))
364              (setq lbs (concat "\n" (make-string (current-column) ?\ )))
365              (while (consp value)
366                (setq cell (car value))
367                (if (and (consp cell)
368                         (consp (car cell))
369                         (setq ret (condition-case nil
370                                       (find-char cell)
371                                     (error nil)))
372                         )
373                    (progn
374                      (setq rest cell
375                            al nil
376                            ;; cal nil
377                            )
378                      (while rest
379                        (setq key (car (car rest)))
380                        ;; (if (find-charset key)
381                        ;;     (setq cal (cons key cal))
382                        (setq al (cons key al))
383                        ;; )
384                        (setq rest (cdr rest)))
385                      (if separator
386                          (insert lbs))
387                      (insert-char-attributes ret
388                                              readable
389                                              al ; cal
390                                              nil 'for-sub-node)
391                      (setq separator lbs))
392                  (if separator
393                      (insert separator))
394                  (insert (prin1-to-string cell))
395                  (setq separator " "))
396                (setq value (cdr value)))
397              (insert ")")
398              (insert line-breaking))
399             (t
400              (insert (format "(%-18s . %S)%s"
401                              name value
402                              line-breaking))))
403       (setq alist (cdr alist))))
404   (insert ")"))
405
406 (defun char-db-insert-char-reference (plist &optional readable column)
407   (unless column
408     (setq column (current-column)))
409   (let ((line-breaking
410          (concat "\n" (make-string (1+ column) ?\ )))
411         (separator "")
412         name value)
413     (insert "(")
414     (while plist
415       (setq name (pop plist))
416       (setq value (pop plist))
417       (cond ((eq name :char)
418              (insert separator)
419              (insert ":char\t")
420              (cond ((numberp value)
421                     (setq value (decode-char '=ucs value)))
422                    ;; ((consp value)
423                    ;;  (setq value (or (find-char value)
424                    ;;                  value)))
425                    )
426              (char-db-insert-char-spec value readable)
427              (insert line-breaking)
428              (setq separator ""))
429             ((eq name :radical)
430              (insert (format "%s%s\t%d ; %c%s"
431                              separator
432                              name value
433                              (ideographic-radical value)
434                              line-breaking))
435              (setq separator ""))
436             (t
437              (insert (format "%s%s\t%S" separator name value))
438              (setq separator line-breaking)))
439       ))
440   (insert ")"))
441
442 (defun char-db-decode-isolated-char (ccs code-point)
443   (let (ret)
444     (setq ret
445           (cond ((eq ccs 'arabic-iso8859-6)
446                  (decode-char ccs code-point))
447                 ((and (memq ccs '(=gt-pj-1
448                                   =gt-pj-2
449                                   =gt-pj-3
450                                   =gt-pj-4
451                                   =gt-pj-5
452                                   =gt-pj-6
453                                   =gt-pj-7
454                                   =gt-pj-8
455                                   =gt-pj-9
456                                   =gt-pj-10
457                                   =gt-pj-11))
458                       (setq ret (decode-char ccs code-point))
459                       (setq ret (encode-char ret '=gt 'defined-only)))
460                  (decode-builtin-char '=gt ret))
461                 (t
462                  (decode-builtin-char ccs code-point))))
463     (cond ((and (<= 0 (char-int ret))
464                 (<= (char-int ret) #x1F))
465            (decode-char '=ucs (+ #x2400 (char-int ret))))
466           ((= (char-int ret) #x7F)
467            ?\u2421)
468           (t ret))))
469
470 (defvar char-db-convert-obsolete-format t)
471
472 (defun char-db-insert-ccs-feature (name value line-breaking)
473   (cond
474    ((integerp value)
475     (insert
476      (format
477       (cond
478        ((memq name '(=shinjigen
479                      =shinjigen@1ed
480                      =shinjigen@rev =shinjigen/+p@rev
481                      =daikanwa/ho))
482         "(%-18s .  %04d)\t; %c")
483        ((eq name '=shinjigen@1ed/24pr)
484         "(%-18s . %04d)\t; %c")
485        ((or (memq name '(=daikanwa =>>daikanwa =>daikanwa
486                          =daikanwa@rev1 =daikanwa@rev2
487                          =daikanwa/+p =daikanwa/+2p
488                          =gt =>>>gt =>>gt =+>gt =>gt
489                          =gt-k =>>gt-k =>gt-k
490                          =adobe-japan1-0 =adobe-japan1-1 =adobe-japan1-2
491                          =adobe-japan1-3 =adobe-japan1-4 =adobe-japan1-5
492                          =adobe-japan1-6 =>>adobe-japan1 =+>adobe-japan1
493                          =cbeta =>>cbeta
494                          =zinbun-oracle =>zinbun-oracle))
495             ;; (string-match "^=adobe-" (symbol-name name))
496             )
497         "(%-18s . %05d)\t; %c")
498        ((memq name '(=hanyo-denshi/ks =>>hanyo-denshi/ks mojikyo))
499         "(%-18s . %06d)\t; %c")
500        ((>= (charset-dimension name) 2)
501         "(%-18s . #x%04X)\t; %c")
502        (t
503         "(%-18s . #x%02X)\t; %c"))
504       name
505       (if (= (charset-iso-graphic-plane name) 1)
506           (logior value
507                   (cond ((= (charset-dimension name) 1)
508                          #x80)
509                         ((= (charset-dimension name) 2)
510                          #x8080)
511                         ((= (charset-dimension name) 3)
512                          #x808080)
513                         (t 0)))
514         value)
515       (char-db-decode-isolated-char name value)))
516     (if (and (= (charset-chars name) 94)
517              (= (charset-dimension name) 2))
518         (insert (format " [%02d-%02d]"
519                         (- (lsh value -8) 32)
520                         (- (logand value 255) 32))))
521     )
522    (t
523     (insert (format "(%-18s . %s)" name value))
524     ))
525   (insert line-breaking))
526
527 (defun char-db-insert-relation-feature (char name value line-breaking
528                                              ccss readable)
529   (insert (format "(%-18s%s " name line-breaking))
530   (let ((lbs (concat "\n" (make-string (current-column) ?\ )))
531         separator cell sources required-features
532         ret)
533     (while (consp value)
534       (setq cell (car value))
535       (if (integerp cell)
536           (setq cell (decode-char '=ucs cell)))
537       (cond
538        ((eq name '->subsumptive)
539         (when (or (not (some (lambda (atr)
540                                (get-char-attribute cell atr))
541                              char-db-ignored-attributes))
542                   (some (lambda (ccs)
543                           (encode-char cell ccs 'defined-only))
544                         ccss))
545           (if separator
546               (insert lbs))
547           (let ((char-db-ignored-attributes
548                  (cons '<-subsumptive
549                        char-db-ignored-attributes)))
550             (insert-char-attributes cell readable nil nil 'for-sub-node))
551           (setq separator lbs))
552         )
553        ((characterp cell)
554         (setq sources
555               (get-char-attribute
556                char (intern (format "%s*sources" name))))
557         (setq required-features nil)
558         (dolist (source sources)
559           (cond
560            ((memq source '(JP
561                            JP/Jouyou
562                            shinjigen shinjigen@1ed shinjigen@rev))
563             (setq required-features
564                   (union required-features
565                          '(=jis-x0208
566                            =jis-x0208@1990
567                            =jis-x0213-1@2000
568                            =jis-x0213-1@2004
569                            =jis-x0213-2
570                            =jis-x0212
571                            =jis-x0208@1983
572                            =jis-x0208@1978
573                            =shinjigen))))
574            ((eq source 'CN)
575             (setq required-features
576                   (union required-features
577                          '(=gb2312
578                            =gb12345
579                            =iso-ir165)))))
580           (cond
581            ((find-charset (setq ret (intern (format "=%s" source))))
582             (setq required-features
583                   (cons ret required-features)))
584            (t (setq required-features
585                     (cons source required-features)))))
586         (cond ((string-match "@JP" (symbol-name name))
587                (setq required-features
588                      (union required-features
589                             '(=jis-x0208
590                               =jis-x0208@1990
591                               =jis-x0213-1-2000
592                               =jis-x0213-2-2000
593                               =jis-x0212
594                               =jis-x0208@1983
595                               =jis-x0208@1978))))
596               ((string-match "@CN" (symbol-name name))
597                (setq required-features
598                      (union required-features
599                             '(=gb2312
600                               =gb12345
601                               =iso-ir165)))))
602         (if separator
603             (insert lbs))
604         (if readable
605             (insert (format "%S" cell))
606           (char-db-insert-char-spec cell readable
607                                     nil
608                                     required-features))
609         (setq separator lbs))
610        ((consp cell)
611         (if separator
612             (insert lbs))
613         (if (consp (car cell))
614             (char-db-insert-char-spec cell readable)
615           (char-db-insert-char-reference cell readable))
616         (setq separator lbs))
617        (t
618         (if separator
619             (insert separator))
620         (insert (prin1-to-string cell))
621         (setq separator " ")))
622       (setq value (cdr value)))
623     (insert ")")
624     (insert line-breaking)))
625
626 (defun insert-char-attributes (char &optional readable attributes column
627                                     for-sub-node)
628   (unless column
629     (setq column (current-column)))
630   (let (name value ; has-long-ccs-name
631         rest
632         radical strokes
633         (line-breaking
634          (concat "\n" (make-string (1+ column) ?\ )))
635         lbs cell separator ret
636         key al cal
637         dest-ccss ; sources required-features
638         ccss)
639     (let (atr-d)
640       (setq attributes
641             (sort (if attributes
642                       (if (consp attributes)
643                           (progn
644                             (dolist (name attributes)
645                               (unless (memq name char-db-ignored-attributes)
646                                 (if (find-charset name)
647                                     (push name ccss))
648                                 (push name atr-d)))
649                             atr-d))
650                     (dolist (name (char-attribute-list))
651                       (unless (memq name char-db-ignored-attributes)
652                         (if (find-charset name)
653                             (push name ccss))
654                         (push name atr-d)))
655                     atr-d)
656                   #'char-attribute-name<)))
657     (insert "(")
658     (when (memq '<-subsumptive attributes)
659       (when (or readable (not for-sub-node))
660         (when (setq value (get-char-attribute char '<-subsumptive))
661           (char-db-insert-relation-feature char '<-subsumptive value
662                                            line-breaking
663                                            ccss readable)))
664       (setq attributes (delq '<-subsumptive attributes)))
665     (when (and (memq '<-denotational attributes)
666                (setq value (get-char-attribute char '<-denotational)))
667       (char-db-insert-relation-feature char '<-denotational value
668                                        line-breaking
669                                        ccss readable)
670       (setq attributes (delq '<-denotational attributes)))
671     (when (and (memq 'name attributes)
672                (setq value (get-char-attribute char 'name)))
673       (insert (format
674                (if (> (+ (current-column) (length value)) 48)
675                    "(name . %S)%s"
676                  "(name               . %S)%s")
677                value line-breaking))
678       (setq attributes (delq 'name attributes))
679       )
680     (when (and (memq 'name* attributes)
681                (setq value (get-char-attribute char 'name*)))
682       (insert (format
683                (if (> (+ (current-column) (length value)) 48)
684                    "(name* . %S)%s"
685                  "(name*              . %S)%s")
686                value line-breaking))
687       (setq attributes (delq 'name* attributes))
688       )
689     (when (and (memq 'script attributes)
690                (setq value (get-char-attribute char 'script)))
691       (insert (format "(script\t\t%s)%s"
692                       (mapconcat (function prin1-to-string)
693                                  value " ")
694                       line-breaking))
695       (setq attributes (delq 'script attributes))
696       )
697     (dolist (name '(=>ucs =>ucs*))
698       (when (and (memq name attributes)
699                  (setq value (get-char-attribute char name)))
700         (insert (format "(%-18s . #x%04X)\t; %c%s"
701                         name value (decode-char '=ucs value)
702                         line-breaking))
703         (setq attributes (delq name attributes))))
704     (dolist (name '(=>ucs@gb =>ucs@big5))
705       (when (and (memq name attributes)
706                  (setq value (get-char-attribute char name)))
707         (insert (format "(%-18s . #x%04X)\t; %c%s"
708                         name value
709                         (decode-char (intern
710                                       (concat "="
711                                               (substring
712                                                (symbol-name name) 2)))
713                                      value)
714                         line-breaking))
715         (setq attributes (delq name attributes))
716         ))
717     ;; (dolist (name '(=>daikanwa))
718     ;;   (when (and (memq name attributes)
719     ;;              (setq value (get-char-attribute char name)))
720     ;;     (insert
721     ;;      (if (integerp value)
722     ;;          (format "(%-18s . %05d)\t; %c%s"
723     ;;                  name value (decode-char '=daikanwa value)
724     ;;                  line-breaking)
725     ;;        (format "(%-18s %s)\t; %c%s"
726     ;;                name
727     ;;                (mapconcat (function prin1-to-string)
728     ;;                           value " ")
729     ;;                (char-representative-of-daikanwa char)
730     ;;                line-breaking)))
731     ;;     (setq attributes (delq name attributes))))
732     (when (and (memq 'general-category attributes)
733                (setq value (get-char-attribute char 'general-category)))
734       (insert (format
735                "(general-category\t%s) ; %s%s"
736                (mapconcat (lambda (cell)
737                             (format "%S" cell))
738                           value " ")
739                (cond ((rassoc value unidata-normative-category-alist)
740                       "Normative Category")
741                      ((rassoc value unidata-informative-category-alist)
742                       "Informative Category")
743                      (t
744                       "Unknown Category"))
745                line-breaking))
746       (setq attributes (delq 'general-category attributes))
747       )
748     (when (and (memq 'bidi-category attributes)
749                (setq value (get-char-attribute char 'bidi-category)))
750       (insert (format "(bidi-category\t. %S)%s"
751                       value
752                       line-breaking))
753       (setq attributes (delq 'bidi-category attributes))
754       )
755     (unless (or (not (memq 'mirrored attributes))
756                 (eq (setq value (get-char-attribute char 'mirrored 'empty))
757                     'empty))
758       (insert (format "(mirrored\t\t. %S)%s"
759                       value
760                       line-breaking))
761       (setq attributes (delq 'mirrored attributes))
762       )
763     (cond
764      ((and (memq 'decimal-digit-value attributes)
765            (setq value (get-char-attribute char 'decimal-digit-value)))
766       (insert (format "(decimal-digit-value . %S)%s"
767                       value
768                       line-breaking))
769       (setq attributes (delq 'decimal-digit-value attributes))
770       (when (and (memq 'digit-value attributes)
771                  (setq value (get-char-attribute char 'digit-value)))
772         (insert (format "(digit-value\t . %S)%s"
773                         value
774                         line-breaking))
775         (setq attributes (delq 'digit-value attributes))
776         )
777       (when (and (memq 'numeric-value attributes)
778                  (setq value (get-char-attribute char 'numeric-value)))
779         (insert (format "(numeric-value\t . %S)%s"
780                         value
781                         line-breaking))
782         (setq attributes (delq 'numeric-value attributes))
783         )
784       )
785      (t
786       (when (and (memq 'digit-value attributes)
787                  (setq value (get-char-attribute char 'digit-value)))
788         (insert (format "(digit-value\t. %S)%s"
789                         value
790                         line-breaking))
791         (setq attributes (delq 'digit-value attributes))
792         )
793       (when (and (memq 'numeric-value attributes)
794                  (setq value (get-char-attribute char 'numeric-value)))
795         (insert (format "(numeric-value\t. %S)%s"
796                         value
797                         line-breaking))
798         (setq attributes (delq 'numeric-value attributes))
799         )))
800     (when (and (memq 'iso-10646-comment attributes)
801                (setq value (get-char-attribute char 'iso-10646-comment)))
802       (insert (format "(iso-10646-comment\t. %S)%s"
803                       value
804                       line-breaking))
805       (setq attributes (delq 'iso-10646-comment attributes))
806       )
807     (when (and (memq 'morohashi-daikanwa attributes)
808                (setq value (get-char-attribute char 'morohashi-daikanwa)))
809       (insert (format "(morohashi-daikanwa\t%s)%s"
810                       (mapconcat (function prin1-to-string) value " ")
811                       line-breaking))
812       (setq attributes (delq 'morohashi-daikanwa attributes))
813       )
814     (setq radical nil
815           strokes nil)
816     (when (and (memq 'ideographic-radical attributes)
817                (setq value (get-char-attribute char 'ideographic-radical)))
818       (setq radical value)
819       (insert (format "(ideographic-radical . %S)\t; %c%s"
820                       radical
821                       (ideographic-radical radical)
822                       line-breaking))
823       (setq attributes (delq 'ideographic-radical attributes))
824       )
825     (when (and (memq 'shuowen-radical attributes)
826                (setq value (get-char-attribute char 'shuowen-radical)))
827       (insert (format "(shuowen-radical\t. %S)\t; %c%s"
828                       value
829                       (shuowen-radical value)
830                       line-breaking))
831       (setq attributes (delq 'shuowen-radical attributes))
832       )
833     (let (key)
834       (dolist (domain
835                (append
836                 char-db-feature-domains
837                 (let (dest domain)
838                   (dolist (feature (char-attribute-list))
839                     (setq feature (symbol-name feature))
840                     (when (string-match
841                            "\\(radical\\|strokes\\)@\\([^@*]+\\)\\(\\*\\|$\\)"
842                            feature)
843                       (setq domain (intern (match-string 2 feature)))
844                      (unless (memq domain dest)
845                        (setq dest (cons domain dest)))))
846                   (sort dest #'string<))))
847         (setq key (intern (format "%s@%s" 'ideographic-radical domain)))
848         (when (and (memq key attributes)
849                    (setq value (get-char-attribute char key)))
850           (setq radical value)
851           (insert (format "(%s . %S)\t; %c%s"
852                           key
853                           radical
854                           (ideographic-radical radical)
855                           line-breaking))
856           (setq attributes (delq key attributes))
857           )
858         (setq key (intern (format "%s@%s" 'ideographic-strokes domain)))
859         (when (and (memq key attributes)
860                    (setq value (get-char-attribute char key)))
861           (setq strokes value)
862           (insert (format "(%s . %S)%s"
863                           key
864                           strokes
865                           line-breaking))
866           (setq attributes (delq key attributes))
867           )
868         (setq key (intern (format "%s@%s" 'total-strokes domain)))
869         (when (and (memq key attributes)
870                    (setq value (get-char-attribute char key)))
871           (insert (format "(%s       . %S)%s"
872                           key
873                           value
874                           line-breaking))
875           (setq attributes (delq key attributes))
876           )
877         (dolist (feature '(ideographic-radical
878                            ideographic-strokes
879                            total-strokes))
880           (setq key (intern (format "%s@%s*sources" feature domain)))
881           (when (and (memq key attributes)
882                      (setq value (get-char-attribute char key)))
883             (insert (format "(%s%s" key line-breaking))
884             (dolist (cell value)
885               (insert (format " %s" cell)))
886             (insert ")")
887             (insert line-breaking)
888             (setq attributes (delq key attributes))
889             ))
890         ))
891     (when (and (memq 'ideographic-strokes attributes)
892                (setq value (get-char-attribute char 'ideographic-strokes)))
893       (setq strokes value)
894       (insert (format "(ideographic-strokes . %S)%s"
895                       strokes
896                       line-breaking))
897       (setq attributes (delq 'ideographic-strokes attributes))
898       )
899     (when (and (memq 'kangxi-radical attributes)
900                (setq value (get-char-attribute char 'kangxi-radical)))
901       (unless (eq value radical)
902         (insert (format "(kangxi-radical\t . %S)\t; %c%s"
903                         value
904                         (ideographic-radical value)
905                         line-breaking))
906         (or radical
907             (setq radical value)))
908       (setq attributes (delq 'kangxi-radical attributes))
909       )
910     (when (and (memq 'kangxi-strokes attributes)
911                (setq value (get-char-attribute char 'kangxi-strokes)))
912       (unless (eq value strokes)
913         (insert (format "(kangxi-strokes\t . %S)%s"
914                         value
915                         line-breaking))
916         (or strokes
917             (setq strokes value)))
918       (setq attributes (delq 'kangxi-strokes attributes))
919       )
920     (when (and (memq 'japanese-radical attributes)
921                (setq value (get-char-attribute char 'japanese-radical)))
922       (unless (eq value radical)
923         (insert (format "(japanese-radical\t . %S)\t; %c%s"
924                         value
925                         (ideographic-radical value)
926                         line-breaking))
927         (or radical
928             (setq radical value)))
929       (setq attributes (delq 'japanese-radical attributes))
930       )
931     (when (and (memq 'japanese-strokes attributes)
932                (setq value (get-char-attribute char 'japanese-strokes)))
933       (unless (eq value strokes)
934         (insert (format "(japanese-strokes\t . %S)%s"
935                         value
936                         line-breaking))
937         (or strokes
938             (setq strokes value)))
939       (setq attributes (delq 'japanese-strokes attributes))
940       )
941     (when (and (memq 'cns-radical attributes)
942                (setq value (get-char-attribute char 'cns-radical)))
943       (insert (format "(cns-radical\t . %S)\t; %c%s"
944                       value
945                       (ideographic-radical value)
946                       line-breaking))
947       (setq attributes (delq 'cns-radical attributes))
948       )
949     (when (and (memq 'cns-strokes attributes)
950                (setq value (get-char-attribute char 'cns-strokes)))
951       (unless (eq value strokes)
952         (insert (format "(cns-strokes\t . %S)%s"
953                         value
954                         line-breaking))
955         (or strokes
956             (setq strokes value)))
957       (setq attributes (delq 'cns-strokes attributes))
958       )
959     (when (and (memq 'shinjigen-1-radical attributes)
960                (setq value (get-char-attribute char 'shinjigen-1-radical)))
961       (unless (eq value radical)
962         (insert (format "(shinjigen-1-radical . %S)\t; %c%s"
963                         value
964                         (ideographic-radical value)
965                         line-breaking))
966         (or radical
967             (setq radical value)))
968       (setq attributes (delq 'shinjigen-1-radical attributes))
969       )
970     (when (and (memq 'ideographic- attributes)
971                (setq value (get-char-attribute char 'ideographic-)))
972       (insert "(ideographic-       ")
973       (setq lbs (concat "\n" (make-string (current-column) ?\ ))
974             separator nil)
975       (while (consp value)
976         (setq cell (car value))
977         (if (integerp cell)
978             (setq cell (decode-char '=ucs cell)))
979         (cond ((characterp cell)
980                (if separator
981                    (insert lbs))
982                (if readable
983                    (insert (format "%S" cell))
984                  (char-db-insert-char-spec cell readable))
985                (setq separator lbs))
986               ((consp cell)
987                (if separator
988                    (insert lbs))
989                (if (consp (car cell))
990                    (char-db-insert-char-spec cell readable)
991                  (char-db-insert-char-reference cell readable))
992                (setq separator lbs))
993               (t
994                (if separator
995                    (insert separator))
996                (insert (prin1-to-string cell))
997                (setq separator " ")))
998         (setq value (cdr value)))
999       (insert ")")
1000       (insert line-breaking)
1001       (setq attributes (delq 'ideographic- attributes)))
1002     (when (and (memq 'total-strokes attributes)
1003                (setq value (get-char-attribute char 'total-strokes)))
1004       (insert (format "(total-strokes       . %S)%s"
1005                       value
1006                       line-breaking))
1007       (setq attributes (delq 'total-strokes attributes))
1008       )
1009     (when (and (memq '->ideograph attributes)
1010                (setq value (get-char-attribute char '->ideograph)))
1011       (insert (format "(->ideograph\t%s)%s"
1012                       (mapconcat (lambda (code)
1013                                    (cond ((symbolp code)
1014                                           (symbol-name code))
1015                                          ((integerp code)
1016                                           (format "#x%04X" code))
1017                                          (t
1018                                           (format "%s %S"
1019                                                   line-breaking code))))
1020                                  value " ")
1021                       line-breaking))
1022       (setq attributes (delq '->ideograph attributes))
1023       )
1024     ;; (when (and (memq '->decomposition attributes)
1025     ;;            (setq value (get-char-attribute char '->decomposition)))
1026     ;;   (insert (format "(->decomposition\t%s)%s"
1027     ;;                   (mapconcat (lambda (code)
1028     ;;                                (cond ((symbolp code)
1029     ;;                                       (symbol-name code))
1030     ;;                                      ((characterp code)
1031     ;;                                       (if readable
1032     ;;                                           (format "%S" code)
1033     ;;                                         (format "#x%04X"
1034     ;;                                                 (char-int code))
1035     ;;                                         ))
1036     ;;                                      ((integerp code)
1037     ;;                                       (format "#x%04X" code))
1038     ;;                                      (t
1039     ;;                                       (format "%s%S" line-breaking code))))
1040     ;;                              value " ")
1041     ;;                   line-breaking))
1042     ;;   (setq attributes (delq '->decomposition attributes))
1043     ;;   )
1044     (if (equal (get-char-attribute char '->titlecase)
1045                (get-char-attribute char '->uppercase))
1046         (setq attributes (delq '->titlecase attributes)))
1047     (when (and (memq '->mojikyo attributes)
1048                (setq value (get-char-attribute char '->mojikyo)))
1049       (insert (format "(->mojikyo\t\t. %06d)\t; %c%s"
1050                       value (decode-char 'mojikyo value)
1051                       line-breaking))
1052       (setq attributes (delq '->mojikyo attributes))
1053       )
1054     (when (and (memq 'hanyu-dazidian-vol attributes)
1055                (setq value (get-char-attribute char 'hanyu-dazidian-vol)))
1056       (insert (format "(hanyu-dazidian-vol  . %d)%s"
1057                       value line-breaking))
1058       (setq attributes (delq 'hanyu-dazidian-vol attributes))
1059       )
1060     (when (and (memq 'hanyu-dazidian-page attributes)
1061                (setq value (get-char-attribute char 'hanyu-dazidian-page)))
1062       (insert (format "(hanyu-dazidian-page . %d)%s"
1063                       value line-breaking))
1064       (setq attributes (delq 'hanyu-dazidian-page attributes))
1065       )
1066     (when (and (memq 'hanyu-dazidian-char attributes)
1067                (setq value (get-char-attribute char 'hanyu-dazidian-char)))
1068       (insert (format "(hanyu-dazidian-char . %d)%s"
1069                       value line-breaking))
1070       (setq attributes (delq 'hanyu-dazidian-char attributes))
1071       )
1072     (unless readable
1073       (dolist (ignored '(composition
1074                          ->denotational <-subsumptive ->ucs-unified
1075                          ->ideographic-component-forms))
1076         (setq attributes (delq ignored attributes))))
1077     (while attributes
1078       (setq name (car attributes))
1079       (unless (eq (setq value (get-char-attribute char name 'value-is-empty))
1080                   'value-is-empty)
1081         (cond ((setq ret (find-charset name))
1082                (setq name (charset-name ret))
1083                (when (not (memq name dest-ccss))
1084                  (setq dest-ccss (cons name dest-ccss))
1085                  (char-db-insert-ccs-feature name value line-breaking))
1086                )
1087               ((string-match "^=>ucs@" (symbol-name name))
1088                (insert (format "(%-18s . #x%04X)\t; %c%s"
1089                                name value (decode-char '=ucs value)
1090                                line-breaking))
1091                )
1092               ((eq name 'jisx0208-1978/4X)
1093                (insert (format "(%-18s . #x%04X)%s"
1094                                name value
1095                                line-breaking))
1096                )
1097               ((and
1098                 (not readable)
1099                 (not (eq name '->subsumptive))
1100                 (not (eq name '->uppercase))
1101                 (not (eq name '->lowercase))
1102                 (not (eq name '->titlecase))
1103                 (not (eq name '->canonical))
1104                 (not (eq name '->Bopomofo))
1105                 (not (eq name '->mistakable))
1106                 (not (eq name '->ideographic-variants))
1107                 (null (get-char-attribute
1108                        char (intern (format "%s*sources" name))))
1109                 (not (string-match "\\*sources$" (symbol-name name)))
1110                 (null (get-char-attribute
1111                        char (intern (format "%s*note" name))))
1112                 (not (string-match "\\*note$" (symbol-name name)))
1113                 (or (eq name '<-identical)
1114                     (eq name '<-uppercase)
1115                     (eq name '<-lowercase)
1116                     (eq name '<-titlecase)
1117                     (eq name '<-canonical)
1118                     (eq name '<-ideographic-variants)
1119                     ;; (eq name '<-synonyms)
1120                     (string-match "^<-synonyms" (symbol-name name))
1121                     (eq name '<-mistakable)
1122                     (when (string-match "^->" (symbol-name name))
1123                       (cond
1124                        ((string-match "^->fullwidth" (symbol-name name))
1125                         (not (and (consp value)
1126                                   (characterp (car value))
1127                                   (encode-char
1128                                    (car value) '=ucs 'defined-only)))
1129                         )
1130                        (t)))
1131                     ))
1132                )
1133               ((or (eq name 'ideographic-structure)
1134                    (eq name 'ideographic-combination)
1135                    (eq name 'ideographic-)
1136                    (eq name '=decomposition)
1137                    (char-feature-base-name= '=decomposition name)
1138                    (char-feature-base-name= '=>decomposition name)
1139                    ;; (string-match "^=>*decomposition\\(@[^*]+\\)?$"
1140                    ;;               (symbol-name name))
1141                    (string-match "^\\(->\\|<-\\)[^*]*$" (symbol-name name))
1142                    (string-match "^\\(->\\|<-\\)[^*]*\\*sources$"
1143                                  (symbol-name name))
1144                    )
1145                (char-db-insert-relation-feature char name value
1146                                                 line-breaking
1147                                                 ccss readable))
1148               ((memq name '(ideograph=
1149                             original-ideograph-of
1150                             ancient-ideograph-of
1151                             vulgar-ideograph-of
1152                             wrong-ideograph-of
1153                             ;; simplified-ideograph-of
1154                             ideographic-variants
1155                             ;; ideographic-different-form-of
1156                             ))
1157                (insert (format "(%-18s%s " name line-breaking))
1158                (setq lbs (concat "\n" (make-string (current-column) ?\ ))
1159                      separator nil)
1160                (while (consp value)
1161                  (setq cell (car value))
1162                  (if (and (consp cell)
1163                           (consp (car cell)))
1164                      (progn
1165                        (if separator
1166                            (insert lbs))
1167                        (char-db-insert-alist cell readable)
1168                        (setq separator lbs))
1169                    (if separator
1170                        (insert separator))
1171                    (insert (prin1-to-string cell))
1172                    (setq separator " "))
1173                  (setq value (cdr value)))
1174                (insert ")")
1175                (insert line-breaking))
1176               ((consp value)
1177                (insert (format "(%-18s " name))
1178                (setq lbs (concat "\n" (make-string (current-column) ?\ ))
1179                      separator nil)
1180                (while (consp value)
1181                  (setq cell (car value))
1182                  (if (and (consp cell)
1183                           (consp (car cell))
1184                           (setq ret (condition-case nil
1185                                         (find-char cell)
1186                                       (error nil))))
1187                      (progn
1188                        (setq rest cell
1189                              al nil
1190                              cal nil)
1191                        (while rest
1192                          (setq key (car (car rest)))
1193                          (if (find-charset key)
1194                              (setq cal (cons key cal))
1195                            (setq al (cons key al)))
1196                          (setq rest (cdr rest)))
1197                        (if separator
1198                            (insert lbs))
1199                        (insert-char-attributes ret
1200                                                readable
1201                                                al ; cal
1202                                                nil 'for-sub-node)
1203                        (setq separator lbs))
1204                    (setq ret (prin1-to-string cell))
1205                    (if separator
1206                        (if (< (+ (current-column)
1207                                  (length ret)
1208                                  (length separator))
1209                               76)
1210                            (insert separator)
1211                          (insert lbs)))
1212                    (insert ret)
1213                    (setq separator " "))
1214                  (setq value (cdr value)))
1215                (insert ")")
1216                (insert line-breaking))
1217               (t
1218                (insert (format "(%-18s" name))
1219                (setq ret (prin1-to-string value))
1220                (unless (< (+ (current-column)
1221                              (length ret)
1222                              3)
1223                           76)
1224                  (insert line-breaking))
1225                (insert " . " ret ")" line-breaking)
1226                ;; (insert (format "(%-18s . %S)%s"
1227                ;;                 name value
1228                ;;                 line-breaking))
1229                )
1230               ))
1231       (setq attributes (cdr attributes)))
1232     (insert ")")))
1233
1234 (defun insert-char-data (char &optional readable
1235                               attributes)
1236   (save-restriction
1237     (narrow-to-region (point)(point))
1238     (insert "(define-char
1239   '")
1240     (insert-char-attributes char readable attributes)
1241     (insert ")\n")
1242     (goto-char (point-min))
1243     (while (re-search-forward "[ \t]+$" nil t)
1244       (replace-match ""))
1245     ;; from tabify.
1246     (goto-char (point-min))
1247     (while (re-search-forward "[ \t][ \t][ \t]*" nil t)
1248       (let ((column (current-column))
1249             (indent-tabs-mode t))
1250         (delete-region (match-beginning 0) (point))
1251         (indent-to column)))
1252     (goto-char (point-max))
1253     ;; (tabify (point-min)(point-max))
1254     ))
1255
1256 (defun insert-char-data-with-variant (char &optional printable
1257                                            no-ucs-unified
1258                                            script excluded-script)
1259   (insert-char-data char printable)
1260   (let ((variants (char-variants char))
1261         rest
1262         variant vs ret)
1263     (setq variants (sort variants #'<))
1264     (setq rest variants)
1265     (setq variants (cons char variants))
1266     (while rest
1267       (setq variant (car rest))
1268       (unless (get-char-attribute variant '<-subsumptive)
1269         (if (and (or (null script)
1270                      (null (setq vs (get-char-attribute variant 'script)))
1271                      (memq script vs))
1272                  (or (null excluded-script)
1273                      (null (setq vs (get-char-attribute variant 'script)))
1274                      (not (memq excluded-script vs))))
1275             (unless (and no-ucs-unified (get-char-attribute variant '=ucs))
1276               (insert-char-data variant printable)
1277               (if (setq ret (char-variants variant))
1278                   (while ret
1279                     (or (memq (car ret) variants)
1280                         ;; (get-char-attribute (car ret) '<-subsumptive)
1281                         (setq rest (nconc rest (list (car ret)))))
1282                     (setq ret (cdr ret)))))))
1283       (setq rest (cdr rest)))))
1284
1285 (defun insert-char-range-data (min max &optional script excluded-script)
1286   (let ((code min)
1287         char)
1288     (while (<= code max)
1289       (setq char (decode-char '=ucs code))
1290       (if (encode-char char '=ucs 'defined-only)
1291           (insert-char-data-with-variant char nil 'no-ucs-unified
1292                                          script excluded-script))
1293       (setq code (1+ code)))))
1294
1295 (defun write-char-range-data-to-file (min max file
1296                                           &optional script excluded-script)
1297   (let ((coding-system-for-write char-db-file-coding-system))
1298     (with-temp-buffer
1299       (insert (format ";; -*- coding: %s -*-\n"
1300                       char-db-file-coding-system))
1301       (insert-char-range-data min max script excluded-script)
1302       (write-region (point-min)(point-max) file))))
1303
1304 (defvar what-character-original-window-configuration)
1305
1306 ;;;###autoload
1307 (defun what-char-definition (char)
1308   (interactive (list (char-after)))
1309   (let ((buf (get-buffer-create "*Character Description*"))
1310         (the-buf (current-buffer))
1311         (win-conf (current-window-configuration)))
1312     (pop-to-buffer buf)
1313     (make-local-variable 'what-character-original-window-configuration)
1314     (setq what-character-original-window-configuration win-conf)
1315     (setq buffer-read-only nil)
1316     (erase-buffer)
1317     (condition-case err
1318         (progn
1319           (insert-char-data-with-variant char 'printable)
1320           (unless (char-attribute-alist char)
1321             (insert (format ";; = %c\n"
1322                             (let* ((rest (split-char char))
1323                                    (ccs (pop rest))
1324                                    (code (pop rest)))
1325                               (while rest
1326                                 (setq code (logior (lsh code 8)
1327                                                    (pop rest))))
1328                               (decode-char ccs code)))))
1329           ;; (char-db-update-comment)
1330           (set-buffer-modified-p nil)
1331           (view-mode the-buf (lambda (buf)
1332                                (set-window-configuration
1333                                 what-character-original-window-configuration)
1334                                ))
1335           (goto-char (point-min)))
1336       (error (progn
1337                (set-window-configuration
1338                 what-character-original-window-configuration)
1339                (signal (car err) (cdr err)))))))
1340
1341
1342 ;;; @ end
1343 ;;;
1344
1345 (provide 'char-db-util)
1346
1347 ;;; char-db-util.el ends here