Function: org-export--missing-definitions

org-export--missing-definitions is a byte-compiled function defined in ox.el.gz.

Signature

(org-export--missing-definitions TREE DEFINITIONS)

Documentation

List footnote definitions missing from TREE.

Missing definitions are searched within DEFINITIONS, which is a list of footnote definitions or in the widened buffer.

Source Code

;; Defined in /usr/src/emacs/lisp/org/ox.el.gz
(defun org-export--missing-definitions (tree definitions)
  "List footnote definitions missing from TREE.
Missing definitions are searched within DEFINITIONS, which is
a list of footnote definitions or in the widened buffer."
  (let* ((list-labels
	  (lambda (data)
	    ;; List all footnote labels encountered in DATA.  Inline
	    ;; footnote references are ignored.
	    (org-element-map data 'footnote-reference
	      (lambda (reference)
		(and (eq (org-element-property :type reference) 'standard)
		     (org-element-property :label reference))))))
	 defined undefined missing-definitions)
    ;; Partition DIRECT-REFERENCES between DEFINED and UNDEFINED
    ;; references.
    (let ((known-definitions
	   (org-element-map tree '(footnote-reference footnote-definition)
	     (lambda (f)
	       (and (or (org-element-type-p f 'footnote-definition)
			(eq (org-element-property :type f) 'inline))
		    (org-element-property :label f)))))
	  ) ;; seen
      (dolist (l (funcall list-labels tree))
	(cond ;; ((member l seen))
	 ((member l known-definitions) (push l defined))
	 (t (push l undefined)))))
    ;; Complete MISSING-DEFINITIONS by finding the definition of every
    ;; undefined label, first by looking into DEFINITIONS, then by
    ;; searching the widened buffer.  This is a recursive process
    ;; since definitions found can themselves contain an undefined
    ;; reference.
    (while undefined
      (let* ((label (pop undefined))
	     (definition
	      (cond
	       ((cl-some
		 (lambda (d) (and (equal (org-element-property :label d) label)
			     d))
		 definitions))
	       ((pcase (org-footnote-get-definition label)
		  (`(,_ ,beg . ,_)
		   (org-with-wide-buffer
		    (goto-char beg)
		    (let ((datum (org-element-context)))
		      (if (org-element-type-p datum 'footnote-reference)
			  datum
			;; Parse definition with contents.
			(save-restriction
			  (narrow-to-region
			   (org-element-begin datum)
			   (org-element-end datum))
			  (org-element-map (org-element-parse-buffer nil nil 'defer)
			      'footnote-definition #'identity nil t))))))
		  (_ nil)))
	       (t (user-error "Definition not found for footnote %s" label)))))
	(push label defined)
	(push definition missing-definitions)
	;; Look for footnote references within DEFINITION, since
	;; we may need to also find their definition.
	(dolist (l (funcall list-labels definition))
	  (unless (or (member l defined)    ;Known label
		      (member l undefined)) ;Processed later
	    (push l undefined)))))
    ;; MISSING-DEFINITIONS may contain footnote references with inline
    ;; definitions.  Make sure those are changed into real footnote
    ;; definitions.
    (mapcar (lambda (d)
	      (if (org-element-type-p d 'footnote-definition) d
		(let ((label (org-element-property :label d)))
		  (apply #'org-element-create
			 'footnote-definition `(:label ,label :post-blank 1)
			 (org-element-contents d)))))
	    missing-definitions)))