|  | @@ -42,6 +42,7 @@
 | 
	
		
			
				|  |  |  (declare-function org-mark-ring-push "org" (&optional pos buffer))
 | 
	
		
			
				|  |  |  (declare-function outline-next-heading "outline")
 | 
	
		
			
				|  |  |  (declare-function org-trim "org" (s))
 | 
	
		
			
				|  |  | +(declare-function org-show-context "org" (&optional key))
 | 
	
		
			
				|  |  |  (declare-function org-back-to-heading "org" (&optional invisible-ok))
 | 
	
		
			
				|  |  |  (declare-function org-end-of-subtree "org"  (&optional invisible-ok to-heading))
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -66,13 +67,14 @@ This can be nil, to place footnotes locally at the end of the current
 | 
	
		
			
				|  |  |  outline node.  If can also be the name of a special outline heading
 | 
	
		
			
				|  |  |  under which footnotes should be put.
 | 
	
		
			
				|  |  |  This variable defines the place where Org puts the definition
 | 
	
		
			
				|  |  | -automatically.  However, by hand you may place definitions *anywhere*.
 | 
	
		
			
				|  |  | +automatically, i.e. when creating the footnote, and when sorting the notes.
 | 
	
		
			
				|  |  | +However, by hand you may place definitions *anywhere*.
 | 
	
		
			
				|  |  |  If this is a string, during export, all subtrees starting with this
 | 
	
		
			
				|  |  |  heading will be removed after extracting footnote definitions."
 | 
	
		
			
				|  |  |    :group 'org-footnotes
 | 
	
		
			
				|  |  |    :type '(choice
 | 
	
		
			
				|  |  | -	  (string :tag "Special outline node name")
 | 
	
		
			
				|  |  | -	  (const :tag "Define footnotes in the current outline node" nil)))
 | 
	
		
			
				|  |  | +	  (string :tag "Collect fotnotes under heading")
 | 
	
		
			
				|  |  | +	  (const :tag "Define footnotes locally" nil)))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  (defcustom org-footnote-tag-for-non-org-mode-files "Footnotes:"
 | 
	
		
			
				|  |  |    "Tag marking the beginning of footnote section.
 | 
	
	
		
			
				|  | @@ -109,6 +111,14 @@ plain      Automatically create plain number labels like [1]"
 | 
	
		
			
				|  |  |  	  (const :tag "Offer automatic [fn:N] for editing" confirm)
 | 
	
		
			
				|  |  |  	  (const :tag "Create automatic [N]" plain)))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +(defcustom org-footnote-fill-after-inline-note-extraction nil
 | 
	
		
			
				|  |  | +  "Non-nil means, fill paragraphs after extracting footnotes.
 | 
	
		
			
				|  |  | +When extracting inline footnotes, the lengths of lines can change a lot.
 | 
	
		
			
				|  |  | +When this option is set, paragraphs from which an inline footnote has been
 | 
	
		
			
				|  |  | +extracted will be filled again."
 | 
	
		
			
				|  |  | +  :group 'org-footnote
 | 
	
		
			
				|  |  | +  :type 'boolean)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  (defun org-footnote-at-reference-p ()
 | 
	
		
			
				|  |  |    "Is the cursor at a footnote reference?
 | 
	
		
			
				|  |  |  If yes, return the beginning position, the label, and the definition, if local."
 | 
	
	
		
			
				|  | @@ -249,7 +259,7 @@ or new, let the user edit the definition of the footnote."
 | 
	
		
			
				|  |  |      (cond
 | 
	
		
			
				|  |  |       ((org-mode-p)
 | 
	
		
			
				|  |  |        (if (not org-footnote-section)
 | 
	
		
			
				|  |  | -	  ;; No section, put foornote into the curren outline node
 | 
	
		
			
				|  |  | +	  ;; No section, put footnote into the current outline node
 | 
	
		
			
				|  |  |  	  nil
 | 
	
		
			
				|  |  |  	;; Try to find or make the special node
 | 
	
		
			
				|  |  |  	(setq re (concat "^\\*+[ \t]+" org-footnote-section "[ \t]*$"))
 | 
	
	
		
			
				|  | @@ -259,10 +269,7 @@ or new, let the user edit the definition of the footnote."
 | 
	
		
			
				|  |  |  	  (goto-char (point-max))
 | 
	
		
			
				|  |  |  	  (insert "\n\n* " org-footnote-section)))
 | 
	
		
			
				|  |  |        ;; Now go to the end of this entry and insert there.
 | 
	
		
			
				|  |  | -      (outline-next-heading)
 | 
	
		
			
				|  |  | -      (setq p (point))
 | 
	
		
			
				|  |  | -      (skip-chars-backward " \t\n\r")
 | 
	
		
			
				|  |  | -      (delete-region (point) p))
 | 
	
		
			
				|  |  | +      (org-footnote-goto-local-insertion-point))
 | 
	
		
			
				|  |  |       (t
 | 
	
		
			
				|  |  |        (setq re (concat "^" org-footnote-tag-for-non-org-mode-files "[ \t]*$"))
 | 
	
		
			
				|  |  |        (unless (re-search-forward re nil t)
 | 
	
	
		
			
				|  | @@ -272,10 +279,8 @@ or new, let the user edit the definition of the footnote."
 | 
	
		
			
				|  |  |  	(delete-region (point) (point-max))
 | 
	
		
			
				|  |  |  	(insert org-footnote-tag-for-non-org-mode-files "\n"))
 | 
	
		
			
				|  |  |        (goto-char (point-max))
 | 
	
		
			
				|  |  | -      (skip-chars-backward " \t\r\n")
 | 
	
		
			
				|  |  | -      (delete-region (point) (point-max))))
 | 
	
		
			
				|  |  | -    (insert "\n\n\n")
 | 
	
		
			
				|  |  | -    (backward-char 1)
 | 
	
		
			
				|  |  | +      (skip-chars-backward " \t\r\n")))
 | 
	
		
			
				|  |  | +    (insert "\n\n")
 | 
	
		
			
				|  |  |      (insert "[" label "] ")
 | 
	
		
			
				|  |  |      (message "Edit definition and go back with `C-c &' or, if unique, with `C-c C-c'.")))
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -317,19 +322,22 @@ Org-mode exporters.
 | 
	
		
			
				|  |  |  When SORT-ONLY is set, only sort the footnote definitions into the
 | 
	
		
			
				|  |  |  referenced sequence."
 | 
	
		
			
				|  |  |    ;; This is based on Paul's function, but rewritten.
 | 
	
		
			
				|  |  | -  (let ((count 0) ref def ref-table liste beg beg1 ref def marker a before
 | 
	
		
			
				|  |  | +  (let ((count 0) ref def idef ref-table liste beg beg1 marker a before
 | 
	
		
			
				|  |  |  	ins-point)
 | 
	
		
			
				|  |  |       (save-excursion
 | 
	
		
			
				|  |  | -      ;; Now find footnote references,
 | 
	
		
			
				|  |  | +      ;; Now find footnote references, and extract the definitions
 | 
	
		
			
				|  |  |        (goto-char (point-min))
 | 
	
		
			
				|  |  |        (while (re-search-forward org-footnote-re nil t)
 | 
	
		
			
				|  |  |  	(org-if-unprotected
 | 
	
		
			
				|  |  |  	 (setq def (match-string 4)
 | 
	
		
			
				|  |  | +	       idef def
 | 
	
		
			
				|  |  |  	       ref (or (match-string 1) (match-string 2))
 | 
	
		
			
				|  |  |  	       before (char-to-string (char-after (match-beginning 0))))
 | 
	
		
			
				|  |  |  	 (if (equal ref "fn:") (setq ref nil))
 | 
	
		
			
				|  |  |  	 (if (and ref (setq a (assoc ref ref-table)))
 | 
	
		
			
				|  |  | -	     (setq marker (nth 1 a))
 | 
	
		
			
				|  |  | +	     (progn
 | 
	
		
			
				|  |  | +	       (setq marker (nth 1 a))
 | 
	
		
			
				|  |  | +	       (unless (nth 2 a) (setf (caddr a) def)))
 | 
	
		
			
				|  |  |  	   (setq marker (number-to-string (incf count))))
 | 
	
		
			
				|  |  |  	 (save-match-data
 | 
	
		
			
				|  |  |  	   (if def
 | 
	
	
		
			
				|  | @@ -337,8 +345,7 @@ referenced sequence."
 | 
	
		
			
				|  |  |  	     (save-excursion
 | 
	
		
			
				|  |  |  	       (if (not (re-search-forward (concat "^\\[" (regexp-quote ref)
 | 
	
		
			
				|  |  |  						   "\\]") nil t))
 | 
	
		
			
				|  |  | -		   (setq def
 | 
	
		
			
				|  |  | -			 (format "FOOTNOTE DEFINITION NOT FOUND: %s" ref))
 | 
	
		
			
				|  |  | +		   (setq def nil)
 | 
	
		
			
				|  |  |  		 (setq beg (match-beginning 0))
 | 
	
		
			
				|  |  |  		 (setq beg1 (match-end 0))
 | 
	
		
			
				|  |  |  		 (re-search-forward
 | 
	
	
		
			
				|  | @@ -346,7 +353,11 @@ referenced sequence."
 | 
	
		
			
				|  |  |  		  nil 'move)
 | 
	
		
			
				|  |  |  		 (setq def (buffer-substring beg1 (match-beginning 0)))
 | 
	
		
			
				|  |  |  		 (delete-region beg (match-beginning 0))))))
 | 
	
		
			
				|  |  | -	 (unless sort-only (replace-match (concat before "[" marker "]")))
 | 
	
		
			
				|  |  | +	 (unless sort-only
 | 
	
		
			
				|  |  | +	   (replace-match (concat before "[" marker "]"))
 | 
	
		
			
				|  |  | +	   (and idef
 | 
	
		
			
				|  |  | +		org-footnote-fill-after-inline-note-extraction
 | 
	
		
			
				|  |  | +		(fill-paragraph)))
 | 
	
		
			
				|  |  |  	 (if (not a) (push (list ref marker def) ref-table))))
 | 
	
		
			
				|  |  |        
 | 
	
		
			
				|  |  |        ;; First find and remove the footnote section
 | 
	
	
		
			
				|  | @@ -358,7 +369,7 @@ referenced sequence."
 | 
	
		
			
				|  |  |  		  (concat "^\\*[ \t]+" (regexp-quote org-footnote-section)
 | 
	
		
			
				|  |  |  			  "[ \t]*$")
 | 
	
		
			
				|  |  |  		  nil t))
 | 
	
		
			
				|  |  | -	    (if for-preprocessor
 | 
	
		
			
				|  |  | +	    (if (or for-preprocessor (not org-footnote-section))
 | 
	
		
			
				|  |  |  		(replace-match "")
 | 
	
		
			
				|  |  |  	      (org-back-to-heading t)
 | 
	
		
			
				|  |  |  	      (forward-line 1)
 | 
	
	
		
			
				|  | @@ -381,24 +392,67 @@ referenced sequence."
 | 
	
		
			
				|  |  |  	(delete-region (point) (point-max))
 | 
	
		
			
				|  |  |  	(insert "\n\n" org-footnote-tag-for-non-org-mode-files "\n")
 | 
	
		
			
				|  |  |  	(setq ins-point (point))))
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +      
 | 
	
		
			
				|  |  |        ;; Insert the footnotes again
 | 
	
		
			
				|  |  |        (goto-char (or ins-point (point-max)))
 | 
	
		
			
				|  |  |        (setq ref-table (reverse ref-table))
 | 
	
		
			
				|  |  |        (when sort-only
 | 
	
		
			
				|  |  | +	;; remove anonymous fotnotes from the list
 | 
	
		
			
				|  |  |  	(setq ref-table
 | 
	
		
			
				|  |  |  	      (delq nil (mapcar
 | 
	
		
			
				|  |  |  			 (lambda (x) (and (car x)
 | 
	
		
			
				|  |  |  					  (not (equal (car x) "fn:"))
 | 
	
		
			
				|  |  |  					  x))
 | 
	
		
			
				|  |  |  			 ref-table))))
 | 
	
		
			
				|  |  | -      (setq def
 | 
	
		
			
				|  |  | -	    (mapconcat
 | 
	
		
			
				|  |  | +      ;; Make sure each footnote has a description, or an error message.
 | 
	
		
			
				|  |  | +      (setq ref-table
 | 
	
		
			
				|  |  | +	    (mapcar
 | 
	
		
			
				|  |  |  	     (lambda (x)
 | 
	
		
			
				|  |  | -	       (format "[%s] %s" (nth (if sort-only 0 1) x)
 | 
	
		
			
				|  |  | -		       (org-trim (nth 2 x))))
 | 
	
		
			
				|  |  | -	     ref-table "\n\n"))
 | 
	
		
			
				|  |  | -      (if ref-table (insert "\n" def "\n\n")))))
 | 
	
		
			
				|  |  | +	       (if (not (nth 2 x))
 | 
	
		
			
				|  |  | +		   (setcar (cddr x)
 | 
	
		
			
				|  |  | +			   (format "FOOTNOTE DEFINITION NOT FOUND: %s" (car x)))
 | 
	
		
			
				|  |  | +		 (setcar (cddr x) (org-trim (nth 2 x))))
 | 
	
		
			
				|  |  | +	       x)
 | 
	
		
			
				|  |  | +	     ref-table))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      (if (or (not (org-mode-p))     ; not an Org file
 | 
	
		
			
				|  |  | +	      org-footnote-section   ; we do not use a footnote section
 | 
	
		
			
				|  |  | +	      (not sort-only)	     ; this is normalization
 | 
	
		
			
				|  |  | +	      for-preprocessor)       ; the is the preprocessor
 | 
	
		
			
				|  |  | +	  ;; Insert the footnotes together in one place
 | 
	
		
			
				|  |  | +	  (progn
 | 
	
		
			
				|  |  | +	    (setq def
 | 
	
		
			
				|  |  | +		  (mapconcat
 | 
	
		
			
				|  |  | +		   (lambda (x)
 | 
	
		
			
				|  |  | +		     (format "[%s] %s" (nth (if sort-only 0 1) x)
 | 
	
		
			
				|  |  | +			     (org-trim (nth 2 x))))
 | 
	
		
			
				|  |  | +		   ref-table "\n\n"))
 | 
	
		
			
				|  |  | +	    (if ref-table (insert "\n" def "\n\n")))
 | 
	
		
			
				|  |  | +	;; Insert each footnote near the first reference
 | 
	
		
			
				|  |  | +	;; Happens only in Org files with no special footnote section,
 | 
	
		
			
				|  |  | +	;; and only when doing sorting
 | 
	
		
			
				|  |  | +	(mapc 'org-insert-footnote-reference-near-definition
 | 
	
		
			
				|  |  | +	      ref-table)))))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +(defun org-insert-footnote-reference-near-definition (entry)
 | 
	
		
			
				|  |  | +  "Find first reference of footnote ENTRY and insert the definition there.
 | 
	
		
			
				|  |  | +ENTRY is (fn-label num-mark definition)."
 | 
	
		
			
				|  |  | +  (when (car entry)
 | 
	
		
			
				|  |  | +    (let ((pos (point)))
 | 
	
		
			
				|  |  | +      (goto-char (point-min))
 | 
	
		
			
				|  |  | +      (when (re-search-forward (format ".\\[%s[]:]" (regexp-quote (car entry)))
 | 
	
		
			
				|  |  | +			       nil t)
 | 
	
		
			
				|  |  | +	(org-footnote-goto-local-insertion-point)
 | 
	
		
			
				|  |  | +	(insert (format "\n\n[%s] %s" (car entry) (nth 2 entry)))))))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +(defun org-footnote-goto-local-insertion-point ()
 | 
	
		
			
				|  |  | +  "Find insertion point for footnote, just before next outline heading."
 | 
	
		
			
				|  |  | +  (outline-next-heading)
 | 
	
		
			
				|  |  | +  (beginning-of-line 0)
 | 
	
		
			
				|  |  | +  (while (and (not (bobp)) (= (char-after) ?#))
 | 
	
		
			
				|  |  | +    (beginning-of-line 0))
 | 
	
		
			
				|  |  | +  (if (looking-at "#\\+TBLFM:") (beginning-of-line 2))
 | 
	
		
			
				|  |  | +  (skip-chars-backward "\n\r\t "))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  (defun org-footnote-delete (&optional label)
 | 
	
		
			
				|  |  |    "Delete the footnote at point.
 | 
	
	
		
			
				|  | @@ -439,4 +493,4 @@ and all references of a footnote label."
 | 
	
		
			
				|  |  |  (provide 'org-footnote)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ;; arch-tag: 1b5954df-fb5d-4da5-8709-78d944dbfc37
 | 
	
		
			
				|  |  | -;;; org-footnote.el ends here
 | 
	
		
			
				|  |  | +;;; org-footnote.el ends here
 |