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

Reply via email to