5

noweb expantion is a very nice tool but it generally allows one to refer to other src-code blocks:

#+NAME: hellomessage
#+BEGIN_SRC emacs-lisp
"hello"
#+END_SRC

#+BEGIN_SRC emacs-lisp :noweb yes 
(message <<hellomessage>>)
#+END_SRC

works perfectly. But it is reasonable to want to do template expansion with properties. I would like something like this to work:

#+PROPERTY: hellomessage hello

#+BEGIN_SRC emacs-lisp :noweb yes 
(message "<<hellomessage>>")
#+END_SRC

or

* Example
  :PROPERTIES:
  :hellomessage: hello
  :END:

#+BEGIN_SRC emacs-lisp :noweb yes 
(message "<<hellomessage>>")
#+END_SRC

but it doesn't since noweb seems only to expand named source blocks. Is there any way to do this?

I have thought of using header arguments with the var keyword but that seems somewhat artificial since the property then is "specific" to src blocks. I would like to avoid this since I would also want to use the property in the normal org-mode way.

Similarly to what Ixemad suggested I tried doing this

* Example
  :PROPERTIES:
  :hellomessage: hello
  :END:

  #+NAME: get_property
  #+BEGIN_SRC elisp :var prop=""
    (org-entry-get nil prop t)
  #+END_SRC
  #+RESULTS: get_property

  #+BEGIN_SRC emacs-lisp :noweb yes
    (message "<<get_property("hellomessage")>>")
  #+END_SRC

  #+RESULTS:
  : hello1

but the problem is that the org-entry-get gets evaluated where the get_property code block is defined, not where it is called as seen by the following example

* Example1
  :PROPERTIES:
  :hellomessage: hello1
  :END:

  #+NAME: get_property
  #+BEGIN_SRC elisp :var prop=""
    (org-entry-get nil prop t)
  #+END_SRC
  #+RESULTS: get_property

  #+BEGIN_SRC emacs-lisp :noweb yes
    (message "<<get_property("hellomessage")>>")
  #+END_SRC

  #+RESULTS:
  : hello1

* Example2
  :PROPERTIES:
  :hellomessage: hello2
  :END:
  #+BEGIN_SRC emacs-lisp :noweb yes
    (message "<<get_property("hellomessage")>>")
  #+END_SRC

  #+RESULTS:
  : hello1

The second result should have been hello2.

2 Answers 2

6

I'm not entirely sure I understand the constraints/requirements you're interested in (e.g. must a solution involve noweb evaluation), but one aspect of this question is similar to a problem I wrestled with recently: block calls and their location. The best solution I could find made use of org-babel-current-src-block-location.

Here are some examples; one uses Elisp only and the other uses noweb block evaluation and org-babel-current-src-block-location. Both appear to solve the block-location problem, if I'm understanding it correctly.

  * Example
    :PROPERTIES:
    :hellomessage: hello
    :END:

    #+NAME: get_property
    #+BEGIN_SRC emacs-lisp :var prop_name="" :results silent
    (org-with-point-at org-babel-current-src-block-location
      (org-entry-get nil prop_name t))
    #+END_SRC

    #+HEADER: :var prop_message=(org-entry-get nil "hellomessage" t)
    #+BEGIN_SRC emacs-lisp
      (message prop_message)
    #+END_SRC

    #+RESULTS:
    : hello

    #+BEGIN_SRC emacs-lisp :noweb yes
      (message "<<get_property("hellomessage")>>")
    #+END_SRC

    #+RESULTS:
    : hello

  * Example2
    :PROPERTIES:
    :hellomessage: hello2
    :END:


    #+HEADER: :var prop_message=(org-entry-get nil "hellomessage" t)
    #+BEGIN_SRC emacs-lisp
      (message prop_message)
    #+END_SRC

    #+RESULTS:
    : hello2

    #+BEGIN_SRC emacs-lisp :noweb yes
      (message "<<get_property("hellomessage")>>")
    #+END_SRC

    #+RESULTS:
    : hello2
1

From the Noweb reference syntax, you can evaluate code block before expansion.

* Example
  :PROPERTIES:
  :hellomessage: hello
  :END:

  #+NAME: get_property
  #+BEGIN_SRC elisp :var prop=""
    (org-entry-get nil prop t)
  #+END_SRC
  #+RESULTS: get_property

  #+BEGIN_SRC emacs-lisp :noweb
    (message "<<get_property("hellomessage")>>")
  #+END_SRC
1
  • I tried and this doesn't work. First of all to make it work I need to change it :noweb to :noweb yes. But most importantly the above code gets the property in the entry where get_property is defined, not where it is called. I will add the clarifying example in my question.
    – GenaU
    Commented Jun 10, 2018 at 3:55

Your Answer

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

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