summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2015-12-16 18:22:27 +0100
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2015-12-22 16:55:17 +0100
commitdeafe565548992fb56a4fe7d613996fcd18d038f (patch)
treeccb5bed97372c9cf23ec54d10aba81df9261c076
parent25eb14bc2cadab293e200c018284870a1eeb4490 (diff)
downloadorg-mode-deafe565548992fb56a4fe7d613996fcd18d038f.tar.gz
org-element: Ignore plain footnotes
* lisp/org-element.el (org-element--set-regexps): (org-element-footnote-definition-interpreter): (org-element-footnote-reference-parser): (org-element-footnote-reference-interpreter): Do not consider [1]-like constructs as footnotes anymore. * lisp/ox.el (org-export-expand-include-keyword): (org-export--prepare-file-contents): Apply changes to footnotes. * doc/org.texi (Footnotes): Remove references to plain footnotes. * testing/lisp/test-org-element.el (test-org-element/footnote-reference-parser): (test-org-element/footnote-reference-interpreter): * testing/lisp/test-ox.el (test-org-export/expand-include): (test-org-export/expand-macro): (test-org-export/get-footnote-number): (test-org-export/collect-footnote-definitions): (test-org-export/footnotes): (test-org-export/fuzzy-link): Update tests. Since it is possible to refer unambiguously to a label without the "fn:" prefix, the latter becomes part of the syntax and no longer part of the label. In particular [fn:1] and [fn:label] are labelled, respectively, "1" and "label".
-rw-r--r--doc/org.texi9
-rw-r--r--lisp/org-element.el25
-rw-r--r--lisp/ox.el15
-rw-r--r--testing/lisp/test-org-element.el15
-rw-r--r--testing/lisp/test-ox.el80
5 files changed, 72 insertions, 72 deletions
diff --git a/doc/org.texi b/doc/org.texi
index 27ec715..232c176 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -1922,16 +1922,9 @@ The Org homepage[fn:1] now looks a lot better than it used to.
@end example
Org mode extends the number-based syntax to @emph{named} footnotes and
-optional inline definition. Using plain numbers as markers (as
-@file{footnote.el} does) is supported for backward compatibility, but not
-encouraged because of possible conflicts with @LaTeX{} snippets (@pxref{Embedded
-@LaTeX{}}). Here are the valid references:
+optional inline definition. Here are the valid references:
@table @code
-@item [1]
-A plain numeric footnote marker. Compatible with @file{footnote.el}, but not
-recommended because something like @samp{[1]} could easily be part of a code
-snippet.
@item [fn:name]
A named footnote reference, where @code{name} is a unique label word, or, for
simplicity of automatic creation, a number.
diff --git a/lisp/org-element.el b/lisp/org-element.el
index 1a01e61..d6695c8 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -151,7 +151,7 @@ specially in `org-element--object-lex'.")
;; Headlines, inlinetasks.
org-outline-regexp "\\|"
;; Footnote definitions.
- "\\[\\(?:[0-9]+\\|fn:[-_[:word:]]+\\)\\]" "\\|"
+ "\\[fn:[-_[:word:]]+\\]" "\\|"
;; Diary sexps.
"%%(" "\\|"
"[ \t]*\\(?:"
@@ -199,7 +199,12 @@ specially in `org-element--object-lex'.")
;; Objects starting with "[": regular link,
;; footnote reference, statistics cookie,
;; timestamp (inactive).
- "\\[\\(?:fn:\\|\\(?:[0-9]\\|\\(?:%\\|/[0-9]*\\)\\]\\)\\|\\[\\)"
+ (concat "\\[\\(?:"
+ "fn:" "\\|"
+ "\\[" "\\|"
+ "[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}" "\\|"
+ "[0-9]*\\(?:%\\|/[0-9]*\\)\\]"
+ "\\)")
;; Objects starting with "@": export snippets.
"@@"
;; Objects starting with "{": macro.
@@ -836,7 +841,7 @@ Assume point is at the beginning of the footnote definition."
(defun org-element-footnote-definition-interpreter (footnote-definition contents)
"Interpret FOOTNOTE-DEFINITION element as Org syntax.
CONTENTS is the contents of the footnote-definition."
- (concat (format "[%s]" (org-element-property :label footnote-definition))
+ (concat (format "[fn:%s]" (org-element-property :label footnote-definition))
" "
contents))
@@ -2767,14 +2772,10 @@ When at a footnote reference, return a list whose car is
(when closing
(save-excursion
(let* ((begin (point))
- (label
- (or (org-match-string-no-properties 2)
- (org-match-string-no-properties 3)
- (and (match-string 1)
- (concat "fn:" (org-match-string-no-properties 1)))))
- (type (if (or (not label) (match-string 1)) 'inline 'standard))
+ (label (match-string-no-properties 1))
(inner-begin (match-end 0))
(inner-end (1- closing))
+ (type (if (match-end 2) 'inline 'standard))
(post-blank (progn (goto-char closing)
(skip-chars-forward " \t")))
(end (point)))
@@ -2790,9 +2791,9 @@ When at a footnote reference, return a list whose car is
(defun org-element-footnote-reference-interpreter (footnote-reference contents)
"Interpret FOOTNOTE-REFERENCE object as Org syntax.
CONTENTS is its definition, when inline, or nil."
- (format "[%s]"
- (concat (or (org-element-property :label footnote-reference) "fn:")
- (and contents (concat ":" contents)))))
+ (format "[fn:%s%s]"
+ (or (org-element-property :label footnote-reference) "")
+ (if contents (concat ":" contents) "")))
;;;; Inline Babel Call
diff --git a/lisp/ox.el b/lisp/ox.el
index 82833e3..119b6b4 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -3351,7 +3351,7 @@ storing and resolving footnotes. It is created automatically."
(unless included
(org-with-wide-buffer
(goto-char (point-max))
- (maphash (lambda (k v) (insert (format "\n[%s] %s\n" k v)))
+ (maphash (lambda (k v) (insert (format "\n[fn:%s] %s\n" k v)))
footnotes)))))))))))
(defun org-export--inclusion-absolute-lines (file location only-contents lines)
@@ -3472,7 +3472,7 @@ the included document."
(unless (eq major-mode 'org-mode)
(let ((org-inhibit-startup t)) (org-mode)))
(goto-char (point-min))
- (let ((ind-str (make-string ind ? )))
+ (let ((ind-str (make-string ind ?\s)))
(while (not (or (eobp) (looking-at org-outline-regexp-bol)))
;; Do not move footnote definitions out of column 0.
(unless (and (looking-at org-footnote-definition-re)
@@ -3508,17 +3508,14 @@ the included document."
(marker-max (point-max-marker))
(get-new-label
(lambda (label)
- ;; Generate new label from LABEL. If LABEL is akin to
- ;; [1] convert it to [fn:--ID-1]. Otherwise add "-ID-"
- ;; after "fn:".
- (if (org-string-match-p "\\`[0-9]+\\'" label)
- (format "fn:--%d-%s" id label)
- (format "fn:-%d-%s" id (substring label 3)))))
+ ;; Generate new label from LABEL by prefixing it with
+ ;; "-ID-".
+ (format "-%d-%s" id label)))
(set-new-label
(lambda (f old new)
;; Replace OLD label with NEW in footnote F.
(save-excursion
- (goto-char (1+ (org-element-property :begin f)))
+ (goto-char (+ (org-element-property :begin f) 4))
(looking-at (regexp-quote old))
(replace-match new))))
(seen-alist))
diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el
index 1abdd9d..12cf2dd 100644
--- a/testing/lisp/test-org-element.el
+++ b/testing/lisp/test-org-element.el
@@ -938,11 +938,6 @@ Some other text
(org-test-with-temp-text "Text[fn:label]"
(org-element-map
(org-element-parse-buffer) 'footnote-reference 'identity)))
- ;; Parse a normalized reference.
- (should
- (org-test-with-temp-text "Text[1]"
- (org-element-map
- (org-element-parse-buffer) 'footnote-reference 'identity)))
;; Parse an inline reference.
(should
(org-test-with-temp-text "Text[fn:test:def]"
@@ -2893,17 +2888,15 @@ DEADLINE: <2012-03-29 thu.> SCHEDULED: <2012-03-29 thu.> CLOSED: [2012-03-29 thu
(ert-deftest test-org-element/footnote-reference-interpreter ()
"Test footnote reference interpreter."
- ;; 1. Regular reference.
+ ;; Regular reference.
(should (equal (org-test-parse-and-interpret "Text[fn:1]") "Text[fn:1]\n"))
- ;; 2. Normalized reference.
- (should (equal (org-test-parse-and-interpret "Text[1]") "Text[1]\n"))
- ;; 3. Named reference.
+ ;; Named reference.
(should (equal (org-test-parse-and-interpret "Text[fn:label]")
"Text[fn:label]\n"))
- ;; 4. Inline reference.
+ ;; Inline reference.
(should (equal (org-test-parse-and-interpret "Text[fn:label:def]")
"Text[fn:label:def]\n"))
- ;; 5. Anonymous reference.
+ ;; Anonymous reference.
(should (equal (org-test-parse-and-interpret "Text[fn::def]")
"Text[fn::def]\n")))
diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el
index 74a94f3..b0518de 100644
--- a/testing/lisp/test-ox.el
+++ b/testing/lisp/test-ox.el
@@ -1054,7 +1054,7 @@ text
(length
(delete-dups
(let ((contents "
-Footnotes[fn:1], [fn:test], [fn:test] and [fn:inline:anonymous footnote].
+Footnotes[fn:1], [fn:test], [fn:test] and [fn:inline:inline footnote].
\[fn:1] Footnote 1
\[fn:test] Footnote \"test\""))
(org-test-with-temp-text-in-file contents
@@ -1070,13 +1070,12 @@ Footnotes[fn:1], [fn:test], [fn:test] and [fn:inline:anonymous footnote].
(lambda (r) (org-element-property :label r)))))))))))))
;; Footnotes labels are not local to each include keyword.
(should
- (= 4
+ (= 3
(length
(delete-dups
(let ((contents "
-Footnotes[fn:1], [fn:test], [2] and [fn:inline:anonymous footnote].
+Footnotes[fn:1], [fn:test] and [fn:inline:inline footnote].
\[fn:1] Footnote 1
-\[2] Footnote 2
\[fn:test] Footnote \"test\""))
(org-test-with-temp-text-in-file contents
(let ((file (buffer-file-name)))
@@ -1089,26 +1088,24 @@ Footnotes[fn:1], [fn:test], [2] and [fn:inline:anonymous footnote].
;; Footnotes are supported by :lines-like elements and unnecessary
;; footnotes are dropped.
(should
- (= 4
+ (= 3
(length
(delete-dups
(let ((contents "
* foo
Footnotes[fn:1]
* bar
-Footnotes[fn:2], foot[fn:test], digit only[3], and [fn:inline:anonymous footnote]
+Footnotes[fn:2], foot[fn:test] and [fn:inline:inline footnote]
\[fn:1] Footnote 1
\[fn:2] Footnote 1
* Footnotes
\[fn:test] Footnote \"test\"
-\[3] Footnote 3
"))
(org-test-with-temp-text-in-file contents
(let ((file (buffer-file-name)))
(org-test-with-temp-text
- (format "#+INCLUDE: \"%s::*bar\"
-" file)
+ (format "#+INCLUDE: \"%s::*bar\"\n" file)
(org-export-expand-include-keyword)
(org-element-map (org-element-parse-buffer)
'footnote-definition
@@ -1119,7 +1116,8 @@ Footnotes[fn:2], foot[fn:test], digit only[3], and [fn:inline:anonymous footnote
"body\n"
(org-test-with-temp-text
(concat
- (format "#+INCLUDE: \"%s/examples/include.org::*Heading\" " org-test-dir)
+ (format "#+INCLUDE: \"%s/examples/include.org::*Heading\" "
+ org-test-dir)
":only-contents t")
(org-export-expand-include-keyword)
(buffer-string))))
@@ -1135,27 +1133,32 @@ Footnotes[fn:2], foot[fn:test], digit only[3], and [fn:inline:anonymous footnote
(equal
"| 1 |\n"
(org-test-with-temp-text
- (format "#+INCLUDE: \"%s/examples/include.org::tbl\" :only-contents t" org-test-dir)
+ (format "#+INCLUDE: \"%s/examples/include.org::tbl\" :only-contents t"
+ org-test-dir)
(org-export-expand-include-keyword)
(buffer-string))))
;; Including non-existing elements should result in an error.
(should-error
(org-test-with-temp-text
- (format "#+INCLUDE: \"%s/examples/include.org::*non-existing heading\"" org-test-dir)
+ (format "#+INCLUDE: \"%s/examples/include.org::*non-existing heading\""
+ org-test-dir)
(org-export-expand-include-keyword)))
;; Lines work relatively to an included element.
(should
(equal
"2\n3\n"
(org-test-with-temp-text
- (format "#+INCLUDE: \"%s/examples/include.org::#ah\" :only-contents t :lines \"2-3\"" org-test-dir)
+ (format "#+INCLUDE: \"%s/examples/include.org::#ah\" :only-contents t \
+:lines \"2-3\""
+ org-test-dir)
(org-export-expand-include-keyword)
(buffer-string))))
;; Properties should be dropped from headlines.
(should
(equal
(org-test-with-temp-text
- (format "#+INCLUDE: \"%s/examples/include.org::#ht\" :only-contents t" org-test-dir)
+ (format "#+INCLUDE: \"%s/examples/include.org::#ht\" :only-contents t"
+ org-test-dir)
(org-export-expand-include-keyword)
(buffer-string))
(org-test-with-temp-text
@@ -1167,7 +1170,8 @@ Footnotes[fn:2], foot[fn:test], digit only[3], and [fn:inline:anonymous footnote
(equal
":LOGBOOK:\ndrawer\n:END:\ncontent\n"
(org-test-with-temp-text
- (format "#+INCLUDE: \"%s/examples/include.org::#dh\" :only-contents t" org-test-dir)
+ (format "#+INCLUDE: \"%s/examples/include.org::#dh\" :only-contents t"
+ org-test-dir)
(org-export-expand-include-keyword)
(buffer-string))))
;; Adjacent INCLUDE-keywords should have the same :minlevel if unspecified.
@@ -1175,8 +1179,10 @@ Footnotes[fn:2], foot[fn:test], digit only[3], and [fn:inline:anonymous footnote
(cl-every (lambda (level) (zerop (1- level)))
(org-test-with-temp-text
(concat
- (format "#+INCLUDE: \"%s/examples/include.org::#ah\"\n" org-test-dir)
- (format "#+INCLUDE: \"%s/examples/include.org::*Heading\"" org-test-dir))
+ (format "#+INCLUDE: \"%s/examples/include.org::#ah\"\n"
+ org-test-dir)
+ (format "#+INCLUDE: \"%s/examples/include.org::*Heading\""
+ org-test-dir))
(org-export-expand-include-keyword)
(org-element-map (org-element-parse-buffer) 'headline
(lambda (head) (org-element-property :level head))))))
@@ -1184,30 +1190,37 @@ Footnotes[fn:2], foot[fn:test], digit only[3], and [fn:inline:anonymous footnote
(should-not
(equal
(org-test-with-temp-text
- (format "#+INCLUDE: \"%s/examples/include2.org\" src emacs-lisp" org-test-dir)
+ (format "#+INCLUDE: \"%s/examples/include2.org\" src emacs-lisp"
+ org-test-dir)
(org-export-expand-include-keyword)
(buffer-string))
(org-test-with-temp-text
- (format "#+INCLUDE: \"%s/examples/include2.org\" src emacs-lisp :minlevel 1" org-test-dir)
+ (format
+ "#+INCLUDE: \"%s/examples/include2.org\" src emacs-lisp :minlevel 1"
+ org-test-dir)
(org-export-expand-include-keyword)
(buffer-string))))
;; INCLUDE assigns the relative :minlevel conditional on narrowing.
(should
(org-test-with-temp-text-in-file
- (format "* h1\n<point>#+INCLUDE: \"%s/examples/include.org::#ah\"" org-test-dir)
+ (format "* h1\n<point>#+INCLUDE: \"%s/examples/include.org::#ah\""
+ org-test-dir)
(narrow-to-region (point) (point-max))
(org-export-expand-include-keyword)
(eq 1 (org-current-level))))
;; If :minlevel is present do not alter it.
(should
(org-test-with-temp-text
- (format "* h1\n<point>#+INCLUDE: \"%s/examples/include.org::#ah\" :minlevel 3" org-test-dir)
+ (format
+ "* h1\n<point>#+INCLUDE: \"%s/examples/include.org::#ah\" :minlevel 3"
+ org-test-dir)
(narrow-to-region (point) (point-max))
(org-export-expand-include-keyword)
(eq 3 (org-current-level)))))
(ert-deftest test-org-export/expand-macro ()
"Test macro expansion in an Org buffer."
+ (require 'ox-org)
;; Standard macro expansion.
(should
(equal "#+MACRO: macro1 value\nvalue\n"
@@ -1873,7 +1886,7 @@ Para2"
;; Test nested footnotes order.
(should
(equal
- '((1 . "fn:1") (2 . "fn:2") (3 . "fn:3") (3 . "fn:3") (4))
+ '((1 . "1") (2 . "2") (3 . "3") (3 . "3") (4))
(org-test-with-parsed-data
"Text[fn:1:A[fn:2]] [fn:3].\n\n[fn:2] B [fn:3] [fn::D].\n\n[fn:3] C."
(org-element-map tree 'footnote-reference
@@ -1904,7 +1917,7 @@ Para2"
;; then footnote definitions.
(should
(equal
- '(("fn:1" . 1) ("fn:2" . 2) ("fn:3" . 3) ("fn:3" . 3))
+ '(("1" . 1) ("2" . 2) ("3" . 3) ("3" . 3))
(org-test-with-parsed-data
"Text[fn:1][fn:2][fn:3]\n\n[fn:1] Def[fn:3]\n[fn:2] Def\n[fn:3] Def"
(org-element-map tree 'footnote-reference
@@ -1914,7 +1927,7 @@ Para2"
info))))
(should
(equal
- '(("fn:1" . 1) ("fn:2" . 3) ("fn:3" . 2) ("fn:3" . 2))
+ '(("1" . 1) ("2" . 3) ("3" . 2) ("3" . 2))
(org-test-with-parsed-data
"Text[fn:1][fn:2][fn:3]\n\n[fn:1] Def[fn:3]\n[fn:2] Def\n[fn:3] Def"
(org-element-map tree 'footnote-reference
@@ -1936,7 +1949,7 @@ Para2"
;; Limit number to provided DATA, when non-nil.
(should
(equal
- '((1 "fn:2"))
+ '((1 "2"))
(org-test-with-parsed-data
"Text[fn:1]\n* H\nText[fn:2]\n\n[fn:1] D1\n[fn:2] D2"
(mapcar #'butlast
@@ -1944,14 +1957,14 @@ Para2"
info (org-element-map tree 'headline #'identity info t))))))
(should
(equal
- '((1 "fn:1") (2 "fn:2"))
+ '((1 "1") (2 "2"))
(org-test-with-parsed-data
"Text[fn:1]\n* H\nText[fn:2]\n\n[fn:1] D1\n[fn:2] D2"
(mapcar #'butlast (org-export-collect-footnote-definitions info)))))
;; With optional argument BODY-FIRST, first check body, then
;; footnote definitions.
(should
- (equal '("fn:1" "fn:3" "fn:2" nil)
+ (equal '("1" "3" "2" nil)
(org-test-with-parsed-data "Text[fn:1:A[fn:2]] [fn:3].
\[fn:2] B [fn:3] [fn::D].
@@ -1960,7 +1973,7 @@ Para2"
(mapcar (lambda (e) (nth 1 e))
(org-export-collect-footnote-definitions info nil t)))))
(should-not
- (equal '("fn:1" "fn:3" "fn:2" nil)
+ (equal '("1" "3" "2" nil)
(org-test-with-parsed-data "Text[fn:1:A[fn:2]] [fn:3].
\[fn:2] B [fn:3] [fn::D].
@@ -1976,9 +1989,9 @@ Para2"
;; Read every type of footnote.
(should
(equal
- '((1 . "A\n") (2 . "B") (3 . "C") (4 . "D"))
+ '((1 . "A\n") (2 . "C") (3 . "D"))
(org-test-with-parsed-data
- "Text[fn:1] [1] [fn:label:C] [fn::D]\n\n[fn:1] A\n\n[1] B"
+ "Text[fn:1] [fn:label:C] [fn::D]\n\n[fn:1] A\n"
(org-element-map tree 'footnote-reference
(lambda (ref)
(let ((def (org-export-get-footnote-definition ref info)))
@@ -1990,7 +2003,7 @@ Para2"
;; Test nested footnote in invisible definitions.
(should
(= 2
- (org-test-with-temp-text "Text[1]\n\n[1] B [2]\n\n[2] C."
+ (org-test-with-temp-text "Text[fn:1]\n\n[fn:1] B [fn:2]\n\n[fn:2] C."
(narrow-to-region (point) (line-end-position))
(catch 'exit
(org-export-as
@@ -2497,7 +2510,10 @@ Para2"
(org-export-resolve-fuzzy-link link info) info)) info t))))
;; Link to a target in a footnote should return footnote's number.
(org-test-with-parsed-data "
-Paragraph[1][2][fn:lbl3:C<<target>>][[test]][[target]]\n[1] A\n\n[2] <<test>>B"
+Paragraph[fn:1][fn:2][fn:lbl3:C<<target>>][[test]][[target]]
+\[fn:1] A
+
+\[fn:2] <<test>>B"
(should
(equal '(2 3)
(org-element-map tree 'link