blockdiag シリーズの trac plugin を書いた

blockdiag シリーズがすごく良かったので trac で使うべくプラグインを書きました。
github で公開しています。

0.1.0 には日本語を含むソースを書くと wikiレンダリングできない残念なバグがあるので既にインストールして頂いた方は 0.1.1 にアップデートしてください。

既に TracBlockDiagPlugin がありましたが、たまに画像が表示されないことがあったので自分で作ることにしました。今のところマクロ構文は TracBlockDiagPlugin を踏襲しています。

バグや要望があれば連絡いただけると助かります。もちろん fork して改造してくださっても結構です。pull requests を頂ければ大変喜びます。

ここにはインストール方法や使い方などを書いておきます。なんか README の邦訳みたいになっていますが、日本語ネイティブなのでむしろ README の英語があやしすぎます。

特徴

TracBlockdiag の特徴など。

  • blockdiag の大半の機能をサポート(fontmap には未対応)
  • PNG/SVG での出力が可能
  • 高速な wiki レンダリング(図は img タグでアクセス時に生成される)
  • 生成された画像への直リンクが可能
  • stateless なので multi-thread/multi-process でも安心安全
  • インストール済みの *diag だけ macro を有効化
  • 外部プロセスを呼ばずに内部で処理するので不要なファイルを作らない

動作環境

trac 0.11 対応はおまけみたいなものなので、できるだけ 0.12 以上を使ってください。

インストール

インストールは普通の trac plugin と変わりません。

リポジトリを clone します。git-flow を使っているので master ブランチは常にリリース版です。安心してお使いください。

$ git clone https://github.com/yosisa/TracBlockdiag.git
$ cd TracBlockdiag

システムワイドに入れるには以下のようにします。

$ python setup.py install

特定の trac env に入れるなら egg を作ってコピーします。

