Search code examples
emacsorg-modeorg-babel

Passing org-mode properties to source code block via org-sbe


I could not figure out how to pass the property RID to a source code block in a different scope, e.g. it fails to evaluate (org-entry-get nil "RID") before it is passed to the function addSomething. It does work when using #+CALL:, but the same syntax is not working in a SRC block (see last example below).

#+NAME: addSomething
#+BEGIN_SRC sh :results value :var x="no"
echo "something: $x"
#+END_SRC

* Heading 1
:PROPERTIES:
:RID:      h1_property
:END:

This works.
#+BEGIN_SRC sh :var y=(org-sbe addSomething (x  "1"))
echo $y
#+END_SRC

#+RESULTS:
: something: 1


This works too:
#+BEGIN_SRC sh :var y=(org-entry-get nil "RID")
echo $y
#+END_SRC

#+RESULTS:
: h1_property

Error: Reference 'RID' not found in this buffer
#+BEGIN_SRC sh :var y=(org-sbe addSomething (org-entry-get nil "RID"))
echo $y
#+END_SRC


Error: Reference 'just a string' not found in this buffer. 
#+BEGIN_SRC sh :var y=(org-sbe addSomething (x  "a string"))
echo $y
#+END_SRC

Why? Passing "1" worked.

Error: Symbol's variable is void: RID
#+BEGIN_SRC sh :var y=(org-sbe addSomething (x (org-entry-get nil "RID")))
echo $y
#+END_SRC

Seems ~(org-entry-get nil "RID")~ is evaluated outside of the current scope.

It works using CALL.
#+CALL: addSomething(x=(org-entry-get nil "RID")) :results value

#+RESULTS:
: something: h1_property

Try the same for `:var`:
#+BEGIN_SRC sh :var y=addSomething(x=(org-entry-get nil "RID"))
echo $y
#+END_SRC

#+RESULTS:
: something:


Solution

  • For the string case, try this:

    #+BEGIN_SRC sh :var y=(org-sbe addSomething (x  $"a string"))
    echo $y
    #+END_SRC
    
    #+RESULTS:
    : something: a string
    

    For the RID case, try this:

    #+BEGIN_SRC sh :var y=(org-sbe addSomething (x (org-entry-get nil \"RID\")))
    echo $y
    #+END_SRC
    
    #+RESULTS:
    : something: h1_property
    

    You can add source blocks to calculate whatever elements you want and then use org-sbe to pass the results to other source blocks; e.g.

    #+name: rid
    #+BEGIN_SRC sh :var y=(org-entry-get nil "RID")
    echo $y
    #+END_SRC
    
    #+BEGIN_SRC sh :var y=(org-sbe addSomething (x (org-sbe rid)))
    echo $y
    #+END_SRC
    
    #+RESULTS:
    : something: h1_property
    

    and similarly

    #+name: string
    #+BEGIN_SRC sh :var y="a string"
    echo $y
    #+END_SRC
    
    #+RESULTS: string
    : a string
    
    #+BEGIN_SRC sh :var y=(org-sbe addSomething (x (org-sbe string)))
    echo $y
    #+END_SRC
    
    #+RESULTS:
    : something: a string
    

    And here's the second example with the arguments passed inline (again using the "rid" source block defined above):

    #+BEGIN_SRC sh :var y=addSomething((org-sbe rid)))
    echo $y
    #+END_SRC
    
    #+RESULTS:
    : something: h1_property
    

    I realize that this is neither a complete nor a satisfactory answer, but I have not had the time or patience to figure out even a small subset (let alone the complete set) of the rules. A good answer would form the core of a very nice blog post that I, for one, would very much look forward to reading (hint, hint...)