1 ;; -*- coding: utf-8-mcs-er -*-
2 (require 'char-db-util)
4 (defvar chise-wiki-view-url "view.cgi")
5 (defvar chise-wiki-edit-url "edit/edit.cgi")
7 (defvar chise-wiki-bitmap-glyphs-url
8 "http://chise.zinbun.kyoto-u.ac.jp/glyphs")
10 (defvar chise-wiki-glyph-cgi-url
11 "http://chise.zinbun.kyoto-u.ac.jp/chisewiki/glyph.cgi")
13 (defun decode-uri-string (string &optional coding-system)
14 (if (> (length string) 0)
18 (mapconcat (lambda (char)
21 (char-to-string char)))
23 (while (string-match "%\\([0-9A-F][0-9A-F]\\)" string i)
24 (setq dest (concat dest
25 (substring string i (match-beginning 0))
28 (string-to-int (match-string 1 string) 16))))
31 (concat dest (substring string i))
34 (defun www-feature-type (feature-name)
35 (or (char-feature-property feature-name 'type)
36 (let ((str (symbol-name feature-name)))
38 ((string-match "^\\(->\\|<-\\)" str)
40 ((string-match "^ideographic-structure\\(@\\|$\\)" str)
44 (defun www-feature-value-format (feature-name)
45 (or (char-feature-property feature-name 'value-format)
46 (let ((type (www-feature-type feature-name)))
47 (cond ((eq type 'relation)
48 'space-separated-char-list)
50 'space-separated-ids)))
51 (if (find-charset feature-name)
52 (if (and (= (charset-dimension feature-name) 2)
53 (= (charset-chars feature-name) 94))
55 " (" (decimal) ") <" (ku-ten) ">")
56 '("0x" (HEX) " (" (decimal) ")")))))
58 (defun char-feature-name-at-domain (feature-name domain)
59 (let ((name (symbol-name feature-name)))
61 ((string-match "@[^*]+$" name)
62 (intern (format "%s/%s" name domain))
65 (intern (format "%s@%s" name domain))
68 (defun www-char-feature (character feature)
69 (let ((latest-feature (char-feature-name-at-domain feature '$rev=latest)))
70 (mount-char-attribute-table latest-feature)
71 (or (char-feature character latest-feature)
72 (char-feature character feature))))
75 ;;; @ URI representation
78 (defun www-uri-decode-feature-name (uri-feature)
81 ((string-match "^from\\." uri-feature)
82 (intern (format "<-%s" (substring uri-feature (match-end 0))))
84 ((string-match "^to\\." uri-feature)
85 (intern (format "->%s" (substring uri-feature (match-end 0))))
87 ((string-match "^rep\\." uri-feature)
88 (intern (format "=%s" (substring uri-feature (match-end 0))))
90 ((string-match "^g\\." uri-feature)
91 (intern (format "=>>%s" (substring uri-feature (match-end 0))))
93 ((string-match "^gi\\." uri-feature)
94 (intern (format "=>>>%s" (substring uri-feature (match-end 0))))
96 ((string-match "^gi\\([0-9]+\\)\\." uri-feature)
97 (intern (format "=>>%s%s"
98 (make-string (string-to-int
99 (match-string 1 uri-feature))
101 (substring uri-feature (match-end 0))))
103 ((string-match "^a\\." uri-feature)
104 (intern (format "=>%s" (substring uri-feature (match-end 0))))
106 ((string-match "^a\\([0-9]+\\)\\." uri-feature)
107 (intern (format "%s>%s"
108 (make-string (string-to-int
109 (match-string 1 uri-feature))
111 (substring uri-feature (match-end 0))))
113 ((and (setq feature (intern (format "=>%s" uri-feature)))
114 (find-charset feature))
116 ((and (setq feature (intern (format "=>>%s" uri-feature)))
117 (find-charset feature))
119 ((and (setq feature (intern (format "=>>>%s" uri-feature)))
120 (find-charset feature))
122 ((and (setq feature (intern (format "=%s" uri-feature)))
123 (find-charset feature))
125 (t (intern uri-feature)))))
127 (defun www-uri-encode-feature-name (feature-name)
128 (setq feature-name (symbol-name feature-name))
130 ((string-match "^=\\([^=>]+\\)" feature-name)
131 (concat "rep." (substring feature-name (match-beginning 1)))
133 ((string-match "^=>>\\([^=>]+\\)" feature-name)
134 (concat "g." (substring feature-name (match-beginning 1)))
136 ((string-match "^=>>>\\([^=>]+\\)" feature-name)
137 (concat "gi." (substring feature-name (match-beginning 1)))
139 ((string-match "^=>>\\(>+\\)" feature-name)
141 (length (match-string 1 feature-name))
142 (substring feature-name (match-end 1)))
144 ((string-match "^=>\\([^=>]+\\)" feature-name)
145 (concat "a." (substring feature-name (match-beginning 1)))
147 ((string-match "^\\(=+\\)>" feature-name)
149 (length (match-string 1 feature-name))
150 (substring feature-name (match-end 0)))
152 ((string-match "^->" feature-name)
153 (concat "to." (substring feature-name (match-end 0)))
155 ((string-match "^<-" feature-name)
156 (concat "from." (substring feature-name (match-end 0)))
160 (defun www-uri-decode-char (char-rep)
163 ((string-match "\\(%3A\\|:\\)" char-rep)
164 (setq ccs (substring char-rep 0 (match-beginning 0))
165 cpos (substring char-rep (match-end 0)))
166 (setq ccs (www-uri-decode-feature-name ccs))
168 ((string-match "^0x" cpos)
170 (string-to-number (substring cpos (match-end 0)) 16))
173 (setq cpos (string-to-number cpos))
176 (decode-char ccs cpos))
179 (setq char-rep (decode-uri-string char-rep 'utf-8-mcs-er))
180 (when (= (length char-rep) 1)
184 (defun www-uri-encode-char (char)
185 (if (encode-char char '=ucs)
188 (format "%%%02X" byte))
189 (encode-coding-string (char-to-string char) 'utf-8-mcs-er)
191 (let ((ccs-list '(; =ucs
192 =cns11643-1 =cns11643-2 =cns11643-3
193 =cns11643-4 =cns11643-5 =cns11643-6 =cns11643-7
195 =jis-x0208 =jis-x0208@1990
198 =jis-x0213-1@2000 =jis-x0213-1@2004
199 =jis-x0208@1983 =jis-x0208@1978
203 =>>jis-x0208 =>>jis-x0213-1
204 =>jis-x0208 =>jis-x0213-1
210 (setq ccs (pop ccs-list))
211 (not (setq ret (encode-char char ccs 'defined-only)))))
214 (www-uri-encode-feature-name ccs)
216 ((and (setq ccs (car (split-char char)))
217 (setq ret (encode-char char ccs)))
219 (www-uri-encode-feature-name ccs)
222 (format "system-char-id:0x%X"
223 (encode-char char 'system-char-id))
227 ;;; @ Feature name presentation
230 (defun www-format-feature-name-default (feature-name)
234 (symbol-name feature-name)
238 (defun www-format-feature-name-as-rel-to (feature-name)
239 (concat "\u2192" (substring (symbol-name feature-name) 2)))
241 (defun www-format-feature-name-as-rel-from (feature-name)
242 (concat "\u2190" (substring (symbol-name feature-name) 2)))
244 (defun www-format-feature-name-as-CCS (feature-name)
247 (symbol-name feature-name)
249 (dest (upcase (pop rest))))
250 (when (string-match "^=+>*" dest)
251 (setq dest (concat (substring dest 0 (match-end 0))
253 (substring dest (match-end 0)))))
257 (setq dest (concat dest " " (upcase (pop rest)))))
258 (if (string-match "^[0-9]+$" (car rest))
259 (concat dest "-" (car rest))
260 (concat dest " " (upcase (car rest))))
264 (defun www-format-feature-name* (feature-name &optional lang)
268 (char-feature-property
270 (intern (format "name@%s" lang))))
271 (char-feature-property
272 feature-name 'name)))
273 ((find-charset feature-name)
274 (www-format-feature-name-as-CCS feature-name))
275 ((and (setq name (symbol-name feature-name))
276 (string-match "^\\(->\\)" name))
277 (www-format-feature-name-as-rel-to feature-name))
278 ((string-match "^\\(<-\\)" name)
279 (www-format-feature-name-as-rel-from feature-name))
281 (www-format-feature-name-default feature-name)))))
283 (defun www-format-feature-name (feature-name &optional lang)
284 (www-format-encode-string
285 (www-format-feature-name* feature-name lang)))
288 ;;; @ Feature value presentation
291 (defun www-format-value-as-kuten (value)
293 (- (lsh value -8) 32)
294 (- (logand value 255) 32)))
296 (defun www-format-value-as-char-list (value &optional without-tags)
301 (www-format-encode-string
302 (format (if (characterp unit)
308 (if (characterp unit)
309 (format "<a href=\"%s?char=%s\">%s</a>"
311 (www-uri-encode-char unit)
312 (www-format-encode-string (char-to-string unit)))
313 (www-format-encode-string (format "%s" unit)))))
315 (www-format-encode-string (format "%s" value) without-tags)))
317 (defun www-format-value-as-ids (value &optional without-tags)
322 (www-format-encode-string
323 (format (if (characterp unit)
329 (if (characterp unit)
330 (format "<a href=\"%s?char=%s\">%s</a>"
332 (www-uri-encode-char unit)
333 (www-format-encode-string (char-to-string unit)))
334 (www-format-encode-string (format "%s" unit)))))
335 (ideographic-structure-to-ids value) " ")
336 (www-format-encode-string (format "%s" value) without-tags)))
338 (defun www-format-value-as-S-exp (value &optional without-tags)
339 (www-format-encode-string (format "%S" value) without-tags))
341 (defun www-format-value-as-HEX (value)
344 (www-format-value-as-S-exp value)))
346 (defun www-format-value-as-CCS-default (value)
349 (www-format-value-as-HEX value)
351 (www-format-value-as-S-exp value)))
353 (defun www-format-value-as-CCS-94x94 (value)
355 (format "0x%s [%s] (%d)"
356 (www-format-value-as-HEX value)
357 (www-format-value-as-kuten value)
359 (www-format-value-as-S-exp value)))
361 (defun www-format-value (value &optional feature-name format without-tags)
363 ;; ((find-charset feature-name)
365 ;; ((and (= (charset-chars feature-name) 94)
366 ;; (= (charset-dimension feature-name) 2))
367 ;; (www-format-value-as-CCS-94x94 value))
369 ;; (www-format-value-as-CCS-default value)))
372 ;; (www-format-value-as-S-exp value)))
373 (www-format-apply-value format nil value nil nil without-tags)
377 ;;; @ format evaluator
380 (defun www-format-encode-string (string &optional without-tags)
383 (let (plane code start end char variants ret)
384 (goto-char (point-min))
385 (while (search-forward "<" nil t)
386 (replace-match "<" nil t))
387 (goto-char (point-min))
388 (while (search-forward ">" nil t)
389 (replace-match ">" nil t))
391 (encode-coding-region (point-min)(point-max) 'utf-8-mcs-er)
392 (let ((coded-charset-entity-reference-alist
394 '(=cns11643-1 "C1-" 4 X)
395 '(=cns11643-2 "C2-" 4 X)
396 '(=cns11643-3 "C3-" 4 X)
397 '(=cns11643-4 "C4-" 4 X)
398 '(=cns11643-5 "C5-" 4 X)
399 '(=cns11643-6 "C6-" 4 X)
400 '(=cns11643-7 "C7-" 4 X)
402 '(=gb12345 "G1-" 4 X)
403 '(=jis-x0208@1990 "J90-" 4 X)
404 '(=jis-x0212 "JSP-" 4 X)
406 '(=jis-x0208@1997 "J97-" 4 X)
407 '(=jis-x0208@1978 "J78-" 4 X)
408 '(=jis-x0208@1983 "J83-" 4 X)
410 '(=zinbun-oracle "ZOB-" 4 d)
411 '(=jef-china3 "JC3-" 4 X)
412 '(=daikanwa "M-" 5 d)
413 coded-charset-entity-reference-alist)))
414 (encode-coding-region (point-min)(point-max) 'utf-8-mcs-er)
416 (goto-char (point-min))
417 (while (re-search-forward "&CB\\([0-9]+\\);" nil t)
418 (setq code (string-to-int (match-string 1)))
420 (format "<img alt=\"CB%05d\" src=\"%s/cb-gaiji/%02d/CB%05d.gif\">"
422 chise-wiki-bitmap-glyphs-url
426 (goto-char (point-min))
427 (while (re-search-forward "&J\\(78\\|83\\|90\\|97\\|SP\\)-\\([0-9A-F][0-9A-F][0-9A-F][0-9A-F]\\);" nil t)
428 (setq plane (match-string 1)
429 code (string-to-int (match-string 2) 16))
431 (format "<img alt=\"J%s-%04X\" src=\"%s/JIS-%s/%02d-%02d.gif\">"
433 chise-wiki-bitmap-glyphs-url
436 (- (logand code 255) 32))
439 (goto-char (point-min))
440 (while (re-search-forward "&G\\([01]\\)-\\([0-9A-F][0-9A-F][0-9A-F][0-9A-F]\\);" nil t)
441 (setq plane (string-to-int (match-string 1))
442 code (string-to-int (match-string 2) 16))
444 (format "<img alt=\"GB%d-%04X\" src=\"%s/GB%d/%02d-%02d.gif\">"
446 chise-wiki-bitmap-glyphs-url
449 (- (logand code 255) 32))
452 (goto-char (point-min))
453 (while (re-search-forward "&C\\([1-7]\\)-\\([0-9A-F][0-9A-F][0-9A-F][0-9A-F]\\);" nil t)
454 (setq plane (string-to-int (match-string 1))
455 code (string-to-int (match-string 2) 16))
457 (format "<img alt=\"CNS%d-%04X\" src=\"%s/CNS%d/%04X.gif\">"
459 chise-wiki-bitmap-glyphs-url
463 (goto-char (point-min))
464 (while (re-search-forward "&JC3-\\([0-9A-F][0-9A-F][0-9A-F][0-9A-F]\\);" nil t)
465 (setq code (string-to-int (match-string 1) 16))
467 (format "<img alt=\"JC3-%04X\" src=\"http://kanji.zinbun.kyoto-u.ac.jp/db/CHINA3/Gaiji/%04x.gif\">"
471 (goto-char (point-min))
472 (while (re-search-forward "&ZOB-\\([0-9]+\\);" nil t)
473 (setq code (string-to-int (match-string 1)))
475 (format "<img alt=\"ZOB-%04d\" src=\"%s/ZOB-1968/%04d.png\">"
477 chise-wiki-bitmap-glyphs-url
481 (goto-char (point-min))
482 (while (re-search-forward "&\\(G-\\)?GT-\\([0-9]+\\);" nil t)
483 (setq code (string-to-int (match-string 2)))
485 (format "<img alt=\"GT-%05d\" src=\"%s?char=GT-%05d\">"
487 chise-wiki-glyph-cgi-url
491 (goto-char (point-min))
492 (while (re-search-forward "&B-\\([0-9A-F]+\\);" nil t)
493 (setq code (string-to-int (match-string 1) 16))
495 (format "<img alt=\"B-%04X\" src=\"%s?char=B-%04X\">"
497 chise-wiki-glyph-cgi-url
501 (goto-char (point-min))
502 (while (re-search-forward "&CDP-\\([0-9A-F]+\\);" nil t)
503 (setq code (string-to-int (match-string 1) 16))
505 (format "<img alt=\"CDP-%04X\" src=\"%s?char=CDP-%04X\">"
507 chise-wiki-glyph-cgi-url
511 (goto-char (point-min))
512 (while (re-search-forward "&UU\\+\\([0-9A-F]+\\);" nil t)
513 (setq code (string-to-int (match-string 1) 16))
515 (format "<img alt=\"UU+%04X\" src=\"http://www.unicode.org/cgi-bin/refglyph?24-%04X\">"
520 (goto-char (point-min))
521 (while (re-search-forward "&MCS-\\([0-9A-F]+\\);" nil t)
522 (setq code (string-to-int (match-string 1) 16))
523 (setq start (match-beginning 0)
525 (setq char (decode-char 'system-char-id code))
526 (setq variants (or (www-char-feature char '->subsumptive)
527 (www-char-feature char '->denotational)))
529 (setq ret (www-format-encode-string
530 (char-to-string (car variants))))
531 (string-match "&MCS-\\([0-9A-F]+\\);" ret))
532 (setq variants (cdr variants)))
533 (unless (string-match "&MCS-\\([0-9A-F]+\\);" ret)
535 (delete-region start end)
538 ;; (goto-char (point-min))
539 ;; (while (search-forward ">-" nil t)
540 ;; (replace-match "&GT-" t 'literal))
543 (defun www-format-props-to-string (props &optional format)
545 (setq format (plist-get props :format)))
547 (plist-get props :flag)
548 (if (plist-get props :zero-padding)
550 (if (plist-get props :len)
551 (format "%d" (plist-get props :len)))
553 ((eq format 'decimal) "d")
554 ((eq format 'hex) "x")
555 ((eq format 'HEX) "X")
556 ((eq format 'S-exp) "S")
559 (defun www-format-apply-value (format props value
560 &optional uri-char uri-feature
565 ((memq format '(decimal hex HEX))
567 (format (www-format-props-to-string props format)
569 (www-format-encode-string
574 (www-format-encode-string
575 (format (www-format-props-to-string props format)
579 (www-format-value-as-kuten value))
580 ((eq format 'space-separated-char-list)
581 (www-format-value-as-char-list value without-tags))
582 ((eq format 'space-separated-ids)
583 (www-format-value-as-ids value without-tags))
585 (setq format 'default)
586 (www-format-encode-string
587 (format (www-format-props-to-string props 'default)
590 (if (or without-tags (eq (plist-get props :mode) 'peek))
592 (format "%s <a href=\"%s?char=%s&feature=%s&format=%s\"
593 ><input type=\"submit\" value=\"edit\" /></a>"
596 uri-char uri-feature format))))
598 (defun www-format-eval-feature-value (char
600 &optional format lang uri-char value)
602 (setq value (www-char-feature char feature-name)))
604 (setq format (www-feature-value-format feature-name)))
607 (www-format-apply-value
609 uri-char (www-uri-encode-feature-name feature-name))
612 (cond ((null (cdr format))
613 (setq format (car format))
614 (www-format-apply-value
615 (car format) (nth 1 format) value
616 uri-char (www-uri-encode-feature-name feature-name))
619 (www-format-eval-list format char feature-name lang uri-char)
622 (defun www-format-eval-unit (exp char feature-name
623 &optional lang uri-char value)
625 (setq value (www-char-feature char feature-name)))
627 (setq uri-char (www-uri-encode-char char)))
629 ((stringp exp) (www-format-encode-string exp))
633 ((memq (car exp) '(value decimal hex HEX ku-ten S-exp default))
634 (if (eq (car exp) 'value)
635 (www-format-eval-feature-value char feature-name
636 (plist-get (nth 1 exp) :format)
638 (www-format-apply-value
639 (car exp) (nth 1 exp) value
640 uri-char (www-uri-encode-feature-name feature-name)))
642 ((eq (car exp) 'name)
643 (format "<a href=\"%s?feature=%s&char=%s\">%s</a>"
645 (www-uri-encode-feature-name feature-name)
647 (www-format-feature-name feature-name lang))
649 ((eq (car exp) 'link)
654 (www-format-eval-list (plist-get (nth 1 exp) :ref)
655 char feature-name lang uri-char)
656 (www-format-eval-list (nthcdr 2 exp)
657 char feature-name lang uri-char)))
663 (www-format-eval-list (nthcdr 2 exp) char feature-name
667 (defun www-format-eval-list (format-list char feature-name
668 &optional lang uri-char)
669 (if (consp format-list)
672 (www-format-eval-unit exp char feature-name lang uri-char))
674 (www-format-eval-unit format-list char feature-name lang uri-char)))
680 (defun www-html-display-text (text)
684 (goto-char (point-min))
685 (while (search-forward "<" nil t)
686 (replace-match "<" nil t))
687 (goto-char (point-min))
688 (while (search-forward ">" nil t)
689 (replace-match ">" nil t))
690 (goto-char (point-min))
691 (while (re-search-forward "\\[\\[\\([^]|[]+\\)|\\([^][]+\\)\\]\\]" nil t)
693 (format "<a href=\"%s\">%s</a>"
697 (encode-coding-region (point-min)(point-max) 'utf-8-mcs-er)
698 (goto-char (point-min))
699 (while (search-forward ">-" nil t)
700 (replace-match "&GT-" nil t))
703 (defun www-html-display-paragraph (text)
705 (www-html-display-text text)
708 (provide 'cwiki-common)