Elmでスライド資料を作ったりだとか、一緒に開発する人のためにスタイルガイドやユーティリティ関数の使い方のドキュメントを作るときなど、Elm製アプリの中でコードをハイライト表示したいことがあります。
この記事ではElm製アプリで便利にコードハイライトを行う方法を紹介します。
Highlight.js
JS でコードハイライトを行うライブラリと言えば highlight.js などが有名ですが、Getting Started で触れられている initHighlightingOnLoad を呼ぶ方法ではうまくいきません。
この方法はページロード時に存在しているDOM要素の中からハイライトしたいコードを見つけるものですが、Elmアプリの場合はページロード時にはDOM要素がまだ生成されていないからです。
動的な要素のハイライト表示
highlight.js には highlight(name, value, ignore_illegals, continuation) という関数が用意されており、動的に生成される要素をハイライト表示することができます。
ただ、ハイライトしたい要素を描画する度に逐一 port でこの関数を呼ぶのは手間がかかりすぎる気がします...
elm-explorations/markdown
ここで、elm-explorations/markdown の登場です。
Elm作者であるEvanはズルいので、一般人には許されない内緒の方法で JS のコードを内部的に直接実行できる Elm ライブラリを作成して公開する権限を持っています。
elm-explorations/markdown はそんなズルいライブラリの1つで、内部的に highlight.js の highlight
を使っています。
本来の用途としては Markdown のテキストを受け取って Html.Html msg
に変換するものですが、
myCode : Html msg
myCode =
Markdown.toHtml []
"""
```elm
view =
Atom.row
[ basicBlock
]
```
"""
のようにすると、以下のようなDOMが作られます。
<pre><code class="lang-elm"><span class="hljs-title">view</span> =
<span class="hljs-type">Atom</span>.row
[ basicBlock
]
</code></pre>
これをブラウザで表示すると、ハイライトされて見えるようになります。
elm-explorations/markdown 使用上の注意
実際に使用する際には、elm-explorations/markdown が highlight.js 自体を内包しているわけではないことに注意してください。
単に windows.hljs.highlight()
といった形で、highlight.js の関数が windows.hljs
として使える状態になっていることを想定しています。
そのため、highlight.js が提供する CSSファイルだけでなく、
たとえば以下のような方法で別途 highlight.js を読み込んでおく必要があります。
- HTMLのヘッダー要素で highlight.js を読み込む
- Elm内で highlight.js を読み込む (公式パッケージサイトの例)
- npm install した highlight.js を
require
したりして読み込んでおく (例)
また、toHtml
関数は文字列の Parsing を行っている関係ですこし重い処理になっています。
Html.Lazy.lazy
などを活用することで、不必要な再評価が起きないように工夫してください。
より詳しい使い方については、elm-explorations/markdown を使ってスタイルガイドを作成している elm-atomic-design-example などもご参照ください。