0

The Org Manual is very clear about how to use constants defined using constructs such as #+CONSTANTS: MYCONSTANT = 10 in table formulas. However, it is unclear if these global constants can be used in source code blocks.

Here is an example of how to use constants in table formulas.

#+CONSTANTS: t=2
|-----+--------|
| Val | Result |
|-----+--------|
|   1 |      2 |
|   2 |      4 |
|-----+--------|
#+TBLFM: @2$2=@2$1 * $t
#+TBLFM: @3$2=@3$1 * $t

Notice that you must prepend $ to the variable name to make it accessible in formulas.

Is there any way to use constants defined using #+CONSTANTS in source code blocks. I am aware of how to use :session to accomplish this with normal variables from one source code block in another. I am not interested in that.

2
  • AFAIK the answer is "no".
    – NickD
    Mar 16, 2022 at 18:48
  • Appreciate the prompt answer. Mar 16, 2022 at 21:24

3 Answers 3

0

It is not directly possible, but you can do something like this:

#+CONSTANTS: t=2

#+BEGIN_SRC python :results output :var constants=(cadar (org-collect-keywords '("CONSTANTS")))
exec(constants)
print(t * 2)
#+END_SRC

#+RESULTS:
: 4

If the src block language doesn't support assignment in this way, you would have to do some additional parsing perhaps like this(here I changed the name to tee because t is a reserved keyword in emacs-lisp). Maybe there is a clever way to know when the value of tee is a number or string, I just assume number here.

#+CONSTANTS: tee=2

#+BEGIN_SRC emacs-lisp :var constants=(cadar (org-collect-keywords '("CONSTANTS")))
(let* ((parts (split-string constants "=")))
  (eval `(setq ,(intern-soft (first parts)) ,(string-to-number (second parts))))
  (* tee 2))
#+END_SRC

#+RESULTS:
: 4
0

You can access properties in code blocks:

:PROPERTIES:
:foo: 42
:END:
#+BEGIN_SRC shell :var foo=(org-macro--get-property "foo" "")
echo $foo
#+END_SRC
0

There is also this mind-bendingly awful trick:

#+property: header-args+ :var routers="rm284 rm288 rm332 rm336"

#+begin_src bash                                                                                                   
echo $routers                                                                                                      
#+end_src                                                                                                          

#+RESULTS[bf71...]:
: rm284 rm288 rm332 rm336 

This way all blocks in the buffer will get the header :var added to it. You can even add more variables without overwriting the last one:

 #+property: header-args+ :var routers="rm284 rm288 rm332 rm336"
 #+property: header-args+ :var horses="neigh"

 #+begin_src bash
 echo $routers
 echo $horses
 #+end_src

 #+RESULTS[88286bf821889c3f3c2eb980b4afdc23b598f248]:
 : rm284 rm288 rm332 rm336
 : neigh

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.