やりたいこと
本サイトは世界最速(The world’s fastest framework for building websites)という謳い文句で知られる、 Hugo によって構築されています。
Hugoでは記事はmarkdownで記述するわけですが、たまにmarkdownゆえに表現力が少し乏しいと感じることもあります。 (それが好都合だとも思っていますが)
例えば以下のような乳幼児の体重・身長の表1 があった場合
生後 | 体重(男) | 体重(女) | 身長(男) | 身長(女) |
---|---|---|---|---|
0月 | 3.00 | 2.94 | 49.0 | 48.5 |
1月 | 4.79 | 4.47 | 55.6 | 54.6 |
2月 | 5.84 | 5.42 | 59.1 | 57.9 |
3月 | 6.63 | 6.15 | 62.0 | 60.7 |
4月 | 7.22 | 6.71 | 64.3 | 63.0 |
5月 | 7.66 | 7.14 | 66.2 | 64.9 |
ではなく
生後 | 体重 | 身長 | ||
---|---|---|---|---|
男 | 女 | 男 | 女 | |
0月 | 3.00 | 2.94 | 49.0 | 48.5 |
1月 | 4.79 | 4.47 | 55.6 | 54.6 |
2月 | 5.84 | 5.42 | 59.1 | 57.9 |
3月 | 6.63 | 6.15 | 62.0 | 60.7 |
4月 | 7.22 | 6.71 | 64.3 | 63.0 |
5月 | 7.66 | 7.14 | 66.2 | 64.9 |
とした方が分かりやすくないですか?
とにかくはじめます🍛
markdown-it
上記のような表は markdown-it と呼ばれるモジュールおよびそのプラグインを使用すると実現できます。
そしてHugoのショートコードを利用して、特定のmarkdownだけmarkdown-it
を使って変換をさせます。
つまりこんな感じ
{{<markdown>}}
ここは`markdown-it`で処理させる
{{</markdown>}}
Hugoのmarkdownエンジンを変更するのではなく、特定のmarkdownだけを変換対象とする考え方です。 これによりできるだけ世界最速の邪魔をしないようにします。
ショートコードの作成
markdown文字列は
netlifyの Functions
を通じてmakdown-it
により変換するだけです。
{{ $query := .Inner | base64Encode | querify "s" | printf "%s" }}
{{ $endpoint := printf "%s/markdown?" $.Page.Site.Params.api_endpoint}}
{{ $jsonData := getJSON $endpoint $query }}
{{ $html := $jsonData.m }}
{{ safeHTML $html }}
ちなみにquerify
を使ってエンコードしないと、 Base64でエンコードされた+
記号がURLではスペースに変換されてひどいことになります。
Functionsの作成
Functionsについては以前の記事も参考にしてください。
まず必要なモジュールをインストールします。 テーブルの変換には markdown-it-multimd-table というプラグインを使います。
$ npm install makdown-it markdown-it-multimd-table
あとはこれで変換する処理を行う関数を書きます。
const md = require('markdown-it')()
.use(require('markdown-it-multimd-table'),
{enableRowspan: true})
exports.handler = (event, context, callback) => {
const s = event.queryStringParameters.s
const t = Buffer.from(s, 'base64').toString()
callback(null, {
statusCode: 200,
"headers": {
"Content-Type": "application/json; charset=utf-8",
},
body: JSON.stringify({
html: md.render(t)
})
})
}
行結合もサポートするため{enableRowspan: true}
を付けています。
結果
冒頭のテーブルはmarkdown
ショートコードを利用して、以下のように記述すれば生成されるようになりました。
|生後 | 体重 || 身長 ||
|^^ | 男 | 女 | 男 | 女 |
|------- | ------- | ------- | ------- | ------- |
|0月 | 3.00 | 2.94 | 49.0 | 48.5 |
|1月 | 4.79 | 4.47 | 55.6 | 54.6 |
|2月 | 5.84 | 5.42 | 59.1 | 57.9 |
|3月 | 6.63 | 6.15 | 62.0 | 60.7 |
|4月 | 7.22 | 6.71 | 64.3 | 63.0 |
|5月 | 7.66 | 7.14 | 66.2 | 64.9 |
おまけ
ちなみにオプションやプラグインを設定すれば、テーブル以外も表現の幅は広がります。
例えばhtml
とlinkify
オプションを有効にすると
Option | サンプル
------- | ------
html | <div style="transform:rotate(-30deg);">回転</div>
linkify | gohugo.io
は以下のように表示されます。
html
はhtmlタグを直接記入可能linkify
はリンクを自動で判別
Option | サンプル |
---|---|
html | 回転 |
linkify | gohugo.io |
html
を直書きする機会は少ないですが、likify
はリンク集などを作る際には便利かもしれません。
追記(2019/12/15)
Hugoの0.60.0
よりマークダウンのエンジンが goldmark になったようです。2
これによりlinkify
など CommonMark に準拠した機能であれば標準でも利用可能になりました。
ただ本記事でやりたかったセル結合などはできないので、やはりmarkdown-it
はまだ必要になりそうです。