CL-WHO - Yet another Lisp markup language

CL-WHO というライブラリがある。

HTML を lisp のS式で表現する。例えばこんな感じ。

(:a :href "http://www.google.co.jp" "google")

最終的には S 式だと困るので cl-who を使用して HTML に変換する。

(who:with-html-output (str *standard-output*) (:a :href "http://www.google.
co.jp" "google"))

(str *standard-output*) は (*standard-output*) としてもよい。
結果はこうなる。

<a href='http://www.google.co.jp'>google</a>


なぜ、who かというと、まったくプログラムとは関係なく作者が the who のファンだからのようだ。

HTML でやりたいことの大半はテンプレート的に中に何かを挿入することだ。たとえば、Lisp の関数を入れて動的にページを作りたい、といったときに cl-who は威力を発揮する。(とはいえ、大概の場合動的にページを作ってはいけない!!)

(defun google (str) (format str "~a" "google"))

(who:with-html-output (str *standard-output*)(:a :href "http://www.google.co.jp" (google str)))

これで XML を編集するよりずっと楽になるし、構造的にプログラムを書くことができる。が、CL-WHO をつかっているとこの S 式をデータとして扱って、動的に(あるいは自動的に) HTML を作りたくなる。どうやら Lisp 的にはマクロを屈指して(マクロを作るマクロとか)作る必要があるのかもしれない。現時点でそのスキルは私にないので、ここはまず車輪の再発明よろしく、自前でマクロにたよらずプログラムを作るプログラミングをすることにする。

cl-who では次の事はできない

(who:with-html-output (str) (:a :href "http://www.googl.co.jp" google))

google というシンボルを解釈してそれを置き換えるという事はできない。JavaScriptXML を扱うときは id とかを指定してそこを場所にして(Place Holder)中身を設定できる。そうなってほしいができない。前述のように関数を入れて、str に対して書きこむという事で差し込むことはできる。

なお蛇足ながら、html-template というライブラリがって、そちらは HTML に直接埋め込みができる。これは perl の HTML::Template の移植(?)。これだと S 式から離れちゃうからね。

やりたいことは (:a :href url title) みたいなデータとしての S 式を変換して (:a :href "http://www.google.co.jp" "google") とすること。そして、それをさらに HTML にする。

これを実現するには Lisp の中で Lisp のパージング(コードウォーク)をしたい。LoL (う~ん。絶版になってしまった)では macrolet を使っている。それでこれが実現できるかどうかは不明なので、単純に再帰でコードウォークして、who-to-who と実現した(cl-clasp という名で github で公開中)。随分前に書いたコードなので(いいわけ)、Lisp としてかなり汚い。途中で Lisp プログラム自信を破壊するプログラムを書いているのに気が付かずに(メタなことをやってういるから)ソースは一貫していない。もう一度書き直したいなぁ。

でもって、最後に HTML に変換しなければならない。そこは S 式に (who:with-html-output (str) を書き足して copy して評価する。copy しないとソースを破壊する。これにきがつかんかった、、、って。結局、差し込んで評価する、、、、あ!!これってマクロじゃないか。と気が付いた時には遅かった。めんどくさいからそのまま公開している。

普段は”使える”からいいかと。

それにしても string-concat して copy して評価するという方式はどうかと思う。macro をつかって書き直したいなぁ。