all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Thibaut Meyer via "General discussions about Org-mode." <emacs-orgmode@gnu.org>
To: yantar92@posteo.net
Cc: emacs-orgmode@gnu.org
Subject: [PATCH] ob-tangle: source blocks without language can be tangled (was: [BUG] Inconsistent org-babel tangle behaviour)
Date: Tue, 31 Dec 2024 10:31:59 +0100	[thread overview]
Message-ID: <20241231093553.13814-1-thibaut@thibaut.dev> (raw)
In-Reply-To: <87jzbix4le.fsf@localhost>

* lisp/ob-tangle.el: (org-babel-tangle-collect-blocks): source blocks
without a language are not not ignored anymore, if they inherit a
src-tfile other than "yes" or "no".
* lisp/ob-core.el: adapts the org-babel-src-block-regexp regular
expression to make the language part of a source block optional.
* testing/lisp/test-ob-tangle.el: (ob-tangle/collect-blocks): Augment
the test with source blocks without language specifiers.
* etc/ORG-NEWS: (=ob-tangle= now tangles source blocks that do not
specify a =language= if an inherited property sets a tangle filename):
Document the new behaviour.
* doc/org-manual.org: (Structure of Code Blocks) Clarify what happens
when the language identifier is omitted.
---
Here is my attempt. Modifying the regex in ob-core.el felt scary, but
it seems fine since this didn't break any tests and manually testing the
new regex seemed to work fine. I've added the small change to the
documentation as you suggested as I think it clarifies things regarding
how the source block structure is interpreted.
Cheers.

 doc/org-manual.org             |  3 ++-
 etc/ORG-NEWS                   |  8 ++++++++
 lisp/ob-core.el                |  4 ++--
 lisp/ob-tangle.el              |  8 ++++++--
 testing/lisp/test-ob-tangle.el | 16 ++++++++++++----
 5 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/doc/org-manual.org b/doc/org-manual.org
index 2d5fd57b3..f0c53265a 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -18028,7 +18028,8 @@ or
   block.  See [[*Languages]], for identifiers of supported languages.
 
   When =<language>= identifier is omitted, the block also cannot
-  have =<switches>= and =<header arguments>=.
+  have =<switches>= and =<header arguments>=.  Otherwise, the first
+  switch/argument will be treated as =<language>=.
 
   Language identifier is also used to fontify code blocks in Org
   buffers, when ~org-src-fontify-natively~ is set to non-~nil~.  See
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 2d4616fab..4aa628c7e 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -437,6 +437,14 @@ For example, given =H:3= and =toc:2= in =#+OPTIONS:=, all headings at
 the 1st and 2nd level appear in the table of contents and those at the
 3rd level do not.
 
+*** =ob-tangle= now tangles source blocks that do not specify a =language= if an inherited property sets a tangle filename
+
+Previously, all source blocks that did not specify a =language= where
+ignored by ~org-babel-tangle-collect-blocks~. Now, if it inherits a
+:tangle header argument with a value other than =no= or =yes= (that is, a
+filename), a source block without =language= will get tangled to that
+file.
+
 * Version 9.7
 
 ** Important announcements and breaking changes
