OK. I wrote a POC, and I would appreciate some feedback about it.
In order to test it, one need to evaluate the following, from an
up-to-date "wip-cite-new" branch:
--8<---------------cut here---------------start------------->8---
(defun org-cite--swap-punctuation (object info)
"Move punctuation following OBJECT before it, if applicable.
When OBJECT is followed by some terminal punctuation character, such as
a period or a question mark, and preceded by some text, move the punctuation
at the end of the previous text. If that text ends with a double quote,
move the punctuation before that quote, too.
INFO is the export state, as a property list."
(let ((next (org-export-get-next-element object info))
(previous
(org-last
(org-element-map (org-export-get-previous-element object info)
'plain-text
#'identity info)))
(punct-re
(rx string-start
(group (or "." "!" "?" "..." "…"))
(or eol (any " " "\t")))))
(when (and previous
(stringp next)
(string-match punct-re next))
(let* ((punct (match-string 1 next))
(new-next (substring next (match-end 1)))
(quote-re
(rx (opt (and (group (or string-start (not (any "." "!" "?"
"…"))))
(group "\"")))
(group (0+ (any " " "\t")))
string-end))
(new-previous
(replace-regexp-in-string
quote-re (concat "\\1" punct "\\2\\3") previous)))
(org-element-set-element next new-next)
(org-element-set-element previous new-previous)))))
(defun org-cite-wrap-citation (citation info &optional move-punctuation)
"Wrap an anonymous inline footnote around CITATION object in the parse tree.
INFO is the export state, as a property list. When optional argument
MOVE-PUNCTUATION is non-nil, move punctuation character following citation
before
it, when applicable. If a quotation mark precedes the citation, move
punctuation before it, too.
The parse tree is modified by side-effect."
(let ((footnote
(list 'footnote-reference
(list :label nil
:type 'inline
:contents-begin (org-element-property :begin citation)
:contents-end (org-element-property :end citation)
:post-blank (org-element-property :post-blank
citation)))))
;; Remove any white space before citation.
(org-cite--set-previous-post-blank citation 0 info)
;; Possibly swap punctuation around citation.
(when move-punctuation (org-cite--swap-punctuation citation info))
;; Footnote swallows citation.
(org-element-insert-before footnote citation)
(org-element-adopt-elements footnote
(org-element-extract-element citation))))
;; test citation processor
(defun test-export-citation (citation nil nil info)
(org-cite-wrap-citation citation info t)
"...")
(org-cite-register-processor 'test
:export-citation #'test-export-citation)
--8<---------------cut here---------------end--------------->8---
For example, the following document:
--8<---------------cut here---------------start------------->8---
#+cite_export: test
This is a test [cite:@a].
This is a test [cite:@a]?
This is a test [cite:@a]...
This is a "test" [cite:@a].
This is a "test." [cite:@a].
This is a *"test"* [cite:@a].
This is a *some /covoluted/ "test"* [cite:@a].
# Do nothing in the following cases.
This is a test [cite:@a]
This is a test. [cite:@a]
[cite:@a].
This is a "test" [cite:@a]
--8<---------------cut here---------------end--------------->8---
would become in ASCII export (without the uninteresting footnotes part):
--8<---------------cut here---------------start------------->8---
This is a test.[1]
This is a test?[2]
This is a test…[3]
This is a « test. »[4]
This is a « test. ».[5]
This is a *« test. »*[6]
This is a *some /covoluted/ « test. »*[7]
This is a test[8]
This is a test.[9]
[10].
This is a « test »[11]
--8<---------------cut here---------------end--------------->8---
Is it what you had in mind?
Also, I have questions about punctuation.
Currently, these changes only apply to terminal punctuation I could
think of: . ! ? ... …
Should the above apply to any punctuation, i.e., [:punct:]? Should it be
limited to a different set of elements instead? If so which one? Should
it be configurable?