chm.rbのバグ?

投稿者 nanki 2009-08-11 22:54:00 GMT

とあるchmファイルをWindowsで見ていて気がついたのだが、一つのキーワードに複数のドキュメントが割り当てられている場合がある。

同じファイルを、Macで見ると、最初のコンテンツしか表示されない。

調べてみると、chmlib のRuby bindingである chm が原因らしい。

そもそも、chmのインデックスは下記のような形式のドキュメントになっていて、chmの中の、chm.rbでこれをパースしているのだが、キーワードが複数のドキュメントに対応する場合が想定されていないようだ。

…
<li><object type="text/sitemap">
  <param name="Name" value="animal">
  <param name="Name" value="dog">
  <param name="Local" value="dog_doc">
  <param name="Name" value="cat">
  <param name="Local" value="cat_doc">
</object>
…

普通の感覚ではこれを見ても一番上のキーワードが下の方まで有効だと思えないのだが…

あと、目次(Topic)を読むところが、case-sensitiveになっていたので、目次が取れていなかった。

コミットしてから気がついたけど、ゴミが…

参考:

今日のgolf - るびまゴルフ

投稿者 nanki 2009-07-02 23:14:00 GMT

久々にgolf。 問題はコチラ.

標準入力から、3,5 という入力を受け取って、3 から5 までの数字を出力するコード。

まず素直(?)に書いて、

p *eval(gets.split(',').join('..')) # 35B

順等に縮めると

p *eval(gets.sub',','..') # 25B

ここからは手強いので寝かせて。

eval'A,B='+gets;p *A..B # 23B

A, Bの重複がとても気になる…

ちょっとずるいけど、$ ruby -n を使っていいと、

p *eval(sub',','..') # 20B

文字列のRangeを使う方法もやってみたけど、挙動に問題があるのでやめ。

風の噂では、20Bまでいける、と聞いたんだけど…がんばります。

参考:

Rubyist Magazine - るびまゴルフ 【第 6 回】


Chemr高速化

投稿者 nanki 2009-04-21 18:46:00 GMT

今回のあらすじ

Flex のドキュメントを、オフライン時にも使えるようにしようと企んだ nanki は、coderepos:chm-generators を手にいれ chm ファイル作ってみるが、サイズが150MBもあるので、Chemr 本体に手を加えて、gzip 圧縮に対応することによって無事50MBにまでスリム化することに成功する。が、よく使うリファレンス群はそもそもサイズが5MB程度なので、たいして役に立たないことに気がつき衝撃を受ける。

これは巨大な chm を作って対抗するしかない、とマシンにインストールされた全ての gem の rdoc をchm 化するが、今度はインデックスが大きすぎるためか検索がもたつくことに気付く。

「これでは仕事ができない!」

不当な怒りに燃えた nanki は、よりよい開発環境を手に入れるために Chemr に改造を施し、高速化することを決意したのだった。

果たして戦いの果てに未来はあるのか!?

結果

一回のインクリメンタル検索処理あたり、0.3~1秒程度かかっていたのが100倍くらい速くなった。 体感では100倍とはわからないが、もたつきが感じられないレベルになった。

インデックスの最初の二文字を抜き出してHashで持ち、検索文字列の最初の二文字でO(1)でしぼりこむ仕組み。

高速化の恩恵は最初の数文字の偏りに大きく依存すると思うけど、そもそもそんな状況では、インクリメンタル検索が快適ではないので気にしないこと。

!DOCTYPE 宣言があると外部CSSが効かない(詳細不明)問題とか、ruby-cocoaでsize/countが無限再帰になる問題とか、Chmerとtypoする問題などにも嵌って大変だった。

その後、バージョン違いがたくさん(railsだけで5個くらい)あったgemを削除しまくったので、普通に速くなってあんまり意味がない。

gem を300種類くらい入れて複数のバージョンを保持しているような人しか恩恵が得られないかも。

