Browse Source

ob: Improve handling of :wrap header

* lisp/ob-core.el (org-babel-insert-result): Improve handling of :wrap
header.
* testing/lisp/test-ob.el (test-ob/inline-src_blk-wrap): New test.
(test-ob/preserve-comma-escape): Add test.
Nicolas Goaziou 1 month ago
parent
commit
06fe9d6b05
2 changed files with 117 additions and 6 deletions
  1. 50 5
      lisp/ob-core.el
  2. 67 1
      testing/lisp/test-ob.el

+ 50 - 5
lisp/ob-core.el

@@ -2373,13 +2373,58 @@ INFO may provide the values of these header arguments (in the
 			     (org-babel-chomp result "\n"))))
 		   (t (goto-char beg) (insert result)))
 		  (setq end (copy-marker (point) t))
-		  ;; possibly wrap result
+		  ;; Possibly wrap result.
 		  (cond
 		   ((assq :wrap (nth 2 info))
-		    (let ((name (or (cdr (assq :wrap (nth 2 info))) "results")))
-		      (funcall wrap (concat "#+begin_" name)
-			       (concat "#+end_" (car (split-string name)))
-			       nil nil (concat "{{{results(@@" name ":") "@@)}}}")))
+		    (let* ((full (or (cdr (assq :wrap (nth 2 info))) "results"))
+			   (split (split-string full))
+			   (type (car split))
+			   (opening-line (concat "#+begin_" full))
+			   (closing-line (concat "#+end_" type)))
+		      (cond
+		       ;; Escape contents from "export" wrap.  Wrap
+		       ;; inline results within an export snippet with
+		       ;; appropriate value.
+		       ((eq t (compare-strings type nil nil "export" nil nil t))
+			(let ((backend (pcase split
+					 (`(,_) "none")
+					 (`(,_ ,b . ,_) b))))
+			  (funcall wrap
+				   opening-line closing-line
+				   nil nil
+				   (format "{{{results(@@%s:"
+					   backend) "@@)}}}")))
+		       ;; Escape contents from "example" wrap.  Mark
+		       ;; inline results as verbatim.
+		       ((eq t (compare-strings type nil nil "example" nil nil t))
+			(funcall wrap
+				 opening-line closing-line
+				 nil nil
+				 "{{{results(=" "=)}}}"))
+		       ;; Escape contents from "src" wrap.  Mark
+		       ;; inline results as inline source code.
+		       ((eq t (compare-strings type nil nil "src" nil nil t))
+			(let ((inline-open
+			       (pcase split
+				 (`(,_)
+				  "{{{results(src_none{")
+				 (`(,_ ,language)
+				  (format "{{{results(src_%s{" language))
+				 (`(,_ ,language . ,rest)
+				  (let ((r (mapconcat #'identity rest " ")))
+				    (format "{{{results(src_%s[%s]{"
+					    language r))))))
+			  (funcall wrap
+				   opening-line closing-line
+				   nil nil
+				   inline-open "})}}}")))
+		       ;; Do not escape contents in non-verbatim
+		       ;; blocks.  Return plain inline results.
+		       (t
+			(funcall wrap
+				 opening-line closing-line
+				 t nil
+				 "{{{results(" ")}}}")))))
 		   ((member "html" result-params)
 		    (funcall wrap "#+begin_export html" "#+end_export" nil nil
 			     "{{{results(@@html:" "@@)}}}"))

+ 67 - 1
testing/lisp/test-ob.el

@@ -465,6 +465,47 @@ at the beginning of a line."
 		       (buffer-substring-no-properties
 			(point-min) (point-max)))))))
 
+(ert-deftest test-ob/inline-src_blk-wrap ()
+  (let ((org-babel-inline-result-wrap "=%s="))
+    ;; Export: use export snippet.
+    (should
+     (string-match-p
+      "@@foo:1@@"
+      (org-test-with-temp-text "src_emacs-lisp[:wrap export foo]{1}"
+	(org-babel-execute-maybe)
+	(buffer-string))))
+    (should
+     (string-match-p
+      "src_foo{1}"
+      (org-test-with-temp-text "src_emacs-lisp[:wrap src foo]{1}"
+	(org-babel-execute-maybe)
+	(buffer-string))))
+    (should
+     (string-match-p
+      "src_foo\\[parameter\\]{1}"
+      (org-test-with-temp-text "src_emacs-lisp[:wrap src foo parameter]{1}"
+	(org-babel-execute-maybe)
+	(buffer-string))))
+    (should
+     (string-match-p
+      "=1="
+      (org-test-with-temp-text "src_emacs-lisp[:wrap example]{1}"
+	(org-babel-execute-maybe)
+	(buffer-string))))
+    ;; Anything else is ignored.
+    (should
+     (string-match-p
+      "{{{results(1)}}}"
+      (org-test-with-temp-text "src_emacs-lisp[:wrap foo]{1}"
+	(org-babel-execute-maybe)
+	(buffer-string))))
+    (should
+     (string-match-p
+      "{{{results(a\\\\,b)}}}"
+      (org-test-with-temp-text "src_emacs-lisp[:wrap foo]{\"a,b\"}"
+	(org-babel-execute-maybe)
+	(buffer-string))))))
+
 (ert-deftest test-ob/combining-scalar-and-raw-result-types ()
   (org-test-with-temp-text-in-file "
 
@@ -1603,7 +1644,32 @@ line 1
       (org-babel-execute-src-block)
       (let ((case-fold-search t)) (search-forward "result" nil t))
       (downcase (buffer-substring-no-properties (line-beginning-position 2)
-						(point-max)))))))
+						(point-max))))))
+  (should
+   (string-match-p
+    ",#"
+    (org-test-with-temp-text "#+begin_src emacs-lisp :wrap export foo
+\"#+keyword: value\"
+#+end_src"
+      (org-babel-execute-src-block)
+      (buffer-string))))
+  (should
+   (string-match-p
+    ",#"
+    (org-test-with-temp-text "#+begin_src emacs-lisp :wrap src foo
+\"#+keyword: value\"
+#+end_src"
+      (org-babel-execute-src-block)
+      (buffer-string))))
+  ;; Do not comma-escape when the block is not verbatim.
+  (should-not
+   (string-match-p
+    ",#"
+    (org-test-with-temp-text "#+begin_src emacs-lisp :wrap special
+\"#+keyword: value\"
+#+end_src"
+      (org-babel-execute-src-block)
+      (buffer-string)))))
 
 (ert-deftest test-ob/safe-header-args ()
   "Detect safe and unsafe header args."