diff --git a/CHANGELOG.md b/CHANGELOG.md index 47e4634..0438f9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Added - [#1270](https://github.com/org-roam/org-roam/pull/1270) capture: create OLP if it does not exist. Removes need for OLP setup in `:head`. +- [#1353](https://github.com/org-roam/org-roam/pull/1353) support file-level property drawers ### Changed - [#1352](https://github.com/org-roam/org-roam/pull/1352) prefer lower-case for roam_tag and roam_alias in interactive commands diff --git a/org-roam.el b/org-roam.el index f54d418..6af20ba 100644 --- a/org-roam.el +++ b/org-roam.el @@ -504,31 +504,45 @@ Use external shell commands if defined in `org-roam-list-files-commands'." (org-roam--list-files (expand-file-name org-roam-directory))) ;;;; Org extraction functions +(defun org-roam--extract-global-props-drawer (props) + "Extract PROPS from the file-level property drawer in Org." + (let (ret) + (org-with-point-at 1 + (dolist (prop props ret) + (when-let ((v (org-entry-get (point) prop))) + (push (cons prop v) ret)))))) + +(defun org-roam--collect-keywords (keywords) + "Collect all Org KEYWORDS in the current buffer." + (if (functionp 'org-collect-keywords) + (org-collect-keywords keywords) + (let ((buf (org-element-parse-buffer)) + res) + (dolist (k keywords) + (let ((p (org-element-map buf 'keyword + (lambda (kw) + (when (string-equal (org-element-property :key kw) k) + (org-element-property :value kw))) + :first-match nil))) + (push (cons k p) res))) + res))) + +(defun org-roam--extract-global-props-keyword (keywords) + "Extract KEYWORDS from the current Org buffer." + (let (ret) + (pcase-dolist (`(,key . ,values) (org-roam--collect-keywords keywords)) + (dolist (value values) + (push (cons key value) ret))) + ret)) + (defun org-roam--extract-global-props (props) - "Extract PROPS from the current org buffer." - (let ((collected - ;; Collect the raw props first - ;; It'll be returned in the form of - ;; (("PROP" "value" ...) ("PROP2" "value" ...)) - (if (functionp 'org-collect-keywords) - (org-collect-keywords props) - (let ((buf (org-element-parse-buffer)) - res) - (dolist (prop props) - (let ((p (org-element-map buf 'keyword - (lambda (kw) - (when (string-equal (org-element-property :key kw) prop) - (org-element-property :value kw))) - :first-match nil))) - (push (cons prop p) res))) - res)))) - ;; convert (("TITLE" "a" "b") ("Another" "c")) - ;; to (("TITLE" . "a") ("TITLE" . "b") ("Another" . "c")) - (let (ret) - (pcase-dolist (`(,key . ,values) collected) - (dolist (value values) - (push (cons key value) ret))) - ret))) + "Extract PROPS from the current Org buffer. +Props are extracted from both the file-level property drawer (if +any), and Org keywords. Org keywords take precedence." + (append + (org-roam--extract-global-props-keyword props) + (org-roam--extract-global-props-drawer props))) + (defun org-roam--get-outline-path () "Return the outline path to the current entry.