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