リスト修行(3) SchemeでHTMLを書こう
HTMLって閉じタグ書くのが面倒ダヨネ。Schemeで書けば閉じタグ要らないじゃん!!と思ったので、今回の修行はリストをHTMLに変換してみたいと思います。
仕様
- リストの先頭はタグで始まり、子要素が続く。タグはシンボルで書く。
- ひとつめの子要素が2重のリストの場合はオプションとなる。オプション内の仕様については考え中。
というシンプルな仕様です。
ちなみに、PLT Web Server Manualのまねっこです。
ではではコーディング。
ゴニョゴニョ
(require (lib "1.ss" "srfi")) (require (lib "13.ss" "srfi")) ; Gauche用 ; (use srfi-1) ; (use srfi-13) (define s-tag `(html (head (title "ボクノス")) (body (h1 "ボクノス") (div (("class" "entry") ("id" "foo")) (h2 "今日のひとこと") (p "ちょっと大変だった。"))))) (define (make-tag t) (cond ((null? t) "") ((not (pair? t)) t) ((null? (cdr t)) (string-append "<" (symbol->string (car t)) " />")) ((pair? (car t)) "(オプションが入る予定。未実装)") (else (let ((head (symbol->string (car t))) (body (cdr t))) (string-append "<" head ">" (string-join (map make-tag body) "\n") "</" head ">"))))) (make-tag s-tag)
タグの閉じ方を思いつくまでに時間がかかった。
実行結果は・・・。
<html><head><title>ボクノス</title></head> <body><h1>ボクノス</h1> <div>(オプションが入る予定。未実装) <h2>今日のひとこと</h2> <p>ちょっと大変だった。</p></div></body></html>
おぉ。改行がイマイチだけど、ちゃんとできた!!
閉じタグが無い分、断然スッキリ書けそうですねぇ。
オプション部分を攻める
オプションも作りました。
こんなリストがあって、
(div (("class" "entry") ("id" "foo")) (p "ほげ"))
divをタグとして取り出して、オプションの取り出しやすいリストを作ります。
((("class" "entry") ("id" "foo")) (p "ほげ"))
次にオプションを文字列に切り出したリストを作ります。
(" class=\"entry\" id=\"foo\"" (p "ほげ"))
car,cdrすれば、オプションと中身が取り出せると。
方針が決まったらコーディング。
(define (make-tag t) (cond ((null? t) "") ((not (pair? t)) t) ((null? (cdr t)) (string-append "<" (symbol->string (car t)) " />")) (else (let* ((head (symbol->string (car t))) (opt (option (cdr t))) (body (cdr opt))) (string-append "<" head (car opt) ">" (string-join (map make-tag body) "\n") "</" head ">"))))) ; body -> (cons "options" body) (define (option t) (if (and (pair? (car t)) (pair? (caar t))) (cons (fold-right (lambda (a b) (string-append " " (car a) "=\"" (cadr a) "\"" b)) "" (car t)) (cdr t)) (cons "" t)))
テストぉ〜。
<html><head><title>ボクノス</title></head> <body><h1>ボクノス</h1> <div class="entry" id="foo"><h2>今日のひとこと</h2> <p>ちょっと大変だった。</p></div> <div class="entry" id="bar"><h2>今日のふたことめ</h2> <p>転んでも泣かない。</p></div></body></html>
おぉぉぉぉ。
かなり実用的になってきました。
さて次はテンプレートを。と思う所ですが、もう既に完成しているという噂が。
,を書けばテンプレートシステム完成です!!
Scheme凄いね・・・自由過ぎる・・・。
追記
バグを修正した。もうちょっとスッキリ書けると思う。