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