citar icon indicating copy to clipboard operation
citar copied to clipboard

Query affixes after adding key

Open denismaier opened this issue 2 years ago • 3 comments

I think we've discussed that before, but would it be possible to prompt for affixes after selecting a key? Maybe in a loop so users can select multiple keys, add affixes for each until they are finished?

denismaier avatar May 23 '22 20:05 denismaier

Is it possible? Sure.

Is it wise? IDK. I suspect the UX may get tricky.

And one can just add them directly to the buffer now.

Finally, there are other higher priorities ATM, including #591.

Also, of note, for another approach to entering keys etc, see:

https://github.com/mclear-tools/citar-capf

For some users, that may work better.

Note, though: I haven't gotten that working yet with Doom.

bdarcus avatar May 23 '22 20:05 bdarcus

Also, of note, for another approach to entering keys etc, see:

https://github.com/mclear-tools/citar-capf

For some users, that may work better.

Note, though: I haven't gotten that working yet with Doom.

Looks interesting, but no success with it on Doom here either...

denismaier avatar May 24 '22 09:05 denismaier

See here for someone experimenting with this, though he's advising org-cite-insert:

https://kristofferbalintona.me/posts/202206141852/#advising-citar-org-update-pre-suffix

This led me to wonder:

It could be one is prompted only when inserting a single citation-reference? Perhaps could use prefix args, in the same way they are used now to prompt for style selection when point is on a citation prefix ([cite:)?

We could also add a little function for this to include in the embark citar-citation-map keymap, for access at point. This is something one can configure locally now. If you do, please report.

bdarcus avatar Jun 15 '22 12:06 bdarcus

See here for someone experimenting with this, though he's advising org-cite-insert:

https://kristofferbalintona.me/posts/202206141852/#advising-citar-org-update-pre-suffix

This led me to wonder:

It could be one is prompted only when inserting a single citation-reference? Perhaps could use prefix args, in the same way they are used now to prompt for style selection when point is on a citation prefix ([cite:)?

We could also add a little function for this to include in the embark citar-citation-map keymap, for access at point. This is something one can configure locally now. If you do, please report.

@bdarcus Hello, I'm' the author of the article you linked. I happened to return and update my citar config today and decided to redo that override advice for citar-org-update-pre-suffix that I wrote, given that citar has gone through a lot of updates since then.

I'm not too familiar with the internals of citar and the org-element API, but I cobbled together something that works for my use case. I defined a new kb/citar-org-update-prefix-suffix (alongside a helper function, kb/citar-org--update-prefix-suffix) to override citar-org-update-pre-suffix:

Code
;; Minor customizations to `citar-org--update-prefix-suffix'; just changed
  ;; prompts
  (defun kb/c itar-org--update-prefix-suffix ()
    "Change the pre/suffix text of the reference at point."
    (let* ((ref (org-element-context))
           (key (org-element-property :key ref))
           (pre (string-trim-right
                 (read-string
                  (concat "Prefix for "
                          (propertize (concat key ": ") 'face 'mode-line-emphasis))
                  (org-element-property :prefix ref))))
           (post (string-trim-left
                  (read-string
                   (concat "Suffix for "
                           (propertize (concat key ": ") 'face 'mode-line-emphasis))
                   (org-element-property :suffix ref))))
           (v1 (org-element-property :begin ref))
           (v2 (org-element-property :end ref)))
      ;; Change post to automatically have one space prior to any user-inputted
      ;; suffix
      (setq post (concat (if (length> post 0) " " "") post))
      (cl--set-buffer-substring v1 v2
                                (org-element-interpret-data
                                 `(citation-reference
                                   (:key ,key :prefix ,pre :suffix ,post))))))
  ;; Gave `kb/citar-org-update-prefix-suffix' the ability to set the
  ;; pre/suffixes for all references in reference
  (defun kb/citar-org-update-prefix-suffix (&optional arg)
    "Change the pre/suffix text of the reference at point.
If given ARG, change the prefix and suffix for every reference in
the citation at point."
    (interactive "P")
    ;; Enable `typo' typographic character cycling in minibuffer. Particularly
    ;; useful in adding en- and em-dashes in citation suffixes (e.g. for page
    ;; ranges)
    (when (featurep 'typo)
      (add-hook 'minibuffer-mode-hook 'typo-mode)) ; Enable dashes
    (save-excursion
      (let* ((citation (or (citar-org-citation-at-point)
                           (error "Not on a citation reference")))
             (refs (if (or arg (not (car (citar-org-key-at-point))))
                       (car citation)
                     (list (car (citar-org-key-at-point)))))
             (beg (cadr citation)))
        (dolist (ref refs)
          (goto-char beg)
          (re-search-forward ref (cddr (citar-org-citation-at-point)))
          (setq beg (point))
          (kb/citar-org--update-prefix-suffix))))
    ;; Remove hook if it was added earlier
    (remove-hook 'minibuffer-mode-hook 'typo-mode))
  (advice-add 'citar-org-update-pre-suffix :override #'kb/citar-org-update-prefix-suffix)

It does the following:

  1. With no prefix arg, if the point is on a reference, a prefix and suffix will be prompted.
  2. With no prefix arg, if the point is on a citation, i.e., one of the square brackets, a prefix and suffix will be prompted for all references in the citation at point, from left to right.
  3. With prefix arg, a prefix and suffix for all references in the citation at point will be prompted for, from left to right.

There are several other personal customizations in the code I pasted, but this shows that this functionality is easily possible now. Here, I chose to rely on re-search-forward to iterate through all the references in a citation; I'm not aware of anything the org-element API gives us that could do something similar.

Let me know what you think.

P.S. My code also resolves #606 since it was a simple matter of processing the prompted strings prior to inserting them into the buffer.

krisbalintona avatar Jul 14 '23 20:07 krisbalintona

I'll take a closer look later (or if you want to prepare a PR, at that), but in the meantime, yes, this sounds like something worth merging.

And on:

... I chose to rely on re-search-forward to iterate through all the references in a citation.

I believe in the org module we only rely on org-element for accessing and manipulating citations and references. Is there a reason that won't work here?

bdarcus avatar Jul 14 '23 20:07 bdarcus

You're right. Initially, I used regexp because I wasn't very familiar with the current citar codebase nor comfortable with the org-element API. But after your comment, I looked around your code a bit and it became clear to me that org-element was the way to go.

I went back and changed my code to use org-element API rather than regexps. I made a pull request just now. Hope this helps.

krisbalintona avatar Jul 15 '23 08:07 krisbalintona