Require 2 blank lines to separate footnote definition

* lisp/org-element.el (org-element-footnote-definition-parser):
  Require 2 blank lines to separate footnote definition.
* lisp/org-footnote.el (org-footnote-at-definition-p): Require 2 blank
  lines to separate footnote definition.
* doc/org.texi: Update documentation for footnotes.
* testing/lisp/test-org-element.el: Update tests.
* testing/lisp/test-org-footnote.el: Add tests.

Footnote definitions can still be separated with other footnote
definitions and headlines. This change allows to have multiple
paragraphs in a footnote definition without resorting to the "\par"
trick.
This commit is contained in:
Nicolas Goaziou 2013-02-21 15:30:16 +01:00
parent a965c06213
commit ca060f7be7
5 changed files with 89 additions and 31 deletions

View File

@ -1845,13 +1845,13 @@ or on a per-file basis by using
@cindex footnotes
Org mode supports the creation of footnotes. In contrast to the
@file{footnote.el} package, Org mode's footnotes are designed for work on a
larger document, not only for one-off documents like emails. The basic
syntax is similar to the one used by @file{footnote.el}, i.e., a footnote is
defined in a paragraph that is started by a footnote marker in square
brackets in column 0, no indentation allowed. If you need a paragraph break
inside a footnote, use the @LaTeX{} idiom @samp{\par}. The footnote reference
is simply the marker in square brackets, inside text. For example:
@file{footnote.el} package, Org mode's footnotes are designed for work on
a larger document, not only for one-off documents like emails.
A footnote is started by a footnote marker in square brackets in column 0, no
indentation allowed. It ends at the next footnote definition, headline, or
after two consecutive empty lines. The footnote reference is simply the
marker in square brackets, inside text. For example:
@example
The Org homepage[fn:1] now looks a lot better than it used to.

View File

@ -693,7 +693,7 @@ Assume point is at the beginning of the footnote definition."
(re-search-forward
(concat org-outline-regexp-bol "\\|"
org-footnote-definition-re "\\|"
"^[ \t]*$") limit 'move))
"^\\([ \t]*\n\\)\\{2,\\}") limit 'move))
(match-beginning 0)
(point))))
(contents-begin (progn (search-forward "]")

View File

@ -251,11 +251,12 @@ otherwise."
(when (save-excursion (beginning-of-line) (org-footnote-in-valid-context-p))
(save-excursion
(end-of-line)
;; Footnotes definitions are separated by new headlines or blank
;; lines.
(let ((lim (save-excursion (re-search-backward
(concat org-outline-regexp-bol
"\\|^[ \t]*$") nil t))))
;; Footnotes definitions are separated by new headlines, another
;; footnote definition or 2 blank lines.
(let ((lim (save-excursion
(re-search-backward
(concat org-outline-regexp-bol
"\\|^\\([ \t]*\n\\)\\{2,\\}") nil t))))
(when (re-search-backward org-footnote-definition-re lim t)
(let ((label (org-match-string-no-properties 1))
(beg (match-beginning 0))
@ -271,7 +272,7 @@ otherwise."
(re-search-forward
(concat org-outline-regexp-bol "\\|"
org-footnote-definition-re "\\|"
"^[ \t]*$") bound 'move))
"^\\([ \t]*\n\\)\\{2,\\}") bound 'move))
(match-beginning 0)
(point)))))
(list label beg end

View File

@ -724,10 +724,10 @@ Some other text
(org-element-parse-buffer) 'footnote-definition 'identity nil t)))
;; Footnote with more contents
(should
(= 28
(= 29
(org-element-property
:end
(org-test-with-temp-text "[fn:1] Definition\n| a | b |"
(org-test-with-temp-text "[fn:1] Definition\n\n| a | b |"
(org-element-map
(org-element-parse-buffer)
'footnote-definition 'identity nil t)))))

View File

@ -19,6 +19,58 @@
;;; Code:
(ert-deftest test-org-footnote/delete ()
"Test `org-footnote-delete' specifications."
;; Regular test.
(should
(equal "Paragraph"
(org-test-with-temp-text "Paragraph[1]\n\n[1] Definition"
(search-forward "[")
(org-footnote-delete)
(org-trim (buffer-string)))))
;; Remove multiple definitions and references.
(should
(equal "Paragraph and another"
(org-test-with-temp-text
"Paragraph[1] and another[1]\n\n[1] def\n\n[1] def"
(search-forward "[")
(org-footnote-delete)
(org-trim (buffer-string)))))
;; Delete inline footnotes and all references.
(should
(equal "Para and"
(org-test-with-temp-text "Para[fn:label:def] and[fn:label]"
(search-forward "[")
(org-footnote-delete)
(org-trim (buffer-string)))))
;; Delete anonymous footnotes.
(should
(equal "Para"
(org-test-with-temp-text "Para[fn::def]"
(search-forward "[")
(org-footnote-delete)
(org-trim (buffer-string)))))
;; With an argument, delete footnote with specified label.
(should
(equal "Paragraph[1] and another\n\n[1] def"
(let ((org-footnote-section nil))
(org-test-with-temp-text
"Paragraph[1] and another[2]\n\n[1] def\n\n[2] def2"
(org-footnote-delete "2")
(org-trim (buffer-string))))))
;; Error when no argument is specified at point is not at a footnote
;; reference.
(should-error
(org-test-with-temp-text "Para[1]\n\n[1] Def"
(org-footnote-delete)))
;; Correctly delete footnotes with multiple paragraphs.
(should
(equal "Para\n\n\nOutside footnote."
(org-test-with-temp-text
"Para[1]\n\n[1] para1\n\npara2\n\n\nOutside footnote."
(org-footnote-delete "1")
(org-trim (buffer-string))))))
(ert-deftest test-org-footnote/normalize-in-org ()
"Test specifications for `org-footnote-normalize' in an Org buffer."
;; 1. With a non-nil `org-footnote-section'.
@ -138,21 +190,10 @@ Text[2]
"Test `org-footnote-normalize' specifications for buffers not in Org mode."
;; 1. In a non-Org buffer, footnotes definitions are always put at
;; its end.
(let ((org-footnote-tag-for-non-org-mode-files nil))
(with-temp-buffer
(insert "Paragraph[fn:1][fn:label][1][fn:inline:Inline][fn::Anonymous]
(should
(equal
"Paragraph[1][2][3][4][5]
\[fn:1] Standard
\[fn:label] Labelled
\[1] Numbered
Some additional text.")
(org-footnote-normalize)
(should
(equal (buffer-string)
"Paragraph[1][2][3][4][5]
Some additional text.
@ -164,7 +205,21 @@ Some additional text.
\[4] Inline
\[5] Anonymous"))))
\[5] Anonymous"
(let ((org-footnote-tag-for-non-org-mode-files nil))
(with-temp-buffer
(insert "Paragraph[fn:1][fn:label][1][fn:inline:Inline][fn::Anonymous]
\[fn:1] Standard
\[fn:label] Labelled
\[1] Numbered
Some additional text.")
(org-footnote-normalize)
(buffer-string)))))
;; 2. With a special tag.
(let ((org-footnote-tag-for-non-org-mode-files "Footnotes:"))
;; 2.1. The tag must be inserted before the footnotes, separated
@ -174,12 +229,14 @@ Some additional text.
\[fn:1] Standard
Some additional text.")
(org-footnote-normalize)
(should
(equal (buffer-string)
"Paragraph[1][2]
Some additional text.
Footnotes: