Browse Source

Forbid footnotes in some contexts

* lisp/org.el (org-in-block-p): new function.
* lisp/org-footnote.el (org-footnote-forbidden-blocks): new variable.
(org-footnote-in-valid-context-p): new function.
(org-footnote-at-reference-p): use new function. Allow inline
footnotes to start at bol.
Nicolas Goaziou 13 years ago
parent
commit
abe9550309
2 changed files with 39 additions and 5 deletions
  1. 23 5
      lisp/org-footnote.el
  2. 16 0
      lisp/org.el

+ 23 - 5
lisp/org-footnote.el

@@ -39,7 +39,9 @@
 (require 'org-compat)
 (require 'org-compat)
 
 
 (declare-function org-in-commented-line "org" ())
 (declare-function org-in-commented-line "org" ())
+(declare-function org-in-indented-comment-line "org" ())
 (declare-function org-in-regexp "org" (re &optional nlines visually))
 (declare-function org-in-regexp "org" (re &optional nlines visually))
+(declare-function org-in-block-p "org" (names))
 (declare-function org-mark-ring-push "org" (&optional pos buffer))
 (declare-function org-mark-ring-push "org" (&optional pos buffer))
 (declare-function outline-next-heading "outline")
 (declare-function outline-next-heading "outline")
 (declare-function org-trim "org" (s))
 (declare-function org-trim "org" (s))
@@ -51,6 +53,7 @@
 (declare-function org-id-uuid "org" ())
 (declare-function org-id-uuid "org" ())
 (declare-function org-fill-paragraph "org" (&optional justify))
 (declare-function org-fill-paragraph "org" (&optional justify))
 (defvar org-odd-levels-only) ;; defined in org.el
 (defvar org-odd-levels-only) ;; defined in org.el
+(defvar org-bracket-link-regexp) ; defined in org.el
 (defvar message-signature-separator) ;; defined in message.el
 (defvar message-signature-separator) ;; defined in message.el
 
 
 (defconst org-footnote-re
 (defconst org-footnote-re
@@ -72,6 +75,11 @@
   (org-re "^\\(\\[\\([0-9]+\\|fn:[-_[:word:]]+\\)\\]\\)")
   (org-re "^\\(\\[\\([0-9]+\\|fn:[-_[:word:]]+\\)\\]\\)")
   "Regular expression matching the definition of a footnote.")
   "Regular expression matching the definition of a footnote.")
 
 
+(defvar org-footnote-forbidden-blocks '("example" "verse" "src"
+					"latex" "html" "docbook")
+  "Names of blocks where footnotes are not allowed.
+Names must be in lower case.")
+
 (defgroup org-footnote nil
 (defgroup org-footnote nil
   "Footnotes in Org-mode."
   "Footnotes in Org-mode."
   :tag "Org Footnote"
   :tag "Org Footnote"
@@ -154,19 +162,29 @@ extracted will be filled again."
   :group 'org-footnote
   :group 'org-footnote
   :type 'boolean)
   :type 'boolean)
 
 
-(defvar org-bracket-link-regexp) ; silent compiler
+(defun org-footnote-in-valid-context-p ()
+  "Is point in a context where footnotes are allowed?"
+  (not (or (org-in-commented-line)
+	   (org-in-indented-comment-line)
+	   (org-in-verbatim-emphasis)
+	   ;; No footnote in literal example.
+	   (save-excursion
+	     (beginning-of-line)
+	     (looking-at "[ \t]*:[ \t]+"))
+	   (org-in-block-p org-footnote-forbidden-blocks))))
+
 (defun org-footnote-at-reference-p ()
 (defun org-footnote-at-reference-p ()
   "Is the cursor at a footnote reference?
   "Is the cursor at a footnote reference?
 
 
 If so, return an list containing its label, beginning and ending
 If so, return an list containing its label, beginning and ending
 positions, and the definition, if local."
 positions, and the definition, if local."
-  (when (and (not (or (org-in-commented-line)
-		      (org-in-verbatim-emphasis)))
+  (when (and (org-footnote-in-valid-context-p)
 	     (or (looking-at org-footnote-re)
 	     (or (looking-at org-footnote-re)
 		 (org-in-regexp org-footnote-re)
 		 (org-in-regexp org-footnote-re)
 		 (save-excursion (re-search-backward org-footnote-re nil t)))
 		 (save-excursion (re-search-backward org-footnote-re nil t)))
-	     ;; A footnote reference cannot start at bol.
-	     (/= (match-beginning 0) (point-at-bol)))
+	     ;; Only inline footnotes can start at bol.
+	     (or (eq (char-before (match-end 0)) 58)
+		 (/= (match-beginning 0) (point-at-bol))))
     (let* ((beg (match-beginning 0))
     (let* ((beg (match-beginning 0))
 	   (label (or (match-string 2) (match-string 3)
 	   (label (or (match-string 2) (match-string 3)
 		      ;; Anonymous footnotes don't have labels
 		      ;; Anonymous footnotes don't have labels

+ 16 - 0
lisp/org.el

@@ -18915,6 +18915,22 @@ defaults to previous heading or `point-min'."
 	       ;; ... but no end-re between start-re and point.
 	       ;; ... but no end-re between start-re and point.
 	       (not (re-search-forward (eval end-re) pos t)))))))
 	       (not (re-search-forward (eval end-re) pos t)))))))
 
 
+(defun org-in-block-p (names)
+  "Is point inside any block whose name belongs to NAMES?
+
+NAMES is a list of strings containing names of blocks."
+  (save-match-data
+    (catch 'exit
+      (let ((case-fold-search t))
+	(mapc (lambda (name)
+		(let ((n (regexp-quote name)))
+		  (when (org-in-regexps-block-p
+			 (concat "^[ \t]*#\\+begin_" n)
+			 (concat "^[ \t]*#\\+end_" n))
+		    (throw 'exit t))))
+	      names))
+      nil)))
+
 (defun org-occur-in-agenda-files (regexp &optional nlines)
 (defun org-occur-in-agenda-files (regexp &optional nlines)
   "Call `multi-occur' with buffers for all agenda files."
   "Call `multi-occur' with buffers for all agenda files."
   (interactive "sOrg-files matching: \np")
   (interactive "sOrg-files matching: \np")