Hello Org:

Over the last weeks I was talking with Ihor about `ob-lisp.el` and how it
handles `verbatim` and multiple values returned by Common Lisp.

I did a change where multiple values are now handled properly. In
particular, returning multiple values works the same as returning a list.
On the other hand, `verbatim` or `scalar` will not strip out the quotes
anymore when returning a string.

I hope this is helpful.

Héctor.
diff --git a/lisp/ob-lisp.el b/lisp/ob-lisp.el
index ed5a4bb00..7c98a6832 100644
--- a/lisp/ob-lisp.el
+++ b/lisp/ob-lisp.el
@@ -92,6 +92,24 @@ current directory string."
 	(format "(pprint %s)" body)
       body)))
 
+(defun org-babel-read-lisp-values (result)
+  "Parse RESULT as a sequence of values.
+
+RESULT is a string containing one or more Lisp values, optionally
+separated by commas. The function reads each expression sequentially
+and returns the parsed values as a list."
+  (if (string-empty-p result)
+      nil
+    (let* ((r (read-from-string result))
+           (current-result (car r))
+           (next-char (cdr r))
+           (rest-result (if (< next-char (length result))
+                            (if (char-equal (aref result next-char) ?\,)
+                                (substring result (+ next-char 2))
+                              (substring result (1+ next-char)))
+                          (substring result next-char))))
+      (cons current-result (org-babel-read-lisp-values rest-result)))))
+
 (defun org-babel-execute:lisp (body params)
   "Execute a block of Common Lisp code with Babel.
 BODY is the contents of the block, as a string.  PARAMS is
@@ -103,31 +121,38 @@ a property list containing the parameters of the block."
       (`sly-eval (org-require-package 'sly "SLY")
                  (setq eval-and-grab-output 'slynk:eval-and-grab-output)))
     (org-babel-reassemble-table
-     (let ((result
-            (funcall (if (member "output" (cdr (assq :result-params params)))
-                         #'car #'cadr)
-                     (with-temp-buffer
-                       (insert (org-babel-expand-body:lisp body params))
-                       (funcall org-babel-lisp-eval-fn
-                                `(,eval-and-grab-output
-                                  ,(let ((dir (if (assq :dir params)
-                                                  (cdr (assq :dir params))
-                                                default-directory)))
-                                     (format
-                                      (if dir (format org-babel-lisp-dir-fmt dir)
-                                        "(progn %s\n)")
-                                      (buffer-substring-no-properties
-                                       (point-min) (point-max)))))
-                                (cdr (assq :package params)))))))
-       (org-babel-result-cond (cdr (assq :result-params params))
-         (org-strip-quotes result)
+     (let* ((result-params (cdr (assq :result-params params)))
+            (result
+             (funcall (if (member "output" result-params)
+                          #'car #'cadr)
+                      (with-temp-buffer
+                        (insert (org-babel-expand-body:lisp body params))
+                        (funcall org-babel-lisp-eval-fn
+                                 `(,eval-and-grab-output
+                                   ,(let ((dir (if (assq :dir params)
+                                                   (cdr (assq :dir params))
+                                                 default-directory)))
+                                      (format
+                                       (if dir (format org-babel-lisp-dir-fmt dir)
+                                         "(progn %s\n)")
+                                       (buffer-substring-no-properties
+                                        (point-min) (point-max)))))
+                                 (cdr (assq :package params)))))))
+       (org-babel-result-cond result-params
+         (if (or (member "scalar" result-params)
+                 (member "verbatim" result-params))
+             result
+           (org-strip-quotes result))
          (condition-case nil
-             (read (org-babel-lisp-vector-to-list result))
+             (let ((list-values (org-babel-read-lisp-values (org-babel-lisp-vector-to-list result))))
+               (if (length= list-values 1)
+                   (car list-values)
+                 list-values))
            (error result))))
      (org-babel-pick-name (cdr (assq :colname-names params))
-			  (cdr (assq :colnames params)))
+                          (cdr (assq :colnames params)))
      (org-babel-pick-name (cdr (assq :rowname-names params))
-			  (cdr (assq :rownames params))))))
+                          (cdr (assq :rownames params))))))
 
 (defun org-babel-lisp-vector-to-list (results)
   "Convert #(...) values in RESULTS string into a (...) list."

Reply via email to