檜山正幸のジャッカル飼育記 このページをアンテナに追加 RSSフィード

最近のコメント

2006-01-14

[]式言語 2 12:10

コメント欄狭いから、こっちで:

if文くらいはあると便利だし、paramから値のリストを渡すようなケースでforeachみたいなのがあるといいかも? でもJavaScript動くの前提なので大抵のことはJavaScriptで書けば済むはずですよね。

if文は式言語じゃなくてテンプレート親言語にあればいいと思う。foreachも親側かと。

{if (条件式)}
 条件成立のときのテンプレート
{/if}

{for 変数名 in リスト式}
 繰り返ししたいテンプレート
{/for}

あー、そうか、条件式書くなら論理演算(&&, ||, !)は必要だし、等号不等号も要りますね。for-in文をサポートするなら、リストとして評価される式(ないしはイテレータ)も要るのですね、やっぱりそれなりの構文か。

JavaScriptそのものを使えるのは、ブラウザに入ってからだから、JACALプロセス時点では無理。テンプレート置換/式評価はあくまでJACALの仕事なので、JavaScriptは使えませんよ。(Perlで実装されたJavaScriptがあれば話が別だが。)

[]テンプレート言語と式言語 16:46

やっぱり、まじめに考えないといかん、つう気がヒシヒシ。

以下、「テンプレート言語」とは式言語を含まない親(ホスト)言語の意味とする。

入力コンテンツからもらえるのはコンテキストに限られる。コンテキストをチェーンすることはあるかもしれないが、いずれにしても、名前・値ペアの組で、値も文字列。よって、式評価器は、コンテキストと式をもらって文字列値を返す。これは原則。

しかし、テンプレート側ではifなどの条件として使いたいなら真偽値(boolean)が欲しいし、for-in文なら、なんらかのコレクション(リスト、配列、マップ、イテレータなどを総称してコレクションとする)が欲しい。となると、型システムと暗黙および明示的な型変換が必要になる。だから、型変換はどちら(テンプレート言語か式言語)が受け持つか、とか、そもそも式言語も型(真偽値やコレクション)を持つべきか、とかが問題になる。

予備知識の最小化の原則からは、型や型変換はJavaScripにあわせたい。が、そうなると式言語の自由度はあまりなくなる。まー、自由度よりは単純さだから、ここはそう悩まないが、JavaScripのコードがテンプレート化されたときの可読性とかはまじめに考えないといけないだろう。

rnarna2006/01/15 06:48>JavaScriptは使えませんよ。
いや、いざとなればJavaScriptのDOMでテンプレート展開を補完できるということです。式言語にfor文がなくても表示時点でJSのfor文でDOMツリーのコピーを回せば見た目は同じこと。

トラックバック - http://jacal.g.hatena.ne.jp/m-hiyama/20060114

2006-01-13

[]式言語 12:00

テンプレート言語の親言語と式言語を分離したいというのが僕の希望。以下、単に「テンプレート言語」といえば親(ホスト)言語だとして、なんらかの区切り/囲みで式部分が識別できて、式部分を式評価器に送って戻り値をもらう、という構造を想定している。理想をいえば、テンプレート言語と式言語の任意の組み合わせを可能にしたい。

TrimPath JSTでは、式言語がJavaScriptそのもの。でも、JACALにはオーバースペックだ。実は、次のようなんでもまにあうような気もする。

 式 ::= 変数
 変数 ::= 名前

だが、せっかくなんばさんがyaccを持ち出し、ヴィルト本を借り出してまで勉強しているので、もう少し式らしい構文までサポートしてもいいのかな、っと。が、値は文字列しかないので(“キャスト”して整数とみなしたりはできる)、演算子も連接くらいしか思いつかん。関数呼び出しがあればうれしいが、その関数を誰がどうやって書くの?って話になるし。

今回は、意図的かつ強固に「利用者に負担をかけない」方針を貫くので、概念的に難しかったり、OldHTML文化圏の人に不自然な方法は避けたい。もういちど、TrimPath JSTとSmartyを吟味してみるかな。←これは僕のTODO。

