(Prototype) Org-marginalia: Write margin notes with Org Mode

Hi folks,

I took the liberty of whipping up yet another tool (call it procrastination).
Source code to be shared soon on GitHub if there is interest.

This time, you can write margin notes that can work with Org-roam.

I am learning French. I thought this might be a good tool to add translations and grammatical notes on the “margin” of the original French text.

Feedback welcome.

I think this is something you were looking for in our GitHub conversation?

Figure 1. Left: main note; Right: “marginalia” file

Figure 2. It uses the standard Org Mode link, so it works well with Org-roam

Figure 3. The source note can be any other text files; Left is .el file to annotate a program

I have looked at following tools for annotation currently available in Emacs. I thought I could use one of them, but not for the way I want:

They seem to be targeted for annotating very brief comments to a software program (mostly fixed-pitch), annotate the entire file, or works only with Org notes.

I wanted something more flexible, and works with Org-roam.

Do you know of any other package? I could not find any more, so I quickly put together a new one (very rough, but works for me now).


I think this is something you were looking for in our GitHub conversation?


Can not wait to play with it. :yum:

Add to GH :wink:


Hello folks:

I’ve hooked up a posframe for nobiot’s org-marginalia.

You can find the code here:

As an inexperienced elisp player, there must be a more elegant solution. Suggestions are welcome.

1 Like

Looks like if I return t from om/next or prev when success, then you don’t need to override the functions. Let me see what I can do…

Yes. I’ve tried to advise om/next or prev, but I could not make it, so I just walk around by this.

I was studying the advice-add and found (info "(elisp) Advising Named Functions") the suggestion of using hook. I was about to ask it.

   ‘advice-add’ can be useful for altering the behavior of existing
calls to an existing function without having to redefine the whole
function.  However, it can be a source of bugs, since existing callers
to the function may assume the old behavior, and work incorrectly when
the behavior is changed by advice.  Advice can also cause confusion in
debugging, if the person doing the debugging does not notice or remember
that the function has been modified by advice.

   For these reasons, advice should be reserved for the cases where you
cannot modify a function’s behavior in any other way.  If it is possible
to do the same thing via a hook, that is preferable (*note Hooks::).  If
you simply want to change what a particular key does, it may be better
to write a new command, and remap the old command’s key bindings to the
new one (*note Remapping Commands::).

Try the latest main branch. I think I managed to return t/nil based on the success of om/next and om/prev. You should be able to use that to do postframe operation.

Thanks for this modification.

I’ve changed the preview function by using wrappers in this commit.

