skip to content
Logo
Yurikago Blog

Marked.jsを拡張してWebP画像を表示する

/ 3 min read

Table of Contents

Marked.jsのレンダラーであるimageメソッドを拡張してWebP画像を表示する方法をまとめました。

このブログはマークダウン形式で記述した記事をMarked.jsでHTMLに変換して表示しています。このとき埋め込み画像は以下のHTMLに変換されます。

![テスト](/test.png)

<img src="/test.png" alt="テスト" />

WebP画像を表示するため、以下のHTMLを出力するようMarked.jsを拡張しました。

<picture>
<source srcset="/test.webp" type="image/webp" />
<img src="/test.png" alt="テスト" />
</picture>

画像の変換

まず既存の画像をWebP形式に変換します。Google Chrome Labsが開発した画像圧縮アプリを利用しました。サンプルとして以下のPNG画像をロスレス方式でWebP画像に変換しました。

ファイル名サイズ
test.png265KB
test.webp203KB

参考: https://squoosh.app/

Marked.jsの拡張

出力内容を変更する方法はドキュメントに記述されています。ドキュメントを参考にvueファイルのロジックを修正しました。

<script>
import marked from 'marked'
// 'raw-loader' をインストールする必要あり
import article from '~/assets/article.md'
export default {
computed: {
helpers () {
return {
// https://github.com/markedjs/marked/blob/v0.8.2/lib/marked.js#L145-L171
cleanUrl: (sanitize, base, href) => {
if (sanitize) {
let prot
try {
prot = decodeURIComponent(unescape(href)).replace(nonWordAndColonTest, '').toLowerCase()
} catch (e) {
return null
}
if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
return null
}
}
if (base && !originIndependentUrl.test(href)) {
href = resolveUrl(base, href)
}
try {
href = encodeURI(href).replace(/%25/g, '%')
} catch (e) {
return null
}
return href
}
}
},
markdown () {
// デフォルトのメソッドをオーバーライドしてWebP画像を表示する
const renderer = new marked.Renderer()
renderer.image = (href, title, text) => {
href = this.helpers.cleanUrl(renderer.options.sanitize, renderer.options.baseUrl, href)
if (href === null) {
return text
}
const out = `<picture>
<source srcset="${href}.webp" type="image/webp">
<img src="${href}.png" alt="${text}">
</picture>`
return out
}
return marked(article, { renderer: renderer })
}
}
}
</script>

参考: https://marked.js.org/#/USING_PRO.md#renderer

renderer.image のロジックはGitHubのソースコードを参照しました。

参考: https://github.com/markedjs/marked/blob/v0.8.2/lib/marked.js#L1007-L1022

マークダウンの修正

拡張子を除いたファイル名とパスを記述します。

![テスト](/test)

以下のHTMLが出力されます。

<picture>
<source srcset="/test.webp" type="image/webp" />
<img src="/test.png" alt="テスト" />
</picture>