diff --git a/lisp/ob-core.el b/lisp/ob-core.el
index ff021cbd3..cf56367f8 100644
--- a/lisp/ob-core.el
+++ b/lisp/ob-core.el
@@ -216,8 +216,8 @@ When matching, reference is stored in match group 1."
 
 (defvar org-babel-src-block-regexp
   (concat
-   ;; (1) indentation                 (2) lang
-   "^\\([ \t]*\\)#\\+begin_src[ \t]+\\([^ \f\t\n\r\v]+\\)[ \t]*"
+   ;; (1) indentation                      (2) lang
+   "^\\([ \t]*\\)#\\+begin_src\\(?:[ \t]+\\([^ \f\t\n\r\v]*\\)\\)?[ \t]*"
    ;; (3) switches
    "\\([^\":\n]*\"[^\"\n*]*\"[^\":\n]*\\|[^\":\n]*\\)"
    ;; (4) header arguments
diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el
index 044212da2..d37d3c67f 100644
--- a/lisp/ob-tangle.el
+++ b/lisp/ob-tangle.el
@@ -508,9 +508,13 @@ code blocks by target file."
 	       (src-lang (nth 0 info))
 	       (src-tfile (cdr (assq :tangle (nth 2 info)))))
 	  (unless (or (string= src-tfile "no")
-                      (not src-lang) ;; src block without lang
+                      ;; src block without lang
+                      (and (not src-lang) (string= src-tfile "yes"))
 		      (and tangle-file (not (equal tangle-file src-tfile)))
-		      (and lang-re (not (string-match-p lang-re src-lang))))
+                      ;; lang-re but either no lang or lang doesn't match
+		      (and lang-re
+                           (or (not src-lang)
+                               (not (string-match-p lang-re src-lang)))))
 	    ;; Add the spec for this block to blocks under its tangled
 	    ;; file name.
 	    (let* ((block (org-babel-tangle-single-block counter))
diff --git a/testing/lisp/test-ob-tangle.el b/testing/lisp/test-ob-tangle.el
index e13bca0cb..6e95c4c91 100644
--- a/testing/lisp/test-ob-tangle.el
+++ b/testing/lisp/test-ob-tangle.el
@@ -628,6 +628,10 @@ another block
 \"H1: :tangle ~/../../tmp/absolute.el\"
 #+end_src
 
+#+begin_src
+\"H1: no language and inherited :tangle relative.el in properties\"
+#+end_src
+
 * H2 without :tangle in properties
 
 #+begin_src emacs-lisp
@@ -660,6 +664,10 @@ another block
 
 #+begin_src emacs-lisp :tangle ~/../../tmp/absolute.el
 \"H2: :tangle ~/../../tmp/absolute.el\"
+#+end_src
+
+#+begin_src
+\"H2: without language and thus without :tangle\"
 #+end_src"
                     `((?a . ,el-file-abs)
                       (?r . ,el-file-rel))))
@@ -684,7 +692,7 @@ another block
                                               collected-blocks)))))
         (should (equal (funcall normalize-expected-targets-alist
                                 `(("/tmp/absolute.el" . 4)
-                                  ("relative.el" . 5)
+                                  ("relative.el" . 6)
                                   ;; file name differs between tests
                                   (,el-file-abs . 4)))
                        (funcall count-blocks-in-target-files
@@ -699,11 +707,11 @@ another block
           (should (equal
                    (funcall normalize-expected-targets-alist
                             `(("/tmp/absolute.el" . 4)
-                              ("relative.el" . 5)
+                              ("relative.el" . 6)
                               ;; Default :tangle header now also
                               ;; points to the file name derived from the name of
-                              ;; the Org file, so 5 blocks should go there.
-                              (,el-file-abs . 5)))
+                              ;; the Org file, so 6 blocks should go there.
+                              (,el-file-abs . 6)))
                    (funcall count-blocks-in-target-files
                             (org-babel-tangle-collect-blocks)))))))))
 
-- 
2.47.1



  reply	other threads:[~2024-12-31 10:04 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-12  7:45 [BUG] Inconsistent org-babel tangle behaviour Thibaut Meyer via General discussions about Org-mode.
2024-12-22 12:37 ` Ihor Radchenko
2024-12-28 13:48   ` Thibaut Meyer via General discussions about Org-mode.
2024-12-29  8:42     ` Ihor Radchenko
2024-12-31  9:31       ` Thibaut Meyer via General discussions about Org-mode. [this message]
2025-01-01  8:29         ` [PATCH] ob-tangle: source blocks without language can be tangled (was: [BUG] Inconsistent org-babel tangle behaviour) Ihor Radchenko
2025-01-01  8:59           ` [PATCH] ob-tangle: source blocks without language can be tangled Thibaut Meyer via General discussions about Org-mode.
2025-01-01  9:18             ` Thibaut Meyer via General discussions about Org-mode.
2025-01-01 13:53               ` Ihor Radchenko
2025-01-01 20:09                 ` Thibaut Meyer via General discussions about Org-mode.
2025-01-02 18:56                   ` Ihor Radchenko
2025-01-03  6:34                     ` Thibaut Meyer via General discussions about Org-mode.
2025-01-01 13:51             ` Ihor Radchenko
2025-01-01 20:16               ` Thibaut Meyer via General discussions about Org-mode.
2025-01-02 18:55                 ` Ihor Radchenko

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

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

  git send-email \
    --in-reply-to=20241231093553.13814-1-thibaut@thibaut.dev \
    --to=emacs-orgmode@gnu.org \
    --cc=thibaut@thibaut.dev \
    --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 external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.