markdown-modeに VSCodeっぽい画像貼り付け機能を実装した

github.com

Emacs 29に yank-media という機能が追加されて clipboardにあるデータを各モードで自由にハンドリングできるようになった. VSCodemarkdownを書いているときに画像をペーストすると inline linkが挿入されますが、それと同じようなことができるように markdown-mode に機能を追加しました. ただし Emacsでは普通の yankでは実現できなくて, M-x yank-media という別のコマンドを使う必要があります. (clipboardの中身を見て先頭が画像だったら挙動を変えるとかの関数を自分で実装すればいけるとは思います). あと Emacs29以上が必要になります.

example

ブラウザでコピーした画像を markdownファイルに貼り付けている例になります.

実装

例として html-mode で clopboardの画像を img タグで Base64で貼り付ける場合を示します.

(add-hook 'html-mode-hook (lambda ()
                            (yank-media-handler "image/.*" #'html--image-media-handler)))

まず各種 major-modeやその hookで yank-media-handler 関数を呼び出して, マッチさせたい mime-typeの正規表現とそのハンドラを設定します. ハンドラの引数は 2つあって, 1つめが mime-type, 2つめがデータになります.

(defun html--image-media-handler (mimetype data)
  (let* ((mime (mailcap-mime-type-to-extension mimetype))
         (base64 (base64-encode-string data))
         (img-tag (format "<img src=\"data:image/%s;base64,%s\" />" mime base64)))
    (insert img-tag)))

ハンドラの実装はこのようになります. あとは dataを好きなように扱ってやればよいです. mime-typeをどうかしたい場合は, mailcap packageなどに各種ユーティリティがあるので探してみるとよいでしょう.