From mboxrd@z Thu Jan 1 00:00:00 1970 From: Thorsten Jolitz Subject: Re: accessing properties in org-element-parse-buffer tree Date: Sat, 30 Aug 2014 21:41:07 +0200 Message-ID: <87bnr17oks.fsf@gmail.com> References: <87ppfhzweg.fsf@ithaka.home> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:42008) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XNoWk-0001xB-8J for emacs-orgmode@gnu.org; Sat, 30 Aug 2014 15:41:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XNoWY-000728-H2 for emacs-orgmode@gnu.org; Sat, 30 Aug 2014 15:41:34 -0400 Received: from plane.gmane.org ([80.91.229.3]:39468) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XNoWY-00071q-AZ for emacs-orgmode@gnu.org; Sat, 30 Aug 2014 15:41:22 -0400 Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1XNoWU-0003Rk-Vt for emacs-orgmode@gnu.org; Sat, 30 Aug 2014 21:41:18 +0200 Received: from e178062046.adsl.alicedsl.de ([85.178.62.46]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sat, 30 Aug 2014 21:41:18 +0200 Received: from tjolitz by e178062046.adsl.alicedsl.de with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sat, 30 Aug 2014 21:41:18 +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 Eike writes: Hello, > I want to ask for help regarding elisp and org-elements. I like to > access the properties of all my headlines and I created the following > function (tree is the parsed tree) that collects them into an a-list: > > #+begin_src emacs-lisp > (defun collect-props (tree) > (car (org-element-map tree 'headline > (lambda (hl) > (when (eq 2 (org-element-property :level hl)) ; want only level-2 properties > (org-element-map hl 'node-property > (lambda (np) > (cons (org-element-property :key np) > (org-element-property :value np))))))))) > #+end_src > > I'm not very confident about this, is this ok? Is there a better way? > For example, the first car looks strange, and I don't know how to get > rid of it. * Answer :PROPERTIES: :CUSTOM_ID: abc123 :foo: bar :END: There are several options, here a few examples, some using my new function 'org-dp-filter-node-props' from org-dp-lib.el which is very good at filtering out only those node-properties you are really interested in. 'org-entry-properties' does some filtering too, but its less generic. #+NAME: ex1 #+BEGIN_SRC emacs-lisp :results raw (org-map-entries (lambda () (org-entry-properties nil nil "foo"))) #+END_SRC #+results: (((CATEGORY . 989)) ((CUSTOM_ID . abc123) (foo . bar) (CATEGORY . 989))) #+NAME: ex2 #+BEGIN_SRC emacs-lisp :results raw (require 'org-dp-lib) (org-map-entries (lambda () (org-dp-filter-node-props 'org t t))) #+END_SRC #+results: (nil ((foo . bar))) #+NAME: ex3 #+BEGIN_SRC emacs-lisp :results raw (org-element-map (org-element-parse-buffer 'headline) 'headline (lambda (hl) (when (eq 1 (org-element-property :level hl)) ; want only level-2 properties (org-element-property :FOO hl)))) #+END_SRC #+results: ex3 (bar) #+NAME: ex4 #+BEGIN_SRC emacs-lisp :results raw (let (props) (save-excursion (goto-char (point-min)) (while (re-search-forward "^\\*+ " nil t) (save-excursion (beginning-of-line) (setq props (cons (org-dp-filter-node-props '("FOO" "CUSTOM_ID") nil t) props)))) (delq nil props))) #+END_SRC #+results: ex4 (((foo . bar) (CUSTOM_ID . abc123))) PS 1 Strange behaviour in src-block ex1. Neither the example given nor (org-entry-properties nil "foo") (org-entry-properties nil "foo" "foo") return what I would expect. PS 2 Without the :results header-arg I get the following error when running src-block ex2: Debugger entered--Lisp error: (args-out-of-range 0 1) orgtbl-to-orgtbl((nil (("foo" . "bar"))) (:fmt (lambda (cell) (format "%s" cell)))) org-babel-insert-result((nil (("foo" . "bar"))) ("replace") ("emacs-lisp" "(require 'org-dp-lib)\n(org-map-entries (lambda () (org-dp-filter-node-props 'org t t)))" ((:comments . "") (:shebang . "") (:cache . "no") (:padline . "") (:noweb . "no") (:tangle . "no") (:exports . "code") (:results . "replace") (:session . "none") (:hlines . "no") (:result-type . value) (:result-params "replace") (:rowname-names) (:colname-names)) "" nil 0 #) nil 0 "emacs-lisp") org-babel-execute-src-block(nil) org-babel-execute-src-block-maybe() org-babel-execute-maybe() org-babel-execute-safely-maybe() run-hook-with-args-until-success(org-babel-execute-safely-maybe) org-ctrl-c-ctrl-c(nil) call-interactively(org-ctrl-c-ctrl-c nil nil) -- cheers, Thorsten