From mboxrd@z Thu Jan 1 00:00:00 1970 From: John Kitchin Subject: question on org-element-interpret-data and when it works Date: Sun, 25 Feb 2018 16:12:14 -0800 Message-ID: Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="089e082fd1c4ccd5850566125c7e" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:34076) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eq6Ox-0004Uk-E3 for emacs-orgmode@gnu.org; Sun, 25 Feb 2018 19:12:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eq6Ov-00076W-QK for emacs-orgmode@gnu.org; Sun, 25 Feb 2018 19:12:19 -0500 Received: from mail-wr0-x236.google.com ([2a00:1450:400c:c0c::236]:38634) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eq6Ov-00075l-G1 for emacs-orgmode@gnu.org; Sun, 25 Feb 2018 19:12:17 -0500 Received: by mail-wr0-x236.google.com with SMTP id n7so19450271wrn.5 for ; Sun, 25 Feb 2018 16:12:17 -0800 (PST) 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" To: org-mode-email --089e082fd1c4ccd5850566125c7e Content-Type: text/plain; charset="UTF-8" I am trying to find some ways to programatically modify org-elements that use fewer regexps and motion commands. It seems like org-dp ( https://github.com/tj64/org-dp) was intended to do that but it is not clear enough how you might use it, and it also doesn't seem to support plain-lists yet. What I imagined happening is that I would get the element to modify as a data structure, modify the data structure, and replace the old element with an interpreted version of the modified data structure. I want to do something like a radio list where only one box can be checked at a time. Suppose I have this: #+attr_org: :radio - [ ] one - [ ] two - [ ] three It gets represented from org-element-context as: (plain-list (:type unordered :begin 579 :end 630 :contents-begin 598 :contents-end 630 :structure ((598 0 "- " nil "[ ]" nil 608) (608 0 "- " nil "[ ]" nil 618) (618 0 "- " nil "[ ]" nil 630)) :post-blank 0 :post-affiliated 598 :attr_org (":radio") :parent nil)) What I thought I could is something like (here I simulate having point in the first item): #+BEGIN_SRC emacs-lisp :results code (let* ((p 600) ;where current point is n (data '(plain-list (:type unordered :begin 579 :end 630 :contents-begin 598 :contents-end 630 :structure ((598 0 "- " nil "[ ]" nil 608) (608 0 "- " nil "[ ]" nil 618) (618 0 "- " nil "[ ]" nil 630)) :post-blank 0 :post-affiliated 598 :attr_org (":radio") :parent nil))) (structure (plist-get (cadr data) :structure))) (loop for i from 0 for item in structure do (if (and (>= p (first item)) (< p (seventh item))) ;; in the item, toggle it (setf (fifth item) (if (string= "[X]" (fifth item)) "[ ]" "[X]")) ;; not on the item (setf (fifth item) "[ ]"))) data) #+END_SRC Which outputs: #+RESULTS: #+BEGIN_SRC emacs-lisp (plain-list (:type unordered :begin 579 :end 630 :contents-begin 598 :contents-end 630 :structure ((598 0 "- " nil "[X]" nil 608) (608 0 "- " nil "[ ]" nil 618) (618 0 "- " nil "[ ]" nil 630)) :post-blank 0 :post-affiliated 598 :attr_org (":radio") :parent nil)) #+END_SRC As a step towards getting to a data structure I could programmatically modify, and then reinterpret, I made this little function: (defun ointerp () (interactive) (let ((el (org-element-context))) (kill-new (org-element-interpret-data el)))) It works on some things, e.g. headlines, src blocks. I put the point on one of those things, run this command, and then I can paste it somewhere to see that it did indeed work. But, it does not work on plain-lists, or paragraphs. I either get an empty string, or Wrong type argument: char-or-string-p, nil Is it possible to do what I am describing? Am I just missing how to get the element data in the right form? Thanks, John ----------------------------------- Professor John Kitchin Doherty Hall A207F Department of Chemical Engineering Carnegie Mellon University Pittsburgh, PA 15213 412-268-7803 @johnkitchin http://kitchingroup.cheme.cmu.edu --089e082fd1c4ccd5850566125c7e Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
I am trying to find some ways to programatically modi= fy org-elements that use fewer regexps and motion commands. It seems like o= rg-dp (https://github.com/tj64/o= rg-dp)=C2=A0was intended to do that but it is not clear enough how you = might use it, and it also doesn't seem to support plain-lists yet.

What I imagined happening is that I would get the elem= ent to modify as a data structure, modify the data structure, and replace t= he old element with an interpreted version of the modified data structure.<= /div>

I want to do something like a radio list where onl= y one box can be checked at a time. Suppose I have this:

#+attr_org: :radio
- [ ] one
- [ ] two
- [ ] three

It gets represented from o= rg-element-context as:

(plain-list
=
=C2=A0(:type unordered :begin 579 :end 630 :contents-begin 598 :conten= ts-end 630 :structure
((5= 98 0 "- " nil "[ ]" nil 608)
(608 0 "- " nil "[ ]" nil 618)=
(618 0 "- " n= il "[ ]" nil 630))
:post-blank 0 :post-affiliated 598 :attr_org
(":radio")
:parent nil))

What= I thought I could is something like (here I simulate having point in the f= irst item):

#+BEGIN_SRC emacs-lisp :results c= ode
(let* ((p 600) ;wh= ere current point is
=C2=A0 =C2=A0 =C2=A0 =C2=A0n
=C2= =A0 =C2=A0 =C2=A0 =C2=A0(data '(plain-list
=C2=A0 =C2=A0 =C2=A0 =C2=A0(:type unordered :begin 57= 9 :end 630 :contents-begin 598 :contents-end 630 :structure
=C2=A0 =C2=A0 =C2=A0 ((598 0 "- &q= uot; nil "[ ]" nil 608)
=C2=A0 =C2=A0 =C2=A0 =C2=A0(608 0 "- " nil "[ ]&qu= ot; nil 618)
=C2=A0 =C2= =A0 =C2=A0 =C2=A0(618 0 "- " nil "[ ]" nil 630))
<= div> =C2=A0 =C2=A0 =C2=A0 :post-bla= nk 0 :post-affiliated 598 :attr_org
=C2=A0 =C2=A0 =C2=A0 (":radio")
=C2=A0 =C2=A0 =C2=A0 :parent nil)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0(structure (plist-get (cadr data) :structure)))=
=C2=A0 (loop for i from 0 for item in structure
do=C2=A0
(if (and (>=3D p (first item))
(< p (seventh item)))
=C2=A0 =C2=A0 ;; in the item, toggle it
=C2=A0 =C2=A0 (setf (fifth it= em) (if (string=3D "[X]" (fifth item))
=C2=A0 =C2=A0"[ ]"
"[X]"))
=C2=A0 ;; not on the item
=C2=A0 (setf (fifth item) "[ ]")))<= /div>
=C2=A0=C2=A0
=C2=A0 data)=C2=A0
#+END_SRC

Which outputs:

#+= RESULTS:
#+BEGIN_SRC emacs-lisp
(plain-list
= =C2=A0(:type unordered :begin 579 :end 630 :contents-begin 598 :contents-en= d 630 :structure
((598 0 = "- " nil "[X]" nil 608)
(608 0 "- " nil "[ ]" nil 618)
(618 0 "- " nil &q= uot;[ ]" nil 630))
:= post-blank 0 :post-affiliated 598 :attr_org
(":radio")
:parent nil))
#+END_SRC

=
As a step towards getting to a data structure I could programmatically= modify, and then reinterpret, I made this little function:

<= /div>
(defun ointerp ()
=C2=A0 (interactive)
=C2=A0 (let ((el (org-element-context)))
=C2=A0 =C2=A0 (kill-new (org-eleme= nt-interpret-data el))))

It works on some things, e.g. = headlines, src blocks. I put the point on one of those things, run this com= mand, and then I can paste it somewhere to see that it did indeed work.

But, it does not work on plain-lists, or paragraphs. = I either get an empty string, or Wrong type argument: char-or-string-p, nil=

Is it possible to do what I am describing? Am I j= ust missing how to get the element data in the right form?

Thanks,



John
=
-----------------------------------
Professor John Kitchin=C2=A0
= Doherty Hall A207F
Department of Chemical Engineering
Carnegie Mellon= University
Pittsburgh, PA 15213
412-268-7803
--089e082fd1c4ccd5850566125c7e--