テキスト埋め込みScheme


Embedded SCheme

略してesc。

Rubyのerbのようなテンプレートエンジンですが、直接の影響を受けたのはPerlのepl(内輪ネタ)です。

トリム機能の使い方に関しては、erbではなくeplを参考にしています
(というよりTemplateToolKit?)

esc.scm

PHP、JSPのようなテキスト埋め込みなSchemeコードを処理します。
Gauche用なので、他の処理系では動きません。

こういうtemplateを、こういうscriptから呼び出す時に使う。

使い方の簡単な説明

以下のルールに従って、解釈されます

 ここは通常のテキスト
 <%
     ;;ここはSchemeのコード
 %>
 ここは通常のテキスト
 <%=
   (string-append
     "ここはSchemeのコードで、"
     "式や変数を評価した結果を挿入します")
 %>

もっと具体的な例は以下のように

埋め込み対象のテキストファイルがこんな感じで

 <html>
 <%
   (let
     ((context (car args)))
 %>
 <head>
 <title><%= (context "title") %></title>
 </head>
 <body>
 <div><%= (context "message") %></div>
 <div>
 <%
     (if
       (context "bool")
       (begin %>真です<% )
       (begin %>偽です<% ))
 %>
 </div>
 </body>
 <%
   )
 %>
 </html>

esc-eval関数を呼び出すとき、テンプレートとなる文字列と、引数として与えるパラメータを渡す(第2引数以降がパラメータとなる)

与えられたパラメータは、暗黙のうちにargsという変数名のリストへまとめられます
(Perlの@_とか、JavaScriptのargumentのようなもの)

 (add-load-path ".")
 (use esc)
 (define context (context-make))
 (context "title" "esc example")
 (context "message" "test")
 (context "bool" #t)
 
 (display
   (esc-eval
     (call-with-input-file "index.esc" port->string)
     context))

context-makeの定義は簡易マッピング機能?を参照してください。

引数に使えるオブジェクトに特に制限はないので、通常の関数が受け取れるオブジェクトなら、基本的に何でも扱えます。

で、上記コードを実行すると出力されるのが以下の文字列(esc-eval関数は、文字列を返します)

 <html>
 
 <head>
 <title>esc example</title>
 </head>
 <body>
 <div>test</div>
 <div>
 真です
 </div>
 </body>
 
 </html>

Webプログラミングをしていると、どうしても共通化したい部品などが出てきますが、そういう場合は以下のようにして別のescファイルをインクルードすることが可能。

 <html>
 <head>
 <title>esc example</title>
 </head>
 <body>
 <%=
   (esc-eval
     (call-with-input-file "common_text.esc" port->string)
     arg1
     arg2) %>
 </body>
 </html>

上記の例では、あるescファイル中から、別のescファイル(common_text.esc)を呼び出して挿入しています。
インクルード対象のesc内でもSchemeコードの埋め込みは有効ですし、引数を与えることも可能です
(例ではarg1とarg2が引数にあたります)

改行を制御するトリム機能は以下のように

こう書くと、<html>タグの直前と</html>タグの直後にくるはずの改行が消去される

 <%
   ;;直後の改行を最大1個だけ消す
 -%>
 <html>
 <body>
 <p>中略~</p>
 </body>
 </html>
 <%-
   ;;直前の改行を最大1個だけ消す
 %>

既知のバグ

TODO

escmとの違い

escm


Last modified : 2008/12/29 22:37:33 JST