白黒にするブックマークレット

投稿者 nanki 2012-01-19 02:21:00 GMT

Webkitの新しい奴で。


Guardを使ったCoffeeScript開発

投稿者 nanki 2011-05-10 16:29:00 GMT

guardはファイルの変更を検知して、決められたタスクを実行するためのツールである。 Mac OS X / Linux / Windows それぞれのファイルシステム変更検知APIに対応しており、それ以外のプラットフォームではポーリングにて変更検知を行う。

$ gem install rb-fsevent # Mac OS X の場合
$ gem install guard
$ gem install guard-coffeescript
$ guard init coffeescript
$ vi Guardfile
guard 'coffeescript', :input => 'src/', :output => 'dist/'
$ guard start

こうすることで、src/ 以下の.coffeeファイルに変更があった場合即座にコンパイルされ、dist/以下に.jsファイルが生成される。

なお、rb-fseventは入れなくても動くがその場合はポーリングになる。 Mac以外のOSではこうするらしい。

$ gem install rb-inotify # Linuxの場合
$ gem install rb-fchange # Windowsの場合

guard-coffeescriptの他にも様々なguardがあるようです。

参考:

Objective-JおよびCappuccinoとそのvim補完 2

投稿者 nanki 2010-07-10 13:15:00 GMT

前回のエントリから早一年半。

Atlasのベータプログラムもいつの間にかスタートして、心躍るネタを提供してくれるObjective-J/Cappuccino.

一方僕はVimScriptを改良した。

主な改善点は、

  • []を自動で追加
  • 代入による変数の型推測
  • 定数を補完データベースに追加

