From: gerard.vermeulen@posteo.net
To: Ihor Radchenko <yantar92@posteo.net>
Cc: Emacs orgmode <emacs-orgmode@gnu.org>
Subject: Re: [PATCH] org-babel-demarcate-block: split using org-element instead of regexp
Date: Tue, 02 Jan 2024 20:20:00 +0000 [thread overview]
Message-ID: <e0252d664af25728243734d67432ad64@posteo.net> (raw)
In-Reply-To: <87zfxo3taa.fsf@localhost>
[-- Attachment #1: Type: text/plain, Size: 1848 bytes --]
On 02.01.2024 11:48, Ihor Radchenko wrote:
> gerard.vermeulen@posteo.net writes:
>
[...]
>
> IMHO, this is a bug.
> The current approach with regexp matching in
> `org-babel-demarcate-block'
> is clearly not accurate. What would be more robust is using
> org-element-at-point + org-element-copy + set :value +
> org-element-interpret-data to carry over all the affiliated keywords
> and
> header arguments.
>
[...]
>
> (org-babel--get-vars (nth 2 (org-babel-get-src-block-info)))
Attached you'll find a new patch trying to implement your suggestions.
Interactive splitting by demarcation seems to work quite well (see the
before and after splitting snippets in the PS).
However, I cannot run the test because org-babel-demarcate-block
always errors "org-element--cache: Emergency exit" while the same
input works interactively. Could there be a problem of cache
synchronization or something like that? Is there something I can do?
I also did not yet look into how to propagate a switch like -n10.
PS:
# begin before splitting snippet
#+caption[Demarcation splitting test]:
#+caption: Demarcation splitting test.
#+header: :var edge="also copied"
#+header: :wrap "src any-spanish -n"
#+name: lst:test
#+begin_src python -i -n :var here="copied" :wrap "src any-english -n"
# above-split
# below-split
#+end_src
# end before splitting snippet
# begin after splitting snippet
#+caption[Demarcation splitting test]:
#+caption: Demarcation splitting test.
#+header: :var edge="also copied"
#+header: :wrap "src any-spanish -n"
#+name: lst:test
#+begin_src python -i -n :var here="copied" :wrap "src any-english -n"
# above-split
#+end_src
#+header: :var edge="also copied"
#+header: :wrap "src any-spanish -n"
#+begin_src python -i -n :var here="copied" :wrap "src any-english -n"
# below-split
#+end_src
# end after splitting snippet
[-- Attachment #2: 0001-org-babel-demarcate-block-split-using-org-element-in.patch --]
[-- Type: application/octet-stream, Size: 5783 bytes --]
From bfd1615e4e0e0dad64e8559f39cb638d6f2d9ce4 Mon Sep 17 00:00:00 2001
From: Gerard Vermeulen <gerard.vermeulen@posteo.net>
Date: Sat, 30 Dec 2023 19:25:25 +0100
Subject: [PATCH] org-babel-demarcate-block: split using org-element instead of
regexp
* lisp/ob-babel.el (org-babel-demarcate-block): Delete the caption and
the name from a copy of (org-element-at-point) and set its value to
the body inside the source block after point. Delete all superfluous
text after point from the current Emacs buffer and add a proper
sentinel to the upper source block. Insert the lower block by
applying `org-element-interpret-data' to the modified copy. Leave
point in a convenient position.
* testing/lisp/test-ob.el (test-ob/demarcate-block-split): New test
for block splitting by demarcation. It checks also that the language,
switches, and header arguments are duplicated.
---
lisp/ob-core.el | 37 +++++++++++++------------------------
testing/lisp/test-ob.el | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+), 24 deletions(-)
diff --git a/lisp/ob-core.el b/lisp/ob-core.el
index f7e4e255f..d541af612 100644
--- a/lisp/ob-core.el
+++ b/lisp/ob-core.el
@@ -2067,35 +2067,24 @@ block of the same language with the previous."
(start (org-babel-where-is-src-block-head))
;; `start' will be nil when within space lines after src block.
(block (and start (match-string 0)))
- (headers (and start (match-string 4)))
(stars (concat (make-string (or (org-current-level) 1) ?*) " "))
(upper-case-p (and block
(let (case-fold-search)
(string-match-p "#\\+BEGIN_SRC" block)))))
(if (and info start) ;; At src block, but not within blank lines after it.
- (mapc
- (lambda (place)
- (save-excursion
- (goto-char place)
- (let ((lang (nth 0 info))
- (indent (make-string (org-current-text-indentation) ?\s)))
- (when (string-match "^[[:space:]]*$"
- (buffer-substring (line-beginning-position)
- (line-end-position)))
- (delete-region (line-beginning-position) (line-end-position)))
- (insert (concat
- (if (looking-at "^") "" "\n")
- indent (if upper-case-p "#+END_SRC\n" "#+end_src\n")
- (if arg stars indent) "\n"
- indent (if upper-case-p "#+BEGIN_SRC " "#+begin_src ")
- lang
- (if (> (length headers) 1)
- (concat " " headers) headers)
- (if (looking-at "[\n\r]")
- ""
- (concat "\n" (make-string (current-column) ? )))))))
- (move-end-of-line 2))
- (sort (if (org-region-active-p) (list (mark) (point)) (list (point))) #'>))
+ (let* ((body-end (match-end 5))
+ (copy (org-element-copy (org-element-at-point)))
+ (beyond (aref (plist-get (cadr copy) :standard-properties) 4))
+ (indent (make-string (org-current-text-indentation) ?\s)))
+ (plist-put (cadr copy) :caption nil)
+ (plist-put (cadr copy) :name nil)
+ (plist-put (cadr copy) :value (buffer-substring (point) body-end))
+ (delete-region (point) beyond)
+ (insert (concat indent (if upper-case-p "#+END_SRC\n" "#+end_src\n")
+ (if arg stars indent) "\n"))
+ (insert (org-element-interpret-data copy))
+ ;; Go back to the lower source block for `org-narrow-to-element':
+ (re-search-backward (rx bol (1+ nonl))))
(let ((start (point))
(lang (or (car info) ; Reuse language from previous block.
(completing-read
diff --git a/testing/lisp/test-ob.el b/testing/lisp/test-ob.el
index 42c77ca56..cfd825c14 100644
--- a/testing/lisp/test-ob.el
+++ b/testing/lisp/test-ob.el
@@ -26,6 +26,42 @@
(require 'org-table)
(eval-and-compile (require 'cl-lib))
+(ert-deftest test-ob/demarcate-block-split ()
+ "Test duplication of headers and switches in demarcation block splitting."
+ (org-test-with-temp-text "
+#+header: :var edge=\"also duplicated\"
+#+header: :wrap \"src any-spanish -n\"
+#+begin_src emacs-lisp -i -n :var here=\"duplicated\" :wrap \"src any-english -n\"
+
+'above-split
+<point>
+'below-split
+
+#+end_src
+"
+ (let ((wrap-val "src any-spanish -n") above below avars bvars)
+ ;; BUG: org-babel-demarcate-block errors "org-element--cache: Emergency exit"
+ (org-babel-demarcate-block)
+ (setq above (org-babel-get-src-block-info))
+ (setq avars (org-babel--get-vars (nth 2 above)))
+ (org-babel-next-src-block)
+ (setq below (org-babel-get-src-block-info))
+ (setq bvars (org-babel--get-vars (nth 2 below)))
+ ;; duplicated multi-line header arguments:
+ (should (string= "also duplicated" (cdr (assq 'edge avars))))
+ (should (string= "also duplicated" (cdr (assq 'edge bvars))))
+ (should (string= wrap-val (cdr (assq :wrap (nth 2 above)))))
+ (should (string= wrap-val (cdr (assq :wrap (nth 2 below)))))
+ ;; duplicated language, other header arguments, and switches:
+ (should (string= "emacs-lisp" (nth 0 above)))
+ (should (string= "emacs-lisp" (nth 0 below)))
+ (should (string= "'above-split" (org-trim (nth 1 above))))
+ (should (string= "'below-split" (org-trim (nth 1 below))))
+ (should (string= "duplicated" (cdr (assq 'here avars))))
+ (should (string= "duplicated" (cdr (assq 'here bvars))))
+ (should (string= "-i -n" (nth 3 above)))
+ (should (string= "-i -n" (nth 3 below))))))
+
(ert-deftest test-ob/indented-cached-org-bracket-link ()
"When the result of a source block is a cached indented link it
should still return the link."
--
2.42.0
next prev parent reply other threads:[~2024-01-02 20:21 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-30 19:13 [PATCH] org-babel-demarcate-block: duplicate switches too gerard.vermeulen
2023-12-31 14:28 ` Ihor Radchenko
2024-01-01 12:52 ` gerard.vermeulen
2024-01-02 10:48 ` Ihor Radchenko
2024-01-02 20:20 ` gerard.vermeulen [this message]
2024-01-03 15:11 ` [PATCH] org-babel-demarcate-block: split using org-element instead of regexp Ihor Radchenko
2024-01-04 8:59 ` gerard.vermeulen
2024-01-04 14:43 ` Ihor Radchenko
2024-01-07 18:49 ` [PATCH] org-babel-demarcate-block: split using element API gerard.vermeulen
2024-01-08 12:08 ` Ihor Radchenko
2024-01-08 20:25 ` gerard.vermeulen
2024-01-09 7:49 ` gerard.vermeulen
2024-01-09 10:50 ` gerard.vermeulen
2024-01-09 14:49 ` Ihor Radchenko
2024-01-13 14:04 ` gerard.vermeulen
2024-01-13 15:17 ` Ihor Radchenko
2024-01-13 20:16 ` gerard.vermeulen
2024-01-14 10:53 ` gerard.vermeulen
2024-01-14 12:16 ` Ihor Radchenko
2024-01-14 19:18 ` gerard.vermeulen
2024-01-15 9:37 ` gerard.vermeulen
2024-01-16 13:34 ` Ihor Radchenko
2024-02-19 9:46 ` Ihor Radchenko
2024-02-19 13:01 ` gerard.vermeulen
2024-02-21 9:40 ` Ihor Radchenko
2024-02-21 18:19 ` gerard.vermeulen
2024-02-22 16:28 ` gerard.vermeulen
2024-02-23 13:43 ` Ihor Radchenko
2024-02-25 12:06 ` gerard.vermeulen
2024-02-25 12:21 ` Ihor Radchenko
2024-02-26 8:51 ` gerard.vermeulen
2024-02-28 11:54 ` Ihor Radchenko
2024-02-29 9:50 ` gerard.vermeulen
2024-02-29 11:56 ` Ihor Radchenko
2024-02-29 17:33 ` gerard.vermeulen
2024-03-03 13:08 ` Ihor Radchenko
2024-03-03 15:45 ` gerard.vermeulen
2024-03-04 10:12 ` Ihor Radchenko
2024-03-04 11:40 ` gerard.vermeulen
2024-03-04 11:51 ` Ihor Radchenko
2024-02-26 9:06 ` gerard.vermeulen
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=e0252d664af25728243734d67432ad64@posteo.net \
--to=gerard.vermeulen@posteo.net \
--cc=emacs-orgmode@gnu.org \
--cc=yantar92@posteo.net \
/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).