From 63029af82f2b40a916ad3a437e16452eb031141e Mon Sep 17 00:00:00 2001 From: Sergiu Ivanov Date: Mon, 20 Jul 2020 23:57:16 +0200 Subject: [PATCH] example: Add Passing values between code blocks. --- example/example.org | 83 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/example/example.org b/example/example.org index d93bae2..8c3c4a7 100644 --- a/example/example.org +++ b/example/example.org @@ -177,6 +177,89 @@ raco pkg install | b | "(not b)" | :END: +** Passing values between code blocks + The =:var= header argument allows using the output of a code block + as an input of another one. For example: + #+NAME: block-1 + #+BEGIN_SRC racket :results output drawer +'(4 2) + #+END_SRC + + #+RESULTS: block-1 + :RESULTS: + '(4 2) + :END: + + Here's how you use its output: + #+NAME: block-2 + #+BEGIN_SRC racket :results output drawer :var input=block-1() +input + #+END_SRC + + #+RESULTS: + :RESULTS: + "'(4 2)\n" + :END: + + The parentheses when calling =block-1= in the header of the second + code block are optional. + + There are a two main problems with what we see in the second code + block: there is a trailing newline and a leading quote. The + trailing newline is not hard to drop, but the leading quote is + trickier: + #+BEGIN_SRC racket :results output drawer :var input=block-1() +(unorg input) + #+END_SRC + + #+RESULTS: + :RESULTS: + ''(4 2) + :END: + + I had much trouble understanding how to get rid of the second + quote, I even thought it was impossible. To understand the + solution, replace ='= with =quote=: =''(4 2)= becomes =(quote + (quote (4 2)))=. Keeping in mind that =(quote (4 2))= is the + same thing as ='(4 2)=, this expression effectively defines a list + whose first element is =quote= and whose second element is =(4 + 2)=. Therefore, to get ='(4 2)= out of =''(4 2)=, I need to simply + get the /second/ element out of the list with double quote: + #+BEGIN_SRC racket :results output drawer :var input=block-1() +(cadr (unorg input)) + #+END_SRC + + #+RESULTS: + :RESULTS: + '(4 2) + :END: + + There's a simpler way to avoid having to deal with the double quote + altogether: use =value= instead of =output= in =:results=. + #+NAME: block-1-value + #+BEGIN_SRC racket :results value drawer +'(4 2) + #+END_SRC + + #+BEGIN_SRC racket :results output drawer :var input=block-1-value +(unorg input) + #+END_SRC + + #+RESULTS: + :RESULTS: + '(4 2) + :END: + + The only way to pass values between Org-babel code blocks is by + writing them to strings. I have looked around for passing the + values natively, but it doesn't seem possible, and it actually + makes sense: code blocks may be written in different languages, and + the most natural way to pass values between them is by serialising + to strings. + + A good option for passing around native values is by using Noweb + references. It does require adapting both code blocks however. + ** Reading Org-mode tables<> Org-mode allows supplying tables as arguments for code blocks.