Highlight.jsで行番号を

長いソースコードから一部を抜粋するときに、行番号を一緒に記録しておくと後で参照できて便利です。markdownで行番号を記録できるようにしてみました。

実物はこんなかんじ。newlibのnano-malloc.cからの抜粋です。

242malloc_size_t alloc_size;
243
244alloc_size = ALIGN_SIZE(s, CHUNK_ALIGN); /* size of aligned data load */
245alloc_size += MALLOC_PADDING; /* padding */
246alloc_size += CHUNK_OFFSET; /* size of chunk head */
247alloc_size = MAX(alloc_size, MALLOC_MINCHUNK);
248

元のhighlight.jsには行番号を表示する機能がありません。ライブラリの方針によると、この機能は意図的に実装されていないそうです。この判断には納得できます。行番号は邪魔な場合が多いですし、シンタックスハイライトを行うライブラリが行番号を付与する必要は全くありません。

とはいえ、表示させるのはそれほど難しくない気がしました。<pre><code>で囲まれたコード部分を改行コードで分割し、各行を<div>で包みます。その後、各行の先頭に数字を置くだけの作業です。簡単でしょう?

さて、実際に使うためにはmarkdownから行番号を指定できなければなりません。どうせ自分しか使わないので、表記方法は

```c {malloc.c:242}
malloc_size_t alloc_size;

alloc_size = ALIGN_SIZE(s, CHUNK_ALIGN); /* size of aligned data load */
alloc_size += MALLOC_PADDING; /* padding */
alloc_size += CHUNK_OFFSET; /* size of chunk head */
alloc_size = MAX(alloc_size, MALLOC_MINCHUNK);
```

という風にしました。 最初はファイル名も一緒に表示しようとしたのですが、結構面倒だと後で気が付いたのでやめました。

行番号を表示するデメリットはコピーするときに行番号が邪魔になることです。幸い、CSSにはuser-select: noneというプロパティがあるので、これを使用しました。CSSの読み込みに失敗しても大丈夫なように、上記スタイルはHTMLに埋め込んであります。文字数的にはかなり無駄ですが、行番号を表示する機会は少ないので大丈夫でしょう。多分。

余談ですが、静的サイトジェネレータmetalsmithを使い始めてから随分経ちました。今回、metalsmith-markdownitが使用しているmarkdown-itのバージョンが古いせいでfenceブロックの横のlangAttrが取得できないことが判明しました。OSSは便利ですが、長く使おうとすると毎度のことながら苦労しますね。