$ python setup.py bdist_egg
$ cp dist/*.egg /path/to/tracenv/plugins

管理画面や trac.ini でプラグインを有効にしてください。

プラグインのインストールが終わったら、使いたい blockdiag シリーズをインストールします。
全部使いたい場合は以下のようにすればいいです。

$ pip install blockdiag seqdiag actdiag nwdiag

nwdiag を使うなら cisco の追加 shape が素敵なのでこれも入れておきましょう。 ::

$ pip install blockdiagcontrib-cisco

以上でインストールは終了です。

使い方

trac 0.12 向けの説明です。0.11 な方は README_ を参照してください。

マクロ構文は以下のようになっています。type のデフォルトは png です。

{{{#!(block|seq|act|nw|rack)diag [type=(png|svg)] [IMG_TAG_ATTR=VALUE ...]
*DIAG_SOURCE_TEXT
}}}

具体例

{{{#!blockdiag
{
A -> B -> C;
B -> D;
}
}}}

これは blockdiag を使って png 画像を生成します。

png は重いので可能なら svg を使いましょう。

{{{#!blockdiag type=svg width=800px
{
A -> B -> C;
B -> D;
}
}}}

width=800px は img タグにくっつきます。height とかももちろん指定できます。

以上です。それでは、楽しい blockdiag life を!

virtualenvwrapperがフリーズするのを回避する

source virtualenvwrapper.sh すると高確率でフリーズして端末を閉じるしかなくなるバグの回避方法。

以下の環境で発現を確認。

  • OS: Lion, Snow Leopard
  • virtualenvwrapper: 2.7.1
  • zsh: 4.3.12 (from Homebrew)

#97 で修正されているのでリポジトリをクローンして手動でインストールすればいい。

  $ pip uninstall virtualenvwrapper
  $ hg clone https://bitbucket.org/dhellmann/virtualenvwrapper
  $ cd virtualenvwrapper
  $ python setup.py install

OS X Lionにhomebrewでemacsとかをインストール

OS X Lionにhomebrewでemacs, cmigemo, apel, wanderlustをインストールする方法。

emacsのインストール。オリジナルのformulaだとビルドに失敗するのでgistにあるformulaを使う。

$ brew install https://gist.github.com/raw/1109223/fd68c54d39c102def876bdf650514b801432f7cc/emacs.rb --cocoa --lion

※追記
起動はterminalから以下のようにする。

$ open /usr/local/Cellar/emacs/23.3/Emacs.app

あるいはFinderで開いてダブルクリックでも大丈夫。起動したらDockのアイコンを右クリックしてdockに追加しておけば次回からは起動が楽。

cmigemoのインストール。

$ brew install https://gist.github.com/raw/1116133/2a8c279518d86644fcf143235123a09230864eae/cmigemo.rb

apelのインストール。

$ brew install https://gist.github.com/raw/1116137/33cc160657ae156c2119a2ef5395845912f1badf/apel.rb

wanderlustのインストール。

$ brew install https://gist.github.com/raw/1116139/f82f6ea67d5721e97e1adbf68ee644315dd0fb43/flim.rb
$ brew install https://gist.github.com/raw/1116144/74d71aac4c7cdf1ef5ed00a7a5a09de5b6d5aaae/semi.rb
$ brew install --HEAD --ignore-dependencies https://gist.github.com/raw/1116146/3f014d1b37146785061beb4628f37110ecb91aa6/wanderlust.rb

@classmethod を自作してみた

classmethodデコレータってどういう実装になってるんだろうっていう話が発端。ソースは見れないし、ググってもそれっぽいのは出てこなかったので自分でやってみた。Python 2.7で確認。

import文いれてもたった10行ですね。以下解説。

myclassmethodはディスクリプタになっていて、これを使うことでオブジェクトの参照動作をカスタマイズしてる。平たく言うとプロパティみたいなもので、myclassmethodクラスのインスタンスが参照 (get) された時に__get__が呼ばれるようになってる。デコレータはシンタックスシュガーなので普通の書き方に戻すとこうなる。

bar = myclassmethod(bar)

つまり、myclassmethodのインスタンスが生成されてそれがbar (クラス変数) に代入される。myclassmethod.__init__にはbarが渡されるが、この時点ではFooクラスはオブジェクト化されておらず、Fooクラスを参照する手立てがないのでとりあえず保存しておく。この時、barはただのfunctionである。

その後、Fooクラスがオブジェクト化されてbarが参照された時に、myclassmethod.__get__が呼ばれる。引数にはFooクラスのインスタンスとクラスオブジェクトが渡されるので、new.instancemethodを使ってself.funcをメソッド化してやる。クラスオブジェクトにboundすることでクラスメソッドができあがる。

new.instancemethodの第三引数がtypeなのは@classmethodデコレータで生成されたメソッドを見てそうしたんだけど、クラスオブジェクトのクラスがtypeだからなのかな。ここはちょっと自信ない。

以上。おしまい。

しかしこうもあっさりできるとは。あーあ、会社でうんうん唸ってたのはなんだったんだろーね、ほんと...。

e2wmのON/OFFに合わせてフレームサイズを自動変更

e2wmの使い方として、普段はOFFにしてて必要な時だけONにしてる。フレームサイズの話をすると、普段は他のウィンドウと重ならないように800pxくらいにしてる。e2wmは横長なフレームを想定してるから使用時には1440pxくらいは欲しい。このサイズ変更がいちいちめんどかったのでlisp書いた。

http://www.bookshelf.jp/soft/meadow_30.html#SEC419のフレームサイズを記憶するlisp入れてたから、e2wmに適したフレームにしたまま終了したら次回起動時に異様に横長くなっちゃうし、そうでなくてもモード変更する都度マウスでウィンドウの端掴んでサイズ変更するのがめんどすぎた。

だったらe2wm-modeのON/OFFのタイミングで自動的にサイズ変更してくれたら嬉しいよね。でもってサイズは終了時に記憶して復元してくれたらいいよねって事でできたのが以下のスクリプト。init.elにコピペすれば動くはず。

現在のフレームサイズは、M-x e2wm-frame-size-save で保存できる。e2wmのON/OFF毎に保存するのでそれぞれ好きなサイズにできる。また、Emacs終了時には自動保存される。

保存したサイズにはモード変更時に自動で切り替わるけど、M-x e2wm-frame-size-load で手動で戻すこともできる。

こんな機能、e2wmが持ってそうな気もしたけど作っちゃったから公開する。

Maven2で作ったjarプロジェクトを簡単に実行する

Maven2は依存関係を自動解決してくれたりと便利そうなんだけど、jarで作ったプロジェクトの実行方法がよく分からなかったので調べた。mvn packageは依存ライブラリを含まないしマニフェストの自動生成もしてくれないのでした。

あとjavaコマンドの-classpath指定は-jarと併用できないんだってね。というわけで解決策は以下の2つ。assembly-pluginでもできるらしいけど未確認。

mvn exec:javaコマンドで直接実行

単に開発環境で実行するだけならこれが一番簡単。pom.xmlに以下を追記する。

<plugins>
  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <configuration>
      <mainClass>メインクラスをフルネームで(jp.example.App)</mainClass>
    </configuration>
  </plugin>
</plugins>

次のように実行できる

$ mvn exec:java

引数も渡せる

$ mvn exec:java -Dexec.args="arg1 arg2 arg3"

マニフェストを定義してmvn packageでjarを作る

配布時とかmvn環境外から実行したいときはこっち。pom.xmlに以下を追記。

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
      <archive>
        <manifest>
          <mainClass>メインクラスをフルネームで(jp.example.App)</mainClass>
          <packageName>パッケージ名(jp.example)</packageName>
          <addClasspath>true</addClasspath>
          <addExtensions>true</addExtensions>
          <classpathPrefix>dependency(jarファイルからライブラリへのパス)</classpathPrefix>
        </manifest>
      </archive>
    </configuration>
  </plugin>
</plugins>

パッケージを作成

$ mvn package

次に依存ライブラリを全て書き出す。デフォルトでtarget/dependencyに出力される。

$ mvn dependency:copy-dependencies

libに書き出すなら次のようにする。この場合はpom.xmlのclasspathPrefixを適宜書き換える。

$ mvn dependency:copy-dependencies -DoutputDirectory=lib

次のように実行できる

$ java -jar target/projectname-version-SNAPSHOT.jar

もちろん引数も渡せる

$ java -jar target/projectname-version-SNAPSHOT.jar arg1 arg2 arg3

なんというか、Maven2はコマンドが複雑怪奇で覚えるのが大変。Eclipse使わずにJavaをやろうとするのが間違ってるのか…