Re: [O] accessing properties in org-element-parse-buffer tree
Eric Abrahamsen writes: > Eike writes: > >> Hello list, >> >> 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: > > You could also take a look at org-collector, in contrib. It might give > you some ideas, or even solve your problem directly. Yes, that looks really interesting! Thanks for the tip! Kind regards Eike
Re: [O] accessing properties in org-element-parse-buffer tree
Eike writes: > Hello list, > > 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: You could also take a look at org-collector, in contrib. It might give you some ideas, or even solve your problem directly. > #+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. > > Thanks you very much in advance!!! > Kind regards > Eike > > -- > gpg: AD7AC35E > finger print: 137F BB0B 1639 D25F DC5D E59C B412 C5F5 AD7A C35E
Re: [O] accessing properties in org-element-parse-buffer tree
Eike writes: > 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. Thats the obvious thing to do in this case, and you can do everything you want this way, but there are some alternatives too. > But your examples now makes me think to work directly on the > buffer. Well, I will play with a few different ways now… I wrote 'org-dp-filter-node-props' based on 'org-dp-contents', so only the property-drawer of the current entry is parsed and its content (the node-properties) filtered. This is meant mostly for local usage (in contrast to the global parse-tree), but can be used as function argument for org-map-entries too. The big advantage is that it becomes really easy to filter out all the system properties, or all properties that do not belong to a specific application. I use it quite often now because I like the database functionality of Org properties. -- cheers, Thorsten
Re: [O] accessing properties in org-element-parse-buffer tree
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 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)
Re: [O] accessing properties in org-element-parse-buffer tree
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
Re: [O] accessing properties in org-element-parse-buffer tree
Hello again it seems that I messed up my testing variables… I always had just one headline and thus the list of lists had always one element that I then extracted with `car'. So `car' must be removed: #+begin_src emacs-lisp (defun collect-props (tree) (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'd still be curious if there are other/better ways to do that; or is this idiomatic usage of provided org functions? Thanks again and kind regards Eike Eike writes: > Hello list, > > 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. > > Thanks you very much in advance!!! > Kind regards > Eike -- gpg: AD7AC35E finger print: 137F BB0B 1639 D25F DC5D E59C B412 C5F5 AD7A C35E
[O] accessing properties in org-element-parse-buffer tree
Hello list, 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. Thanks you very much in advance!!! Kind regards Eike -- gpg: AD7AC35E finger print: 137F BB0B 1639 D25F DC5D E59C B412 C5F5 AD7A C35E