forked from mirrors/org-mode
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.
This commit is contained in:
parent
df9ccbd119
commit
ca6ecf9e49
|
@ -194,8 +194,8 @@ is not sufficient to know if point is at a paragraph ending. See
|
||||||
"Complete list of object types.")
|
"Complete list of object types.")
|
||||||
|
|
||||||
(defconst org-element-recursive-objects
|
(defconst org-element-recursive-objects
|
||||||
'(bold italic link subscript radio-target strike-through superscript
|
'(bold footnote-reference italic link subscript radio-target strike-through
|
||||||
table-cell underline)
|
superscript table-cell underline)
|
||||||
"List of recursive object types.")
|
"List of recursive object types.")
|
||||||
|
|
||||||
(defvar org-element-block-name-alist
|
(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
|
(defconst org-element-secondary-value-alist
|
||||||
'((headline . :title)
|
'((headline . :title)
|
||||||
(inlinetask . :title)
|
(inlinetask . :title)
|
||||||
(item . :tag)
|
(item . :tag))
|
||||||
(footnote-reference . :inline-definition))
|
|
||||||
"Alist between element types and location of secondary value.")
|
"Alist between element types and location of secondary value.")
|
||||||
|
|
||||||
(defconst org-element-object-variables '(org-link-abbrev-alist-local)
|
(defconst org-element-object-variables '(org-link-abbrev-alist-local)
|
||||||
|
@ -2755,13 +2754,14 @@ CONTENTS is nil."
|
||||||
|
|
||||||
When at a footnote reference, return a list whose car is
|
When at a footnote reference, return a list whose car is
|
||||||
`footnote-reference' and cdr a plist with `:label', `:type',
|
`footnote-reference' and cdr a plist with `:label', `:type',
|
||||||
`:inline-definition', `:begin', `:end' and `:post-blank' as
|
`:begin', `:end', `:content-begin', `:contents-end' and
|
||||||
keywords. Otherwise, return nil."
|
`:post-blank' as keywords. Otherwise, return nil."
|
||||||
(catch 'no-object
|
(catch 'no-object
|
||||||
(when (looking-at org-footnote-re)
|
(when (looking-at org-footnote-re)
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(let* ((begin (point))
|
(let* ((begin (point))
|
||||||
(label (or (org-match-string-no-properties 2)
|
(label
|
||||||
|
(or (org-match-string-no-properties 2)
|
||||||
(org-match-string-no-properties 3)
|
(org-match-string-no-properties 3)
|
||||||
(and (match-string 1)
|
(and (match-string 1)
|
||||||
(concat "fn:" (org-match-string-no-properties 1)))))
|
(concat "fn:" (org-match-string-no-properties 1)))))
|
||||||
|
@ -2776,32 +2776,22 @@ keywords. Otherwise, return nil."
|
||||||
(1- (point))))
|
(1- (point))))
|
||||||
(post-blank (progn (goto-char (1+ inner-end))
|
(post-blank (progn (goto-char (1+ inner-end))
|
||||||
(skip-chars-forward " \t")))
|
(skip-chars-forward " \t")))
|
||||||
(end (point))
|
(end (point)))
|
||||||
(footnote-reference
|
|
||||||
(list 'footnote-reference
|
(list 'footnote-reference
|
||||||
(list :label label
|
(list :label label
|
||||||
:type type
|
:type type
|
||||||
:begin begin
|
:begin begin
|
||||||
:end end
|
:end end
|
||||||
:post-blank post-blank))))
|
:contents-begin (and (eq type 'inline) inner-begin)
|
||||||
(org-element-put-property
|
:contents-end (and (eq type 'inline) inner-end)
|
||||||
footnote-reference :inline-definition
|
:post-blank post-blank)))))))
|
||||||
(and (eq type 'inline)
|
|
||||||
(org-element-parse-secondary-string
|
|
||||||
(buffer-substring inner-begin inner-end)
|
|
||||||
(org-element-restriction 'footnote-reference)
|
|
||||||
footnote-reference))))))))
|
|
||||||
|
|
||||||
(defun org-element-footnote-reference-interpreter (footnote-reference contents)
|
(defun org-element-footnote-reference-interpreter (footnote-reference contents)
|
||||||
"Interpret FOOTNOTE-REFERENCE object as Org syntax.
|
"Interpret FOOTNOTE-REFERENCE object as Org syntax.
|
||||||
CONTENTS is nil."
|
CONTENTS is nil."
|
||||||
(let ((label (or (org-element-property :label footnote-reference) "fn:"))
|
(format "[%s]"
|
||||||
(def
|
(concat (or (org-element-property :label footnote-reference) "fn:")
|
||||||
(let ((inline-def
|
(and contents (concat ":" contents)))))
|
||||||
(org-element-property :inline-definition footnote-reference)))
|
|
||||||
(if (not inline-def) ""
|
|
||||||
(concat ":" (org-element-interpret-data inline-def))))))
|
|
||||||
(format "[%s]" (concat label def))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;; Inline Babel Call
|
;;;; Inline Babel Call
|
||||||
|
|
34
lisp/ox.el
34
lisp/ox.el
|
@ -1579,17 +1579,31 @@ inferior to file-local settings."
|
||||||
(let (alist)
|
(let (alist)
|
||||||
(org-with-wide-buffer
|
(org-with-wide-buffer
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(while (re-search-forward org-footnote-definition-re nil t)
|
(while (re-search-forward org-footnote-re nil t)
|
||||||
(let ((def (save-match-data (org-element-at-point))))
|
(backward-char)
|
||||||
(when (eq (org-element-type def) 'footnote-definition)
|
(let ((fn (save-match-data (org-element-context))))
|
||||||
|
(case (org-element-type fn)
|
||||||
|
(footnote-definition
|
||||||
(push
|
(push
|
||||||
(cons (org-element-property :label def)
|
(cons (org-element-property :label fn)
|
||||||
(let ((cbeg (org-element-property :contents-begin def)))
|
(let ((cbeg (org-element-property :contents-begin fn)))
|
||||||
(when cbeg
|
(when cbeg
|
||||||
(org-element--parse-elements
|
(org-element--parse-elements
|
||||||
cbeg (org-element-property :contents-end def)
|
cbeg (org-element-property :contents-end fn)
|
||||||
nil nil nil nil (list 'org-data nil)))))
|
nil nil nil nil (list 'org-data nil)))))
|
||||||
alist))))
|
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))
|
alist))
|
||||||
:id-alist
|
:id-alist
|
||||||
;; Collect id references.
|
;; 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)
|
(defun org-export-get-footnote-definition (footnote-reference info)
|
||||||
"Return definition of FOOTNOTE-REFERENCE as parsed data.
|
"Return definition of FOOTNOTE-REFERENCE as parsed data.
|
||||||
INFO is the plist used as a communication channel. If no such
|
INFO is the plist used as a communication channel. If no such
|
||||||
definition can be found, return the \"DEFINITION NOT FOUND\"
|
definition can be found, return \"DEFINITION NOT FOUND\"."
|
||||||
string."
|
|
||||||
(let ((label (org-element-property :label footnote-reference)))
|
(let ((label (org-element-property :label footnote-reference)))
|
||||||
(or (org-element-property :inline-definition footnote-reference)
|
(or (if label
|
||||||
(cdr (assoc label (plist-get info :footnote-definition-alist)))
|
(cdr (assoc label (plist-get info :footnote-definition-alist)))
|
||||||
|
(org-element-contents footnote-reference))
|
||||||
"DEFINITION NOT FOUND.")))
|
"DEFINITION NOT FOUND.")))
|
||||||
|
|
||||||
(defun org-export-get-footnote-number (footnote info)
|
(defun org-export-get-footnote-number (footnote info)
|
||||||
|
|
|
@ -891,43 +891,43 @@ Some other text
|
||||||
|
|
||||||
(ert-deftest test-org-element/footnote-reference-parser ()
|
(ert-deftest test-org-element/footnote-reference-parser ()
|
||||||
"Test `footnote-reference' parser."
|
"Test `footnote-reference' parser."
|
||||||
;; 1. Parse a standard reference.
|
;; Parse a standard reference.
|
||||||
|
(should
|
||||||
(org-test-with-temp-text "Text[fn:label]"
|
(org-test-with-temp-text "Text[fn:label]"
|
||||||
(should
|
|
||||||
(org-element-map
|
(org-element-map
|
||||||
(org-element-parse-buffer) 'footnote-reference 'identity)))
|
(org-element-parse-buffer) 'footnote-reference 'identity)))
|
||||||
;; 2. Parse a normalized reference.
|
;; Parse a normalized reference.
|
||||||
|
(should
|
||||||
(org-test-with-temp-text "Text[1]"
|
(org-test-with-temp-text "Text[1]"
|
||||||
(should
|
|
||||||
(org-element-map
|
(org-element-map
|
||||||
(org-element-parse-buffer) 'footnote-reference 'identity)))
|
(org-element-parse-buffer) 'footnote-reference 'identity)))
|
||||||
;; 3. Parse an inline reference.
|
;; Parse an inline reference.
|
||||||
|
(should
|
||||||
(org-test-with-temp-text "Text[fn:test:def]"
|
(org-test-with-temp-text "Text[fn:test:def]"
|
||||||
(should
|
|
||||||
(org-element-map
|
(org-element-map
|
||||||
(org-element-parse-buffer) 'footnote-reference 'identity)))
|
(org-element-parse-buffer) 'footnote-reference 'identity)))
|
||||||
;; 4. Parse an anonymous reference.
|
;; Parse an anonymous reference.
|
||||||
|
(should
|
||||||
(org-test-with-temp-text "Text[fn::def]"
|
(org-test-with-temp-text "Text[fn::def]"
|
||||||
(should
|
|
||||||
(org-element-map
|
(org-element-map
|
||||||
(org-element-parse-buffer) 'footnote-reference 'identity)))
|
(org-element-parse-buffer) 'footnote-reference 'identity)))
|
||||||
;; 5. Parse nested footnotes.
|
;; Parse nested footnotes.
|
||||||
|
(should
|
||||||
|
(= 2
|
||||||
|
(length
|
||||||
(org-test-with-temp-text "Text[fn::def [fn:label]]"
|
(org-test-with-temp-text "Text[fn::def [fn:label]]"
|
||||||
(should
|
|
||||||
(= 2
|
|
||||||
(length
|
|
||||||
(org-element-map
|
(org-element-map
|
||||||
(org-element-parse-buffer) 'footnote-reference 'identity)))))
|
(org-element-parse-buffer) 'footnote-reference 'identity)))))
|
||||||
;; 6. Parse adjacent footnotes.
|
;; Parse adjacent footnotes.
|
||||||
|
(should
|
||||||
(org-test-with-temp-text "Text[fn:label1][fn:label2]"
|
(org-test-with-temp-text "Text[fn:label1][fn:label2]"
|
||||||
(should
|
|
||||||
(= 2
|
(= 2
|
||||||
(length
|
(length
|
||||||
(org-element-map
|
(org-element-map
|
||||||
(org-element-parse-buffer) 'footnote-reference 'identity)))))
|
(org-element-parse-buffer) 'footnote-reference 'identity)))))
|
||||||
;; 7. Only properly closed footnotes are recognized as such.
|
;; Only properly closed footnotes are recognized as such.
|
||||||
(org-test-with-temp-text "Text[fn:label"
|
|
||||||
(should-not
|
(should-not
|
||||||
|
(org-test-with-temp-text "Text[fn:label"
|
||||||
(org-element-map
|
(org-element-map
|
||||||
(org-element-parse-buffer) 'footnote-reference 'identity))))
|
(org-element-parse-buffer) 'footnote-reference 'identity))))
|
||||||
|
|
||||||
|
@ -3136,6 +3136,11 @@ Paragraph \\alpha."
|
||||||
(eq 'table-cell
|
(eq 'table-cell
|
||||||
(org-test-with-temp-text "|a|b|c"
|
(org-test-with-temp-text "|a|b|c"
|
||||||
(goto-char (point-max))
|
(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))))))
|
(org-element-type (org-element-context))))))
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue