こんにちわ。自分のブログでtypoしまくりのmattnです。
tokuhirom氏がApp::Chariotをリリースしたので、さっそく動かしてみましたが結構使い勝手は良くて色々と弄ってます。
App::ChariotにはFormatterとしてHatena(Text::Hatena)と、Markdown(Text::Markdown)が選べるのですが、Text::Hatenaの最大の魅力と言えばやはりソースコードハイライトが出来るスーパーpre記法だと思います。
ただし、Text::Hatenaのversion0.16頃まではText::Vim-Colorを使ったシンタックスハイライトが動いていましたがversion0.20では無くなってしまいました。かつ、vimをサーバで動かせない人もいるかと思います。そこで今日はText::Hatenaを若干弄ってソースハイライトする仕組みをご紹介したいと思います。
まず、Text::Hatenaに各言語のハイライト処理を入れるのは間違いなく脳が爆発してしまいますので、ここはクライアント側にハイライトさせるべくjavascriptライブラリを使用したいと思います。
著名な所では
が有名かと思います。今日はどちらでも対応出来る様にしたいと思います。
まず、現状スーパーpre記法でもpre記法と変らないpreタグを取得するText::Hatenaを触ります。
--- lib/Text/Hatena.pm.orig Wed May 28 15:27:34 2008
+++ lib/Text/Hatena.pm Wed May 28 15:04:04 2008
@@ -209,9 +209,11 @@
sub super_pre {
my $class = shift;
my $items = shift->{items};
- my $filter = $1 || ''; # todo
+ my $item = $items->[0] or return;
+ $item =~ s/^.*?>|(\w+)|$/$1/;
+ my $filter = $1 || $item;
my $texts = $class->expand($items->[1]);
- return "<pre>\n$texts</pre>\n";
+ return "<pre name=\"code\" class=\"$filter\">\n$texts</pre>\n";
}
sub pre {
何をしているかと言うと、syntaxhighlighterが扱える形式は属性「name」に"code"という値、かつ属性「class」に言語名という形式になりますので、スーパーpre記法のハイライト指定
>|perl|
で指定されたperlをclass属性に、name属性に"code"を埋め込む修正となっています。
あとはこれを使って
use strict; use Text::Hatena; Text::Hatena->parse($text);
とすればsyntaxhighlighter向けのコードが出力されます。
さてクライアント側ですが、syntaxhighlighterの場合はCSSとjavascriptをHTMLに付け加え
<script type="text/javascript"><!--
dp.SyntaxHighlighter.HighlightAll('code');
--></script>
とすればokです。またgoogle-code-prettifyの場合は
<script type="text/javascript"><!--
(function(onload){ // load
if (window.addEventListener) {
window.addEventListener('load', onload, false);
} else if (window.attachEvent){
window.attachEvent('onload', onload, false);
} else {
window.onload = onload;
}
})(function(){
if (typeof prettyPrint === 'function') {
var pre = document.getElementsByTagName('pre');
for (var n = 0; n < pre.length; n++) {
if (pre[n].getAttribute('name') === 'code') {
var classNames = pre[n].className;
classNames = classNames ? classNames.split(/\s/) : [];
classNames.push('prettyprint');
pre[n].className = classNames.join(' ');
}
}
prettyPrint();
}
});
--></script>
のコードをヘッダ部に入れればそれだけでok。google-code-prettifyの場合は言語名を指定しなくても良いのです(コレデイイノダ)。
見事サーバでvimを動かさないText::Hatenaを使い、スーパーpre記法が実現出来ました。
以下App::Chariotの実行結果。
鯖でvim動かすなんてXXXって人向けですね。
追記
ちなみにこの例で使ったChangeLogは以下
2008-05-27 mattn <mattn.jp at gmail dot com>
* yahoo-text-conversion.pl: Convert Japanese Sentence by Yahoo API.
*perl-mongers.orgに記事を書いた
>|perl|
use strict;
use warnings;
use Encode;
use WebService::Simple;
use YAML::Syck;
if ($^O eq 'MSWin32') {
binmode(STDERR, ':encoding(shift_jis)');
Encode::from_to($ARGV[0], 'cp932', 'utf-8');
}
my $yahoo = WebService::Simple->new(
base_url => "http://jlp.yahooapis.jp/JIMService/V1/conversion",
params => { appid => "YahooDemo", }
);
my $response = $yahoo->get( { sentence => $ARGV[0] || 'となりのきゃくはよくかきくうきゃくだ。' } );
warn Dump $response->parse_response->{Result};
||<
* simple.c: 後で書く
>|
書かないな、きっと
|<



Leave a comment