• このエントリーをはてなブックマークに追加
  • このエントリをクリップ! このエントリをクリップ!

はじめに

CPANモジュール Image::Size を使って画像サイズを取得できないケースに遭遇したのでメモ.

なお,モジュールのバージョンは 3.230 です.

現象

同モジュールを入れると imgsize コマンドを利用できるようになります.本来であれば次のような感じ:

% imgsize /path/to/img_ok.jpg
width="2693" height="1800"

しかし,次のようなケースに遭遇しました:

% imgsize /path/to/img_ng.jpg
Use of uninitialized value in printf at /home/www/perl5/perlbrew/perls/perl-5.14.2/bin/imgsize line 61.

Perlスクリプトとして実行してみたら,次のようになりました:

% perl -MImage::Size=imgsize -MData::Dumper -le 'print Dumper [ imgsize("/path/to/img_ng.jpg") ]'
$VAR1 = [
          undef,
          undef,
          'Data stream is not a known image file format'
        ];

うーん,画像フォーマットの識別がうまくいっていないのかな,と推測.

ひとまずの対処法

同モジュールのソースをざっと眺めてみると,Image::Magick モジュールを読み込んでいれば,そのメソッド ->Get() を使ってくれることがわかったので,とりあえずはそんな感じで対処:

% perl -MImage::Magick -MImage::Size=imgsize -MData::Dumper -le 'print Dumper [ imgsize("/path/to/img_ng.jpg") ]'
$VAR1 = [
          2693,
          1800,
          'Joint Photographic Experts Group JFIF format'
        ];

取得できました!

おわりに

以上,Image::Size モジュール(または imgsize コマンド)で画像サイズ情報を取得できないケースに遭遇して,アドホックに対処したお話でした.

また,imgsize($file, { format => 'jpeg' }) のような感じで画像フォーマットを強制的に固定できるようになってもいいんじゃないかな,とか思ったりしました.

あとでもう少し詳しくソースを読んでみるとします.

  • このエントリーをはてなブックマークに追加
  • このエントリをクリップ! このエントリをクリップ!

こういうの食べればいいの?

はじめに

この連休中にaquaさんでちょこっと走った際の記録などです.

2012-05-03: 名古屋〜豊橋

朝はまだ雨が少し降っていたものの次第に晴れてきたので,スタートが遅いかなと思いつつも決行することに.

初めて碧南・蒲郡方面を経由してみました.全体的に平坦な感じで走りやすかったです.一部唐突に出現する上り坂なんかもありましたが.

記録

iPhoneアプリ Cyclemeter での記録です.またデータが一部欠けちゃってるなぁ...

スタート: 2012/05/03 11:51:26
バイクタイム: 4:57:59
停止時間: 0:00
距離: 101.75 km
平均スピード: 時速 20.49 km
最高スピード: 時速 58.46 km
登り: 259 メートル
降り: 220 メートル

写真いくつか

西尾のあたり.車通りもそんなに多くありませんでした:

西尾に入った。

蒲郡を経由した証w:

競艇場前。

あ,ラグーナとか撮ってないやw

2012-05-05: 豊橋駅〜渥美半島の根元あたり

有名らしい「大松屋食堂」を目的地に設定して,国道259号線と国道42号線を,という感じに.

駅のコインロッカーに,輪行袋はじめ帰り用のかさばる荷物を預けておいたので気楽です.

記録

同じく Cyclemeter での記録.こっちはデータ欠けてないみたい.

スタート: 2012/05/05 9:38:43
バイクタイム: 5:52:00
停止時間: 12:44
距離: 53.95 km
平均スピード: 時速 9.20 km
最高スピード: 時速 60.28 km
登り: 247 メートル
降り: 211 メートル

写真いくつか

大松屋食堂.中に入れるまで30分くらい待ちました:

目的地到着!順番まで30分待ち!

天丼がヤバいw:

天丼がやばい!

食後,膨れたお腹を抱えて海沿いにゆっくりと道の駅まで:

Untitled

大清水駅からは,土曜・休日に運行している,渥美線のサイクルトレインに乗車して豊橋駅まで移動しました:

渥美線のサイクルトレインに。

おまけ:2012-05-02: 荷物を実家へ

走るのに要らないだろう荷物を,先に実家へ送りました:

これから実家に送る。

同様に,5日の朝,実家近くのコンビニから名古屋の自宅へ向けて送り返してやりました.

おわりに

以上,この連休中にaquaさんで走ったメモでした.快晴の下を走るのは最高ですね!

しかし,日焼け止めを塗っていなかったため,腕が火傷した感じになってしまいましたとさ.涼しいことと日差しの強さは無関係ですね><:

筋肉痛はまったくないんだけど、日焼けが痛いw
  • このエントリーをはてなブックマークに追加
  • このエントリをクリップ! このエントリをクリップ!