Great :blush:. This might be a little too technically specific to our stuff (away from Org-roam too much), but just very quickly. I just added transient navigation, that is to allow C-c n [ [ [, without needing to press C-c n again and again to jump around. Your next/previous function might automatically “inherits” this by the looks of how you do it (it might not). You might like to update OM and try it :wink:

1 Like

Hi @nobiot,

I tried the package, nicely done! As a constructive criticism: I wonder if some of the interactions should be a little more fluid; e.g., marking, saving, and opening all at once when creating a new annotation? Similarly, browsing comments a bit more fluidly. Some suggested code for these additive features below.

One deeper change that I didn’t implement: I think that there should be a function om/delete that removes both the highlight and also the the headline and notes. Relatedly, I wonder if there should be a config variable so that when a new annotation is created with an existing headline, it should go under the old headline rather than a new headline. (I’m guessing that might require a bit of thinking to implement?)

(defun om/make-annotation ()
  (let ((mark-end (region-end)))
    (om/mark (region-beginning) (region-end))
    (om/open (1- mark-end))
(define-key org-marginalia-mode-map (kbd "C-c M") #'om/make-annotation)
(defun om/browse-forward ()
  (let ((buf (current-buffer)))
    (om/next) (om/open (point))
    (pop-to-buffer buf nil t)))
(define-key org-marginalia-mode-map (kbd "C-c n }") #'om/browse-forward)
(defun om/browse-backward ()
  (let ((buf (current-buffer)))
    (om/prev) (om/open (point)) (pop-to-buffer buf nil t)))
(define-key org-marginalia-mode-map (kbd "C-c n {") #'om/browse-backward)

The integration with org-roam shouldn’t be underestimated: with the *org-roam* buffer open, the marginal notes all show up together; that’s nice.

This does suggest a critique for org-roam itself, since the marginal notes don’t immediately update inside that buffer when they’re created. Is there a way to force the backlinks buffer to update other than to browse wiki links.

BTW I’ve been interested in related kinds of software tools for a while and will hopefully get back to work on the annotation-driven system that I started way back in 2005! People have often asked me how it related to Org Mode and your package might be one useful “bridge”. I never got around to properly packaging up my code, but if you’re curious what the heck I’m talking about, info is here: https://repo.or.cz/w/arxana.git

Great! Thank you. I need to spend some time using your code and come back to you. Browsing is something I wanted to implement. I have some thoughts around the make-annotation. Regarding Org-roam buffer update, while the project is working to revamp the side buffer, there is a workaround. Revert buffer or OR’s update buffer. I’ll come back to this point too.

C’est toujours super de voir quelqu’un apprendre le français :slight_smile:

Great, i’m an heavy user of margin/footnotes, so i’m really interested by your project.
Some question/remarks :

  • That could be really nice if margin note are exported as margin note by using ox-publish export. By example by cherry picking this part on ox-tufte ?
  • How do you differentiate a footnote from a classic roam ZK link ? Because this is not totally the same thing by concept IMHO. In my mind, even if footnote are huge they are limited in size, linked to some sort of final publication (thesis, memoir, webpage, etc.) I see that more constrained than a ZK note.

Merci. C’est un long chemin :slightly_smiling_face:

For export:
There is also a feature request. I looked at ox-tufte. I have to say that publishing is not top of my list at the moment, but I am also interested in something like this. I might put together something real quick (with a lot of limitations, but as a minimal feature); or it will need to wait until April/May 2021 – but I want to see something. The minimal idea is simply:

  1. Assume you’re exporting Org file (marginalia works for any text files, so I will not try a generic feature to cover all possibilities)
  2. You have ox-tufte set up for your PC (but I don’t want to make it a dependency to use marginalia)
  3. Margin notes are reasonably small with no sub headlines

Then I think I could use one of the org-export-hooks to insert the margin notes to be included as Tufte’s marginnotes.

For footnote vs classic ZK link:
Technically speaking, a link from margin notes back to the main file is a regular Org link – this is the reason why we get backlink feature from Org-roam without doing anything extra.

You can differentiate margin notes from other links because they are in the marginalia file – every note you write in the marginalia file is margin notes.

1 Like

Just quickly for this. This below works for me.

  (defun my/update-org-roam-buffer ()
    (when (and (functionp #'org-roam--org-roam-file-p)
               (org-roam--org-roam-file-p (buffer-file-name (current-buffer)))
               (not (eq (org-roam-buffer--visibility) 'none)))
      (setq org-roam--current-buffer (current-buffer))

  (add-hook 'after-save-hook #'my/update-org-roam-buffer 50)

(WRONG) org-roam--org-file-p
(CORRECT) org-roam--org-roam-file-p

Tried to implement one. Not good. Spent a whole day, struggling with org-export and margin notes syntax of ox-tufte. I won’t go into detail but I need to change the course. Footnotes might work better.

In any case, I will put the export feature to the back burner; it will need to be something I’ll come back to in May or so in the new year.


Have a good rest. Take away from Emacs world for a while. When you back, everything will be good again. : )

ah no, I just have a backlog of stuff to do until April as you know. Emacs is my tool for procrastination and productivity in one package :package:

1 Like

For now, I have added your great suggestions as part of README. I will come back to it after my other project is in a better shape (book writing…) :wink:

1 Like

Nice work!

Are you aware of the marginalia package? Might be confusing to have two packages with same base name, that have no relation?

Thank you.

Yes, I am aware; I use it myself.
I don’t feel strongly about the name, but not sure if this “confusion” is something I should avoid.

  1. The packages do not have overlapping functions.
    Marginalia displays (and only displays) additional information on the margin of minibuffer. Org-marginalia lets you write marginal notes in Org Mode for other text files

  2. If both packages used a common word, e.g. Annotation vs Org-annotation, this perceived confusion seems to go away (my personal gut feel). “Marginalia” is not a common word; perhaps that’s the source of perceived confusion. I am not sure if I should mind it (maybe there is a good reason to mind it)

  3. Maybe it’s good for searching. This confusion might help serendipitous discoveries – e.g. you are trying to get marginalia, and hit upon `org-marginalia. “Cunning” strategy? Maybe, but I don’t find it problematic, as they have no competing features.

What do you think? Like I said, I am not strongly attached to the name. I’d prefer om as prefix even :wink: Maybe if I propose it to be part of MELPA (if or when), the reviewer may have some advice on this matter.