[library][xyzzy] CL-HAMLが xyzzyに対応しました

xyzzyという Common Lispベースの拡張言語を採用した Emacs風のエディタで CL-HAMLが動くようになりました。私だけが嬉しいバージョンアップですね。バージョン番号上げるの忘れてた。

xyzzy対応でのやったこと色々

xyzzy lispCommon Lispへの対応状況は6割くらい」みたいな話をどこかで見た気がしますが、実際に ANSI Common Lispの処理系で動作しているライブラリを動かそうとしたときに、結構な問題にブチあたりました。そして、いろいろ助けてもらいました。

CLOSが無い

クラスが作成出来ない(構造体はある)。メソッドが作成出来ない。

今回は、構造体で問題無いレベルのクラスしか使用していなかったので、構造体に変更してしまった。

PATHNAMEが無い

pathnameという型は存在しない。でも pathname関係の関数はそれなりに揃っている。pathnamepが定義されていなかったので、常に nilを返す関数として定義した。

LOOPマクロが標準では非常に貧弱

標準の LOOPマクロは無限ループするだけ。
cmu_loop という拡張loopライブラリがあるけど、動きが怪しい。

id:miyamuko =サンの ansi-loopというライブラリを利用することで、対応出来た。

clパッケージが無く、lispパッケージ

clパッケージは存在せず、lispパッケージがその役割を担っているらしい。

"#+xyzzy :lisp #-xyzzy :cl" という感じで対処。

cl-userパッケージが無く、userパッケージ

上に同じく、"#+xyzzy :user #-xyzzy :cl-user" という感じで対処。

CL-HAMLが依存するライブラリも移植しないと...

CL-HAMLは CL-WHOに依存しています。なので、先に CL-WHOを xyzzy上で動作するようにしないといけないのでした。

という話を Twitterで呟いたら、id:youz =サンが凄い速さで移植してくれたので万歳。

ANSI Common Lispの関数、マクロがチョイチョイ存在しない

これもない!アレもない!と吃驚する。

id:bowbow99 =サンの ansifyというライブラリで結構な範囲がカバーされている。大変ありがたい。

思えば遠くに来たものだ...

xyzzyは最近、有志による開発の再開が行われるようになりました。私がLispを触るようになった切っ掛けは xyzzyの拡張を読み書き出来るようになりたい!という気持ちだったこともありまして CL-HAMLxyzzyで動作させることにしたのでした。ちなみに「xyzzy lispANSI Common Lisp準拠にしたい」と思ったけど、xyzzyのソースのどの部分がlisp処理系なのか 調べる段階で面倒になったなんて言えない。

QuickLispに対応

CL-HAMLが QuickLispの本日の更新で取り込まれました。なので、QuickLispが使える人は

(ql:quickload :cl-haml)

だけで試すことが出来るようになりました。楽。

出力HTMLのインデントを消す機能とかちょっとした修正をローカルで行なっていたのだけど、GithubにPushするの忘れてたというオチが付きました。

[library] CL-HAML 1.0.0

Common Lisp用の Hamlっぽいライブラリ、CL-HAMLの version 1.0.0を githubで公開しました。

使用方法は以前とほとんど変化ありません。内容を書き直しただけです。

インストール

QuickLispに対応していません。githubから取得してください。

https://github.com/Unspeakable/cl-haml

取得後は asdfで loadしてください。

機能

Referenceに利用可能な機能を記述しています。でもよく考えたら、Hamlファイルの書き方は書いたけど、Hamlファイルを変換する方法が書いてなかったりしました。READMEには書いてあるのですが。

CL-USER> (ASDF:LOAD-SYSTEM :CL-HAML)
CL-USER> (CL-HAML:EXECUTE-HAML (MERGE-PATHNAMES "examples/example1.haml"
                                                (ASDF:SYSTEM-SOURCE-DIRECTORY :CL-HAML)))

という感じで、execute-haml関数に hamlファイルのパスネームを渡します。パスネーム毎に関数化して保持しているため、2回目以降は比較的早く出力を返します。