ss-1335401781

はじめに

WordPressのプラグイン WP-Syntax で利用されていることでもおなじみの,シンタックスハイライトなPHPライブラリ GeSHi ですが,Textileにおける bc. とか bc.. とかの記法を少し拡張してシンタックスハイライトするのに使えないかどうか,ということを考えていました.

少々力技ではありますが,ざっと形になったので,Text::Textile::Pluggable::Plugin::SyntaxHighlight::GeSHi という名前をつけてGitHubに公開してみました.

できること

Textile記法では,コードブロックを表記するのに,bc. とか bc.. とかを使います.

bc. foo
bar
baz
 
this line is not code
 
bc.. foo
bar
baz
 
this line is code too

そこで,本プラグインでは,bc[lang].bc[lang].. という記法が使えるようにしてみました.で,lang が示す言語に沿ったシンタックスハイライトが施されるようになっています.(もちろん,GeSHiに対応しているもののみですが!)

bc[lang]. foo
bar
baz
 
this line is not code
 
bc[lang].. foo
bar
baz
 
this line is code too

使い方

use Text::Textile qw/textile/;
 
my $text = << '...';
bc[perl].
use strict;
use warnings;
print 'foobar.';
...
 
# procedural usage
my $html = textile($text, [qw/SyntaxHighlight::GeSHi/]);
 
# OOP usage
my $textile = Text::Textile::Pluggable->new(
    plugins => [qw/SyntaxHighlight::GeSHi/],
);
my $html = $textile->process($text);

環境的な前提

環境的には,次の3点が前提となります:

  • Text-Textile-Pluggable-0.03
  • PHP
  • GeSHi

Text-Textile-Pluggable-0.03

プラグインモジュールのロード処理まわりを少し修正したバージョンが必要になります.

PHP

PHPも使える必要があります.バージョンはそれなりにテキトーで問題ないかと思います.

GeSHi

これが肝心ですね.

ダウンロードは次から行えます:

<?php include_once 'geshi/geshi.php'; ?> ができるように,展開したものをそのまま include_path へ移動します.

なお,include_path は,次のようにすれば見つけられるでしょう:

% echo '<? phpinfo() ?>' | php | grep include_path
include_path => .:/Users/issm/local/lib/php => .:/Users/issm/local/lib/php

私の環境では,/Users/issm/local/lib/php がそれにあたるので,/Users/issm/local/lib/php/geshi/geshi.php として参照できるような形になればOK,という感じです.

力技の中身

  1. bc[lang].<pre><code language="lang">...</code></pre> というようなHTMLに変換される)
  2. 渡されたHTMLテキストから <pre><code language="lang">...</code></pre> となっている個所を抜き出す
  3. 抜き出したコード部分を一時ファイルに書き出す
  4. `echo $php_code | php -- $file $lang` みたいな感じでPHPを実行する
  5. PHP内では,一時ファイルを読んでGeSHiに通してできたHTMLを標準出力する,というようなことをしている
  6. 先の <pre><code language="lang">...</code></pre> な部分を,得られたHTMLで置換する
  7. これを繰り返す

PHPコードを標準入力として読み込ませれば,それ専用のスクリプトファイルを準備しなくてもいいよね,といった判断でこうなりました.

また,GeSHiを通すためのコード自体も引数とかで与えようとしたけれど,クオートとかの処理がよくわからなかったので,一時ファイルを経由する形にしてしまいました.

プラグインのソースコード

package Text::Textile::Pluggable::Plugin::SyntaxHighlight::GeSHi;
use 5.008001;
use strict;
use warnings;
use File::Temp qw/tempfile/;
use HTML::Entities qw/decode_entities/;
use Encode qw/encode_utf8 decode_utf8/;
our $VERSION = '0.01';
 
my $php_code = << '...';
<?php
include_once "geshi/geshi.php";
 
$file = $argv[1];
$lang = $argv[2];
$code = file_get_contents($file);
 
$geshi = new GeSHi($code, $lang);
$html = $geshi->parse_code();
 
echo $html;
?>
...
 
my $re_html_code = qr{<pre><code (?:\s language="([^\"]+)" )?>((?:.|\n)*?)</code></ pre>}mx;
# "</ pre>": WP-Syntaxが誤反応しないための対策.通常はスペースはない
 
sub init {
    my $o = shift;
    $o->{'plugin.geshi'} = {
        echo => '/bin/echo',
        php  => '/usr/bin/env php',
    };
}
 
