diff options
author | Bastien Guerry <bastien1@free.fr> | 2012-01-03 18:27:21 +0100 |
---|---|---|
committer | Bastien Guerry <bastien1@free.fr> | 2012-01-03 18:27:21 +0100 |
commit | e66ba1dfc4cf2e12100191d2c24436c42d097268 (patch) | |
tree | b50b009e703fe1a9e8cb13cddf7928a97ad6210c /lisp/org/org-footnote.el | |
parent | 88c5c7c8313162b94173fd4333e6062aa07c4d2e (diff) | |
download | emacs-e66ba1dfc4cf2e12100191d2c24436c42d097268.tar.gz emacs-e66ba1dfc4cf2e12100191d2c24436c42d097268.tar.bz2 emacs-e66ba1dfc4cf2e12100191d2c24436c42d097268.zip |
Merge Org 7.8.03
Diffstat (limited to 'lisp/org/org-footnote.el')
-rw-r--r-- | lisp/org/org-footnote.el | 400 |
1 files changed, 228 insertions, 172 deletions
diff --git a/lisp/org/org-footnote.el b/lisp/org/org-footnote.el index 0d47132d2f8..a8125513db6 100644 --- a/lisp/org/org-footnote.el +++ b/lisp/org/org-footnote.el @@ -5,7 +5,6 @@ ;; Author: Carsten Dominik <carsten at orgmode dot org> ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.7 ;; ;; This file is part of GNU Emacs. ;; @@ -38,28 +37,33 @@ (require 'org-macs) (require 'org-compat) +(declare-function message-point-in-header-p "message" ()) +(declare-function org-back-over-empty-lines "org" ()) +(declare-function org-back-to-heading "org" (&optional invisible-ok)) (declare-function org-combine-plists "org" (&rest plists)) +(declare-function org-end-of-subtree "org" (&optional invisible-ok to-heading)) +(declare-function org-export-preprocess-string "org-exp" + (string &rest parameters)) +(declare-function org-fill-paragraph "org" (&optional justify)) +(declare-function org-icompleting-read "org" (&rest args)) +(declare-function org-id-uuid "org-id" ()) +(declare-function org-in-block-p "org" (names)) (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-block-p "org" (names)) -(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)) (declare-function org-in-verbatim-emphasis "org" ()) +(declare-function org-inside-LaTeX-fragment-p "org" ()) (declare-function org-inside-latex-macro-p "org" ()) -(declare-function org-id-uuid "org" ()) -(declare-function org-fill-paragraph "org" (&optional justify)) -(declare-function org-export-preprocess-string "org-exp" - (string &rest parameters)) +(declare-function org-mark-ring-push "org" (&optional pos buffer)) +(declare-function org-show-context "org" (&optional key)) +(declare-function org-trim "org" (s)) +(declare-function outline-next-heading "outline") -(defvar org-outline-regexp-bol) ; 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 org-outline-regexp-bol) ; defined in org.el +(defvar org-odd-levels-only) ; defined in org.el +(defvar org-bracket-link-regexp) ; defined in org.el +(defvar message-cite-prefix-regexp) ; defined in message.el +(defvar message-signature-separator) ; defined in message.el (defconst org-footnote-re ;; Only [1]-like footnotes are closed in this regexp, as footnotes @@ -67,17 +71,17 @@ ;; their definition. ;; ;; `org-re' is used for regexp compatibility with XEmacs. - (org-re (concat "\\[\\(?:" - ;; Match inline footnotes. - "fn:\\([-_[:word:]]+\\)?:\\|" - ;; Match other footnotes. - "\\(?:\\([0-9]+\\)\\]\\)\\|" - "\\(fn:[-_[:word:]]+\\)" - "\\)")) + (concat "\\[\\(?:" + ;; Match inline footnotes. + (org-re "fn:\\([-_[:word:]]+\\)?:\\|") + ;; Match other footnotes. + "\\(?:\\([0-9]+\\)\\]\\)\\|" + (org-re "\\(fn:[-_[:word:]]+\\)") + "\\)") "Regular expression for matching footnotes.") (defconst org-footnote-definition-re - (org-re "^\\(\\[\\([0-9]+\\|fn:[-_[:word:]]+\\)\\]\\)") + (org-re "^\\[\\([0-9]+\\|fn:[-_[:word:]]+\\)\\]") "Regular expression matching the definition of a footnote.") (defvar org-footnote-forbidden-blocks '("example" "verse" "src" "ascii" "beamer" @@ -106,13 +110,17 @@ heading will be removed after extracting footnote definitions." (defcustom org-footnote-tag-for-non-org-mode-files "Footnotes:" "Tag marking the beginning of footnote section. -The Org-mode footnote engine can be used in arbitrary text files as well -as in Org-mode. Outside Org-mode, new footnotes are always placed at +The Org footnote engine can be used in arbitrary text files as well +as in Org-mode. Outside Org mode, new footnotes are always placed at the end of the file. When you normalize the notes, any line containing only this tag will be removed, a new one will be inserted at the end -of the file, followed by the collected and normalized footnotes." +of the file, followed by the collected and normalized footnotes. + +If you don't want any tag in such buffers, set this variable to nil." :group 'org-footnote - :type 'string) + :type '(choice + (string :tag "Collect footnotes under tag") + (const :tag "Don't use a tag" nil))) (defcustom org-footnote-define-inline nil "Non-nil means define footnotes inline, at reference location. @@ -171,8 +179,11 @@ extracted will be filled again." (save-match-data (not (or (org-in-commented-line) (org-in-indented-comment-line) - (org-in-verbatim-emphasis) + (org-inside-LaTeX-fragment-p) + ;; Avoid protected environments (LaTeX export) + (get-text-property (point) 'org-protected) ;; Avoid literal example. + (org-in-verbatim-emphasis) (save-excursion (beginning-of-line) (looking-at "[ \t]*:[ \t]+")) @@ -194,13 +205,13 @@ positions, and the definition, when inlined." (or (looking-at org-footnote-re) (org-in-regexp org-footnote-re) (save-excursion (re-search-backward org-footnote-re nil t))) - ;; Only inline footnotes can start at bol. - (or (eq (char-before (match-end 0)) 58) - (/= (match-beginning 0) (point-at-bol)))) + (/= (match-beginning 0) (point-at-bol))) (let* ((beg (match-beginning 0)) - (label (or (match-string 2) (match-string 3) + (label (or (org-match-string-no-properties 2) + (org-match-string-no-properties 3) ;; Anonymous footnotes don't have labels - (and (match-string 1) (concat "fn:" (match-string 1))))) + (and (match-string 1) + (concat "fn:" (org-match-string-no-properties 1))))) ;; Inline footnotes don't end at (match-end 0) as ;; `org-footnote-re' stops just after the second colon. ;; Find the real ending with `scan-sexps', so Org doesn't @@ -223,12 +234,12 @@ positions, and the definition, when inlined." ;; 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))))) + (get-text-property (1- beg) 'org-protected))) (list label beg end ;; Definition: ensure this is an inline footnote first. (and (or (not label) (match-string 1)) - (org-trim (buffer-substring (match-end 0) (1- end))))))))) + (org-trim (buffer-substring-no-properties + (match-end 0) (1- end))))))))) (defun org-footnote-at-definition-p () "Is the cursor at a footnote definition? @@ -239,7 +250,7 @@ footnote text is included and defined locally. 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." - (when (org-footnote-in-valid-context-p) + (when (save-excursion (beginning-of-line) (org-footnote-in-valid-context-p)) (save-excursion (end-of-line) (let ((lim (save-excursion (re-search-backward @@ -247,7 +258,7 @@ label, start, end and definition of the footnote otherwise." "\\|^[ \t]*$") nil t)))) (when (re-search-backward org-footnote-definition-re lim t) (end-of-line) - (list (match-string 2) + (list (org-match-string-no-properties 1) (match-beginning 0) (save-match-data ;; In a message, limit search to signature. @@ -257,15 +268,14 @@ label, start, end and definition of the footnote otherwise." (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:]]+\\)\\]")) + (concat org-outline-regexp-bol "\\|" + org-footnote-definition-re "\\|" + "^[ \t]*$") bound 'move) (progn (skip-chars-forward " \t\n") (point-at-bol))) (point)))) - (org-trim (buffer-substring (match-end 0) (point))))))))) + (org-trim (buffer-substring-no-properties + (match-end 0) (point))))))))) (defun org-footnote-get-next-reference (&optional label backward limit) "Return complete reference of the next footnote. @@ -295,10 +305,11 @@ LIMIT is the buffer position bounding the search. Return value is a list like those provided by `org-footnote-at-reference-p' or `org-footnote-at-definition-p'. If no footnote is found, return nil." - (let* (ref) + (let* (ref (origin (point))) (catch 'exit (while t (unless (re-search-forward org-footnote-re limit t) + (goto-char origin) (throw 'exit nil)) ;; Beware: with [1]-like footnotes point will be just after ;; the closing square bracket. @@ -320,19 +331,21 @@ If no footnote is found, return nil." (re (format "^\\[%s\\]\\|.\\[%s:" label label)) pos) (save-excursion - (when (or (re-search-forward re nil t) - (and (goto-char (point-min)) - (re-search-forward re nil t)) - (and (progn (widen) t) - (goto-char (point-min)) - (re-search-forward re nil t))) - (let ((refp (org-footnote-at-reference-p))) - (cond - ((and (nth 3 refp) refp)) - ((org-footnote-at-definition-p)))))))) + (save-restriction + (when (or (re-search-forward re nil t) + (and (goto-char (point-min)) + (re-search-forward re nil t)) + (and (progn (widen) t) + (goto-char (point-min)) + (re-search-forward re nil t))) + (let ((refp (org-footnote-at-reference-p))) + (cond + ((and (nth 3 refp) refp)) + ((org-footnote-at-definition-p))))))))) (defun org-footnote-goto-definition (label) - "Move point to the definition of the footnote LABEL." + "Move point to the definition of the footnote LABEL. +Return a non-nil value when a definition has been found." (interactive "sLabel: ") (org-mark-ring-push) (let ((def (org-footnote-get-definition label))) @@ -342,7 +355,9 @@ If no footnote is found, return nil." (looking-at (format "\\[%s\\]\\|\\[%s:" label label)) (goto-char (match-end 0)) (org-show-context 'link-search) - (message "Edit definition and go back with `C-c &' or, if unique, with `C-c C-c'.")))) + (when (eq major-mode 'org-mode) + (message "Edit definition and go back with `C-c &' or, if unique, with `C-c C-c'.")) + t))) (defun org-footnote-goto-previous-reference (label) "Find the first closest (to point) reference of footnote with label LABEL." @@ -406,7 +421,12 @@ and value definition." (defun org-footnote-unique-label (&optional current) "Return a new unique footnote label. -The returns the firsts fn:N labels that is currently not used." + +The function returns the first \"fn:N\" or \"N\" label that is +currently not used. + +Optional argument CURRENT is the list of labels active in the +buffer." (unless current (setq current (org-footnote-all-labels))) (let ((fmt (if (eq org-footnote-auto-label 'plain) "%d" "fn:%d")) (cnt 1)) @@ -414,21 +434,17 @@ The returns the firsts fn:N labels that is currently not used." (incf cnt)) (format fmt cnt))) -(defvar org-footnote-label-history nil - "History of footnote labels entered in current buffer.") -(make-variable-buffer-local 'org-footnote-label-history) - (defun org-footnote-new () "Insert a new footnote. 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 or new, let the user edit the definition of the footnote." (interactive) - (unless (and (not (bolp)) (org-footnote-in-valid-context-p)) + (unless (org-footnote-in-valid-context-p) (error "Cannot insert a footnote here")) - (let* ((labels (and (not (equal org-footnote-auto-label 'random)) - (org-footnote-all-labels))) - (propose (org-footnote-unique-label labels)) + (let* ((lbls (and (not (equal org-footnote-auto-label 'random)) + (org-footnote-all-labels))) + (propose (org-footnote-unique-label lbls)) (label (org-footnote-normalize-label (cond @@ -438,16 +454,16 @@ or new, let the user edit the definition of the footnote." (require 'org-id) (substring (org-id-uuid) 0 8)) (t - (completing-read + (org-icompleting-read "Label (leave empty for anonymous): " - (mapcar 'list labels) nil nil - (if (eq org-footnote-auto-label 'confirm) propose nil) - 'org-footnote-label-history)))))) + (mapcar 'list lbls) nil nil + (if (eq org-footnote-auto-label 'confirm) propose nil))))))) (cond + ((bolp) (error "Cannot create a footnote reference at left margin")) ((not label) (insert "[fn:: ]") (backward-char 1)) - ((member label labels) + ((member label lbls) (insert "[" label "]") (message "New reference to existing note")) (org-footnote-define-inline @@ -459,51 +475,78 @@ or new, let the user edit the definition of the footnote." (org-footnote-create-definition label) (org-footnote-auto-adjust-maybe))))) +(defvar org-blank-before-new-entry nil) ; silence byte-compiler (defun org-footnote-create-definition (label) "Start the definition of a footnote with label LABEL." (interactive "sLabel: ") (let ((label (org-footnote-normalize-label label))) (cond - ((org-mode-p) - ;; No section, put footnote into the current outline node Try to - ;; find or make the special node + ;; In an Org file. + ((eq major-mode 'org-mode) + ;; If `org-footnote-section' is defined, find it, or create it + ;; at the end of the buffer. (when org-footnote-section (goto-char (point-min)) (let ((re (concat "^\\*+[ \t]+" org-footnote-section "[ \t]*$"))) (unless (or (re-search-forward re nil t) (and (progn (widen) t) (re-search-forward re nil t))) - (goto-char (point-max)) - (insert "\n\n* " org-footnote-section "\n")))) - ;; Now go to the end of this entry and insert there. + (goto-char (point-max)) + (skip-chars-backward " \t\r\n") + (unless (bolp) (newline)) + ;; Insert new section. Separate it from the previous one + ;; with a blank line, unless `org-blank-before-new-entry' + ;; explicitly says no. + (when (and (cdr (assq 'heading org-blank-before-new-entry)) + (zerop (save-excursion (org-back-over-empty-lines)))) + (insert "\n")) + (insert "* " org-footnote-section "\n")))) + ;; Move to the end of this entry (which may be + ;; `org-footnote-section' or the current one). (org-footnote-goto-local-insertion-point) (org-show-context 'link-search)) (t ;; In a non-Org file. Search for footnote tag, or create it if - ;; necessary (at the end of buffer, or before a signature if in + ;; specified (at the end of buffer, or before signature if in ;; Message mode). Set point after any definition already there. - (let ((tag (concat "^" org-footnote-tag-for-non-org-mode-files "[ \t]*$")) - (max (save-excursion - (if (and (derived-mode-p 'message-mode) - (re-search-forward - message-signature-separator nil t)) - (copy-marker (point-at-bol) t) - (copy-marker (point-max) t))))) + (let ((tag (and org-footnote-tag-for-non-org-mode-files + (concat "^" (regexp-quote + org-footnote-tag-for-non-org-mode-files) + "[ \t]*$"))) + (max (if (and (derived-mode-p 'message-mode) + (goto-char (point-max)) + (re-search-backward + message-signature-separator nil t)) + (progn + ;; Ensure one blank line separates last + ;; footnote from signature. + (beginning-of-line) + (open-line 2) + (point-marker)) + (point-max-marker)))) + (set-marker-insertion-type max t) (goto-char max) - (unless (re-search-backward tag nil t) + ;; Check if the footnote tag is defined but missing. In this + ;; case, insert it, before any footnote or one blank line + ;; after any previous text. + (when (and tag (not (re-search-backward tag nil t))) (skip-chars-backward " \t\r\n") - (delete-region (point) max) - (insert "\n\n" org-footnote-tag-for-non-org-mode-files "\n")) - ;; Skip existing footnotes. - (while (re-search-forward org-footnote-definition-re max t)) - (let ((def (org-footnote-at-definition-p))) - (when def (goto-char (nth 2 def)))) + (while (re-search-backward org-footnote-definition-re nil t)) + (unless (bolp) (newline 2)) + (insert org-footnote-tag-for-non-org-mode-files "\n\n")) + ;; Remove superfluous white space and clear marker. + (goto-char max) + (skip-chars-backward " \t\r\n") + (delete-region (point) max) + (unless (bolp) (newline)) (set-marker max nil)))) - ;; Insert footnote label, position point and notify user. - (unless (bolp) (insert "\n")) - (insert "\n[" label "] \n") - (backward-char) - (message "Edit definition and go back with `C-c &' or, if unique, with `C-c C-c'."))) + ;; Insert footnote label. + (insert "\n[" label "] ") + ;; Only notify user about next possible action when in an Org + ;; buffer, as the bindings may have different meanings otherwise. + (when (eq major-mode 'org-mode) + (message + "Edit definition and go back with `C-c &' or, if unique, with `C-c C-c'.")))) ;;;###autoload (defun org-footnote-action (&optional special) @@ -570,11 +613,11 @@ If Org is amidst an export process, EXPORT-PROPS will hold the export properties of the buffer. When EXPORT-PROPS is non-nil, the default action is to insert -normalized footnotes towards the end of the pre-processing buffer. -Some exporters like docbook, odt, etc. expect that footnote -definitions be available before any references to them. Such -exporters can let bind `org-footnote-insert-pos-for-preprocessor' to -symbol 'point-min to achieve the desired behavior. +normalized footnotes towards the end of the pre-processing +buffer. Some exporters (docbook, odt...) expect footnote +definitions to be available before any references to them. Such +exporters can let bind `org-footnote-insert-pos-for-preprocessor' +to symbol `point-min' to achieve the desired behaviour. Additional note on `org-footnote-insert-pos-for-preprocessor': 1. This variable has not effect when FOR-PREPROCESSOR is nil. @@ -634,8 +677,8 @@ Additional note on `org-footnote-insert-pos-for-preprocessor': (and inlinep org-footnote-fill-after-inline-note-extraction (org-fill-paragraph))) - ;; Add label (REF), identifier (MARKER) and definition (DEF) - ;; to REF-TABLE if data was unknown. + ;; Add label (REF), identifier (MARKER), definition (DEF) + ;; and type (INLINEP) to REF-TABLE if data was unknown. (unless a (let ((def (or (nth 3 ref) ; inline (and export-props @@ -646,52 +689,52 @@ Additional note on `org-footnote-insert-pos-for-preprocessor': ;; through `org-export-preprocess-string' so ;; it is ready to insert in the ;; backend-specific buffer. - (if export-props + (if (and export-props def) (let ((parameters (org-combine-plists export-props '(:todo-keywords t :tags t :priority t)))) (org-export-preprocess-string def parameters)) def) - inlinep) ref-table))) - ;; Remove definition of non-inlined footnotes. - (unless inlinep (org-footnote-delete-definitions lbl)))) + inlinep) ref-table))))) ;; 2. Find and remove the footnote section, if any. Also ;; determine where footnotes shall be inserted (INS-POINT). (goto-char (point-min)) (cond - ((org-mode-p) - (if (and org-footnote-section - (re-search-forward - (concat "^\\*[ \t]+" (regexp-quote org-footnote-section) - "[ \t]*$") - nil t)) - (progn - (setq ins-point (match-beginning 0)) - (delete-region (match-beginning 0) (org-end-of-subtree t))) - (setq ins-point (point-max)))) + ((and org-footnote-section + (eq major-mode 'org-mode) + (re-search-forward + (concat "^\\*[ \t]+" (regexp-quote org-footnote-section) + "[ \t]*$") + nil t)) + (delete-region (match-beginning 0) (org-end-of-subtree t))) + ((eq major-mode 'org-mode) + (goto-char (point-max)) + (unless (bolp) (newline))) (t - (when (re-search-forward - (concat "^" - (regexp-quote org-footnote-tag-for-non-org-mode-files) - "[ \t]*$") - nil t) - (replace-match "")) - ;; In message-mode, ensure footnotes are inserted before the + ;; Remove any left-over tag in the buffer, if one is set up. + (when org-footnote-tag-for-non-org-mode-files + (let ((tag (concat "^" (regexp-quote + org-footnote-tag-for-non-org-mode-files) + "[ \t]*$"))) + (while (re-search-forward tag nil t) + (replace-match "") + (delete-region (point) (progn (forward-line) (point)))))) + ;; In Message mode, ensure footnotes are inserted before the ;; signature. - (let ((pt-max - (or (and (derived-mode-p 'message-mode) - (save-excursion - (goto-char (point-max)) - (re-search-backward - message-signature-separator nil t) - (1- (point)))) - (point-max)))) - (goto-char pt-max) - (skip-chars-backward " \t\n\r") - (forward-line) - (delete-region (point) pt-max)) - (setq ins-point (point)))) + (if (and (derived-mode-p 'message-mode) + (goto-char (point-max)) + (re-search-backward message-signature-separator nil t)) + (beginning-of-line) + (goto-char (point-max))))) + ;; During export, `org-footnote-insert-pos-for-preprocessor' has + ;; precedence over previously found position. + (setq ins-point + (copy-marker + (if (and export-props + (eq org-footnote-insert-pos-for-preprocessor 'point-min)) + (point-min) + (point)))) ;; 3. Clean-up REF-TABLE. (setq ref-table (delq nil @@ -708,34 +751,48 @@ Additional note on `org-footnote-insert-pos-for-preprocessor': (t x))) ref-table))) (setq ref-table (nreverse ref-table)) - ;; 4. Insert the footnotes again in the buffer, at the + ;; 4. Remove left-over definitions in the buffer. + (mapc (lambda (x) (unless (nth 3 x) + (org-footnote-delete-definitions (car x)))) + ref-table) + ;; 5. Insert the footnotes again in the buffer, at the ;; appropriate spot. - (goto-char (or - (and export-props - (eq org-footnote-insert-pos-for-preprocessor 'point-min) - (point-min)) - ins-point - (point-max))) + (goto-char ins-point) (cond ;; No footnote: exit. ((not ref-table)) ;; Cases when footnotes should be inserted in one place. - ((or (not (org-mode-p)) + ((or (not (eq major-mode 'org-mode)) org-footnote-section (not sort-only)) - ;; Insert again the section title. + ;; Insert again the section title, if any. Ensure that title, + ;; or the subsequent footnotes, will be separated by a blank + ;; lines from the rest of the document. In an Org buffer, + ;; separate section with a blank line, unless explicitly + ;; stated in `org-blank-before-new-entry'. (cond - ((not (org-mode-p)) - (insert "\n\n" org-footnote-tag-for-non-org-mode-files "\n")) + ((not (eq major-mode 'org-mode)) + (skip-chars-backward " \t\n\r") + (delete-region (point) ins-point) + (unless (bolp) (newline)) + ;; Keep one blank line between footnotes and signature. + (when (and (derived-mode-p 'message-mode) + (save-excursion + (re-search-forward message-signature-separator nil t))) + (open-line 1)) + (when org-footnote-tag-for-non-org-mode-files + (insert "\n" org-footnote-tag-for-non-org-mode-files "\n"))) ((and org-footnote-section (not export-props)) - (or (bolp) (insert "\n")) + (when (and (cdr (assq 'heading org-blank-before-new-entry)) + (zerop (save-excursion (org-back-over-empty-lines)))) + (insert "\n")) (insert "* " org-footnote-section "\n"))) - ;; Insert the footnotes. - (insert "\n" - (mapconcat (lambda (x) (format "[%s] %s" + (set-marker ins-point nil) + ;; Insert the footnotes, separated by a blank line. + (insert (mapconcat (lambda (x) (format "\n[%s] %s" (nth (if sort-only 0 1) x) (nth 2 x))) - ref-table "\n\n") - "\n\n") + ref-table "\n")) + (unless (eobp) (insert "\n")) ;; When exporting, add newly inserted markers along with their ;; associated definition to `org-export-footnotes-seen'. (when export-props @@ -831,20 +888,21 @@ If LABEL is non-nil, delete that footnote instead." (defun org-footnote-renumber-fn:N () "Renumber the simple footnotes like fn:17 into a sequence in the document." (interactive) - (let (map i (n 0)) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (while (re-search-forward "\\[fn:\\([0-9]+\\)[]:]" nil t) - (setq i (string-to-number (match-string 1))) - (when (and (string-match "\\S-" (buffer-substring - (point-at-bol) (match-beginning 0))) - (not (assq i map))) - (push (cons i (number-to-string (incf n))) map))) - (goto-char (point-min)) - (while (re-search-forward "\\(\\[fn:\\)\\([0-9]+\\)\\([]:]\\)" nil t) - (replace-match (concat "\\1" (cdr (assq (string-to-number (match-string 2)) map)) "\\3"))))))) + (let (map (n 0)) + (org-with-wide-buffer + (goto-char (point-min)) + (while (re-search-forward "\\[fn:\\([0-9]+\\)[]:]" nil t) + (save-excursion + (goto-char (match-beginning 0)) + ;; Ensure match is a footnote reference or definition. + (when (save-match-data (if (bolp) + (org-footnote-at-definition-p) + (org-footnote-at-reference-p))) + (let ((new-val (or (cdr (assoc (match-string 1) map)) + (number-to-string (incf n))))) + (unless (assoc (match-string 1) map) + (push (cons (match-string 1) new-val) map)) + (replace-match new-val nil nil nil 1)))))))) (defun org-footnote-auto-adjust-maybe () "Renumber and/or sort footnotes according to user settings." @@ -862,6 +920,4 @@ If LABEL is non-nil, delete that footnote instead." (provide 'org-footnote) - - ;;; org-footnote.el ends here |