TracのシンタックスハイライトでPHPのタグを省略可能にしてみた

TracWikiWikiプロセッサという機能を利用することでソースコードシンタックスハイライト表示ができるんだけど、PHPソースコードは<?php 〜 ?>で括ってあげないとハイライトしてくれない。
PHP的にはPHPタグ(?)外の部分は標準出力される部分になるので、それはそれで正しいのだけど、数行だけ書きたい場合などに不便だったのでPHPタグがなくてもハイライトしてくれるようにハックしてみた。

Pygmentsのオプションで制御

PHPシンタックスハイライト処理はPygmentsというライブラリを使っているようなので、Pygmentsのソースを眺めてみると


PhpLexer

    `startinline`
        If given and ``True`` the lexer starts highlighting with
        php code (i.e.: no starting ``<?php`` required).  The default
        is ``False``.

lexers/web.py

というオプションを発見。

ソースとHTMLを一ファイルに書くようなオールドスタイルもあるかもしれないので、<?phpが含まれていなかった時だけstartinlineオプションを有効にする、という方針で呼び出し側のTracのコードを書き換えてみた。

パッチ

http://eureka.pasela.org/products/scripts/trac/trac_pygments_php_inline.patch

--- trac/mimeview/pygments.py	2009-04-17 11:13:06.000000000 +0900
+++ trac/mimeview/pygments_php_inline.py	2009-04-17 12:09:03.000000000 +0900
@@ -187,7 +187,10 @@
         )
 
     def _generate(self, language, content):
-        lexer = get_lexer_by_name(language, stripnl=False)
+        if language == 'php' and re.search(r'<\?php\s', content) == None:
+            lexer = get_lexer_by_name(language, stripnl=False, startinline=True)
+        else:
+            lexer = get_lexer_by_name(language, stripnl=False)
         return GenshiHtmlFormatter().generate(lexer.get_tokens(content))
 
 

これをtrac_pygments_php_inline.patchとか適当な名前で保存して、tracディレクトリと同じ階層に置いて

patch -p0 <trac_pygments_php_inline.patch

とかやればパッチが当たる(まぁ、位置は-pで調整してくれ)。

既に稼働中の場合はサーバを再起動すればいいんだけど、Webサーバが書き込み権限持ってない位置にインストールしてあるときは一時的にtrac/mimeviewとpygments.pycの書き込み権限を与えてあげないと.pycが更新されないので注意。

こう書ける

従来

{{{
#!php
<?php
function hello() {
    echo 'Hello, Trac World!';
}
?>
}}}

パッチ後

{{{
#!php
function hello() {
    echo 'Hello, Trac World!';
}
}}}