Introduce helper function to format Ledger CLI output as Org table

This function is ideal, but it's doing the job.  It can be used to
format output of calls to ledger as follows:

    #+begin_src emacs-lisp :results value raw table
    (db/ledger-cli-to-org-table-list
     (concat "ledger -f finance.ledger "
             "--period monthly --depth 2 "
             "--display 'd >= [2024-07-01]' "
             "--empty "
             "lisp ^Expense"))
    #+end_src
This commit is contained in:
Daniel Borchmann 2024-07-01 20:07:58 +02:00
parent 4714e0d0df
commit e7c08b088d
No known key found for this signature in database
GPG Key ID: 784AA8DF0CCDF625

View File

@ -1076,6 +1076,53 @@ _q_ → Quit this hydra"
("q" (message "Abort") nil) ("q" (message "Abort") nil)
("C-g" (message "Abort") nil)) ("C-g" (message "Abort") nil))
(defun db/ledger-cli-to-org-table-list (command)
"Run ledger COMMAND and convert the result to Org table list.
COMMAND is expected to be a call to ledger-cli and its `lisp'
subcommand, the result of which is a list of transactions. This
list is converted in such a way that Org can display it as table,
where the rows are all accounts contained in the result of
COMMAND, and where the columns are the individual transactions,
headlined with their date."
;; XXX: this implementation is certainly not ideal
(let* ((data (->> command
shell-command-to-string
read-from-string ; XXX: this needs some error handling
car
;; Format time and remove unnecessary data
(-map #'(lambda (row)
(list (format-time-string "%F" (nth 2 row))
(-map #'(lambda (entry)
(list (nth 1 entry)
(nth 2 entry)))
(-drop 5 row)))))))
(months (-map #'-first-item data))
funds
result)
(dolist (row data)
(let ((month (-first-item row)))
(dolist (entry (-second-item row))
(let ((fund (-first-item entry))
(value (-second-item entry)))
(setf (alist-get month (alist-get fund funds nil nil #'string=) nil nil #'string=)
value)))))
(push (cl-list* "" months) result)
(push (cl-list* " " (-repeat (length data) "<r>")) result)
(push 'hline result)
(dolist (fund (-sort #'string< (-map #'-first-item funds)))
(push (cl-list* fund
(-map #'(lambda (month)
(alist-get month (alist-get fund funds nil nil #'string=)
"0.00€" nil #'string=))
months))
result))
(reverse result)))
;;; Checklist Handling ;;; Checklist Handling