(est-coded-charset-priority-list): Add `===ucs@iso'.
[chise/est.git] / cwiki-common.el
1 ;; -*- coding: utf-8-mcs-er -*-
2 (require 'char-db-util)
3
4 (setq file-name-coding-system 'utf-8-mcs-er)
5
6
7 (concord-assign-genre 'creator@ruimoku "/usr/local/var/ruimoku/db")
8 (concord-assign-genre 'person-name@ruimoku "/usr/local/var/ruimoku/db")
9
10 (concord-assign-genre 'journal-volume@ruimoku "/usr/local/var/ruimoku/db")
11 (concord-assign-genre 'article@ruimoku "/usr/local/var/ruimoku/db")
12 (concord-assign-genre 'book@ruimoku "/usr/local/var/ruimoku/db")
13
14 (concord-assign-genre 'classification@ruimoku "/usr/local/var/ruimoku/db")
15 (concord-assign-genre 'region@ruimoku "/usr/local/var/ruimoku/db")
16 (concord-assign-genre 'era@ruimoku "/usr/local/var/ruimoku/db")
17 (concord-assign-genre 'period@ruimoku "/usr/local/var/ruimoku/db")
18 (concord-assign-genre 'journal@ruimoku "/usr/local/var/ruimoku/db")
19 (concord-assign-genre 'journal-name@ruimoku "/usr/local/var/ruimoku/db")
20 (concord-assign-genre 'publisher@ruimoku "/usr/local/var/ruimoku/db")
21 (concord-assign-genre 'publisher-name@ruimoku "/usr/local/var/ruimoku/db")
22
23 (mount-char-attribute-table '*instance@ruimoku/bibliography/title)
24 ;; (mount-char-attribute-table '*instance@ruimoku/bibliography/content*note)
25
26 (concord-assign-genre 'entry@zh-classical "/usr/local/var/kanbun/db")
27 ;; (concord-assign-genre 'morpheme-entry@zh-classical "/usr/local/var/kanbun/db")
28 (concord-assign-genre 'word-class@zh-classical "/usr/local/var/kanbun/db")
29 (concord-assign-genre 'morpheme@zh-classical "/usr/local/var/kanbun/db")
30 (concord-assign-genre 'sentence@zh-classical "/usr/local/var/kanbun/db")
31 ;; (concord-assign-genre 'sentence-entry@zh-classical "/usr/local/var/kanbun/db")
32
33 (mount-char-attribute-table '*instance@morpheme-entry/zh-classical)
34
35
36 (mount-char-attribute-table '->HNG)
37 (mount-char-attribute-table '<-HNG)
38
39
40 (defvar est-hide-cgi-mode nil)
41 (defvar est-view-url-prefix "..")
42 (defvar chise-wiki-view-url "view.cgi")
43 (defvar chise-wiki-edit-url "edit.cgi")
44
45 (defvar chise-wiki-bitmap-glyphs-url
46   "http://www.chise.org/glyphs")
47
48 (defvar chise-wiki-hng-bitmap-glyphs-url
49   "http://hng.chise.org/glyphs/HNG")
50
51 (defvar chise-wiki-glyph-cgi-url
52   "http://www.chise.org/chisewiki/glyph.cgi")
53
54 (defvar chise-wiki-displayed-features nil)
55
56 (defvar est-coded-charset-priority-list
57   '(; =ucs
58     =cns11643-1 =cns11643-2 =cns11643-3
59     =cns11643-4 =cns11643-5 =cns11643-6 =cns11643-7
60     =gb2312 =gb12345
61     =jis-x0208 =jis-x0208@1990
62     =jis-x0213-2
63     =jis-x0212
64     =adobe-japan1
65     =cbeta =jef-china3
66     =jis-x0213-1@2000 =jis-x0213-1@2004
67     =jis-x0208@1983 =jis-x0208@1978
68     =zinbun-oracle =>zinbun-oracle
69     =daikanwa
70     =gt =gt-k
71     =>>>adobe-japan1
72     =>>>jis-x0208 =>>>jis-x0213-1 =>>>jis-x0213-2
73     =>>jis-x0208 =>>jis-x0213-1 =>>jis-x0213-2
74     =>>adobe-japan1
75     =+>jis-x0208 =+>jis-x0213-1 =+>jis-x0213-2
76     =+>jis-x0208@1978
77     =+>adobe-japan1
78     =>jis-x0208 =>jis-x0213-1
79     =>>gt
80     =>ucs@iso =>ucs@unicode
81     =>ucs@jis =>ucs@cns =>ucs@ks
82     =>>ucs@iso =>>ucs@unicode
83     =>>ucs@jis =>>ucs@cns =>>ucs@ks
84     =>>>ucs@iso =>>>ucs@unicode
85     =>>>ucs@jis =>>>ucs@cns =>>>ucs@ks
86     ===ucs@iso
87     =ruimoku-v6
88     =big5
89     =big5-cdp
90     =ucs-itaiji-002))
91
92 (defun decode-uri-string (string &optional coding-system)
93   (if (> (length string) 0)
94       (let ((i 0)
95             dest)
96         (setq string
97               (mapconcat (lambda (char)
98                            (if (eq char ?+)
99                                " "
100                              (char-to-string char)))
101                          string ""))
102         (while (string-match "%\\([0-9A-F][0-9A-F]\\)" string i)
103           (setq dest (concat dest
104                              (substring string i (match-beginning 0))
105                              (char-to-string
106                               (int-char
107                                (string-to-int (match-string 1 string) 16))))
108                 i (match-end 0)))
109         (decode-coding-string
110          (concat dest (substring string i))
111          coding-system))))
112
113 (defun www-feature-type (feature-name)
114   (or (char-feature-property feature-name 'type)
115       (let ((str (symbol-name feature-name)))
116         (cond
117          ((string-match "\\*note\\(@[^*]+\\)?$" str)
118           'stext)
119          ((string-match "\\*sources\\(@[^*]+\\)?$" str)
120           'domain-list)
121          ((string-match "\\*" str)
122           nil)
123          ((string-match "^\\(->\\|<-\\)" str)
124           'relation)
125          ((string-match "^ideographic-structure\\(@\\|$\\)" str)
126           'structure)
127          ))))
128
129 (defun www-feature-format (feature-name)
130   (or (char-feature-property feature-name 'presentation-format)
131       (char-feature-property feature-name 'format)
132       (let (fn parent ret)
133         (setq fn feature-name)
134         (while (and (setq parent (char-feature-name-parent fn))
135                     (null (setq ret
136                                 (char-feature-property
137                                  parent 'format))))
138           (setq fn parent))
139         ret)
140       '((name) " : " (value))))
141
142 (defun www-feature-value-format (feature-name)
143   (or (char-feature-property feature-name 'value-presentation-format)
144       (char-feature-property feature-name 'value-format)
145       (let (fn parent ret)
146         (setq fn feature-name)
147         (while (and (setq parent (char-feature-name-parent fn))
148                     (null (setq ret
149                                 (or (char-feature-property
150                                      parent 'value-presentation-format)
151                                     (char-feature-property
152                                      parent 'value-format)))))
153           (setq fn parent))
154         ret)
155       (let ((type (www-feature-type feature-name)))
156         (cond ((eq type 'relation)
157                'space-separated)
158               ((eq type 'structure)
159                'space-separated-ids)
160               ((eq type 'stext)
161                'wiki-text)
162               ))
163       (if (find-charset feature-name)
164           (if (and (= (charset-dimension feature-name) 2)
165                    (= (charset-chars feature-name) 94))
166               '("0x" (HEX)
167                 " (" (decimal) ") <" (ku-ten) "> " (prev-char) (next-char))
168             '("0x" (HEX) " (" (decimal) ") " (prev-char) (next-char))))
169       'space-separated))
170
171 (defun char-feature-name-at-domain (feature-name domain)
172   (if domain
173       (let ((name (symbol-name feature-name)))
174         (cond
175          ((string-match "@[^*]+$" name)
176           (intern (format "%s/%s" name domain))
177           )
178          (t
179           (intern (format "%s@%s" name domain))
180           )))
181     feature-name))
182
183 (defun char-feature-name-parent (feature-name)
184   (let ((name (symbol-name feature-name)))
185     (if (string-match "@[^@/*]+\\(/[^@/*]+\\)*$" name)
186         (intern (substring name 0 (car (last (match-data) 2)))))))
187
188 (defun char-feature-name-domain (feature-name)
189   (let ((name (symbol-name feature-name)))
190     (if (string-match "@[^@/*]+\\(/[^@/*]+\\)*$" name)
191         (intern (substring name (1+ (match-beginning 0)))))))
192
193 (defun char-feature-name-sans-versions (feature)
194   (let ((feature-name (symbol-name feature)))
195     (if (string-match "[@/]\\$rev=latest$" feature-name)
196         (intern (substring feature-name 0 (match-beginning 0)))
197       feature)))
198
199 (defun est-object-genre (object)
200   (if (characterp object)
201       'character
202     (concord-object-genre object)))
203
204 (defun www-get-feature-value (object feature)
205   (let ((latest-feature (char-feature-name-at-domain feature '$rev=latest)))
206     (cond
207      ((characterp object)
208       (mount-char-attribute-table latest-feature)
209       (or (char-feature object latest-feature)
210           (char-feature object feature))
211       )
212      (t
213       (or (condition-case nil
214               (concord-object-get object latest-feature)
215             (error nil))
216           (condition-case nil
217               (concord-object-get object feature)
218             (error nil)))
219       ))))
220
221 (defun get-previous-code-point (ccs code)
222   (let ((chars (charset-chars ccs))
223         (dim (charset-dimension ccs))
224         (i 0)
225         mask byte-min byte-max
226         bytes dest)
227     (cond
228      ((= chars 94)
229       (setq mask #x7F
230             byte-min 33
231             byte-max 126)
232       )
233      ((= chars 96)
234       (setq mask #x7F
235             byte-min 32
236             byte-max 127)
237       )
238      ((= chars 128)
239       (setq mask #x7F
240             byte-min 0
241             byte-max #xFF)
242       )
243      (t ; (= chars 256)
244       (setq mask #xFF
245             byte-min 0
246             byte-max #xFF)
247       ))
248     (setq bytes (make-vector dim 0))
249     (while (< i dim)
250       (aset bytes i (logand (lsh code (* i -8)) mask))
251       (setq i (1+ i)))
252     (setq i 0)
253     (while (and (< i dim)
254                 (progn
255                   (aset bytes i (1- (aref bytes i)))
256                   (< (aref bytes i) byte-min)))
257       (aset bytes i byte-max)
258       (setq i (1+ i)))
259     (when (< i dim)
260       (setq dest (aref bytes 0)
261             i 1)
262       (while (< i dim)
263         (setq dest (logior dest (lsh (aref bytes i) (* i 8)))
264               i (1+ i)))
265       dest)))
266
267 (defun get-next-code-point (ccs code)
268   (let ((chars (charset-chars ccs))
269         (dim (charset-dimension ccs))
270         (i 0)
271         mask byte-min byte-max
272         bytes dest)
273     (cond
274      ((= chars 94)
275       (setq mask #x7F
276             byte-min 33
277             byte-max 126)
278       )
279      ((= chars 96)
280       (setq mask #x7F
281             byte-min 32
282             byte-max 127)
283       )
284      ((= chars 128)
285       (setq mask #x7F
286             byte-min 0
287             byte-max #xFF)
288       )
289      (t ; (= chars 256)
290       (setq mask #xFF
291             byte-min 0
292             byte-max #xFF)
293       ))
294     (setq bytes (make-vector dim 0))
295     (while (< i dim)
296       (aset bytes i (logand (lsh code (* i -8)) mask))
297       (setq i (1+ i)))
298     (setq i 0)
299     (while (and (< i dim)
300                 (progn
301                   (aset bytes i (1+ (aref bytes i)))
302                   (> (aref bytes i) byte-max)))
303       (aset bytes i byte-min)
304       (setq i (1+ i)))
305     (when (< i dim)
306       (setq dest (aref bytes 0)
307             i 1)
308       (while (< i dim)
309         (setq dest (logior dest (lsh (aref bytes i) (* i 8)))
310               i (1+ i)))
311       dest)))
312
313 (defun find-previous-defined-code-point (ccs code)
314   (let ((i (get-previous-code-point ccs code))
315         char)
316     (cond
317      ((eq ccs '=jis-x0208)
318       (setq ccs '=jis-x0208@1990))
319      ((eq ccs '=jis-x0213-1)
320       (setq ccs '=jis-x0213-1@2004)))
321     (while (and i
322                 (>= i 0)
323                 (null (setq char (decode-char ccs i
324                                               (unless (eq ccs '=ucs)
325                                                 'defined-only)))))
326       (setq i (get-previous-code-point ccs i)))
327     char))
328
329 (defun find-next-defined-code-point (ccs code)
330   (let ((i (get-next-code-point ccs code))
331         max char)
332     (setq max (+ code 1000))
333     (cond
334      ((eq ccs '=jis-x0208)
335       (setq ccs '=jis-x0208@1990))
336      ((eq ccs '=jis-x0213-1)
337       (setq ccs '=jis-x0213-1@2004)))
338     (while (and i
339                 (<= i max)
340                 (null (setq char (decode-char ccs i
341                                               (unless (eq ccs '=ucs)
342                                                 'defined-only)))))
343       (setq i (get-next-code-point ccs i)))
344     char))
345
346
347 ;;; @ URI representation
348 ;;;
349
350 (defun est-uri-decode-feature-name-body (uri-feature)
351   (let ((len (length uri-feature))
352         (i 0)
353         ch dest)
354     (while (< i len)
355       (setq dest
356             (concat
357              dest
358              (if (eq (aref uri-feature i) ?\.)
359                  (if (and (< (+ i 2) len)
360                           (eq (aref uri-feature (+ i 2)) ?\.))
361                      (prog1
362                          (cond
363                           ((eq (setq ch (aref uri-feature (1+ i))) ?\.)
364                            "/")
365                           ((eq ch ?-)
366                            "*")
367                           (t
368                            (substring uri-feature i (+ i 3))
369                            ))
370                        (setq i (+ i 3)))
371                    (setq i (1+ i))
372                    ".")
373                (prog1
374                    (char-to-string (aref uri-feature i))
375                  (setq i (1+ i)))))))
376     dest))
377
378 (defun est-uri-encode-feature-name-body (feature)
379   (mapconcat (lambda (c)
380                (cond ((eq c ?*)
381                       ".-.")
382                      ((eq c ?/)
383                       "...")
384                      (t (char-to-string c))))
385              feature ""))
386
387 (defun www-uri-decode-feature-name (uri-feature)
388   (let (feature)
389     (setq uri-feature (decode-uri-string uri-feature 'utf-8-mcs-er))
390     (cond
391      ((string-match "^from\\." uri-feature)
392       (intern (format "<-%s"
393                       (est-uri-decode-feature-name-body
394                        (substring uri-feature (match-end 0)))))
395       )
396      ((string-match "^to\\." uri-feature)
397       (intern (format "->%s"
398                       (est-uri-decode-feature-name-body
399                        (substring uri-feature (match-end 0)))))
400       )
401      ((string-match "^rep\\." uri-feature)
402       (intern (format "=%s"
403                       (est-uri-decode-feature-name-body
404                        (substring uri-feature (match-end 0)))))
405       )
406      ((string-match "^rep[2i]\\." uri-feature)
407       (intern (format "===%s"
408                       (est-uri-decode-feature-name-body
409                        (substring uri-feature (match-end 0)))))
410       )
411      ((string-match "^g\\." uri-feature)
412       (intern (format "=>>%s"
413                       (est-uri-decode-feature-name-body
414                        (substring uri-feature (match-end 0)))))
415       )
416      ((string-match "^g[i2]\\." uri-feature)
417       (intern (format "==%s"
418                       (est-uri-decode-feature-name-body
419                        (substring uri-feature (match-end 0)))))
420       )
421      ((string-match "^gi\\([0-9]+\\)\\." uri-feature)
422       (intern (format "=>>%s%s"
423                       (make-string (string-to-int
424                                     (match-string 1 uri-feature))
425                                    ?>)
426                       (est-uri-decode-feature-name-body
427                        (substring uri-feature (match-end 0)))))
428       )
429      ((string-match "^o\\." uri-feature)
430       (intern (format "=+>%s"
431                       (est-uri-decode-feature-name-body
432                        (substring uri-feature (match-end 0)))))
433       )
434      ((string-match "^a\\." uri-feature)
435       (intern (format "=>%s"
436                       (est-uri-decode-feature-name-body
437                        (substring uri-feature (match-end 0)))))
438       )
439      ((string-match "^a\\([0-9]+\\)\\." uri-feature)
440       (intern (format "%s>%s"
441                       (make-string (string-to-int
442                                     (match-string 1 uri-feature))
443                                    ?=)
444                       (est-uri-decode-feature-name-body
445                        (substring uri-feature (match-end 0)))))
446       )
447      ((and (setq uri-feature (est-uri-decode-feature-name-body uri-feature))
448            (setq feature (intern (format "=>%s" uri-feature)))
449            (find-charset feature))
450       feature)
451      ((and (setq feature (intern (format "=>>%s" uri-feature)))
452            (find-charset feature))
453       feature)
454      ((and (setq feature (intern (format "=>>>%s" uri-feature)))
455            (find-charset feature))
456       feature)
457      ((and (setq feature (intern (format "=%s" uri-feature)))
458            (find-charset feature))
459       feature)
460      (t (intern uri-feature)))))
461
462 (defun www-uri-encode-feature-name (feature-name)
463   (setq feature-name (symbol-name feature-name))
464   (cond
465    ((string-match "^=\\+>\\([^=>]+\\)" feature-name)
466     (concat "o."
467             (est-uri-encode-feature-name-body
468              (substring feature-name (match-beginning 1))))
469     )
470    ((string-match "^=\\([^=>]+\\)" feature-name)
471     (concat "rep."
472             (est-uri-encode-feature-name-body
473              (substring feature-name (match-beginning 1))))
474     )
475    ((string-match "^==\\([^=>]+\\)" feature-name)
476     (concat "g2."
477             (est-uri-encode-feature-name-body
478              (substring feature-name (match-beginning 1))))
479     )
480    ((string-match "^===\\([^=>]+\\)" feature-name)
481     (concat "repi."
482             (est-uri-encode-feature-name-body
483              (substring feature-name (match-beginning 1))))
484     )
485    ((string-match "^=>>\\([^=>]+\\)" feature-name)
486     (concat "g."
487             (est-uri-encode-feature-name-body
488              (substring feature-name (match-beginning 1))))
489     )
490    ((string-match "^=>>>\\([^=>]+\\)" feature-name)
491     (concat "gi."
492             (est-uri-encode-feature-name-body
493              (substring feature-name (match-beginning 1))))
494     )
495    ((string-match "^=>>\\(>+\\)" feature-name)
496     (format "gi%d.%s"
497             (length (match-string 1 feature-name))
498             (est-uri-encode-feature-name-body
499              (substring feature-name (match-end 1))))
500     )
501    ((string-match "^=>\\([^=>]+\\)" feature-name)
502     (concat "a."
503             (est-uri-encode-feature-name-body
504              (substring feature-name (match-beginning 1))))
505     )
506    ((string-match "^\\(=+\\)>" feature-name)
507     (format "a%d.%s"
508             (length (match-string 1 feature-name))
509             (est-uri-encode-feature-name-body
510              (substring feature-name (match-end 0))))
511     )
512    ((string-match "^->" feature-name)
513     (concat "to."
514             (est-uri-encode-feature-name-body
515              (substring feature-name (match-end 0))))
516     )
517    ((string-match "^<-" feature-name)
518     (concat "from."
519             (est-uri-encode-feature-name-body
520              (substring feature-name (match-end 0))))
521     )
522    (t (est-uri-encode-feature-name-body feature-name))))
523
524 (defun www-uri-make-feature-name-url (uri-genre uri-feature-name uri-object)
525   (if est-hide-cgi-mode
526       (format "../feature/%s&%s/%s"
527               uri-feature-name uri-genre uri-object)
528     (format "%s?feature=%s&%s=%s"
529             chise-wiki-view-url uri-feature-name uri-genre uri-object)))
530
531 (defun www-uri-decode-object (genre char-rep)
532   (let (ccs cpos)
533     (cond
534      ((string-match (if est-hide-cgi-mode
535                         "\\(%3D\\|=\\|%3A\\|:\\)"
536                       "\\(%3A\\|:\\)") char-rep)
537       (setq ccs (substring char-rep 0 (match-beginning 0))
538             cpos (substring char-rep (match-end 0)))
539       (setq ccs (www-uri-decode-feature-name ccs))
540       (setq cpos (est-uri-decode-feature-name-body cpos))
541       (cond
542        ((string-match "^0x" cpos)
543         (setq cpos
544               (string-to-number (substring cpos (match-end 0)) 16))
545         )
546        (t
547         (setq cpos (car (read-from-string
548                          (decode-uri-string
549                           cpos file-name-coding-system))))
550         ))
551       (if (and (eq genre 'character)
552                (numberp cpos))
553           (decode-char ccs cpos)
554         (concord-decode-object ccs cpos genre))
555       )
556      (t
557       (setq char-rep (decode-uri-string char-rep 'utf-8-mcs-er))
558       (cond
559        ((eq genre 'character)
560         (when (= (length char-rep) 1)
561           (aref char-rep 0))
562         )
563        ((eq genre 'feature)
564         (concord-decode-object
565          '=id (www-uri-decode-feature-name char-rep) 'feature)
566         )
567        (t
568         (concord-decode-object
569          '=id (car (read-from-string char-rep)) genre)
570         ))))))
571
572 (defun www-uri-encode-object (object)
573   (if (characterp object)
574       (if (encode-char object '=ucs)
575           (mapconcat
576            (lambda (byte)
577              (format "%%%02X" byte))
578            (encode-coding-string (char-to-string object) 'utf-8-mcs-er)
579            "")
580         (let ((ccs-list est-coded-charset-priority-list)
581               ccs ret)
582           (while (and ccs-list
583                       (setq ccs (pop ccs-list))
584                       (not (setq ret (encode-char object ccs 'defined-only)))))
585           (cond (ret
586                  (format (if est-hide-cgi-mode
587                              "%s=0x%X"
588                            "%s:0x%X")
589                          (www-uri-encode-feature-name ccs)
590                          ret))
591                 ((and (setq ccs (car (split-char object)))
592                       (setq ret (encode-char object ccs)))
593                  (format (if est-hide-cgi-mode
594                              "%s=0x%X"
595                            "%s:0x%X")
596                          (www-uri-encode-feature-name ccs)
597                          ret))
598                 (t
599                  (format (if est-hide-cgi-mode
600                              "system-char-id=0x%X"
601                            "system-char-id:0x%X")
602                          (encode-char object 'system-char-id))
603                  ))))
604     (format (if est-hide-cgi-mode
605                 "rep.id=%s"
606               "rep.id:%s")
607             (est-uri-encode-feature-name-body
608              (format "%s" (concord-object-id object))))))
609
610 (defun est-format-object (object &optional readable)
611   (if (characterp object)
612       (char-to-string object)
613     (let ((ret (or (if readable
614                        (or (concord-object-get object 'name)
615                            (concord-object-get object '=name)
616                            (concord-object-get object 'title)))
617                    (concord-object-id object))))
618       (format "%s" ret))))
619
620 (defun www-uri-make-object-url (object &optional uri-object)
621   (if est-hide-cgi-mode
622       (format "%s/%s/%s"
623               est-view-url-prefix
624               (est-object-genre object)
625               (or uri-object
626                   (www-uri-encode-object object)))
627     (format "%s?%s=%s"
628             chise-wiki-view-url
629             (est-object-genre object)
630             (or uri-object
631                 (www-uri-encode-object object)))))
632
633
634 ;;; @ Feature name presentation
635 ;;;
636
637 (defun www-format-feature-name-default (feature-name)
638   (mapconcat
639    #'capitalize
640    (split-string
641     (symbol-name feature-name)
642     "-")
643    " "))
644
645 (defun www-format-feature-name-as-metadata (feature-name &optional lang)
646   (let ((str (symbol-name feature-name))
647         base meta)
648     (cond
649      ((string-match "\\*[^*]+$" str)
650       (setq base (substring str 0 (match-beginning 0))
651             meta (substring str (match-beginning 0)))
652       (concat (www-format-feature-name* (intern base) lang)
653               meta))
654      (t
655       (www-format-feature-name-default feature-name)
656       ))))
657
658 (defun www-format-feature-name-as-rel-to (feature-name)
659   (concat "\u2192" (substring (symbol-name feature-name) 2)))
660
661 (defun www-format-feature-name-as-rel-from (feature-name)
662   (concat "\u2190" (substring (symbol-name feature-name) 2)))
663
664 (defun www-format-feature-name-as-CCS (feature-name)
665   (let* ((rest
666           (split-string
667            (symbol-name feature-name)
668            "-"))
669          (dest (upcase (pop rest))))
670     (when (string-match "^=+>*" dest)
671       (setq dest (concat (substring dest 0 (match-end 0))
672                          " "
673                          (substring dest (match-end 0)))))
674     (cond
675      (rest
676       (while (cdr rest)
677         (setq dest (concat dest " " (upcase (pop rest)))))
678       (if (string-match "^[0-9]+$" (car rest))
679           (concat dest "-" (car rest))
680         (concat dest " " (upcase (car rest))))
681       )
682      (t dest))))
683
684 (defun www-format-feature-name* (feature-name &optional lang)
685   (let (name fn parent ret)
686     (cond
687      ((or (and lang
688                (char-feature-property
689                 feature-name
690                 (intern (format "name@%s" lang))))
691           (char-feature-property
692            feature-name 'name)))
693      ((and (setq name (symbol-name feature-name))
694            (string-match "\\*" name))
695       (www-format-feature-name-as-metadata feature-name lang))
696      (t
697       (setq fn feature-name)
698       (while (and (setq parent (char-feature-name-parent fn))
699                   (null (setq ret
700                               (or (and lang
701                                        (char-feature-property
702                                         parent
703                                         (intern (format "name@%s" lang))))
704                                   (char-feature-property
705                                    parent 'name)))))
706         (setq fn parent))
707       (cond
708        (ret
709         (concat ret (substring (symbol-name feature-name)
710                                (length (symbol-name parent)))))
711        ((find-charset feature-name)
712         (www-format-feature-name-as-CCS feature-name))
713        ((string-match "^\\(->\\)" name)
714         (www-format-feature-name-as-rel-to feature-name))
715        ((string-match "^\\(<-\\)" name)
716         (www-format-feature-name-as-rel-from feature-name))
717        (t
718         (www-format-feature-name-default feature-name)
719         ))
720       ))))
721
722 (defun www-format-feature-name (feature-name &optional lang)
723   (www-format-encode-string
724    (www-format-feature-name* feature-name lang)))
725
726
727 ;;; @ HTML generator
728 ;;;
729
730 (defvar www-format-char-img-style "vertical-align:bottom;")
731
732 (defun www-format-encode-string (string &optional without-tags as-body)
733   (with-temp-buffer
734     (insert string)
735     (let (plane code subcode start end char variants ret rret)
736       (when as-body
737         (goto-char (point-min))
738         (while (search-forward "&" nil t)
739           (replace-match "&amp;" nil t)))
740       (goto-char (point-min))
741       (while (search-forward "<" nil t)
742         (replace-match "&lt;" nil t))
743       (goto-char (point-min))
744       (while (search-forward ">" nil t)
745         (replace-match "&gt;" nil t))
746       (if without-tags
747           (encode-coding-region (point-min)(point-max) 'utf-8-mcs-er)
748         (let ((coded-charset-entity-reference-alist
749                (list*
750                 '(=gt                   "GT-" 5 d)
751                 '(=hanyo-denshi/ja   "HD-JA-" 4 X)
752                 '(=hanyo-denshi/jb   "HD-JB-" 4 X)
753                 '(=hanyo-denshi/jc   "HD-JC-" 4 X)
754                 '(=hanyo-denshi/jd   "HD-JD-" 4 X)
755                 '(=hanyo-denshi/ft   "HD-FT-" 4 X)
756                 '(=hanyo-denshi/ia   "HD-IA-" 4 X)
757                 '(=hanyo-denshi/ib   "HD-IB-" 4 X)
758                 '(=hanyo-denshi/hg   "HD-HG-" 4 X)
759                 '(=hanyo-denshi/ip   "HD-IP-" 4 X)
760                 '(=hanyo-denshi/jt   "HD-JT-" 4 X)
761                 '(=hanyo-denshi/ks   "HD-KS-" 6 d)
762                 '(=>>hanyo-denshi/ja "G-HD-JA-" 4 X)
763                 '(=>>hanyo-denshi/jb "G-HD-JB-" 4 X)
764                 '(=>>hanyo-denshi/jc "G-HD-JC-" 4 X)
765                 '(=>>hanyo-denshi/jd "G-HD-JD-" 4 X)
766                 '(=>>hanyo-denshi/ft "G-HD-FT-" 4 X)
767                 '(=>>hanyo-denshi/ia "G-HD-IA-" 4 X)
768                 '(=>>hanyo-denshi/ib "G-HD-IB-" 4 X)
769                 '(=>>hanyo-denshi/hg "G-HD-HG-" 4 X)
770                 '(=>>hanyo-denshi/ip "G-HD-IP-" 4 X)
771                 '(=>>hanyo-denshi/jt "G-HD-JT-" 4 X)
772                 '(=>>hanyo-denshi/ks "G-HD-KS-" 6 d)
773                 '(==hanyo-denshi/ja "g2-HD-JA-" 4 X)
774                 '(==hanyo-denshi/jb "g2-HD-JB-" 4 X)
775                 '(==hanyo-denshi/jc "g2-HD-JC-" 4 X)
776                 '(==hanyo-denshi/jd "g2-HD-JD-" 4 X)
777                 '(==hanyo-denshi/ft "g2-HD-FT-" 4 X)
778                 '(==hanyo-denshi/ia "g2-HD-IA-" 4 X)
779                 '(==hanyo-denshi/ib "g2-HD-IB-" 4 X)
780                 '(==hanyo-denshi/hg "g2-HD-HG-" 4 X)
781                 '(==hanyo-denshi/ip "g2-HD-IP-" 4 X)
782                 '(==hanyo-denshi/jt "g2-HD-JT-" 4 X)
783                 '(==hanyo-denshi/ks "g2-HD-KS-" 6 d)
784                 '(=cns11643-1           "C1-" 4 X)
785                 '(=cns11643-2           "C2-" 4 X)
786                 '(=cns11643-3           "C3-" 4 X)
787                 '(=cns11643-4           "C4-" 4 X)
788                 '(=cns11643-5           "C5-" 4 X)
789                 '(=cns11643-6           "C6-" 4 X)
790                 '(=cns11643-7           "C7-" 4 X)
791                 '(=adobe-japan1-6       "AJ1-" 5 d)
792                 '(=big5-cdp             "CDP-" 4 X)
793                 '(=gb2312               "G0-" 4 X)
794                 '(=gb12345              "G1-" 4 X)
795                 '(=jis-x0208@1990       "J90-" 4 X)
796                 '(=jis-x0212            "JSP-" 4 X)
797                 '(=cbeta                "CB" 5 d)
798                 '(=jis-x0208@1997       "J97-" 4 X)
799                 '(=jis-x0208@1978       "J78-" 4 X)
800                 '(=jis-x0208@1983       "J83-" 4 X)
801                 '(=ruimoku-v6           "RUI6-" 4 X)
802                 '(=zinbun-oracle        "ZOB-" 4 d)
803                 '(=jef-china3           "JC3-" 4 X)
804                 '(=ucs@unicode          "UU+" 4 X)
805                 '(=ucs@JP/hanazono  "hanaJU+" 4 X)
806                 '(=daikanwa              "M-" 5 d)
807                 '(==cns11643-1        "R-C1-" 4 X)
808                 '(==cns11643-2        "R-C2-" 4 X)
809                 '(==cns11643-3        "R-C3-" 4 X)
810                 '(==cns11643-4        "R-C4-" 4 X)
811                 '(==cns11643-5        "R-C5-" 4 X)
812                 '(==cns11643-6        "R-C6-" 4 X)
813                 '(==cns11643-7        "R-C7-" 4 X)
814                 coded-charset-entity-reference-alist)))
815           (encode-coding-region (point-min)(point-max) 'utf-8-mcs-er)
816
817           (goto-char (point-min))
818           (while (re-search-forward "&CB\\([0-9]+\\);" nil t)
819             (setq code (string-to-int (match-string 1)))
820             (replace-match
821              (format "<img alt=\"CB%05d\" src=\"%s/cb-gaiji/%02d/CB%05d.gif\"
822 style=\"%s\">"
823                      code
824                      chise-wiki-bitmap-glyphs-url
825                      (/ code 1000) code
826                      www-format-char-img-style)
827              t 'literal))
828
829           (goto-char (point-min))
830           (while (re-search-forward "&\\(o-\\|G-\\|g2-\\|R-\\)?J\\(78\\|83\\|90\\|97\\|SP\\)-\\([0-9A-F][0-9A-F][0-9A-F][0-9A-F]\\);" nil t)
831             (setq plane (match-string 2)
832                   code (string-to-int (match-string 3) 16))
833             (replace-match
834              (format "<img alt=\"J%s-%04X\" src=\"%s/JIS-%s/%02d-%02d.gif\"
835 style=\"%s\">"
836                      plane code
837                      chise-wiki-bitmap-glyphs-url
838                      plane
839                      (- (lsh code -8) 32)
840                      (- (logand code 255) 32)
841                      www-format-char-img-style)
842              t 'literal))
843
844           (goto-char (point-min))
845           (while (re-search-forward "&\\(o-\\|G-\\|g2-\\|R-\\)?J0-\\([0-9A-F][0-9A-F][0-9A-F][0-9A-F]\\);" nil t)
846             (setq code (string-to-int (match-string 2) 16))
847             (replace-match
848              (format "<img alt=\"J0-%04X\" src=\"%s/JIS-90/%02d-%02d.gif\"
849 style=\"%s\">"
850                      code
851                      chise-wiki-bitmap-glyphs-url
852                      (- (lsh code -8) 32)
853                      (- (logand code 255) 32)
854                      www-format-char-img-style)
855              t 'literal))
856
857           (goto-char (point-min))
858           (while (re-search-forward "&\\(o-\\|G-\\|g2-\\|R-\\)?HD-\\(JA\\|JB\\|JC\\|JD\\|FT\\|IA\\|IB\\|HG\\)-\\([0-9A-F][0-9A-F][0-9A-F][0-9A-F]\\);" nil t)
859             (setq plane (match-string 2)
860                   code (string-to-int (match-string 3) 16))
861             (replace-match
862              (format "<img alt=\"HD-%s-%04X\" src=\"%s/IVD/HanyoDenshi/%s%02d%02d.png\"
863 style=\"%s\">"
864                      plane code
865                      chise-wiki-bitmap-glyphs-url
866                      plane
867                      (- (lsh code -8) 32)
868                      (- (logand code 255) 32)
869                      www-format-char-img-style)
870              t 'literal))
871
872           (goto-char (point-min))
873           (while (re-search-forward "&\\(o-\\|G-\\|g2-\\|R-\\)?HD-\\(IP\\|JT\\)-\\([0-9A-F][0-9A-F][0-9A-F][0-9A-F]\\);" nil t)
874             (setq plane (match-string 2)
875                   code (string-to-int (match-string 3) 16))
876             (replace-match
877              (format "<img alt=\"HD-%s-%04X\" src=\"%s/IVD/HanyoDenshi/%s%04X.png\"
878 style=\"%s\">"
879                      plane code
880                      chise-wiki-bitmap-glyphs-url
881                      plane code
882                      www-format-char-img-style)
883              t 'literal))
884
885           (goto-char (point-min))
886           (while (re-search-forward "&\\(o-\\|G-\\|g2-\\|R-\\)?HD-KS-\\([0-9]+\\);" nil t)
887             (setq code (string-to-int (match-string 2)))
888             (replace-match
889              (format "<img alt=\"HD-KS%06d\" src=\"%s/IVD/HanyoDenshi/KS%06d.png\"
890 style=\"vertical-align:middle\">"
891                      code
892                      chise-wiki-bitmap-glyphs-url
893                      code
894                      www-format-char-img-style)
895              t 'literal))
896
897           (goto-char (point-min))
898           (while (re-search-forward "&G\\([01]\\)-\\([0-9A-F][0-9A-F][0-9A-F][0-9A-F]\\);" nil t)
899             (setq plane (string-to-int (match-string 1))
900                   code (string-to-int (match-string 2) 16))
901             (replace-match
902              (format "<img alt=\"GB%d-%04X\" src=\"%s/GB%d/%02d-%02d.gif\"
903 style=\"%s\">"
904                      plane code
905                      chise-wiki-bitmap-glyphs-url
906                      plane
907                      (- (lsh code -8) 32)
908                      (- (logand code 255) 32)
909                      www-format-char-img-style)
910              t 'literal))
911
912           (goto-char (point-min))
913           (while (re-search-forward "&\\(R-\\)?C\\([1-7]\\)-\\([0-9A-F][0-9A-F][0-9A-F][0-9A-F]\\);" nil t)
914             (setq plane (string-to-int (match-string 2))
915                   code (string-to-int (match-string 3) 16))
916             (replace-match
917              (format "<img alt=\"CNS%d-%04X\" src=\"%s/CNS%d/%04X.gif\"
918 style=\"%s\">"
919                      plane code
920                      chise-wiki-bitmap-glyphs-url
921                      plane code
922                      www-format-char-img-style)
923              t 'literal))
924
925           (goto-char (point-min))
926           (while (re-search-forward "&\\(R-\\)?JC3-\\([0-9A-F][0-9A-F][0-9A-F][0-9A-F]\\);" nil t)
927             (setq code (string-to-int (match-string 2) 16))
928             (replace-match
929              (format "<img alt=\"JC3-%04X\" src=\"http://kanji.zinbun.kyoto-u.ac.jp/db/CHINA3/Gaiji/%04x.gif\">"
930                      code code)
931              t 'literal))
932
933           (goto-char (point-min))
934           (while (re-search-forward "&\\(A-\\)?ZOB-\\([0-9]+\\);" nil t)
935             (setq code (string-to-int (match-string 2)))
936             (replace-match
937              (format "<img alt=\"ZOB-%04d\" src=\"%s/ZOB-1968/%04d.png\"
938 style=\"vertical-align:middle\">"
939                      code
940                      chise-wiki-bitmap-glyphs-url
941                      code
942                      www-format-char-img-style)
943              t 'literal))
944
945           (goto-char (point-min))
946           (while (re-search-forward "&HNG\\([0-9]+\\)-\\([0-9][0-9][0-9][0-9]\\)\\([0-9]\\);" nil t)
947             (setq plane (match-string 1)
948                   code (string-to-int (match-string 2))
949                   subcode (string-to-int (match-string 3)))
950             (setq subcode
951                   (if (eq subcode 0)
952                       ""
953                     (char-to-string (decode-char 'ascii (+ 96 subcode)))))
954             (replace-match
955              (format
956               "<img alt=\"HNG%s-%04d%s\" src=\"%s/%s/%04d%s.png\"
957 style=\"vertical-align:middle; width: 48px; height: 48px\">"
958               plane code subcode
959               chise-wiki-hng-bitmap-glyphs-url
960               plane code subcode
961               www-format-char-img-style)
962              t 'literal))
963
964           (goto-char (point-min))
965           (while (re-search-forward "&\\(o-\\|G-\\|g2-\\|R-\\)?AJ1-\\([0-9]+\\);" nil t)
966             (setq code (string-to-int (match-string 2)))
967             (replace-match
968              (format "<img alt=\"AJ1-%05d\" src=\"%s/IVD/AdobeJapan1/CID+%d.png\"
969 style=\"vertical-align:middle\">"
970                      code
971                      chise-wiki-bitmap-glyphs-url
972                      code
973                      www-format-char-img-style)
974              t 'literal))
975
976           (goto-char (point-min))
977           (while (re-search-forward "&\\(o-\\|G-\\|g2-\\|R-\\)?MJ\\([0-9]+\\);" nil t)
978             (setq code (string-to-int (match-string 2)))
979             (replace-match
980              (format "<img alt=\"MJ%06d\" src=\"http://mojikiban.ipa.go.jp/search/MJ%06d\"
981 style=\"vertical-align:middle; width: 48px; height: 48px\">"
982                      code
983                      code
984                      www-format-char-img-style)
985              t 'literal))
986
987           (goto-char (point-min))
988           (while (re-search-forward "&\\(o-\\|G-\\|g2-\\)?IU-\\([0-9A-F]+\\);" nil t)
989             (setq code (string-to-int (match-string 2) 16))
990             (replace-match
991              (format "<img alt=\"u%04x\" src=\"http://glyphwiki.org/glyph/u%04x.100px.png\"
992 style=\"vertical-align:middle; width: 48px; height: 48px\">"
993                      code
994                      code
995                      www-format-char-img-style)
996              t 'literal))
997
998           (goto-char (point-min))
999           (while (re-search-forward "&\\(o-\\|G-\\|g2-\\|R-\\)?U-i\\([0-9]+\\)\\+\\([0-9A-F]+\\);" nil t)
1000             (setq plane (string-to-int (match-string 2))
1001                   code (string-to-int (match-string 3) 16))
1002             (replace-match
1003              (format "<img alt=\"u%04x-itaiji-%03d\" src=\"http://glyphwiki.org/glyph/u%04x-itaiji-%03d.100px.png\"
1004 style=\"vertical-align:middle; width: 48px; height: 48px\">"
1005                      code
1006                      plane
1007                      code
1008                      plane
1009                      www-format-char-img-style)
1010              t 'literal))
1011
1012           (goto-char (point-min))
1013           (while (re-search-forward "&\\(G-\\|R-\\|g2-\\)?GT-\\([0-9]+\\);" nil t)
1014             (setq code (string-to-int (match-string 2)))
1015             (replace-match
1016              (format "<img alt=\"GT-%05d\" src=\"%s?char=GT-%05d\"
1017 style=\"%s\">"
1018                      code
1019                      chise-wiki-glyph-cgi-url
1020                      code
1021                      www-format-char-img-style)
1022              t 'literal))
1023
1024           (goto-char (point-min))
1025           (while (re-search-forward "&\\(G-\\)?GT-K\\([0-9]+\\);" nil t)
1026             (setq code (string-to-int (match-string 2)))
1027             (replace-match
1028              (format "<img alt=\"GT-K%05d\" src=\"%s?char=GT-K%05d\"
1029 style=\"%s\">"
1030                      code
1031                      chise-wiki-glyph-cgi-url
1032                      code
1033                      www-format-char-img-style)
1034              t 'literal))
1035
1036           (goto-char (point-min))
1037           (while (re-search-forward "&B-\\([0-9A-F]+\\);" nil t)
1038             (setq code (string-to-int (match-string 1) 16))
1039             (replace-match
1040              (format "<img alt=\"B-%04X\" src=\"%s?char=B-%04X\"
1041 style=\"%s\">"
1042                      code
1043                      chise-wiki-glyph-cgi-url
1044                      code
1045                      www-format-char-img-style)
1046              t 'literal))
1047
1048           (goto-char (point-min))
1049           (while (re-search-forward "&\\(G-\\|g2-\\|R-\\)?CDP-\\([0-9A-F]+\\);" nil t)
1050             (setq code (string-to-int (match-string 2) 16))
1051             (replace-match
1052              (format "<img alt=\"CDP-%04X\" src=\"%s?char=CDP-%04X\"
1053 style=\"%s\">"
1054                      code
1055                      chise-wiki-glyph-cgi-url
1056                      code
1057                      www-format-char-img-style)
1058              t 'literal))
1059
1060           (goto-char (point-min))
1061           (while (re-search-forward "&RUI6-\\([0-9A-F]+\\);" nil t)
1062             (setq code (string-to-int (match-string 1) 16))
1063             (replace-match
1064              (format "<img alt=\"RUI6-%04X\" src=\"%s?char=RUI6-%04X\"
1065 style=\"vertical-align:middle\">"
1066                      code
1067                      chise-wiki-glyph-cgi-url
1068                      code
1069                      www-format-char-img-style)
1070              t 'literal))
1071
1072           (goto-char (point-min))
1073           (while (re-search-forward "&hanaJU\\+\\([0-9A-F]+\\);" nil t)
1074             (setq code (string-to-int (match-string 1) 16))
1075             (replace-match
1076              (format "<img alt=\"hanaJU+%04X\" src=\"%s?char=hana-JU+%04X\"
1077 style=\"vertical-align:middle\">"
1078                      code
1079                      chise-wiki-glyph-cgi-url
1080                      code
1081                      www-format-char-img-style)
1082              t 'literal))
1083
1084           (goto-char (point-min))
1085           (while (re-search-forward "&\\(A-\\|G-\\|g2-\\|R-\\)?\\(UU\\+\\|U-\\)\\([0-9A-F]+\\);" nil t)
1086             (setq code (string-to-int (match-string 3) 16))
1087             (replace-match
1088              (format "<img alt=\"UU+%04X\" src=\"http://www.unicode.org/cgi-bin/refglyph?24-%04X\"
1089 style=\"vertical-align:middle\">"
1090                      code
1091                      code
1092                      www-format-char-img-style)
1093              t 'literal))
1094
1095           (goto-char (point-min))
1096           (while (re-search-forward "&MCS-\\([0-9A-F]+\\);" nil t)
1097             (setq code (string-to-int (match-string 1) 16))
1098             (setq start (match-beginning 0)
1099                   end (match-end 0))
1100             (setq char (decode-char 'system-char-id code))
1101             (cond
1102              ((and (setq variants
1103                          (or (www-get-feature-value char '->subsumptive)
1104                              (www-get-feature-value char '->denotational)))
1105                    (progn
1106                      (while (and variants
1107                                  (setq ret (www-format-encode-string
1108                                             (char-to-string (car variants))))
1109                                  (string-match "&MCS-\\([0-9A-F]+\\);" ret))
1110                        (setq variants (cdr variants)))
1111                      ret))
1112               (unless (string-match "&MCS-\\([0-9A-F]+\\);" ret)
1113                 (goto-char start)
1114                 (delete-region start end)
1115                 (insert ret))
1116               )
1117              ((setq ret (or (www-get-feature-value char 'ideographic-combination)
1118                             (www-get-feature-value char 'ideographic-structure)))
1119               (setq ret
1120                     (mapconcat
1121                      (lambda (ch)
1122                        (if (listp ch)
1123                            (if (characterp (setq rret (find-char ch)))
1124                                (setq ch rret)))
1125                        (if (characterp ch)
1126                            (www-format-encode-string
1127                             (char-to-string ch) without-tags)
1128                          (www-format-encode-string
1129                           (format "%S" ch) without-tags)))
1130                      ret ""))
1131               (when ret
1132                 (goto-char start)
1133                 (delete-region start end)
1134                 (insert ret))
1135               )))
1136           ))
1137       ;; (goto-char (point-min))
1138       ;; (while (search-forward "&GT-" nil t)
1139       ;;   (replace-match "&amp;GT-" t 'literal))
1140       (buffer-string))))
1141
1142 (defun www-html-display-text (text)
1143   (princ
1144    (with-temp-buffer
1145      (insert text)
1146      (goto-char (point-min))
1147      (while (search-forward "<" nil t)
1148        (replace-match "&lt;" nil t))
1149      (goto-char (point-min))
1150      (while (search-forward ">" nil t)
1151        (replace-match "&gt;" nil t))
1152      (goto-char (point-min))
1153      (while (re-search-forward "\\[\\[\\([^]|[]+\\)|\\([^][]+\\)\\]\\]" nil t)
1154        (replace-match
1155         (format "<a href=\"%s\">%s</a>"
1156                 (match-string 2)
1157                 (match-string 1))
1158         nil t))
1159      (encode-coding-region (point-min)(point-max) 'utf-8-mcs-er)
1160      (goto-char (point-min))
1161      (while (search-forward "&GT-" nil t)
1162        (replace-match "&amp;GT-" nil t))
1163      (buffer-string))))
1164
1165 (defun www-html-display-paragraph (text)
1166   (princ "<p>")
1167   (www-html-display-text text)
1168   (princ "</p>\n"))
1169
1170
1171 ;;; @ for GlyphWiki
1172 ;;;
1173
1174 (defvar coded-charset-GlyphWiki-id-alist
1175   '((=ucs               "u"     4 x nil)
1176     (=adobe-japan1-0    "aj1-"  5 d nil)
1177     (=adobe-japan1-1    "aj1-"  5 d nil)
1178     (=adobe-japan1-2    "aj1-"  5 d nil)
1179     (=adobe-japan1-3    "aj1-"  5 d nil)
1180     (=adobe-japan1-4    "aj1-"  5 d nil)
1181     (=adobe-japan1-5    "aj1-"  5 d nil)
1182     (=adobe-japan1-6    "aj1-"  5 d nil)
1183     (==adobe-japan1-0   "aj1-"  5 d nil)
1184     (==adobe-japan1-1   "aj1-"  5 d nil)
1185     (==adobe-japan1-2   "aj1-"  5 d nil)
1186     (==adobe-japan1-3   "aj1-"  5 d nil)
1187     (==adobe-japan1-4   "aj1-"  5 d nil)
1188     (==adobe-japan1-5   "aj1-"  5 d nil)
1189     (==adobe-japan1-6   "aj1-"  5 d nil)
1190     (===adobe-japan1-0  "aj1-"  5 d nil)
1191     (===adobe-japan1-1  "aj1-"  5 d nil)
1192     (===adobe-japan1-2  "aj1-"  5 d nil)
1193     (===adobe-japan1-3  "aj1-"  5 d nil)
1194     (===adobe-japan1-4  "aj1-"  5 d nil)
1195     (===adobe-japan1-5  "aj1-"  5 d nil)
1196     (===adobe-japan1-6  "aj1-"  5 d nil)
1197     (=decomposition@cid)
1198     (=decomposition@hanyo-denshi)
1199     (=hanyo-denshi/ks   "koseki-" 6 d nil)
1200     (=>>hanyo-denshi/ks "koseki-" 6 d nil)
1201     (=ucs@jis           "u"     4 x nil)
1202     (==ucs@jis          "u"     4 x nil)
1203     (==ucs@iso          "u"     4 x nil)
1204     (===ucs@jis         "u"     4 x nil)
1205     (=ucs@cns           "u"     4 x "-t")
1206     (==ucs@cns          "u"     4 x "-t")
1207     (=jis-x0212         "jsp-"  4 x nil)
1208     (=jis-x0213-1@2000  "jx1-2000-" 4 x nil)
1209     (=jis-x0213-1@2004  "jx1-2004-" 4 x nil)
1210     (=jis-x0213-2       "jx2-"  4 x nil)
1211     (=gt                "gt-"   5 d nil)
1212     (=daikanwa          "dkw-"  5 d nil)
1213     (==daikanwa         "dkw-"  5 d nil)
1214     (===daikanwa        "dkw-"  5 d nil)
1215     (=gt-k              "gt-k"  5 d nil)
1216     (=jef-china3        "jc3-"  4 x nil)
1217     (=big5              "b-"    4 x nil)
1218     (=ucs@ks            "u"     4 x "-k")
1219     (==ucs@ks           "u"     4 x "-k")
1220     (===ucs@ks          "u"     4 x "-k")
1221     (=ks-x1001          "k0-"   4 x nil)
1222     (=jis-x0208@1978/1pr "j78-" 4 x nil)
1223     (=jis-x0208@1978/-4pr "j78-" 4 x nil)
1224     (=jis-x0208@1978    "j78-"  4 x nil)
1225     (=>>>jis-x0208@1978 "j78-"  4 x nil)
1226     (=>>jis-x0208@1978  "j78-"  4 x nil)
1227     (=+>jis-x0208@1978  "j78-"  4 x nil)
1228     (=ucs@JP            "u"     4 x nil)
1229     (=ucs@gb            "u"     4 x "-g")
1230     (=ucs@iso           "u"     4 x "-u")
1231     (=ucs@unicode       "u"     4 x "-us")
1232     (=big5-cdp          "cdp-"  4 x nil)
1233     (=>>big5-cdp        "cdp-"  4 x nil)
1234     (=cns11643-1        "c1-"   4 x nil)
1235     (=cns11643-2        "c2-"   4 x nil)
1236     (=cns11643-3        "c3-"   4 x nil)
1237     (=cns11643-4        "c4-"   4 x nil)
1238     (=cns11643-5        "c5-"   4 x nil)
1239     (=cns11643-6        "c6-"   4 x nil)
1240     (=cns11643-7        "c7-"   4 x nil)
1241     (=jis-x0208         "j90-"  4 x nil)
1242     (=>>>jis-x0208      "j90-"  4 x nil)
1243     (=>>jis-x0208       "j90-"  4 x nil)
1244     (=+>jis-x0208       "j90-"  4 x nil)
1245     (=jis-x0208@1990    "j90-"  4 x nil)
1246     (=>>>jis-x0208@1990 "j90-"  4 x nil)
1247     (=>>jis-x0208@1990  "j90-"  4 x nil)
1248     (=+>jis-x0208@1990  "j90-"  4 x nil)
1249     (=jis-x0208@1983    "j83-"  4 x nil)
1250     (=>>>jis-x0208@1983 "j83-"  4 x nil)
1251     (=>>jis-x0208@1983  "j83-"  4 x nil)
1252     (=+>jis-x0208@1983  "j83-"  4 x nil)
1253     (=cbeta             "cb"    5 d nil)
1254     (=>>daikanwa        "dkw-"  5 d nil)
1255     (=ucs-var-001       "u"     4 x "-var-001")
1256     (=ucs-var-002       "u"     4 x "-var-002")
1257     (=ucs-var-003       "u"     4 x "-var-003")
1258     (=ucs-itaiji-002    "u"     4 x "-itaiji-002")
1259     (=ucs-itaiji-084    "u"     4 x "-itaiji-084")
1260     (=big5-cdp-var-3    "cdp-"  4 x "-var-3")
1261     (=big5-cdp-var-5    "cdp-"  4 x "-var-5")
1262     ))
1263
1264 (defun char-GlyphWiki-id (char)
1265   (let ((rest coded-charset-GlyphWiki-id-alist)
1266         spec ret code)
1267     (while (and rest
1268                 (setq spec (pop rest))
1269                 (null (setq ret (char-feature char (car spec))))))
1270     (when ret
1271       (or
1272        (and (listp ret)
1273             (mapconcat #'char-GlyphWiki-id ret "-"))
1274        (and (memq (car spec) '(=ucs@unicode '=ucs@iso))
1275             (cond
1276              ((and (or (encode-char char '=jis-x0208@1990)
1277                        (encode-char char '=jis-x0212)
1278                        (encode-char char '=jis-x0213-1)
1279                        (encode-char char '=jis-x0213-2))
1280                    (setq code (encode-char char '=ucs@jis)))
1281               (format "u%04x" code)
1282               )
1283              ((and (or (encode-char char '=gb2312)
1284                        (encode-char char '=gb12345))
1285                    (setq code (encode-char char '=ucs@gb)))
1286               (format "u%04x-g" code)
1287               )
1288              ((and (or (encode-char char '=cns11643-1)
1289                        (encode-char char '=cns11643-2)
1290                        (encode-char char '=cns11643-3)
1291                        (encode-char char '=cns11643-4)
1292                        (encode-char char '=cns11643-5)
1293                        (encode-char char '=cns11643-6)
1294                        (encode-char char '=cns11643-7))
1295                    (setq code (encode-char char '=ucs@cns)))
1296               (format "u%04x-t" code)
1297               )
1298              ((and (encode-char char '=ks-x1001)
1299                    (setq code (encode-char char '=ucs@ks)))
1300               (format "u%04x-k" code)
1301               )))
1302        (format (format "%s%%0%d%s%s"
1303                        (nth 1 spec)
1304                        (nth 2 spec)
1305                        (nth 3 spec)
1306                        (or (nth 4 spec) ""))
1307                ret)))))
1308
1309
1310 ;;; @ End.
1311 ;;;
1312
1313 (provide 'cwiki-common)
1314
1315 ;;; cwiki-common.el ends here