ottt

xyzzy の覚え書き

S 式 で html を出力してみる

(format nil "~A~A" :foo "bar") こう書けるみたいなので , s式html もどきをでっち上げ(attribute をきっちり html の属性を書いてやれば補完もできるっぽいけど、めんどくさい) 文字列が悩む所だけど、インデントで読みやすかったりする気が少しする。

自動生成版に変更し多少メンテしやすくした。

 (provide "shtml")
 (defmacro !DOCTYPE (&rest rest)
  `(format nil "~%"
           (list ,@rest)))
 (defmacro !-- (&rest rest)
  `(format nil "~%~%"
           (list ,@rest)))

 (defmacro tag (tag
               container
               (&rest rest &key attribute)
               (&rest child))
  `(format nil "~[~;~%~;~:;~%~]<~A~{~^ ~A=\"~A\"~^ ~}>~{~A~}~[~;~%~;~:;~%~]"
           ,container
           ,tag
           (list ,@rest)
           (list ,@child)
           ,tag
           ,container))

 (defmacro html-tag-mac(tag container)
  `(defmacro ,tag((&rest rest &key attribute) &rest child)
     `(tag ,,(string tag) ,,container ,rest ,child)))

 (defvar *html-style*
  '((html 1)
    (head 1)
    (title 1)
    (body 1 )
    (h1 1)
    (h2 1)
    (h3 1)
    (h4 1)
    (h5 1)
    (h6 1)
    (div 1)
    (ol 1)
    (ul 1)
    (li 1)
    (a 0 )
    (abbr 0)
    (acronym 0)
    (address 0)
    (applet 0 )
    (b 0 )
    (basefont 1)
    (bdo 0)
    (big 0)
    (blink 0)
    (blockquote 1)
    (button 1)
    (caption 1)
    (center 1)
    (cite 0)
    (code 0)
    (colgroup 1)
    (comment 1)
    (dd 1)
    (del 0)
    (dfn 0)
    (dir 1)
    (dl 1)
    (dt 1)
    (em 0)
    (embed 1)
    (fieldset 1)
    (font 0)
    (form 1)
    (frameset 1)
    (i 1)
    (iframe 0)
    (ilayer 1)
    (ins 0)
    (kbd 0)
    (label 1)
    (layer 1)
    (legend 1)
    (listing 1)
    (map 1)
    (marquee 1)
    (menu 1)
    (multicol 1)
    (nobr 1)
    (noembed 1)
    (noframes 1)
    (nolayer 1)
    (noscript 1)
    (object 1)
    (optgroup 1)
    (option 1)
    (p 1)
    (pre 1)
    (q 0)
    (rb 0)
    (rp 0)
    (rt 0)
    (ruby 1)
    (s 0)
    (samp 0)
    (script 1)
    (select 1)
    (server 1)
    (small 0)
    (span 0)
    (strike 0)
    (strong 0)
    (style 1)
    (sub 0)
    (sup 0)
    (table 1)
    (tbody 1)
    (td 1)
    (textarea 1)
    (tfoot 1)
    (th 1)
    (thead 1)
    (title 1)
    (tr 1)
    (tt 1)
    (u 0)
    (var 0)
    (xmp 0)
    ))
 (dolist(x *html-style*)
  (eval `(html-tag-mac ,(car x) ,(cadr x))))
 (defmacro tag-c (tag (&rest rest &key attribute))
  `(format nil "<~A~{~^ ~A=\"~A\"~} />~%"
           ,tag
           (list ,@rest)))
 (defmacro html-single-tag-mac(tag)
  `(defmacro ,tag(&rest rest &key attribute)
     `(tag-c ,,(string tag) ,rest)))
 (defvar *html-single-style*
  '(meta
    link
    br
    hr
    base
    area
    frame
    img
    input
    bgsound
    col
    keygen
    param
    wbr))
 (dolist(x *html-single-style*)
  (eval `(html-single-tag-mac ,x)))

例えば , こういう s式を *scratch* で評価

 (html()
     (head()
          (title () "test")
          (meta (:name "EE")))
     (body()
          (h1 (:id "H1")
              "FOOOOOO!")
          (div ()
               (p ()
                  "ふがふが" (a(:href "foo")"ふう")
                  "RoR")
               (p () "ほげほげ"))
          (ol ()
              (li () "list1")
              (li () "list2"))
          (h2 (:id "H2" :class "hoge")
              (a (:href "hoge") "ほげ")
              (table(:background "blue"
                     :border "3")
                    (tr ()
                         (td ()  "1")
                          (td () "2"))
                     (tr ()
                         (td () "1234")
                         (td () "5678"))
                     ))))
   =>
   "
   <html>
   <head>
   <title>test</title>
   </head>


   <body>
   <h1 id=\"H1\">FOOOOOO!</h1>


   <div>
   <p>ふがふが
   <a href=\"foo\">ふう</a>
   </p>


   <p>ほげほげ</p>
   </div>


   <ol>
   <li>list1</li>


   <li>list2</li>
   </ol>


   <h2 class=\"hoge\" id=\"H2\">
   <a href=\"hoge\">ほげ</a>


   <table border=\"3\" background=\"blue\">
   <tr>
   <td>1</td>


   <td>2</td>
   </tr>


   <tr>
   <td>1234</td>


   <td>5678</td>
   </tr>
   </table>
   </h2>
   </body>
   </html>
   "

括弧を減らした。


last modified Sun, 27 Jan 2008 15:39:21 JST-9