Taking bibliographical notes (ZK nomenclature)

EDIT 03/09/24 It turns out there are some related elements that’s worth putting together here:

  • this post on this platform deals with a similar effect with :PROPERTIES: being added in a separate drawer. Somehow related (like in my case) with the use of prompts
  • this issue report deals with the same topic

Hi, first post here, go easy on me :slight_smile:

I would like to implement a Zettelkasten or slip-box and I am now focusing on creation of the bibliographical notes. These are, in my definition, a single note per paper/book/web-page, containing a :ROAM_REFS: property wich either has - automagically created - a CITEKEY citation link or a web address in case of a web publication like a blog post, tutorial, you name it.

As far as the CITEKEY part is concerned, I have found a way to obtain a first success, doing the following:

  1. install biblio, to be able to search and insert records in one’s bib file by drawing info from databases like CrossRef and the like.
  2. install org-roam-bibtex and ivy-bibtex. The first should integrate bibtex-like bibliographical information into org-roam nodes and templates, while the latter is a completion system to browse one’s bib files, but also ultimately gave me “the key” to a bibliographical note.
  3. M-x ivy-bibtex, then insert a few words, select the target record, M-o e to effectively create a note.

Having activated org-roam-bibtex-mode (BTW, how to do it by default? Is it not default because I am not in an org buffer to start with?) the associate note editing function called from within ivy-bibtex does what is needed at a basic level:


Now, I would like to add two custom features, namely:

  1. Store this type of notes in a sub-folder and not where my other “main nodes” reside
  2. Add some keywords in the property drawer

That’s where the issues arise and where I need your wisdom :smiley:

I could not trace back where the templates are defined/used for the specific note creation function, so I have tried to add another template to the default, in order to be able to implement those customizations. The relevant init.el portion looks then like this:

(use-package org-roam
  :ensure t
  (org-roam-directory "m:/ZK")
   '(("d" "default" plain
      :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
      :unnarrowed t)
     ("r" "reference" plain
      :if-new (file+head "reference/${citekey}.org"
#+title: ${title}\n")
  :unnarrowed t)))
  :bind (("C-c n l" . org-roam-buffer-toggle)
         ("C-c n f" . org-roam-node-find)
         ("C-c n i" . org-roam-node-insert))

I added a new template that saves the note in a different location with the ${citekey} variable as file name, then it should add a bunch of properties, among which I just tried to define a test one, “KEY”. It’s just a try at this point.

However, what comes out is this:

:ID:       6a4f9129-488b-44b3-9a8e-e5722dea9902
:ROAM_REFS: cite:Lou
#+title: Design of cmos rf low-noise amplifiers and mixer for wireless applications

The note is created in the location I indicated, so this is good.

However, the original template (the one I don’t know where it’s located or how to modify) is not extended, it is just put there, closed with the :END: and then my stuff is appended.
Of course then the second :ROAM_REFS: key is totally redundant, I could just remove it from the template, but I’d still like to have the extra properties before the :END:.

Finally, the question: how do I handle the creation of notes via a more flexible template, that adds properties where they should normally go?
Maybe I should just settle for adding properties after the #+title line, with the alternative
+#PROPERTY syntax and be happy?

Any comments, thoughts and suggestions very welcome!!


I found this very elegant solution by Jethro Kuan, which however I would have to adapt to work with ivy-bibtex and not citar, as I don’t have it and would not llike to add another package just for this…

This is weird. I don’t use org-roam-bibtex, so I tried this just now and had no double-up of PROPERTIES.

