emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[O] [ANN] org-dp.el - Declarative Programming with Org Elements


From: Thorsten Jolitz
Subject: [O] [ANN] org-dp.el - Declarative Programming with Org Elements
Date: Sun, 17 Aug 2014 03:12:14 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux)

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]