From: Daniele Nicolodi <daniele@grinta.net>
To: emacs-orgmode@gnu.org
Subject: Re: How is org-sbe supposed to work?
Date: Fri, 13 Nov 2020 22:56:48 +0100 [thread overview]
Message-ID: <d429d29b-42fa-7d7b-6f3a-9fe692fd6dc7@grinta.net> (raw)
In-Reply-To: <7de3bd69-4604-302a-b6d4-4e190f23bdb8@grinta.net>
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
prev parent reply other threads:[~2020-11-13 21:57 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-13 14:39 How is org-sbe supposed to work? Daniele Nicolodi
2020-11-13 21:56 ` Daniele Nicolodi [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.orgmode.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d429d29b-42fa-7d7b-6f3a-9fe692fd6dc7@grinta.net \
--to=daniele@grinta.net \
--cc=emacs-orgmode@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).