2

Is it possible to use the result of one source code block not within another code block but actually within another source blocks header argument? I know this piece of functionality works

#+name: block-1
#+BEGIN_SRC emacs-lisp
(current-time-string)
#+END_SRC

#+BEGIN_SRC emacs-lisp :var input=block-1
(format "We got %S in block-1" input)
#+END_SRC

but what I want is something like this, i.e. to reuse the result to e.g. form a path for the dir header argument

#+name: block-1
#+BEGIN_SRC emacs-lisp
(current-time-string)
#+END_SRC

#+BEGIN_SRC emacs-lisp :var input=block-1 :dir path/input
(format "We got %S in block-1" input)
#+END_SRC

so what I want to achieve is to have a variable path for the :dir header argument.

maybe there is a way to concatenate the argument to :dir in a dynamic way depending on what the first source block resulted in?

3 Answers 3

2

Looks like it might be possible to achieve it by creating a helper lisp function:

#+name: block-1
#+BEGIN_SRC sh
  echo '/bin'
#+END_SRC

#+RESULTS: block-1
: /bin

#+begin_src emacs-lisp :results silent
  (defun result1 ()
    (save-excursion
      (org-babel-goto-named-result "block-1")
      (setq value (org-babel-read-result))
      )
    (print value)
    )
#+end_src

#+BEGIN_SRC sh :dir (result1) :results scalar
  pwd
#+END_SRC

#+RESULTS:
: /bin

In second code block we define a function result1 which prints contents of block-1 result (those with better lisp knowledge can make this function accept an argument), and in last code block we use output of this function as current directory (:dir (result1)). Apparently, it's a documented feature.

2

Use org-sbe in :dir header to fetch the result from a named block.

Tip: Create dirB directory in same directory as the org-mode example file otherwise the pwd command will throw an error.

#+NAME: block-a
#+BEGIN_SRC elisp 
(format "%sdirB" (file-name-directory (buffer-file-name)))
#+END_SRC

#+RESULTS: block-a
: /tmp/sx/org-mode/dirB

#+NAME: block-b
#+BEGIN_SRC bash :dir (org-sbe block-a)
  pwd
#+END_SRC 

#+RESULTS: block-b
: /tmp/sx/org-mode/dirB


This answer was tested using:
emacs version: GNU Emacs 25.2.1 (x86_64-unknown-cygwin, GTK+ Version 3.22.10) org-mode version: 9.1.2

7
  • 3
    As two of the answers here point out, you can give a value to e.g. :dir by evaluating a lisp form. As this answer points out, org-sbe can be used to get the result of another source block (as a string). But you cannot write :dir foo/(org-sbe "something") trying to interpolate the result of a lisp call in a string: you have to do something like this instead: :dir (concat "foo/" (org-sbe "something")).
    – NickD
    Apr 15, 2020 at 1:58
  • thanks a lot guys for the help. I stuck with the sbe option. The background is, that I want to assemble a path to attach to docker container dynamically via docker-tramp github.com/emacs-pe/docker-tramp.el by generating container names in a shell script during execution
    – CD86
    Apr 15, 2020 at 7:46
  • 1
    in the sbe case, is the first code block automatically run when the second one is executed?
    – CD86
    Apr 15, 2020 at 10:06
  • @CD86 - Correct, the first block is executed automatically when the second block is executed because the headers on the second block are evaluated before the code in the second block is evaluated. The org-sbe macro can be very useful to fetch results from code blocks.
    – Melioratus
    Apr 15, 2020 at 14:30
  • @CD86 - I use org-mode for Literate DevOps everyday and have been looking for a way to add docker in my CI/CD pipelines. I hope you’ll write up a tutorial and/or add your answer when you get this working.
    – Melioratus
    Apr 15, 2020 at 14:36
1

You can use org-babel-execute:org from that answer. Just put it in your init file. I think a (require 'cl-lib) in front of it should make the code run in your init file.

Therewith executing an org source block will duplicate it with the header variables replaced by their values.

See the following example:

Before Execution:

#+NAME: block-1
#+BEGIN_SRC emacs-lisp 
"2020-04-14"
#+END_SRC

#+BEGIN_SRC org :var mydir=block-1 :noweb yes :results raw
,#+BEGIN_SRC emacs-lisp :dir mydir
default-directory
,#+END_SRC
#+END_SRC

After Execution With C-c C-v b:

#+NAME: block-1
#+BEGIN_SRC emacs-lisp 
"2020-04-14"
#+END_SRC

#+RESULTS: block-1
: 2020-04-14

#+BEGIN_SRC org :var mydir=block-1 :noweb yes :results raw
,#+BEGIN_SRC emacs-lisp :dir mydir
default-directory
,#+END_SRC
#+END_SRC

#+RESULTS:
#+BEGIN_SRC emacs-lisp :dir 2020-04-14
default-directory
#+END_SRC

#+RESULTS:
: /home/Tobias/Work/2020-04-14/
1
  • this doesnt work for me for some reason. let alone, that the escaping of source code block is maeh...
    – CD86
    Apr 15, 2020 at 15:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.