google-code-prettifyをIEでわりとまともに使うパッチ

やっぱり、コードはぷりちーにプリントしたいよね。それはまさに、全人類の夢。

というわけで、google-code-prettifyについていろいろ調べてたら、IEではpre要素に対してinnerHTMLでテキストを流し込むと、ホワイトスペースが正しく反映されないという、すてきな仕様のため、改行が表示されないやら、コピー&ペーストしたときにおかしくなるやらで、導入を見送ったって人が結構いるみたい。そして、残念な事に、その後、解決したっていう話を聞かないんだよね。

実はこの問題だけど、IE6に対しては、Issue 21: Fix for innerHTML quirkで解決してるよ。かなり力技にみえるけど、強引に解決しちゃうんだもんね、Google...恐ろしい子。

とりあえず、プロジェクトのホームにリンクされてるprettify_31_Aug_2007.zipは古いので、SVNリポジトリから、trunkをチェックアウトしてくれば幸せになれそう。今のところ最新は、リビジョン35だね。

だけど、世の中そんなに甘くはなくて、なんとIE7でも同じ問題が発生するのであった(Microsoftさんお願いしますよ)。だったら、ハックしろってことで、IE7でもIE6の時と同じ処理を行うように修正した。それから、'\r\n'に置き換えると、行頭に余分なスペースが表示されちゃうみたいなので、'\r'に置き換えるようにした。

diffはこんな感じ。

117,121c117,122
< function PR_isIE6() {
<   var isIE6 = navigator && navigator.userAgent
<       && /\bMSIE 6\./.test(navigator.userAgent);
<   PR_isIE6 = function () { return isIE6; }
<   return isIE6;
---
> function PR_isIE() {
>   var isIE = navigator && navigator.userAgent
>       && (/\bMSIE 6\./.test(navigator.userAgent)
>        || /\bMSIE 7\./.test(navigator.userAgent));
>   PR_isIE = function () { return isIE; }
>   return isIE;
937c938
<   var isIE6 = PR_isIE6();
---
>   var isIE = PR_isIE();
1010c1011
<           if (isIE6 && cs.tagName === 'PRE') {
---
>           if (isIE && cs.tagName === 'PRE') {
1015c1016
<                   document.createTextNode('\r\n'), lineBreak);
---
>                   document.createTextNode('\r'), lineBreak);

パッチも置いておくので、必要な人はどーぞ。

prettify-r35-ie-hack.js.patch

ただ、ソースにもコメントがあるけど、これだとレンダリングが遅くなっちゃうみたい。結局、IEの場合はgoogle-code-prettifyを使わないってのが正解かもね。