rnarna2006/01/13 16:52if文くらいはあると便利だし、paramから値のリストを渡すようなケースでforeachみたいなのがあるといいかも? でもJavaScript動くの前提なので大抵のことはJavaScriptで書けば済むはずですよね。

トラックバック - http://jacal.g.hatena.ne.jp/m-hiyama/20060113

2005-12-12

[]コンポネントクラス定義 事例 18:13

コンポネントクラス定義はあんまり正確に定義してないけど、感じは伝わるだろう。コンポネントFoo.Barに対して、Foo/Bar.jacalがないときは、プロセッサが暗黙に自動生成する(ファイルは作らないが、ファイルがあるかのごとく振る舞う)。その定義は:

<jacal xmlns="http://xmlns.jacal.org/jacal" name="Foo.Bar" />

これじゃなんだかわからないから、もう少し書くと:

<jacal xmlns="http://xmlns.jacal.org/jacal" name="Foo.Bar" >
 <params>
  <param name="#any" />
 </params>
 <resources>
  <libraryScript name="Foo.Bar" />
  <embeddedScript name="Foo.Bar" />
  <libraryStyle name="Foo.Bar" />
  <presentation name="Foo.Bar" />
 </resources>
</jacal>

<resources>の中身をもう少し詳しく書けば:

  <libraryScript name="Foo.Bar" loader="jsan" confirm="true"
    required="false" />  
  <embeddedScript name="Foo.Bar"
    required="false" />
  <libraryStyle name="Foo.Bar" loader="html" confirm="true"
    required="false" />
  <presentation name="Foo.Bar"
    required="false" />

nameの解釈は、iclude pathに依存するが、include pathが"."の場合は次のようになる。

 <libraryScript location="./Foo/Bar.js" confirm="true">
   <libraryScript location="./Foo/Bar.js.jst" confirm="true">
     <libraryScript location="./Foo/Bar.js.jst.xwt" confirm="false" />
   </libraryScript>
 </libraryScript>

Content-Typeみたいな属性とか、TemplateLanguageの指定とか入れてもいいのだけど、とりあえずは拡張子で判断でもいいような気がする。リソースファイル名の最初のピリオドより前の部分がモジュール名に対応し、複数の拡張子を重ねて種別を表す。

  • .js, .css, .html :普通の用法、ただし、.htmlはHTML断片かもしれない。
  • *.emb.* :埋め込みで使う。
  • *.jst : テンプレートファイル。
  • *.xwt : エンコーディングを明示するために、XMLでラップしたテキスト/テンプレート。

include pathをたどって、次々と代替リソースを探すのはそれなりに手間だが、問題になるほどのことはないでしょう。

トラックバック - http://jacal.g.hatena.ne.jp/m-hiyama/20051212

2005-12-08

[]コンポネントクラス定義 confirm, required, フォールバック 15:21

confirm

confirmは次の3つのケースでしか意味がない。

  1. libraryStyleで、locationが指定されているとき
  2. libraryScriptで、locationが指定されているとき
  3. libraryScriptで、loader="jsan"、nameが指定されているとき

その他のケースでは、nameまたはsrcの確認がどうせ必要になる。

上記3つのケースで、cofirm="false"なら、実際のリソースの存在確認をせずに、あたかもそれらのリソースが存在するかのように振る舞う。デフォルトはconfirm="true"で、通常は確認をする。

required

required="true"のとき、当該リソースが存在しないならエラーとする。

required="false"のとき、当該リソースが存在しないなら、特に何もしない(出力に配備しない)。ただし、指定されたコンポネントに対して何一つリソースがないときはエラーとする(がいいと思う)。

フォールバック

リソースタグのネストを使うとフォールバック指定になる。

<libraryScript confirm="true" locatoin="mysty.css" loader="html" />
  <libraryScript confirm="true" locatoin="sty/mysty.css" loader="html" />
   <libraryScript required="true" confirm="true" locatoin="../sty/mysty.css" loader="html" />
  </libraryScript>
