From 14b18cebe0f0055a611556011a70686dcc755334 Mon Sep 17 00:00:00 2001
From: Brian Lester <blester125@gmail.com>
Date: Tue, 3 Aug 2021 22:08:44 -0400
Subject: Use `org-roam-bibtex` to find titles for node-less cite nodes.

This change uses `org-roam-bibtex` (if it and it's dependencies are
installed) to look up the cite links that do not have an associated
node in the bibliography. This feature also needs to be enabled by
setting `org-roam-ui-find-ref-title` variable to `'t`.

This uses `fboundp` and `boundp` to check if `org-roam-bibtex` is
installed, this are the same kinds of checks that projectile uses to
decide between backends like helm or ivy, so it seems like a reason
approach.

I currently have only tested on my personal graph which only has around
10 node-less cite links, so I don't know how drastically this would slow
things down. Given that bibliography entries are not updated often it
think it would be safe to cache the titles based on the ref, then only
the initial load of the graph would be slow. Later, adding a cite link
to a new entry would get looked up, but that wouldn't be a huge cost. We
could either roll our own with a hash table or bring in a
[memoization library](https://github.com/skeeto/emacs-memoize)
---
 org-roam-ui.el | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/org-roam-ui.el b/org-roam-ui.el
index 368d788..505785b 100644
--- a/org-roam-ui.el
+++ b/org-roam-ui.el
@@ -102,6 +102,11 @@ This can lead to some jank."
   :group 'org-roam-ui
   :type 'boolean)
 
+(defcustom org-roam-ui-find-ref-title nil
+  "Should org-roam-ui use `org-roam-bibtex' to try to find the title of a reference in the bibliography?"
+  :group 'org-roam-ui
+  :type 'boolean)
+
 (defvar org-roam-ui--ws-current-node nil
   "Var to keep track of which node you are looking at.")
 (defvar oru-ws nil
@@ -157,8 +162,21 @@ This serves the web-build and API over HTTP."
     (org-roam-ui--send-graphdata))
   )
 
+(defun org-roam-ui--find-ref-title (ref)
+  "Find the title of the bibtex entry keyed by `ref'.
+
+Requires `org-roam-bibtex' and `bibtex-completion' (a dependency of `orb') to be
+loaded. Returns `ref' if an entry could not be found."
+  (if (and org-roam-ui-find-ref-title
+           (fboundp 'bibtex-completion-get-entry)
+           (boundp 'orb-bibtex-entry-get-value-function))
+      (if-let ((entry (bibtex-completion-get-entry ref)))
+          (funcall orb-bibtex-entry-get-value-function "title" entry ref)
+        ref)
+    ref))
+
 (defun org-roam-ui--create-fake-node (ref)
-  (list ref ref ref 0 `(("ROAM_REFS" . ,(format "cite:%s" ref)) ("FILELESS" . t)) 'nil))
+  (list ref ref (org-roam-ui--find-ref-title ref) 0 `(("ROAM_REFS" . ,(format "cite:%s" ref)) ("FILELESS" . t)) 'nil))
 
 (defun org-roam-ui--send-graphdata ()
   "Get roam data, make JSON, send through websocket to org-roam-ui."
@@ -186,7 +204,8 @@ This serves the web-build and API over HTTP."
                                          (list source node-id "ref")
                                        (list source dest type)))) links-db-rows))
          (links-with-empty-refs (seq-filter (lambda (l) (equal (nth 2 l) "cite")) links-db-rows))
-         (fake-nodes (delete-dups (seq-map (lambda (l) (org-roam-ui--create-fake-node (nth 1 l))) links-with-empty-refs)))
+         (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))
          (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))
-- 
cgit v1.2.3