emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* [PATCH] ob-calc: Format vector and matrix results as Org table
@ 2024-12-13 18:53 Visuwesh
  2024-12-24 10:58 ` Ihor Radchenko
  0 siblings, 1 reply; 6+ messages in thread
From: Visuwesh @ 2024-12-13 18:53 UTC (permalink / raw)
  To: emacs-orgmode

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

Attached patch formats vector and matrix results from a Calc source
block as Org table.  To test, try

    #+NAME: test
    | 1 | 2 |

    #+BEGIN_SRC calc :var t=test
      2 * t
    #+END_SRC

It should return

    #+RESULTS:
    | 2 | 4 |

now.  The patch passes the old tests, and I added three new tests to
check the correctness of this conversion.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ob-calc-Format-vector-and-matrix-results-as-Org-tabl.patch --]
[-- Type: text/x-diff, Size: 5808 bytes --]

From f58dddf37728248e05cbdf2dcb56517f6723261e Mon Sep 17 00:00:00 2001
From: Visuwesh <visuweshm@gmail.com>
Date: Sat, 14 Dec 2024 00:23:14 +0530
Subject: [PATCH] ob-calc: Format vector and matrix results as Org tables

* lisp/ob-calc.el: (org-babel-execute:calc): Format vector and matrix
results as Org tables using the raw Calc object.
* testing/lisp/test-ob-calc.el (ob-calc/matrix-inversion)
(ob-calc/matrix-algebra, ob-calc/matrix-correct-conv-column)
(ob-calc/matrix-correct-conv-row): Use ':results verbatim' for the old
tests.
(ob-calc/conv-scalar, ob-calc/conv-vector, ob-calc/conv-matrix): Add
new tests to verify correct conversion of vector, matrix, and scalar
results with ':results replace'.
* etc/ORG-NEWS: Announce the new feature.
---
 etc/ORG-NEWS                 |  6 ++++++
 lisp/ob-calc.el              | 29 ++++++++++++++++++++-----
 testing/lisp/test-ob-calc.el | 42 ++++++++++++++++++++++++++++++++----
 3 files changed, 68 insertions(+), 9 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index ca73f06e7..fa98c41e6 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -946,6 +946,12 @@ properties, links to headlines in the file can also be made more
 robust by using the file id instead of the file path.
 
 ** New features
+*** =ob-calc.el=: Vector and matrix results can be formatted as Org tables
+
+~ob-calc~ can now format vector and matrix results as Org tables.
+This conversion can be overriden using the usual ~:results verbatim~
+keyword.
+
 *** =ob-tangle.el=: New flag to remove tangle targets before writing
 
 When ~org-babel-tangle-remove-file-before-write~ is set to ~t~ the
diff --git a/lisp/ob-calc.el b/lisp/ob-calc.el
index 810ed1735..e3fdc0cbd 100644
--- a/lisp/ob-calc.el
+++ b/lisp/ob-calc.el
@@ -110,11 +110,30 @@ (defun org-babel-execute:calc (body params)
                   ))))))
      (mapcar #'org-trim
 	     (split-string (org-babel-expand-body:calc body params) "[\n\r]"))))
-  (save-excursion
-    (with-current-buffer (get-buffer "*Calculator*")
-      (prog1
-          (calc-eval (calc-top 1))
-        (calc-pop 1)))))
+  (let ((result (prog1
+                    ;; Cannot use 'top' as SEPARATOR reliably when the
+                    ;; top of the stack has a vector.
+                    (calc-eval (calc-top 1) 'raw)
+                  (calc-eval 1 'pop)))
+        (calc-line-numbering)
+        lisp-table)
+    (org-babel-reassemble-table
+     (org-babel-result-cond (cdr (assq :result-params params))
+       (calc-eval result)
+       (if (Math-vectorp result)
+           (progn
+             (dolist (r (if (math-matrixp result)
+                            (cdr result) ; Ignore the 'vec item.
+                          (list result)))
+               (setq r (cdr r))         ; Ignore the 'vec item.
+               (push (mapcar (lambda (x) (math-format-stack-value (list x 1 nil))) r)
+                     lisp-table))
+             (setq lisp-table (nreverse lisp-table)))
+         (calc-eval result)))
+     (org-babel-pick-name
+      (cdr (assq :colname-names params)) (cdr (assq :colnames params)))
+     (org-babel-pick-name
+      (cdr (assq :rowname-names params)) (cdr (assq :rownames params)))))))
 
 (defun org-babel-calc-maybe-resolve-var (el)
 "Resolve user variables in EL.
diff --git a/testing/lisp/test-ob-calc.el b/testing/lisp/test-ob-calc.el
index 6d6ca104d..cfa1fb4f6 100644
--- a/testing/lisp/test-ob-calc.el
+++ b/testing/lisp/test-ob-calc.el
@@ -55,7 +55,7 @@ (ert-deftest ob-calc/matrix-inversion ()
 | 5 |  6 |  7 |
 | 9 | 14 | 11 |
 
-<point>#+BEGIN_SRC calc :results silent :var a=ob-calc-table-1
+<point>#+BEGIN_SRC calc :results silent verbatim :var a=ob-calc-table-1
 	inv(a)
 #+END_SRC "
     (should (equal "[[-1, 0.625, -0.125], [0.25, -0.5, 0.25], [0.5, 0.125, -0.125]]"
@@ -67,7 +67,7 @@ (ert-deftest ob-calc/matrix-algebra ()
 #+NAME: ob-calc-table-2
 | 1 | 2 | 3 | 4 | 5 |
 
-<point>#+BEGIN_SRC calc :results silent :var a=ob-calc-table-2
+<point>#+BEGIN_SRC calc :results silent verbatim :var a=ob-calc-table-2
 	a*2 - 2
 #+END_SRC"
     (should (equal "[0, 2, 4, 6, 8]"
@@ -93,7 +93,7 @@ (ert-deftest ob-calc/matrix-correct-conv-column ()
 | 2 |
 | 3 |
 
-<point>#+BEGIN_SRC calc :results silent :var a=ob-calc-table-3
+<point>#+BEGIN_SRC calc :results silent verbatim :var a=ob-calc-table-3
 	a
 #+END_SRC"
     (should (equal "[[1], [2], [3]]"
@@ -105,11 +105,45 @@ (ert-deftest ob-calc/matrix-correct-conv-row ()
 #+NAME: ob-calc-table-2
 | 1 | 2 | 3 | 4 | 5 |
 
-<point>#+BEGIN_SRC calc :results silent :var a=ob-calc-table-2
+<point>#+BEGIN_SRC calc :results silent verbatim :var a=ob-calc-table-2
 	a
 #+END_SRC"
     (should (equal "[1, 2, 3, 4, 5]"
                    (org-babel-execute-src-block)))))
 
+(ert-deftest ob-calc/conv-scalar ()
+  "Test of conversion of scalar for :result replace."
+  (org-test-with-temp-text "\
+<point>#+BEGIN_SRC calc :results silent
+	4 * 4
+#+END_SRC"
+    (should (equal "16"
+                   (org-babel-execute-src-block)))))
+
+(ert-deftest ob-calc/conv-vector ()
+  "Test of conversion of vector for :result replace."
+  (org-test-with-temp-text "\
+#+NAME: ob-calc-table
+| 1 | 2 | 3 | 4.1 | 5 | 6 |
+
+<point>#+BEGIN_SRC calc :results silent :var a=ob-calc-table
+	a * 2
+#+END_SRC"
+    (should (equal '(("2" "4" "6" "8.2" "10" "12"))
+                   (org-babel-execute-src-block)))))
+
+(ert-deftest ob-calc/conv-matrix ()
+  "Test of conversion of matrix for :result replace."
+  (org-test-with-temp-text "\
+#+NAME: ob-calc-table
+|   1 |   2 |
+| 2.2 | 4.2 |
+
+<point>#+BEGIN_SRC calc :results silent table :var a=ob-calc-table
+	a * 2
+#+END_SRC"
+    (should (equal '(("2" "4") ("4.4" "8.4"))
+                   (org-babel-execute-src-block)))))
+
 (provide 'test-ob-calc)
 ;;; test-ob-calc.el ends here
-- 
2.45.2


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

end of thread, other threads:[~2024-12-27 17:54 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-13 18:53 [PATCH] ob-calc: Format vector and matrix results as Org table Visuwesh
2024-12-24 10:58 ` Ihor Radchenko
2024-12-24 13:02   ` Visuwesh
2024-12-24 13:40     ` Ihor Radchenko
2024-12-26 13:06   ` Visuwesh
2024-12-27 17:54     ` Ihor Radchenko

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).