</libraryScript>

この場合、mysty.css、sty/mysty.css、../sty/mysty.cssの順で探して、最後の../sty/mysty.cssが見つからない時点で(required="true"なので)エラーとなる。

追記:あっ、「フォールバック」は混乱しそう、代替リソースとかにしよう。

属性のデフォルト値

なるべく属性を指定しなくて済むように決める。

トラックバック - http://jacal.g.hatena.ne.jp/m-hiyama/20051208

2005-12-07

[]コンポネントクラス定義 リソース(まだ部分) 18:03

こんな感じ:

<!ELEMENT resources
 ( libraryScript | embeddedScript
 | libraryStyle  | embeddedStyle 
 | presentation 
 | style | script
 )* 
>

<!ELEMENT script (libraryScript | embeddedScript)* >

<!ELEMENT style (libraryStyle  | embeddedStyle)* >

共通に使う属性は:

  • name : JSANモジュール名(ドット区切り)
  • location : URL文字列(そのままリテラルとして使う)
  • src : URL文字列、このURLを読みにいく。
  • loader : ロード方法を示す名前 (jsan|html|css)
  • confirm :配備時に存在確認するかどうか、ブーリアン。
  • required : 必須かどうか?

library* は出力ファイルから参照されるリソースで、embedded*は出力ファイルに内容が埋め込まれるリソース。

属性の使用法

要素タグ名 name location src loader
libraryScript jsan/html
libraryStyle html/css
embeddedScript
embeddedStyle
presentation
  • nameとlocationは排他的
  • nameとsrcは排他的
  • loader="jsan" 以外のときは、nameの解決はJACALプロセッサの責任
  • locationは属性値文字列をそのまま出力側でも使う。

例:

  • <libraryScript name="Example.Counter" loader="jsan" /> -- JSANによりモジュールをロードする。
  • <libraryScript name="Example.Counter" loader="html" /> -- scriptタグとsrc属性を使う。Example.CounterをURLに直すのはJACALプロセッサ。
  • <libraryScript location="../js/Example/Counter.js" loader="html" /> -- scriptタグとsrc属性を使う。locationはそのまま使う。
  • <libraryStyle location="style/mysty.css" loader="html" /> -- linkタグでスタイルをロードする。
  • <libraryStyle location="style/mysty.css" loader="css" /> -- styleタグと@importでスタイルをロードする。

次の例は、ひとつのscriptタグ内に複数のJSANロードと埋め込み:

<script>
 <libraryScript name="Example.Counter" loader="jsan" />
 <libraryScript name="Example.Selector" loader="jsan" />
 <embeddedScript src="lib/appmain.js" />
</script>

confirmとrequiredの指定と挙動、テンプレート関連はまだ

トラックバック - http://jacal.g.hatena.ne.jp/m-hiyama/20051207

2005-12-02

