tasks/05-result-formatting.md done

This commit is contained in:
2026-01-24 17:40:13 +01:00
parent 879ffd08e7
commit 853516b47e
2 changed files with 150 additions and 1 deletions

View File

@@ -236,6 +236,108 @@ Handles:
;; Fallback
(t (format "%S" value))))
;;; Result Formatting
(defvar ob-elixir-nil-to 'hline
"Elisp value to use for Elixir nil in table cells.
When nil appears in an Elixir list that becomes a table,
it is replaced with this value. Use `hline' for org table
horizontal lines, or nil for empty cells.")
(defun ob-elixir--parse-value (str)
"Parse STR as a simple Elixir value."
(let ((trimmed (string-trim str)))
(cond
((string= trimmed "nil") nil)
((string= trimmed "true") t)
((string= trimmed "false") nil)
((string-match-p "^[0-9]+$" trimmed)
(string-to-number trimmed))
((string-match-p "^[0-9]+\\.[0-9]+$" trimmed)
(string-to-number trimmed))
((string-match-p "^\".*\"$" trimmed)
(substring trimmed 1 -1))
((string-match-p "^:.*$" trimmed)
(intern (substring trimmed 1)))
(t trimmed))))
(defun ob-elixir--parse-keyword-list (str)
"Parse STR as Elixir keyword list into alist.
Handles format like: [a: 1, b: 2]"
(when (string-match "^\\[\\(.*\\)\\]$" str)
(let ((content (match-string 1 str)))
(when (string-match-p "^[a-z_]+:" content)
(let ((pairs '()))
(dolist (part (split-string content ", "))
(when (string-match "^\\([a-z_]+\\):\\s-*\\(.+\\)$" part)
(push (cons (intern (match-string 1 part))
(ob-elixir--parse-value (match-string 2 part)))
pairs)))
(nreverse pairs))))))
(defun ob-elixir--sanitize-row (row)
"Sanitize a single ROW for table display."
(if (listp row)
(mapcar (lambda (cell)
(cond
((null cell) ob-elixir-nil-to)
((eq cell 'nil) ob-elixir-nil-to)
(t cell)))
row)
row))
(defun ob-elixir--sanitize-table (data)
"Sanitize DATA for use as an org table.
Replaces nil values according to `ob-elixir-nil-to'.
Ensures consistent structure for table rendering."
(cond
;; Not a list - return as-is
((not (listp data)) data)
;; Empty list
((null data) nil)
;; List of lists - could be table
((and (listp (car data)) (not (null (car data))))
(mapcar #'ob-elixir--sanitize-row data))
;; Simple list - single row
(t (ob-elixir--sanitize-row data))))
(defun ob-elixir--table-or-string (result)
"Convert RESULT to Emacs table or string.
If RESULT looks like a list, parse it into an Elisp list.
Otherwise return as string.
Uses `org-babel-script-escape' for parsing."
(let ((trimmed (string-trim result)))
(cond
;; Empty result
((string-empty-p trimmed) nil)
;; Looks like a list - try to parse
((string-match-p "^\\[.*\\]$" trimmed)
(condition-case nil
(let ((parsed (org-babel-script-escape trimmed)))
(ob-elixir--sanitize-table parsed))
(error trimmed)))
;; Looks like a tuple - convert to list first
((string-match-p "^{.*}$" trimmed)
(condition-case nil
(let* ((as-list (replace-regexp-in-string
"^{\\(.*\\)}$" "[\\1]" trimmed))
(parsed (org-babel-script-escape as-list)))
(ob-elixir--sanitize-table parsed))
(error trimmed)))
;; Scalar value
(t trimmed))))
;;; Variable Handling
(defun ob-elixir--var-name (name)
@@ -318,8 +420,10 @@ This function is called by `org-babel-execute-src-block'."
(result (ob-elixir--execute full-body result-type)))
(org-babel-reassemble-table
(org-babel-result-cond result-params
;; For output/scalar/verbatim - return as-is
result
(org-babel-script-escape result))
;; For value - parse into Elisp data
(ob-elixir--table-or-string result))
(org-babel-pick-name (cdr (assq :colname-names params))
(cdr (assq :colnames params)))
(org-babel-pick-name (cdr (assq :rowname-names params))