2005年 10月 23日

ruby-xslt 0.8.2

新しくなっているのに気付いた。 ruby extconf.rb --enable-error-handler (off by default) とか書いてあるのでちょっと期待しつつ。

とりあえず cygwin で make できんので Makefile 修正。OBJS に /lib/libxml2.dll.a /lib/libxslt.dll.a を追加して強制リンキング。exslt ははずす。

いろいろやってみたんだけど、よくわからん。USE_ERROR_HANDLERXML::XSLT.errors が定義されるんだけどエラー起こしても特に何も入ってない。/* this is really quite inelegant */ とか書いてあって苦労してんなぁとかなんとか。

とりあえずさらに really quite inelegant なコードで解決を図る。Ruby 側で…

require '../xslt'
xslt = XML::XSLT.new
xslt.xmlfile = "fuzface.xml"
xslt.xslfile = "fuzface.xsl"
begin
err = STDERR.dup
pipe = IO.pipe
STDERR.reopen(pipe[1])
out = xslt.serve # raise RuntimeError
rescue RuntimeError => e
p XML::XSLT.errors #=> []
if e.message =~ /^(XSL|XML|Stylesheet) /
p e
p pipe[0].readpartial(4096) #=> エラーメッセージ
else
raise
end
ensure
STDERR.reopen(err)
end
__END__
起こりうるエラーたち (grep)
parser.c:53:      rb_raise( rb_eRuntimeError, "XSL parsing error" );
parser.c:59:      rb_raise( rb_eRuntimeError, "XSL Stylesheet parsing error" );
parser.c:65:      rb_raise( rb_eRuntimeError, "XSL Stylesheet parsing error" );
parser.c:84:      rb_raise( rb_eRuntimeError, "XML parsing error" );
parser.c:90:      rb_raise( rb_eRuntimeError, "XML parsing error" );
parser.c:97:      rb_raise( rb_eRuntimeError, "Stylesheet transformation error" );

tests/fuzface.rb の改造。xmlfile= は使うなという警告がでるけどとりあえず放置。$stderr じゃなくて STDERR にメッセージを吐くらしくめんどっちいことをやってる。readpartial は cygwin の ruby が 1.8.3 になったから使ってみた。便利よねコレ

ごちゃごちゃやってみたけど使わない。XREA に入れるのめんどいし……

これでドウダ

class XML::XSLT
class XSLTError < StandardError; end
class XSLParsingError < XSLTError; end
class XSLStylesheetParsingError < XSLTError; end
class XMLParsingError < XSLTError; end
class StylesheetTransformationError < XSLTError; end
alias __org__serve serve
def serve
ret = nil
err = STDERR.dup
pipe = IO.pipe
Thread.critical = true
STDERR.reopen(pipe[1])
begin
ret = __org__serve
rescue RuntimeError => e
STDERR.reopen(err)
Thread.critical = false
message = pipe[0].sysread(4096)
error_class = XSLTError
case e.message
when "XSL parsing error"
error_class = XSLParsingError
when "XSL Stylesheet parsing error"
error_class = XSLStylesheetParsingError
when "XML parsing error"
error_class = XMLParsingError
when "Stylesheet transformation error"
error_class = StylesheetTransformationError
end
raise error_class.new(message)
ensure
STDERR.reopen(err)
Thread.critical = false
end
ret
end
end
xslt = XML::XSLT.new
xslt.xmlfile = "fuzface.xml"
xslt.xslfile = "fuzface.xsl"
begin
xslt.serve
rescue XML::XSLT::XSLTError => e
p e
end

将来完璧な実装になっても消すだけ! これなら使えそう? ごめん嘘。エラークラス云々があるのでそのままじゃ無理。

ruby-xslt on XREA

make がうまくいったっぽいのでメモ。ちなみに数度要望の末 ruby-xslt を入れてもらってある (この過程で別の鯖と違う点があるかもしれない)。でもやっぱり自分でビルドできないかなぁという試行。

