forked from mirrors/org-mode
ox: Fix footnotes in included files
* lisp/ox.el (org-export--prepare-file-contents): Do not error when including multiple footnotes with the same label. * testing/lisp/test-ox.el (test-org-export/expand-include): Update test. Reported-by: Leonard Randall <leonard.a.randall@gmail.com> <http://permalink.gmane.org/gmane.emacs.orgmode/100906>
This commit is contained in:
parent
a2662dc365
commit
a7394224aa
25
lisp/ox.el
25
lisp/ox.el
|
@ -3371,20 +3371,20 @@ lines, include only those lines.
|
||||||
Optional argument IND, when non-nil, is an integer specifying the
|
Optional argument IND, when non-nil, is an integer specifying the
|
||||||
global indentation of returned contents. Since its purpose is to
|
global indentation of returned contents. Since its purpose is to
|
||||||
allow an included file to stay in the same environment it was
|
allow an included file to stay in the same environment it was
|
||||||
created \(i.e. a list item), it doesn't apply past the first
|
created (e.g., a list item), it doesn't apply past the first
|
||||||
headline encountered.
|
headline encountered.
|
||||||
|
|
||||||
Optional argument MINLEVEL, when non-nil, is an integer
|
Optional argument MINLEVEL, when non-nil, is an integer
|
||||||
specifying the level that any top-level headline in the included
|
specifying the level that any top-level headline in the included
|
||||||
file should have.
|
file should have.
|
||||||
|
|
||||||
Optional argument ID is an integer that will be inserted before
|
Optional argument ID is an integer that will be inserted before
|
||||||
each footnote definition and reference if FILE is an Org file.
|
each footnote definition and reference if FILE is an Org file.
|
||||||
This is useful to avoid conflicts when more than one Org file
|
This is useful to avoid conflicts when more than one Org file
|
||||||
with footnotes is included in a document.
|
with footnotes is included in a document.
|
||||||
|
|
||||||
Optional argument FOOTNOTES is a hash-table to store footnotes in
|
Optional argument FOOTNOTES is a hash-table to store footnotes in
|
||||||
the included document.
|
the included document."
|
||||||
"
|
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(insert-file-contents file)
|
(insert-file-contents file)
|
||||||
(when lines
|
(when lines
|
||||||
|
@ -3413,7 +3413,7 @@ the included document.
|
||||||
(delete-region (point) (point-max))
|
(delete-region (point) (point-max))
|
||||||
;; If IND is set, preserve indentation of include keyword until
|
;; If IND is set, preserve indentation of include keyword until
|
||||||
;; the first headline encountered.
|
;; the first headline encountered.
|
||||||
(when ind
|
(when (and ind (> ind 0))
|
||||||
(unless (eq major-mode 'org-mode)
|
(unless (eq major-mode 'org-mode)
|
||||||
(let ((org-inhibit-startup t)) (org-mode)))
|
(let ((org-inhibit-startup t)) (org-mode)))
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
|
@ -3435,21 +3435,23 @@ the included document.
|
||||||
(let ((levels (org-map-entries
|
(let ((levels (org-map-entries
|
||||||
(lambda () (org-reduced-level (org-current-level))))))
|
(lambda () (org-reduced-level (org-current-level))))))
|
||||||
(when levels
|
(when levels
|
||||||
(let ((offset (- minlevel (apply 'min levels))))
|
(let ((offset (- minlevel (apply #'min levels))))
|
||||||
(unless (zerop offset)
|
(unless (zerop offset)
|
||||||
(when org-odd-levels-only (setq offset (* offset 2)))
|
(when org-odd-levels-only (setq offset (* offset 2)))
|
||||||
;; Only change stars, don't bother moving whole
|
;; Only change stars, don't bother moving whole
|
||||||
;; sections.
|
;; sections.
|
||||||
(org-map-entries
|
(org-map-entries
|
||||||
(lambda () (if (< offset 0) (delete-char (abs offset))
|
(lambda ()
|
||||||
(insert (make-string offset ?*)))))))))))
|
(if (< offset 0) (delete-char (abs offset))
|
||||||
|
(insert (make-string offset ?*)))))))))))
|
||||||
;; Append ID to all footnote references and definitions, so they
|
;; Append ID to all footnote references and definitions, so they
|
||||||
;; become file specific and cannot collide with footnotes in other
|
;; become file specific and cannot collide with footnotes in other
|
||||||
;; included files. Further, collect relevant footnotes outside of
|
;; included files. Further, collect relevant footnotes outside of
|
||||||
;; LINES.
|
;; LINES.
|
||||||
(when id
|
(when id
|
||||||
(let ((marker-min (point-min-marker))
|
(let ((marker-min (point-min-marker))
|
||||||
(marker-max (point-max-marker)))
|
(marker-max (point-max-marker))
|
||||||
|
seen)
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(while (re-search-forward org-footnote-re nil t)
|
(while (re-search-forward org-footnote-re nil t)
|
||||||
(let ((reference (org-element-context)))
|
(let ((reference (org-element-context)))
|
||||||
|
@ -3466,7 +3468,10 @@ the included document.
|
||||||
(let ((new-label (org-export--update-footnote-label
|
(let ((new-label (org-export--update-footnote-label
|
||||||
(org-element-property :begin reference)
|
(org-element-property :begin reference)
|
||||||
digit-label id)))
|
digit-label id)))
|
||||||
(unless (eq (org-element-property :type reference) 'inline)
|
(unless (or (eq (org-element-property :type reference)
|
||||||
|
'inline)
|
||||||
|
(member label seen))
|
||||||
|
(push label seen)
|
||||||
(org-with-wide-buffer
|
(org-with-wide-buffer
|
||||||
(let* ((definition (org-footnote-get-definition label))
|
(let* ((definition (org-footnote-get-definition label))
|
||||||
(beginning (nth 1 definition)))
|
(beginning (nth 1 definition)))
|
||||||
|
@ -3475,7 +3480,7 @@ the included document.
|
||||||
"Definition not found for footnote %s in file %s"
|
"Definition not found for footnote %s in file %s"
|
||||||
label file))
|
label file))
|
||||||
(if (or (< beginning marker-min)
|
(if (or (< beginning marker-min)
|
||||||
(> beginning marker-max))
|
(>= beginning marker-max))
|
||||||
;; Store since footnote-definition is
|
;; Store since footnote-definition is
|
||||||
;; outside of LINES.
|
;; outside of LINES.
|
||||||
(puthash new-label
|
(puthash new-label
|
||||||
|
|
|
@ -974,7 +974,7 @@ text
|
||||||
(length
|
(length
|
||||||
(delete-dups
|
(delete-dups
|
||||||
(let ((contents "
|
(let ((contents "
|
||||||
Footnotes[fn:1], [fn:test] and [fn:inline:anonymous footnote].
|
Footnotes[fn:1], [fn:test], [fn:test] and [fn:inline:anonymous footnote].
|
||||||
\[fn:1] Footnote 1
|
\[fn:1] Footnote 1
|
||||||
\[fn:test] Footnote \"test\""))
|
\[fn:test] Footnote \"test\""))
|
||||||
(org-test-with-temp-text-in-file contents
|
(org-test-with-temp-text-in-file contents
|
||||||
|
@ -987,8 +987,7 @@ Footnotes[fn:1], [fn:test] and [fn:inline:anonymous footnote].
|
||||||
(org-export-expand-include-keyword)
|
(org-export-expand-include-keyword)
|
||||||
(org-element-map (org-element-parse-buffer)
|
(org-element-map (org-element-parse-buffer)
|
||||||
'footnote-reference
|
'footnote-reference
|
||||||
(lambda (ref)
|
(lambda (r) (org-element-property :label r)))))))))))))
|
||||||
(org-element-property :label ref)))))))))))))
|
|
||||||
;; Footnotes labels are not local to each include keyword.
|
;; Footnotes labels are not local to each include keyword.
|
||||||
(should
|
(should
|
||||||
(= 4
|
(= 4
|
||||||
|
|
Loading…
Reference in a new issue