ちなみに、もたつきが気になるというのは、僕のタイプ速度より速く、キーリピートより遅いくらい。つまり全然支障はない。

codereposのは古いっぽい…?

参考:

僕はあんまり携帯HTMLをいじらないけど、タイトルのような問題があるという話はよく聞く。

また、CSSにはスコープの概念がないので、TinyMCEなどのWYSIWYGエディタを使っていると、Wordなどから<style>タグを含む断片が貼付けられて、ページ全体のスタイルに影響を与えてしまう、などといったことが起こる。

こういった問題への対応策として、CSSのインライン化が有効に働きそうなので、調べてみた。 参考に挙げているが、Perl/PHP では、こういったライブラリが存在しているらしい。

我らが(?)Rubyはというと、(最近遊びでCSSParserを書いたので、なければ作ろうと思ってたけど)やっぱり存在していて、これが結構便利そう。

TamTam: Inline CSS

しかし、こんな名前で公開されても…。見ても気付かないよ…

インストール

$ sudo gem install tamtam

コードがドキュメント、とばかりに、主要な部分を読んでみた。 使い方を見てみよう。

使い方

TamTam.inline
  :css => '.a { background-color:red }',
  :body => "<div class='a'></div>"
#=> "<div class="a" style="background-color: red;"></div>"

素晴らしい。

また、:documentを使うことによって、HTML内の<style>タグの内容をそのまま使うこともできる。

TamTam.inline
  :document => "<style>.a { background-color:red }</style><div class='a'></div>"
#=> "<style>.a { background-color:red }</style><div class="a" style="background-color: red;"></div>"

スタイルを適用した後の余計なclass属性は、元から存在するclass名と衝突するかもしれない。 そんなあなたには、:prune_classes => trueというそれらしいオプションがあるのだが、 バグなのか何なのか、スタイルを適用する前にclassを全部取りさってしまうので(僕の)望む動きとは違うようだ。

TamTam.inline
  :document => "<style>.a { background-color:red }</style><div class='a'></div>",
  :prune_classes => true
#=> "<style>.a { background-color:red }</style><div></div>"
# 適用されてない!

携帯電話…

携帯電話用に使う場合、<link>タグを認識する部分を自分で書かないといけない。

それと、聞いた話では、携帯電話の場合は通信量を減らすために、style='background-color: …'よりも、bgcolor='…'が好まれるそうだ。

CSSだけでは属性を指定するという使い方は出来ないので、その場合も独自に拡張する必要がありそうではある。

参考:


Mac OS X で Wii Remote API を使う

投稿者 nanki 2009-03-22 21:22:00 GMT

Canvasを使ったWii用ゲームを作ってみた (Kanasansoft Web Lab.)

Nintendo Wii に載っているOpera にはWii Remote APIなるものがあって、WiiリモコンとCanvasを使って色々できる。

うちには、OperaもWii のコントローラ(だけ)もあるのに、kanasan の力作が遊べないなんて!ありえない!

というわけで、Wii Remote API のふりをするコードを書いてみた。


WiiFake: emulate Wii Remote API on Mac OS X. from NANKI Haruo on Vimeo.

requires at runtime

How to use.

  1. Copy WiiRemote.framework to your ~/Library/frameworks/ directory.
  2. WiiFake を落としてくる。
  3. Wii リモコンの 1 2 keyを押したままサーバを起動する。
    $ ruby server.rb
  4. このbookmarkletを起動 WiiRemote bookmaklet
  5. 必要に応じてページの初期化処理を呼び出す。
    (上記kanasanのページだと、javascript:initialize())

仕組み

bookmarklet で読み込んだ WiiProxy.swf から localhostに立てたRubyサーバに繋いで、JSON形式で受け取った情報を、javascriptの世界に渡しているだけです。

テスト

Safariでしかテストしてない;;

画質のテストのため、同じムービーをYoutubeにもアップロードしてみた。

参考: