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
というコマンドがあり、ここから着想を得た。