Mukai Systems

Syntax highlight for Paren

「Lispのよいところを述べよ」と言われたら、少なくないLisperが構文の簡潔さを挙げるだろう。

LispはS式によって記述される。S式とは、リストまたはアトムのことをいう。リストは零個以上のS式からなる。アトムは文字列や数値などのそれ以上分解できないもののことをいう。

プログラム = S式 ...
S式 = リスト | アトム
リスト = ( S式 ...)

典型的な(そして、ちょっとわざとらしい)Parenのプログラムは以下のようなものである。

(function main (args)
  (println "hello world"))

このプログラムは1つのS式からなる。そのS式は4つのS式function, main, (args), (println "hello world")からなるリストで、…といった具合である。

構文の簡潔さを活かして、ブログ内のParenのソースコードを読みやすくするためのシンタックスハイライトを自作してみた。1

例えば、以下のようなhtmlがあるとしよう。

<pre><code class='paren'>
(function main (args)
  (println "hello world"))
</code></pre>

pre code.parenなエレメントに対して、JavaScriptでtokenizeして以下のようなhtmlに変換できたとしよう。

<pre><code class='paren'>
<span class="delim">(</span><span class="symbol reserved">function</span><span class="space"> </span><span class="symbol">main</span><span class="space"> </span><span class="delim">(</span><span class="symbol">args</span><span class="delim">)</span><span class="space">
  </span><span class="delim">(</span><span class="symbol reserved">println</span><span class="space"> </span><span class="string">"hello world"</span><span class="delim">))</span>
</code></pre>

事前に以下のようなcssを定義しておけば、目的が達成されることになる。2

code .keyword, code .global { color: #a4e1f9; }
code .reserved { color: #e67a45; font-weight: bold; }
code .constant { color: #87ceeb; }
code .string { color: #ffaaaa; }
code .number { color: #fadd5a; }
code .comment { color: #a6f02e; }
code .delim { color: #40e0db; font-weight: bold; }
code .method { color: #fad07a; }

この方法を用いれば、新しい言語を作成した際もその言語の字句解析機だけ作成すれば、同じCSSでハイライトできる。

Examples

以下の例は以下に示すようなトークンを一通り網羅してある。

; comment
(function foo (args)
  "str\"str "
  3.141592
  (assert (= (+ -1 +1) 0))
  0x3f
  23434
  (<- CONST true
         $global nil)
  (apply eval args)
  (! (== x y)))

(function main (args)
  (println "hello world"))

fontはもう少し凝ってもよいかもしれない。

Source code

More info


[1] highlight.jsを入れたのでこの記事で

[2] Vimにはバッファをhtmlに変換するTOhtmlというコマンドがあり、ここから着想を得た。