render.lisp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. (in-package #:pta-ledger)
  2. (defun render-date (universal-time)
  3. (when universal-time
  4. (format nil "~{~4,'0D/~2,'0D/~2,'0D~}" (get-date universal-time))))
  5. (defgeneric render (object &optional stream)
  6. (:documentation "Render OBJECT to STREAM in text format."))
  7. (defmethod render ((null null) &optional stream)
  8. (declare (ignore stream)))
  9. (defmethod render ((amount amount) &optional stream)
  10. (format stream "~$ ~A" (amount-quantity amount) (amount-commodity amount)))
  11. (defmethod render ((posting posting) &optional stream)
  12. (with-slots (status account amount unit-price total-price comment) posting
  13. (let* ((amount-text (render amount))
  14. (status-text (format nil "~@[~A ~]" status))
  15. (text (format nil " ~A~vA~@[ ~A~]~@[ @ ~A~]~@[ @@ ~A~]"
  16. status-text
  17. (if amount-text (- 46 (position #\Space amount-text) (length status-text)) 0)
  18. account
  19. amount-text
  20. (when unit-price (render unit-price))
  21. (when total-price (render total-price))))
  22. (comments (split comment))
  23. (first-comment (first comments))
  24. (rest-comments (rest comments)))
  25. (format stream "~A~@[ ; ~A~]~{~%~vA ; ~A~}" text first-comment
  26. (loop for comment in rest-comments append (list (length text) "" comment))))))
  27. (defmethod render ((entry entry) &optional stream)
  28. (with-slots (date secondary-date status code description comment postings) entry
  29. (let* ((text (format nil "~A~@[=~A~]~@[ ~A~]~@[ (~A)~]~@[ ~A~]"
  30. (render-date date) (render-date secondary-date)
  31. status code description))
  32. (comments (split comment))
  33. (first-comment (first comments))
  34. (rest-comments (rest comments)))
  35. (format stream "~A~@[ ; ~A~]~{~%~vA ; ~A~}~{~%~A~}" text first-comment
  36. (loop for comment in rest-comments append (list (length text) "" comment))
  37. (loop for posting in postings collect (render posting))))))