From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kaushal Modi Subject: Re: Concatenating Org property values from parent subtrees Date: Mon, 1 Oct 2018 17:00:32 -0400 Message-ID: References: <87k1n46tdw.fsf@luisa.c0t0d0s0.de> <87k1n42jm5.fsf@luisa.c0t0d0s0.de> <87k1n414ww.fsf@luisa.c0t0d0s0.de> <87ftxpu0rb.fsf@yantar92-laptop.i-did-not-set--mail-host-address--so-tickle-me> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="000000000000b595bc0577311a7c" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:46810) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g75JZ-0001Du-1O for emacs-orgmode@gnu.org; Mon, 01 Oct 2018 17:01:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g75JW-0002bh-Pt for emacs-orgmode@gnu.org; Mon, 01 Oct 2018 17:01:12 -0400 Received: from mail-lf1-x12b.google.com ([2a00:1450:4864:20::12b]:35188) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g75JW-0002b5-HA for emacs-orgmode@gnu.org; Mon, 01 Oct 2018 17:01:10 -0400 Received: by mail-lf1-x12b.google.com with SMTP id r191-v6so10993424lff.2 for ; Mon, 01 Oct 2018 14:01:10 -0700 (PDT) In-Reply-To: <87ftxpu0rb.fsf@yantar92-laptop.i-did-not-set--mail-host-address--so-tickle-me> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: "Emacs-orgmode" To: yantar92@gmail.com Cc: emacs-org list , mwe012008@gmx.net --000000000000b595bc0577311a7c Content-Type: text/plain; charset="UTF-8" On Mon, Oct 1, 2018 at 11:50 AM Ihor Radchenko wrote: > Hi, > > Check out the following code: > > ```` > (defvar org-concatenated-properties '("AA") > "A list of property names (strings), which should be computed via > concatenation with the parent properties.") > > (define-advice org-entry-get (:around (oldfun pom property &optional > inherit literal-nil) concatenate-parents-maybe) > Hello Ihor, That code is perfect! I was able to get what I want with minor refactoring. Thanks! Refactored code: ===== (defvar org-concatenated-properties '("AA") "List of property names whose values are allowed to be concatenated. The list is of type '(PROP1 PROP2 ..) where each element is a string.") (defvar org-property-concat-string "/" "String use to concat the `org-concatenated-properties' properties.") (defun org-get-parent-property (property inherit literal-nil) "Get the value of PROPERTY from the parent relative to current point." (org-with-wide-buffer (if (org-up-heading-safe) (or (org-entry-get nil property inherit literal-nil) "") ""))) (defun org/advice-concatenate-properties-maybe (orig-fun &rest args) "Concatenate an Org Property value with its inherited value. The concatenation happens only if the Org Property is in `org-concatenated-properties' list." (let* ((value-orig (apply orig-fun args)) (property (nth 1 args)) (dont-concat (not (member property org-concatenated-properties)))) ;; (message "dbg: args:%S value-orig:%S property:%S" args value-orig property) (if dont-concat value-orig (let* ((pom (nth 0 args)) (inherit (nth 2 args)) (literal-nil (nth 3 args)) (value-here-no-inherit (apply orig-fun `(,pom ,property nil ,literal-nil))) (value-parent (apply #'org-get-parent-property `(,property ,inherit ,literal-nil)))) ;; (message "dbg advice: value-here-no-inherit: %S" value-here-no-inherit) (if value-here-no-inherit (format "%s%s%s" value-parent (if (org-string-nw-p value-parent) org-property-concat-string "") value-orig) value-parent))))) (advice-add 'org-entry-get :around #'org/advice-concatenate-properties-maybe) ;; (advice-remove 'org-entry-get #'org/advice-concatenate-properties-maybe) ===== Example Org file: ===== * heading 1 :PROPERTIES: :FOO: abc :END: asdf ** heading 1 :PROPERTIES: :FOO: def :AA: pqr :END: *** heading 2 :PROPERTIES: :FOO: 123 :AA: 456 :END: **** heading 3 ===== --000000000000b595bc0577311a7c Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On Mon, Oct 1, 2018 at 11:50 AM Ihor Radchenko <yantar92@gmail.com> wrote:
Hi,

Check out the following code:

````
(defvar org-concatenated-properties '("AA")
=C2=A0 "A list of property names (strings), which should be computed v= ia concatenation with the parent properties.")

(define-advice org-entry-get (:around (oldfun pom property &optional in= herit literal-nil) concatenate-parents-maybe)

Hello Ihor,

That code is perfect!

I was able to get what I want with minor refactoring. Thank= s!

Refactored code:

=3D= =3D=3D=3D=3D
(defvar org-concatenated-properties '("= AA")
=C2=A0 "List of property names whose values are allowed t= o be concatenated.
The list is of type '(PROP1 PROP2 ..) where each = element is a string.")

(defvar org-property-concat-string "= ;/"
=C2=A0 "String use to concat the `org-concatenated-propert= ies' properties.")

(defun org-get-parent-property (property= inherit literal-nil)
=C2=A0 "Get the value of PROPERTY from the pa= rent relative to current point."
=C2=A0 (org-with-wide-buffer
= =C2=A0=C2=A0 (if (org-up-heading-safe)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 (or (org-entry-get nil property inherit literal-nil) "")
= =C2=A0=C2=A0=C2=A0=C2=A0 "")))

(defun org/advice-concatena= te-properties-maybe (orig-fun &rest args)
=C2=A0 "Concatenate a= n Org Property value with its inherited value.
The concatenation happens= only if the Org Property is in
`org-concatenated-properties' list.&= quot;
=C2=A0 (let* ((value-orig (apply orig-fun args))
=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (property (nth 1 args))
=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (dont-concat (not (member property = org-concatenated-properties))))
=C2=A0=C2=A0=C2=A0 ;; (message "dbg= : args:%S value-orig:%S property:%S" args value-orig property)
=C2= =A0=C2=A0=C2=A0 (if dont-concat
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 value-orig
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (let* ((pom (nth 0 args))<= br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= (inherit (nth 2 args))
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 (literal-nil (nth 3 args))
=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (value-here-no-inher= it (apply orig-fun `(,pom ,property nil ,literal-nil)))
=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (value-parent (ap= ply #'org-get-parent-property `(,property ,inherit ,literal-nil))))
= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ;; (message "dbg advice: va= lue-here-no-inherit: %S" value-here-no-inherit)
=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 (if value-here-no-inherit
=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (format "%s%s%s"=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 value-parent
=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 (if (org-string-nw-p value-parent)
=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 org-property-concat-str= ing
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "")<= br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 value-orig)
=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 value-parent)))))
(advice-add &#= 39;org-entry-get :around #'org/advice-concatenate-properties-maybe)
= ;; (advice-remove 'org-entry-get #'org/advice-concatenate-propertie= s-maybe)
=3D=3D=3D=3D=3D

Example Org= file:

=3D=3D=3D=3D=3D

* heading 1:PROPERTIES:
:FOO:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 abc
:END:

a= sdf
** heading 1
:PROPERTIES:
:FOO: def
:AA: pqr
:END:
**= * heading 2
:PROPERTIES:
:FOO: 123
:AA: 456
:END:
**** headi= ng 3
=3D=3D=3D=3D=3D
--000000000000b595bc0577311a7c--