mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
Merge Org 7.8.03
This commit is contained in:
parent
88c5c7c831
commit
e66ba1dfc4
116 changed files with 15215 additions and 3740 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue