Skip to content

Commit

Permalink
feat(org): enhance prefix/suffix updating
Browse files Browse the repository at this point in the history
* Add ability to update affixes in multiple references in a citation.
* Fix formatting (mostly whitespace) issues.

Closes: #606, #607

---------

Co-authored-by: Kristoffer Balintona <[email protected]>
  • Loading branch information
krisbalintona and krisbalintona authored Jul 15, 2023
1 parent 65745e8 commit 648ef55
Showing 1 changed file with 49 additions and 14 deletions.
63 changes: 49 additions & 14 deletions citar-org.el
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Each function takes one argument, a citation."
(define-key map (kbd "C-c C-x k") (cons "kill citation" #'citar-org-kill-citation))
(define-key map (kbd "S-<left>") (cons "shift left" #'citar-org-shift-reference-left))
(define-key map (kbd "S-<right>") (cons "shift right" #'citar-org-shift-reference-right))
(define-key map (kbd "M-p") (cons "update prefix/suffix" #'citar-org-update-pre-suffix))
(define-key map (kbd "M-p") (cons "update prefix/suffix" #'citar-org-update-prefix-suffix))
map)
"Keymap for interacting with org citations at point.")

Expand Down Expand Up @@ -440,27 +440,62 @@ or citation-reference."
(let ((datum (org-element-context)))
(citar-org--shift-reference datum 'right)))

(defun citar-org-update-pre-suffix ()
"Change the pre/suffix text of the reference at point."
;; TODO I want this to also work for global affixes on the citation,
;; but haven't figured that out yet.
(interactive)
(let* ((datum (org-element-context))
(datum-type (org-element-type datum))
(ref (if (eq datum-type 'citation-reference) datum
(error "Not on a citation reference")))
(defun citar-org--update-prefix-suffix (datum)
"Change the prefix and suffix text of the DATUM at point.
DATUM should be a reference, otherwise throw an error."
(let* ((ref-p (eq 'citation-reference (org-element-type datum)))
(ref (if ref-p datum (error "Not on a reference")))
(key (org-element-property :key ref))
;; TODO handle space delimiter elegantly.
(pre (read-string "Prefix text: " (org-element-property :prefix ref)))
(post (read-string "Suffix text: " (org-element-property :suffix ref)))
(citekey-str (propertize key 'face 'mode-line-emphasis))
(pre (org-element-interpret-data (org-element-property :prefix ref)))
(post (org-element-interpret-data (org-element-property :suffix ref)))
;; TODO Unsure if we want to process prefix at all
(prefix (read-string (concat "Prefix for " citekey-str ": ")
(string-trim pre)))
(suffix (string-trim-left ; Remove leading whitespace
(read-string (concat "Suffix for " citekey-str ": ")
(string-trim post))))
;; Change suffix to have one space prior to the user-inputted suffix, unless suffix is already empty
;; or just whitespace
(suffix-processed
(concat (unless (string-empty-p suffix) " ") suffix))
(v1
(org-element-property :begin ref))
(v2
(org-element-property :end ref)))
(cl--set-buffer-substring v1 v2
(org-element-interpret-data
`(citation-reference
(:key ,key :prefix ,pre :suffix ,post))))))
(:key ,key :prefix ,prefix :suffix ,suffix-processed))))))

(defun citar-org-update-prefix-suffix (&optional arg)
"Change the prefix and suffix text of the reference at point.
If given ARG, change the prefix and suffix for every reference in
the citation at point.
If point is not on a reference or citation, throw an error."
(interactive "P")
(let* ((datum (org-element-context))
(citation-p (eq 'citation (org-element-type datum)))
(ref-p (eq 'citation-reference (org-element-type datum)))
(current-citation (cond
(citation-p datum)
(ref-p (org-element-property :parent datum))
(t (error "Not on a citation or reference"))))
(refs (org-cite-get-references current-citation)))
(save-excursion
(if (or arg citation-p)
;; We use dotimes over dolist because the buffer changes as we iterate through the list, meaning we
;; cannot simply use the initial value of refs all throughout
(dotimes (ref-index (length refs))
(citar-org--update-prefix-suffix (nth ref-index refs))
;; Update refs since the begins and ends for the following references could have changed when
;; adding a prefix and/or suffix
(setq refs (org-cite-get-references
(if citation-p
(org-element-context)
(org-element-property :parent (org-element-context))))))
(citar-org--update-prefix-suffix (org-element-context))))))

;; Load this last.

Expand Down

0 comments on commit 648ef55

Please sign in to comment.