From mboxrd@z Thu Jan 1 00:00:00 1970 From: Thorsten Jolitz Subject: [ANN] org-dp.el - Declarative Programming with Org Elements Date: Sun, 17 Aug 2014 03:12:14 +0200 Message-ID: <87r40f6hsh.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:45824) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XIp1O-00050L-7u for emacs-orgmode@gnu.org; Sat, 16 Aug 2014 21:12:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XIp1I-00027O-9b for emacs-orgmode@gnu.org; Sat, 16 Aug 2014 21:12:34 -0400 Received: from plane.gmane.org ([80.91.229.3]:39537) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XIp1H-00026e-Uj for emacs-orgmode@gnu.org; Sat, 16 Aug 2014 21:12:28 -0400 Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1XIp1F-0000cY-Iy for emacs-orgmode@gnu.org; Sun, 17 Aug 2014 03:12:25 +0200 Received: from g231111238.adsl.alicedsl.de ([92.231.111.238]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sun, 17 Aug 2014 03:12:25 +0200 Received: from tjolitz by g231111238.adsl.alicedsl.de with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sun, 17 Aug 2014 03:12:25 +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 Hi List, check it out, its cool (but still work in progress)! (https://github.com/tj64/org-dp) Primarily meant for acting on local elements (i.e. without parsing the whole buffer). Acts on the internal (nested list) representation of the elements instead on their textual representation (what you see in the buffer), and thus reduces the creation and modification of local Org elements to assigning values to properties. Since the internal representation of elements is very uniform "(type (properties) (contents))", programming with org-dp lets you express diverse actions on diverse elements in very uniform ways. Its really only about two functions: ,----[ C-h f org-dp-create RET ] | org-dp-create is a Lisp function in `org-dp.el'. | | (org-dp-create ELEM-TYPE &optional CONTENTS INSERT-P AFFILIATED &rest | ARGS) | | Create Org element, maybe insert at point. | | [back] `---- ,----[ C-h f org-dp-rewire RET ] | org-dp-rewire is a Lisp function in `org-dp.el'. | | (org-dp-rewire ELEM-TYPE &optional CONTENTS REPLACE AFFILIATED ELEMENT | &rest ARGS) | | Rewire element-at-point or ELEMENT (if given). | | If CONTENT is non-nil, act conditional on its value: | | - string or internal representation (parse-tree) :: use | raw/interpreted value as rewired element's contents. | | - function with two arguments :: call function with original | argument's contents (in parse-tree format) as first argument | and original element (in parse-tree format) as second | argument. Use the returned string/list (in parse-tree format) | as rewired element's raw/interpreted contents. | | - t :: (boolean) get interpreted contents of original element. | | Act conditional on value of REPLACE: | | - append :: (symbol) append rewired element after original element | | - prepend :: (symbol) prepend rewired element before original element | | - non-nil :: (any) replace original element with rewired element | | - nil :: just return rewired element | | Act conditional on value of AFFILIATED: | | - list of keywords :: (consp) properties of the original element | whose keys are member (memq) of this list (of downcased | keywords from `org-element-affiliated-keywords') are | retained in the rewired element. | | - non-nil :: (any) all affiliated keywords are retained in | rewired element. | | - nil :: (boolean) no affiliated keywords are retained in | rewired element. | | ELEM-TYPE is one of the types in `org-element-all-elements'. If | it is nil, the element type of the original element is used. ARGS | is a plist consisting of key-val pairs of all other keyword | arguments given. | | The former value of an element property can be reused in the | creation of a new value by giving a `lambda' expession with two | function arguments instead of a value to a key. The first | argument will then be replaced by the property's former value | when applying the function. The second argument should be the | parsed element itself, enabling access to its type and all its | properties inside of the lambda expression. | | [back] `---- Here is a 'funny' example: Eval this: #+begin_src emacs-lisp (defun my-get-pri (_old_ elem) (let (prio) (mapc (lambda (--param) (when (string-match ":var " --param) (setq prio (string-to-number (car (last (split-string --param "=" t))))))) (org-element-property :header elem)) prio)) #+end_src #+results: : my-get-pri and then copy this into an org-mode buffer and call M-x org-babel-execute-buffer on that buffer: * ORG SCRATCH #+BEGIN_SRC emacs-lisp -l (org-dp-rewire 'headline "hello world" t nil nil :level (lambda (_old_ elem) (let ((head (org-element-property :header elem))) (if head (length head) 1))) :todo-keyword "TODO" :priority 'my-get-pri :title (lambda (_old_ elem) (format "%s %s" (org-element-property :language elem) (org-element-property :switches elem))) :archivedp nil :tags '("office" "home") :commentedp nil :pre-blank 1 :footnote-section-p nil) #+END_SRC #+NAME: myblock1 #+HEADER: :var pri=67 #+BEGIN_SRC emacs-lisp -n (org-dp-rewire 'headline "hello world" t nil nil :level (lambda (_old_ elem) (length (org-element-property :header elem))) :todo-keyword "TODO" :priority 'my-get-pri :title (lambda (_old_ elem) (format "%s %s" (org-element-property :language elem) (org-element-property :switches elem))) :archivedp nil :tags '("office" "home") :commentedp nil :pre-blank 1 :footnote-section-p nil) #+END_SRC #+NAME: myblock #+HEADER: :results none #+HEADER: :var pri=66 #+BEGIN_SRC emacs-lisp (org-dp-rewire 'headline "hello world" t nil nil :level (lambda (_old_ elem) (length (org-element-property :header elem))) :todo-keyword "TODO" :priority 'my-get-pri :title (lambda (_old_ elem) (org-element-property :language elem)) :archivedp nil :tags '("office" "home") :commentedp nil :pre-blank 1 :footnote-section-p nil) #+END_SRC The src-blocks will replace themselves with headlines that contain information from the src-blocks. I added another file to the git repo, org-dp-lib.el, containing useful functions programmed with org-dp. Right now only one is really working, but its already quite useful, hope there will be more soon: ,----[ C-h f org-dp-toggle-headers RET ] | org-dp-toggle-headers is an interactive Lisp function in | `org-dp-lib.el'. | | (org-dp-toggle-headers &optional ACTION) | | Toggle header argument representation. | With prefix-arg, prompt user for ACTION, otherwise, if non-nil, | it should take one the values `swap', `header' or `param', | meaning to either swap :header and :parameter values, or make | them all :header or :parameter values repectively. | | [back] `---- put point on beginning of this src-block and call M-x org-dp-toggle-headers #+header: :exports both #+begin_src emacs-lisp :results raw :var x=2 (+ 2 2) #+end_src => swapped #+HEADER: :results raw #+HEADER: :var x=2 #+BEGIN_SRC emacs-lisp :exports both (+ 2 2) #+END_SRC now put point on beginning of this src-block and call C-u M-x org-dp-toggle-headers and select 'header': => all headers #+HEADER: :exports both #+HEADER: :results raw #+HEADER: :var x=2 #+BEGIN_SRC emacs-lisp (+ 2 2) #+END_SRC now once again put point on beginning of this src-block and call M-x org-dp-toggle-headers => all params #+BEGIN_SRC emacs-lisp :var x=2 :results raw :exports both (+ 2 2) #+END_SRC -- cheers, Thorsten