[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: How is org-sbe supposed to work?
From: |
Daniele Nicolodi |
Subject: |
Re: How is org-sbe supposed to work? |
Date: |
Fri, 13 Nov 2020 22:56:48 +0100 |
User-agent: |
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Thunderbird/68.12.1 |
On 13/11/2020 15:39, Daniele Nicolodi wrote:
> How are variables passed to the code block supposed to be handled? The
> macro docstring does not mention anything particular, thus I would
> imagine they are handled just like in any other lisp code. However, this
> does not seem to be the case.
After some more testing and starring at the code some more, it seems
that the odd behavior comes from the attempt of org-sbe to be clever and
do not require to use the N flag in the org table formula definition to
parse numbers as such, maybe.
Anyway, I came up with an alternative macro that does what I would
expect org-sbe to do, acting as a transparent interface to execute org
code blocks, without surprises:
(defun org-sbx1 (name header args)
(let* ((args (mapconcat
(lambda (x)
(format "%s=%S" (symbol-name (car x)) (cadr x)))
args ", "))
(ctx (list 'babel-call (list :call name
:name name
:inside-header header
:arguments args
:end-header ":results silent")))
(info (org-babel-lob-get-info ctx)))
(when info (org-babel-execute-src-block nil info))))
(defmacro org-sbx (name &rest args)
(let* ((header (if (stringp (car args)) (car args) nil))
(args (if (stringp (car args)) (cdr args) args)))
(unless (stringp name)
(setq name (symbol-name name)))
(let ((result (org-sbx1 name header args)))
(org-trim (if (stringp result) result (format "%S" result))))))
which I find significantly simpler than the implementation of org-sbe.
It works emulating what a #+call: directive does constructing by hand
the parsed version returned by org-element-parse. Demo:
#+name: sum
#+begin_src elisp :var x='(2 3)
(apply '+ x)
#+end_src
#+name: concat
#+begin_src elisp :var x='()
(apply 'concat x)
#+end_src
| 1 | 2 | 3 | 4 | 5 | 15 | 15 |
| a | b | c | d | e | abcde | abcde |
#+TBLFM: @1$6='(org-sbx sum (x '($1..$5)));N
#+TBLFM: @1$7='(apply '+ '($1..$5));N
#+TBLFM: @2$6='(org-sbx concat (x '($1..$5)))
#+TBLFM: @2$7='(apply 'concat '($1..$5))
The only problem I have with it is that the point jumps around during
evaluation and that while the macro is evaluated the formula definition
line is duplicated. I haven't yet investigated why (however the same
happens with org-sbe).
It may be that it is not too difficult to avoid having to convert the
arguments to a string representation and back, but this would require
digging a bit deeper into ob-core.el.
Cheers,
Dan