7

Is there a way to use file local variables set in an org-mode file in the following contexts:

  1. Simply expanding the variable when text is exported (eg: to LaTeX)
  2. Passing the value to :var in a babel source block (SQL or Python)
  3. Expanding the variable in a org-mode table for use in #+TBLFM

For example here is the local variable definition at the end of the document:

# Local Variables:                                             
# mode: org
# foo: bar
# aNumber: 32                                                     
# End:  

Context 1:

* First Section
is about <foo>

Context 2:

#+BEGIN_SRC python :var baz=<foo>
print(baz)
#+END_SRC

Context 3:

|Numbers | NumbersMultipliedBy2 |
|<aNumber>   | =@2$1 * 2            |

1 Answer 1

4

Orgmode's export function copies the buffer content to a new buffer and evaluates the source blocks in the new buffer. Thereby only buffer local variables with prefixes org- and orgtbl- are copied from the original buffer to the new one.

That means you need to prefix your buffer local variables with org- or orgtbl-.

In order to avoid clashes between org variables and your own buffer local variables I suggest to use some unique id at the second position of the name, e.g., org-my-....

I did not find a simple inline substitution of local variables by their evaluation result.
The closest one gets is inline source code src_emacs-lisp[:var baz=org-my-foo]{baz}. The problem is that the :exports header argument does not work for inline source code. So you cannot suppress the source code.

For that reason I defined a new eval: link type with the following elisp code.

(require 'org)

(defun my-org-link-eval (path &rest _rest)
  "Evaluate PATH and return result as string."
  (condition-case err
      (prin1-to-string (eval (read path)))
    (error (format "Error in eval of %S: %S." path err))))

(defun my-org-link-eval-activate (start end path bracketp)
  "Display text from START to END as result of the eval of PATH.
BRACKETP is ignored."
  (save-excursion
    (if org-descriptive-links
      (add-text-properties
       start end
       (list 'display (propertize (my-org-link-eval path) 'face 'org-link)))
      (remove-text-properties start end '(display nil)))))

(org-link-set-parameters "val"
             :export #'my-org-link-eval
             :activate-func #'my-org-link-eval-activate)

If you install that code in your init file and restart emacs you can use the following org file as a demo for all your contexts.

Context 1:
* First Section
is about [[val:org-my-foo]]

Context 2:

#+BEGIN_SRC python :var baz=(prin1-to-string org-my-foo) :exports results
return(baz)
#+END_SRC

#+RESULTS:
: bar

Context 3:

| Numbers | NumbersMultipliedBy2 |
|---------+----------------------|
|      32 |                   64 |
#+TBLFM: $1='(prin1-to-string org-my-aNumber)::$2=@2$1 * 2

# Local Variables:                                             
# mode: org
# org-my-foo: bar
# org-my-aNumber: 32                                                     
# End:

With descriptive links activated [[eval:org-my-foo]] is displayed as bar. Independently of the display the link always exports to bar.

The header argument :var baz=(prin1-to-string org-my-foo) of the python source block evaluates org-my-foo in the course of function argument evaluation and formats the resulting value as string. The resulting string is assigned to the python variable baz.

The '(prin1-to-string org-my-aNumber) in the table formula evaluates the lisp form (prin1-to-string org-my-aNumber) in the same way as in the previous paragraph.

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.