From mboxrd@z Thu Jan 1 00:00:00 1970 From: Thorsten Jolitz Subject: Re: [RFC] Rewrite `org-entry-properties' using parser Date: Thu, 21 Aug 2014 02:16:38 +0200 Message-ID: <87fvgqae8p.fsf@gmail.com> References: <87tx5xunas.fsf@gmail.com> <87a97o9w53.fsf@nicolasgoaziou.fr> <874mxrw139.fsf@gmail.com> <8761i525ak.fsf@nicolasgoaziou.fr> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:41034) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XKG3y-000876-1E for emacs-orgmode@gnu.org; Wed, 20 Aug 2014 20:17:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XKG3n-0005ih-Vy for emacs-orgmode@gnu.org; Wed, 20 Aug 2014 20:17:09 -0400 Received: from plane.gmane.org ([80.91.229.3]:50647) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XKG3n-0005iF-ML for emacs-orgmode@gnu.org; Wed, 20 Aug 2014 20:16:59 -0400 Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1XKG3k-0002oM-2U for emacs-orgmode@gnu.org; Thu, 21 Aug 2014 02:16:56 +0200 Received: from e178061066.adsl.alicedsl.de ([85.178.61.66]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Thu, 21 Aug 2014 02:16:56 +0200 Received: from tjolitz by e178061066.adsl.alicedsl.de with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Thu, 21 Aug 2014 02:16:56 +0200 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-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs-orgmode@gnu.org Nicolas Goaziou writes: Hello, > You may want to read my answer again. There is no "write this, write > that" in it. I'm pointing out what is missing or flawed and _suggesting_ > alternative approaches. I appreciate your comments and input, but unfortunately I gave up on the original idea because I did not want to make another "much more time consuming than planned" side-project out of this. >> so I rather leave this to you (or whoever wants to do it). > Unfortunately, my plate is full at the moment. Ok, so I simplified the task and wrote ,----[ C-h f org-dp-filter-node-props RET ] | org-dp-filter-node-props is a Lisp function in `org-dp-lib.el'. | | (org-dp-filter-node-props FILTER &optional NEGATE-P SILENT-P) | | Return filtered node-properties. | FILTER should either be the car of one of the cons-pairs in | `org-dp-prop-filters' or a regexp-string. If NEGATE-P is non-nil, | the properties not matched by the filter are returned. If | SILENT-P is non-nil, no message is printed if no property-drawer | is found. `---- - this function acts on element-type 'node-property', not 'headline' - it does not attempt to replace `org-entry-properties' or to be compatible with its signature, its written from scratch. but it does what I want - make it easy to filter out application properties and user defined properties from the usual property-mix found in property drawers. It relies on the following constants: ,----[ C-h v org-dp-prop-filters RET ] | org-dp-prop-filters is a variable defined in `org-dp-lib.el'. | Its value is ((special . org-special-properties) | (custom . org-custom-properties) | (default . org-default-properties) | (file . org-file-properties) | (global mapcar 'car org-global-properties) | (org) | (user-defined)) | | Alist of filter-types and associated property-classes. `---- (do I miss an Org property class here?) ,----[ C-h v org-dp-org-props RET ] | org-dp-org-props is a variable defined in `org-dp-lib.el'. | [...] | Union of special, custom, file and global properties, as well | as those properties specified by the user in customizable | variable `org-dp-misc-props'. `---- Thus given the following Org headline two typical function calls would be: #+BEGIN_SRC emacs-lisp :results raw (save-excursion (outline-next-heading) (org-dp-filter-node-props "^foo-.")) #+END_SRC #+results: ((foo-star . star1) (foo-bar . bar1)) #+BEGIN_SRC emacs-lisp :results raw (save-excursion (outline-next-heading) (org-dp-filter-node-props 'org t)) #+END_SRC #+results: ((cho-bar . bar2) (foo-star . star1) (foo-bar . bar1)) * ORG SCRATCH :PROPERTIES: :CUSTOM_ID: abc123 :CATEGORY: mycat :foo-bar: bar1 :foo-star: star1 :cho-bar: bar2 :END: PS For completeness I attach the code: #+BEGIN_SRC emacs-lisp (defun org-dp-filter-node-props (filter &optional negate-p silent-p) "Return filtered node-properties. FILTER should either be the car of one of the cons-pairs in `org-dp-prop-filters' or a regexp-string. If NEGATE-P is non-nil, the properties not matched by the filter are returned. If SILENT-P is non-nil, no message is printed if no property-drawer is found." (let ((props (save-excursion (and (or (org-at-heading-p) (outline-previous-heading)) (re-search-forward org-property-drawer-re nil 'NOERROR 1) (progn (goto-char (match-beginning 0)) (org-dp-contents))))) filtered-props) (if (not props) (unless silent-p (message "Could not find properties at point %d in buffer %s." (point) (current-buffer))) (org-element-map props 'node-property (lambda (--prop) (let* ((key (org-element-property :key --prop)) (val (org-element-property :value --prop)) (memberp (case filter ((special custom default file global) (member-ignore-case key (eval (cdr-safe (assoc filter org-dp-prop-filters))))) (org (member-ignore-case key org-dp-org-props)) (t (if (stringp filter) (string-match filter key) (error "Not a valid filter: %s" filter)))))) (when (or (and negate-p (not memberp)) (and (not negate-p) memberp)) (setq filtered-props (cons (cons key val) filtered-props)))))) filtered-props))) #+END_SRC -- cheers, Thorsten