summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2014-07-06 09:08:57 (GMT)
committer Nicolas Goaziou <mail@nicolasgoaziou.fr>2014-07-06 09:24:12 (GMT)
commitca6ecf9e498e6c4750f279e9f0ea0185bc8b1d10 (patch)
treeb709f136e89f674c50f9ecb65558d02545bb41dc
parentdf9ccbd11918c8e7273b98520f335573f512aa05 (diff)
downloadorg-mode-ca6ecf9e498e6c4750f279e9f0ea0185bc8b1d10.zip
org-mode-ca6ecf9e498e6c4750f279e9f0ea0185bc8b1d10.tar.gz
org-element: Remove :inline-definition from inline footnotes
* lisp/org-element.el (org-element-recursive-objects): Add `footnote-reference'. (org-element-secondary-value-alist): Remove reference to `footnote-reference'. (org-element-footnote-reference-parser): Definition for inline references is stored as the contents of the reference, not in a secondary string. (org-element-footnote-reference-interpreter): Apply changes from parser. * lisp/ox.el (org-export-get-footnote-definition, org-export-get-environment): Apply changes from parser. * testing/lisp/test-org-element.el (test-org-element/footnote-reference-parser): Update test. (test-org-element/context): Add test. Storing definition in a secondary string was a poor design choice as there is no "primary" string anyway. This also prevents `org-element-context' from finding objects within the inline definition.
-rw-r--r--lisp/org-element.el54
-rw-r--r--lisp/ox.el44
-rw-r--r--testing/lisp/test-org-element.el65
3 files changed, 86 insertions, 77 deletions
diff --git a/lisp/org-element.el b/lisp/org-element.el
index 1aa7fad..b69e9d1 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -194,8 +194,8 @@ is not sufficient to know if point is at a paragraph ending. See
"Complete list of object types.")
(defconst org-element-recursive-objects
- '(bold italic link subscript radio-target strike-through superscript
- table-cell underline)
+ '(bold footnote-reference italic link subscript radio-target strike-through
+ superscript table-cell underline)
"List of recursive object types.")
(defvar org-element-block-name-alist
@@ -341,8 +341,7 @@ still has an entry since one of its properties (`:title') does.")
(defconst org-element-secondary-value-alist
'((headline . :title)
(inlinetask . :title)
- (item . :tag)
- (footnote-reference . :inline-definition))
+ (item . :tag))
"Alist between element types and location of secondary value.")
(defconst org-element-object-variables '(org-link-abbrev-alist-local)
@@ -2755,16 +2754,17 @@ CONTENTS is nil."
When at a footnote reference, return a list whose car is
`footnote-reference' and cdr a plist with `:label', `:type',
-`:inline-definition', `:begin', `:end' and `:post-blank' as
-keywords. Otherwise, return nil."
+`:begin', `:end', `:content-begin', `:contents-end' and
+`:post-blank' as keywords. Otherwise, return nil."
(catch 'no-object
(when (looking-at org-footnote-re)
(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)))))
+ (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))
(inner-begin (match-end 0))
(inner-end
@@ -2776,32 +2776,22 @@ keywords. Otherwise, return nil."
(1- (point))))
(post-blank (progn (goto-char (1+ inner-end))
(skip-chars-forward " \t")))
- (end (point))
- (footnote-reference
- (list 'footnote-reference
- (list :label label
- :type type
- :begin begin
- :end end
- :post-blank post-blank))))
- (org-element-put-property
- footnote-reference :inline-definition
- (and (eq type 'inline)
- (org-element-parse-secondary-string
- (buffer-substring inner-begin inner-end)
- (org-element-restriction 'footnote-reference)
- footnote-reference))))))))
+ (end (point)))
+ (list 'footnote-reference
+ (list :label label
+ :type type
+ :begin begin
+ :end end
+ :contents-begin (and (eq type 'inline) inner-begin)
+ :contents-end (and (eq type 'inline) inner-end)
+ :post-blank post-blank)))))))
(defun org-element-footnote-reference-interpreter (footnote-reference contents)
"Interpret FOOTNOTE-REFERENCE object as Org syntax.
CONTENTS is nil."
- (let ((label (or (org-element-property :label footnote-reference) "fn:"))
- (def
- (let ((inline-def
- (org-element-property :inline-definition footnote-reference)))
- (if (not inline-def) ""
- (concat ":" (org-element-interpret-data inline-def))))))
- (format "[%s]" (concat label def))))
+ (format "[%s]"
+ (concat (or (org-element-property :label footnote-reference) "fn:")
+ (and contents (concat ":" contents)))))
;;;; Inline Babel Call
diff --git a/lisp/ox.el b/lisp/ox.el
index 4a538ae..7fbbed1 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -1579,17 +1579,31 @@ inferior to file-local settings."
(let (alist)
(org-with-wide-buffer
(goto-char (point-min))
- (while (re-search-forward org-footnote-definition-re nil t)
- (let ((def (save-match-data (org-element-at-point))))
- (when (eq (org-element-type def) 'footnote-definition)
- (push
- (cons (org-element-property :label def)
- (let ((cbeg (org-element-property :contents-begin def)))
- (when cbeg
- (org-element--parse-elements
- cbeg (org-element-property :contents-end def)
- nil nil nil nil (list 'org-data nil)))))
- alist))))
+ (while (re-search-forward org-footnote-re nil t)
+ (backward-char)
+ (let ((fn (save-match-data (org-element-context))))
+ (case (org-element-type fn)
+ (footnote-definition
+ (push
+ (cons (org-element-property :label fn)
+ (let ((cbeg (org-element-property :contents-begin fn)))
+ (when cbeg
+ (org-element--parse-elements
+ cbeg (org-element-property :contents-end fn)
+ nil nil nil nil (list 'org-data nil)))))
+ alist))
+ (footnote-reference
+ (let ((label (org-element-property :label fn))
+ (cbeg (org-element-property :contents-begin fn)))
+ (when (and label cbeg
+ (eq (org-element-property :type fn) 'inline))
+ (push
+ (cons label
+ (org-element-parse-secondary-string
+ (buffer-substring
+ cbeg (org-element-property :contents-end fn))
+ (org-element-restriction 'footnote-reference)))
+ alist)))))))
alist))
:id-alist
;; Collect id references.
@@ -3689,11 +3703,11 @@ INFO is the plist used as a communication channel."
(defun org-export-get-footnote-definition (footnote-reference info)
"Return definition of FOOTNOTE-REFERENCE as parsed data.
INFO is the plist used as a communication channel. If no such
-definition can be found, return the \"DEFINITION NOT FOUND\"
-string."
+definition can be found, return \"DEFINITION NOT FOUND\"."
(let ((label (org-element-property :label footnote-reference)))
- (or (org-element-property :inline-definition footnote-reference)
- (cdr (assoc label (plist-get info :footnote-definition-alist)))
+ (or (if label
+ (cdr (assoc label (plist-get info :footnote-definition-alist)))
+ (org-element-contents footnote-reference))
"DEFINITION NOT FOUND.")))
(defun org-export-get-footnote-number (footnote info)
diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el
index 42a19bf..b2b0c52 100644
--- a/testing/lisp/test-org-element.el
+++ b/testing/lisp/test-org-element.el
@@ -891,45 +891,45 @@ Some other text
(ert-deftest test-org-element/footnote-reference-parser ()
"Test `footnote-reference' parser."
- ;; 1. Parse a standard reference.
- (org-test-with-temp-text "Text[fn:label]"
- (should
+ ;; Parse a standard reference.
+ (should
+ (org-test-with-temp-text "Text[fn:label]"
(org-element-map
- (org-element-parse-buffer) 'footnote-reference 'identity)))
- ;; 2. Parse a normalized reference.
- (org-test-with-temp-text "Text[1]"
- (should
+ (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)))
- ;; 3. Parse an inline reference.
- (org-test-with-temp-text "Text[fn:test:def]"
- (should
+ (org-element-parse-buffer) 'footnote-reference 'identity)))
+ ;; Parse an inline reference.
+ (should
+ (org-test-with-temp-text "Text[fn:test:def]"
(org-element-map
- (org-element-parse-buffer) 'footnote-reference 'identity)))
- ;; 4. Parse an anonymous reference.
- (org-test-with-temp-text "Text[fn::def]"
- (should
+ (org-element-parse-buffer) 'footnote-reference 'identity)))
+ ;; Parse an anonymous reference.
+ (should
+ (org-test-with-temp-text "Text[fn::def]"
(org-element-map
- (org-element-parse-buffer) 'footnote-reference 'identity)))
- ;; 5. Parse nested footnotes.
- (org-test-with-temp-text "Text[fn::def [fn:label]]"
- (should
- (= 2
- (length
+ (org-element-parse-buffer) 'footnote-reference 'identity)))
+ ;; Parse nested footnotes.
+ (should
+ (= 2
+ (length
+ (org-test-with-temp-text "Text[fn::def [fn:label]]"
(org-element-map
- (org-element-parse-buffer) 'footnote-reference 'identity)))))
- ;; 6. Parse adjacent footnotes.
- (org-test-with-temp-text "Text[fn:label1][fn:label2]"
- (should
+ (org-element-parse-buffer) 'footnote-reference 'identity)))))
+ ;; Parse adjacent footnotes.
+ (should
+ (org-test-with-temp-text "Text[fn:label1][fn:label2]"
(= 2
(length
(org-element-map
- (org-element-parse-buffer) 'footnote-reference 'identity)))))
- ;; 7. Only properly closed footnotes are recognized as such.
- (org-test-with-temp-text "Text[fn:label"
- (should-not
+ (org-element-parse-buffer) 'footnote-reference 'identity)))))
+ ;; Only properly closed footnotes are recognized as such.
+ (should-not
+ (org-test-with-temp-text "Text[fn:label"
(org-element-map
- (org-element-parse-buffer) 'footnote-reference 'identity))))
+ (org-element-parse-buffer) 'footnote-reference 'identity))))
;;;; Headline
@@ -3136,6 +3136,11 @@ Paragraph \\alpha."
(eq 'table-cell
(org-test-with-temp-text "|a|b|c"
(goto-char (point-max))
+ (org-element-type (org-element-context)))))
+ ;; Special case: objects in inline footnotes.
+ (should
+ (eq 'link
+ (org-test-with-temp-text "[fn::[[<point>http://orgmode.org]]]"
(org-element-type (org-element-context))))))