(setq org-roam-capture-templates
      '(("r" "reference" plain
         :if-new (file+head "test.org"
:ROAM_REFS: value
#+title: ${title}\n"))))

Jethro’s configuration does not seem specific to Citar for adding additional properties directly in the template like you, he and I all have done. I didn’t think org-roam-bibtex did anything special for this part…

How do you capture the one you referrred to above? It’s not via org-roam-capture, is it?

By the way, the ID property is added by a function during the capture process where it creates a new buffer: org-roam-capture--setup-target-location (at the bottom, there is a function call to org-id-get if there is no ID present in the buffer yet).

My understanding is that because this process is done after the capture text is added, org-id-get function simply appends the ID to this property drawer that the template adds in – this is the reason why the ID property is the last property in my example above – At least this is how I understand the capture process works for org-roam.

Thanks for your reply!

Yeah, I should have been clearer in my explanation…
First, let me declare my goal: I would like to be able to query my bibliographical data (e.g. my .bib file) for a specific record (citation), relative to which I can create an org-roam style note, i.e. one:

  • with a unique ID
  • with a :ROAM_REFS: property carrying the relevant CITEKEY
  • extra features:
    • custom save path
    • custom :PROPERTIES:

To this end, I set up the flow described above, which starts with a call to ivy-bibtex for searching the records stored in my .bib file, then, from within the ivy-bibtex buffer, use M-o to access the function menu and choose e → for “edit note”.
This last operation, which is bound to the ivy function and then to the org-roam function for note creation, does the “magic” of inserting the cite link in the :ROAM_REFS: property and the rest.

I could not understand/find how to modify this function, which is “hopping” from ivy to bibtex-completion-edit-note to bibtex-completion-edit-note-function which is then set by (org-roam-bibtex-mode 1) to point to - finally - (orb-org-ref-edit-note CITEKEY) function… I cannot understand how the last function really works as I am not familiar with lisp and am a very basic programmer.

Therefore, I resorted to trying and modifying the templates, by adding a “reference” template which I showed above.

Now, onto your question.

If I just M-x org-roam-find-node and use my template definition (it’s in the previous post), I do get this double-counting:

:ID:       d0dc7637-b758-45f1-b912-d5da5c5d2d10
#+title: New Reference No(T|D)e

TBH, I don’t know why :frowning:

Your template looks basically the same of mine, the only differences are that you are not inserting the ${citekey} bits but just giving straight values…

If you have any suggestions on how to “debug” this, I’m all ears.

The other thing I wish to mention is that inserting a node like I’ve done above does not fulfill my purpose, because there is no CITEKEY search involved: I should just insert it myself and that’s not necessarily what I want to do all the time. I’d rather have a searching facility in place when I am creating such notes, so that’s why I resorted to ivy-bibtex.

What I am referring to is that - from my limited understanding - the note creation process in Jethro’s function goes through a CITEKEY (and possibly other elements) retrieval, operated by the citar module. At least, this is how I understand this part of his code:

(defun jethro/org-roam-node-from-cite (keys-entries)
    (interactive (list (citar-select-ref :multiple nil :rebuild-cache t)))
    (let ((title (citar--format-entry-no-widths (cdr keys-entries)
                                                "${author editor} :: ${title}")))

That citar-select-ref and thereabouts should be, I think, a way of retrieving the CITEKEY from a search… Which is exactly what I am up to. Only, I would like not to add another package if possible.

Or let’s just say I would like to have the feeling that I know a bit what I’m doing :smiley:

Thanks for any insight!

EDIT 03/08/24 : it looks like the issue I was reporting is not something isolated. I did not read the full thread but in this report the behaviour is the same one I was struggling with (double drawer insertion)

… And final twist (see below for the first one :-D)

It turns out - don’t ask me why as I don’t know - that somehow the structure I had put in the :ROAM_REFS: part of my previous template, namely:

     ("r" "reference" plain
      :if-new (file+head "reference/${citekey}.org"
#+title: ${title}\n")

Was causing mayhem. I patiently sarted from your verbatim template, @nobiot, and saw that it translated beautifully, no issues whatsoever (see below, first edit).

I then went on substituting the ${citekey} token for the file name at first: a plain variable substitution took place, the node was not showing any repetition.

Same thing for insertion of the second ${citekey} in the :ROAM_REFS: property…

Third, I changed the cite link syntax with respect to what I gathered from Jethro’s function. He writes this:

:ROAM_REFS: [cite:@${citekey}]

I went for a simpler:

:ROAM_REFS: cite:${citekey}

… And this did the trick! I now have everything as I want, and the reference notes are created according to what one would expect, without repetition!

:ROAM_REFS: cite:nguyen2015radio
:ID:       0aed351c-7c15-4a49-9ba6-93b66d73293e
#+title: Radio-Frequency Integrated-Circuit Engineering
This now works flawlessly!!

It is also interesting to note that the engine ‘cleverizes’ my dumb template, it does not add an extra :PROPERITES: line, or a double :END: line for that matter… It nicely merges the internal information of the :ID: with my custom properties, no hassle.

It would be interesting to understand a little deeper, what in Jethro’s syntax applied to my case created this sort of doubling…

(first edit)
Interesting twist!!

@nobiot If I reproduce your template verbatim, then I also get no repetitions in the :PROPERTIES:!!

So, it seems that the insertion of ${} elements might trigger some extra action…

Glad it worked out for you. As to why the first attempt didn’t work, I would have to debug the evaluation interactively line by line with edebug.

Don’t think you would have to trouble yourself this much.

1 Like

I’ve learned a lot thanks to your insights, @nobiot, so thank you!
The last thing learned: there is a thing called edebug with which you can (hope to) debug lisp!

1 Like