diff options
Diffstat (limited to 'org-roam-ui.el')
-rw-r--r-- | org-roam-ui.el | 49 |
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)) |