Is it possible to evaluate all fields in a document like how is possible in Mathematica and Jupyter notebooks? Using the evaluate all from the toolbar only evaluates connected fields.
Evaluate all in document?
Hi and welcome to the forum!
As far as I know, an evaluation command to evaluate all fields in a document does not exist, I agree that it would be useful.
I found that “Evaluate all” executes session-evaluate-all
, defined with this code:
(tm-define (session-evaluate-all)
(session-forall
(lambda (t)
(when (not (tree-empty? (tree-ref t 1)))
(field-process-input t)))))
My feeling is that it is possible to extend this by iterating over all of the trees that represent the same session. Give me a little time, maybe I am able to write code that does that.
Other relevant functions are
(define (session-forall-sub fun t)
(for (u (tree-children t))
(when (field-context? u)
(fun u))
(when (and (tm-func? u 'unfolded-subsession)
(tm-func? (tree-ref u 1) 'document))
(session-forall-sub fun (tree-ref u 1)))))
(define (session-forall fun)
(with-innermost t subsession-document-context?
(session-forall-sub fun t)))
(I found all of them in progs/dynamic/session-edit.scm)
It’s a bit tricky, as the functions in session-edit.scm
rely on (get-env "prog-session")
to send input to the right session. But the environment variable is only set to the right value if the cursor is in the session. I tried
(map
(lambda (ses) (begin (tree-go-to ses 1 1 0) (session-evaluate-all)))
(tree-search (buffer-tree) subsession-document-context?))
to move the cursor to the session and then evaluate, but it doesn’t work.
Nice work
I found out that with for-each
it works:
(define (ev-all) (for-each
(lambda (ses) (begin (tree-go-to ses 1 1 0) (session-evaluate-all)))
(tree-search (buffer-tree) subsession-document-context?)))
(kbd-map
("A-e" (ev-all)))
I have a faint hint of why that may be the case (executing the statements in order? it does not seem a sufficient explanation).
Edit: the shortcut A-e in regular text starts an enumeration environment in the emacs look and feel. But perhaps it is ok as it is written, as it works inside a session. One should (again, perhaps) adapt the shortcut to the look and feel.
@konfou Putting everything in your my-init-texmacs should provide you the command for evaluating all fields; maybe a refinement is still helpful as this evaluates all fields in all sessions in your document, and you might want to evaluate all fields in a given session (even if they are disconnected).
You can also extend the context menu using
(tm-menu (texmacs-popup-menu)
(:require (inside? 'session))
(former)
---
("Evaluate all fields in document" (ev-all)))
(also to add in my-init-texmacs.scm)
Thanks, works great! Just an addition, in the older TeXmacs version I’m using, tree-search
isn’t in global namespace and it has to be imported using
(use-modules
((link link-extract)
#:select (tree-search)))
I’ve got one more suggestion: in the previous incarnation, the cursor went to the second element of the session (1 1 0
), the first element usually being the banner. However, if you have a session without banner and just one field, this may break. I think this should work better (note the (tree-go-to ses :last 1 0)
):
(define (ev-all)
(for-each (lambda (ses) (begin (tree-go-to ses :last 1 0) (session-evaluate-all)))
(tree-search (buffer-tree) subsession-document-context?)))