Thanks a lot for the examples, they are very helpful! I first thought to parse the org buffer and then work with the resulting tree. But your examples now makes me think to work directly on the buffer. Well, I will play with a few different ways now…
Regards Eike Thorsten Jolitz writes: > Eike <e...@eknet.org> 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 > #<marker at 1263 in *outorg-edit-buffer*>) 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)