diff --git a/doc/org.texi b/doc/org.texi index f40f458e3..28b90a844 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -10899,22 +10899,25 @@ settings that cannot be changed using keywords. @cindex list of tables @cindex list of listings -@cindex #+TOC @vindex org-export-with-toc -Org normally inserts the table of contents directly before the first headline -of the file. Org sets the TOC depth the same as the headline levels in the -file. Use a lower number for lower TOC depth. To turn off TOC entirely, use -@code{nil}. This is configured in the @code{org-export-with-toc} variable or -as keywords in an Org file as: +The table of contents includes all @emph{numbered} headlines in the document. +Its depth is therefore the same as the headline levels in the file. If you +need to use a different depth, or turn it off entirely, set the +@code{org-export-with-toc} variable accordingly. You can achieve the same on +a per file basis, using the following @samp{toc} item in @samp{#+OPTIONS} +keyword: @example #+OPTIONS: toc:2 @r{only include two levels in TOC} #+OPTIONS: toc:nil @r{no default TOC at all} @end example -To move the table of contents to a different location, first turn off the -default with @code{org-export-with-toc} variable or with @code{#+OPTIONS: -toc:nil}. Then insert @code{#+TOC: headlines N} at the desired location(s). +@cindex #+TOC +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 +turn off the default with @code{org-export-with-toc} variable or with +@code{#+OPTIONS: toc:nil}. Then insert @code{#+TOC: headlines N} at the +desired location(s). @example #+OPTIONS: toc:nil @r{no default TOC} diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index d2a2a4eaf..148866832 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -12,6 +12,12 @@ Please send Org bug reports to mailto:emacs-orgmode@gnu.org. * Version 9.2 ** Incompatible changes +*** Table of contents ignore unnumbered headlines + +This allows finer control over the table of contents itself, using, +e.g., =UNNUMBERED= property. It is also more consistent with LaTeX +export. + *** =align= STARTUP value no longer narrow table columns Columns narrowing (or shrinking) is now dynamic. See [[*Dynamically diff --git a/lisp/ox-texinfo.el b/lisp/ox-texinfo.el index ec9cd7fd4..faa07d914 100644 --- a/lisp/ox-texinfo.el +++ b/lisp/ox-texinfo.el @@ -146,10 +146,10 @@ If nil it will default to `buffer-file-coding-system'." (defcustom org-texinfo-classes '(("info" "@documentencoding AUTO\n@documentlanguage AUTO" - ("@chapter %s" "@unnumbered %s" "@appendix %s") - ("@section %s" "@unnumberedsec %s" "@appendixsec %s") - ("@subsection %s" "@unnumberedsubsec %s" "@appendixsubsec %s") - ("@subsubsection %s" "@unnumberedsubsubsec %s" "@appendixsubsubsec %s"))) + ("@chapter %s" "@chapheading %s" "@appendix %s") + ("@section %s" "@heading %s" "@appendixsec %s") + ("@subsection %s" "@subheading %s" "@appendixsubsec %s") + ("@subsubsection %s" "@subsubheading %s" "@appendixsubsubsec %s"))) "Alist of Texinfo classes and associated header and structure. If #+TEXINFO_CLASS is set in the buffer, use its value and the associated information. Here is the structure of a class @@ -193,7 +193,7 @@ of strings is specified. A %s formatter is mandatory in each section string and will be replaced by the title of the section." :group 'org-export-texinfo :version "26.1" - :package-version '(Org . "9.1") + :package-version '(Org . "9.2") :type '(repeat (list (string :tag "Texinfo class") (string :tag "Texinfo header") diff --git a/lisp/ox.el b/lisp/ox.el index 14da82ca1..16ff8988b 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -5214,7 +5214,7 @@ there is no such headline, collect all headlines. In any case, argument N becomes relative to the level of that headline. Return a list of all exportable headlines as parsed elements. -Footnote sections are ignored." +Footnote sections and unnumbered headlines are ignored." (let* ((scope (cond ((not scope) (plist-get info :parse-tree)) ((eq (org-element-type scope) 'headline) scope) ((org-export-get-parent-headline scope)) @@ -5226,7 +5226,8 @@ Footnote sections are ignored." limit)))) (org-element-map (org-element-contents scope) 'headline (lambda (headline) - (unless (org-element-property :footnote-section-p headline) + (unless (or (org-element-property :footnote-section-p headline) + (not (org-export-numbered-headline-p headline info))) (let ((level (org-export-get-relative-level headline info))) (and (<= level n) headline)))) info))) diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index 72b6c8ccd..9d5f1fedf 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -4286,39 +4286,58 @@ Another text. (ref:text) "Test `org-export-collect-headlines' specifications." ;; Standard test. (should - (= 2 - (length - (org-test-with-parsed-data "* H1\n** H2" - (org-export-collect-headlines info))))) + (equal '("H1" "H2") + (org-test-with-parsed-data "* H1\n** H2" + (mapcar (lambda (h) (org-element-property :raw-value h)) + (org-export-collect-headlines info))))) ;; Do not collect headlines below optional argument. (should - (= 1 - (length - (org-test-with-parsed-data "* H1\n** H2" - (org-export-collect-headlines info 1))))) + (equal '("H1") + (org-test-with-parsed-data "* H1\n** H2" + (mapcar (lambda (h) (org-element-property :raw-value h)) + (org-export-collect-headlines info 1))))) ;; Never collect headlines below maximum headline level. (should - (= 1 - (length - (org-test-with-parsed-data "#+OPTIONS: H:1\n* H1\n** H2" - (org-export-collect-headlines info))))) + (equal '("H1") + (org-test-with-parsed-data "#+OPTIONS: H:1\n* H1\n** H2" + (mapcar (lambda (h) (org-element-property :raw-value h)) + (org-export-collect-headlines info))))) (should - (= 1 - (length - (org-test-with-parsed-data "#+OPTIONS: H:1\n* H1\n** H2" - (org-export-collect-headlines info 2))))) + (equal '("H1") + (org-test-with-parsed-data "#+OPTIONS: H:1\n* H1\n** H2" + (mapcar (lambda (h) (org-element-property :raw-value h)) + (org-export-collect-headlines info 2))))) + ;; Do not collect footnote section. + (should + (equal '("H1") + (let ((org-footnote-section "Footnotes")) + (org-test-with-parsed-data "* H1\n** Footnotes" + (mapcar (lambda (h) (org-element-property :raw-value h)) + (org-export-collect-headlines info)))))) + ;; Do not collect unnumbered headlines. + (should-not + (org-test-with-parsed-data "#+options: num:nil\n* H1\n** H2" + (org-export-collect-headlines info))) + (should + (equal '("H1") + (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. (should - (= 2 - (org-test-with-parsed-data "* H1\n** H2\n** H3" - (let ((scope (org-element-map tree 'headline #'identity info t))) - (length (org-export-collect-headlines info nil scope)))))) + (equal '("H2" "H3") + (org-test-with-parsed-data "* H1\n** H2\n** H3" + (let ((scope (org-element-map tree 'headline #'identity info t))) + (mapcar (lambda (h) (org-element-property :raw-value h)) + (org-export-collect-headlines info nil scope)))))) ;; When collecting locally, optional level is relative. (should - (= 1 - (org-test-with-parsed-data "* H1\n** H2\n*** H3" - (let ((scope (org-element-map tree 'headline #'identity info t))) - (length (org-export-collect-headlines info 1 scope))))))) + (equal '("H2") + (org-test-with-parsed-data "* H1\n** H2\n*** H3" + (let ((scope (org-element-map tree 'headline #'identity info t))) + (mapcar (lambda (h) (org-element-property :raw-value h)) + (org-export-collect-headlines info 1 scope)))))))