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