diff --git a/lisp/oc-natbib.el b/lisp/oc-natbib.el index 13cac9ed0..bf086f36d 100644 --- a/lisp/oc-natbib.el +++ b/lisp/oc-natbib.el @@ -119,11 +119,7 @@ If \"natbib\" package is already required in the document, e.g., through (defun org-cite-natbib--build-optional-arguments (citation info) "Build optional arguments for citation command. CITATION is the citation object. INFO is the export state, as a property list." - (let* ((origin (pcase (org-cite-get-references citation) - (`(,reference) reference) - (_ citation))) - (suffix (org-element-property :suffix origin)) - (prefix (org-element-property :prefix origin))) + (pcase-let ((`(,prefix . ,suffix) (org-cite-main-affixes citation))) (concat (and prefix (format "[%s]" (org-trim (org-export-data prefix info)))) (cond (suffix (format "[%s]" (org-trim (org-export-data suffix info)))) diff --git a/lisp/oc.el b/lisp/oc.el index ca6265822..41fd688c0 100644 --- a/lisp/oc.el +++ b/lisp/oc.el @@ -638,6 +638,24 @@ in the current buffer. Positions include leading \"@\" character." (re-search-forward org-element-citation-key-re end t) (cons (match-beginning 0) (match-end 0))))) +(defun org-cite-main-affixes (citation) + "Return main affixes for CITATION object. + +Some export back-ends only support a single pair of affixes per +citation, even if it contains multiple keys. This function +decides what affixes are the most appropriate. + +Return a pair (PREFIX . SUFFIX) where PREFIX and SUFFIX are +parsed data." + (let ((source + ;; When there are multiple references, use global affixes. + ;; Otherwise, local affixes have priority. + (pcase (org-cite-get-references citation) + (`(,reference) reference) + (_ citation)))) + (cons (org-element-property :prefix source) + (org-element-property :suffix source)))) + (defun org-cite-supported-styles (&optional processors) "List of supported citation styles and variants. diff --git a/testing/lisp/test-oc.el b/testing/lisp/test-oc.el index 80d74be95..49140fe0f 100644 --- a/testing/lisp/test-oc.el +++ b/testing/lisp/test-oc.el @@ -251,6 +251,45 @@ (car boundaries) (cdr boundaries))))))) +(ert-deftest test-org-cite/main-affixes () + "Test`org-cite-main-affixes'." + (should + (equal '(nil . nil) + (org-test-with-temp-text "[cite:@key]" + (org-cite-main-affixes (org-element-context))))) + (should + (equal '(nil . nil) + (org-test-with-temp-text "[cite:@key1;@key2]" + (org-cite-main-affixes (org-element-context))))) + (should + (equal '(("pre ") . nil) + (org-test-with-temp-text "[cite:pre @key]" + (org-cite-main-affixes (org-element-context))))) + (should + (equal '(("pre ") . (" post")) + (org-test-with-temp-text "[cite:pre @key post]" + (org-cite-main-affixes (org-element-context))))) + (should + (equal '(("pre ") . nil) + (org-test-with-temp-text "[cite:global pre;pre @key]" + (org-cite-main-affixes (org-element-context))))) + (should + (equal '(nil . (" post")) + (org-test-with-temp-text "[cite:@key post;global post]" + (org-cite-main-affixes (org-element-context))))) + (should + (equal '(("global pre") . ("global post")) + (org-test-with-temp-text "[cite:global pre;@key1;@key2;global post]" + (org-cite-main-affixes (org-element-context))))) + (should + (equal '(("global pre") . nil) + (org-test-with-temp-text "[cite:global pre;pre1 @key1;pre2 @key2]" + (org-cite-main-affixes (org-element-context))))) + (should + (equal '(nil . ("global post")) + (org-test-with-temp-text "[cite:@key1 post1;@key2 post2; global post]" + (org-cite-main-affixes (org-element-context)))))) + (ert-deftest test-org-cite/supported-styles () "Test `org-cite-supported-styles'." ;; Default behavior is to use export processors.