branch: externals/org
commit ba8e112ccfe16be69472f788a577b8ca5575f3d6
Author: Tim Hansinger <[email protected]>
Commit: Ihor Radchenko <[email protected]>

    ob-plantuml.el: Fix body parsing to handle @start/@end keywords
    
    * lisp/ob-plantuml.el (org-babel-plantuml-make-body):
    Refactor `org-babel-plantuml-make-body' to properly parse and preserve
    content around PlantUML diagram blocks.
    
    Previously, the function would apply variable expansion to the entire
    body content and only check for @start keyword to decide whether to
    wrap with @startuml/@enduml tags.
    
    Changes:
    - Parse body into 4 components: pre-body, keyword-type (e.g., uml),
      inner-body, and post-body.
    - Only apply variable expansion to the inner-body, not the entire
      body.
    - Require exact matching between @start<type> and @end<type>
      keywords (e.g., @startuml must pair with @enduml, not @endsalt).
    - If @start<type> exists but no matching @end<type> is found, treat
      the entire body as diagram content and wrap with default
      keywords (@startuml ... @enduml).
    - Preserve any content before the first @start keyword (pre-body) and
      after the last @end keyword (post-body) without modification
      (except trimming).
    
    This ensures variable substitution only affects the actual diagram
    content.
    
    Examples now supported:
    - Content before/after diagram blocks
    - Proper handling of mismatched start/end keyword pairs
    
    * testing/lisp/test-ob-plantuml.el
    
(test-ob-plantuml/single-var-on-body-with-start-end-keywords-and-content-outside-the-keywords):
    Added an additional test for aboves use case (var definition on a BODY
    with pre-existing @startxxx ... @endxxx keywords and pre-body /
    post-body content).
    
    Reported-by: "Tim Hansinger" <[email protected]>
    Link: 
https://list.orgmode.org/[email protected]/
    
    TINYCHANGE
---
 lisp/ob-plantuml.el              | 50 ++++++++++++++++++++++++++++++++++------
 testing/lisp/test-ob-plantuml.el | 30 ++++++++++++++++++++++++
 2 files changed, 73 insertions(+), 7 deletions(-)

diff --git a/lisp/ob-plantuml.el b/lisp/ob-plantuml.el
index d1b6b138c1..3cc2ab0b80 100644
--- a/lisp/ob-plantuml.el
+++ b/lisp/ob-plantuml.el
@@ -102,13 +102,49 @@ of source block parameters.  This function relies on the
 from PARAMS and on the `org-babel-variable-assignments:plantuml'
 function to convert variables to PlantUML assignments.
 
-If BODY does not contain @startXXX ... @endXXX clauses, @startuml
-... @enduml will be added."
-  (let ((full-body
-        (org-babel-expand-body:generic
-         body params (org-babel-variable-assignments:plantuml params))))
-    (if (string-prefix-p "@start" body t) full-body
-      (format "@startuml\n%s\n@enduml" full-body))))
+The function parses BODY to find matching @startXXX ... @endXXX
+keyword pairs:
+- If a matching pair is found (e.g., @startuml/@enduml or
+  @startsalt/@endsalt), variable expansion is applied only to the
+  content between the keywords, preserving any content outside the
+  keywords.
+- If @startXXX is found but no matching @endXXX, or if no @startXXX is
+  found, the entire BODY is treated as diagram content and wrapped
+  with @startuml ... @enduml keywords after variable expansion."
+  (let* ((regex (rx
+                 (group (zero-or-more anything))
+                 line-start
+                 (zero-or-more blank)
+                 "@start"
+                 (group (one-or-more (not whitespace)))
+                 (zero-or-more blank)
+                 line-end
+                 (zero-or-one whitespace)
+                 (group (zero-or-more anychar))
+                 line-start
+                 (zero-or-more blank)
+                 "@end"
+                 (backref 2)
+                 (zero-or-more blank)
+                 line-end
+                 (group (zero-or-more anything))))
+         (_ (string-match regex body))
+         (pre-body (string-trim (or (match-string 1 body) "")))
+         (keyword-type (or (match-string 2 body) "uml"))
+         (inner-body (string-trim (or (match-string 3 body) body)))
+         (post-body (string-trim (or (match-string 4 body) ""))))
+
+    (string-join
+     (remove ""
+             (list pre-body
+                   (string-join (list "@start" keyword-type))
+                   (org-babel-expand-body:generic
+                    inner-body
+                    params
+                    (org-babel-variable-assignments:plantuml params))
+                   (string-join (list "@end" keyword-type))
+                   post-body))
+     "\n")))
 
 (defun org-babel-execute:plantuml (body params)
   "Execute a block of plantuml code with org-babel.
diff --git a/testing/lisp/test-ob-plantuml.el b/testing/lisp/test-ob-plantuml.el
index 3ab5b918f4..851fc20af9 100644
--- a/testing/lisp/test-ob-plantuml.el
+++ b/testing/lisp/test-ob-plantuml.el
@@ -49,6 +49,36 @@ class CLASSNAME
           (car src-block-info)
           (car (cdr src-block-info)))))))))
 
+(ert-deftest 
test-ob-plantuml/single-var-on-body-with-start-end-keywords-and-content-outside-the-keywords
 ()
+  "Test file output with input variable on BODY with @startXXX ... @endXXX 
keywords
+and pre-body / post-body content."
+  (should
+   (string=
+    "pre-body content
+@startuml
+!define CLASSNAME test_class
+class CLASSNAME
+@enduml
+post-body content"
+    (let ((org-plantuml-jar-path nil))
+      (org-test-with-temp-text
+       "#+name: variable_value
+: test_class
+
+#+header: :file tmp.puml
+#+header: :var CLASSNAME=variable_value
+#+begin_src plantuml
+pre-body content
+@startuml
+class CLASSNAME
+@enduml
+post-body content
+#+end_src"
+       (org-babel-next-src-block)
+       (let ((src-block-info (cdr (org-babel-get-src-block-info))))
+        (org-babel-plantuml-make-body
+         (car src-block-info)
+         (car (cdr src-block-info)))))))))
 
 (ert-deftest test-ob-plantuml/prologue ()
   "Test file output with prologue."

Reply via email to