Nicolas Goaziou <m...@nicolasgoaziou.fr> writes:

> Rasmus <ras...@gmx.us> writes:
>
>> Could we inject labels in all footnotes?  If so we could simply use
>>
>>    \textsuperscript{\ref{FN-LABEL}}
>>
>> In place of
>>
>>    \footnotemark[FN-GUESS]{}
>>
>> It seems \footref of scrextend.sty has some extra robustness built into it
>> but until someone complains I think the \textsuperscript hack should be
>> enough and better then what we’ve got.
>
> That's a bit hackish, but definitely possible. Do yo want to provide
> a patch?

With the attached patch ox-latex seems to behave in this way.  Though
perhaps there’s a more efficient way to get the first footnote-reference
to a given definition than trawling through with
org-export--footnote-reference-map.

Nicolas, where is the info plist documented or defined/populated?

Rasmus

-- 
Together we will make the possible totalllly impossible!
>From 07f15d538aa02d5b45fa545395442f5663260430 Mon Sep 17 00:00:00 2001
From: Rasmus <ras...@gmx.us>
Date: Sun, 22 May 2016 20:33:06 +0200
Subject: [PATCH] ox-latex: More robust footnote referencing

* lisp/ox-latex.el (org-latex--label): Prefix footnote with "fn".
(org-latex--delayed-footnotes-definitions): Fix typo in docstring.
(org-latex-footnote-reference): Use \ref{.} and \label{.} for repeated
references.
---
 lisp/ox-latex.el | 72 ++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 47 insertions(+), 25 deletions(-)

diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index 9c31645..3c66a32 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1246,6 +1246,8 @@ Eventually, if FULL is non-nil, wrap label within \"\\label{}\"."
 				  org-latex-math-environments-re
 				  (org-element-property :value datum))
 				 "eq:"))
+			   (footnote-reference "fn:")
+			   (footnote-definition "fn:")
 			   (paragraph
 			    (and (org-element-property :caption datum)
 				 "fig:")))
@@ -1498,7 +1500,7 @@ INFO is a plist used as a communication channel.  See
 
 INFO is a plist used as a communication channel.
 
-Footnotes definitions are returned within \"\\footnotetxt{}\"
+Footnotes definitions are returned within \"\\footnotetext{}\"
 commands.
 
 This function is used within constructs that don't support
@@ -1803,30 +1805,50 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
 (defun org-latex-footnote-reference (footnote-reference _contents info)
   "Transcode a FOOTNOTE-REFERENCE element from Org to LaTeX.
 CONTENTS is nil.  INFO is a plist holding contextual information."
-  (concat
-   ;; Insert separator between two footnotes in a row.
-   (let ((prev (org-export-get-previous-element footnote-reference info)))
-     (when (eq (org-element-type prev) 'footnote-reference)
-       (plist-get info :latex-footnote-separator)))
-   (cond
-    ;; Use \footnotemark if the footnote has already been defined.
-    ((not (org-export-footnote-first-reference-p footnote-reference info))
-     (format "\\footnotemark[%s]{}"
-	     (org-export-get-footnote-number footnote-reference info)))
-    ;; Use \footnotemark if reference is within another footnote
-    ;; reference, footnote definition or table cell.
-    ((org-element-lineage footnote-reference
-			  '(footnote-reference footnote-definition table-cell))
-     "\\footnotemark")
-    ;; Otherwise, define it with \footnote command.
-    (t
-     (let ((def (org-export-get-footnote-definition footnote-reference info)))
-       (concat
-	(format "\\footnote{%s}" (org-trim (org-export-data def info)))
-	;; Retrieve all footnote references within the footnote and
-	;; add their definition after it, since LaTeX doesn't support
-	;; them inside.
-	(org-latex--delayed-footnotes-definitions def info)))))))
+  (let ((label (org-element-property :label footnote-reference)))
+    (concat
+     ;; Insert separator between two footnotes in a row.
+     (let ((prev (org-export-get-previous-element footnote-reference info)))
+       (when (eq (org-element-type prev) 'footnote-reference)
+	 (plist-get info :latex-footnote-separator)))
+     (cond
+      ;; Use \footnotemark if the footnote has already been defined.
+      ((not (org-export-footnote-first-reference-p footnote-reference info))
+       (format "\\textsuperscript{\\ref{%s}}"
+	       (org-latex--label
+		(catch 'exit
+		  (org-export--footnote-reference-map
+		   (lambda (f)
+		     (let ((l (org-element-property :label f)))
+		       (when (and l label (string= label l))
+			 (throw 'exit f))))
+		   (plist-get info :parse-tree) info))
+		info t)))
+      ;; Use \footnotemark if reference is within another footnote
+      ;; reference, footnote definition or table cell.
+      ((org-element-lineage footnote-reference
+			    '(footnote-reference footnote-definition table-cell))
+       "\\footnotemark")
+      ;; Otherwise, define it with \footnote command.
+      (t
+       (let ((def (org-export-get-footnote-definition footnote-reference info)))
+	 (concat
+	  (format "\\footnote{%s%s}" (org-trim (org-export-data def info))
+		  (if (catch 'exit
+			(org-export--footnote-reference-map
+			 (lambda (f)
+			   (let ((l (org-element-property :label f)))
+			     (when (and l label
+					(not (eq f footnote-reference))
+					(string= label l))
+			       (throw 'exit t))))
+			 (plist-get info :parse-tree) info))
+		      (org-latex--label footnote-reference info t t)
+		    ""))
+	  ;; Retrieve all footnote references within the footnote and
+	  ;; add their definition after it, since LaTeX doesn't support
+	  ;; them inside.
+	  (org-latex--delayed-footnotes-definitions def info))))))))
 
 
 ;;;; Headline
-- 
2.8.2

Reply via email to