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