Skip to main content
3 of 7
improve problem description

Set org-babel source block parameters dynamically

I am trying to set the default header parameters for org source blocks in plantuml-mode.

My goal is to generate the result file in the org attachment directory with a generic name by default, and display it as an inline image in the result drawer.

This is my first attempt:

(setq org-babel-default-header-args:plantuml
         `((:results . "file link") (:output-dir . ,(org-attach-dir-get-create)) (:file-ext . "png") (:file . "diagram.png") (:exports . "results")))

This works fine the first time, but then, the org-attach-dir string is prepended to the file path string at every code block execution.

So for example, if org-attach-dir-get-create returns "mydir/", the first time I execute the block, the :file value is "mydir/diagram.png". The second time I execute the block, I get "mydir/mydir/diagram.png", the third time, "mydir/mydir/mydir/diagram.png", and so on.

Please note that I am keeping file-ext, file, and output-dir as separated parameters in the hope of being able to override them individually if needed in specific cases.

I understood from that failure that the header-defaults are set at each block execution, so I tried to pass them all as a function:

(defun my/org-babel-plantuml-header-args ()
  "Set dynamic header arguments for PlantUML source blocks."
  (let ((output-dir (org-attach-dir-get-create)))
    `((:results . "file link")
      (:output-dir . ,output-dir)
      (:file-ext . "png")
      (:file . "diagram.png")
      (:exports . "results"))))

  (setq org-babel-default-header-args:plantuml
         (my/org-babel-plantuml-header-args))

This has exactly the same outcome. It does not make sense to me, but my tests are very stubborn at proving me wrong.

I would appreciate some help in gettng it to work, because I used some of my most advanced Elisp tricks for that one :)