summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--org-roam-ui.el49
1 files changed, 49 insertions, 0 deletions
diff --git a/org-roam-ui.el b/org-roam-ui.el
index b3a50eb..8a67ce6 100644
--- a/org-roam-ui.el
+++ b/org-roam-ui.el
@@ -107,6 +107,12 @@ This can lead to some jank."
:group 'org-roam-ui
:type 'boolean)
+(defcustom org-roam-ui-retitle-ref-nodes t
+ "Should org-roam-ui use `org-roam-bibtex' to try to update the title of a
+reference node that has an underlying note, using information from the bibliography."
+ :group 'org-roam-ui
+ :type 'boolean)
+
(defcustom org-roam-ui-ref-title-template "%^{author-abbrev} (%^{year}) %^{title}"
"A template for title creation, used for references without an associated nodes.
@@ -186,6 +192,45 @@ loaded. Returns `ref' if an entry could not be found."
ref)
ref))
+(defun org-roam-ui--replace-nth (el n lst)
+ "Non-destructively replace the `n'th element of `lst' with `el'."
+ (let ((head (butlast lst (- (length lst) n)))
+ (tail (nthcdr (+ n 1) lst)))
+ (append head (list el) tail)))
+
+(defun org-roam-ui--citekey-to-ref (citekey)
+ "Convert a citekey property (most likely with a `cite:' prefix) to just a key
+
+This method is mostly taken from `org-roam-bibtex' see https://github.com/org-roam/org-roam-bibtex/blob/919ec8d837a7a3bd25232bdba17a0208efaefb2a/orb-utils.el#L289
+but is has been adapted to operate on a sting instead of a node. Requires
+`org-ref' to be loaded. Returns the `key' or `nil' if the format does not match
+the `org-ref-cite-re'"
+ (if-let ((boundp 'org-ref-cite-re)
+ (citekey-list (split-string-and-unquote citekey)))
+ (catch 'found
+ (dolist (c citekey-list)
+ (when (string-match org-ref-cite-re c)
+ (throw 'found (match-string 2 c)))))))
+
+(defun org-roam-ui--retitle-node (node)
+ "Replace the title of citation nodes with associated notes.
+
+A new title is created using information from the bibliography and formatted
+according to `org-roam-ui-ref-title-template', just like the citation nodes with
+a note are. It requires `org-roam-bibtex' and it's dependencies
+(`bibtex-completion' and `org-ref') to be loaded.
+
+Returns the node with an updated title if the current node is a reference node
+and the key was found in the bibliography, otherwise the node is returned
+unchanged."
+ (if-let* (org-roam-ui-retitle-ref-nodes
+ (boundp 'org-ref-cite-re)
+ (citekey (cdr (assoc "ROAM_REFS" (nth 4 node))))
+ (ref (org-roam-ui--citekey-to-ref citekey))
+ (title (org-roam-ui--find-ref-title ref)))
+ (org-roam-ui--replace-nth title 2 node)
+ node))
+
(defun org-roam-ui--create-fake-node (ref)
(list ref ref (org-roam-ui--find-ref-title ref) 0 `(("ROAM_REFS" . ,(format "cite:%s" ref)) ("FILELESS" . t)) 'nil))
@@ -217,6 +262,10 @@ loaded. Returns `ref' if an entry could not be found."
(links-with-empty-refs (seq-filter (lambda (l) (equal (nth 2 l) "cite")) links-db-rows))
(empty-refs (delete-dups (seq-map (lambda (l) (nth 1 l)) links-with-empty-refs)))
(fake-nodes (seq-map 'org-roam-ui--create-fake-node empty-refs))
+ ;; Try to update real nodes that are reference with a title build from
+ ;; their bibliography entry. Check configuration here for avoid unneeded
+ ;; iteration though nodes.
+ (nodes-db-rows (if org-roam-ui-retitle-ref-nodes (seq-map 'org-roam-ui--retitle-node nodes-db-rows) nodes-db-rows))
(nodes-db-rows (append nodes-db-rows fake-nodes))
(response `((nodes . ,(mapcar (apply-partially #'org-roam-ui-sql-to-alist (append nodes-names nil)) nodes-db-rows))
(links . ,(mapcar (apply-partially #'org-roam-ui-sql-to-alist '(source target type)) links-db-rows))