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