feat: add spine-add-book write function

This commit is contained in:
2026-06-21 08:18:18 -04:00
parent a8ecf952c6
commit 9aacccb2ee
+65
View File
@@ -137,6 +137,71 @@ SELECTED-ID expands the matching book's detail section."
("reading_count" reading-count) ("reading_count" reading-count)
("groups" (nreverse groups)))))) ("groups" (nreverse groups))))))
(defun spine-add-book (&rest args)
"Add a new WANT book to `spine-org-file'.
Keyword arguments: :title :author :category :format :isbn :cover
:rec_by :rec_note :date_added :initial_note
Signals an error on failure."
(let ((title (plist-get args :title))
(author (plist-get args :author))
(category (plist-get args :category))
(format (plist-get args :format))
(isbn (plist-get args :isbn))
(cover (plist-get args :cover))
(rec-by (plist-get args :rec_by))
(rec-note (plist-get args :rec_note))
(date-added (plist-get args :date_added))
(initial-note (plist-get args :initial_note)))
(unless title
(error "spine-add-book: title is required"))
(let ((org-file (expand-file-name spine-org-file)))
;; Create file if it doesn't exist
(unless (file-exists-p org-file)
(with-temp-file org-file
(insert "#+TODO: WANT(w) READING(r) | READ(d) ABANDONED(a)\n\n")))
(with-current-buffer (find-file-noselect org-file)
(unwind-protect
(progn
(goto-char (point-max))
;; Insert new headline
(org-insert-heading nil t)
(insert title)
;; Set TODO state
(org-todo "WANT")
;; Set properties (only non-empty)
(when (and author (> (length author) 0))
(org-set-property "AUTHOR" author))
(when (and format (> (length format) 0))
(org-set-property "FORMAT" format))
(when (and isbn (> (length isbn) 0))
(org-set-property "ISBN" isbn))
(when (and cover (> (length cover) 0))
(org-set-property "COVER" cover))
(when (and rec-by (> (length rec-by) 0))
(org-set-property "REC_BY" rec-by))
(when (and rec-note (> (length rec-note) 0))
(org-set-property "REC_NOTE" rec-note))
(when (and date-added (> (length date-added) 0))
(org-set-property "ADDED" (format "[%s]" date-added)))
;; Set ID
(org-set-property "ID"
(format "%04x-%s"
(random 65535)
(substring (sha1 (concat title (number-to-string (random)))) 0 4)))
;; Set tags
(when (and category (> (length category) 0))
(org-set-tags (list category)))
;; Add initial note
(when (and initial-note (> (length initial-note) 0))
(let ((date (if (and date-added (> (length date-added) 0))
date-added
(format-time-string "%Y-%m-%d"))))
(goto-char (org-entry-end-position))
(insert (format "\n- [%s] %s\n" date initial-note))))
(save-buffer)
t)
(kill-buffer))))))
(defun spine--extract-notes (hl-begin hl-end) (defun spine--extract-notes (hl-begin hl-end)
"Extract reading notes from headline body between HL-BEGIN and HL-END. "Extract reading notes from headline body between HL-BEGIN and HL-END.
Returns list of (date-string text-string) pairs." Returns list of (date-string text-string) pairs."