Sfoglia il codice sorgente

ox: Correctly handle footnote section

* lisp/ox.el (org-export--collect-headline-numbering): Remove footnote
  section from TOC.
(org-export-collect-headlines): Do not count footnote section when
numbering a headline.
* testing/lisp/test-ox.el: Add tests.
Nicolas Goaziou 12 anni fa
parent
commit
39ed70495c
2 ha cambiato i file con 57 aggiunte e 38 eliminazioni
  1. 18 14
      lisp/ox.el
  2. 39 24
      testing/lisp/test-ox.el

+ 18 - 14
lisp/ox.el

@@ -1795,19 +1795,21 @@ DATA is the parse tree.  OPTIONS is the plist holding export
 options.
 options.
 
 
 Return an alist whose key is an headline and value is its
 Return an alist whose key is an headline and value is its
-associated numbering \(in the shape of a list of numbers\)."
+associated numbering \(in the shape of a list of numbers\) or nil
+for a footnotes section."
   (let ((numbering (make-vector org-export-max-depth 0)))
   (let ((numbering (make-vector org-export-max-depth 0)))
     (org-element-map data 'headline
     (org-element-map data 'headline
       (lambda (headline)
       (lambda (headline)
-	(let ((relative-level
-	       (1- (org-export-get-relative-level headline options))))
-	  (cons
-	   headline
-	   (loop for n across numbering
-		 for idx from 0 to org-export-max-depth
-		 when (< idx relative-level) collect n
-		 when (= idx relative-level) collect (aset numbering idx (1+ n))
-		 when (> idx relative-level) do (aset numbering idx 0)))))
+	(unless (org-element-property :footnote-section-p headline)
+	  (let ((relative-level
+		 (1- (org-export-get-relative-level headline options))))
+	    (cons
+	     headline
+	     (loop for n across numbering
+		   for idx from 0 to org-export-max-depth
+		   when (< idx relative-level) collect n
+		   when (= idx relative-level) collect (aset numbering idx (1+ n))
+		   when (> idx relative-level) do (aset numbering idx 0))))))
       options)))
       options)))
 
 
 (defun org-export--populate-ignore-list (data options)
 (defun org-export--populate-ignore-list (data options)
@@ -4434,13 +4436,15 @@ the table of contents.  Otherwise, it is set to the value of the
 last headline level.  See `org-export-headline-levels' for more
 last headline level.  See `org-export-headline-levels' for more
 information.
 information.
 
 
-Return a list of all exportable headlines as parsed elements."
+Return a list of all exportable headlines as parsed elements.
+Footnote sections, if any, will be ignored."
   (unless (wholenump n) (setq n (plist-get info :headline-levels)))
   (unless (wholenump n) (setq n (plist-get info :headline-levels)))
   (org-element-map (plist-get info :parse-tree) 'headline
   (org-element-map (plist-get info :parse-tree) 'headline
     (lambda (headline)
     (lambda (headline)
-      ;; Strip contents from HEADLINE.
-      (let ((relative-level (org-export-get-relative-level headline info)))
-	(unless (> relative-level n) headline)))
+      (unless (org-element-property :footnote-section-p headline)
+	;; Strip contents from HEADLINE.
+	(let ((relative-level (org-export-get-relative-level headline info)))
+	  (unless (> relative-level n) headline))))
     info))
     info))
 
 
 (defun org-export-collect-elements (type info &optional predicate)
 (defun org-export-collect-elements (type info &optional predicate)

+ 39 - 24
testing/lisp/test-ox.el

@@ -794,29 +794,29 @@ body\n")))
      (equal
      (equal
       '((1 . "A\n") (2 . "B") (3 . "C") (4 . "D"))
       '((1 . "A\n") (2 . "B") (3 . "C") (4 . "D"))
       (org-test-with-parsed-data
       (org-test-with-parsed-data
-       "Text[fn:1] [1] [fn:label:C] [fn::D]\n\n[fn:1] A\n\n[1] B"
-       (org-element-map
-	tree 'footnote-reference
-	(lambda (ref)
-	  (let ((def (org-export-get-footnote-definition ref info)))
-	    (cons (org-export-get-footnote-number ref info)
-		  (if (eq (org-element-property :type ref) 'inline) (car def)
-		    (car (org-element-contents
-			  (car (org-element-contents def))))))))
-	info))))
+	  "Text[fn:1] [1] [fn:label:C] [fn::D]\n\n[fn:1] A\n\n[1] B"
+	(org-element-map
+	    tree 'footnote-reference
+	  (lambda (ref)
+	    (let ((def (org-export-get-footnote-definition ref info)))
+	      (cons (org-export-get-footnote-number ref info)
+		    (if (eq (org-element-property :type ref) 'inline) (car def)
+		      (car (org-element-contents
+			    (car (org-element-contents def))))))))
+	  info))))
     ;; 2. Test nested footnotes order.
     ;; 2. Test nested footnotes order.
     (org-test-with-parsed-data
     (org-test-with-parsed-data
-     "Text[fn:1:A[fn:2]] [fn:3].\n\n[fn:2] B [fn:3] [fn::D].\n\n[fn:3] C."
-     (should
-      (equal
-       '((1 . "fn:1") (2 . "fn:2") (3 . "fn:3") (4))
-       (org-element-map
-	tree 'footnote-reference
-	(lambda (ref)
-	  (when (org-export-footnote-first-reference-p ref info)
-	    (cons (org-export-get-footnote-number ref info)
-		  (org-element-property :label ref))))
-	info))))
+	"Text[fn:1:A[fn:2]] [fn:3].\n\n[fn:2] B [fn:3] [fn::D].\n\n[fn:3] C."
+      (should
+       (equal
+	'((1 . "fn:1") (2 . "fn:2") (3 . "fn:3") (4))
+	(org-element-map
+	    tree 'footnote-reference
+	  (lambda (ref)
+	    (when (org-export-footnote-first-reference-p ref info)
+	      (cons (org-export-get-footnote-number ref info)
+		    (org-element-property :label ref))))
+	  info))))
     ;; 3. Test nested footnote in invisible definitions.
     ;; 3. Test nested footnote in invisible definitions.
     (org-test-with-temp-text "Text[1]\n\n[1] B [2]\n\n[2] C."
     (org-test-with-temp-text "Text[1]\n\n[1] B [2]\n\n[2] C."
       ;; Hide definitions.
       ;; Hide definitions.
@@ -835,8 +835,8 @@ body\n")))
 \[fn:2] B [fn:3] [fn::D].
 \[fn:2] B [fn:3] [fn::D].
 
 
 \[fn:3] C."
 \[fn:3] C."
-			       (should (= (length (org-export-collect-footnote-definitions tree info))
-					  4)))
+      (should (= (length (org-export-collect-footnote-definitions tree info))
+		 4)))
     ;; 5. Test export of footnotes defined outside parsing scope.
     ;; 5. Test export of footnotes defined outside parsing scope.
     (org-test-with-temp-text "[fn:1] Out of scope
     (org-test-with-temp-text "[fn:1] Out of scope
 * Title
 * Title
@@ -858,7 +858,22 @@ Paragraph[fn:1]"
     (should
     (should
      (org-test-with-parsed-data "[fn:1]"
      (org-test-with-parsed-data "[fn:1]"
        (org-export-get-footnote-definition
        (org-export-get-footnote-definition
-	(org-element-map tree 'footnote-reference 'identity info t) info)))))
+	(org-element-map tree 'footnote-reference 'identity info t) info)))
+    ;; 7. Footnote section should be ignored in TOC and in headlines
+    ;;    numbering.
+    (should
+     (= 1 (let ((org-footnote-section "Footnotes"))
+	    (length (org-test-with-parsed-data "* H1\n* Footnotes\n"
+		      (org-export-collect-headlines info))))))
+    (should
+     (equal '(2)
+	    (let ((org-footnote-section "Footnotes"))
+	      (org-test-with-parsed-data "* H1\n* Footnotes\n* H2"
+		(org-element-map tree 'headline
+		  (lambda (hl)
+		    (when (equal (org-element-property :raw-value hl) "H2")
+		      (org-export-get-headline-number hl info)))
+		  info t)))))))