sub post {
    my $o    = shift;
    my $text = shift;
 
    my $echo = $o->{'plugin.geshi'}{echo};
    my $php  = $o->{'plugin.geshi'}{php};
 
    while ( my @m = $text =~ $re_html_code ) {
        my ($lang, $code) = @m;
        $lang ||= 'text';
        chomp($code = decode_entities($code));
 
        my ($fh, $file) = tempfile(UNLINK => 1);
        print $fh encode_utf8($code);
        close $fh;
 
        $text =~ s{$re_html_code}{
            decode_utf8( `$echo '$php_code' | $php -- $file $lang` );
        }ex;
    }
 
    return $text;
}

おわりに

以上,Textile記法をちょこっと拡張してGeSHiを使ったシンタックスハイライトを行えるようにするための Text::Textile::Pluggable プラグインを書いてみたお話でした.

なお,冒頭のスクリーンショットは,SiTeWiki に本プラグインを追加してみたときのものです.一応動いていますねw

  • このエントリーをはてなブックマークに追加
  • このエントリをクリップ! このエントリをクリップ!

はじめに

前エントリ@hell2u さん に次のように言及されていたみたいです:

blog.iss.ms/2012/04/19/135… 良さそうなのでMarkdownでおながいします。
Twitter / @hell2u: http://t.co/x25im9FB 良さそうな …

...ということなので調子に乗って Text::Markdown::Pluggable というモジュールも書いてみました.

概要と基本的な使い方

Text::Markdown のサブクラスで,そこに「プラグイン」を読み込むしくみを追加しています.(プラグインの作り方については,Text::Textile::Pluggable 書いてみたエントリ は「プラグインの作り方」の部分のサンプルコードの [Tt]extile[Mm]arkdown に置き換えて読んでくださいw)

使い方は次のとおりです:

use Text::Markdown::Pluggable qw/markdown/;
my $html = markdown($text, [qw/Foobar +MyApp::Markdown::Plugin/]);
 
use Text::Markdown::Pluggable qw/markdown/;
my $html = markdown($text, [qw/Foobar +MyApp::Markdown::Plugin/], {
    empty_element_suffix => '>',
    tab_width => 2,
});
 
use Text::Markdown::Pluggable;
my $m = Text::Markdown->new(
    plugins => [qw/Foobar +MyApp::Markdown::Plugin/],
);
my $html = $m->markdown($text);
 
use Text::Markdown::Pluggable;
my $m = Text::Markdown->new(
    plugins => [qw/Foobar +MyApp::Markdown::Plugin/],
    empty_element_suffix => '>',
    tab_width => 2,
);
my $html = $m->markdown($text);

プラグインを読み込むことを除けば, 使い方は Text::Markdown と同様だと思います.

サンプル

Text::Textile::Pluggable と同様,次の2つのモジュールを同梱しています:

  • Text::Markdown::Pluggable::Plugin::GitHub::Links
  • Text::Markdown::Pluggable::Plugin::GitHub::Gist

GitHub::Links プラグインのサンプル:

% perl -Ilib -M5.10.0 -MText::Markdown::Pluggable=markdown -le 'say markdown("github:issm")'
<p>github:issm</p>
 
% perl -Ilib -M5.10.0 -MText::Markdown::Pluggable=markdown -le 'say markdown("github:issm", [qw/GitHub::Links/])'
<p><a href="https://github.com/issm">github:issm</a></p>
 
% perl -Ilib -M5.10.0 -MText::Markdown::Pluggable=markdown -le 'say markdown("github:issm/p5-Text-Markdown-Pluggable", [qw/GitHub::Links/])'
<p><a href="https://github.com/issm/p5-Text-Markdown-Pluggable">github:issm/p5-Text-Markdown-Pluggable</a></p>
 
%

GitHub::Gist プラグインのサンプル:

% perl -Ilib -M5.10.0 -MText::Markdown::Pluggable=markdown -le 'say markdown("gist:123456")'
<p>gist:123456</p>
 
% perl -Ilib -M5.10.0 -MText::Markdown::Pluggable=markdown -le 'say markdown("gist:123456", [qw/GitHub::Gist/])'
<script src="https://gist.github.com/123456.js"></script>
 
% perl -Ilib -M5.10.0 -MText::Markdown::Pluggable=markdown -le 'say markdown("gist:123456#file1", [qw/GitHub::Gist/])'
<script src="https://gist.github.com/123456.js?file=file1"></script>
 
%

おわりに

以上,Markdown 記法をちょこっと独自拡張するのに便利かもしれないモジュール Text::Markdown::Pluggable を調子に乗って書いてみた,というお話でした.

やっぱり Markdown記法の方が需要はあるんですかね.私はとりあえず今のところ Textile記法推し(?)で生きていってみますw

あと,Markdown にしろ Textile にしろ,Bootstrap とかのCSSフレームワークと併用するとラクしていい感じのドキュメントページができますね!

  • このエントリーをはてなブックマークに追加
  • このエントリをクリップ! このエントリをクリップ!

はじめに

