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:

![](/media/mental-model-shift-to-start-blogging-1.png)

This works great for web URLs or static site generators that treat /media as a root folder. But 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. So Emacs needed a little help.

Exploration

  1. I hit SPC h d f my shortcut to call (describe-function)
  2. I search for markdown inline image and I find a function called markdown-toggle-inline-images.
  3. I look up it’s source, it takes me to makrdown-mode.el
  4. I see something called as markdown-translate-filename-function
  5. Be amazed, thank the library developers for thinking of this use case
  6. 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)))
  1. It doesn’t work :(
  2. 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 live 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?