org-footnote.el: Allow to inline external footnotes

* org-footnote.el (org-footnote-new): When point is at a
position where no footnote can be inserted, offer the menu
from `org-footnote-action' instead.
(org-footnote-inline-footnotes): New command.
(org-footnote-action): Make the new command accessible through
the menu.

Thanks to Leonard Randall for the suggestion.
This commit is contained in:
Bastien Guerry 2014-05-30 14:54:11 +02:00
parent a060fb0a08
commit 8738f173e5
1 changed files with 61 additions and 36 deletions

View File

@ -450,41 +450,41 @@ 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 (org-footnote-in-valid-context-p)
(error "Cannot insert a footnote here"))
(let* ((lbls (and (not (equal org-footnote-auto-label 'random))
(org-footnote-all-labels)))
(propose (and (not (equal org-footnote-auto-label 'random))
(org-footnote-unique-label lbls)))
(label
(org-footnote-normalize-label
(cond
((member org-footnote-auto-label '(t plain))
propose)
((equal org-footnote-auto-label 'random)
(require 'org-id)
(substring (org-id-uuid) 0 8))
(t
(org-icompleting-read
"Label (leave empty for anonymous): "
(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 lbls)
(insert "[" label "]")
(message "New reference to existing note"))
(org-footnote-define-inline
(insert "[" label ": ]")
(backward-char 1)
(org-footnote-auto-adjust-maybe))
(t
(insert "[" label "]")
(org-footnote-create-definition label)
(org-footnote-auto-adjust-maybe)))))
(if (not (org-footnote-in-valid-context-p))
(org-footnote-action '(4))
(let* ((lbls (and (not (equal org-footnote-auto-label 'random))
(org-footnote-all-labels)))
(propose (and (not (equal org-footnote-auto-label 'random))
(org-footnote-unique-label lbls)))
(label
(org-footnote-normalize-label
(cond
((member org-footnote-auto-label '(t plain))
propose)
((equal org-footnote-auto-label 'random)
(require 'org-id)
(substring (org-id-uuid) 0 8))
(t
(org-icompleting-read
"Label (leave empty for anonymous): "
(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 lbls)
(insert "[" label "]")
(message "New reference to existing note"))
(org-footnote-define-inline
(insert "[" label ": ]")
(backward-char 1)
(org-footnote-auto-adjust-maybe))
(t
(insert "[" label "]")
(org-footnote-create-definition label)
(org-footnote-auto-adjust-maybe))))))
(defvar org-blank-before-new-entry) ; silence byte-compiler
(defun org-footnote-create-definition (label)
@ -579,9 +579,10 @@ With prefix arg SPECIAL, offer additional commands in a menu."
(let (tmp c)
(cond
(special
(message "Footnotes: [s]ort | [r]enumber fn:N | [S]=r+s |->[n]umeric | [d]elete")
(message "Footnotes: [s]ort, [r]enumber fn:N, [S]=r+s, ->[n]umeric, [d]elete, [i]inline")
(setq c (read-char-exclusive))
(cond
((eq c ?i) (org-footnote-inline-footnotes))
((eq c ?s) (org-footnote-normalize 'sort))
((eq c ?r) (org-footnote-renumber-fn:N))
((eq c ?S)
@ -870,6 +871,30 @@ If LABEL is non-nil, delete that footnote instead."
(push (cons (match-string 1) new-val) map))
(replace-match new-val nil nil nil 1))))))))
(defun org-footnote-inline-footnotes ()
"Convert external footnotes into inline ones."
(interactive)
(org-with-wide-buffer
(goto-char (point-min))
(while (re-search-forward (concat org-footnote-re "\\]") nil t)
(let ((fn (match-string 0)) fnd-end repl)
(save-excursion
(save-match-data
(when (and (re-search-forward (regexp-quote fn) nil t)
(eq (car (org-element-at-point)) 'footnote-definition))
(beginning-of-line)
(setq fnd-end (save-excursion (org-forward-element) (point)))
(setq repl (org-trim
(replace-regexp-in-string
(concat "\n\\|" org-footnote-re "\\]")
" " (buffer-substring (point) fnd-end))))
(delete-region (point) fnd-end))))
(replace-match (format "[fn::%s]" repl))))
(goto-char (point-min))
;; Delete the * Footnotes heading
(when (re-search-forward (concat org-outline-regexp-bol org-footnote-section) nil t)
(replace-match ""))))
(defun org-footnote-auto-adjust-maybe ()
"Renumber and/or sort footnotes according to user settings."
(when (memq org-footnote-auto-adjust '(t renumber))