Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does #+BIND: really works

Tags:

emacs

org-mode

I am completely confused with the #+BIND: mechanism in org-mode (9.0.3).

I need to fix some settings which do not have specific keywords and I want my org file to be portable (do not want to impose change to people's emacs init file I will send it).

I thus change the org-export-allow-bind-keywords with file local variables and try to fix the needed emacs variable through the #+BIND: mechanism.

It seems that the specified variables are not binded at all.

In order to understand if the binding is done or not, I tried to print the content of the variable during export with the following example :

#+BIND: myvar " middle "

#+BEGIN_SRC emacs-lisp :results value :exports results
(concat "before" myvar "after")
#+END_SRC

# Local Variables:
# org-export-allow-bind-keywords: t
# End:

Of course before opening the file I fixed an initial value to myvar in my emacs init file through (setq myvar " empty ").

When exporting I do not get the expected value, before middle after, but the following one: before empty after.

Any idea what I missed?

like image 652
Bruno BEAUFILS Avatar asked Jan 31 '17 18:01

Bruno BEAUFILS


1 Answers

This is not meant as a complete answer: there are subtleties with #+BIND. But the basic reason why the above example does not work is that the evaluation of the source block is done way before the #+BIND construct is even used during export. Look in function org-export-as (in file lisp/ox.el): in line 3061, the function org-babel-exp-process-buffer is called to process the source block; the #+BIND construct is used in org-export-get-environment, at line 3078 - that is after the source block has been processed. (The line numbers are from my version, 9.0.3+, so they should be close but probably not the same for recent versions of org).

The #+BIND construct was never meant as a mechanism to bind arbitrary variables during export: there were some in-buffer settings that affected export and some settings that could not be set in-buffer, but people wanted to tweak those per-file, instead of having to set them globally (and then perhaps having to unset them after the export). So Carsten Dominik (the creator of org-mode) added a few, but then decided to create the more general mechanism so he wouldn't have to keep adding in-buffer settings. In general, I think that #+BIND is not particularly useful any longer: the export mechanism has changed so substantially as to make it almost irrelevant.

Update: here's one way to do what you want:

#+name: myvar
#+BEGIN_SRC emacs-lisp
" middle "
#+END_SRC

#+BEGIN_SRC emacs-lisp :var x=myvar :results value :exports results
(concat "before" x "after")
#+END_SRC
like image 184
NickD Avatar answered Oct 09 '22 23:10

NickD