Powerful emacs hacks: patching markdown-mode
I recently read a beginners guide to extending emacs and it describes why I love emacs perfectly:
I haven’t written plugins for other editors extensively, but I can tell you this: emacs doesn’t just make deep customization available, but it actively encourages you to make an absolute customization messes masterpieces. Core editor functions aren’t just documented, but often include tidbits about “you probably want to see this other variable” or “here’s how you should use this”.
Not only that, but emacs happily hands you functions shaped like nuclear warheads like advice-add (that let you override any function) that can absolutely obliterate your editor if you hold it the wrong way. Of course, this also grants you unlimited power.
Remember that emacs is designed to be torn apart and rearranged.
So let me show you this philosophy with a walk through of how I hack emacs to my liking.
Problem
I write my blog posts in markdown, and use my handwritten static site generator genox to convert all markdown files into a nested directory of html files.
For images to show up correctly in my html files, they need to be written like so in markdown:

This image is stored under src/media/ but my markdown file
referencing this image is stored in src/blog/.
Now when I’m editing my markdown file (and I link to an image) I don’t want to see this line, I want to see the actual image right there.
Something like this:

And emacs does support it, but only if it can find a correct relative
link to it. But emacs can’t understand where to look for a file
starting with /media/.. for the file I have opened.
If you were using any other editor
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 fmy shortcut to call(describe-function) - I search for
markdown inline imageand 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/