From mboxrd@z Thu Jan 1 00:00:00 1970 From: Thorsten Jolitz Subject: Re: Two potentially useful functions for org-element Date: Thu, 07 Aug 2014 10:59:22 +0200 Message-ID: <87oavwad5h.fsf@gmail.com> References: <87wqalql21.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:34177) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XFJXz-0004X3-Rw for emacs-orgmode@gnu.org; Thu, 07 Aug 2014 04:59:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XFJXs-0003cu-B1 for emacs-orgmode@gnu.org; Thu, 07 Aug 2014 04:59:43 -0400 Received: from plane.gmane.org ([80.91.229.3]:42455) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XFJXs-0003ch-4O for emacs-orgmode@gnu.org; Thu, 07 Aug 2014 04:59:36 -0400 Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1XFJXq-0001GR-Nk for emacs-orgmode@gnu.org; Thu, 07 Aug 2014 10:59:34 +0200 Received: from g231105104.adsl.alicedsl.de ([92.231.105.104]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Thu, 07 Aug 2014 10:59:34 +0200 Received: from tjolitz by g231105104.adsl.alicedsl.de with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Thu, 07 Aug 2014 10:59:34 +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 Thorsten Jolitz writes: Hi List, > now that I understand the 'org-element API' a bit better, I think that > the following two functions can be very useful for creating and > modifying Org elements without the usual point movements, regexp > searches and string operations in a buffer: > > #+begin_src emacs-lisp > ;; might become `org-element-create' > (defun* tj/create-element (&optional insert-p &rest args &key (type 'headline) &allow-other-keys) > "Create Org element, maybe insert at point." > (let ((strg (org-element-interpret-data > (list type args)))) > (if insert-p (insert strg) strg))) > #+end_src I made the second 'rewire element' function smarter so that it can now reuse the old value when setting a new value for a property of the 'rewired' element: #+begin_src emacs-lisp ;; might become `org-element-rewire' (defun* tj/rewire-element (&optional replace &rest args &key type &allow-other-keys) "Rewire element at point, maybe replace it. The former value of an element property can be reused in the creation of a new value by giving a `lambda' expession with one function argument instead of a value to a key. That argument will then be replaced by the property's former value when applying the function." (let* ((elem (org-element-at-point)) (plist (cadr elem)) (beg (org-element-property :begin elem)) (end (org-element-property :end elem)) strg) (while args (let* ((key (pop args)) (val-or-fun (pop args)) (old-val (org-element-property key elem)) (new-val (if (functionp val-or-fun) (apply val-or-fun (list old-val)) val-or-fun))) (setq plist (plist-put plist key new-val)))) (setq strg (org-element-interpret-data (list (or type (org-element-type elem)) plist))) (case replace (append (save-excursion (goto-char end) (insert strg))) (prepend (goto-char beg) (insert strg)) (t (if replace (let ((marker (save-excursion (goto-char end) (point-marker)))) (delete-region beg end) (goto-char marker) (set-marker marker nil) (save-excursion (insert strg))) strg))))) #+end_src #+results: : tj/rewire-element Here a few examples, all of them assuming point is at beginning of this src-block if not stated otherwise: #+begin_src emacs-lisp (+ 2 2) #+end_src 1. do M-: [content-of-next-src-block] #+begin_src emacs-lisp (tj/rewire-element 'append :name (format "rewired-%d" (1+ (random 10)))) #+end_src #+NAME: rewired-7 #+BEGIN_SRC emacs-lisp (+ 2 2) #+END_SRC 2. do M-: [content-of-next-src-block] #+begin_src emacs-lisp (tj/rewire-element 'append :name (lambda (_old_) (if _old_ (format "rewired-%d" (* (string-to-number (car (last (split-string _old_ "-" t)))) (1+ (random 10)))) (format "rewired-%d" (1+ (random 10))))) :language "picolisp") #+end_src gives #+NAME: rewired-2 #+BEGIN_SRC picolisp (+ 2 2) #+END_SRC when called on the original src-block, but #+NAME: rewired-63 #+BEGIN_SRC picolisp (+ 2 2) #+END_SRC when called on the result of usage example 1 (with name rewired-7). 3. do M-: [content-of-next-src-block] #+begin_src emacs-lisp (tj/rewire-element 'append :value (lambda (_old_) (concat "(message \"%d\" " (car (split-string _old_ "\n" t)) ")\n")) :parameters ":results raw") #+end_src gives #+BEGIN_SRC emacs-lisp :results raw (message "%d" (+ 2 2)) #+END_SRC -- cheers, Thorsten