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