[仕様メモ」コンポネントクラス定義(部分) 11:01

JACALコンポネントクラスを定義するXML構文。

暫定案、途中まで(未完成)。構文記述にはDTD記法と説明文を用いる。

全体の構造

コンポンネントクラスを定義するファイルはXML形式であり、その名前空間http://xmlns.jacal.org/jacal とする。jacal.orgはドメイン取得済み。全体は次のような構造。

<jacal xmlns="http://xmlns.jacal.org/jacal" name="Component.Name">
 <params>
  <!-- ここにパラメータ記述 -->
 </params>
 <resources>
  <!-- ここにリソース記述 -->
 </resources>
</jacal>

<!ENTITY % Path "CDATA" >

<!ELEMENT jacal (params?, resources?) >
<!ATTLIST jacal
 name %Path; #REQUIRED
>

どのコンストラクトも省略可能で:

  • 属性name : 省略されると、ファイルの置かれた場所とファイル名から推測する。指定されていれば、場所と名前との整合性をチェックする。
  • 要素params : 省略されると、パラメータのチェックは一切行われない。
  • 要素resources : 省略されると、コンポネントクラス名からデフォルトのリソースを推測する。

次は正しい(しかし、実質的な意味がない)定義である。

<jacal xmlns="http://xmlns.jacal.org/jacal" />

パラメータ記述 params

次の構造を持つ。

<!ENTITY % Name "CDATA" >

<!ELEMENT params (param*) >

<!ELEMENT param EMPTY>
<!ATTLIST param
 name %Name; #REQUIRED
 type %Type; #IMPLIED
 required (true|false) "false"
 default CDATA #IMPLIED 
>

例:

<jacal xmlns="http://xmlns.jacal.org/jacal" >
 <params>
  <param name="max" default="1000" />
  <param name="min" default="-1000" />
  <param name="init" required="true" />
  <param name="#other" />
 </params>
</jacal>

params内に記述されたparam達により、コンポネントのパラメータ仕様が決まる。ここに指定された名前(ただし、特殊な名前有り)以外のパラメータの出現は禁止される(エラーとして扱う)。各属性の意味は次のとおり。

  • type : 値のデータ型。別個、型システムを定義する必要がある(型システムは先延ばし)。typeが指定されなくれば、型チェックをしない。
  • required : trueなら必ず指定されなくてはいけない。falseなら省略してもよい。
  • default : デフォルト値。requiredがtrueのときは指定しない。

次の2つの名前は特殊な目的で使う。

  • #any : すべての名前を意味する。name="#any" のparam要素を1個書くと、その他のparam要素は無視される。
  • #other : 指定された具体的な名前以外のすべての名前を意味する。

名前に#any、#otherを指定した場合は、type以外の属性を使えない。

次は、paramsを省略した場合と同じ意味を持つ。

<jacal xmlns="http://xmlns.jacal.org/jacal" >
 <params>
  <param name="#any" />
 </params>
</jacal>

トラックバック - http://jacal.g.hatena.ne.jp/m-hiyama/20051202

2005-11-24

[]onloadハンドラ 13:23

window.onloadは実行環境に1つしかないから、みんなで仲良く共有すべき貴重な資源。もちろん、共有するメカニズムが必要だが、次のような関数を使えば解決できる(ただし、この関数は今書いただけでテストしてない)。

function registerOnload(func) {
 if (window.attachEvent){
  window.attachEvent("onload", func);
 } else if (window.addEventListener){
  window.addEventListener("load", func, false);
 } else {
  throw new Error("Cannot set onload handler");
 }
}

エラーを投げている部分(IEでもMozilla系でもないとき)も、がんばれば対処できる。やることは、ハンドラ関数をチェーンとして繋いで、onloadのときに、このチェーンの関数を順番に呼び出す。

もし、必要ならJACAL.jsとかに、jacal_registerOnloadとかJACAL.registerOnloadとかの名前で関数を用意して、「みんな使ってね」と言えばいいかと。

JACAL.jsのロードも明示的にJSAN使ってもいいし、jacalプロセッサが挿入してもいいし、決めてしまえばあんまり問題にはならないかと。

[]encode 13:26

テンプレート構文に何を使うにしても、次のようにXMLでラップすることを考えていた。

<?xml version="1.0" encoding="Shift_JIS"?>
<template xmlns="http://xmlns.jacal.org/xtw">
 <param name="min" default="0" />
 <body><![CDATA[
  // テンプレート本体
 ]]>
 </body>
</template>

エンコーディングとパラメータ仕様を与えるのが目的だから、bodyを要求せずに、次のようなエエカゲン・マークアップでも許容したい(許容しても問題ない)。

<?xml version="1.0" encoding="Shift_JIS"?>
<template xmlns="http://xmlns.jacal.org/xtw">
 <param name="min" default="0" />
 // いきないテンプレート本体
</template>

強いて内容モデルを書けば、(param* (body|#PCDATA))と許されないモデルとなるが、これが「許されないほうが許されない」と僕は思っている。

rnarna2005/11/25 01:10registerOnload でうまくいけました。タグいじるのはややこしいのでそれでいきます。

トラックバック - http://jacal.g.hatena.ne.jp/m-hiyama/20051124

2005-11-22

[]式の区切り 12:00

http://jacal.g.hatena.ne.jp/rna/20051121/p1 :

JST では ${% {hogehoge} %} みたく書けますが、「%}」を使う式言語があったらどうするのよ? ってことでしょうか。

理屈上ではそういう心配もあるけど、僕がイメージしていたことはちょっと違う。

式の始まりと終わりの区切りを変更できるとして(そうしたほうが便利だと思う)、$(...)を使うとき、$((a + b)*2)から式を切り出すと、(a + bが式評価器に渡ってエラーになる -- これってあまりにもバカっぽいな、と。それと、%}を演算子として含むような式は考えにくいにしても、文字列リテラルでは、どんな文字列も登場可能だし。

まーしかし、使う側が区切りを慎重に選ぶってことでもいいような気もしてきた。

[]マクロ呼び出し 12:01

例えば、<img src="../images/foo.gif" title="image: foo"> の"foo"をパラメータ化したマクロを考えるとして:

{macro image(name)}
 <img src="../images/${name}.gif" title="image: ${name}">
{/macro}

で、マクロ呼び出し構文をどうすべきか?

  1. ${image('foo')} と式言語内の関数呼び出し。
  2. {image name="foo"} とテンプレート言語の文(コマンド)。
  3. <jacal name="image'><param name="name" value="foo"></jacal> とJACALタグ。

JACALタグとして呼び出すのは面白いけど、JavaScript内でマクロ呼び出し使うときは変だわ。

[]入力ファイル名、出力ファイル名(再) 12:03

まとめると:

  1. 入力ファイルをそのままブラウザで黙視確認できたほうがいい。よって、入力ファイルも.htmlか.htm拡張子が多そうだ。
  2. 出力ファイルはもちろん.html拡張子
  3. .htmlと.htmで区別するのは、一般には嫌われそう(檜山はそうしているけど)。
  4. 入力と出力を別ディレクトリに置くべき(かもしれない)。が、それは安直ではない。

jacalコマンド (perl jacal.pl) を使う状況設定がまだ曖昧な気もする。それと、「入力も出力もHTML形式」というのが、ここではアダとなっているなー。普通のコンパイラでは、入力と出力は全然別だから拡張子変わるのが自然だもんな。

と、決定案はまだ出ない。

トラックバック - http://jacal.g.hatena.ne.jp/m-hiyama/20051122

2005-11-19

[]入力ファイル名、出力ファイル名 16:39

入力ファイル名を$JACAL_DOC_BASE/に繋げた形が出力ファイル名らしいけど、カレントディレクトリを$JACAL_DOC_BASE/と同一にして動かすと、常に失敗するのはちょっと困る。なぜなら、$JACAL_INCLUDE_PATHのデフォルトは、.;lib(JSANデフォルト)だから、何の設定もしない状態ではまともに動かないことになる。

入力ファイル名がdir1/dir2/base.extのとき、出力は$JACAL_DOC_BASE/base.htmlがいいと思う。入力が-のときもこのルールに従うか例外扱いするかは微妙だけど。

[]リソースの検索と配備 16:39

HTML断片、JavaScriotコード、スタイルシートのどれか1つでもあれば、いちおう「処理は成功」としたい。ただし、配備処理時点で存在しないリソースは出力に配備(展開)しない。

トラックバック - http://jacal.g.hatena.ne.jp/m-hiyama/20051119

2005-11-18

[]コマンドライン・オプション 10:34

出力をmoreにパイプして見たいときとかあるので、stdoutに出すオプションが欲しい。

"-p"かな。古典的な1文字オプションと --print、--verboseとかの両方が使えたほうがいいね、オプション解析のライブラリってあるでしょ?

--output=filename ってオプションを --output=- って使うってのもあるけど、頻繁に使う割にはメンド過ぎだろう。

[]置換系に関して 10:38

TrimPath JSTは、構文も実装もPHP Smartyの影響を強く受けている。が、PHP→JavaScriptのSmarty移植版というわけではなくて、変更もしている。

僕としては、SmartyにもJSTにも不満があって、かといって新規構文は作りたくないし、、、で悩んでいます。

行きがかり上、それと備忘のために、Smartyについて若干説明しておく: Smartyでのメタ文字(区切り記号)は、「{」と「}」だけで、それらは変数$ldelim、$rdelimで参照できる。$ldelim, $rdelimに別な文字列を代入すればメタ文字を変更できる。(が、PHPコードではなくてテンプレート構文側での変更はないようだ、確信ないけど。)

「{」と「}」は、XMLの「<」「>」に対応していて、一種のタグ構文。{foo attr1="val1" attr2="val2"}...{/foo}と使う。空内容は{foo/}ではなくて、SGML同様メタデータで判断するようだ。Antのカスタム・タスクと同様に、プラグインPHPコードによりSmartyタグ({hoge}のこと)を足せる。ただし、{if}などはタグ的に解釈できない(XMLパラフレーズできない)特殊構文。

プラッガブルである点はいいが、式と文の区別がないところが辛い。で、JSTでは、式と文を区別している。とはいえ、置換主処理と式評価を完全に分離できるかいうと、今のJSTでは難しい。

${式}が出現したとき、置換主処理側で式を切り出そうとすると、式内の'}'に反応してしまう。'}'が式の途中か終わりかを判断するには式言語を知っている必要があるが、それじゃ分離できてない。よって、'${'の残りのストリームを式パーザーに渡す必要があり、そのとき'}'が終端記号であることを式パーザーに知らせる必要もある。

また、JSTにはマクロ機構があるが、マクロ呼び出しが${macroname args}なので、マクロ定義の登録を式処理系の関数定義として行う必要がある。これはそれほど悪いことではないが(置換主処理側で、式処理系の関数定義を叩くだけ)、マクロ文を書けない。文と式を分けたのだから、procedureとfunctionを分ける必要があって、define procedureとdefine functionの構文が必要なんだよね。

JSTでマクロ定義ができる(Smartyではできないみたい)のはいいのだけど、マクロをまとめて外だしできないので、マクロライブラリが作れない。{include 外部ファイル}文があればとりあえずいいのだけど。

SmartyもJSTも、言語処理系の作法がイマイチわかってなかったみたい。僕の希望をまとめると:

  1. 文と式は分けるべき。式パーザー、評価器を主処理から独立にしたいのだ。
  2. 組み込み構文も含めて、プラッガブルなフレームワークで記述できるのが望ましい。
  3. XML構文との類推が効けば、そのほうがいい。(強くは言わない。)
  4. マクロ手続き、マクロ関数が書けるのが望ましい。
  5. メタ文字の変更が、背後のプログラミング言語の助けを借りずにできたほうがいい。

Smartyを尊重しつつ、JSTの兄弟分(似てるが違う)を作るしかないかもしれない。あるいは、別な既存テンプレート構文か(まったく新規はやらない!)。なんばさん、どう思う?

rnarna2005/11/18 12:550.0.1 では -c オプションで標準出力に出力、ファイル名に - を指定すると標準入力から入力、という機能をオマケで入れてあります。

m-hiyamam-hiyama2005/11/18 16:56あらそうだったの、失礼しました。

トラックバック - http://jacal.g.hatena.ne.jp/m-hiyama/20051118

2005-11-17

[]整合的理屈とメンタルモデルは違う:事前にラショネール 18:17

もし、プレゼンテーション部テンプレートの再帰的置換処理を許すなら、トップレベルの入力ファイルもテンプレートと考えるのが自然であり美しい。となると、入力ファイルと(コンポネントのリソースである)プレゼンテーション・テンプレートは同じ構文でもよいことになる。

いや待て! 入力ファイルもコンポネントも同じテンプレート構文でホントにいいのか?

入力ファイルは普通のHTMLページ作成者が書き、コンポネントはより専門性が高い人間が書く(そう想定している)。ふつうの人が書く入力ファイルに、制御構造や変数/式(${...})が入るのは変じゃなか。入力ファイルもテンプレートだと考えると、「単なる(plain old)HTML」から離れてしまう。

入力に含まれるJACALタグは、機能/使い方としてはobjectタグに近い。objectタグ類似なら、構文的にも心理的にもそれほどの違和感はないだろうと思う。それと、objectタグ類似のカスタムタグしか含まれないなら、入力ファイルをそのままブラウザで視認チェックできるし。

つまり、入力ファイルにもテンプレート構文を許すのは、理屈の上では何ら問題はないし、むしろ整合的だ。だがしかし、利用者=入力ファイルを書く人の素朴なメンタルモデルを裏切るので採用できない。実際の運用がどうであれ、設計の前提は、「入力ファイルは人が直<じか>に手書きする」です。

※ Webフレームワークの一部として使うなら話が違うが、それは想定したプライマリな使い方ではない。

トラックバック - http://jacal.g.hatena.ne.jp/m-hiyama/20051117

2005-11-11

[]エラーの認識と修正(修復)の問題 12:39

http://jacal.g.hatena.ne.jp/rna/20051107/p1

何をどういうエラーにするか(現状は予期しない入力には予期しない出力が。。。)

もう少し予期できたほうがいいと思います。

次の例を入力としてみましたが、なにが/だれが悪いのかわかりません。このような入力がうれしくないなら、「悪いのはアンタ」と言ってくれたほうがいいか、と。※でも、エラー処理は解析のなかでも一番わずらわしい部分だから、後回しでもいいけどね。

<jacal name="hoge" ></jacal>

<body>
<jacal name="hoge" ></jacal>

<head>
<jacal name="hoge" ></jacal>

<html>
<jacal name="hoge" ></jacal>

<body>
<jacal name="hoge" >

<body>
<jacal ></jacal>

<body>
<jacal name="hoge" >
<param name="foo" value="123" >

<body>
<jacal name="hoge" >
<param name="foo" >
</jacal>

<body>
<jacal name="hoge" >
<param name="foo" ></param>
</jacal>

<body>
<jacal name="hoge" >
<param name="foo" value="123">
</body>

課題:OldHTMLとしては許されるがXHTML的に好ましくない入力に対して、それを修正することは 親切な行為か余計なお世話か? -- これは、政治的(あるいは宗教的)価値観の問題になってしまうかもしれないなー。

僕としては、入力はできるだけ寛容にしたいが、出力はキチンとしたXHTMLがいいと思う。だが、タグコーディングを勝手にいじられるのをいやがる人もいるかもしれない。なまじ政治的/宗教的判断をするよりは、実装の手間だけで判断したほうがいいような気もする。

トラックバック - http://jacal.g.hatena.ne.jp/m-hiyama/20051111

2005-11-10

[]JACALの全体像(ラフな説明) 09:11

以下では、JACALプロセッサの構造と動作を説明するが、実装を問題にしているわけではなくて、これを通じてJACALの全体像を伝えるのが目的。だが、とてもラフだし、例もない。 (これじゃ解説にならんか?)

JACAL文書」「JACAL断片」という言葉を使うが、これは仮称。いい言葉があれば取り替えるつもり。

JACALプロセッサは、だいたい次のような部分からなる。

  1. JACAL文書パーザー
  2. JACAL断片パーザー
  3. JACAL要素プロセッサ
  4. テンプレート置換系
  5. 式評価器
  6. その他(バックエンド)

これらをざっと説明する。

JACAL文書パーザーJACAL断片パーザーはほとんど同じものだが、文書パーザーはHTML文書全体の構造を知っている。例えば、headとbodyの知識を持っている。一方、断片とは単なるwell-balancedなタグ(HTMLタグ+JACALタグ)付きテキストであるから、断片パーザーは文書全体の構造を意識する必要はない。(断片にbodyタグは禁止したほうがよさそう。)

まず入力ファイルが文書パーザーで解析される。文書内のJACAL要素は要素プロセッサで処理されるが、そのとき、断片パーザーが呼び出されることになる。断片パーザーは、外部HTML断片またはフォールバックの処理に使われる。

外部HTML断片とフォールバック部は、ほとんど同じように扱われる。リソースが文書の外に存在するか文書に埋め込まれているかの違いがあるだけといってよい。(もちろん、フォールバックは外部HTML断片読み込みに失敗したときに行われるが。)

JACAL要素プロセッサは、次のことを行う。

  1. JACAL要素の内部を解析する。
  2. パラメータからコンテキストオブジェクトを作る。
  3. コンポネントクラス名から必要なリソースを探す(ことをバックエンドに依頼する)。
  4. 必要ならコンテキストオブジェクトを渡してリソースを読み込む。
  5. リソースの読み込みに成功したら、適切な位置に配備する。
  6. リソースの読み込みに失敗したら、フォールバックを処理する。

読み込んだ外部リソースやフォールバック内に再びJACAL要素があれば、処理は再帰的に行われる。

テンプレート置換系式評価器は、テンプレートリソースを読み込むとき、コンテキストを参照しながら置換を行う。ファイルIO機能に含まれるのでバックエンドの一部と考えてもよい。テンプレート置換は、要素プロセッサから渡されたコンテキストをもとに行われる。

その他(バックエンド)は、JSAN/JACALリポジトリと、そこに格納されているコンポネントリソースを探したり、読み込んだりする部分である。リポジトリ/リソースを抽象化するIOサブシステムといえる。

トラックバック - http://jacal.g.hatena.ne.jp/m-hiyama/20051110

2005-11-09

[][]入力ファイル 13:36

JACALプロセッサへの入力をなんと呼ぶか? あー、思いつかん。

JACAL文書? これだと独自形式みたいで「ほとんどHTMLである」という特徴が隠れる気がする。JACAL拡張HTML文書? 正確な表現だが長すぎる。JACAL HTML文書? 拡張HTML文書? いまいち。

拡張子も問題だ。ズボラな僕は、入力も.htmlでいいという気がするのだが、JACAL_DOC_BASE=. の状態だと、foo.htmlの出力先もfoo.htmlになって上書きされてしまう。.jhtmlとかだと、入力を直接ブラウザで見るときに不便。

僕自身は、.htmlと.htmを使ってこのての問題を回避しているが、一般的とは思えないし、.htmを嫌う人もいそうだし。

トラックバック - http://jacal.g.hatena.ne.jp/m-hiyama/20051109

2005-11-08

[]悩みどころ 09:24

http://jacal.g.hatena.ne.jp/rna/20051107/p1

悩みどころ:

何をどういうエラーにするか(現状は予期しない入力には予期しない出力が。。。)

これは本質的に難しいので、最初から考え込んでもラチがあかないと思います。

イベント駆動型APIの上にストレートに書き殴ってるのでソースがかなり読みにくい。

それは知らん。

[]jacalとobject 17:39

JACALタグは、構文もセマンティクス(というよりメンタルモデル)もobjectに似せている。メリットは当然に、学習負担と心理的障壁の軽減だ(0-learning, 0-training)。

が、objectとjacalがいくらでも再帰的に出現できることになってしまった。

  1. jacalのparam内に、jacalもobjectも出現可能。
  2. jacalのフォールバック内に、jacalもobjectも出現可能。
  3. objectのフォールバック内に、jacalもobjectも出現可能。
  4. 外部リソース(HTML断片)に、jacalもobjectも出現可能。

多くのケースでは、フラットか浅いネストだろうが、作為的にやれば、異常に深く複雑なネストも作れる。が、パラメータやフォールバックを導入すればそれは必然だから、しょうがないっすね。

トラックバック - http://jacal.g.hatena.ne.jp/m-hiyama/20051108