* Concatenate properties
@ 2022-05-05 22:37 Tyler Grinn
2022-05-05 22:56 ` John Kitchin
0 siblings, 1 reply; 19+ messages in thread
From: Tyler Grinn @ 2022-05-05 22:37 UTC (permalink / raw)
To: emacs-orgmode
I'm exporting sub-trees as pdf files for some classes I'm taking:
# -*- org-use-property-inheritance: t; -*-
* Class A
:PROPERTIES:
:EXPORT_FILE_NAME: support/Class A
:END:
** Assignment 1
:PROPERTIES:
:EXPORT_FILE_NAME+: /assignment-1
:END:
Some assignment for Class A
** Assignment 2
:PROPERTIES:
:EXPORT_FILE_NAME+: /assignment-2
:END:
Some other assignment for Class A
* Class B
:PROPERTIES
:EXPORT_FILE_NAME: support/Class B
:END:
** Assignment 1
:PROPERTIES:
:EXPORT_FILE_NAME+: /assignment-1
:END:
Some assignment for Class B
** Assignment 2
:PROPERTIES:
:EXPORT_FILE_NAME+: /assignment-2
:END:
Some other assignment for Class B
And this works great, except there's always a space between
'support/Class A' and '/assignment-1.pdf'. Is there any way to
concatenate the two properties rather than join them with spaces?
Best,
Tyler
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Concatenate properties
2022-05-05 22:37 Concatenate properties Tyler Grinn
@ 2022-05-05 22:56 ` John Kitchin
2022-05-06 15:40 ` Tyler Grinn
0 siblings, 1 reply; 19+ messages in thread
From: John Kitchin @ 2022-05-05 22:56 UTC (permalink / raw)
To: Tyler Grinn; +Cc: org-mode-email
[-- Attachment #1: Type: text/plain, Size: 1523 bytes --]
I believe this is hard coded in org-entry-get-with-inheritance. The fastest
option would be an override advice with your own function that
replaces (and value " ") with (and value ""), and maybe the two other " "
with "".
John
-----------------------------------
Professor John Kitchin (he/him/his)
Doherty Hall A207F
Department of Chemical Engineering
Carnegie Mellon University
Pittsburgh, PA 15213
412-268-7803
@johnkitchin
http://kitchingroup.cheme.cmu.edu
On Thu, May 5, 2022 at 6:38 PM Tyler Grinn <tylergrinn@gmail.com> wrote:
>
> I'm exporting sub-trees as pdf files for some classes I'm taking:
>
> # -*- org-use-property-inheritance: t; -*-
>
> * Class A
> :PROPERTIES:
> :EXPORT_FILE_NAME: support/Class A
> :END:
> ** Assignment 1
> :PROPERTIES:
> :EXPORT_FILE_NAME+: /assignment-1
> :END:
> Some assignment for Class A
> ** Assignment 2
> :PROPERTIES:
> :EXPORT_FILE_NAME+: /assignment-2
> :END:
> Some other assignment for Class A
> * Class B
> :PROPERTIES
> :EXPORT_FILE_NAME: support/Class B
> :END:
> ** Assignment 1
> :PROPERTIES:
> :EXPORT_FILE_NAME+: /assignment-1
> :END:
> Some assignment for Class B
> ** Assignment 2
> :PROPERTIES:
> :EXPORT_FILE_NAME+: /assignment-2
> :END:
> Some other assignment for Class B
>
> And this works great, except there's always a space between
> 'support/Class A' and '/assignment-1.pdf'. Is there any way to
> concatenate the two properties rather than join them with spaces?
>
> Best,
>
> Tyler
>
>
[-- Attachment #2: Type: text/html, Size: 2335 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Concatenate properties
2022-05-05 22:56 ` John Kitchin
@ 2022-05-06 15:40 ` Tyler Grinn
2022-05-07 5:33 ` Ihor Radchenko
2022-05-07 13:20 ` John Kitchin
0 siblings, 2 replies; 19+ messages in thread
From: Tyler Grinn @ 2022-05-06 15:40 UTC (permalink / raw)
To: John Kitchin; +Cc: org-mode-email
John Kitchin <jkitchin@andrew.cmu.edu> writes:
> I believe this is hard coded in org-entry-get-with-inheritance. The
> fastest option would be an override advice with your own function that
> replaces (and value " ") with (and value ""), and maybe the two other
> " " with "".
>
> John
>
> -----------------------------------
> Professor John Kitchin (he/him/his)
> Doherty Hall A207F
> Department of Chemical Engineering
> Carnegie Mellon University
> Pittsburgh, PA 15213
> 412-268-7803
> @johnkitchin
> http://kitchingroup.cheme.cmu.edu
>
Thanks for the advice. I've added the caret symbol (:EXPORT_FILE_NAME^:
assignment-1) to mean 'concatenate' as opposed to + for 'joining'. If
this is something the community would want I will clean it up and send
in a patch.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Concatenate properties
2022-05-06 15:40 ` Tyler Grinn
@ 2022-05-07 5:33 ` Ihor Radchenko
2022-05-07 11:44 ` John Kitchin
2022-05-07 13:20 ` John Kitchin
1 sibling, 1 reply; 19+ messages in thread
From: Ihor Radchenko @ 2022-05-07 5:33 UTC (permalink / raw)
To: Tyler Grinn; +Cc: John Kitchin, org-mode-email
Tyler Grinn <tylergrinn@gmail.com> writes:
> Thanks for the advice. I've added the caret symbol (:EXPORT_FILE_NAME^:
> assignment-1) to mean 'concatenate' as opposed to + for 'joining'. If
> this is something the community would want I will clean it up and send
> in a patch.
Hmm. I am not sure if it going to be a straightforward patch. You may
need to update org-element parser accordingly.
Also, I do not like the idea of extending org syntax with :PROPERTY^:.
It may be easier to introduce a variable similar to
org-use-property-inheritance where the user can customise how to
accumulate parent properties.
Best,
Ihor
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Concatenate properties
2022-05-07 5:33 ` Ihor Radchenko
@ 2022-05-07 11:44 ` John Kitchin
2022-05-07 12:29 ` Tyler Grinn
0 siblings, 1 reply; 19+ messages in thread
From: John Kitchin @ 2022-05-07 11:44 UTC (permalink / raw)
To: Ihor Radchenko; +Cc: Tyler Grinn, org-mode-email
[-- Attachment #1: Type: text/plain, Size: 1307 bytes --]
I like the variable idea. I would make it a concatenation string for
joining. That way “” would concatenate the way Tyler wants, “ “ would
preserve current behavior, and “,” could lead to a comma separated list for
example. Other things like “\n” might lead to a column, etc.
On Sat, May 7, 2022 at 1:32 AM Ihor Radchenko <yantar92@gmail.com> wrote:
> Tyler Grinn <tylergrinn@gmail.com> writes:
>
> > Thanks for the advice. I've added the caret symbol (:EXPORT_FILE_NAME^:
> > assignment-1) to mean 'concatenate' as opposed to + for 'joining'. If
> > this is something the community would want I will clean it up and send
> > in a patch.
>
> Hmm. I am not sure if it going to be a straightforward patch. You may
> need to update org-element parser accordingly.
>
> Also, I do not like the idea of extending org syntax with :PROPERTY^:.
> It may be easier to introduce a variable similar to
> org-use-property-inheritance where the user can customise how to
> accumulate parent properties.
>
> Best,
> Ihor
>
--
John
-----------------------------------
Professor John Kitchin (he/him/his)
Doherty Hall A207F
Department of Chemical Engineering
Carnegie Mellon University
Pittsburgh, PA 15213
412-268-7803
@johnkitchin
http://kitchingroup.cheme.cmu.edu
[-- Attachment #2: Type: text/html, Size: 2005 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Concatenate properties
2022-05-07 11:44 ` John Kitchin
@ 2022-05-07 12:29 ` Tyler Grinn
2022-05-08 12:21 ` Ihor Radchenko
0 siblings, 1 reply; 19+ messages in thread
From: Tyler Grinn @ 2022-05-07 12:29 UTC (permalink / raw)
To: John Kitchin; +Cc: Ihor Radchenko, org-mode-email
John Kitchin <jkitchin@andrew.cmu.edu> writes:
> I like the variable idea. I would make it a concatenation string for
> joining. That way “” would concatenate the way Tyler wants, “ “ would
> preserve current behavior, and “,” could lead to a comma separated
> list for example. Other things like “\n” might lead to a column, etc.
I'm not a huge fan of the variable idea because it would make it
impossible to include both behaviors in a single file, whereas extending
the syntax maintains any existing properties that used '+'.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Concatenate properties
2022-05-06 15:40 ` Tyler Grinn
2022-05-07 5:33 ` Ihor Radchenko
@ 2022-05-07 13:20 ` John Kitchin
2022-05-07 14:09 ` Tyler Grinn
1 sibling, 1 reply; 19+ messages in thread
From: John Kitchin @ 2022-05-07 13:20 UTC (permalink / raw)
To: Tyler Grinn; +Cc: org-mode-email
[-- Attachment #1: Type: text/plain, Size: 1161 bytes --]
Where did you add that?
John
-----------------------------------
Professor John Kitchin (he/him/his)
Doherty Hall A207F
Department of Chemical Engineering
Carnegie Mellon University
Pittsburgh, PA 15213
412-268-7803
@johnkitchin
http://kitchingroup.cheme.cmu.edu
On Fri, May 6, 2022 at 11:40 AM Tyler Grinn <tylergrinn@gmail.com> wrote:
> John Kitchin <jkitchin@andrew.cmu.edu> writes:
>
> > I believe this is hard coded in org-entry-get-with-inheritance. The
> > fastest option would be an override advice with your own function that
> > replaces (and value " ") with (and value ""), and maybe the two other
> > " " with "".
> >
> > John
> >
> > -----------------------------------
> > Professor John Kitchin (he/him/his)
> > Doherty Hall A207F
> > Department of Chemical Engineering
> > Carnegie Mellon University
> > Pittsburgh, PA 15213
> > 412-268-7803
> > @johnkitchin
> > http://kitchingroup.cheme.cmu.edu
> >
>
> Thanks for the advice. I've added the caret symbol (:EXPORT_FILE_NAME^:
> assignment-1) to mean 'concatenate' as opposed to + for 'joining'. If
> this is something the community would want I will clean it up and send
> in a patch.
>
[-- Attachment #2: Type: text/html, Size: 2064 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Concatenate properties
2022-05-07 13:20 ` John Kitchin
@ 2022-05-07 14:09 ` Tyler Grinn
0 siblings, 0 replies; 19+ messages in thread
From: Tyler Grinn @ 2022-05-07 14:09 UTC (permalink / raw)
To: John Kitchin; +Cc: org-mode-email
John Kitchin <jkitchin@andrew.cmu.edu> writes:
> Where did you add that?
>
> John
>
> -----------------------------------
> Professor John Kitchin (he/him/his)
> Doherty Hall A207F
> Department of Chemical Engineering
> Carnegie Mellon University
> Pittsburgh, PA 15213
> 412-268-7803
> @johnkitchin
> http://kitchingroup.cheme.cmu.edu
>
> On Fri, May 6, 2022 at 11:40 AM Tyler Grinn <tylergrinn@gmail.com>
> wrote:
>
> Thanks for the advice. I've added the caret symbol
> (:EXPORT_FILE_NAME^:
> assignment-1) to mean 'concatenate' as opposed to + for 'joining'.
> If
> this is something the community would want I will clean it up and
> send
> in a patch.
I modified 'org--property-local-values' to return a cons list with the
car being the value of the property and the cdr being either 'concat or
'join.
;; Find additional values.
(let* ((property-extension (org-re-property
(concat (regexp-quote property)
"[+^]")
t t)))
(while (re-search-forward property-extension end t)
(push (cons (match-string-no-properties 3)
(if (string-match-p "\\^\\'" (match-string-no-properties 2))
'concat
'join))
value)))
I used a single re-search in order to maintain the ordering of
properties, ie:
:PROP: he
:PROP^: llo
:PROP+: world
produces 'hello world'
I then updated both 'org-entry-get' and
'org-entry-get-with-inheritance' to 'cl-reduce' the cons list into the
final string value.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Concatenate properties
2022-05-07 12:29 ` Tyler Grinn
@ 2022-05-08 12:21 ` Ihor Radchenko
2022-05-08 14:14 ` Tyler Grinn
0 siblings, 1 reply; 19+ messages in thread
From: Ihor Radchenko @ 2022-05-08 12:21 UTC (permalink / raw)
To: Tyler Grinn; +Cc: John Kitchin, org-mode-email
Tyler Grinn <tylergrinn@gmail.com> writes:
> John Kitchin <jkitchin@andrew.cmu.edu> writes:
>
>> I like the variable idea. I would make it a concatenation string for
>> joining. That way “” would concatenate the way Tyler wants, “ “ would
>> preserve current behavior, and “,” could lead to a comma separated
>> list for example. Other things like “\n” might lead to a column, etc.
>
> I'm not a huge fan of the variable idea because it would make it
> impossible to include both behaviors in a single file, whereas extending
> the syntax maintains any existing properties that used '+'.
I think I need to elaborate what I meant by "similar to
org-use-property-inheritance".
org-use-property-inheritance docstring:
>>> When nil, only the properties directly given in the current entry
>>> count. When t, every property is inherited. The value may also be a
>>> list of properties that should have inheritance, or a regular
>>> expression matching properties that should be inherited.
Similarly, concatenation of PROPERTY+ can be controlled on per-property
basis.
Best,
Ihor
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Concatenate properties
2022-05-08 12:21 ` Ihor Radchenko
@ 2022-05-08 14:14 ` Tyler Grinn
2022-05-08 14:47 ` Ihor Radchenko
0 siblings, 1 reply; 19+ messages in thread
From: Tyler Grinn @ 2022-05-08 14:14 UTC (permalink / raw)
To: Ihor Radchenko; +Cc: org-mode-email
Ihor Radchenko <yantar92@gmail.com> writes:
> Tyler Grinn <tylergrinn@gmail.com> writes:
>
>> John Kitchin <jkitchin@andrew.cmu.edu> writes:
>>
>>> I like the variable idea. I would make it a concatenation string for
>>> joining. That way “” would concatenate the way Tyler wants, “ “ would
>>> preserve current behavior, and “,” could lead to a comma separated
>>> list for example. Other things like “\n” might lead to a column, etc.
>>
>> I'm not a huge fan of the variable idea because it would make it
>> impossible to include both behaviors in a single file, whereas extending
>> the syntax maintains any existing properties that used '+'.
>
> I think I need to elaborate what I meant by "similar to
> org-use-property-inheritance".
>
> org-use-property-inheritance docstring:
>
>>>> When nil, only the properties directly given in the current entry
>>>> count. When t, every property is inherited. The value may also be a
>>>> list of properties that should have inheritance, or a regular
>>>> expression matching properties that should be inherited.
>
> Similarly, concatenation of PROPERTY+ can be controlled on per-property
> basis.
>
> Best,
> Ihor
Could you provide an example of what the value of that variable would be
if, for instance, I wanted PROP_A and PROP_B to be joined with a single
space and PROP_C and PROP_D to be concatenated? Or better yet, have the
default be to join with a single space for any property and have only
PROP_C and PROP_D concatenated?
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Concatenate properties
2022-05-08 14:14 ` Tyler Grinn
@ 2022-05-08 14:47 ` Ihor Radchenko
2022-05-09 20:18 ` Tyler Grinn
0 siblings, 1 reply; 19+ messages in thread
From: Ihor Radchenko @ 2022-05-08 14:47 UTC (permalink / raw)
To: Tyler Grinn; +Cc: org-mode-email
Tyler Grinn <tylergrinn@gmail.com> writes:
>
> Could you provide an example of what the value of that variable would be
> if, for instance, I wanted PROP_A and PROP_B to be joined with a single
> space and PROP_C and PROP_D to be concatenated? Or better yet, have the
> default be to join with a single space for any property and have only
> PROP_C and PROP_D concatenated?
Say,
'(("PROP_[CD]" . ""))
or
'(("PROP_[AB]" . "/") ("PROP_[CD]" . "") (".+" . "∿"))
Best,
Ihor
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Concatenate properties
2022-05-08 14:47 ` Ihor Radchenko
@ 2022-05-09 20:18 ` Tyler Grinn
2022-05-11 11:51 ` Ihor Radchenko
0 siblings, 1 reply; 19+ messages in thread
From: Tyler Grinn @ 2022-05-09 20:18 UTC (permalink / raw)
To: Ihor Radchenko; +Cc: org-mode-email
Ihor Radchenko <yantar92@gmail.com> writes:
> Tyler Grinn <tylergrinn@gmail.com> writes:
>
>>
>> Could you provide an example of what the value of that variable would be
>> if, for instance, I wanted PROP_A and PROP_B to be joined with a single
>> space and PROP_C and PROP_D to be concatenated? Or better yet, have the
>> default be to join with a single space for any property and have only
>> PROP_C and PROP_D concatenated?
>
> Say,
>
> '(("PROP_[CD]" . ""))
>
> or
>
> '(("PROP_[AB]" . "/") ("PROP_[CD]" . "") (".+" . "∿"))
>
> Best,
> Ihor
I'm not sure forcing regular expressions for all use cases is ideal. Is
there a way to allow the option (I'm calling it org-property-separators)
to allow either regular expressions or exact matches, like
org-use-property-inheritance does?
Other than that I'm mostly ready to send in my first patch. Should I
attach it in this thread or start a new one?
Best,
Tyler
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Concatenate properties
2022-05-09 20:18 ` Tyler Grinn
@ 2022-05-11 11:51 ` Ihor Radchenko
2022-05-11 17:47 ` [PATCH] " Tyler Grinn
0 siblings, 1 reply; 19+ messages in thread
From: Ihor Radchenko @ 2022-05-11 11:51 UTC (permalink / raw)
To: Tyler Grinn; +Cc: org-mode-email
Tyler Grinn <tylergrinn@gmail.com> writes:
> Ihor Radchenko <yantar92@gmail.com> writes:
>
>> Tyler Grinn <tylergrinn@gmail.com> writes:
>>
>>>
>>> Could you provide an example of what the value of that variable would be
>>> if, for instance, I wanted PROP_A and PROP_B to be joined with a single
>>> space and PROP_C and PROP_D to be concatenated? Or better yet, have the
>>> default be to join with a single space for any property and have only
>>> PROP_C and PROP_D concatenated?
>>
>> Say,
>>
>> '(("PROP_[CD]" . ""))
>>
>> or
>>
>> '(("PROP_[AB]" . "/") ("PROP_[CD]" . "") (".+" . "∿"))
>>
>> Best,
>> Ihor
>
> I'm not sure forcing regular expressions for all use cases is ideal. Is
> there a way to allow the option (I'm calling it org-property-separators)
> to allow either regular expressions or exact matches, like
> org-use-property-inheritance does?
It's up to you. I merely suggested that the new option should work
similarly to org-use-property-inheritance. It will not be the exact
match since we also need to provide the separator string.
> Other than that I'm mostly ready to send in my first patch. Should I
> attach it in this thread or start a new one?
Keeping the patch within this thread will be more reasonable for future
readers. Just remember to prefix the subject line with [PATCH].
Best,
Ihor
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH] Re: Concatenate properties
2022-05-11 11:51 ` Ihor Radchenko
@ 2022-05-11 17:47 ` Tyler Grinn
2022-05-12 9:59 ` Ihor Radchenko
0 siblings, 1 reply; 19+ messages in thread
From: Tyler Grinn @ 2022-05-11 17:47 UTC (permalink / raw)
To: Ihor Radchenko; +Cc: org-mode-email
[-- Attachment #1: Type: text/plain, Size: 1670 bytes --]
Ihor Radchenko <yantar92@gmail.com> writes:
> Tyler Grinn <tylergrinn@gmail.com> writes:
>
>> Ihor Radchenko <yantar92@gmail.com> writes:
>>
>>> Tyler Grinn <tylergrinn@gmail.com> writes:
>>>
>>>>
>>>> Could you provide an example of what the value of that variable would be
>>>> if, for instance, I wanted PROP_A and PROP_B to be joined with a single
>>>> space and PROP_C and PROP_D to be concatenated? Or better yet, have the
>>>> default be to join with a single space for any property and have only
>>>> PROP_C and PROP_D concatenated?
>>>
>>> Say,
>>>
>>> '(("PROP_[CD]" . ""))
>>>
>>> or
>>>
>>> '(("PROP_[AB]" . "/") ("PROP_[CD]" . "") (".+" . "∿"))
>>>
>>> Best,
>>> Ihor
>>
>> I'm not sure forcing regular expressions for all use cases is ideal. Is
>> there a way to allow the option (I'm calling it org-property-separators)
>> to allow either regular expressions or exact matches, like
>> org-use-property-inheritance does?
>
> It's up to you. I merely suggested that the new option should work
> similarly to org-use-property-inheritance. It will not be the exact
> match since we also need to provide the separator string.
>
>> Other than that I'm mostly ready to send in my first patch. Should I
>> attach it in this thread or start a new one?
>
> Keeping the patch within this thread will be more reasonable for future
> readers. Just remember to prefix the subject line with [PATCH].
>
> Best,
> Ihor
OK, what I have now is that if the car of an alist item is a list, exact
matching will be done for each list item, but if it is a string, it will
be matched as a regular expression.
Best,
Tyler
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Add org-property-separators option --]
[-- Type: text/x-patch, Size: 8332 bytes --]
From c23b45dd5d0bc5a049b916a4b4003c6f55ce4b51 Mon Sep 17 00:00:00 2001
From: Tyler Grinn <tylergrinn@gmail.com>
Date: Mon, 9 May 2022 15:52:58 -0400
Subject: [PATCH] lisp/org.el: Add org-property-separators option
* lisp/org.el (org-property-separators, org-property-get-separator):
Created.
(org-entry-get, org-entry-get-with-inheritance): Use new
org-property-get-separator function.
* testing/lisp/test-org.el (test-org/entry-get): Added tests for
combining properties with custom separators
org-property-separators is a customization option that allows for
properties to be combined using a separator other than the default (a
single space). It is an alist with the car of each element being a
list of property names or regular expression and the cdr being the
separator string, like '((("EXPORT_FILE_NAME") . "/")).
---
etc/ORG-NEWS | 21 ++++++++++++++++++++
lisp/org.el | 43 ++++++++++++++++++++++++++++++++--------
testing/lisp/test-org.el | 30 +++++++++++++++++++++++++++-
3 files changed, 85 insertions(+), 9 deletions(-)
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 27de6da62..0297a9d49 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -141,6 +141,27 @@ discouraged when working with Org files.
** New features
+*** New customization option =org-property-separators=
+A new alist variable to control how properties are combined.
+
+If a property is specified multiple times with a =+=, like
+=:EXPORT_FILE_NAME+:=, the old behavior was to always combine them
+with a single space. For the new variable, the car of each item in the
+alist should be either a list of property names or a regular
+expression, while the cdr should be the separator to use when
+combining that property.
+
+The default value for the separator is a single space, if none of the
+provided items in the alist match a given property.
+
+For example, in order to combine =EXPORT_FILE_NAME= properties with a
+forward slash =/=, one can use
+
+#+begin_src emacs-lisp
+(setq org-use-property-inheritance '("EXPORT_FILE_NAME")
+ org-property-separators '((("EXPORT_FILE_NAME") . "/")))
+#+end_src
+
*** New library =org-persist.el= implements variable persistence across Emacs sessions
The library stores variable data in ~org-persist-directory~ (set to XDG
diff --git a/lisp/org.el b/lisp/org.el
index cab59b87c..a53505752 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -2850,6 +2850,30 @@ in this variable)."
(member-ignore-case property org-use-property-inheritance))
(t (error "Invalid setting of `org-use-property-inheritance'"))))
+(defcustom org-property-separators nil
+ "An alist to control how properties are combined.
+
+The car of each item should be either a list of property names or
+a regular expression, while the cdr should be the separator to
+use when combining that property.
+
+If an alist item cannot be found that matches a given property, a
+single space will be used as the separator."
+ :group 'org-properties
+ :type '(alist :key-type string :value-type sexp))
+
+(defun org-property-get-separator (property)
+ "Get the separator to use for combining PROPERTY."
+ (or
+ (catch 'separator
+ (dolist (spec org-property-separators)
+ (if (listp (car spec))
+ (if (member property (car spec))
+ (throw 'separator (cdr spec)))
+ (if (string-match-p (car spec) property)
+ (throw 'separator (cdr spec))))))
+ " "))
+
(defcustom org-columns-default-format "%25ITEM %TODO %3PRIORITY %TAGS"
"The default column format, if no other format has been defined.
This variable can be set on the per-file basis by inserting a line
@@ -12355,7 +12379,9 @@ value higher up the hierarchy."
(org-entry-get-with-inheritance property literal-nil))
(t
(let* ((local (org--property-local-values property literal-nil))
- (value (and local (mapconcat #'identity (delq nil local) " "))))
+ (value (and local (mapconcat #'identity
+ (delq nil local)
+ (org-property-get-separator property)))))
(if literal-nil value (org-not-nil value)))))))
(defun org-property-or-variable-value (var &optional inherit)
@@ -12464,7 +12490,8 @@ However, if LITERAL-NIL is set, return the string value \"nil\" instead."
(catch 'exit
(let ((element (or element
(and (org-element--cache-active-p)
- (org-element-at-point nil 'cached)))))
+ (org-element-at-point nil 'cached))))
+ (separator (org-property-get-separator property)))
(if element
(let ((element (org-element-lineage element '(headline org-data inlinetask) 'with-self)))
(while t
@@ -12472,8 +12499,8 @@ However, if LITERAL-NIL is set, return the string value \"nil\" instead."
(v (if (listp v) v (list v))))
(when v
(setq value
- (concat (mapconcat #'identity (delq nil v) " ")
- (and value " ")
+ (concat (mapconcat #'identity (delq nil v) separator)
+ (and value separator)
value)))
(cond
((car v)
@@ -12484,15 +12511,15 @@ However, if LITERAL-NIL is set, return the string value \"nil\" instead."
(t
(let ((global (org--property-global-or-keyword-value property literal-nil)))
(cond ((not global))
- (value (setq value (concat global " " value)))
+ (value (setq value (concat global separator value)))
(t (setq value global))))
(throw 'exit nil))))))
(while t
(let ((v (org--property-local-values property literal-nil)))
(when v
(setq value
- (concat (mapconcat #'identity (delq nil v) " ")
- (and value " ")
+ (concat (mapconcat #'identity (delq nil v) separator)
+ (and value separator)
value)))
(cond
((car v)
@@ -12513,7 +12540,7 @@ However, if LITERAL-NIL is set, return the string value \"nil\" instead."
(t
(let ((global (org--property-global-or-keyword-value property literal-nil)))
(cond ((not global))
- (value (setq value (concat global " " value)))
+ (value (setq value (concat global separator value)))
(t (setq value global))))
(throw 'exit nil))))))))
(if literal-nil value (org-not-nil value)))))
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index 0cee31d4e..c0c13f586 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -5997,7 +5997,35 @@ Paragraph<point>"
(org-test-with-temp-text
":PROPERTIES:\n:A: 0\n:END:\n#+PROPERTY: A 1\n* H\n:PROPERTIES:\n:A+: 2\n:END:"
(org-mode-restart)
- (org-entry-get (point-max) "A" t)))))
+ (org-entry-get (point-max) "A" t))))
+ ;; Use alternate separators
+ (should
+ (equal "0~2"
+ (org-test-with-temp-text
+ ":PROPERTIES:\n:A: 0\n:A+: 2\n:END:"
+ (let ((org-property-separators '((("A") . "~"))))
+ (org-entry-get (point) "A")))))
+ ;; Default separator is single space
+ (should
+ (equal "0 2"
+ (org-test-with-temp-text
+ ":PROPERTIES:\n:A: 0\n:B: 1\n:A+: 2\n:B+: 3\n:END:"
+ (let ((org-property-separators '((("B") . "~"))))
+ (org-entry-get (point) "A")))))
+ ;; Regular expression matching for separator
+ (should
+ (equal "0/2"
+ (org-test-with-temp-text
+ ":PROPERTIES:\n:A: 0\n:A+: 2\n:END:"
+ (let ((org-property-separators '((("B") . "~") ("[AC]" . "/"))))
+ (org-entry-get (point) "A")))))
+ ;; Separator works with inheritance
+ (should
+ (equal "1~2"
+ (org-test-with-temp-text
+ "* H\n:PROPERTIES:\n:A: 1\n:END:\n** H2\n:PROPERTIES:\n:A+: 2\n:END:"
+ (let ((org-property-separators '((("A") . "~"))))
+ (org-entry-get (point-max) "A" t))))))
(ert-deftest test-org/entry-properties ()
"Test `org-entry-properties' specifications."
--
2.35.3
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH] Re: Concatenate properties
2022-05-11 17:47 ` [PATCH] " Tyler Grinn
@ 2022-05-12 9:59 ` Ihor Radchenko
2022-05-12 23:27 ` Tyler Grinn
0 siblings, 1 reply; 19+ messages in thread
From: Ihor Radchenko @ 2022-05-12 9:59 UTC (permalink / raw)
To: Tyler Grinn; +Cc: org-mode-email
Tyler Grinn <tylergrinn@gmail.com> writes:
> OK, what I have now is that if the car of an alist item is a list, exact
> matching will be done for each list item, but if it is a string, it will
> be matched as a regular expression.
Sounds reasonable.
Note that your patch is >15LOC long and you need to sign the copyright
agreement with FSF in order to contribute. See
https://orgmode.org/worg/org-contribute.html#copyright
Some comments on the patch:
> * lisp/org.el (org-property-separators, org-property-get-separator):
> Created.
I'd make the function private: org--property-get-separator. It is not
intended as an API function.
> (org-entry-get, org-entry-get-with-inheritance): Use new
> org-property-get-separator function.
> org-property-separators is a customization option that allows for
Please quote the function name as `org-property-get-separator'.
> +If a property is specified multiple times with a =+=, like
> +=:EXPORT_FILE_NAME+:=, the old behavior was to always combine them
> +with a single space. For the new variable, the car of each item in
> the
Please, use double space " " to separate sentences. Also, see
doc/Documentation_Standards.org
> +For example, in order to combine =EXPORT_FILE_NAME= properties with a
> +forward slash =/=, one can use
> +
> +#+begin_src emacs-lisp
> +(setq org-use-property-inheritance '("EXPORT_FILE_NAME")
> + org-property-separators '((("EXPORT_FILE_NAME") . "/")))
> +#+end_src
This example is a bit confusing because it is unclear what you want to
achieve and why you also need to set inheritance.
> +(defcustom org-property-separators nil
> ...
> + :group 'org-properties
> + :type '(alist :key-type string :value-type sexp))
This defcustom type does not match what you described in the docstring.
You need something like :type '(alist :key-type (choice string (repeat string)) :value-type string)
Best,
Ihor
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Re: Concatenate properties
2022-05-12 9:59 ` Ihor Radchenko
@ 2022-05-12 23:27 ` Tyler Grinn
2022-05-13 12:21 ` Ihor Radchenko
0 siblings, 1 reply; 19+ messages in thread
From: Tyler Grinn @ 2022-05-12 23:27 UTC (permalink / raw)
To: Ihor Radchenko; +Cc: org-mode-email
[-- Attachment #1: Type: text/plain, Size: 2419 bytes --]
Ihor Radchenko <yantar92@gmail.com> writes:
> Note that your patch is >15LOC long and you need to sign the copyright
> agreement with FSF in order to contribute. See
> https://orgmode.org/worg/org-contribute.html#copyright
I've already submitted a copyright assignment to the FSF in order to
publish on ELPA. Do I need one specific to org-mode?
> Some comments on the patch:
>
>> * lisp/org.el (org-property-separators, org-property-get-separator):
>> Created.
>
> I'd make the function private: org--property-get-separator. It is not
> intended as an API function.
I agree, that was an oversight.
>
>> (org-entry-get, org-entry-get-with-inheritance): Use new
>> org-property-get-separator function.
>
>> org-property-separators is a customization option that allows for
>
> Please quote the function name as `org-property-get-separator'.
>
No problem.
>> +If a property is specified multiple times with a =+=, like
>> +=:EXPORT_FILE_NAME+:=, the old behavior was to always combine them
>> +with a single space. For the new variable, the car of each item in
>> the
>
> Please, use double space " " to separate sentences. Also, see
> doc/Documentation_Standards.org
No problem.
>
>> +For example, in order to combine =EXPORT_FILE_NAME= properties with a
>> +forward slash =/=, one can use
>> +
>> +#+begin_src emacs-lisp
>> +(setq org-use-property-inheritance '("EXPORT_FILE_NAME")
>> + org-property-separators '((("EXPORT_FILE_NAME") . "/")))
>> +#+end_src
>
> This example is a bit confusing because it is unclear what you want to
> achieve and why you also need to set inheritance.
Inheritance is the most likely scenario one would need to use the '+'
property syntax, but I do agree it's kinda distracting and not
absolutely necessary in order to get the correct behavior.
>
>> +(defcustom org-property-separators nil
>> ...
>> + :group 'org-properties
>> + :type '(alist :key-type string :value-type sexp))
>
> This defcustom type does not match what you described in the docstring.
> You need something like :type '(alist :key-type (choice string (repeat string)) :value-type string)
>
> Best,
> Ihor
Setting ':value-type string' is confusing, in my opinion, because the
default single space looks like: in the customization buffer, which is
indistinguishable from no space: . I just found out about the restricted-sexp
type, which I think makes the customization buffer more user-friendly.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Add org-property-separators option --]
[-- Type: text/x-patch, Size: 8763 bytes --]
From f474cb25840fdc6b24618b1452cb7fdd32545092 Mon Sep 17 00:00:00 2001
From: Tyler Grinn <tylergrinn@gmail.com>
Date: Mon, 9 May 2022 15:52:58 -0400
Subject: [PATCH] lisp/org.el: Add org-property-separators option
* lisp/org.el (org-property-separators, org-property-get-separator):
Created.
(org-entry-get, org-entry-get-with-inheritance): Use new
`org-property-get-separator' function.
* testing/lisp/test-org.el (test-org/entry-get): Added tests for
combining properties with custom separators
`org-property-separators' is a customization option that allows for
properties to be combined using a separator other than the default (a
single space). It is an alist with the car of each element being a
list of property names or regular expression and the cdr being the
separator string, like '((("EXPORT_FILE_NAME") . "/")).
---
etc/ORG-NEWS | 31 ++++++++++++++++++++++++++
lisp/org.el | 47 +++++++++++++++++++++++++++++++++-------
testing/lisp/test-org.el | 30 ++++++++++++++++++++++++-
3 files changed, 99 insertions(+), 9 deletions(-)
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 27de6da62..9d1d2cdcf 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -141,6 +141,37 @@ discouraged when working with Org files.
** New features
+*** New customization option =org-property-separators=
+A new alist variable to control how properties are combined.
+
+If a property is specified multiple times with a =+=, like
+
+#+begin_src org
+:PROPERTIES:
+:EXPORT_FILE_NAME: some/path
+:EXPORT_FILE_NAME+: to/file
+:END:
+#+end_src
+
+the old behavior was to always combine them with a single space
+(=some/path to/file=). For the new variable, the car of each item in
+the alist should be either a list of property names or a regular
+expression, while the cdr should be the separator to use when
+combining that property.
+
+The default value for the separator is a single space, if none of the
+provided items in the alist match a given property.
+
+For example, in order to combine =EXPORT_FILE_NAME= properties with a
+forward slash =/=, one can use
+
+#+begin_src emacs-lisp
+(setq org-property-separators '((("EXPORT_FILE_NAME") . "/")))
+#+end_src
+
+The example above would then produce the property value
+=some/path/to/file=.
+
*** New library =org-persist.el= implements variable persistence across Emacs sessions
The library stores variable data in ~org-persist-directory~ (set to XDG
diff --git a/lisp/org.el b/lisp/org.el
index cab59b87c..643fd6b73 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -2850,6 +2850,34 @@ in this variable)."
(member-ignore-case property org-use-property-inheritance))
(t (error "Invalid setting of `org-use-property-inheritance'"))))
+(defcustom org-property-separators nil
+ "An alist to control how properties are combined.
+
+The car of each item should be either a list of property names or
+a regular expression, while the cdr should be the separator to
+use when combining that property.
+
+If an alist item cannot be found that matches a given property, a
+single space will be used as the separator."
+ :group 'org-properties
+ :type '(alist :key-type (choice (repeat :tag "Properties" string)
+ (string :tag "Regular Expression"))
+ :value-type (restricted-sexp :tag "Separator"
+ :match-alternatives (stringp)
+ :value " ")))
+
+(defun org--property-get-separator (property)
+ "Get the separator to use for combining PROPERTY."
+ (or
+ (catch 'separator
+ (dolist (spec org-property-separators)
+ (if (listp (car spec))
+ (if (member property (car spec))
+ (throw 'separator (cdr spec)))
+ (if (string-match-p (car spec) property)
+ (throw 'separator (cdr spec))))))
+ " "))
+
(defcustom org-columns-default-format "%25ITEM %TODO %3PRIORITY %TAGS"
"The default column format, if no other format has been defined.
This variable can be set on the per-file basis by inserting a line
@@ -12355,7 +12383,9 @@ value higher up the hierarchy."
(org-entry-get-with-inheritance property literal-nil))
(t
(let* ((local (org--property-local-values property literal-nil))
- (value (and local (mapconcat #'identity (delq nil local) " "))))
+ (value (and local (mapconcat #'identity
+ (delq nil local)
+ (org--property-get-separator property)))))
(if literal-nil value (org-not-nil value)))))))
(defun org-property-or-variable-value (var &optional inherit)
@@ -12464,7 +12494,8 @@ However, if LITERAL-NIL is set, return the string value \"nil\" instead."
(catch 'exit
(let ((element (or element
(and (org-element--cache-active-p)
- (org-element-at-point nil 'cached)))))
+ (org-element-at-point nil 'cached))))
+ (separator (org--property-get-separator property)))
(if element
(let ((element (org-element-lineage element '(headline org-data inlinetask) 'with-self)))
(while t
@@ -12472,8 +12503,8 @@ However, if LITERAL-NIL is set, return the string value \"nil\" instead."
(v (if (listp v) v (list v))))
(when v
(setq value
- (concat (mapconcat #'identity (delq nil v) " ")
- (and value " ")
+ (concat (mapconcat #'identity (delq nil v) separator)
+ (and value separator)
value)))
(cond
((car v)
@@ -12484,15 +12515,15 @@ However, if LITERAL-NIL is set, return the string value \"nil\" instead."
(t
(let ((global (org--property-global-or-keyword-value property literal-nil)))
(cond ((not global))
- (value (setq value (concat global " " value)))
+ (value (setq value (concat global separator value)))
(t (setq value global))))
(throw 'exit nil))))))
(while t
(let ((v (org--property-local-values property literal-nil)))
(when v
(setq value
- (concat (mapconcat #'identity (delq nil v) " ")
- (and value " ")
+ (concat (mapconcat #'identity (delq nil v) separator)
+ (and value separator)
value)))
(cond
((car v)
@@ -12513,7 +12544,7 @@ However, if LITERAL-NIL is set, return the string value \"nil\" instead."
(t
(let ((global (org--property-global-or-keyword-value property literal-nil)))
(cond ((not global))
- (value (setq value (concat global " " value)))
+ (value (setq value (concat global separator value)))
(t (setq value global))))
(throw 'exit nil))))))))
(if literal-nil value (org-not-nil value)))))
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index 0cee31d4e..c0c13f586 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -5997,7 +5997,35 @@ Paragraph<point>"
(org-test-with-temp-text
":PROPERTIES:\n:A: 0\n:END:\n#+PROPERTY: A 1\n* H\n:PROPERTIES:\n:A+: 2\n:END:"
(org-mode-restart)
- (org-entry-get (point-max) "A" t)))))
+ (org-entry-get (point-max) "A" t))))
+ ;; Use alternate separators
+ (should
+ (equal "0~2"
+ (org-test-with-temp-text
+ ":PROPERTIES:\n:A: 0\n:A+: 2\n:END:"
+ (let ((org-property-separators '((("A") . "~"))))
+ (org-entry-get (point) "A")))))
+ ;; Default separator is single space
+ (should
+ (equal "0 2"
+ (org-test-with-temp-text
+ ":PROPERTIES:\n:A: 0\n:B: 1\n:A+: 2\n:B+: 3\n:END:"
+ (let ((org-property-separators '((("B") . "~"))))
+ (org-entry-get (point) "A")))))
+ ;; Regular expression matching for separator
+ (should
+ (equal "0/2"
+ (org-test-with-temp-text
+ ":PROPERTIES:\n:A: 0\n:A+: 2\n:END:"
+ (let ((org-property-separators '((("B") . "~") ("[AC]" . "/"))))
+ (org-entry-get (point) "A")))))
+ ;; Separator works with inheritance
+ (should
+ (equal "1~2"
+ (org-test-with-temp-text
+ "* H\n:PROPERTIES:\n:A: 1\n:END:\n** H2\n:PROPERTIES:\n:A+: 2\n:END:"
+ (let ((org-property-separators '((("A") . "~"))))
+ (org-entry-get (point-max) "A" t))))))
(ert-deftest test-org/entry-properties ()
"Test `org-entry-properties' specifications."
--
2.35.3
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH] Re: Concatenate properties
2022-05-12 23:27 ` Tyler Grinn
@ 2022-05-13 12:21 ` Ihor Radchenko
2022-05-14 2:11 ` Tyler Grinn
2022-05-20 8:04 ` Ihor Radchenko
0 siblings, 2 replies; 19+ messages in thread
From: Ihor Radchenko @ 2022-05-13 12:21 UTC (permalink / raw)
To: Tyler Grinn; +Cc: org-mode-email
Tyler Grinn <tylergrinn@gmail.com> writes:
> Ihor Radchenko <yantar92@gmail.com> writes:
>
>> Note that your patch is >15LOC long and you need to sign the copyright
>> agreement with FSF in order to contribute. See
>> https://orgmode.org/worg/org-contribute.html#copyright
>
> I've already submitted a copyright assignment to the FSF in order to
> publish on ELPA. Do I need one specific to org-mode?
Nope. The ELPA one is good enough. Basically, Org has the same
requirement as Emacs (Org is a part of Emacs).
>>> +(defcustom org-property-separators nil
>>> ...
>>> + :group 'org-properties
>>> + :type '(alist :key-type string :value-type sexp))
>>
>> This defcustom type does not match what you described in the docstring.
>> You need something like :type '(alist :key-type (choice string (repeat string)) :value-type string)
>
> Setting ':value-type string' is confusing, in my opinion, because the
> default single space looks like: in the customization buffer, which is
> indistinguishable from no space: . I just found out about the restricted-sexp
> type, which I think makes the customization buffer more user-friendly.
restricted-sexp is fine. Though you could also do something like
(choice (const :tag "Single space" " ") (string :tag "Other string"))
> From f474cb25840fdc6b24618b1452cb7fdd32545092 Mon Sep 17 00:00:00 2001
> From: Tyler Grinn <tylergrinn@gmail.com>
> Date: Mon, 9 May 2022 15:52:58 -0400
> Subject: [PATCH] lisp/org.el: Add org-property-separators option
LGTM!
I will leave this for another week to give other people a chance to
comment.
For reference, this patch might be useful in https://orgmode.org/list/87o821dv7o.fsf@localhost
Best,
Ihor
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Re: Concatenate properties
2022-05-13 12:21 ` Ihor Radchenko
@ 2022-05-14 2:11 ` Tyler Grinn
2022-05-20 8:04 ` Ihor Radchenko
1 sibling, 0 replies; 19+ messages in thread
From: Tyler Grinn @ 2022-05-14 2:11 UTC (permalink / raw)
To: Ihor Radchenko; +Cc: org-mode-email
Ihor Radchenko <yantar92@gmail.com> writes:
>> From f474cb25840fdc6b24618b1452cb7fdd32545092 Mon Sep 17 00:00:00 2001
>> From: Tyler Grinn <tylergrinn@gmail.com>
>> Date: Mon, 9 May 2022 15:52:58 -0400
>> Subject: [PATCH] lisp/org.el: Add org-property-separators option
>
> LGTM!
>
> I will leave this for another week to give other people a chance to
> comment.
>
> For reference, this patch might be useful in https://orgmode.org/list/87o821dv7o.fsf@localhost
>
> Best,
> Ihor
Great; it's exciting to have my first patch accepted and I look forward
to future development.
Best,
Tyler
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Re: Concatenate properties
2022-05-13 12:21 ` Ihor Radchenko
2022-05-14 2:11 ` Tyler Grinn
@ 2022-05-20 8:04 ` Ihor Radchenko
1 sibling, 0 replies; 19+ messages in thread
From: Ihor Radchenko @ 2022-05-20 8:04 UTC (permalink / raw)
To: Tyler Grinn; +Cc: org-mode-email
Ihor Radchenko <yantar92@gmail.com> writes:
> I will leave this for another week to give other people a chance to
> comment.
Applied upstream onto main via e268e4797.
Best,
Ihor
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2022-05-20 8:07 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-05-05 22:37 Concatenate properties Tyler Grinn
2022-05-05 22:56 ` John Kitchin
2022-05-06 15:40 ` Tyler Grinn
2022-05-07 5:33 ` Ihor Radchenko
2022-05-07 11:44 ` John Kitchin
2022-05-07 12:29 ` Tyler Grinn
2022-05-08 12:21 ` Ihor Radchenko
2022-05-08 14:14 ` Tyler Grinn
2022-05-08 14:47 ` Ihor Radchenko
2022-05-09 20:18 ` Tyler Grinn
2022-05-11 11:51 ` Ihor Radchenko
2022-05-11 17:47 ` [PATCH] " Tyler Grinn
2022-05-12 9:59 ` Ihor Radchenko
2022-05-12 23:27 ` Tyler Grinn
2022-05-13 12:21 ` Ihor Radchenko
2022-05-14 2:11 ` Tyler Grinn
2022-05-20 8:04 ` Ihor Radchenko
2022-05-07 13:20 ` John Kitchin
2022-05-07 14:09 ` Tyler Grinn
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).