#!/bin/sh
PATH="/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:$PATH"
export PATH
ruby extconf.rb #1
#make #2
# test
#cd tests
#ruby fuzface.rb

みたいなのを make.sh として作って保存しとく。ちなみに AddHandler cgi-script-debug .sh してある。念のため一発でやらずに一行ずつ実行させる。

ruby extconf.rb は Permission Denied がでつつも一応通るので問題なしということにしとく。んで、make なんだけど libxml/* が見つからないとかいわれる。しかたないのでローカルの /usr/include/libxml2/libxml を同じディレクトリに転送する。エラー一切なく make が通った。テストもしてみたけど大丈夫っぽい。微妙だけど。

関係ないけど XREA に拡張ライブラリ置くとき怪しいことをすることにした。/virtual/username/lib/ruby/RUBY_PLATFORM を掘ってその中に入れる。ローカルは cygwin なので /virtual/username/lib/ruby/i386-cygwin/xml/xslt.so、XREA は /virtual/username/lib/ruby/i686-linux/xml/xslt.so。んで使う場合は $LOAD_PATH.unshift("/virtual/lowreal/lib/ruby", "/virtual/lowreal/lib/ruby/#{RUBY_PLATFORM}") しとく。もともと XREA 上の RSS パーサが古いのでアレしてコレした感じ。

s63.xrea.com 上で作った xslt.so。ちゃんと動くかは知らない。

ちなみに上のセクションのスクリプトは動かないです。1.8.2 なので。readpartial を sysread にすればとりあえず動きます。どっちでもよさげだから sysread にしとくのが吉か。

2005年 10月 22日

やる気あるんだかないんだか

IE で表示崩れていることには気付きつつ、あの例のリンクホバーで margin だか padding だかがぶっとぶバグなわけで、解決方法をバグリストから探して云々ってのがめんどくさくてめんどくさくて……

仕方ないから新しくスクラッチから書き直すか、とか思ってみたりもするんだけど、いやそれむしろもっと面倒くさくなっているよとも思うわけでして、あーしかしそろそろ今の CSS 飽きたなぁとか、なんかグッっとくるテーマが欲しいなぁなんて。なにがグッっとくるんだよって話だけど。

2005年 10月 20日

site-script.js の整理

とりあえず似非 require を使うことに。ミニ JSAN みたいな実装にしといた。変数のリストを取得できないからこれ以外方法がなさげ。まぁ必要なオブジェクトを明示できるから悪いとはいえないんだけど。

function require(__path, __exports) {
if (!__exports) __exports = [];
var __code = (require.LOADED_FEATURES[__path]) ? require.LOADED_FEATURES[__path] : HTTP.get(__path);
(function () {
with (Global) {
eval(__code);
}
for (var __i = 0, __len = __exports.length; __i < __len; __i++) {
Global[__exports[__i]] = eval(__exports[__i]);
}
})();
require.LOADED_FEATURES[__path] = __code;
return true;
}
require.LOADED_FEATURES = {};
require("/ruby.js");
require("/xb.js",   ["document_addEventListener", "document_removeEventListener"]);
require("/dom.js",  ["getElementsByAttribute", "getElementsByClassName"]);
require("/mm.js",   ["MetadataManipulator"]);
require("/code.js", ["markupCode"]);
require("/util.js", ["MessageArea", "ProgressBar", "AccessibilityOption"]);

余計なことをしても使わないので、できるだけ短くすることにした。"Obj.prop" みたいなのも渡せるようにしたやつも書いてみたけど思ったより長くなったので却下した。

HTTP.get とか書いてるけどこれより前にそういうのを書いてある。

さっき気付いたんだけど IE で表示崩れるよね。なんか直す気力がないから放置するよ。別に読めないわけじゃないし。それにともなって MM のテストをいったん廃止

2005年 10月 19日

Javascript で require もどき・eval の実行コンテキスト

Javascript はファイル間の依存関係を一切書けない。ロードする順番は結局 script 要素の出現順、つまり HTML 依存。どう考えても気持ち悪い。のでどうにかして require もどきを作りたい。

function createXMLHttpRequest() {
return this.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
}
var __LOADED_FEATURES = {};
var Global = this; // this == window == Global
function require(lib) {
if (__LOADED_FEATURES[lib]) return false;
var req = createXMLHttpRequest();
req.open("GET", lib, false); // 同期
req.send(null);
if (req.status == 200) {
// IE ではグローバルコンテキストで実行してくれない。
Global.eval(req.responseText);
__LOADED_FEATURES[lib] = true;
} else {
throw Error("Load Error");
}
return true;
}
require("/ruby.js");
require("/mm.js");

Global という名前のオブジェクトが宣言されてなかったりするので強調をこめて宣言してある。それ以上の意味はないです。window.eval でも問題なし。見たとおり XMLHttpRequest を使って取得し、eval させてみる。

これは Firefox 1.0.7と Opera 8 ではうまくいくけど、IE 6 ではうまくいかない。

IE の場合 eval する部分のコンテキストが変わってくれない。つまり mm.js に var MottoMottoMeidosan = function () { .. } とかいう宣言があったとき、require 関数の変数オブジェクトに代入されやがるので、require のあとに new MottoMottoMeidosan() とか書くと「そんな変数宣言されてません」と怒られる。

解決法なんですが、さっぱりわかりません。誰か助けて。

なんだったら .php にでもして include() でもいいんだろうけど、これは完全に負けだよね(謎

卑怯な解決方法1を発見した。

eval(req.responseText.replace(/^var/g, ""));

インデント依存っていうか副作用がどれだけあるか不明すぎ。

JSAN つかえよバーカ。

JSAN はそもそもグローバルスコープで eval することなんて考えてない。指定したオブジェクトだけグローバルスコープに登録してる。つまり基本的に一個のファイルで一つの固まりしかロードできない。use は必要なのをグローバルスコープに登録するらしい。 DOM 定数とかをグローバルスコープに登録するなら全部 use/export の引数に書けってことなのか?

なんか素晴らしすぎて使いづらいなぁ。特定ファイルを単純にロードしたい。とくにディレクトリ構造を要求するのがなんともいえない。

疑問なんだけど JSAN は 291 行ものコードを最初から書いておけっていうだろうか?

script 要素二つ書けっていうんだったら目的が違うな。モジュールシステムが欲しいんじゃないし。

続きを書いた。

2005年 10月 17日

MetadataManipulator

icho にデフォルトで搭載される予定らしい MetadataManipulator について。

とりあえず基本的に icho に依存しないので自分のサイトで実験することにする。Javascript 入れていれば左上になんか出てるはず。たぶん。

どこまで決めうちしていいか考え中なので、いまのところ MetadataManipulator 自体はソース生成しかやってない。ピョコピョコさせたり、CSS 的に欲しい要素を補完するのも外側。

link 要素の出現順に何も考えずにソース生成すると CSS が適用しずらいのでいくつか MetadataManipulator の外側で修正してある。内側に入れるか悩む。入れるんだろうけどどうやって入れるか悩む。

  1. あんまり役に立たない。next, prev はいいけど……
  2. in-page heading が役に立ちそうだけどうまいことナビゲーション生成するのがめんどい。汎用性云々。ながったらしいし。h2 だけ抽出とかにすればいいのか。
  3. 実装が定まらない。クラスっぽくするかモジュールっぽくするか。
  4. マルチリンガルじゃない。"in-page heading" っていう文字列を埋め込んでる。"ja-jp,ja;q=0.8,en-us;q=0.5,en;q=0.3" とかいう文字列を優先順位高い順に配列に突っ込む関数は書いたけど、どの時点で実行するか迷う。
  5. あんまりときめかない。

# IECSS の問題があるけど本質じゃないのでとりあえず放置

var mmul = document.getElementById("MetadataManipulator-Local-RelatedLinks-Dd").childNodes[0];
var fill = function (linkName) {
var ret = getElementsByClassName("MetadataManipulator-" + linkName, "li", mmul);
if (ret.length < 1) {
ret = document.createElement("li");
ret.className = "MetadataManipulator-" + linkName;
ret.appendChild(document.createTextNode(linkName));
} else {
ret = ret[0].parentNode.removeChild(ret[0]);
}
return ret;
}
// 順番を保証・これ以外の rel は copyright の次以降に。
var standard_link_rel = ["start", "prev", "next", "contents", "index", "glossary", "help", "copyright"];
var links = {};
standard_link_rel.each (function (i) {
links[i] = fill(i);
});
standard_link_rel.eachWithIndex (function (i, index) {
mmul.insertBefore(links[i], mmul.childNodes[0+index]);
});
with (mmul.parentNode) {
style.left = "-201px";
if (document.all && document.attachEvent) mmul.parentNode.addEventListener    = document_addEventListener;
addEventListener("mouseover", function (e) {
style.left = "0px";
}, true);
addEventListener("mouseout", function (e) {
style.left = "-201px";
}, true);
}

ながったらしい CSS との組み合わせです。see base.css

alt=""

alt="" になるような画像の存在意義がわからない。飾りとかは CSS の範疇だろうし、他に何かあったかなぁ……

2005年 10月 15日

アクセス解析で得る解像度の悪夢

あれってブラウザの表示領域のサイズじゃないんだよね。最近は 1280x1024 な解像度のモニタが多いけど、最大化してみてるやつなんて何割もいない気がする (あくまで想像)。だからアクセス解析で見られる解像度の割合なんて殆どあてにならないし、ましてはそれを参考にして 1280x1024 に最適化しました☆なんてやっちゃだめだ。なんの意味もない。

俺の場合表示領域を 900x600 ぐらいにして見ていることが多い。サイドバーを常時表示しているし、背面にある IRC クライアントを見たいのでこんな感じに。横幅広すぎると読みにくいしね。だから 1280x1024 推奨とか書いちゃってるページはよく横スクロールを求められる。やれやれ

あ、そもそも勘違いの可能性が。

っていうか RSS で読んでるサイトのトピックに「最適化しました☆」ってのがあったからなんとなく書いてみたんだけど、RSS で読んでるんだから関係ないな。頭おかしい

2005年 10月 11日

www.bumpofchicken.com

少し前にまた少しデザインが変わってたのは知っていたのだけど、ふと今日になって「 HTML ソースがまともな気がする」と俺の近くを浮遊している妖精さんが言ってきたので見てみたら、なんか普通によかった。

accesskey やら title 属性を活用しているし、CSS を切ると必要以上の画像はなし。デザイン的なものはちゃんと CSS に分離されてた。定義リスト使ったほうがよさげな部分があったりするけど普通的には関係ないところだろうなぁ。だがしかし、CSS ファイルの書き方は汚かった(謎

PLAN DE SENS っていう会社がデザインしているようだけど、コーディングもやってるんだろうか。謎だ。同じ会社の別のサイトを見てみたけど DreamWeaver で作られたと思わしき似非 HTML 4.01 なサイトばっかりだし、そもそも会社自体のページは Flash のみだし……

割とよく見る一般サイトがこういう風になってると感動しちゃうね。Valid であるぐらいはほんとは当たり前なのにね。

マイナーアーティストのウェブサイトとか作りたいなぁ。なんかこうかっこいいじゃん。

Last.fm webservice

Audioscrobbler.net Web Services

気が付けばちゃんと profile 系のデータも提供されるように。でもさー、なんで Unix Time Stamp なんか出力するかなぁ。もったいない。ちょーもったいない。これのせいで直接 XSLT に入れても日付表示できん。いやできるの? 計算すればできるの? どんだけ面倒くさいの?

なんか微妙にズレてんなー。

どうでもいいけど Last.fm の tag 機能はいまいち使いづらいよっていつも思う。

あ、あと名前空間はつけて欲しいって思った。