(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:
Kisaragi Hiu
2021-06-09 21:21:08 +09:00
committed by GitHub
parent 53c9a16e90
commit 756f6215b6
5 changed files with 47 additions and 27 deletions

View File

@ -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`

View File

@ -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.

View File

@ -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)=

View File

@ -1 +1,2 @@
#+roam_alias: "roam" "alias" #+roam_alias: "roam" "alias"
#+roam_alias: "second" "line"

View File

@ -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