From a78471e77479503db52b3428a3ff6aab3b7cc2be Mon Sep 17 00:00:00 2001
From: Mingtong Lin <mt.oss@fastmail.com>
Date: Thu, 27 Nov 2025 14:42:16 -0500
Subject: [PATCH 1/6] lisp/ob-core.el: Fix incorrect interposition of Noweb
 prefixes testing/lisp/test-ob.el: Add test.

* ob-core.el (org-babel-expand-noweb-references): Fix incorrect
interposition of Noweb prefixes.

Currently, the following example

,#+name: a string
,#+begin_src emacs-lisp
"hello"
,#+end_src

,#+begin_src emacs-lisp :tangle tangle-bug.el :noweb yes :comments noweb
prefix<<a string>>
,#+end_src

tangles to

,#+begin_src emacs-lisp
;; [[file:org-babel-tangle.org::*Incorrect interposition of Noweb prefix when =:comments noweb=][Incorrect interposition of Noweb prefix when =:comments noweb=:2]]
prefix;; [[file:org-babel-tangle.org::a string][a string]]
prefix"hello"
prefix;; a string ends here
prefix
;; Incorrect interposition of Noweb prefix when =:comments noweb=:2 ends here
,#+end_src

where we get one more occurrence of "prefix" than expected at the end of
the expansion.  This is because org-babel-expand-noweb-references adds
an empty line after the Noweb comments blindly, *before* interposition
happens.

In this patch, the empty line is only added when needed (i.e., when
Noweb comments are desired, and the block body does not end with a Noweb
reference), and is done after the interposition.

Reported-by: "Mingtong Lin" <mt.oss@fastmail.com>
Link: https://list.orgmode.org/f43360bb-dc8f-41bb-b40e-dfdd38ebb87b@app.fastmail.com/
---
 lisp/ob-core.el         | 21 ++++++++++++++-------
 testing/lisp/test-ob.el | 22 +++++++++++++++++++++-
 2 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/lisp/ob-core.el b/lisp/ob-core.el
index ddd3766a3..32177fb56 100644
--- a/lisp/ob-core.el
+++ b/lisp/ob-core.el
@@ -3230,7 +3230,7 @@ block but are passed literally to the \"example-block\"."
 		         (let ((cs (org-babel-tangle-comment-links ,i)))
 		           (concat (c-wrap (car cs)) "\n"
 			           b "\n"
-			           (c-wrap (cadr cs)) "\n")))))
+			           (c-wrap (cadr cs)))))))
 	          (expand-references
 	            (ref)
 	            `(pcase (gethash ,ref org-babel-expand-noweb-references--cache)
@@ -3320,12 +3320,19 @@ block but are passed literally to the \"example-block\"."
 			      (push info (gethash ref org-babel-expand-noweb-references--cache))))))
                        (puthash 'buffer-processed t org-babel-expand-noweb-references--cache)
 		       (expand-references id)))))
-	       ;; Interpose PREFIX between every line.
-               (if noweb-prefix
-		   (mapconcat #'identity
-			      (split-string expansion "[\n\r]")
-			      (concat "\n" prefix))
-                 expansion)))))
+	       (let ((interposed
+	              ;; Interpose PREFIX between every line.
+		      (if noweb-prefix
+			  (mapconcat #'identity
+				     (split-string expansion "[\n\r]")
+				     (concat "\n" prefix))
+			expansion))
+		     (ref (concat org-babel-noweb-wrap-start
+				  id
+				  org-babel-noweb-wrap-end)))
+		 (if (and comment (not (string-suffix-p ref body)))
+		     (concat interposed "\n")
+		   interposed))))))
        body t t 2))))
 
 (defun org-babel--script-escape-inner (str)
diff --git a/testing/lisp/test-ob.el b/testing/lisp/test-ob.el
index a75e5fa72..bdb8d9c21 100644
--- a/testing/lisp/test-ob.el
+++ b/testing/lisp/test-ob.el
@@ -985,7 +985,27 @@ x
 "
             (goto-char (point-min))
             (search-forward "begin_src")
-            (org-babel-expand-noweb-references nil nil :eval)))))
+            (org-babel-expand-noweb-references nil nil :eval))))
+  ;; Test interposition of Noweb prefix under :comments noweb.
+  (should
+   (org-test-with-temp-text-in-file
+ "* H
+#+name: inner
+#+begin_src emacs-lisp
+1
+#+end_src
+
+#+header: :comments noweb :noweb yes
+#+begin_src emacs-lisp<point>
+prefix<<inner>>
+#+end_src"
+ (let ((file (file-name-nondirectory (buffer-file-name))))
+   (equal
+    (format "prefix;; [[file:%s::inner][inner]]
+prefix1
+prefix;; inner ends here"
+            file file)
+    (org-babel-expand-noweb-references nil nil :eval))))))
 
 (ert-deftest test-ob/splitting-variable-lists-in-references ()
   (org-test-with-temp-text ""
-- 
2.39.5 (Apple Git-154)

