[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[kahua-dev:00773] Kahua で RSS (xml DOCTYPE 宣言したい)



初めまして,柴田といいます.

KahuaでRSSを出力するようなコードを書いてみました.


RSSでは下のようなxml宣言を付けて文字コードを指定しないといけません.

<?xml version="1.0" encoding="euc-jp" ?>       <-----これ
<rss version="2.0">
	<channel>
		<title>top title</title>
	<link>
		.....

でも,Kahuaのrender-procが扱うnodesは,
下の2個なのでxml宣言を付けられません.(多分)
a) (node-set (html (head (title .....))))
b) ((html (head (title ....))))

そこで,下のようなSXML nodeも扱えるようにkahua.serverをいじって,
<html>タグなど外側にDOCTYPE宣言とxml宣言を書けるようにしてみました.

(*TOP* (*PI* version "foo" )
       (*DECL* "baa")
       (html (head (title ...)..).))
      
これは

<?version foo ?>
<!DOCTYPE baa >
<html>
 <head>
  <title>
  ...
  </title>
  ..
 </head>
  .
</html>

と出力されます.

ツッコミ等おねがいします.
       
--------------------------------------------------------------------------------
diff -c ../Kahua-0.2.8/src/kahua/server.scm ./server.scm
*** ../Kahua-0.2.8/src/kahua/server.scm 2004-08-11 21:15:58.000000000 +0900
--- ./server.scm        2004-09-23 18:56:24.000000000 +0900
***************
*** 246,257 ****
  ;; default render proc
  ;; TODO: should apply interp-html-rec to all nodes!
  (define (kahua-render-proc nodes context)
    (let* ((expanded
            (cond ((procedure? nodes) (car (rev-nodes (exec '() nodes))))
                  ((eq? (car nodes) 'node-set) (cadr nodes))
                  (else (car nodes))))
!          (interp (get-interp expanded)))
!     (interp expanded context values)))

  (define-values (add-interp! get-interp)
    (let ((table (make-hash-table))
--- 246,281 ----
  ;; default render proc
  ;; TODO: should apply interp-html-rec to all nodes!
  (define (kahua-render-proc nodes context)
+   ;; '(*TOP* (*PI* a... ) (*DECL* b...) (html ...))
+   ;; -> '(("<?" a... "?>")("<!DOCTYPE " b.... " >"))
+   (define (get-declarations nodes)
+     (define (iter node)
+       (let1 node-name (sxml:node-name node)
+             (cond ((eq? '*PI* node-name)
+                    `("<?" ,(cadr node) " " ,(caddr node) " ?>\n"))
+                   ((eq? '*DECL* node-name)
+                    `("<!DOCTYPE " ,(cadr node) " >\n"))
+                   (else #f))))
+     (filter-map iter (sxml:content-raw nodes)))
+   ;; '(*TOP* (*PI* ... ) (*DECL* ...) (html ...)) -> '(html ...)
+   (define (filter-declaration-node nodes)
+     (car (filter
+           (lambda (node) (not (eq? '*DECL* (sxml:node-name node))))
+           (sxml:content nodes))))
+
    (let* ((expanded
            (cond ((procedure? nodes) (car (rev-nodes (exec '() nodes))))
                  ((eq? (car nodes) 'node-set) (cadr nodes))
+                 ((eq? (car nodes) '*TOP*) (filter-declaration-node nodes))
                  (else (car nodes))))
!          (interp (get-interp expanded))
!          (cont (if (and (pair? nodes)
!                         (eq? (car nodes) '*TOP*))
!                    (lambda (nds cntx)
!                      (values
!                       (append (get-declarations nodes) nds) cntx))
!                  values)))
!     (interp expanded context cont)))

  (define-values (add-interp! get-interp)
    (let ((table (make-hash-table))
    


--------------------------------------------------------------------------------
;;kahua-webでrss出力するentry

; <page-data>:id -> String
(define (page-url page)
  (kahua-self-uri-full #`"show,(pagename-join
                                   (map uri-encode-string
                                        (pagename-split
                                         (ref (find-kahua-instance <page-data> page) 'name))))"))
; <page-data>:id -> String
(define (page-title page)
  (base-pagename  (ref (find-kahua-instance <page-data> page) 'name)))

; <page-data>:id -> String
(define (pubdate-mtime page)
  (let1 secs (ref (find-kahua-instance <page-data> page) 'mtime)
        (sys-strftime "%a, %d %b %Y %H:%M:%S +0000" (sys-localtime secs))))

(define-entry (rss)
  (let* ((full-url (kahua-self-uri-full))
         ; (List <page-data>:id)
         (entries (ref (find-kahua-instance <page-set> "recent-changes")
                       'pages)))
    ;; SXML
    `(*TOP*
      (*PI* xml "version=\"1.0\" encoding=\"euc-jp\"")
      (rss (@ (version "2.0"))
           (extra-header (@ (name "content-type")
                            (value "text/xml; charset=euc-jp")))
           (channel
            (title "*top title*")
            (link  ,full-url)
            (description "*description of this site*")
            (lastBuildDate ,(pubdate-mtime (car entries)))
            ,@(map (lambda (entry)
                      `(item
                        (title ,(page-title entry))
                        (link ,(page-url entry))
                        (pubDate  ,(pubdate-mtime entry))))
                   entries))))))
--------------------------------------------------------------------------------