Objective-CやObjective-Jでは、メッセージを続けて送る場合、[]を入れ子に書かないといけなくて、かなり苦痛なのだが、直前の対応する[の前に[を自動挿入することで、

  [CPView alloc] init
  // ☟
  [[CPView alloc] init]

という補完が行われるようになった。


WebSDL - Ruby/SDL × WebSocket/Canvas

投稿者 nanki 2010-06-23 02:42:00 GMT

Ruby勉強会@関西44の懇親会にて @cyross, @KazkiMatz さんらとSDLをWebSocketと組み合わせて…という話をしていておもしろそうだったので実装してみた。

websdl
青は@nanki, 赤は@ujm

github - WebSDL

  1. Ruby/SDLの画面描画を全て文字列としてシリアライズし、WebSocketで送信、Canvasに描画する。
  2. ブラウザ上で発生したイベントをWebSocketで送信、SDLのイベントモデルの中に還元してやる。

というのが基本的な仕組み。

# samples/sample1.rb
require 'rubygems'
gem 'rubysdl'
require 'sdl'
require 'websdl'

class TestFrame < Frame
  attr_reader :mx, :my, :color

  def initialize
    @color = 0xff000000 | (1..3).inject(0){|r,i|r << 8 | rand(0xff)}
    @mx = -100
    @my = -100
  end

  def open_screen
    SDL::Screen.open(640, 480, 32, SDL::HWSURFACE || SDL::DOUBLEBUF)
  end

  def mainloop(screen)
    screen.fill_rect(0, 0, screen.w, screen.h, 0)

    while event = SDL::Event.poll
      @mx, @my = event.x, event.y if SDL::Event::MouseMotion === event
    end

    frames.each do |f|
      screen.fill_rect(f.mx - 15, f.my - 15, 30, 30, f.color)
    end
    
    screen.flip
  end
end


SDL = WebSDL if ARGV.first == 'web'

SDL.init(SDL::INIT_VIDEO)
SDL.run(TestFrame, :host => '0.0.0.0', :port => 3000)

上記のようなコードで、

$ rsdl -Ilib samples/sample1.rb

ではSDLのウィンドウが起動し、

$ ruby -Ilib samples/sample1.rb web

でWebSDL版が起動するようになっている。 WebSDL版はsamples/test.html をWebSocket, Canvasに対応したブラウザで開く。

ただCanvasを使うだけでは芸が無いので、マルチユーザに対応、ユーザ間の情報共有にも対応してみた。

言うまでもなくProof of Conceptの段階であり、SDLの機能もdraw_rect, MouseMotion くらいしか実装していない。

また、0.1秒毎に更新しているのがかっこわるいが、適切なイベントに基づいた処理をすれば、パズルゲームやアドベンチャーゲームなど頻繁に画面更新のないものなら実用的なものができる可能性がある。 ウェブへぇボタンとかね。

問題点

一方、SDLのAPIは同期的なものもあり、SDL::Surface#get_pixel (画面上のピクセルの色を返す) などは現在の方法では実現が困難である。

参考:

Windowsを自動化 - EventGhost便利

投稿者 nanki 2009-08-12 22:40:00 GMT

eventghost

InternetExplorerのテスト用に飼っている、VMWare上のWindowsに新たな使命が課せられた。 携帯シミュレータでのテストだ。

ただ、シミュレータは3キャリア分あって、操作方法も全部違うので、これからげんなりすることを思うとげんなりする。

そこで、とりあえず、一発でreloadができるようにならないか方法を探してみた。

ページのリロード

EventGhost というのがあるらしいので、ダウンロードする。 ページのリロードは、指定した名前のウィンドウを探して、F5キーを押すことで実現。これを、3キャリア分設定。(ソフトによってキーは違う)

あっさりとできてしまった。

キャプチャ

それだけだと面白くないので、リロードした後、画像をキャプチャするようにした。 IrfanViewには、起動オプションでアクティブなウィンドウの内容をキャプチャする機能があるらしいので、それを使う。 起動オプションこんな感じ。

i_view32.exe /capture=3 /convert="\\\\.host\Shared Folders\Public\softbank.png"

ウェブサーバ

さらに、プラグインを見てみると、WebServerというのがある。 このプラグインを追加すると、指定したポートでHTTPサーバが起動し、指定したフォルダの内容が見られるようになる。

さらに、クエリーストリングに、HTTP.reload という文字列をつけてGETなどすると、同じ名前のイベントが発生して、アクションをトリガーできるようになるらしい。

そんなわけで、最終的にスクリーンショットのような構成になり、Safariから、http://192.168.1.1/?HTTP.reload などとすると、リロードしてスクリーンショットが見られるようになった。 (スクリーンショットが撮られるまでにはタイムラグがあるので、javascriptで定期的に画像をリロードする)

ウェブサーバ機能はかなり便利。

問題点

  • リロードの終了を検知できないので、2秒待つ、みたいなことをしないといけない。
  • アクティブなウィンドウをキャプチャするので、排他的にしか処理できない。
参考:

僕はあんまり携帯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だけでは属性を指定するという使い方は出来ないので、その場合も独自に拡張する必要がありそうではある。

参考:


Objective-J および cappuccino とそのvim補完

投稿者 nanki 2009-02-05 23:03:00 GMT

vim objj

しばらくはprototype.js や jQuery、時々はExt JS で楽しく遊んでいたけども、デスクトップアプリケーションのような物を作るのには力が不足していると感じていた。(機能が、ではなく、抽象化の程度が)

年初めくらいに cappuccinoというプロジェクトを見つけてきて、しばらくソースを眺めていたりしたのだけど、これはいい。 久々にピリピリ来るプロジェクト。

最近、iPhone SDK などでObjective-Cに触れて、Cocoa APIに慣れ親しんだせいもあるけど、それを差し引いても、よくできている。 興味と暇のある人は是非、調べてみて欲しい。

実際に、Keynote にしか見えないアプリケーション なんかもこれで作られている。

ちょっとソースを見ると、こんな調子だ。

<script type="text/javascript">
    OBJJ_MAIN_FILE = "main.j";
</script>
<script src="Frameworks/Objective-J/Objective-J.js" type="text/javascript"></script>

main.j というのが、Objective-J 言語で書かれていて、Objective-J.js を読み込むと、その場でJavaScriptにコンパイルされる。

元々、Objective-C は、Objective-Cのランタイム(Cの関数)とプリプロセッサだけでこしらえてある(と思う)のだが、その手の抜けた?実装とは裏腹に強力なオブジェクト指向機能を持っている。

今回、Objective-J がその手法をJavaScriptに対して適用したのを見て、この方法の持つシンプルさと力ににやにやせずにはいられない。(JavaScriptにOOを導入するとは!)

でも、Cocoa APIはフルスペリングでAPIが長いのでとても覚えられない。 IDEなどのコード補完機能がないと書く気が起こらない…ということで、vim の補完関数を作った。

github に置いてあるので、使うなり改良するなりしてください。

関係ないけど、Objective-J ではメソッドの定義に型を書くんだけど、コンパイルの時点で廃棄されている。(ので間違っててもコンパイルは通る) しかし、コード補完を作るにあたって、この型情報は非常に役に立った。

参考:

Web用画像処理言語purlにGyazoモジュール追加

投稿者 nanki 2008-10-30 18:11:00 GMT

purl にGyazoモジュールを追加しました。

デフォルト環境にはロードされないので、自分でロードする必要があります。

Purl::Purl.new のあたり。

# app/controllers/purl_controller.rb
class PurlController < ApplicationController
  caches_page :filter

  def filter
    begin
      result = Purl::StackMachine.new(
        params[:commands], Purl::Purl.new{|p| p.load_feature Purl::Features::Gyazo}).run
      send_data(result[-2], :type => result[-1], :disposition => 'inline')
    rescue => e
      render :status => 500, :text => 'error'
    end
  end
end

コード例

/purl/(a7d96c2ff64900f507ef9c8dab99f983):gyazo:5:round:5:5:5:5:extend:5:dropshadow:to.png gyazo

参考:

決定版! Rails用画像添付プラグインpurl

投稿者 nanki 2008-10-23 10:15:00 GMT

Rails pluginとして動く言語、purlを公開しました。

purl はクライアントサイドから柔軟な画像処理を行うために開発されました。 サムネイルの生成などを行うプラグインはいくつかありますが、そのどれよりも強力で汎用性、拡張性があります。

セットアップ

Rails2.1以上では、

$ script/plugin install git://github.com/nanki/purl.git

それ未満では、

$ git clone git://github.com/nanki/purl.git -- vendor/plugins/purl

gitが無い環境なら、githubのdownloadからファイルを落として、vendor/plugins/ に配置してください。

依存ライブラリ

  • 必須: ImageMagick, rmagick
  • あった方がいい: cairo, rcairo

その他

purl のデフォルトの環境では、画像の保存にデータベースを利用します。 imagesテーブルに、blob型のdataカラムを追加してください。

# app/models/image.rb
class Image < ActiveRecord::Base
  attr_readonly :data
end

その上で、ImageController#upload などに以下のように記述します。

# app/controllers/image_controller.rb
class ImageController < ApplicationController
  def upload
    Image.create(:data => params[:data].read)
  end
end

さらに、config/routes.rbを書き替え、purl が実行されるようにします。 書く場所は先頭に近い方がいいと思います。

# config/routes.rb
  map.connect 'purl/:commands',
    :controller => 'purl', :action => 'filter', :commands => /.*/
# app/controllers/purl_controller.rb
class PurlController < ApplicationController
  caches_page :filter

  def filter
    begin
      result = Purl::StackMachine.new(
        params[:commands], Purl::Purl.new).run
      send_data(result[-2], :type => result[-1], :disposition => 'inline')
    rescue => e
      render :status => 500, :text => 'error'
    end
  end
end

そんなこんなでセットアップは終わり。

言語

purl はURL上で記述されることを前提としています。 常にワンライナーであれ!

文法

purl は逆ポーランド記法を採用しています。 データと命令を書かれた順番にスタックマシンにプッシュしていき、命令が実行された結果がスタックマシン上につまれていきます。 命令列は最初に:で区切られ、数字としてパースできるものは数字へ、()で囲われた部分は文字列へと変換されます。

ポリシー

デフォルトで用意される全ての命令は、外部の値に依存しません。 つまり、命令列が決まれば実行結果は確定します。 このポリシーにより、全ての実行結果がキャッシュ可能になります。

サンプルコード

画像をそのまま表示

次の例では、load はスタック上に既にある数字1を消費して、ID=1のImage#dataをデータベースからロードして、スタック上にプッシュします。 to.png では、スタック上の画像データをPNG形式のバイト列に変換し、mimetypeとともにスタック上に積みます。

/purl/1:load:to.png

画像の形式を変換

次の例では、画像をGIF形式に変換しています。

/purl/1:load:to.gif

画像のリサイズ

次の例では、画像を100x100にリサイズしています。 リサイズ用の命令は、何種類か用意されており、高さを一定に保つ resize.heightや、上限を指定する、resize.upto などがあります。

/purl/1:load:100:100:resize:to.png

画像の合成

次の例ではふたつの画像を合成しています。

/purl/1:load:9:load:composite:to.png

次の例では順番を入れ替えています。

/purl/1:load:9:load:swap:composite:to.png

コメント

スタックに積んだ後すぐにpopすると、単純に無視されるので、コメントとして使えます。 キャッシュのライフサイクルコントロールなどに使えると思います。

/purl/1:load:(daily):pop:to.png

図形の描画

詳しくは解説しませんが、試験的にcairoの描画機能をベースにした図形描画命令を用意しています。 ctx命令で、指定したサイズのcairoコンテキストを準備し、xtc命令で実際にサーフェースへの描画を実行します。

/purl/80:80:ctx:40:40:moveto:40:40:40:-20:20:arc.ccw:1:0.3:0:rgb:fill:60:20:4:circle:0:0:0:rgb:fill:xtc:to.png

制限

実行結果をファイルとしてキャッシュする場合、ファイルシステムによる字数制限を受けます。

拡張

拡張は命令モジュールの追加という形で行います。 詳しくはソースコード見てください。

今後

  • 無名関数的なもの。
  • 外部から直接呼び出せない命令とか?
  • エラーメッセージとか?
参考:

iPhone/iPod touch用 JavaScript コンソール

投稿者 nanki 2008-09-09 18:55:00 GMT

iPhone/iPodのキーボードは、まったくもってプログラミングに向かいないけれども、 ちょっとしたJavaScriptを試してみたい時はあるので、どうにかならないか試してみた。

jsconsole for iphone

JavaScript Console for iPhone

若干妙なところもあるけど、一応動く。 ちょっとしたコードなら、思ったよりさくさく?かける。

高度なカーソル移動や、単語境界まで削除、みたいな機能は欲しいなぁ。

やっぱり、touchイベントを使うので、普通のSafariで動かない。めんどい… textareaのスクロールも…

AJAX Libraries API を使って、著名なライブラリをロードできる機能もつけてみた。

http://tools.netswitch.jp/jsconsole/?lib=j,ju こんな感じにすると、jQuery, jQueryUIを読み込んでいる(はず).

j=jQuery, ju=jQuery UI, p=prototype, s=scriptaculous, m=mootools, d=dojo

書き上がったJavaScriptはメールで送信できるらしい。

参考: