From mboxrd@z Thu Jan 1 00:00:00 1970 From: Nicolas Goaziou Subject: [RFC] Exclude headlines from TOC, take 2 Date: Sat, 07 Oct 2017 16:16:27 +0200 Message-ID: <87zi93gi10.fsf@nicolasgoaziou.fr> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:38267) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e0pu4-0005ea-DS for emacs-orgmode@gnu.org; Sat, 07 Oct 2017 10:16:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e0pu3-0000sj-25 for emacs-orgmode@gnu.org; Sat, 07 Oct 2017 10:16:32 -0400 Received: from relay4-d.mail.gandi.net ([2001:4b98:c:538::196]:34193) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e0pu2-0000s2-O8 for emacs-orgmode@gnu.org; Sat, 07 Oct 2017 10:16:30 -0400 Received: from saiph.selenimh (000043010000000000000469.ipv6.commingeshautdebit.fr [IPv6:2a03:a0a0:0:4301::469]) (Authenticated sender: mail@nicolasgoaziou.fr) by relay4-d.mail.gandi.net (Postfix) with ESMTPSA id A529B1720A1 for ; Sat, 7 Oct 2017 16:16:27 +0200 (CEST) Received: from ngz by saiph.selenimh with local (Exim 4.89) (envelope-from ) id 1e0ptz-0006YM-1d for emacs-orgmode@gnu.org; Sat, 07 Oct 2017 16:16:27 +0200 List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: "Emacs-orgmode" To: Org Mode List --=-=-= Content-Type: text/plain Hello, Here is another take on the possibility to exclude headlines from the table of contents. Last attempt was rejected because users need to include /unnumbered/ headlines in the TOC. Point taken. However, I don't think it makes sense to exclude /numbered/ headlines from the TOC. Hence, I propose to exclude any headline with an UNNUMBERED property set to "notoc". So basically, - only unnumbered headlines can be excluded - we do not introduce another property Here is an example document, with the generated TOC in plain text export: --8<---------------cut here---------------start------------->8--- #+options: toc:t * H1 :PROPERTIES: :UNNUMBERED: t :END: * H2 ** H2.1 ** H2.2 :PROPERTIES: :UNNUMBERED: notoc :END: *** H221 ** H2.3 * H3 :PROPERTIES: :UNNUMBERED: notoc :END: * H4 * H5 :PROPERTIES: :UNNUMBERED: t :END: --8<---------------cut here---------------end--------------->8--- gives H1 1 H2 .. 1.1 H2.1 .. 1.2 H2.3 2 H4 H5 I attach a possible implementation, with documentation and tests. Note that this doesn't work with LaTeX export back-end, which still dutifully ignores any unnumbered headline. Patches welcome to improve this. WDYT? Regards, -- Nicolas Goaziou 0x80A93738 --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0001-ox-Implement-notoc-UNNUMBERED-value.patch >From e6c6534997e03d4817a95c6f57f9c0421810c50b Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Sat, 7 Oct 2017 16:03:17 +0200 Subject: [PATCH] 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. --- doc/org.texi | 24 +++++++++++++++++++++--- etc/ORG-NEWS | 3 +++ lisp/ox.el | 14 +++++++++----- testing/lisp/test-ox.el | 15 +++++++++++++++ 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/doc/org.texi b/doc/org.texi index fd26d9790..146699b11 100644 --- a/doc/org.texi +++ b/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 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 -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: @vindex org-export-with-planning @@ -10911,6 +10913,22 @@ keyword: #+OPTIONS: toc:nil @r{no default TOC at all} @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, notably @LaTeX{}, do +not obey this specification. They simply exclude every unnumbered headline +from the table of contents.}. If you need to exclude unnumbered headlines, +along with all their children, set their @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 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 @@ -10935,8 +10953,8 @@ compatibility issues, @code{titletoc} has to be loaded @emph{before} variable. @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 Use the @code{TOC} keyword to generate list of tables (resp.@: all listings) diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 53d604b8c..86c253d9c 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -26,6 +26,9 @@ document, use =shrink= value instead, or in addition to align: #+END_EXAMPLE ** 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 Archiving headers through ~org-archive-subtree~ and diff --git a/lisp/ox.el b/lisp/ox.el index 4d3d7afb9..cba254d6f 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -5223,12 +5223,16 @@ Footnote sections are ignored." (n (if (not (wholenump n)) limit (min (if (eq (org-element-type scope) 'org-data) n (+ (org-export-get-relative-level scope info) n)) - limit)))) + limit))) + (skipped nil)) (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))) (defun org-export-collect-elements (type info &optional predicate) diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index 46ef51bab..cbfee4c8c 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -4314,6 +4314,21 @@ Another text. (ref:text) (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 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. (should (equal '("H2" "H3") -- 2.14.1 --=-=-=--