Hi Rudy,

> (default-start "@startuml")
>     (default-end "@enduml")

shouldn't this stay as it is, because this is what we wrap around the body 
manually if no matching @start... @end... items are found in the text. So the 
defaults I wouldn't generalize.

> (start-regex "^[[:blank:]]*@start\\([a-zA-Z]+\\)[[:blank:]]*$")
>     (start-match-pos (string-match start-regex body))
>     (start-match-end (when start-match-pos (match-end 0)))
>     (start-type (when start-match-pos                       (progn 
> (string-match start-regex body start-match-pos)
>                          (match-string 1 body))))
>     (end-regex (when start-type (format 
> "^[[:blank:]]*@end%s\\(?:[[:blank:]]*$\\)" start-type)))
>     (end-match-pos (when end-regex
>                      (string-match end-regex body start-match-end)))
>     (end-match-end (when end-match-pos (match-end 0)))

Here I am searching for the @start<XXX> blocks.
It will also match e.g. (where _ represents spaces or tabs):
@start<XXX>__

It will filter out the start-type (the XXX part) and then use this start-type 
to get the exactly matching end-type (@end<XXX>) ... so @end<ZZZ> would e.g. 
not match.

We now use the positions of these start/end items to grab whatever is BEFORE 
the @start<XXX> which I called in my code prologue, but it is not the prologue 
that comes from header arguments... it could be e.g. when someone writes a 
comment before @start<XXX>. It will also extract the body in between and the 
epilogue (again this is not the epilogue that comes from the header 
arguments... it is just "stuff/text" that someone might have written after the 
@end<XXX> block).

I can through out/remove the pro and epi parts as we probably don't need them, 
I just thought you wanted them in there which seems to have been a 
misunderstanding.

Then the extracted body in between the @start<XXX> and @end<XXX> lines (or the 
whole body if no matching @start/@end are found) is sent / expanded by 
org-babel-expand-body:generic as it should.

In the end we then simply put the single elements back together into the final 
complete body... here I am just removing empty list items before joining them 
so no unnecessary newlines are created if e.g. the expanded-body is empty.

So my code is not doing anything that is and rightfully should be done by 
org-babel-expand-body:generic.

If we remove the pro and epi stuff then the code would get a bit tighter.
And you are correct, I should also rename wrapped-body to unwrapped-body.

> (if wrapped-body
> (string-join (remove "" (list pro
> start
> expanded-body
> end
> epi))
> "\n")
> (string-join (remove "" (list default-start
> expanded-body
> default-end))
> "\n"))))

So I really think I generalized the finding of the start-type and use that 
correctly to find a matching end type.

Best
Tim

On 29 Sep 2025, at 22:19, Rudolf Adamkovič wrote:

> Tim Hansinger [email protected] writes:
>
>>> Hello Rudy,
>>>
>>> here's the new patch. I tried to add all your suggestions and
>>> advanced handling of prologue/epilogue to it.
>
> Howdy, howdy Tim!
>
> I am a bit confused, TBH.
>
> Prologue/epilogue, handled by the `org-babel-expand-body:generic'
> function, are header arguments, right? They are not parts of the
> body, nor something to be matched with regexps.
>
> Let us consider again, the starting point, now with inline TODOs:
>
> (defun org-babel-plantuml-make-body (body params)
> "[...]"
> (let* ((default-start "@startuml") ;; TODO generalize to @startXXX
> (default-end "@enduml") ;; TODO generalize to @endXXX
> (wrapped-body ;; TODO rename to unwrapped-body :)
> (and (string-match (rx (literal default-start)
> ;; TODO Anchor and ignore whitespace.
> (group (zero-or-more anything))
> (literal default-end))
> body)
> (match-string 1 body)))
> (expanded-body
> (org-babel-expand-body:generic
> (or wrapped-body body)
> params
> (org-babel-variable-assignments:plantuml params))))
> (if wrapped-body
> (string-join (list default-start
> expanded-body
> default-end)
> "\n")
> expanded-body)))
>
> Is this not all we need, if TODOs were fixed?
>
> If it is, then we should not overcomplicate the code with the many
> when' and setq' and all that. We need is (1) one string-match' to unwrap the 
> body if needed (2) one call to babel to expand the body, and (3) one 
> string-join' to re-wrap the body if needed.
>
> Note again how, compared to your original patch, this code always runs
> the body through `org-babel-expand-body:generic' that handles prologue
> and epilogue and who-knows-what in the future. We want to do that for
> robustness.
>
> Rudy
>
> "'Obvious' is all too often a synonym for 'wrong'."
> --- Jeff Erickson, Algorithms, 2019
>
> Rudolf Adamkovič [email protected] [he/him]
> http://adamkovic.org

Reply via email to