Hello,
this is my first email to this mailing list so please don't be too hard on me.
I am looking for guidance/proposals to the code fix I provide here. If it is
acceptable however I would suggest to implement it.
Problem description
Currently variables are not working if @start... and @end... lines are defined
in a code block.
Examples
Working example
This works perfectly (meaning replace_me will be replaced in the image output
by the text this is variable content):
#+begin_src plantuml :var replace_me="this is variable content"
"replace_me"
#+end_src
Here's how the temporary plantuml output file looks like (which will then be
converted to an image):
@startuml
!define replace_me this is variable content
"replace_me"
@enduml
Non-working example
This example does not work (in the image output the text will be replace_me):
#+begin_src plantuml :var replace_me="this is variable content"
@startuml
"replace_me"
@enduml
#+end_src
Here's how the temporary plantuml output file looks like (which will then be
converted to an image):
@startuml
!define replace_me this is variable content
\@startuml
"replace_me"
@enduml
@enduml
Possible Fix (this is what I use currently)
I changed the function org-babel-plantuml-make-body inside ob-plantuml.el
from this (I removed the function comment/documentation in belows code example):
(defun org-babel-plantuml-make-body (body params)
(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))))
to this:
(defun org-babel-plantuml-make-body (body params)
(let ((assignments (org-babel-variable-assignments:plantuml params)))
(if
(or (string-prefix-p "@start" body t)
(string-prefix-p "\\@start" body t))
(if assignments
(let*
((lines (split-string body "\n")) (first-line (car lines))
(rest-lines (cdr lines))
(assignment-lines (mapconcat 'identity assignments "\n"))
(clean-first-line
(replace-regexp-in-string "\\\\@" "@" first-line)))
(concat clean-first-line "\n" assignment-lines
(when rest-lines
(concat "\n" (mapconcat 'identity rest-lines "\n")))))
body)
(let ((full-body (org-babel-expand-body:generic body params assignments)))
(format "@startuml\n%s\n@enduml" full-body)))))
Output with the fix applied
When I now check the output of aboves non-working example I get this.
@startuml
!define replace_me this is variable content
"replace_me"
@enduml
Why this is important
There are many more language specifications other than @startuml that can be
used in plantuml (e.g. @startsalt etc.). Therefore at the moment it is not
possible to use variables with these.
Here's an example using @startsalt that currently (without the fix) also
doesn't work:
#+begin_src plantuml :var replace_me="this is variable content"
@startsalt
{
replace_me
}
@endsalt
#+end_src
Best
Tim