emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Visuwesh <visuweshm@gmail.com>
To: Org Mode List <emacs-orgmode@gnu.org>
Subject: Re: [PATCH] Add support for tables in Calc src block :var
Date: Fri, 13 Dec 2024 13:01:38 +0530	[thread overview]
Message-ID: <87pllw2g4l.fsf@gmail.com> (raw)
In-Reply-To: <87sf0239bm.fsf@ucl.ac.uk> (Eric Fraga's message of "Wed, 3 Apr 2024 12:43:58 +0000")

Sorry for getting back after so long!

[புதன் ஏப்ரல் 03, 2024] Fraga, Eric wrote:

> On Saturday, 30 Mar 2024 at 18:34, Visuwesh wrote:
>>> Specifically, I would love to make reference to calc variables,
>>> especially those defined using embedded calc, in org tables.
>>
>> Can you please provide a minimal example for me to play around with?  I
>> realise I would like something like this too [*] but I don't know
>> concretely what this would/should look like.
>
> So, embedded calc processes expressions in any buffer, including org
> mode, which might look like this:
>
> x := 3
>
> y := 5
>
> z := 3 x - y => 4
>
> where, in this case, the value of z has been determined by calc and the
> answer given after the => in the line.  The beauty of embedded calc is
> you can change the value of x and the subsequent expressions will be
> updated automatically (well, with C-x * u).
>
> I would then love to be able to have a table that would allow me to
> include the value of any variable, e.g. z above, something like
>
> | var | value |
> |-----+-------|
> | x   |     3 |
> | z   |     4 |
>
> where the values in the second column are obtained by querying Calc.

Here's a hack I cooked up:

    (defun vz/calc-embedded-get-var (var)
      "Return the value of active `calc-embedded' VAR in current buffer."
      (let* ((info (cdr (assq (current-buffer) calc-embedded-active)))
             (var-info
              (seq-find
               (lambda (x)
                 ;; 9 is the variable name: (var XXX var-XXX)
                 (eq var (nth 1 (aref x 9))))
               info))
             old-val)
        (when (and info var-info)
          ;; This is called the `old-val' in `calc-embedded-update'.
          ;; This can be nil when the formula isn't evaled I think?
          ;; (aref VAR-INFO 8) is again repeated in 11th slot when the
          ;; variable is simply as assignment.
          (or (if (consp (setq old-val (aref var-info 11)))
                  (car (last old-val))
                old-val)
              ;; 8 is the eval form: (calcFun-evalto ...) or
              ;; (calcFun-assign ...)
              (car (last (aref var-info 8)))))))

    (define-advice org-table-get-constant (:around (oldfun name) vz/consider-calc-embedded-var)
      "Check if NAME is a `calc-embedded' at last."
      (let ((val (funcall oldfun name)))
        (if (equal val "#UNDEFINED_NAME")
            (or (number-to-string (vz/calc-embedded-get-var (intern name)))
                val)
          val)))

Some caveats:

  1. You need to ensure that all the calc-embedded variables that you
     use in the formula need to be active and evaluated beforehand.
  2. The calc-embedded var is considered at last after everything else
     in org-table-get-constant in the advice.  This would be the best
     way to go forward.

It would be nice to lift the restrict in (1) but I think it would be
better to leave it to the user to ensure everything stays updated since
the user may want to use the old value.  However, ensuring all the vars
are active and eval-ed would be a royal pain when you're quickly
evaluating a table formula.

Here's the case I used to test this hack:

    x := 3

    y := 5

    z := 5 x - y => 10


    | 1 | 20 |
    #+TBLFM: $2=$z*2


  reply	other threads:[~2024-12-13  7:32 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-16  3:45 [PATCH] Add support for tables in Calc src block :var Visuwesh
2024-03-16  9:52 ` Ihor Radchenko
2024-03-16 11:37   ` Visuwesh
2024-03-16 12:19     ` Ihor Radchenko
2024-03-16 12:34       ` Visuwesh
2024-03-18 12:48         ` Fraga, Eric
2024-03-18 15:29           ` Visuwesh
2024-03-18 15:45             ` Fraga, Eric
2024-03-30 13:04           ` Visuwesh
2024-04-03 12:43             ` Fraga, Eric
2024-12-13  7:31               ` Visuwesh [this message]
2024-12-13  9:02                 ` Visuwesh
2024-12-13 10:53                   ` Fraga, Eric
2024-12-13 11:06                     ` Visuwesh
2024-12-13 11:48                       ` Fraga, Eric

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=87pllw2g4l.fsf@gmail.com \
    --to=visuweshm@gmail.com \
    --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).