hugo という静的サイトジェネレータを使いはじめて、 急にこのブログサイトのオレオレ静的サイトジェネレータがみすぼらしく感じはじめた。 ならば、このブログサイトも hugo で構築すればいいじゃないか、と思ったのだが、 hugo 用の気に入ったテーマが見つからない。
hugo で使うコンテンツは markdown で記述するのだが、それをHTMLに変換するエンジンには goldmark という golang 製の markdown パーサーが使われているという。 ならば、変換部分だけは goldmark を使うことにして、残りのサイト構築部分は既存のものを流用しつつ 良い感じにすればいいんじゃないの?ということで、オレオレサイトジェネレータの刷新がはじまった。
その顛末は長いので割愛するが、肝心の markdown を HTML に変換する goldmark がすばらしく便利なので、 そこだけ紹介します。
mymark ディレクトリを作成して初期化。
mkdir mymark
cd mymark
go mod init mymark
main.go に以下を記述。
package main
import (
"bytes"
"fmt"
"github.com/yuin/goldmark"
"io/ioutil"
"os"
)
func main() {
source, err := ioutil.ReadAll(os.Stdin)
if err != nil {
panic(err)
}
var buf bytes.Buffer
if err := goldmark.Convert(source, &buf); err != nil {
panic(err)
}
fmt.Println(buf.String())
}
ビルド
go build
goldmark モジュールがない!的なエラーが出るので、メッセージに従い取得して再度ビルド:
go get github.com/yuin/goldmark
go build
mymark コマンドが生成されます。 標準入力から markdown テキストを与えると結果がHTMLになって 標準出力されます。
echo '# hello world!' | ./mymark
あとは、この mymark をパスの通った場所に配置するだけです。
このブログにはコード記載が割と多いので、その部分を読みやすく出力したい。
mymark ( goldmark ) で変換した結果の HTML のコード部分にシンタックスハイライトをつけるにはどうしたらいいか?
結論としては highlightjs.org を使いました。
たとえば、次の入力に対して:
class Main {
public static void main(String[] args){
System.out.println(args);
}
}
goldmark は次の HTML を出力します。
<pre><code class="language-java">class Main {
public static void main(String[] args){
System.out.println(args);
}
}
</code></pre>
code 要素に language-java
とここでは出力されていますが、
つまり、hoge 言語に対して language-hoge というクラス名をつけてくれるわけです。
これがちょうど highlightjs.org が期待する記述と一致しているので、それがそのまま使えます。
おそらく、goldmark が highlightjs を想定しているのか、それとも、最近ではこの手の記述方法がデファクトスタンダードなのでしょうか。
詳しくは https://highlightjs.org/usage/ をご覧ください。
先ほどのシンタックスハイライトはCSSとの併用で実現するものですが、 CSSなしに直接コード部分に色付けした状態のHTMLを出力する方法がありました。
詳細はこちら goldmark-highlightingをご覧ください。
とりあえず一番単純なものの場合、コードにするとこれだけのことです。
package main
import (
"bytes"
"fmt"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark-highlighting"
"io/ioutil"
"os"
)
func main() {
source, err := ioutil.ReadAll(os.Stdin)
if err != nil {
panic(err)
}
markdown := goldmark.New(
goldmark.WithExtensions(
highlighting.Highlighting,
),
)
var buf bytes.Buffer
if err := markdown.Convert(source, &buf); err == nil {
fmt.Println(buf.String())
}
}