実行時のHamlファイルのタイムスタンプと、関数を作成した時のファイルのタイムスタンプを毎回比較し、ファイルが更新されると関数も更新されます。そのため、わざわざ関数の再定義などを明示的に行なう必要はありません。たぶんですが、マルチスレッド環境でも問題ないと思います(CL-EMBからパクりました)。

TODO

まだまだ、追加/修正したい機能が多々あります。なるべく、1週間くらいのスパンで更新していきたいです。

  • 幾つかの Filter
  • Self-Closing Tags: /
  • インデントの修正(もう少し本家Hamlに近づけたい)
  • Whitespace Preservation: ~
  • Whitespace Removal: > and

くらいは対応したいなーと思いました。

CL-HAML 再び

作成していた CL-HAML、既に書いた自分でも意味が分からなくなりました。色々と直したいのですが、もう何が何やら。

なので、最初から書き直すことにしました。仕様も多分、大幅変更になると思います。本家 Hamlの仕様も一部無視するだろうし、他のライブラリとの兼ね合いで、変更する部分もあると思います。

最初はクソみたいなコードのまま公開することになると思いますが、それをコネコネして 甘いクソくらいまでは 育てたいですねー。

[library] CL-HAML

少し前に、RubyHAMLっぽいものが欲しくなったので、作ってみました。現状、かなりの手抜きですが、自分で使いながら育てていこうと思っています。

https://github.com/Unspeakable/cl-haml

どんなものなのか

HTMLより(個人的には)楽な記法で書いたファイルを、HTMLに変換します。実際のHTMLに変換する部分は、CL-WHOに丸投げしているので、CL-WHOの入力用S式に変換するのが主な仕事。

!!! 5
%html
  %head
    %meta{:charset "utf-8"}
    %title Hello, world
  %body
    %h1 (format t "Hello, world!")
    %table{:border 1}
      - dotimes (i 10)
        %tr
          - dotimes (j 10)
            %td= (* i j)

上記の内容をファイル(仮に ~/sample.haml)に保存し、以下のように実行。

CL-USER> (asdf:load-system :cl-haml)
CL-USER> (setf cl-haml:*haml-file-root* (user-homedir-pathname))
CL-USER> (cl-haml:execute-haml "sample.haml" nil)

文字列で生成したHTMLを返します。hamlの中で、@ではじまるシンボルはパラメータとして外部から受けられるようになっています。パラメータは execute-haml の第2引数に plistで。ただし、キーの部分は @を除いた キーワードシンボル。なんでこんなことになっているかと言うと覚えてません。

execute-haml

この関数は初回だけ、Hamlファイルを関数に変換する処理が行われるため結構 動作が遅いです。2回目以降は 最初に作られた関数を保存していて、そいつを実行するので 普通の速度なのではないでしょうか。

ちなみに、hamlファイルを更新するとファイルのタイムスタンプと 関数生成時のタイムスタンプを比較して関数を作り直すので、開発中などHamlファイルを編集をすることが多い日でも安心。

package

先日 Hunchentoot上で使って気付いたのですが、マルチスレッドで動くWebアプリケーションでは特に指定していない場合は実行時の packageは :CL-USER になっていました。

execute-haml関数は実行中に関数を作るので、パッケージを指定していないシンボルは :CL-USER のシンボルになるらしい。common-lispの標準関数等なら問題無いのですが自分で定義した関数が常に :CL-USER パッケージに入っているわけではありません。なので第3引数(optional)として パッケージを指定できるようにしました。

CL-USER> (cl-haml:execute-haml "sample.haml" nil :cl-haml)

問題はいっぱい

個人的には HAMLが結構好きなので、本家に近付けたいなーとは思っているのですが残念なことにやる気とスキルが低めなので捗りません。READMEに 本家と異なる部分でボクが認識しているものは書いてあります。

今年中に、ある程度整理しておきたい。

Smiley Hackathon #10に行ってきました

7月2日(土)、Smiley Hackathon #10に行ってきました。主催の id:acotie さん、会場提供の Gaiax さん ありがとうございます。

