Powerful emacs hacks: patching markdown-mode
Why do I love emacs? Let me show you.
Problem
My blog expects images with absolute directory like so:

But I don’t want to see this line, I want to see the actual image right there. And emacs does support it, but only if it can find a correct relative link to it. So I want it to look something like this:
But emacs can’t understand where to look for a file starting with /media/..
for the file I have opened.
If you were editing this inside a browser using some CMS then you wouldn’t have the problem, as /media
would be served by your http server. But I am editing my blog posts inside emacs. Like me, most devs use an editor, espeically if they are using static site generators. Editor like emacs / vscode / obsidian support displaying images given they can resolve the path correctly to a file. (vim doesn’t support displaying inline images as far as I know?, maybe gui vim/neovim does)
These editors don’t understand where to render /media
from. Some editors try to render it from git project root. Some editors need extra plugins to resolve the file paths. None of this works easily.
Emacs, by default, tries to open /media/...
from the actual root of your filesystem which obviously fails.
In my project, the images are actually stored in a ../media/
folder relative to the Markdown file of the blog post. So Emacs needed a little help.
Exploration
- I hit
SPC h d f
my shortcut to call(describe-function)
- I search for
markdown inline image
and I find a function calledmarkdown-toggle-inline-images
. - I look up it’s source, it takes me to
makrdown-mode.el
- I see something called as
markdown-translate-filename-function
- Be amazed, thank the library developers for thinking of this use case
- Ask chatgpt for a quick translate function:
(defun genox/markdown-translate-image-path (path)
"Translate /media/... image links to ../media/... relative to buffer."
(if (string-prefix-p "/media/" path)
(let ((path* (expand-file-name
(substring path 7) ;; strip "/media/"
(expand-file-name "../media/" (file-name-directory (buffer-file-name))))))
(message "Markdown path")
(message path*)
path*)
path))
(add-hook 'markdown-mode-hook
(lambda ()
(setq-local markdown-translate-filename-function
#'genox/markdown-translate-image-path)))
- It doesn’t work :(
- Start debugging
✨ The Emacs Magic
I read the code for markdown-toggle-inline-images
to see that it’s calling markdown-display-inline-images
.
Looking at the code I see this:
Voila. This function only uses markdown-translate-filename-function
to download a remote file. If it’s not a valid URL, then it won’t set the file correctly.
That is not what I want.
So I patch the above code quickly:
Re-evaluate it right there (emacs is a live programming environment, you can think of it as hot swapping of code), switch to my blog post buffer and check if it works! And it does :D
I then copy the entire function and add it to my emacs config file init.el
and done! I’ve patched a third party library emacs function within minutes.
(use-package markdown-mode
:config
(defun markdown-display-inline-images ()
...)
There are probably better ways to achieve this, but I got this done within minutes, and now I shall move on until this breaks after 5 years and I spend some more time looking at it.
If this was any other editor, I’d either need to create my own extension, patch the existing extension and get that setup locally, or maybe even fork the entire editor to get this done?
Read next post in the series: https://oxal.org/blog/powerful-emacs-hacks-paste-images-markdown/