mirror of
https://github.com/org-roam/org-roam
synced 2025-08-01 12:17:21 -05:00
(feat): allow setting #+roam_alias and #+roam_tag on multiple lines (#1540)
This brings them more in line with how other Org keywords, such as \#+PROPERTY, are declared. Previously #+roam_alias: abc def #+roam_alias: ghi would result in only the last one ("ghi") being extracted. Now ("abc" "def" "ghi") are all extracted (in that order). * org-roam.el (org-roam--extract-tags-prop, org-roam--extract-titles-alias): Accept and return all values in a list, not just from one line. (org-roam--extract-prop-as-list): New function. List prop extraction refactored from `org-roam--extract-tags-prop` and `org-roam--extract-titles-alias` * tests/test-org-roam.el: Add tests for defining tags and aliases in multiple lines
This commit is contained in:
@ -9,6 +9,7 @@
|
|||||||
### Changed
|
### Changed
|
||||||
- [#1352](https://github.com/org-roam/org-roam/pull/1352) prefer lower-case for roam_tag and roam_alias in interactive commands
|
- [#1352](https://github.com/org-roam/org-roam/pull/1352) prefer lower-case for roam_tag and roam_alias in interactive commands
|
||||||
- [#1513](https://github.com/org-roam/org-roam/pull/1513) replaced hardcoded "svg" with defcustom org-roam-graph-filetype
|
- [#1513](https://github.com/org-roam/org-roam/pull/1513) replaced hardcoded "svg" with defcustom org-roam-graph-filetype
|
||||||
|
- [#1540](https://github.com/org-roam/org-roam/pull/1540) allow `roam_tag` and `roam_alias` to be specified on multiple lines
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- [#1281](https://github.com/org-roam/org-roam/pull/1281) fixed idle-timer not instantiated on `org-roam-mode`
|
- [#1281](https://github.com/org-roam/org-roam/pull/1281) fixed idle-timer not instantiated on `org-roam-mode`
|
||||||
|
63
org-roam.el
63
org-roam.el
@ -559,6 +559,28 @@ any), and Org keywords. Org keywords take precedence."
|
|||||||
(org-roam--extract-global-props-keyword props)
|
(org-roam--extract-global-props-keyword props)
|
||||||
(org-roam--extract-global-props-drawer props)))
|
(org-roam--extract-global-props-drawer props)))
|
||||||
|
|
||||||
|
(defun org-roam--extract-prop-as-list (prop)
|
||||||
|
"Extract PROP from the current Org buffer as a list.
|
||||||
|
|
||||||
|
This is the common logic behind the extraction of roam_tags and
|
||||||
|
roam_alias."
|
||||||
|
;; Values are split in two ways:
|
||||||
|
;; 1. with spaces and double quotes:
|
||||||
|
;; #+prop: a b c \"quoted string\"
|
||||||
|
;; -> '(\"a\" \"b\" \"c\" \"quoted string\")
|
||||||
|
;; 2. and/or with multiple lines:
|
||||||
|
;; #+prop: a b
|
||||||
|
;; #+prop: c d
|
||||||
|
;; -> '(\"a\" \"b\" \"c\" \"d\")
|
||||||
|
(--> (org-roam--extract-global-props (list prop))
|
||||||
|
;; so that the returned order is the same as in the buffer
|
||||||
|
nreverse
|
||||||
|
;; '(("ROAM_TAGS" . "a b") ("ROAM_TAGS" . "c d"))
|
||||||
|
;; -> '("a b" "c d")
|
||||||
|
(mapcar #'cdr it)
|
||||||
|
(mapcar #'split-string-and-unquote it)
|
||||||
|
;; We have a list of lists at this point. Join them.
|
||||||
|
(apply #'append it)))
|
||||||
|
|
||||||
(defun org-roam--get-outline-path ()
|
(defun org-roam--get-outline-path ()
|
||||||
"Return the outline path to the current entry.
|
"Return the outline path to the current entry.
|
||||||
@ -667,18 +689,15 @@ If FILE-PATH is nil, use the current file."
|
|||||||
(defun org-roam--extract-titles-alias ()
|
(defun org-roam--extract-titles-alias ()
|
||||||
"Return the aliases from the current buffer.
|
"Return the aliases from the current buffer.
|
||||||
Reads from the \"roam_alias\" property."
|
Reads from the \"roam_alias\" property."
|
||||||
(let* ((prop (org-roam--extract-global-props '("ROAM_ALIAS")))
|
(condition-case nil
|
||||||
(aliases (or (cdr (assoc "ROAM_ALIAS" prop))
|
(org-roam--extract-prop-as-list "ROAM_ALIAS")
|
||||||
"")))
|
(error
|
||||||
(condition-case nil
|
(progn
|
||||||
(split-string-and-unquote aliases)
|
(lwarn '(org-roam) :error
|
||||||
(error
|
"Failed to parse aliases for buffer: %s. Skipping"
|
||||||
(progn
|
(or org-roam-file-name
|
||||||
(lwarn '(org-roam) :error
|
(buffer-file-name)))
|
||||||
"Failed to parse aliases for buffer: %s. Skipping"
|
nil))))
|
||||||
(or org-roam-file-name
|
|
||||||
(buffer-file-name)))
|
|
||||||
nil)))))
|
|
||||||
|
|
||||||
(defun org-roam--extract-titles-headline ()
|
(defun org-roam--extract-titles-headline ()
|
||||||
"Return the first headline of the current buffer."
|
"Return the first headline of the current buffer."
|
||||||
@ -735,17 +754,15 @@ tag."
|
|||||||
|
|
||||||
(defun org-roam--extract-tags-prop (_file)
|
(defun org-roam--extract-tags-prop (_file)
|
||||||
"Extract tags from the current buffer's \"#roam_tags\" global property."
|
"Extract tags from the current buffer's \"#roam_tags\" global property."
|
||||||
(let* ((prop (or (cdr (assoc "ROAM_TAGS" (org-roam--extract-global-props '("ROAM_TAGS"))))
|
(condition-case nil
|
||||||
"")))
|
(org-roam--extract-prop-as-list "ROAM_TAGS")
|
||||||
(condition-case nil
|
(error
|
||||||
(split-string-and-unquote prop)
|
(progn
|
||||||
(error
|
(lwarn '(org-roam) :error
|
||||||
(progn
|
"Failed to parse tags for buffer: %s. Skipping"
|
||||||
(lwarn '(org-roam) :error
|
(or org-roam-file-name
|
||||||
"Failed to parse tags for buffer: %s. Skipping"
|
(buffer-file-name)))
|
||||||
(or org-roam-file-name
|
nil))))
|
||||||
(buffer-file-name)))
|
|
||||||
nil)))))
|
|
||||||
|
|
||||||
(defun org-roam--extract-tags-vanilla (_file)
|
(defun org-roam--extract-tags-vanilla (_file)
|
||||||
"Extract vanilla `org-mode' tags.
|
"Extract vanilla `org-mode' tags.
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#+roam_tags: "t1" "t2 with space" t3
|
#+roam_tags: "t1" "t2 with space" t3
|
||||||
|
#+roam_tags: "t4 second-line"
|
||||||
#+title: Tags
|
#+title: Tags
|
||||||
|
|
||||||
This file is used to test functionality for =(org-roam--extract-tags)=
|
This file is used to test functionality for =(org-roam--extract-tags)=
|
||||||
|
@ -1 +1,2 @@
|
|||||||
#+roam_alias: "roam" "alias"
|
#+roam_alias: "roam" "alias"
|
||||||
|
#+roam_alias: "second" "line"
|
||||||
|
@ -126,7 +126,7 @@
|
|||||||
(expect (test #'org-roam--extract-titles-alias
|
(expect (test #'org-roam--extract-titles-alias
|
||||||
"titles/aliases.org")
|
"titles/aliases.org")
|
||||||
:to-equal
|
:to-equal
|
||||||
'("roam" "alias"))
|
'("roam" "alias" "second" "line"))
|
||||||
(expect (test #'org-roam--extract-titles-alias
|
(expect (test #'org-roam--extract-titles-alias
|
||||||
"titles/headline.org")
|
"titles/headline.org")
|
||||||
:to-equal
|
:to-equal
|
||||||
@ -192,7 +192,7 @@
|
|||||||
(expect (test #'org-roam--extract-tags-prop
|
(expect (test #'org-roam--extract-tags-prop
|
||||||
"tags/tag.org")
|
"tags/tag.org")
|
||||||
:to-equal
|
:to-equal
|
||||||
'("t1" "t2 with space" "t3"))
|
'("t1" "t2 with space" "t3" "t4 second-line"))
|
||||||
(expect (test #'org-roam--extract-tags-prop
|
(expect (test #'org-roam--extract-tags-prop
|
||||||
"tags/no_tag.org")
|
"tags/no_tag.org")
|
||||||
:to-equal
|
:to-equal
|
||||||
@ -246,13 +246,13 @@
|
|||||||
(test #'org-roam--extract-tags
|
(test #'org-roam--extract-tags
|
||||||
"tags/tag.org"))
|
"tags/tag.org"))
|
||||||
:to-equal
|
:to-equal
|
||||||
'("t1" "t2 with space" "t3")))
|
'("t1" "t2 with space" "t3" "t4 second-line")))
|
||||||
(it "'(prop all-directories)"
|
(it "'(prop all-directories)"
|
||||||
(expect (let ((org-roam-tag-sources '(prop all-directories)))
|
(expect (let ((org-roam-tag-sources '(prop all-directories)))
|
||||||
(test #'org-roam--extract-tags
|
(test #'org-roam--extract-tags
|
||||||
"tags/tag.org"))
|
"tags/tag.org"))
|
||||||
:to-equal
|
:to-equal
|
||||||
'("t1" "t2 with space" "t3" "tags"))))))
|
'("t1" "t2 with space" "t3" "t4 second-line" "tags"))))))
|
||||||
|
|
||||||
(describe "ID extraction"
|
(describe "ID extraction"
|
||||||
(before-all
|
(before-all
|
||||||
|
Reference in New Issue
Block a user