2011年3月29日火曜日

e4x@Rhinoで名前空間の付いた属性とか雑多なこと

e4xネタです。 Rhino 1.7R2 で名前空間付きの属性を変更しようとしてハマったので調べてみました。

ブログでいっぺんに書くにはダラダラしたコードなので分断して書きます。 テストコード全体は下の方に載せます。 まずはコードの先頭。

var x =
<root xmlns:xlink="http://www.w3.org/1999/xlink" dummy="d">
    <elem id='i0' test_attr='t'/>
    <elem id='i1' test_attr=''/>
    <elem id='i2'/>
    <elem id='i3' xlink:href="#i0"/>
    <elem id='i4' xlink:href="#i1"/>
    <elem id='i5' xlink:href="#i2"><child_elem/></elem>
</root>;

var xlink = new Namespace('http://www.w3.org/1999/xlink');
var i, elem, elems, attr, attrs, str;

e4xでハイフンつきの属性をリストアップ

e4xでハイフンつきの属性にアクセスする方法です。

普通の属性は@を使えば簡単なコードでアクセスできます。 svgという変数にxmlオブジェクトが代入されてるとして、

var elems = svg..@id;

とすると属性idのリストが得られます。 しかし、「clip-path」のように属性名にハイフンが入っている場合、ハイフンがマイナス演算子扱いされるのでそのままコードに書けません。 e4xでこのような属性にアクセスする場合は次のように書きます。

var elems = svg..@['clip-path'];

これは、シンタックスシュガーなのかな? e4xはコードを書くときに便利なように色々なシンタックスシュガーがあるようですが、それが原因でごちゃごちゃになってる部分もありますよね。

e4xでXMLListの連結

足し算記号(+)でXMLListの連結が出来るようです。 例えば、svgという変数にxmlオブジェクトが代入されてるとして、

var elems1 = svg..rect;
for(var i in elems1)
{
    ~ (1) elems1[i]への処理 ~
}
var elems2 = svg..path;
for(var j in elems2)
{
    ~ (2) elems2[j]への処理 ~
}

(1)と(2)は同じ事やってんだ~、って時には次のように書けます。

var elems = svg..rect + svg..path;
for(var i in elems)
{
    ~ elems[i]への処理 ~
}

仕様の日本語訳を見れば書いてあったけど、e4xの仕様って読みにくいんですよね。 別口で今日気づきました。 まぁ、プログラム言語の仕様なんてあんまり読んだことないんですけど...

e4xの詳細なリファレンスとかもまだ見つけてないし、どうしたもんでしょ?

2011年3月27日日曜日

google chromeのインラインSVGがちょっと改善してた

しばらく見ないうちに、google chromeで自分が描いたsvgのインライン画像が表示できるようになってました。

以前、「インラインだとtransformが上手く働いていない」と書きましたが、それは改善されてました。 パターンにも対応済み、クリップにも対応済みでした。 マスクはまだおかしいところがありますが、基本的な使い方は出来るようです。

マスクのおかしいところと言うのは「transformでマスクの位置がズレるケースがある」という点です。 svgを描いたあとにサイズや余白の調整でtransformを追加するとズレてしまうかもしれないのです。 でもズレないこともあったり、謎な状況ですね。 現状、svgで絵を描くときは、できるだけ早いうちにサイズや構図を決めた方が良いみたいです。

マスクに限らず、自分が描いたsvgが色んなブラウザで正常に表示できるかどうかはやってみないと分かりません。 svgはまだまだ主要なブラウザでサポートされ始めたばかりの状況ですから。 しばらくは色んなブラウザで表示してみて、表示できるようなら公開、出来ないようなら修正or断念orやっぱりそのまま公開ってするしかなさそうです。 そのまま公開の時は注釈書いた方が親切かも。

それにしても、インラインでは表示できなくてもsvgファイル単体では表示できたり...はぁ。

まぁ、chromeのマスクについては他の要素と同じようにちょっとずつジワジワと改善さるでしょう。 マスクの完全対応にも期待。

2011年3月26日土曜日

inkscapeのフィル/スウォッチは少しだけファイルサイズの無駄

inkscapeにあるよく分からない塗りつぶし方~スウォッチ。 調べてみると、色を登録しておいてリスト選択で選べるようにするためのものらしいです。 ペイント系ソフトのパレットのように使うらしい。

