Text::Vim-Colorを使えなくてもText::HatenaでSuperPreを使う

| 0 Comments | 1 TrackBack | このエントリーをはてなブックマークに追加 このエントリーのはてなブックマーク件数

こんにちわ。自分のブログで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の実行結果。

http://perl-mongers.org/2008/05/28/syntaxhighlight-with-text-hatena/app-chariot-text-hatena-thumb-400x560.png

鯖で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: 後で書く

	>|
	書かないな、きっと
	|<

1 TrackBack

TrackBack URL: http://perl-mongers.org/MT/mt-tb.cgi/26

今日は、perl-mongers.org の微調整 hack を行いました。 convert lines break で <pre> を書いた場合に、シンタックスハイライトされるように変更しました。 Text::Hatena でシンタックスハイライトの方法を、vimcolor から google-code-prettify へ変更しました。mattn さんのエントリ(Text::Vim-Colorを使えなくてもText::HatenaでSuperPreを使う - perl-mongers... Read More

Leave a comment

About this Entry

This page contains a single entry by mattn published on May 28, 2008 3:11 PM.

WebService::SimpleでYahoo!の「かな漢字変換Webサービス」を使ってみる was the previous entry in this blog.

YourFileHost の flv を WWW::YourFileHost を使って簡単にダウンロード is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Categories

Pages

Creative Commons License
This blog is licensed under a Creative Commons License.
Powered by Movable Type 4.21-en