update.
[chise/chiset.git] / concord-turtle-dump.el
1 ;;; concord-turtle-dump.el --- Character Database utility -*- coding: utf-8-er; -*-
2
3 ;; Copyright (C) 2017,2018 MORIOKA Tomohiko.
4
5 ;; Author: MORIOKA Tomohiko <tomo@kanji.zinbun.kyoto-u.ac.jp>
6 ;; Keywords: CHISE, Character Database, RDF, Turtle, ISO/IEC 10646, UCS, Unicode, MULE.
7
8 ;; This file is part of CHISET (CHISE/Turtle).
9
10 ;; XEmacs CHISE is free software; you can redistribute it and/or
11 ;; modify it under the terms of the GNU General Public License as
12 ;; published by the Free Software Foundation; either version 2, or (at
13 ;; your option) any later version.
14
15 ;; XEmacs CHISE is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 ;; General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with XEmacs CHISE; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;; Code:
26
27 (require 'char-db-util)
28 (require 'cwiki-common)
29 (require 'isd-turtle)
30 (require 'ideograph-util)
31
32 (setq est-coded-charset-priority-list
33   '(; =ucs
34     =mj
35     =adobe-japan1-0
36     =adobe-japan1-1
37     =adobe-japan1-2
38     =adobe-japan1-3
39     =adobe-japan1-4
40     =adobe-japan1-5
41     =adobe-japan1-6
42     =ucs@iso
43     =jis-x0208 =jis-x0208@1990
44     =jis-x0213-1
45     =jis-x0213-1@2000 =jis-x0213-1@2004
46     =jis-x0213-2
47     =jis-x0212
48     =gt
49     =hanyo-denshi/ks
50     =hanyo-denshi/tk
51     =ucs-itaiji-001
52     =ucs-itaiji-002
53     =ucs-itaiji-003
54     =ucs-itaiji-004
55     =ucs-itaiji-005
56     =ucs-itaiji-006
57     =ucs-itaiji-007
58     =ucs-itaiji-008
59     =ucs-itaiji-009
60     =ucs-itaiji-010
61     =ucs-itaiji-011
62     =ucs-itaiji-084
63     =ucs-var-001
64     =ucs-var-002
65     =ucs-var-003
66     =ucs-var-004
67     =ucs-var-005
68     =ucs-var-006
69     =ucs-var-008
70     =ucs-var-010
71     =cns11643-1 =cns11643-2 =cns11643-3
72     =cns11643-4 =cns11643-5 =cns11643-6 =cns11643-7
73     =gb2312
74     =big5-cdp
75     =ks-x1001
76     =gt-k
77     =ucs@unicode
78     =ucs@JP/hanazono
79     =gb12345
80     =ucs@cns
81     =ucs@gb
82     =zinbun-oracle =>zinbun-oracle
83     =daikanwa
84     =ruimoku-v6
85     =cbeta =jef-china3
86     =daikanwa/+2p
87     =+>ucs@iso =+>ucs@unicode
88     =+>ucs@jis
89     =+>ucs@cns
90     =+>ucs@ks
91     =+>ucs@jis/1990
92     =>mj
93     =>jis-x0208 =>jis-x0213-1
94     =>jis-x0208@1997
95     =>ucs@iwds-1
96     =>ucs@cognate
97     =>ucs@component
98     =>iwds-1
99     =>ucs@iso
100     =>ucs@unicode
101     =>ucs@jis =>ucs@cns =>ucs@ks
102     =>gt
103     =>gt-k
104     =>>ucs@iso =>>ucs@unicode
105     =>>ucs@jis =>>ucs@cns =>>ucs@ks
106     =>>gt-k
107     =>>hanyo-denshi/ks
108     ==mj
109     ==ucs@iso
110     ==ucs@unicode
111     ==adobe-japan1-0
112     ==adobe-japan1-1
113     ==adobe-japan1-2
114     ==adobe-japan1-3
115     ==adobe-japan1-4
116     ==adobe-japan1-5
117     ==adobe-japan1-6
118     ==ks-x1001
119     ==hanyo-denshi/ks
120     ==hanyo-denshi/tk
121     ==ucs@jis
122     ==gt
123     ==cns11643-1 ==cns11643-2 ==cns11643-3
124     ==cns11643-4 ==cns11643-5 ==cns11643-6 ==cns11643-7
125     ==jis-x0212
126     ==ucs@cns
127     ==koseki
128     ==daikanwa
129     ==gt-k
130     ==ucs@gb
131     ==ucs-itaiji-001
132     ==ucs-itaiji-002
133     ==ucs-itaiji-003
134     ==ucs-itaiji-005
135     ==ucs-var-002
136     ==ucs@JP/hanazono
137     ==daikanwa/+2p
138     =>>jis-x0208 =>>jis-x0213-1 =>>jis-x0213-2
139     =+>jis-x0208 =+>jis-x0213-1 =+>jis-x0213-2
140     =+>hanyo-denshi/jt
141     =+>jis-x0208@1978
142     =>>gt
143     =+>adobe-japan1
144     =>>adobe-japan1
145     =jis-x0208@1983 =jis-x0208@1978
146     =>ucs-itaiji-001
147     =>ucs-itaiji-002
148     =>ucs-itaiji-003
149     =>ucs-itaiji-004
150     =>ucs-itaiji-005
151     =>ucs-itaiji-006
152     =>ucs-itaiji-007
153     ==>ucs@bucs
154     =big5
155     =>cbeta
156     ===mj
157     ===ucs@iso
158     ===ucs@unicode
159     ===hanyo-denshi/ks
160     ===ks-x1001
161     ===gt
162     ===gt-k
163     ===ucs@ks
164     ===ucs@gb
165     =shinjigen
166     =shinjigen@rev
167     =shinjigen@1ed
168     =shinjigen/+p@rev
169     ==shinjigen
170     ==shinjigen@rev
171     ==daikanwa/+p
172     ==shinjigen@1ed
173     ===daikanwa/+p
174     =>daikanwa/ho
175     ===daikanwa/ho
176     ))
177
178 (defvar chise-turtle-ccs-prefix-alist nil)
179
180 (setq chise-turtle-feature-domains
181       (append char-db-feature-domains
182               (let (dest domain)
183                 (dolist (feature (char-attribute-list))
184                   (setq feature (symbol-name feature))
185                   (when (string-match
186                          "\\(radical\\|strokes\\)@\\([^@*]+\\)\\(\\*\\|$\\)"
187                          feature)
188                     (setq domain (intern (match-string 2 feature)))
189                     (unless (memq domain dest)
190                       (setq dest (cons domain dest)))))
191                 (sort dest #'string<))))
192
193 (defun charset-code-point-format-spec (ccs)
194   (cond ((memq ccs '(=ucs))
195          "0x%04X")
196         (t
197          (let ((ccs-name (symbol-name ccs)))
198            (cond
199             ((string-match
200               "\\(shinjigen\\|daikanwa/ho\\|=>iwds-1\\)"
201               ccs-name)
202              "%04d")
203             ((string-match
204               "\\(gt\\|daikanwa\\|adobe-japan1\\|cbeta\\|zinbun-oracle\\|hng\\)"
205               ccs-name)
206              "%05d")
207             ((string-match "\\(hanyo-denshi/ks\\|koseki\\|mj\\)" ccs-name)
208              "%06d")
209             ((string-match "hanyo-denshi/tk" ccs-name)
210              "%08d")
211             (t
212              "0x%X"))))))
213
214 (defun chise-turtle-uri-decode-feature-name (uri-feature)
215   (cond ((string= "a.ucs" uri-feature)
216          '=ucs)
217         ((string= "a.big5" uri-feature)
218          '=big5)
219         (t
220          (www-uri-decode-feature-name uri-feature))))
221
222 (defun chise-turtle-uri-encode-ccs-name (feature-name)
223   (cond
224    ((eq '=ucs feature-name)
225     "a.ucs")
226    ((eq '=big5 feature-name)
227     "a.big5")
228    ((eq '==>ucs@bucs feature-name)
229     "bucs")
230    (t
231     (mapconcat (lambda (c)
232                  (cond
233                   ((eq c ?@)
234                    "_")
235                   ((eq c ?+)
236                    "._.")
237                   ((eq c ?=)
238                    ".:.")
239                   ((eq c ?|)
240                    "._cmp_.")
241                   (t
242                    (char-to-string c))))
243                (www-uri-encode-feature-name feature-name)
244                ""))))
245
246 (defun chise-turtle-uri-encode-feature-name (feature-name)
247   (cond
248    ((eq '->subsumptive feature-name)
249     ":subsume")
250    ((eq '<-denotational feature-name)
251     ":denotation-of")
252    ((eq '<-formed feature-name)
253     ":form-of")
254    ((eq '<-same feature-name)
255     "ideo:same-as")
256    ((eq '<-simplified feature-name)
257     "ideo:simplified-form-of")
258    ((eq '<-vulgar feature-name)
259     "ideo:vulgar-form-of")
260    ((eq '<-wrong feature-name)
261     "ideo:wrong-form-of")
262    ((eq '<-original feature-name)
263     "ideo:original-form-of")
264    ((eq '<-ancient feature-name)
265     "ideo:ancient-form-of")
266    ((eq '<-Small-Seal feature-name)
267     "ideo:Small-Seal-of")
268    ((eq '<-interchangeable feature-name)
269     "ideo:interchangeable-form-of")
270    ((eq '->interchangeable feature-name)
271     "ideo:interchangeable")
272    ((eq '->mistakable feature-name)
273     "ideo:mistakable")
274    ((eq 'hanyu-dazidian feature-name)
275     "ideo:hanyu-dazidian")
276    (t
277     (concat ":" (chise-turtle-uri-encode-ccs-name feature-name)))))
278
279 (defun chise-turtle-format-ccs-code-point (ccs code-point)
280   (let ((ccs-uri (chise-turtle-uri-encode-ccs-name ccs)))
281     (unless (assoc ccs-uri chise-turtle-ccs-prefix-alist)
282       (setq chise-turtle-ccs-prefix-alist
283             (cons (cons ccs-uri ccs)
284                   chise-turtle-ccs-prefix-alist)))
285     (format "%s:%s"
286             ccs-uri
287             (format (charset-code-point-format-spec ccs)
288                     code-point))))
289
290 (defun chise-turtle-encode-char (object)
291   (let ((ccs-list est-coded-charset-priority-list)
292         ccs ret ret2)
293     (if (setq ret (encode-char object '=ucs))
294         (chise-turtle-format-ccs-code-point '=ucs ret)
295       (while (and ccs-list
296                   (setq ccs (pop ccs-list))
297                   (not (setq ret (encode-char object ccs 'defined-only)))))
298       (cond (ret
299              (chise-turtle-format-ccs-code-point ccs ret)
300              )
301             ((and (setq ccs (car (split-char object)))
302                   (setq ret (encode-char object ccs)))
303              (chise-turtle-format-ccs-code-point ccs ret)
304              )
305             ((setq ret (get-char-attribute object 'ideographic-combination))
306              (format "ideocomb:%s"
307                      (mapconcat (lambda (cell)
308                                   (cond ((characterp cell)
309                                          (char-to-string cell)
310                                          )
311                                         ((setq ret2 (find-char cell))
312                                          (char-to-string ret2)
313                                          )
314                                         (t
315                                          (format "%S" cell)
316                                          )))
317                                 ret ""))
318              )
319             (t
320              (format (if est-hide-cgi-mode
321                          "system-char-id=0x%X"
322                        "system-char-id:0x%X")
323                      (encode-char object 'system-char-id))
324              )))))
325
326 (defun concord-turtle-encode-object (obj)
327   (cond ((characterp obj)
328          (chise-turtle-encode-char obj)
329          )
330         ((concord-object-p obj)
331          (let ((genre (est-object-genre obj))
332                (url-object (www-uri-encode-object obj)))
333            (format "<%s/%s/%s>"
334                    "http://www.chise.org/est/view"
335                    genre
336                    url-object)))))
337
338 (defun chise-split-feature-name (feature-name)
339   (let (base domain number meta)
340     (setq feature-name (symbol-name feature-name))
341     (if (string-match ".\\*." feature-name)
342         (setq meta (intern
343                     (format ":%s" (substring feature-name (1- (match-end 0)))))
344               feature-name (substring feature-name 0 (1+ (match-beginning 0)))))
345     (if (string-match "\\$_\\([0-9]+\\)$" feature-name)
346         (setq number (car (read-from-string (match-string 1 feature-name)))
347               feature-name (substring feature-name 0 (match-beginning 0))))
348     (if (string-match "@" feature-name)
349         (setq domain (car (read-from-string (substring feature-name (match-end 0))))
350               base (intern (substring feature-name 0 (match-beginning 0))))
351       (setq base (intern feature-name)))
352     (list base domain number meta)))
353
354 (defun chise-compose-feature-name (base domain number meta)
355   (let ((name (if domain
356                   (format "%s@%s" base domain)
357                 (symbol-name base))))
358     (if number
359         (setq name (format "%s$_%d" name number)))
360     (if meta
361         (setq name (format "%s*%s" name
362                            (substring (symbol-name meta) 1))))
363     (intern name)))
364
365 (defvar chise-feature-name-base-metadata-alist nil)
366
367 (defun chise-update-feature-name-base-metadata-alist ()
368   (interactive)
369   (let (base domain number metadata
370              bcell dcell ncell ret)
371     (setq chise-feature-name-base-metadata-alist nil)
372     (dolist (fname (sort (char-attribute-list)
373                          #'char-attribute-name<))
374       (setq ret (chise-split-feature-name fname)
375             base (car ret)
376             domain (nth 1 ret)
377             number (nth 2 ret)
378             metadata (nth 3 ret))
379       (when metadata
380         (if (setq bcell (assq base chise-feature-name-base-metadata-alist))
381             (if (setq dcell (assq domain (cdr bcell)))
382                 (if (setq ncell (assq number (cdr dcell)))
383                     (unless (memq metadata (cdr ncell))
384                       (setcdr ncell (nconc (cdr ncell)
385                                            (list metadata))))
386                   (setcdr dcell (cons (list number metadata)
387                                       (cdr dcell))))
388               (setcdr bcell (cons (list domain (list number metadata))
389                                   (cdr bcell))))
390           (setq chise-feature-name-base-metadata-alist
391                 (cons (list base (list domain (list number metadata)))
392                       chise-feature-name-base-metadata-alist))
393           )))))
394
395 (chise-update-feature-name-base-metadata-alist)
396
397 (defun chise-get-char-attribute-with-metadata (obj-spec feature-name-base domain)
398   (let ((feature-pair (assq (chise-compose-feature-name
399                              feature-name-base domain nil nil)
400                             obj-spec))
401         value
402         dcell
403         base-metadata metadata
404         ret m i rest dest)
405     (when feature-pair
406       (setq value (cdr feature-pair))
407       (cond
408        ((and (setq ret (assq feature-name-base
409                              chise-feature-name-base-metadata-alist))
410              (setq dcell (assq domain (cdr ret))))
411         (if (setq ret (assq nil (cdr dcell)))
412             (dolist (bmn (cdr ret))
413               (when (setq m (assq (chise-compose-feature-name
414                                    feature-name-base domain nil bmn)
415                                   obj-spec))
416                 (setq m (cdr m))
417                 (setq base-metadata
418                       (list* bmn m base-metadata)))))
419         (setq i 1
420               rest value)
421         (while (consp rest)
422           (setq dest
423                 (cons (cond
424                        ((setq ret (assq i (cdr dcell)))
425                         (setq metadata nil)
426                         (dolist (mn (cdr ret))
427                           (when (setq m (assq (chise-compose-feature-name
428                                                feature-name-base domain i mn)
429                                               obj-spec))
430                             (setq m (cdr m))
431                             (setq metadata (list* mn m metadata))))
432                         (if metadata
433                             (list* :value (car rest) metadata)
434                           (car rest))
435                         )
436                        (t (car rest)))
437                       dest))
438           (setq i (1+ i)
439                 rest (cdr rest)))
440         (list (nconc (nreverse dest) rest)
441               base-metadata)
442         )
443        (t (list value nil)))
444       )))
445           
446 (defun chise-split-ccs-name (ccs)
447   (cond ((eq ccs '=ucs)
448          '(ucs abstract-character nil)
449          )
450         ((eq ccs '=big5)
451          '(big5 abstract-character nil)
452          )
453         (t
454          (setq ccs (symbol-name ccs))
455          (let (ret)
456            (if (string-match "^\\(=[=+>]*\\)\\([^=>@*]+\\)@?" ccs)
457                (list (intern (match-string 2 ccs))
458                      (chise-decode-ccs-prefix (match-string 1 ccs))
459                      (if (string= (setq ret (substring ccs (match-end 0))) "")
460                          nil
461                        (intern ret))))
462            ))))
463
464 (defun chise-decode-ccs-prefix (ccs)
465   (or (cdr (assoc ccs '(("==>" . super-abstract-character)
466                         ("=>"  . abstract-character)
467                         ("=+>" . unified-glyph)
468                         ("="   . abstract-glyph)
469                         ("=>>" . detailed-glyph)
470                         ("=="  . abstract-glyph-form)
471                         ("===" . glyph-image))))
472       'character))
473
474 (defun chise-turtle-uri-split-ccs (uri-ccs)
475   (cond
476    ((string-match "^a2\\." uri-ccs)
477     (cons ":super-abstract-character"
478           (substring uri-ccs (match-end 0)))
479     )
480    ((string-match "^a\\." uri-ccs)
481     (cons ":abstract-character"
482           (substring uri-ccs (match-end 0)))
483     )
484    ((string-match "^o\\." uri-ccs)
485     (cons ":unified-glyph"
486           (substring uri-ccs (match-end 0)))
487     )
488    ((string-match "^rep\\." uri-ccs)
489     (cons ":abstract-glyph"
490           (substring uri-ccs (match-end 0)))
491     )
492    ((string-match "^g\\." uri-ccs)
493     (cons ":detailed-glyph"
494           (substring uri-ccs (match-end 0)))
495     )
496    ((string-match "^g2\\." uri-ccs)
497     (cons ":abstract-glyph-form"
498           (substring uri-ccs (match-end 0)))
499     )
500    ((string-match "^gi\\." uri-ccs)
501     (cons ":abstract-glyph-form"
502           (substring uri-ccs (match-end 0)))
503     )
504    ((string-match "^repi\\." uri-ccs)
505     (cons ":glyph-image"
506           (substring uri-ccs (match-end 0)))
507     )
508    (t (cons ":character" uri-ccs))))
509
510 (defun concord-turtle-insert-relation-feature (char name value line-breaking
511                                                     ccss readable)
512   (insert (format "    %s%s        "
513                   (chise-turtle-uri-encode-feature-name name)
514                   line-breaking))
515   (concord-turtle-insert-relations value readable)
516   (insert " ;")
517   )
518
519 (defun concord-turtle-insert-metadata (name value)
520   (let (col indent ret)
521     (insert (format "%-7s " name))
522     (cond
523      ((or (eq name :sources)
524           (eq name :denied))
525       (setq col (current-column))
526       (setq indent (make-string col ?\ ))
527       (insert (format "chisebib:%s"
528                       (chise-turtle-uri-encode-ccs-name (car value))))
529       (dolist (source (cdr value))
530         (insert (format " ,\n%schisebib:%s" indent
531                         (chise-turtle-uri-encode-ccs-name source))))
532       nil)
533      ((eq name :references)
534       (setq ret (car value))
535       (setq ret (plist-get (nth 1 ret) :ref))
536       (setq col (current-column))
537       (setq indent (make-string col ?\ ))
538       (insert (format "<%s>" ret))
539       (dolist (refspec (cdr value))
540         (setq ret (plist-get (nth 1 refspec) :ref))
541         (insert (format " ,\n%s<%s>" indent ret)))
542       nil)
543      (t
544       (insert (format "%S" value))
545       nil))))
546
547 (defun concord-turtle-insert-radical (radical-number)
548   (insert (format "        %3d ; # %c"
549                   radical-number
550                   (ideographic-radical radical-number)))
551   'with-separator)
552
553 (defun concord-turtle-insert-list (value &optional readable)
554   (let (lbs separator rest cell al cal key ret)
555     (insert "( ")
556     (setq lbs (concat "\n" (make-string (current-column) ?\ ))
557           separator nil)
558     (while (consp value)
559       (setq cell (car value))
560       (if (and (consp cell)
561                (consp (car cell))
562                (setq ret (condition-case nil
563                              (find-char cell)
564                            (error nil))))
565           (progn
566             (setq rest cell
567                   al nil
568                   cal nil)
569             (while rest
570               (setq key (car (car rest)))
571               (if (find-charset key)
572                   (setq cal (cons key cal))
573                 (setq al (cons key al)))
574               (setq rest (cdr rest)))
575             (if separator
576                 (insert lbs))
577             (concord-turtle-insert-object-features ret
578                                                  readable
579                                                  al
580                                                  nil 'for-sub-node)
581             (setq separator lbs))
582         (setq ret (prin1-to-string cell))
583         (if separator
584             (if (< (+ (current-column)
585                       (length ret)
586                       (length separator))
587                    76)
588                 (insert separator)
589               (insert lbs)))
590         (insert ret)
591         (setq separator " "))
592       (setq value (cdr value)))
593     (insert " ) ;")
594     'with-separator))
595
596 (defun concord-turtle-insert-source-list (value &optional readable)
597   (let (lbs separator rest cell al cal key ret)
598     (setq lbs (concat " ,\n" (make-string (current-column) ?\ ))
599           separator nil)
600     (while (consp value)
601       (setq cell (car value))
602       (if (and (consp cell)
603                (consp (car cell))
604                (setq ret (condition-case nil
605                              (find-char cell)
606                            (error nil))))
607           (progn
608             (setq rest cell
609                   al nil
610                   cal nil)
611             (while rest
612               (setq key (car (car rest)))
613               (if (find-charset key)
614                   (setq cal (cons key cal))
615                 (setq al (cons key al)))
616               (setq rest (cdr rest)))
617             (if separator
618                 (insert lbs))
619             (concord-turtle-insert-object-features ret
620                                                  readable
621                                                  al
622                                                  nil 'for-sub-node)
623             (setq separator lbs))
624         (setq ret (prin1-to-string cell))
625         (if separator
626             (if (< (+ (current-column)
627                       (length ret)
628                       (length separator))
629                    76)
630                 (insert separator)
631               (insert lbs)))
632         (if (string-match "=" ret)
633             (insert (format "%s:%s"
634                             (substring ret 0 (match-beginning 0))
635                             (substring ret (match-end 0))))
636           (insert (format "chisebib:%s" ret)))
637         (setq separator " , "))
638       (setq value (cdr value)))
639     (insert " ;")
640     'with-separator))
641
642 (defun concord-turtle-insert-relations (value &optional readable)
643   (let ((lbs (concat "\n" (make-string (current-column) ?\ )))
644         separator cell)
645     (if (characterp value)
646         (setq value (list value)))
647     (while (consp value)
648       (setq cell (car value))
649       (if (integerp cell)
650           (setq cell (decode-char '=ucs cell)))
651       (if separator
652           (insert separator)
653         (setq separator (format " ,%s" lbs)))
654       (cond
655        ((characterp cell)
656         (insert (format "%-20s" (chise-turtle-encode-char cell)))
657         )
658        ((concord-object-p cell)
659         (insert (format "%-20s" (concord-turtle-encode-object cell)))
660         )
661        (t
662         (concord-turtle-insert-char-ref cell '<-formed)))
663       (setq value (cdr value)))
664     nil))
665
666 (defun concord-turtle-insert-target-value (value feature-name-base &optional readable)
667   (cond ((eq feature-name-base 'ideographic-radical)
668          (concord-turtle-insert-radical value)
669          )
670         ((or (eq feature-name-base 'ideographic-combination)
671              (eq feature-name-base '=decomposition)
672              (eq feature-name-base '<-formed)
673              (string-match "^\\(->\\|<-\\)[^*]*$" (symbol-name feature-name-base)))
674          (concord-turtle-insert-relations value readable)
675          )
676         ((eq feature-name-base 'comment)
677          (insert (format "%S" value))
678          nil)
679         ((eq feature-name-base 'sources)
680          (concord-turtle-insert-source-list value readable)
681          )
682         ((consp value)
683          (concord-turtle-insert-list value readable)
684          )
685         ((or (symbolp value)
686              (char-or-string-p value))
687          (insert (format " %-14s" (format "\"%s\"" value)))
688          nil)
689         (t
690          (insert (format " %-14s" value))
691          nil)))
692
693 (defun concord-turtle-insert-feature-value (value metadata domain feature-name-base)
694   (let (indent0 indent rest mdname mdval lb)
695     (cond
696      ((or metadata domain)
697       (setq indent0 (make-string (current-column) ?\ ))
698       (insert "[ ")
699       (setq indent (make-string (current-column) ?\ ))
700       (when domain
701         (insert (format ":context domain:%-7s ;"
702                         (chise-turtle-uri-encode-ccs-name domain)))
703         (setq lb t))
704       (setq rest metadata)
705       (while rest
706         (setq mdname (pop rest)
707               mdval  (pop rest))
708         (if lb
709             (insert (format "\n%s" indent))
710           (setq lb t))
711         (unless (concord-turtle-insert-metadata mdname mdval)
712           (insert " ;")))
713       (if lb
714           (insert (format "\n%s" indent)))
715       (insert "rdf:value  ")
716       (if (concord-turtle-insert-target-value value feature-name-base)
717           (insert (format "\n%s] ;" indent0))
718         (insert " ] ;"))
719       'with-separator)
720      (t
721       (concord-turtle-insert-target-value value feature-name-base)
722       ))))
723
724 (defun concord-turtle-insert-char-ref (char-ref feature-name-base)
725   (let (indent0 indent rest mdname mdval lb last-sep)
726     (setq indent0 (make-string (current-column) ?\ ))
727     (insert "[ ")
728     (setq indent (make-string (current-column) ?\ ))
729     (setq rest char-ref)
730     (while rest
731       (setq mdname (pop rest)
732             mdval  (pop rest))
733       (if lb
734           (insert (format "%s\n%s"
735                           (if last-sep
736                               ""
737                             " ;")
738                           indent))
739         (setq lb t))
740       (setq last-sep
741             (cond ((eq mdname :value)
742                    (insert "rdf:value  ")
743                    (concord-turtle-insert-target-value mdval feature-name-base)
744                    )
745                   (t
746                    (concord-turtle-insert-metadata mdname mdval)))))
747     (if last-sep
748         (insert (format "\n%s]" indent0))
749       (insert " ]"))
750     nil))
751   
752 (defun concord-turtle-insert-object-features (object
753                                               &optional readable attributes column
754                                               for-sub-node)
755   (unless column
756     (setq column (current-column)))
757   (let ((est-coded-charset-priority-list est-coded-charset-priority-list)
758         (est-view-url-prefix "http://chise.org/est/view")
759         (obj-spec (sort (del-alist 'composition
760                                    (if (characterp object)
761                                        (char-attribute-alist object)
762                                      (concord-object-spec object)))
763                         (lambda (a b)
764                           (char-attribute-name< (car a)(car b)))))
765         feature-pair
766         id obj-id type domain
767         name value metadata
768         name-base name-domain
769         radical strokes
770         (line-breaking (concat "\n" (make-string column ?\ )))
771         line-separator
772         ret
773         skey
774         dest-ccss ; sources required-features
775         ccss eq-cpos-list
776         uri-ccs uri-cpos ccs-base children child-ccs-list col indent)
777     (setq line-separator line-breaking)
778     (setq id (concord-turtle-encode-object object))
779     (insert (format "%s" id))
780     (cond
781      ((characterp object)
782       (setq obj-id (file-name-nondirectory id))
783       (string-match ":" obj-id)
784       (setq uri-ccs (substring obj-id 0 (match-beginning 0))
785             uri-cpos (substring obj-id (match-end 0)))
786       (setq ret (assoc uri-ccs chise-turtle-ccs-prefix-alist))
787       (setq dest-ccss (list (cdr ret)))
788       (setq ret (chise-split-ccs-name (cdr ret)))
789       (setq ccs-base (car ret)
790             type (nth 1 ret)
791             domain (nth 2 ret))
792       (insert (format "%s    a chisegg:%s ;" line-separator type))
793       (insert (format "%s    :%s-of" line-breaking type))
794       (if (null domain)
795           (insert (format " %s:%s ;"
796                           (chise-turtle-uri-encode-ccs-name ccs-base) uri-cpos))
797         (insert " [ ")
798         (setq col (current-column))
799         (insert (format ":context domain:%-7s ;\n%srdf:value %7s:%-7s ] ;"
800                         (chise-turtle-uri-encode-ccs-name domain)
801                         (make-string col ?\ )
802                         (chise-turtle-uri-encode-ccs-name ccs-base) uri-cpos)))
803       ))
804     (when (setq feature-pair (assq '<-subsumptive obj-spec))
805       (when (or readable (not for-sub-node))
806         (when (setq value (cdr feature-pair))
807           (insert line-separator)
808           (concord-turtle-insert-relation-feature object '<-subsumptive value
809                                                   line-breaking
810                                                   ccss readable)
811           ))
812       (setq obj-spec (delete feature-pair obj-spec))
813       )
814     (when (and (setq feature-pair (assq '<-denotational obj-spec))
815                (setq value (cdr feature-pair)))
816       (insert line-separator)
817       (concord-turtle-insert-relation-feature object '<-denotational value
818                                             line-breaking
819                                             ccss readable)
820       (setq obj-spec (delete feature-pair obj-spec))
821       )
822     (when (and (setq feature-pair (assq '<-denotational@component obj-spec))
823                (setq value (cdr feature-pair)))
824       (insert line-separator)
825       (concord-turtle-insert-relation-feature
826        object '<-denotational@component value
827        line-breaking
828        ccss readable)
829       (setq obj-spec (delete feature-pair obj-spec))
830       )
831     (when (and (setq feature-pair (assq 'name obj-spec))
832                (setq value (cdr feature-pair)))
833       (insert (format "%s    " line-separator))
834       (insert (format
835                (if (> (+ (current-column) (length value)) 48)
836                    ":name %S ;"
837                  ":name                 %S ;")
838                value))
839       (setq obj-spec (delete feature-pair obj-spec))
840       )
841     (when (and (setq feature-pair (assq 'name* obj-spec))
842                (setq value (cdr feature-pair)))
843       (insert (format "%s    " line-separator))
844       (insert (format
845                (if (> (+ (current-column) (length value)) 48)
846                    ":unofficial-name %S ;"
847                  ":unofficial-name       %S ;")
848                value))
849       (setq obj-spec (delete feature-pair obj-spec))
850       )
851     (when (and (setq feature-pair (assq 'script obj-spec))
852                (setq value (cdr feature-pair)))
853       (insert (format "%s    :script\t\t  ( %s ) ;"
854                       line-separator
855                       (mapconcat (lambda (cell)
856                                    (format "script:%s" cell))
857                                  value " ")))
858       (setq obj-spec (delete feature-pair obj-spec))
859       )
860     (when (and (setq feature-pair (assq '=>ucs obj-spec))
861                (setq value (cdr feature-pair)))
862       (insert (format "%s    :to.ucs\t\t  a.ucs:0x%04X ; # %c"
863                       line-separator value (decode-char '=ucs value)))
864       (setq obj-spec (delete feature-pair obj-spec))
865       )
866     (when (and (setq feature-pair (assq '=>ucs* obj-spec))
867                (setq value (cdr feature-pair)))
868       (insert (format "%s    :to.canonical-ucs\ta.ucs:0x%04X ; # %c"
869                       line-separator value (decode-char '=ucs value)))
870       (setq obj-spec (delete feature-pair obj-spec))
871       )
872     (dolist (name '(=>ucs@gb =>ucs@big5))
873       (when (and (setq feature-pair (assq name obj-spec))
874                  (setq value (cdr feature-pair)))
875         (insert line-separator)
876         (insert (format " \"%-20s\":  #x%04X,\t\"_comment\": \"%c\"%s"
877                         name value
878                         (decode-char (intern
879                                       (concat "="
880                                               (substring
881                                                (symbol-name name) 2)))
882                                      value)
883                         line-breaking))
884         (setq obj-spec (delete feature-pair obj-spec))
885         ))
886     (when (and (setq feature-pair (assq 'general-category obj-spec))
887                (setq value (cdr feature-pair)))
888       (insert (format "%s    :general-category     \"%s\" ; # %s"
889                       line-separator value
890                       (cond ((rassoc value unidata-normative-category-alist)
891                              "Normative Category")
892                             ((rassoc value unidata-informative-category-alist)
893                              "Informative Category")
894                             (t
895                              "Unknown Category"))))
896       (setq obj-spec (delete feature-pair obj-spec))
897       )
898     (when (and (setq feature-pair (assq 'bidi-category obj-spec))
899                (setq value (cdr feature-pair)))
900       (insert (format "%s    :bidi-category        %S ;"
901                       line-separator
902                       value))
903       (setq obj-spec (delete feature-pair obj-spec))
904       )
905     (when (and (setq feature-pair (assq 'mirrored obj-spec))
906                (setq value (cdr feature-pair)))
907       (insert (format "%s    :mirrored             \"%s\" ;"
908                       line-separator
909                       value))
910       (setq obj-spec (delete feature-pair obj-spec))
911       )
912     (cond
913      ((and (and (setq feature-pair (assq 'decimal-digit-value obj-spec))
914                 (setq value (cdr feature-pair))))
915       (insert (format "%s    :decimal-digit-value  %2d ;"
916                       line-separator value))
917       (setq obj-spec (delete feature-pair obj-spec))
918       (when (and (setq feature-pair (assq 'digit-value obj-spec))
919                  (setq value (cdr feature-pair)))
920         (insert (format "%s    :digit-value\t  %2d ;"
921                         line-separator value))
922         (setq obj-spec (delete feature-pair obj-spec))
923         )
924       (when (and (setq feature-pair (assq 'numeric-value obj-spec))
925                  (setq value (cdr feature-pair)))
926         (insert (format "%s    :numeric-value\t  %2d ;"
927                         line-separator value))
928         (setq obj-spec (delete feature-pair obj-spec))
929         )
930       )
931      (t
932       (when (and (setq feature-pair (assq 'digit-value obj-spec))
933                  (setq value (cdr feature-pair)))
934         (insert line-separator)
935         (insert (format "%s    :digit-value\t  %2d ;"
936                         line-separator value))
937         (setq obj-spec (delete feature-pair obj-spec))
938         )
939       (when (and (setq feature-pair (assq 'numeric-value obj-spec))
940                  (setq value (cdr feature-pair)))
941         (insert line-separator)
942         (insert (format "%s    :numeric-value\t  %2d ;"
943                         line-separator value))
944         (setq obj-spec (delete feature-pair obj-spec))
945         )))
946     (when (and (setq feature-pair (assq 'iso-10646-comment obj-spec))
947                (setq value (cdr feature-pair)))
948       (insert line-separator)
949       (insert (format "{\"iso-10646-comment\":\t %S}%s"
950                       value
951                       line-breaking))
952       (setq obj-spec (delete feature-pair obj-spec))
953       )
954     (when (and (setq feature-pair (assq 'morohashi-daikanwa obj-spec))
955                (setq value (cdr feature-pair)))
956       (insert line-separator)
957       (insert (format "%s    :morohashi-daikanwa\t  %S ;"
958                       line-separator value))
959       (setq obj-spec (delete feature-pair obj-spec))
960       )
961     (setq radical nil
962           strokes nil)
963     (when (and (setq feature-pair (assq 'ideographic-radical obj-spec))
964                (setq value (cdr feature-pair)))
965       (setq radical value)
966       (insert (format "%s    ideo:radical         %3d ; # %c "
967                       line-separator
968                       radical
969                       (ideographic-radical radical)
970                       ))
971       (setq obj-spec (delete feature-pair obj-spec))
972       )
973     (when (and (setq feature-pair (assq 'shuowen-radical obj-spec))
974                (setq value (cdr feature-pair)))
975       (insert line-separator)
976       (insert (format " \"shuowen-radical\":\t %S,\t\"_comment\": \"%c\""
977                       value
978                       (shuowen-radical value)))
979       (setq obj-spec (delete feature-pair obj-spec))
980       )
981     (let (key)
982       (dolist (domain chise-turtle-feature-domains)
983         (setq key (intern (format "%s@%s" 'ideographic-radical domain)))
984         (when (and (setq feature-pair (assq key obj-spec))
985                    (setq value (cdr feature-pair)))
986           (setq radical value)
987           (insert (format "%s    ideo:radical           [ "
988                           line-separator))
989           (setq col (current-column))
990           (setq indent (make-string col ?\ ))
991           (insert (format ":context domain:%-7s ;\n%srdf:value  %S"
992                           (chise-turtle-uri-encode-ccs-name domain)
993                           indent radical))
994           (setq obj-spec (delete feature-pair obj-spec))
995           (setq skey (intern (format "%s*sources" key)))
996           (when (and (setq feature-pair (assq skey obj-spec))
997                      (setq value (cdr feature-pair)))
998             (insert (format " ;\n%s" indent))
999             (concord-turtle-insert-metadata :sources value)
1000             ;; (insert (format " ;\n%s:sources (" indent))
1001             ;; (setq col (current-column))
1002             ;; (setq indent (make-string col ?\ ))
1003             ;; (insert (format " chisebib:%s" (car value)))
1004             ;; (dolist (cell (cdr value))
1005             ;;   (insert (format "\n%s chisebib:%s" indent cell)))
1006             ;; (insert " )")
1007             )
1008           (setq obj-spec (delete feature-pair obj-spec))
1009           (insert " ] ;")
1010           )
1011         (setq key (intern (format "%s@%s" 'ideographic-strokes domain)))
1012         (when (and (setq feature-pair (assq key obj-spec))
1013                    (setq value (cdr feature-pair)))
1014           (setq strokes value)
1015           (insert (format "%s    ideo:strokes           [ "
1016                           line-separator))
1017           (setq col (current-column))
1018           (setq indent (make-string col ?\ ))
1019           (insert (format ":context domain:%-7s ;\n%srdf:value  %S"
1020                           (chise-turtle-uri-encode-ccs-name domain)
1021                           indent strokes))
1022           (setq obj-spec (delete feature-pair obj-spec))
1023           (setq skey (intern (format "%s*sources" key)))
1024           (when (and (setq feature-pair (assq skey obj-spec))
1025                      (setq value (cdr feature-pair)))
1026             (insert (format " ;\n%s" indent))
1027             (concord-turtle-insert-metadata :sources value)
1028             ;; (insert (format " ;\n%s:sources (" indent))
1029             ;; (setq col (current-column))
1030             ;; (setq indent (make-string col ?\ ))
1031             ;; (insert (format " chisebib:%s" (car value)))
1032             ;; (dolist (cell (cdr value))
1033             ;;   (insert (format "\n%s chisebib:%s" indent cell)))
1034             ;; (insert " )")
1035             )
1036           (setq obj-spec (delete feature-pair obj-spec))
1037           (insert " ] ;")
1038           )
1039         (setq key (intern (format "%s@%s" 'total-strokes domain)))
1040         (when (and (setq feature-pair (assq key obj-spec))
1041                    (setq value (cdr feature-pair)))
1042           (insert (format "%s    ideo:total-strokes     [ "
1043                           line-separator))
1044           (setq col (current-column))
1045           (insert (format ":context domain:%-7s ;\n%srdf:value  %S"
1046                           (chise-turtle-uri-encode-ccs-name domain)
1047                           (make-string col ?\ )
1048                           value))
1049           (setq obj-spec (delete feature-pair obj-spec))
1050           (setq skey (intern (format "%s*sources" key)))
1051           (when (and (setq feature-pair (assq skey obj-spec))
1052                      (setq value (cdr feature-pair)))
1053             (insert (format " ;\n%s" indent))
1054             (concord-turtle-insert-metadata :sources value)
1055             ;; (insert (format " ;\n%s:sources (" indent))
1056             ;; (setq col (current-column))
1057             ;; (setq indent (make-string col ?\ ))
1058             ;; (insert (format " chisebib:%s" (car value)))
1059             ;; (dolist (cell (cdr value))
1060             ;;   (insert (format "\n%s chisebib:%s" indent cell)))
1061             ;; (insert " )")
1062             )
1063           (setq obj-spec (delete feature-pair obj-spec))
1064           (insert " ] ;")
1065           )
1066         ;; (dolist (feature '(ideographic-radical
1067         ;;                    ideographic-strokes
1068         ;;                    total-strokes))
1069         ;;   (setq key (intern (format "%s@%s*sources" feature domain)))
1070         ;;   (when (and (setq feature-pair (assq key obj-spec))
1071         ;;              (setq value (cdr feature-pair)))
1072         ;;     (insert line-separator)
1073         ;;     (insert (format " \"%s\":%s" key line-breaking))
1074         ;;     (dolist (cell value)
1075         ;;       (insert (format " %s" cell)))
1076         ;;     (setq obj-spec (delete feature-pair obj-spec))
1077         ;;     ))
1078         ))
1079     (when (and (setq feature-pair (assq 'ideographic-strokes obj-spec))
1080                (setq value (cdr feature-pair)))
1081       (setq strokes value)
1082       (insert (format "%s    ideo:strokes          %2d ;"
1083                       line-separator strokes))
1084       (setq obj-spec (delete feature-pair obj-spec))
1085       )
1086     (when (and (setq feature-pair (assq 'total-strokes obj-spec))
1087                (setq value (cdr feature-pair)))
1088       (insert (format "%s    ideo:total-strokes    %2d ;"
1089                       line-separator value))
1090       (setq obj-spec (delete feature-pair obj-spec))
1091       )
1092     ;; (if (equal (get-char-attribute char '->titlecase)
1093     ;;            (get-char-attribute char '->uppercase))
1094     ;;     (setq attributes (delq '->titlecase attributes)))
1095     ;; (unless readable
1096     ;;   (dolist (ignored '(composition
1097     ;;                      ->denotational <-subsumptive ->ucs-unified
1098     ;;                      ->ideographic-component-forms))
1099     ;;     (setq attributes (delq ignored attributes))))
1100     (while obj-spec
1101       (setq name (car (car obj-spec)))
1102       (setq ret (chise-split-feature-name name))
1103       (setq name-base (car ret)
1104             name-domain (nth 1 ret))
1105       (when (setq value (chise-get-char-attribute-with-metadata
1106                          obj-spec name-base name-domain))
1107         (setq metadata (nth 1 value)
1108               value (car value))
1109         (cond ((setq ret (find-charset name))
1110                (setq name (charset-name ret))
1111                (when (not (memq name dest-ccss))
1112                  (setq dest-ccss (cons name dest-ccss))
1113                  (if (null value)
1114                      (insert (format "%s    :%-25s rdf:nil ;" line-separator
1115                                      (chise-turtle-uri-encode-ccs-name name)))
1116                    (setq ret (chise-turtle-format-ccs-code-point name value))
1117                    (insert (format "%s    :eq %-25s ; # %c" line-separator
1118                                    ret
1119                                    (char-db-decode-isolated-char name value)))
1120                    (setq eq-cpos-list (cons (list ret name value) eq-cpos-list))))
1121                (if (find-charset
1122                     (setq ret (if (eq name '=ucs)
1123                                   (if (< value #x10000)
1124                                       '==ucs@unicode
1125                                     '==ucs@iso)
1126                                 (intern (format "=%s" name)))))
1127                    (setq child-ccs-list (cons ret child-ccs-list)))
1128                )
1129               ((and
1130                 (not readable)
1131                 (not (eq name '->subsumptive))
1132                 (not (eq name '->uppercase))
1133                 (not (eq name '->lowercase))
1134                 (not (eq name '->titlecase))
1135                 (not (eq name '->canonical))
1136                 (not (eq name '->Bopomofo))
1137                 (not (eq name '->mistakable))
1138                 (not (eq name '->ideographic-variants))
1139                 (or (eq name '<-identical)
1140                     (eq name '<-uppercase)
1141                     (eq name '<-lowercase)
1142                     (eq name '<-titlecase)
1143                     (eq name '<-canonical)
1144                     (eq name '<-ideographic-variants)
1145                     ;; (eq name '<-synonyms)
1146                     (string-match "^<-synonyms" (symbol-name name))
1147                     (eq name '<-mistakable)
1148                     (when (string-match "^->" (symbol-name name))
1149                       (cond
1150                        ((string-match "^->fullwidth" (symbol-name name))
1151                         (not (and (consp value)
1152                                   (characterp (car value))
1153                                   (encode-char
1154                                    (car value) '=ucs 'defined-only)))
1155                         )
1156                        (t)))
1157                     ))
1158                )
1159               ((eq name 'ideographic-structure)
1160                (insert (isd-turtle-format-char nil nil value (/ column 4)
1161                                                'isd 'without-head-char))
1162                (insert " ;")
1163                )
1164               ((eq name '->subsumptive)
1165                (insert line-separator)
1166                (concord-turtle-insert-relation-feature object name value
1167                                                        line-breaking
1168                                                        ccss readable)
1169                (setq children value)
1170                )
1171               ((eq name 'character)
1172                (insert line-separator)
1173                (concord-turtle-insert-relation-feature object name value
1174                                                        line-breaking
1175                                                        ccss readable)
1176                ;; (setq children value)
1177                )
1178               (t
1179                (insert (format "%s    %-20s "
1180                                line-separator
1181                                (chise-turtle-uri-encode-feature-name name-base)))
1182                (unless (concord-turtle-insert-feature-value
1183                         value metadata name-domain name-base)
1184                  (insert " ;"))
1185                )
1186               ))
1187       (setq obj-spec (cdr obj-spec)))
1188     (insert (format "%s    ." line-breaking))
1189     (dolist (eq-cpos (nreverse eq-cpos-list))
1190       (setq ret (chise-split-ccs-name (nth 1 eq-cpos)))
1191       (insert (format "%s    %s" line-breaking
1192                       (car eq-cpos)))
1193       (insert (format "%s        %25s" line-breaking
1194                       (format ":%s-of" (nth 1 ret))))
1195       (if (null (nth 2 ret))
1196           (insert (format " %14s:%-7s ."
1197                           (chise-turtle-uri-encode-ccs-name (car ret))
1198                           (nth 1 (split-string (car eq-cpos) ":"))))
1199         (insert " [ ")
1200         (setq col (current-column))
1201         (insert (format ":context domain:%-7s ;\n%srdf:value %7s:%-7s ] ."
1202                         (chise-turtle-uri-encode-ccs-name (nth 2 ret))
1203                         (make-string col ?\ )
1204                         (chise-turtle-uri-encode-ccs-name (car ret))
1205                         (nth 1 (split-string (car eq-cpos) ":"))))))
1206     (setq est-coded-charset-priority-list
1207           (append est-coded-charset-priority-list
1208                   (nreverse child-ccs-list)))
1209     (when children
1210       (dolist (child children)
1211         (insert (format "%s    " line-breaking))
1212         (concord-turtle-insert-object-features child nil nil nil 'for-sub-node)))
1213     ))
1214
1215 (defun concord-turtle-insert-char-data (char &optional readable attributes)
1216   (save-restriction
1217     (narrow-to-region (point)(point))
1218     (concord-turtle-insert-object-features char readable attributes)
1219     (insert "\n\n")
1220     ))
1221
1222 (defun concord-turtle-insert-prefix ()
1223   (let (base-ccs-list ret)
1224     (insert "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
1225 @prefix : <http://rdf.chise.org/rdf/property/character/main/> .
1226 @prefix ideo: <http://rdf.chise.org/rdf/property/character/ideo/> .
1227 @prefix isd: <http://rdf.chise.org/rdf/property/character/isd/> .
1228 @prefix idc: <http://rdf.chise.org/rdf/type/character/idc/> .
1229 @prefix chisegg: <http://rdf.chise.org/rdf/type/character/ggg/> .
1230 @prefix domain: <http://rdf.chise.org/data/domain/> .
1231 @prefix script: <http://rdf.chise.org/data/script/> .
1232 @prefix ideocomb: <http://rdf.chise.org/data/character/ideo/combination/> .
1233 @prefix chisebib: <http://rdf.chise.org/data/bibliography/> .
1234 @prefix ruimoku: <http://www.chise.org/est/view/article@ruimoku/rep.id=/> .
1235 @prefix zob1959: <http://chise.zinbun.kyoto-u.ac.jp/koukotsu/rubbings/> .
1236
1237 ")
1238     (dolist (cell (sort chise-turtle-ccs-prefix-alist
1239                         (lambda (a b)
1240                           (char-attribute-name< (cdr a)(cdr b)))))
1241       (insert (format "@prefix %s: <%s/%s=> .\n"
1242                       (car cell)
1243                       "http://www.chise.org/est/view/character"
1244                       (www-uri-encode-feature-name (cdr cell))))
1245       (setq ret (chise-split-ccs-name (cdr cell)))
1246       (unless (memq (car ret) base-ccs-list)
1247         (setq base-ccs-list (cons (car ret) base-ccs-list))))
1248     (insert "\n")
1249     (dolist (base-ccs (nreverse base-ccs-list))
1250       (insert (format "@prefix %s: <%s/%s/code-point/> .\n"
1251                       (chise-turtle-uri-encode-ccs-name base-ccs)
1252                       "http://rdf.chise.org/data/ccs"
1253                       (www-uri-encode-feature-name base-ccs))))))
1254
1255 (defun concord-turtle-insert-ideograph-radical-char-data (radical)
1256   (let ((chars
1257          (sort (copy-list (aref ideograph-radical-chars-vector radical))
1258                (lambda (a b)
1259                  (ideograph-char< a b radical))))
1260         attributes)
1261     (dolist (name (char-attribute-list))
1262       (unless (memq name char-db-ignored-attributes)
1263         (push name attributes)
1264         ))
1265     (setq attributes (sort attributes #'char-attribute-name<))
1266     (aset ideograph-radical-chars-vector radical chars)
1267     (dolist (char chars)
1268       (when (not (some (lambda (atr)
1269                          (get-char-attribute char atr))
1270                        char-db-ignored-attributes))
1271         (concord-turtle-insert-char-data char nil attributes)))
1272     ))
1273
1274 (defun char-db-turtle-write-ideograph-radical-char-data (radical file)
1275   (if (file-directory-p file)
1276       (let ((name (char-feature (decode-char 'ucs (+ #x2EFF radical))
1277                                 'name)))
1278         (if (string-match "KANGXI RADICAL " name)
1279             (setq name (capitalize (substring name (match-end 0)))))
1280         (setq name (mapconcat (lambda (char)
1281                                 (if (eq char ? )
1282                                     "-"
1283                                   (char-to-string char))) name ""))
1284         (setq file
1285               (expand-file-name
1286                (format "Ideograph-R%03d-%s.ttl" radical name)
1287                file))))
1288   (let (chise-turtle-ccs-prefix-alist)
1289     (with-temp-buffer
1290       (concord-turtle-insert-ideograph-radical-char-data radical)
1291       (goto-char (point-min))
1292       (concord-turtle-insert-prefix)
1293       (insert "\n")
1294       (goto-char (point-min))
1295       (insert (format "# -*- coding: %s -*-\n"
1296                       char-db-file-coding-system))
1297       (let ((coding-system-for-write char-db-file-coding-system))
1298         (write-region (point-min)(point-max) file)))))
1299
1300
1301 ;;; @ end
1302 ;;;
1303
1304 (provide 'concord-turtle-dump)
1305
1306 ;;; concord-turtle-dump.el ends here