-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathekg-org-roam.el
136 lines (124 loc) · 7.48 KB
/
ekg-org-roam.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
;;; ekg-org-roam.el --- Importing and exporting between org-roam and ekg -*- lexical-binding: t -*-
;; Copyright (c) 2023 Andrew Hyatt <ahyatt@gmail.com>
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 3 of the
;; License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;;
;; These utilities provide a method for handling the import and (eventually) the
;; export of data from org-roam into ekg.
(require 'ekg)
(require 'triples)
(require 'org nil t)
(require 'org-roam nil t)
(require 'org-roam-db nil t)
(require 'org-roam-utils nil t)
(require 'org-roam-dailies nil t)
(require 'rx)
(require 'url-handlers)
;;; Code:
(defvar ekg-org-roam-import-tag-to-prefix nil
"Tags which need to be prefixed to the title.
For example, if you tag every idea with the `idea' tag, then I
think it's best to not bring that tag to ekg, but instead to
prefix the title with this tag name. This is a list of tags that
should operate like that - so, if one is found (at max one should
ever be found, these should be exclusionary), it turns into a
prefix on the title instead.")
(defvar ekg-org-roam-import-tag-to-ignore nil
"Tags to ignore and not bring into ekg.")
;; Declarations to remove byte compilation warnings.
(declare-function org-roam-node-from-id "ext:org-roam-node.el")
(declare-function org-roam-node-title "ext:org-roam-node.el")
(declare-function org-roam-node-tags "ext:org-roam-node.el")
(declare-function org-roam-node-list "ext:org-roam-node.el")
(declare-function org-roam-node-file "ext:org-roam-node.el")
(declare-function org-roam-node-level "ext:org-roam-node.el")
(declare-function org-roam-node-point "ext:org-roam-node.el")
(declare-function org-roam-node-id "ext:org-roam-node.el")
(declare-function org-roam-node-refs "ext:org-roam-node.el")
(declare-function org-roam-with-file "ext:org-roam-utils.el")
(declare-function org-roam-db-query "ext:org-roam-db.el")
(declare-function org-narrow-to-element "ext:org.el")
(defvar org-roam-directory)
(defvar org-roam-dailies-directory)
(defun ekg-org-roam-import-title-to-tag (title tags)
"From a TITLE and TAGS compute the new title according to prefix rules."
(if (iso8601-valid-p title)
(format "date/%s" title)
(let ((tags (append tags)))
(if-let (diff (seq-intersection tags
ekg-org-roam-import-tag-to-prefix))
(if (= 1 (length diff))
(format "%s/%s" (car diff) title)
(warn "Unexpectedly found more than one tag in `ekg-org-roam-import-tag-to-prefix' in tags for node %s. Tags: %s."
title tags)
title)
title))))
(defun ekg-org-roam-import--tags-from-links ()
"From the current buffer, return tags from the links found.
The links are turned into tags, without regards for ignored tags.
However, we do pay attention to
`ekg-org-roam-import-tag-to-prefix'."
(let ((tags-from-links))
(while (re-search-forward org-link-bracket-re nil t)
(let* ((type-val (split-string (substring-no-properties (match-string 1)) ":")))
(when (string-equal (downcase (car type-val)) "file")
(when-let ((node (org-roam-node-from-id (caar (org-roam-db-query [:select [id] :from nodes
:where (= file $s1)
:and (= level 0)]
(cadr type-val))))))
(cl-pushnew (ekg-org-roam-import-title-to-tag (org-roam-node-title node) (org-roam-node-tags node)) tags-from-links)))
(when (string-equal (downcase (car type-val)) "id")
(when-let (linked-node (org-roam-node-from-id (cadr type-val)))
(cl-pushnew (ekg-org-roam-import-title-to-tag (org-roam-node-title linked-node) (org-roam-node-tags linked-node)) tags-from-links)))))
tags-from-links))
(defun ekg-org-roam-import ()
"Import all data from org-roam into ekg."
(ekg-connect)
(triples-add-schema ekg-db 'org-roam '(id (:base/unique t)))
(dolist (node (org-roam-node-list))
(save-excursion
(org-roam-with-file (org-roam-node-file node) nil
(goto-char (org-roam-node-point node))
(when (> (org-roam-node-level node) 0)
(condition-case nil
(org-narrow-to-element)
(error nil)))
(let ((tags-from-links)
(text (buffer-substring (save-excursion
(goto-char (point-min))
(font-lock-ensure)
(point)) (point-max))))
(unless (triples-subjects-with-predicate-object ekg-db 'org-roam/id (org-roam-node-id node))
(setq tags-from-links (ekg-org-roam-import--tags-from-links))
(triples-with-transaction ekg-db
(let* ((note (ekg-note-create
:text text
:mode 'org-mode
:tags (seq-difference (seq-uniq
(append
(list (ekg-org-roam-import-title-to-tag (org-roam-node-title node) (org-roam-node-tags node)))
tags-from-links
(org-roam-node-tags node)))
(seq-union ekg-org-roam-import-tag-to-ignore
ekg-org-roam-import-tag-to-prefix
#'equal)
#'equal))))
(setf (ekg-note-id note) (org-roam-node-id node))
(when (org-roam-node-refs node)
(setf (ekg-note-properties note) `(:reference/url ,(org-roam-node-refs node))))
(ekg-save-note note)
(triples-set-type ekg-db (ekg-note-id note) 'org-roam `(:id ,(org-roam-node-id node)))))))))))
(provide 'ekg-org-roam)
;;; ekg-org-roam.el ends here