From mboxrd@z Thu Jan 1 00:00:00 1970 From: John Kitchin Subject: Re: Expose value-begin and value-end instead of just value in org-element API Date: Sun, 25 Feb 2018 19:43:26 -0800 Message-ID: References: <87k1v6k2wt.fsf@nicolasgoaziou.fr> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:48845) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eq9hN-0003yp-Nt for emacs-orgmode@gnu.org; Sun, 25 Feb 2018 22:43:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eq9hM-0004Sf-E9 for emacs-orgmode@gnu.org; Sun, 25 Feb 2018 22:43:33 -0500 Received: from mail-pg0-x234.google.com ([2607:f8b0:400e:c05::234]:35519) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eq9hM-0004SW-4L for emacs-orgmode@gnu.org; Sun, 25 Feb 2018 22:43:32 -0500 Received: by mail-pg0-x234.google.com with SMTP id l131so5703344pga.2 for ; Sun, 25 Feb 2018 19:43:31 -0800 (PST) In-reply-to: <87k1v6k2wt.fsf@nicolasgoaziou.fr> 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: Nicolas Goaziou Cc: "Somelauw ." , "emacs-orgmode@gnu.org" Nicolas Goaziou writes: > Hello, > > John Kitchin writes: > >> +1 on this. >> >> I also have some janky code to do things like go to the beginning/end of >> the value in a src block. Here is my solution to mark the code in a src >> block. >> >> (defun ob-ipython-mark-code () >> "Mark the code in the block." >> (interactive) >> (org-edit-special) >> (let ((p0 (point-min)) >> (p1 (point-max))) >> (goto-char p0) >> (org-edit-src-exit) >> (set-mark (point)) >> (goto-char (+ (point) (- p1 2))))) > > You get the beginning of the code of a source block with > > (org-with-point-at (org-element-property :post-affiliated element) > (line-beginning-position 2)) > > and its end with > > (org-with-point-at (org-element-property :end element) > (line-beginning-position (- (org-element-property :post-blank element)))) > Wow. I would not have guessed either one of these! Thanks for sharing them. Is that documented somewhere? I gather that given something like #+header: :var a=5 #+name: test #+BEGIN_SRC ipython print(a) #+END_SRC which parses like (from org-element-context): (src-block (:language "ipython" :switches nil :parameters nil :begin 362 :end 436 :number-lines nil :preserve-indent nil :retain-labels t :use-labels t :label-fmt nil :value "\nprint(a)\n\n" :post-blank 1 :post-affiliated 394 :header (":var a=5") :name "test" :parent nil)) In this: :begin refers to the point at the beginning of the #+header line. whereas :post-affiliated is the point after all the "affiliated" header/name lines, i.e. the beginning of #+BEGIN_SRC. :end refers to the point where the end of the element is, which may include blank lines. :post-blank is the number of blank lines (including lines that are just spaces) after the element. is that the right interpretation? For elements with a :contents-begin where does :post-affiliated come in? > From there, you can easily construct something that doesn't rely on > `org-edit-special'. > >>> I think it would be preferable to also expose the value by beginning and >>> ending buffer positions for the following reasons: >>> - Consistency with elements that expose contents-begin and contents-end. > > The point is terminal elements are not consistent with non-terminal > ones, and should not be. > >>> - More powerful. In my evil-org plugin I want to be able to mark the value >>> property of the org element at point (so the user can do stuff like easily >>> copy the code of the current code block), but to do so I need the beginning >>> and ending position in the buffer of "value". The org-element API does >>> currently not provide clean way to retrieve these positions. > > See above. It is quite simple to extract this information from the parse > tree. Once you get the idea, maybe, but this approach seems specific to src-blocks (maybe any block) where there are delimiting lines. It doesn't work on all elements (which to be fair was not claimed). I think the OP was interested in something more consistent, which I am sympathetic to. Some things aren't clear to me what should happen though, especially in composite elements like tables and plain lists. E.g. To just select a table without the affiliated lines, one can use :contents-begin and :contents-end, once you get the table element (e.g. by walking up the :parent chain if you are in a cell or row). In the absence of a single way, maybe there could be a small number of ways to do this? How many cases do you think there are? - blocks (which have :value) - composite elements (which have :contents-begin/end and/or non-nil :parents) - regular elements (which have :contents-begin/end) Are there any others? > >>> - It's usually more efficient to return the beginning and ending positions >>> than to retrieve the substring that contains the value, which may require a >>> large buffer partition to be copied. > > Efficiency is a moot point because you still need to store the value of > the block. If you remove it, the parse tree is no longer an equivalent > representation of the document. I can see this argument, but I am still unclear on which elements need a value, and which don't. For example, src-blocks have a value, but a paragraph doesn't, nor do items in a plain list, at least from (org-element-context). I guess my confusion comes from these being different than what comes out of (org-element-parse-buffer). > > Regards, -- 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