Function: org-footnote-normalize
org-footnote-normalize is an interactive and byte-compiled function
defined in org-footnote.el.gz.
Signature
(org-footnote-normalize)
Documentation
Turn every footnote in buffer into a numbered one.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/org/org-footnote.el.gz
(defun org-footnote-normalize ()
"Turn every footnote in buffer into a numbered one."
(interactive)
(org-preserve-local-variables
(let ((n 0)
(translations nil)
(definitions nil)
(references (org-footnote--collect-references 'anonymous)))
(org-with-wide-buffer
;; Update label for reference. We need to do this before
;; clearing definitions in order to rename nested footnotes
;; before they are deleted.
(dolist (cell references)
(let* ((label (car cell))
(anonymous (not label))
(new
(cond
;; In order to differentiate anonymous references
;; from regular ones, set their labels to integers,
;; not strings.
(anonymous (setcar cell (cl-incf n)))
((cdr (assoc label translations)))
(t (let ((l (number-to-string (cl-incf n))))
(push (cons label l) translations)
l)))))
(goto-char (nth 1 cell)) ; Move to reference's start.
(org-footnote--set-label
(if anonymous (number-to-string new) new))
(let ((size (nth 3 cell)))
;; Transform inline footnotes into regular references and
;; retain their definition for later insertion as
;; a regular footnote definition.
(when size
(let ((def (concat
(format "[fn:%s] " new)
(org-trim
(substring
(delete-and-extract-region
(point) (+ (point) size 1))
1)))))
(push (cons (if anonymous new label) def) definitions)
(when org-footnote-fill-after-inline-note-extraction
(org-fill-paragraph)))))))
;; Collect definitions. Update labels according to ALIST.
(let ((definitions
(nconc definitions
(org-footnote--collect-definitions 'delete)))
(inserted))
(org-footnote--clear-footnote-section)
(dolist (cell references)
(let* ((label (car cell))
(anonymous (integerp label))
(pos (nth 1 cell)))
;; Move to appropriate location, if required. When there
;; is a footnote section or reference is nested, point is
;; already at the expected location.
(unless (or org-footnote-section (not (nth 2 cell)))
(goto-char pos)
(org-footnote--goto-local-insertion-point))
;; Insert new definition once label is updated.
(unless (member label inserted)
(push label inserted)
(let ((stored (cdr (assoc label definitions)))
;; Anonymous footnotes' label is already
;; up-to-date.
(new (if anonymous label
(cdr (assoc label translations)))))
(insert "\n"
(cond
((not stored)
(format "[fn:%s] DEFINITION NOT FOUND." new))
(anonymous stored)
(t
(replace-regexp-in-string
"\\`\\[fn:\\(.*?\\)\\]" new stored nil nil 1)))
"\n")))))
;; Insert un-referenced footnote definitions at the end.
(pcase-dolist (`(,label . ,definition) definitions)
(unless (member label inserted)
(insert "\n"
(replace-regexp-in-string org-footnote-definition-re
(format "[fn:%d]" (cl-incf n))
definition)
"\n"))))))))