Re: [O] accessing properties in org-element-parse-buffer tree

2014-08-31 Thread Eike


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

2014-08-30 Thread Eric Abrahamsen
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

2014-08-30 Thread Thorsten Jolitz
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

2014-08-30 Thread Eike

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

2014-08-30 Thread Thorsten Jolitz
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

2014-08-30 Thread Eike

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

2014-08-30 Thread Eike

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