お仕事で情報をテキストで共有するための書式に利用したり,「SiTeWiki」とかいうものを作ったり,もちろんRedmineのテキスト入力系でも使ったり,と,Textile記法 にちょこっと触れている今日この頃です.特に,アプリケーションを実装する際には,CPANモジュール Text::Textile にはお世話になりっぱなしです.

そんな中,Redmineでの commit:abcdef とか #1234 とかの表記がと特定ページへのリンクに変換されるような処理を,Text::Textile を使ったアプリケーションにも組み込みたくなり,ただ,直接処理を書くよりは,拡張部分だけを使い回しできるようなしくみにした方が後々幸せになれそう,みたいな背景のもと,Text::Textile::Pluggable という俺得モジュールを書いてみました.

GitHub で公開するとともに,PrePAN にも submit してみました(初PrePAN!).

概要と基本的な使い方

Text::Textile のサブクラスで,そこに「プラグイン」(作り方は後述)を読み込むしくみを追加しています.

使い方は次のとおりです:

use Text::Textile::Pluggable qw/textile/;
 
# procedural usage
my $html = textile($text, [qw/Foobar +MyApp::Textile::Plugin/]);
 
# OOP usage
my $textile = Text::Textile::Pluggable->new(
    plugins => [qw/Foobar +MyApp::Textile::Plugin/],
);
$html = $textile->process($text);

プラグインを読み込むことを除けば, 使い方は Text::Textile と同様です.(プラグインを読み込まなければ,Text::Textile そのまんまですねw)

プラグインの作り方

テキトーな名前のモジュールに,サブルーチン prepost を準備します.

package Text::Textile::Pluggable::Plugin::Foobar;
 
# before proceccing textiled text
sub pre {
    my $textile = shift;
    my $text    = shift;  # text BEFORE processing
    ...
    return $text;
}
 
# after proceccing textiled text
sub post {
    my $textile = shift;
    my $text    = shift;  # text AFTER processing
    ...
    return $text;
}
 
1;

pre には Textile記法 → HTML 変換前のテキストに対する処理を,post には変換後のテキストに対する処理を記述します.必要なければ定義は不要です.

名前空間を Text::Textile::Pluggable::Plugin::* とすれば,プラグイン読み込み時に plugins => ['Foobar'] のように省略できますが,必ずこの名前空間に従う必要もなく,好きな名前で作れます.

package MyApp::Textile::Plugin;
 
...
 
1;

独自の名前で準備した場合には, plugins => ['+MyApp::Textile::Plugin'] とすることで読み込めます.

サンプル

サンプルプラグインとして,次の2つを同梱しました:

  • Text::Textile::Pluggable::Plugin::GitHub::Links
  • Text::Textile::Pluggable::Plugin::GitHub::Gist

GitHub::Links プラグインは,github:issm とか github:issm/p5-Text-Textile-Pluggable とかの表記を,GitHub へのリンクに置き換えます.

% perl -MText::Textile::Pluggable=textile -le 'print textile("github:issm")'
<p>github:issm</p>
% perl -MText::Textile::Pluggable=textile -le 'print textile("github:issm", [qw/GitHub::Links/])'
<p><a href="https://github.com/issm">github:issm</a></p>
% perl -Ilib -MText::Textile::Pluggable=textile -le 'print textile("github:issm/p5-Text-Textile-Pluggable", [qw/GitHub::Links/])'
<p><a href="https://github.com/issm/p5-Text-Textile-Pluggable">github:issm/p5-Text-Textile-Pluggable</a></p>

GitHub::Gist プラグインは,gist:123456 とか gist:123456#file1 とかの表記を,番号「123456」に該当する gist のコードを埋め込むためのコードに変換します.

% perl -MText::Textile::Pluggable=textile -le 'print textile("gist:123456")'
<p>gist:123456</p>
% perl -MText::Textile::Pluggable=textile -le 'print textile("gist:123456", [qw/GitHub::Gist/])'
<script src="https://gist.github.com/123456.js"></script>
% perl -MText::Textile::Pluggable=textile -le 'print textile("gist:123456#file1", [qw/GitHub::Gist/])'
<script src="https://gist.github.com/123456.js?file=file1"></script>

おわりに

以上,Textile記法をちょこっと独自拡張するのに便利(自称)なモジュール Text::Textile::Pluggable を書いてみた,というお話でした.

とりあえずは,お仕事用に作っているアプリケーションにおけるTextile記法まわりを拡張するところから始めてみるとします.

1 of 9912345...102030...99
  • twitter
  • facebook
  • github
  • hatena bookmark
  • SlideShare
  • flickr
  • foursquare
  • ustream
  • tumblr
  • friendfeed
  • mixi
  • Apple
  • WordPress
  • come icons are powered by komodomedia!