Crest
Published:
15 December 2025 / 25 Frimaire 234
Last Edited:
15 Dec 2025

Handwritten notes in Emacs using Xournal++

My girlfriend recently bought a Framework 12 laptop1 with a correspoding stylus and, influenced by my ravings about the power of GNU Emacs, wants to take handwritten digital notes on it for her engineering and mathematics classes and then organise them in org-mode. I see a younger version of myself clearly in her, and of course want to help her attain the vision she has for her own Emacs system. At the same time I am a strong believer in that you should not try and learn Emacs, but that it should be molded to your own personal desires. For that reason I try to act in merely an advisory capacity, while helping whenever she asks.

At first we discovered an old package named org-xournalpp that seems to fit perfectly. It creates xournal++-specific links that opens the corresponding xournal file whenever clicked, and they are rendered like inline images in the org-mode buffer. We had some trouble getting Emacs to load the file after installing with the new built-in :vc keyword for use-package (it worked fine on my machine, but not hers) but after installing it the inline previews would not be displayed. Worse yet, running the included org-xournalpp-mode (that tries to render the images) would cause Emacs to freeze.

But how hard can it be to implement your own version of this functionality? Org-mode already has the ability to display inline images (as I am well familiar with) and xournal++ can export to both .png and .svg formats. For this we wrote a small function that uses xournalpp to export a given file to png format and then inserts a link to it in the buffer.

  (defun create-png-xournal-file (&optional only-export)
    "Creates a png from a xournal file and inserts it into the buffer."
    (interactive "P")
    (let ((file-name (expand-file-name
                      (file-name-sans-extension
                       (read-file-name ".xopp file to convert: ")))))
      (shell-command (format "xournalpp --create-img=%s.png %s.xopp"
                             file-name file-name))
      (unless only-export
       (kill-new (concat "[[" file-name ".png" "]]"))
       (yank)
       (org-display-inline-images))
      (org-redisplay-inline-images)))

  (bind-key "C-ö" 'create-png-xournal-file)

If org-startup-with-inline-images is t this is then immediately rendered as an image in the buffer. If called with a prefix argument (usually C-u) this skips the insertion part and calls org-redisplay-inline-images to get an updated version.

The experience of imagining functionality that you wish was possible and in an afternoon creating a program (even one as small as a single 11-loc function) that fulfills your requirements is something that you rarely get outside of Emacs. Even in other free software, few programs open themselves so fully to introspection and modification. Something as simple as the *scratch*-buffer, with its use as a quasi-persistent REPL, invites creative solutions and problem solving — not to mention the self-documenting capabilities of C-h and docstrings.

While I am not one of those users insistent on reducing the number of packages installed2, there is a certain perspective that you should be emphasised; You can easily make do with home-grown functionality that builds on packages you already have installed, or the rich functionality that already comes with Emacs.

Footnotes:

1

For the short period she’s had it now it seems like a great product, but I still prefer the philosophy of MNT Research. It is however good enough that I do not have any issues with linking to it.

2

My current count as of writing this is 134.

Tags: technology emacs