土曜日は奥さんが着物の着付け教室へ行くため、一歳の娘を児童センターに預けてから参加。ノートPC、Kinesis、娘、娘の荷物を担いで五反田を走り回ったら疲れた。途中で荷物を一つ紛失したらしい。おおーん。

会場は広くて、すごく快適。自動販売機の飲み物が安くて羨ましい。最終的に17〜18人いたと思うけど、そのうち3人は Lispやってたので 世の中の 15%少々は Lispを書いていると言っても過言ではない。

やったこと

職場でやっていることと同じで、Weblocksのソースを読んでいたのでした。Widget周りは「このクラスの内容を以下にしてHTMLとして出力するか」が大半で、あまり面白くない。さっさと読んで「自分で作る、Weblocksの widget」を書いてしまいたい。けど、面白くないから進まない。一つわかったことは、自分が見ていた datalist widgetは、作ろうとしている widgetの参考には あまりならないということでした!くそ!

気分転換に フレームワークとか使わずに、Hunchentootをそのまま使って 簡単なWebサイト作って遊んでた。

GANCとかLispマシンとか

オワコンのLAMPを葬るために、GANC (Gentoo, Arc, Nginx, CouchDD)を提唱する [twitter:@mgiken]さんに Arcのソースとか CouchDBのArc View Serverとか見せてもらって面白かった。ドM、ドM言ってスミマセン。

あと [twitter:@g177564]さんに Lispマッシーンの話とか聞いて歴史が繰り返されていることを知ったのでした。あと、このフォント が思いの外見やすくて 今、会社のPCにブチ込もうとしてる。

そう、日曜なのにボクは出社しています。会社で、またLISPのコードを眺めたり、LISPを書いたりしています。プール行きてぇなぁ。

[library] HTML-TEMPLATE

cl-whoはデザイナーさんがイジるにはハードル高過ぎるかなーと思って HTML-TEMPLATE を使ってみたので、何となくメモ。

これは何ですか

動的にHTMLを作るためのライブラリ。
Perlに HTML::Template ってのがあって、それっぽくしてあるらしい。JavaJSPとかRubyのERBみたいな。

どう使うの

Quicklispでインストール可能。テンプレートの作り方は元サイトをどうぞ。

<!-- TMPL_VAR --> 値を埋め込み
<!-- TMPL_LOOP キー --><!-- /TMPL_LOOP --> dolistな繰り返し
<!-- TMPL_REPEAT キー --><!-- /TMPL_REPEAT --> dotimesな繰り返し
<!-- TMPL_IF キー --><!-- TMPL_ELSE --><!-- /TMPL_IF --> ifな条件分岐 elseは省略可能
<!-- TMPL_UNLESS キー --><!-- TMPL_ELSE --><!-- /TMPL_UNLESS --> unlessな条件分岐 elseは省略可能
<!-- TMPL_INCLUDE 'パス' --> パスで指定したファイルの内容を、そこに展開
<!-- TMPL_CALL キー --> テンプレートを処理した結果を埋め込む

fill-and-print-template にテンプレートファイルの pathnameを渡すとか、文字列で テンプレートを直接渡すとか。

注意点

デフォルトでは標準出力辺りにHTMLを出力しているよう。html-template:*default-template-output* を、自分の出力したい先へ束縛するといいのだと思う。

注意点2

HTML_INCLUDE を使うとき、勝手に相対パスで見てくれたりしません。
html-template:*default-template-pathname* からの相対パス、またはマシンの絶対パスで指定するっぽい。
それっぽい パスを束縛しましょう。

注意点3

fill-and-print-template のキーワード引数で :external-format は指定したほうが多分いい。
Windows, SBCL, UTF-8のテンプレートだと :external-format を指定しないと、日本語の引数を渡したときに死んでいた。

よく分かってない

正直、あまり良く分かってません。ただ、特殊な機能が タグではなく、コメントとして記述するってのは、ちょっと面白いなーと思ったのでした。