xmlエディタでdefsを見ると、その正体はstopが1つしかないlinearGradientでした。 それに fill:url(#id) のリンクを張ることで同じ色を選べるという仕掛けです。

と、いうわけでスウォッチを使うたびにdefsにlinearGradientが追加されます。 そのオブジェクトで最初にスウォッチをクリックしたときにとりあえずのlinearGradientが追加されます。 そのためsvgファイルのサイズは肥大。 一応、「Defのバキューム」で消せる...と思ったら消えませんね。 このコマンドは何に効いて何に効かないか良く分からないです。 まぁ、効くときもあるんでしょう。 ファイルサイズにこだわるならスウォッチは使わない方が無難です。

javascriptの正規表現 globalマッチしたもの全部に処理

Rhino用だとこんなコードになるらしい。

// 角括弧[]の中身を取り出す(数字があった場合)
var text = 'a[0]bc[1]de[]fg[2][3]hij[4]klmn[';
var r = new RegExp(/\[(\d+)\]/g);
var m;

while( (m = r.exec(text) ) != null)
{
    print('m[1] = ' + m[1] );
}

結果は、

m[1] = 0
m[1] = 1
m[1] = 2
m[1] = 3
m[1] = 4

globalマッチのときは '文字列'.match(/正規表現/g) をするとマッチした部分全体の文字列が入った配列が帰ります。 カッコ内の取り出しはできないっぽい?

2011年3月24日木曜日

Rhinoでテキストファイル出力

Rhinoでファイル出力をするときは、javaのクラスを使います。 javaのクラスの使い方はRhinoのオフィシャルサイトの説明の通りです。 javaで書くときと同じようなコードになります。 簡単なコードですが、実際にファイル出力をするサンプルがネットで見つからなかったので書いてみました。

var file_name = "dummy_dir";
var out;
try
{
    out = new java.io.PrintWriter(file_name);
    out.println("test 日本語");
}
catch(exc)
{
    print('ファイル出力エラー');
}
finally
{
    if(out != null)
    {
        out.close();
    }
}

file_nameがdummy_dirになっているのは例外のcatchを確認するためです。 「普通に出力」と「あらかじめディレクトリdummy_dirを作って実行 → ファイル作成失敗 → 例外発生を確認」の両方をやってみました。 どちらも普通に処理されました。

PrintWriterのcloseは例外発生の可能性があります。 javaだとcloseもtry~catchで囲む必要アリ。 ですがまぁ、「javascriptでコードを書く場合は雑になるのが普通だろう」ってことでこのコードでは割愛しました。

firefox4がリリース

firefox4がリリースされました。 とりあえずインストール。 オフィシャルサイトの「ガイドツアーfirefoxを使いこなそう」を見るとブラウザ全体が激重に。 ちょっと不安になりましたが、いつも見てるページをまわってみたらそちらは大丈夫でした。 動画が埋め込まれているサイトだけ重くなるのかな? firefox3.6のままこのページを見たらどうだったんでしょうね。

アドオンで使えなくなったのは1つだけでした。 あまり使ってないヤツだけ。 以前のバージョンアップのときはTab Mix plusをはじめ有用なアドオンが使えなくなって困りました。 今回はそういうことが無くて一安心。

で、ステータスバーが無くなったため今までステータスバーに表示されていたアドオンのアイコンがナビゲーションツールバーに移動。 NoScriptのアイコンもそっちに移りました。 クリックしてみるとメニューの順番が上下逆に。

「一時的に許可」と「恒久的に許可」がステータスバーに表示されていたときと逆の順番になっています。 セキュリティ関係のソフトでそれはないでしょう。 私の場合は先に気づいたからよかったけど、知らない人はちょっと見るだけのサイトで「一時的に許可」したつもりで「恒久的に許可」になってしまうこともありえます。 ちょっとワキが甘いですね。

最後に、インラインSVGがちゃんと表示されるかチェック。 以前に自分で描いた絵を見てみました。

大丈夫みたいですね。 今まで自分で投稿しておきながら表示確認してなかったので気になってました。 表示が確認できてよかった。

2011年3月19日土曜日

フリーメールの取得

使い捨てのメールアカウントがいるかもしれないということで、フリーメールのアカウントをいくつかとってみました。

・Yahooメール

他のメールアカウントが必要。 定番。

・エキサイトメール

他のメールアドレスは不要!? ウェブにさえ接続できればアカウントが取れる。

・Gmail

googleアカウント取得時に携帯電話の番号を聞かれました。 ロボットではないことの確認のためらしい。 使い捨てのメールアカウントを得るために使うのは不向き。

こんな感じでした。

医者と薬剤師に震災の話をするときは注意

この前通院したときの話。 医者に「震災の報道をずっと見てたら気分が落ち込みます」などと言ったら渋い反応でした。 話題にしない方がよかったかもしれません。

よく考えたら、医大生は数少ない医大に全国から集まって、就職するときに全国に散るんですよね。 医者は他の職業より同期に被災者がいる可能性は高いのかも。 かかった医者がそうだったかどうかは分かりませんが、どちらにしても医者に震災の話をするのは避けた方が良さそうです。

通院の帰りに寄った薬局の薬剤師さんも少し疲れがたまってそうでした。 職業が薬剤師の人もそうか...

確認するわけにはいかない話ですね。 とにかく注意で。

2011年3月18日金曜日

カップ麺と缶詰が品薄

今日、床屋に行ったら理容師さんとこんな話になりました。

理容師 「スーパーのカップ麺がすっかり売り切れてるみたいですね。」

私 「そうなんですか? 我が家の近くのスーパーは普段どおりですが...」

被災地じゃないので買いだめに走る人はあまりいないと思ってました。 しかし帰りに自宅近くのスーパー(普段行っていない少し高い店)に寄ると、カップ麺の棚は8割くらい売れてしまってガラガラの状態。 2~3日前に別のスーパーを見たときは普通の品揃えだったのに。 ニュースを見て買いだめした人が多かったのかな? やはり地震の影響は避けられないみたいです。 結果的にウソをついたことになってしまった。 スミマセン、理容師さん。

2011年3月13日日曜日

Rhinoのフィルタ演算は正規表現じゃなくても良かった

特定の属性を持った要素を取り出すコードを検索すると次のように正規表現を使ったものが多く見つかります。

// test3.js 例1
var x = <root>
    <link ref="#ref0">section 0</link>
    <link ref="http://dummy.jp/dummy.html#ref1">Outer section 1</link>
    <link ref="#ref2">section 2</link>
</root>;

var elems = x.link.(@ref.match(/^#.*/) );
for(var i in elems)
{
    var elem = elems[i]
    print('link to "' + elem + '" ... ' + elem.@ref);
}

結果は、

D:\~\rhino1_7R2>java -jar js.jar -w -strict -encoding utf-8 test3.js
link to "section 0" ... #ref0
link to "section 2" ... #ref2

これ、正規表現じゃなくても普通の文字列比較関数でもいいみたいです。 例えばこんなコードでも同じ結果になります。

テレビの地震特番

テレビをつけると、地震の特番が続いています。 民法の番組を見ると右上にずっと「死者不明者??人」と表示されています。 これは止めるべきではないでしょうか?

選挙特番のときは開票速報を競うように表示して批判が上がっていました。 死者不明者に関する表示はそれとは比べ物にならないくらい品がないです。

通常の番組を放送し始めた局もありました。 地震特番の時はCMが中止になっていたのですが、CMも復活です。 そのほとんどがAC、公共広告機構のものでした。

下手なCMを流せない今、妥当なところかな? と思ったら保険会社のCMが混ざってました。 何を考えているのでしょう?

2011年3月8日火曜日

今使っているブラウザでsvgの内部スタイルシートが表示されるか?

たまに描くsvg、inkscapeで編集することが多いです。 inkscapeはスタイル情報を全てインラインスタイルで保持してしまいます。 内部スタイルシートっていう仕様があるのは知ってましたが、今使っているブラウザでそれが表示されるか試した事がありませんでした。 ってことで試してみました。

svgのコードは手入力でこんなのを用意。

2011年3月7日月曜日

Rhinoで標準出力と標準エラー出力

Rhinoで標準出力と標準エラー出力を使う方法。 ちょっと試しただけなので確認不足かもしれませんが、一応投稿です。 javascriptだけでは出力できないのでjavaのクラスを使用します。 Rhinoがjava上で動いているからできるらしい。 次のようなコードで動きました。

var con_err = java.lang.System.err;
con_err.println('標準エラー出力テスト');
con_err.flush();

検索「Rhino 標準出力」で探すとStream系クラスでラッピングしているサンプルコードがあったけど、ラッピングは不要です。 なのでimportPackageも不要。 標準入力は試してません。 そっちもラッピング不要なんでしょうか? 使う当てがないから試しませんけどね。

上の例ではSystem.errオブジェクトを適当な変数に代入して使ってます。 毎回「java.lang~」と書くなら代入は不要です。

java.lang.System.out.println('標準出力テスト');

flushは無くても大丈夫でした。 でもそれは環境によって違うかもしれません。 色んな環境で使うコードではflushしておいた方が良さそうな気配です。

2011年3月5日土曜日

e4xのXML.prototypeは変更できないらしい

今日もポチポチとRhinoでxmlを読むコードを試してました。 どうやらe4xには「要素.hasChildNodes()」のメソッドが無いようですね。 代わりにこんな感じでいいのかな?

if(0 < 要素.*.length() )
{
    子要素があるときの処理
}

一応動いているようだけど、よく確認してません。 ほんとにこれでいいんでしょうか?

2011年3月2日水曜日

RhinoでXMLを使うときデフォルト名前空間を設定...できたけど何か変?

前回の投稿で名前空間の扱いがよく分からず、力技で処理してました。 その後ちょっと勉強してデフォルト名前空間を設定するコードを発見。 次のようにすればいいようです。

var ns = xmlobj.namespace();
default xml namespace = ns;

これでxmlの各要素にアクセスできるようになりました。 例えば次のようなxmlファイル「test.xml」を用意して、

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://www.dummy.jp">
    <msg attr="属性">テキスト</msg>
</root>

msg要素にアクセスするには次のようにします。