Browse Source

oc: Fix citations in footnotes when using biblatex back-end

* lisp/oc.el (org-cite-list-citations): Do not use
`org-export-get-footnote-definition' so as to not cache footnote
definitions too early, i.e., when citations are still present in the
parse tree.
* lisp/oc-biblatex.el (org-cite-biblatex--multi-arguments): Append
"\relax" unconditionally to avoid calling `org-export-data' on next
object, when citations are still present in the parse tree.

Reported-by: Elias Bounatirou <elias.bounatirou@gmail.com>
<http://lists.gnu.org/r/emacs-orgmode/2021-09/msg00067.html>
Nicolas Goaziou 3 years ago
parent
commit
7d22dca54e
2 changed files with 17 additions and 11 deletions
  1. 4 8
      lisp/oc-biblatex.el
  2. 13 3
      lisp/oc.el

+ 4 - 8
lisp/oc-biblatex.el

@@ -165,15 +165,11 @@ INFO is the export state, as a property list."
                          (org-cite-biblatex--atomic-arguments (list r) info))
                        (org-cite-get-references citation)
                        "")
-            ;; According to biblatex manual, left braces or brackets
+            ;; According to BibLaTeX manual, left braces or brackets
             ;; following a multicite command could be parsed as other
-            ;; arguments. So we look ahead and insert a \relax if
-            ;; needed.
-            (and (let ((next (org-export-get-next-element citation info)))
-                   (and next
-                        (string-match (rx string-start (or "{" "["))
-                                      (org-export-data next info))))
-                 "\\relax"))))
+            ;; arguments. So we stop any further parsing by inserting
+            ;; a \relax unconditionally.
+            "\\relax")))
 
 (defun org-cite-biblatex--command (citation info base &optional multi no-opt)
   "Return biblatex command using BASE name for CITATION object.

+ 13 - 3
lisp/oc.el

@@ -89,7 +89,6 @@
 (declare-function org-element-type "org-element" (element))
 
 (declare-function org-export-derived-backend-p "org-export" (backend &rest backends))
-(declare-function org-export-get-footnote-definition "org-export" (footnote-reference info))
 (declare-function org-export-get-next-element "org-export" (blob info &optional n))
 (declare-function org-export-get-previous-element "org-export" (blob info &optional n))
 (declare-function org-export-raw-string "org-export" (s))
@@ -799,9 +798,20 @@ INFO is the export communication channel, as a property list."
 		        ;; Do not force entering inline definitions, since
 		        ;; `org-element-map' is going to enter it anyway.
                         ((guard (eq 'inline (org-element-property :type datum))))
+                        ;; Find definition for current standard
+                        ;; footnote reference.  Unlike to
+                        ;; `org-export-get-footnote-definition', do
+                        ;; not cache results as they would contain
+                        ;; un-processed citation objects.
                         (_
-                         (funcall search-cites
-                                  (org-export-get-footnote-definition datum info)))))
+                         (let ((label (org-element-property :label datum)))
+                           (funcall
+                            search-cites
+                            (org-element-map data 'footnote-definition
+                              (lambda (d)
+                                (and
+                                 (equal label (org-element-property :label d))
+                                 (or (org-element-contents d) "")))))))))
                     info nil 'footnote-definition t))))
         (funcall search-cites (plist-get info :parse-tree))
         (let ((result (nreverse cites)))