emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Thorsten Jolitz <tjolitz@gmail.com>
To: emacs-orgmode@gnu.org
Subject: [ANN] org-dp.el - Declarative Programming with Org Elements
Date: Sun, 17 Aug 2014 03:12:14 +0200	[thread overview]
Message-ID: <87r40f6hsh.fsf@gmail.com> (raw)


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	other threads:[~2014-08-17  1:12 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87r40f6hsh.fsf@gmail.com \
    --to=tjolitz@gmail.com \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).