org-element: Remove dependency on org-footnote predicates

* contrib/lisp/org-element.el (org-element-footnote-definition-parser):
  Remove the need for `org-footnote-at-definition-p'.
  (org-element-footnote-reference-parser): Remove the need for
  `org-footnote-at-reference-p'.
(org-element-footnote-reference-successor): Do not use
`org-footnote-get-next-reference'.
* testing/lisp/test-org-element.el: Add test.
This commit is contained in:
Nicolas Goaziou 2012-04-06 23:50:00 +02:00
parent 4019559ee2
commit 8453ac1bf3
2 changed files with 110 additions and 29 deletions

View File

@ -273,20 +273,27 @@ CONTENTS is the contents of the element."
(defun org-element-footnote-definition-parser ()
"Parse a footnote definition.
Return a list whose car is `footnote-definition' and cdr is
Return a list whose CAR is `footnote-definition' and CDR is
a plist containing `:label', `:begin' `:end', `:contents-begin',
`:contents-end' and `:post-blank' keywords."
`:contents-end' and `:post-blank' keywords.
Assume point is at the beginning of the footnote definition."
(save-excursion
(let* ((f-def (org-footnote-at-definition-p))
(label (car f-def))
(keywords (progn (goto-char (nth 1 f-def))
(org-element-collect-affiliated-keywords)))
(looking-at org-footnote-definition-re)
(let* ((label (org-match-string-no-properties 1))
(keywords (org-element-collect-affiliated-keywords))
(begin (car keywords))
(contents-begin (progn (looking-at (concat "\\[" label "\\]"))
(goto-char (match-end 0))
(contents-begin (progn (search-forward "]")
(org-skip-whitespace)
(point)))
(contents-end (goto-char (nth 2 f-def)))
(contents-end (if (progn
(end-of-line)
(re-search-forward
(concat org-outline-regexp-bol "\\|"
org-footnote-definition-re "\\|"
"^[ \t]*$") nil t))
(match-beginning 0)
(point-max)))
(end (progn (org-skip-whitespace)
(if (eobp) (point) (point-at-bol)))))
`(footnote-definition
@ -1783,28 +1790,37 @@ its beginning position."
(defun org-element-footnote-reference-parser ()
"Parse footnote reference at point.
Return a list whose car is `footnote-reference' and cdr a plist
Return a list whose CAR is `footnote-reference' and CDR a plist
with `:label', `:type', `:inline-definition', `:begin', `:end'
and `:post-blank' as keywords."
(save-excursion
(let* ((ref (org-footnote-at-reference-p))
(label (car ref))
(inline-def
(let ((raw-def (nth 3 ref)))
(and raw-def
(org-element-parse-secondary-string
raw-def
(cdr (assq 'footnote-reference
org-element-string-restrictions))))))
(type (if (nth 3 ref) 'inline 'standard))
(begin (nth 1 ref))
(post-blank (progn (goto-char (nth 2 ref))
(looking-at org-footnote-re)
(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))
(inner-begin (match-end 0))
(inner-end
(let ((count 1))
(forward-char)
(while (and (> count 0) (re-search-forward "[][]" nil t))
(if (equal (match-string 0) "[") (incf count) (decf count)))
(1- (point))))
(post-blank (progn (goto-char (1+ inner-end))
(skip-chars-forward " \t")))
(end (point)))
(end (point))
(inline-definition
(and (eq type 'inline)
(org-element-parse-secondary-string
(buffer-substring inner-begin inner-end)
(cdr (assq 'footnote-reference
org-element-string-restrictions))))))
`(footnote-reference
(:label ,label
:type ,type
:inline-definition ,inline-def
:inline-definition ,inline-definition
:begin ,begin
:end ,end
:post-blank ,post-blank)))))
@ -1825,11 +1841,19 @@ CONTENTS is nil."
LIMIT bounds the search.
Return value is a cons cell whose car is `footnote-reference' and
cdr is beginning position."
(let (fn-ref)
(when (setq fn-ref (org-footnote-get-next-reference nil nil limit))
(cons 'footnote-reference (nth 1 fn-ref)))))
Return value is a cons cell whose CAR is `footnote-reference' and
CDR is beginning position."
(save-excursion
(catch 'exit
(while (re-search-forward org-footnote-re limit t)
(save-excursion
(let ((beg (match-beginning 0))
(count 1))
(backward-char)
(while (re-search-forward "[][]" limit t)
(if (equal (match-string 0) "[") (incf count) (decf count))
(when (zerop count)
(throw 'exit (cons 'footnote-reference beg))))))))))
;;;; Inline Babel Call

View File

@ -203,6 +203,63 @@
(equal (org-element-property :label-fmt element) "[ref:%s]"))))))
;;;; Footnotes references and definitions
(ert-deftest test-org-element/footnote-reference ()
"Test footnote-reference parsing."
;; 1. Parse a standard reference.
(org-test-with-temp-text "[fn:label]"
(should (equal (org-element-footnote-reference-parser)
'(footnote-reference
(:label "fn:label" :type standard :inline-definition nil
:begin 1 :end 11 :post-blank 0)))))
;; 2. Parse a normalized reference.
(org-test-with-temp-text "[1]"
(should (equal (org-element-footnote-reference-parser)
'(footnote-reference
(:label "1" :type standard :inline-definition nil
:begin 1 :end 4 :post-blank 0)))))
;; 3. Parse an inline reference.
(org-test-with-temp-text "[fn:test:def]"
(should (equal (org-element-footnote-reference-parser)
'(footnote-reference
(:label "fn:test" :type inline :inline-definition ("def")
:begin 1 :end 14 :post-blank 0)))))
;; 4. Parse an anonymous reference.
(org-test-with-temp-text "[fn::def]"
(should (equal (org-element-footnote-reference-parser)
'(footnote-reference
(:label nil :type inline :inline-definition ("def")
:begin 1 :end 10 :post-blank 0)))))
;; 5. Parse nested footnotes.
(org-test-with-temp-text "[fn::def [fn:label]]"
(should
(equal
(org-element-footnote-reference-parser)
'(footnote-reference
(:label nil :type inline
:inline-definition
("def "
(footnote-reference
(:label "fn:label" :type standard :inline-definition nil
:begin 5 :end 15 :post-blank 0)))
:begin 1 :end 21 :post-blank 0)))))
;; 6. Parse adjacent footnotes.
(org-test-with-temp-text "[fn:label1][fn:label2]"
(should
(equal
(org-element-footnote-reference-parser)
'(footnote-reference
(:label "fn:label1" :type standard :inline-definition nil :begin 1
:end 12 :post-blank 0)))))
;; 7. Only properly closed footnotes are recognized as such.
(org-test-with-temp-text "Text [fn:label"
(should-not
(org-element-map
(org-element-parse-buffer) 'footnote-reference 'identity))))
;;; Granularity