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