emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* call blocks as a function from inside elisp code
@ 2022-01-19 15:56 George Mauer
  2022-01-19 16:43 ` Eric S Fraga
  0 siblings, 1 reply; 3+ messages in thread
From: George Mauer @ 2022-01-19 15:56 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1111 bytes --]

Hi everyone,

I know that I can call a source block as a function in a header argument
such as :var, inside noweb annotations, or with a #+call: as described here
https://orgmode.org/manual/Evaluating-Code-Blocks.html

I am interested in going one step further though.

I have one emacs-lisp block that generates a list of python files which
mention a search term provided by a variable (eg
gim/get-file-list(search="_utilities") )

I have another code block written in python that given a python filename
will do some ast parsing to tell me some interesting facts about it (eg
#+call: gim/get-python-program-info(filename="foo/bar/some_module.py") )

What I would like to do is to chain the two together (ideally inside a code
block so I can dynamically format the output) so that I can get info on
*each* of the files produced by the first block.

So is there a way to do the equivalent of #+call:
gim/get-python-program-info(filename="foo/bar/some_module.py") from
*inside* an elisp code block? I am aware that I can call things via noweb,
but I'm trying to see if I can avoid that for several other reasons

[-- Attachment #2: Type: text/html, Size: 1370 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: call blocks as a function from inside elisp code
  2022-01-19 15:56 call blocks as a function from inside elisp code George Mauer
@ 2022-01-19 16:43 ` Eric S Fraga
  2022-01-19 20:00   ` Tom Gillespie
  0 siblings, 1 reply; 3+ messages in thread
From: Eric S Fraga @ 2022-01-19 16:43 UTC (permalink / raw)
  To: George Mauer; +Cc: emacs-orgmode

On Wednesday, 19 Jan 2022 at 09:56, George Mauer wrote:
> So is there a way to do the equivalent of #+call:
> gim/get-python-program-info(filename="foo/bar/some_module.py") from
> *inside* an elisp code block? I am aware that I can call things via
> noweb, but I'm trying to see if I can avoid that for several other
> reasons

Two ways I can think of:

1. use the :post header argument to chain calls or
2. invoke (org-sbe "blockname") although I am not sure if you can pass
   variables.  org-sbe is a macro in ob-table.el.
   
There may be (very likely) a more general way to evaluate a src block
from with elisp.

HTH,
eric


-- 
: Eric S Fraga, with org release_9.5.2-306-g9623da in Emacs 29.0.50


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: call blocks as a function from inside elisp code
  2022-01-19 16:43 ` Eric S Fraga
@ 2022-01-19 20:00   ` Tom Gillespie
  0 siblings, 0 replies; 3+ messages in thread
From: Tom Gillespie @ 2022-01-19 20:00 UTC (permalink / raw)
  To: Org Mode List; +Cc: George Mauer

Hi George,
    Here is an example of how I call nested elisp and python. The
python block is an input argument to the elisp block in this case, but
the python block could be called directly as well. I'm not sure how to
pass arguments to the block from inside elisp via org-babel-eval
though, that seems like it would require some deeper
tampering/advising of functions. Best,
Tom

https://github.com/SciCrunch/sparc-curation/blame/master/docs/queries.org#L1704-L1707
#+begin_src elisp :results none :exports none
(ow-babel-eval "neru-simplified")
#+end_src

The implementation I use is included below and is source dfrom
https://github.com/tgbugs/orgstrap/blob/bc981b957967be8d872c08be9ba7f2dbde5caf1d/ow.el#L786-L803

(defun ow-babel-eval (block-name &optional universal-argument)
  "Use to confirm running a chain of dependent blocks starting with BLOCK-NAME.
This retains single confirmation at the entry point for the block."
  ;; TODO consider a header arg for a variant of this in org babel proper
  (interactive "P")
  (let ((org-confirm-babel-evaluate (lambda (_l _b) nil))) ;; FIXME
TODO set messages buffer size to nil
    (save-excursion
      (when (org-babel-find-named-block block-name)
        ;; goto won't raise an error which results in the block where
        ;; `ow-confirm-once' is being used being called an infinite
        ;; number of times and blowing the stack
        (org-babel-goto-named-src-block block-name)
        (unwind-protect
            (progn
              ;; FIXME optionally raise errors on failure here !?
              (advice-add #'org-babel-insert-result :around
#'ow--results-silent)
              (org-babel-execute-src-block))
          (advice-remove #'org-babel-insert-result #'ow--results-silent))))))

(defun ow--results-silent (fun &rest args)
  "Whoever named the original version of this has a strange sense of humor."
  ;; so :results silent, which is what org babel calls between vars
  ;; set automatically is completely broken when one block calls another
  ;; there likely needs to be an internal gensymed value that babel blocks
  ;; can pass to eachother so that a malicious user cannot actually slience
  ;; values, along with an option to still print, but until then we have this
  (let ((result (car args))
        (result-params (cadr args)))
    (if (member "silent" result-params)
        result
      (apply fun args))))


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-01-19 20:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-19 15:56 call blocks as a function from inside elisp code George Mauer
2022-01-19 16:43 ` Eric S Fraga
2022-01-19 20:00   ` Tom Gillespie

Code repositories for project(s) associated with this 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).