Browse Source

ox: Implement "notoc" UNNUMBERED value

* lisp/ox.el (org-export-collect-headlines): Exclude headlines with
  UNNUMBERED property set to "notoc".

* doc/org.texi (Export settings):
(Table of contents): Document new value.

* testing/lisp/test-ox.el (test-org-export/collect-headlines): Add
  test.
Nicolas Goaziou 7 years ago
parent
commit
9b13e44ad7
4 changed files with 48 additions and 8 deletions
  1. 21 3
      doc/org.texi
  2. 3 0
      etc/ORG-NEWS
  3. 9 5
      lisp/ox.el
  4. 15 0
      testing/lisp/test-ox.el

+ 21 - 3
doc/org.texi

@@ -10813,7 +10813,9 @@ Toggle inclusion of inlinetasks (@code{org-export-with-inlinetasks}).
 Toggle section-numbers (@code{org-export-with-section-numbers}).  When set to
 Toggle section-numbers (@code{org-export-with-section-numbers}).  When set to
 number @samp{n}, Org numbers only those headlines at level @samp{n} or above.
 number @samp{n}, Org numbers only those headlines at level @samp{n} or above.
 Set @code{UNNUMBERED} property to non-@code{nil} to disable numbering of
 Set @code{UNNUMBERED} property to non-@code{nil} to disable numbering of
-heading and subheadings entirely.
+heading and subheadings entirely.  Moreover, when the value is @samp{notoc}
+the headline, and all its children, do not appear in the table of contents
+either (@pxref{Table of contents}).
 
 
 @item p:
 @item p:
 @vindex org-export-with-planning
 @vindex org-export-with-planning
@@ -10911,6 +10913,22 @@ keyword:
 #+OPTIONS: toc:nil        @r{no default TOC at all}
 #+OPTIONS: toc:nil        @r{no default TOC at all}
 @end example
 @end example
 
 
+@cindex excluding entries from table of contents
+@cindex table of contents, exclude entries
+Org includes both numbered and unnumbered headlines in the table of
+contents@footnote{At the moment, some export back-ends do not obey this
+specification.  For example, @LaTeX{} export excludes every unnumbered
+headline from the table of contents.}.  If you need to exclude an unnumbered
+headline, along with all its children, set the @samp{UNNUMBERED} property to
+@samp{notoc} value.
+
+@example
+* Subtree not numbered, not in table of contents either
+  :PROPERTIES:
+  :UNNUMBERED: notoc
+  :END:
+@end example
+
 @cindex #+TOC
 @cindex #+TOC
 Org normally inserts the table of contents directly before the first headline
 Org normally inserts the table of contents directly before the first headline
 of the file.  To move the table of contents to a different location, first
 of the file.  To move the table of contents to a different location, first
@@ -10935,8 +10953,8 @@ compatibility issues, @code{titletoc} has to be loaded @emph{before}
 variable.
 variable.
 
 
 @example
 @example
-* Section #+TOC: headlines 1 local @r{insert local TOC, with direct children
-only}
+* Section
+#+TOC: headlines 1 local @r{insert local TOC, with direct children only}
 @end example
 @end example
 
 
 Use the @code{TOC} keyword to generate list of tables (resp.@: all listings)
 Use the @code{TOC} keyword to generate list of tables (resp.@: all listings)

+ 3 - 0
etc/ORG-NEWS

@@ -26,6 +26,9 @@ document, use =shrink= value instead, or in addition to align:
 #+END_EXAMPLE
 #+END_EXAMPLE
 
 
 ** New features
 ** New features
+*** Exclude unnumbered headlines from table of contents
+Set their =UNNUMBERED= property to the special =notoc= value.  See
+manual for details.
 *** ~org-archive~ functions update status cookies
 *** ~org-archive~ functions update status cookies
 
 
 Archiving headers through ~org-archive-subtree~ and
 Archiving headers through ~org-archive-subtree~ and

+ 9 - 5
lisp/ox.el

@@ -5226,12 +5226,16 @@ Footnote sections are ignored."
 	 (n (if (not (wholenump n)) limit
 	 (n (if (not (wholenump n)) limit
 	      (min (if (eq (org-element-type scope) 'org-data) n
 	      (min (if (eq (org-element-type scope) 'org-data) n
 		     (+ (org-export-get-relative-level scope info) n))
 		     (+ (org-export-get-relative-level scope info) n))
-		   limit))))
+		   limit)))
+	 (skipped nil))
     (org-element-map (org-element-contents scope) 'headline
     (org-element-map (org-element-contents scope) 'headline
-      (lambda (headline)
-	(unless (org-element-property :footnote-section-p headline)
-	  (let ((level (org-export-get-relative-level headline info)))
-	    (and (<= level n) headline))))
+      (lambda (h)
+	(if (or (org-element-property :footnote-section-p h)
+		(equal "notoc" (org-element-property :UNNUMBERED h))
+		(memq (org-element-property :parent h) skipped)
+		(< n (org-export-get-relative-level h info)))
+	    (progn (push h skipped) nil)
+	  h))
       info)))
       info)))
 
 
 (defun org-export-collect-elements (type info &optional predicate)
 (defun org-export-collect-elements (type info &optional predicate)

+ 15 - 0
testing/lisp/test-ox.el

@@ -4314,6 +4314,21 @@ Another text. (ref:text)
 	    (org-test-with-parsed-data "* H1\n** Footnotes"
 	    (org-test-with-parsed-data "* H1\n** Footnotes"
 	      (mapcar (lambda (h) (org-element-property :raw-value h))
 	      (mapcar (lambda (h) (org-element-property :raw-value h))
 		      (org-export-collect-headlines info))))))
 		      (org-export-collect-headlines info))))))
+  ;; Do not collect headlines with UNNUMBERED property set to "notoc".
+  ;; Headlines with another value for the property are still
+  ;; collected.
+  (should
+   (equal '("H1")
+	  (org-test-with-parsed-data
+	      "* H1\n* H2\n:PROPERTIES:\n:UNNUMBERED: notoc\n:END:"
+	    (mapcar (lambda (h) (org-element-property :raw-value h))
+		    (org-export-collect-headlines info)))))
+  (should
+   (equal '("H1" "H2")
+	  (org-test-with-parsed-data
+	      "* H1\n* H2\n:PROPERTIES:\n:UNNUMBERED: t\n:END:"
+	    (mapcar (lambda (h) (org-element-property :raw-value h))
+		    (org-export-collect-headlines info)))))
   ;; Collect headlines locally.
   ;; Collect headlines locally.
   (should
   (should
    (equal '("H2" "H3")
    (equal '("H2" "H3")