Browse Source

org-footnote: add more checks to avoid false-positives

* lisp/org-footnote.el (org-footnote-at-reference-p): test if match is
  in cited text, when replying to a message.
(org-footnote-new): do not create a new footnote at bol, as it might
be seen as a definition.
(org-footnote-at-definition-p): ignore definitions in forbidden
blocks, as it is already the case for references.
Nicolas Goaziou 14 years ago
parent
commit
6278c73cdb
1 changed files with 51 additions and 44 deletions
  1. 51 44
      lisp/org-footnote.el

+ 51 - 44
lisp/org-footnote.el

@@ -199,23 +199,29 @@ positions, and the definition, when inlined."
 	   ;; get fooled by unrelated closing square brackets.
 	   ;; get fooled by unrelated closing square brackets.
 	   (end (ignore-errors (scan-sexps beg 1))))
 	   (end (ignore-errors (scan-sexps beg 1))))
       ;; Point is really at a reference if it's located before true
       ;; Point is really at a reference if it's located before true
-      ;; ending of the footnote and isn't within a link or a LaTeX
-      ;; macro.  About that case, some special attention should be
-      ;; paid.  Indeed, when two footnotes are side by side, once the
-      ;; first one is changed into LaTeX, the second one might then be
-      ;; considered as an optional argument of the command.  To
-      ;; prevent that, we have a look at the `org-protected' property
-      ;; of that LaTeX command.
-      (when (and end (< (point) end)
-		 (not (save-excursion
-			(goto-char beg)
-			(let ((linkp
-			       (save-match-data
-				 (org-in-regexp org-bracket-link-regexp))))
-			  (and linkp (< (point) (cdr linkp))))))
-		 (or (not (org-inside-latex-macro-p))
-		     (and (get-text-property (1- beg) 'org-protected)
-			  (not (get-text-property beg 'org-protected)))))
+      ;; ending of the footnote.
+      (when (save-match-data
+	      (and end (< (point) end)
+		   ;; Verify match isn't a part of a link.
+		   (not (save-excursion
+			  (goto-char beg)
+			  (let ((linkp (org-in-regexp org-bracket-link-regexp)))
+			    (and linkp (< (point) (cdr linkp))))))
+		   ;; When in message-mode, verify match doesn't belong
+		   ;; to cited text.
+		   (not (and (derived-mode-p 'message-mode)
+			     (save-excursion
+			       (beginning-of-line)
+			       (looking-at message-cite-prefix-regexp))))
+		   ;; Verify point doesn't belong to a LaTeX macro.
+		   ;; Beware though, when two footnotes are side by
+		   ;; side, once the first one is changed into LaTeX,
+		   ;; the second one might then be considered as an
+		   ;; optional argument of the command.  Thus, check
+		   ;; the `org-protected' property of that command.
+		   (or (not (org-inside-latex-macro-p))
+		       (and (get-text-property (1- beg) 'org-protected)
+			    (not (get-text-property beg 'org-protected))))))
 	(list label beg end
 	(list label beg end
 	      ;; Definition: ensure this is an inline footnote first.
 	      ;; Definition: ensure this is an inline footnote first.
 	      (and (or (not label) (match-string 1))
 	      (and (or (not label) (match-string 1))
@@ -230,32 +236,33 @@ footnote text is included and defined locally.
 
 
 The return value will be nil if not at a footnote definition, and a list with
 The return value will be nil if not at a footnote definition, and a list with
 label, start, end and definition of the footnote otherwise."
 label, start, end and definition of the footnote otherwise."
-  (save-excursion
-    (end-of-line)
-    (let ((lim (save-excursion (re-search-backward
-				(concat org-outline-regexp-bol
-					"\\|^[ \t]*$") nil t))))
-      (when (re-search-backward org-footnote-definition-re lim t)
-	(end-of-line)
-	(list (match-string 2)
-	      (match-beginning 0)
-	      (save-match-data
-		;; In a message, limit search to signature.
-		(let ((bound (and (derived-mode-p 'message-mode)
-				  (save-excursion
-				    (goto-char (point-max))
-				    (re-search-backward
-				     message-signature-separator nil t)))))
-		  (or (and (re-search-forward
-			    (org-re
-			     (concat "^[ \t]*$" "\\|"
-				     org-outline-regexp-bol
-				     "\\|"
-				     "^\\[\\([0-9]+\\|fn:[-_[:word:]]+\\)\\]"))
-			    bound 'move)
-			   (progn (skip-chars-forward " \t\n") (point-at-bol)))
-		      (point))))
-	      (org-trim (buffer-substring (match-end 0) (point))))))))
+  (when (org-footnote-in-valid-context-p)
+    (save-excursion
+      (end-of-line)
+      (let ((lim (save-excursion (re-search-backward
+				  (concat org-outline-regexp-bol
+					  "\\|^[ \t]*$") nil t))))
+	(when (re-search-backward org-footnote-definition-re lim t)
+	  (end-of-line)
+	  (list (match-string 2)
+		(match-beginning 0)
+		(save-match-data
+		  ;; In a message, limit search to signature.
+		  (let ((bound (and (derived-mode-p 'message-mode)
+				    (save-excursion
+				      (goto-char (point-max))
+				      (re-search-backward
+				       message-signature-separator nil t)))))
+		    (or (and (re-search-forward
+			      (org-re
+			       (concat "^[ \t]*$" "\\|"
+				       org-outline-regexp-bol
+				       "\\|"
+				       "^\\[\\([0-9]+\\|fn:[-_[:word:]]+\\)\\]"))
+			      bound 'move)
+			     (progn (skip-chars-forward " \t\n") (point-at-bol)))
+			(point))))
+		(org-trim (buffer-substring (match-end 0) (point)))))))))
 
 
 (defun org-footnote-get-next-reference (&optional label backward limit)
 (defun org-footnote-get-next-reference (&optional label backward limit)
   "Return complete reference of the next footnote.
   "Return complete reference of the next footnote.
@@ -414,7 +421,7 @@ This command prompts for a label.  If this is a label referencing an
 existing label, only insert the label.  If the footnote label is empty
 existing label, only insert the label.  If the footnote label is empty
 or new, let the user edit the definition of the footnote."
 or new, let the user edit the definition of the footnote."
   (interactive)
   (interactive)
-  (unless (org-footnote-in-valid-context-p)
+  (unless (and (not (bolp)) (org-footnote-in-valid-context-p))
     (error "Cannot insert a footnote here"))
     (error "Cannot insert a footnote here"))
   (let* ((labels (and (not (equal org-footnote-auto-label 'random))
   (let* ((labels (and (not (equal org-footnote-auto-label 'random))
 		      (org-footnote-all-labels)))
 		      (org-footnote-all-labels)))