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