adiaryでシンタックス・ハイライト

外部ライブラリ(JavaScript)を使用するので、"adiaryで"とか書いてしまうと、半ば釣りと思われるかもしれませんが、気にせず参ります(笑)

できるだけシステム的な変更はなしで、外部ライブラリを使用してシンタックスハイライトを実現する方法を検討してみました。(少ないですけど)

adiaryで、実装だけしてあって、特に利用することのない>|filetype|~||<記法をうまく使ってやりたいなと思います。

google-code-prettifyで解決

これを利用するのが最速っぽいです。言語名を指定しなくても、勝手にキーワードをハイライトしてくれるので、使い勝手は良いです。また、スケルトンだけで対応できるのでシステムの変更に強く、導入が楽です。

20080916-gcp.JPG

  1. /path/to/diary.skel/_frame.htmlを/path/to/adiary/diary.user.skelにコピーします。

    以後は/path/to/diary.user.skel下の_frame.htmlを編集します。
  2. こちらのページからprettify-small-***.zipをダウンロードし、適当なディレクトリに展開します。
    私は/prettifyに入れました。
  3. 以下のコードを_frame.htmlのヘッダ部に挿入します。
    <link type="text/css" rel="stylesheet" media="all" href="<@Basepath>prettify/prettify.css">
    <script type="text/javascript" src="<@Basepath>prettify/prettify.js"></script>
    <script type="text/javascript"><!--
    (function(onload){
    if (window.addEventListener) {
    window.addEventListener('load', onload, false);
    } else if (window.attachEvent){
    window.attachEvent('onload',  onload, false);
    } else {
    window.onload = onload;
    }
    })(function(){
    var pre = document.getElementsByTagName('pre');
    for (var n = 0; n < pre.length; n++) {
    if ( pre[n].className === 'syntax-highlight' )
    pre[n].className=pre[n].className + ' prettyprint';
    }
    prettyPrint();
    });
    --></script>
    

これで完了です。あとは、記事を作成する際に

>|ruby|
module English
def hello
puts "Hello"
end
module_function :hello
end
English.hello
||<

などと書けば、ハイライトされます。(若干地味ですね。)

filetype(ここではruby)の部分は、google-code-prettifyはfiletype(言語名)を意識しないので、なんでもいいです。hogeとかfooとかでも。

わざわざ、filetypeを指定したくない場合は、挿入したコード中の

if ( pre[n].className === 'syntax-highlight' )

を削除すればOKですが、すべてのpreタグがハイライト化の対象になってしまうので、あまりよろしくないです。

SHJSで解決

もう一つは、SHJSでの対応法を。こちらは、言語ごとにjs、cssファイルがメンテできたり、表示がきれいだったりします。ただ、ほんのちょっとシステム的な変更もしなければいけません。

20080916-shjs.JPG

  1. /path/to/diary.skel/_frame.htmlを/path/to/adiary/diary.user.skelにコピーします。

    以後は/path/to/diary.user.skel下の_frame.htmlを編集します。
  2. こちらのページからshjs-***.zipをダウンロードし、適当なディレクトリに展開します。
    私は/shjsに入れました。
  3. /path/to/lib/Satsuki/TextParser/Satsuki.pmを修正します。
    if ($line =~ /^>\|(\w+)\|/) { $new_block_end = '||<'; $block_tag='pre'; $p=$tag=$atag=0; $dc="syntax-highlight"; }
    

    の部分を

    if ($line =~ /^>\|(\w+)\|/) { $new_block_end = '||<'; $block_tag='pre'; $p=$tag=$atag=0; $dc="$1"; }
    

    に修正します。

  4. 以下のコードを_frame.htmlのヘッダ部に挿入します。
    <link type="text/css" rel="stylesheet" media="all" href="<@Basepath>shjs/sh_style.css">
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_bison.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_changelog.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_cpp.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_csharp.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_css.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_diff.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_flex.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_html.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_java.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_javascript.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_latex.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_log.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_m4.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_makefile.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_oracle.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_pascal.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_perl.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_php.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_prolog.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_python.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_ruby.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_sh.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_sql.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_tcl.min.js"></script>
    <script type="text/javascript" src="<@Basepath>shjs/lang/sh_xml.min.js"></script>
    <script type="text/javascript"><!--
    (function(onload){
    if (window.addEventListener) {
    window.addEventListener('load', onload, false);
    } else if (window.attachEvent){
    window.attachEvent('onload',  onload, false);
    } else {
    window.onload = onload;
    }
    })(function(){
    sh_highlightDocument();
    });
    --></script>
    

    これは、すべてのJavaScriptをロードする欲張りバージョンですが、ロードだけでものすごく時間がかかるので、使いそうな言語だけに絞ってロードした方が良さそうです。

手順としては以上で完了です。あとは記事を書く際に

>|sh_ruby|
module English
def hello
puts "Hello"
end
module_function :hello
end
English.hello
||<

などと書けば、ハイライトされます。

filetype(ここではsh_ruby)の部分は、こちらをご参照ください。基本的にsh_言語名です。

これは、adiaryの>|filetipe|~||<記法が<pre class="syntax-highlight">~</pre>で展開されることと、SHJSのUsageが<pre class="sh_xxxx">~</pre>ということで、比較的楽に導入できそうということで試してみました。

他には?

あなたのソースコードを彩る、Syntax Highlighterまとめ - Blog.37to.netがよくまとまっています!

ほかにも使い勝手のよいライブラリがあるのかもしれません。

以前のはてなのようにText::VimColorなどを利用すれば、adiaryでもシステム的に対応できそうな気はしますが…。そんなに使用頻度ないしなぁ(笑