3

Following Situation:

  • I would like to calculate some fields from an org-table filled with strings.
  • There are many tables which all could share the same lisp-code.
  • The lisp-code is rather complex and long.
  • It should run for a single table multiple times, but with different parameters.
  • I would like to share the org-document along with calculation-ability.

Is it possible to achive this? If so how to achieve this?

I have done some simple tests to show you where my problem is:

#+NAME: test3
#+BEGIN_SRC emacs-lisp :var x="foobar"
(length x)
#+END_SRC

#+TBLNAME: test3-tbl
| blahbar |   |
| testi   | 7 |
#+TBLFM: @2$2='(org-sbe test3 (x $@1$1))

The above code works it takes one string from the table and prints its length into the table, fine.

Next code is also working:

#+NAME: test5
#+BEGIN_SRC emacs-lisp :var x='(2 3)
(* (car x) (cadr x))
#+END_SRC

#+TBLNAME: test5-tbl
| 4 |  5 |
|---+----|
| 6 | 20 |
#+TBLFM: @>$1='(org-sbe test5)::@>$2='(org-sbe test5 (x @1$1..@1$2))

It takes a range of numbers from the table and does some calculation, fine.

Now I tried to combine the stuff from above, and there I hit the wall. How to give a range (fields @1$1 to @1$2) from test-tbl4 to code-block test4?

#+NAME: test4
#+BEGIN_SRC emacs-lisp :var x='("foobar" "barfoo")
(concat (car x) (cadr x))
#+END_SRC

#+TBLNAME: test4-tbl
| blahbar      | test   |
| foobarbarfoo | #ERROR |
#+TBLFM: @>$1='(org-sbe test4)::@>$2='(org-sbe test4 (x $@1$1..$@1$2))

As you can see by #ERROR it is not working.

So my Questions:

  1. How get table test4-tbl to work with code-block test4?
  2. And could you please point me to the documentation where this is described?

2 Answers 2

2

The interpretation of a cell’s value as a string with the $ prefix doesn’t seem to work for ranges of cells. Your example does work without the range reference though:

#+NAME: test4
#+BEGIN_SRC emacs-lisp :var x='("foobar" "barfoo")
(concat (car x) (cadr x))
#+END_SRC

#+TBLNAME: test4-tbl
| blahbar      | test        |
| foobarbarfoo | blahbartest |
#+TBLFM: @>$1='(org-sbe test4)::@>$2='(org-sbe test4 (x $@1$1 $@1$2))

If you prefer range references, I’d change the code block to

#+NAME: test5
#+BEGIN_SRC emacs-lisp :var x='()
(mapconcat 'prin1-to-string x "")
#+END_SRC

#+TBLNAME: test4-tbl
| blahbar      | test        | another            |
| foobarbarfoo | blahbartest | blahbartestanother |
#+TBLFM: @>$3='(org-sbe test5 (x @1$1..@1$3))
2
  • The second part of your answer solves my problem, thanks. Do you have a clue where to find more information about constructs like "$@1$1" especially with the '$' in front. The org-mode manual does not seem to explain this.
    – jue
    May 18, 2017 at 8:16
  • 1
    Unfortunately not. What I did was turning on the org-table-toggle-formula-debugger to see what the range reference actually returned.
    – mutbuerger
    May 18, 2017 at 8:51
1

As of the org-mode git version since 2018-03-19, you can pass a range via org-sbe as a list:

#+name: concat
#+begin_src emacs-lisp :eval yes
  (mapconcat #'identity x "")
#+end_src

| foo | bar | foobar |
#+TBLFM: $3 = '(org-sbe concat (x (list $1..$2)))

This will now work correctly even if the table cells contain quotes or backslashes.

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.