From mboxrd@z Thu Jan 1 00:00:00 1970 From: Rasmus Subject: [patch, ox] Unnumbered headlines Date: Fri, 08 Aug 2014 15:39:15 +0200 Message-ID: <87lhqzyubg.fsf@gmx.us> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:51414) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XFkOO-0007mx-3A for emacs-orgmode@gnu.org; Fri, 08 Aug 2014 09:39:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XFkOI-0004Ky-GG for emacs-orgmode@gnu.org; Fri, 08 Aug 2014 09:39:36 -0400 Received: from plane.gmane.org ([80.91.229.3]:53204) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XFkOI-0004Ku-5e for emacs-orgmode@gnu.org; Fri, 08 Aug 2014 09:39:30 -0400 Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1XFkOG-0004lS-4d for emacs-orgmode@gnu.org; Fri, 08 Aug 2014 15:39:28 +0200 Received: from 109.201.152.5 ([109.201.152.5]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Fri, 08 Aug 2014 15:39:28 +0200 Received: from rasmus by 109.201.152.5 with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Fri, 08 Aug 2014 15:39:28 +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-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs-orgmode@gnu.org Cc: alantyree@gmail.com, tsd@tsdye.com --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Hi, In a recent thread¹ Tom and Alan mention that authors sometimes need unnumbered headlines, e.g. for prefaces. This patch (tries to) add this feature via the tag :nonumber: (customizable via Custom or in-file). I make two assumptions. First, the tag is recursive, so if the parent is not numbered the child is not numbered. Secondly, I depart from the LaTeX tradition of ignoring unnumbered headlines in the TOC (except in the case of ox-latex.el where it depends on org-latex-classes). (See example below). Needless to say such a feature needs to be discussed and I not sure whether the greater Org community finds it useful or needless clutter. In my opinion a :nonumber: tag is a natural continuation of :export: and :noexport: and unlike :ignoreheading: the implementation is fairly clean (or maybe I'm cheating myself here). A reason for why to include it is that it seems relatively easy to do *during* export, but it's hard to consistently get it right on in both headlines and the TOC via filters. The patch is messing with ox.el, and thus I would appreciate a review and potentially testing, in the case that it is agreed that such a feature would be OK to add to ox. It seems to work well with ox-latex.el, ox-ascii.el and ox-html.el. It doesn't play well with ox-odt.el (headlines are still numbered). I will fix this as well as adding documentation if a consensus of the worthwhileness of the patch can be reached. Finally, here's an example output using ox-ascii #+begin_src org * a (not numbered) :nonum: ** aa (not numbert) * b (1) ** ba (not numbered) :nonum: *** baa (not numbered) ** bb (1.1) #+end_src #+RESULTS: (TOC only, but the rest is as expected) a (not numbered) .. aa (not numbert) 1 b (1) .. ba (not numbered) ..... baa (not numbered) .. 1.1 bb (1.1) Thanks, Rasmus Footnotes: ¹ http://permalink.gmane.org/gmane.emacs.orgmode/89515 -- Vote for proprietary math! --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-ox.el-Support-unnumbered-headlines-via-tag.patch >From d38a728fef66af9df2a0b87e2126533961d87ecf Mon Sep 17 00:00:00 2001 From: Rasmus Date: Fri, 8 Aug 2014 14:53:01 +0200 Subject: [PATCH] ox.el: Support unnumbered headlines via tag. * ox.el (org-export-options-alist): NO_NUMBER_TAGS new keyword. (org-export-not-numbered-tags): New defcustom. (org-export--collect-headline-numbering): Considers whether headline is numbered. (org-export-numbered-headline-p): Tests if headline is to be numbered. (org-export--recursive-tags): New function based. Previouesly part of `orge-export-get-tags'. (org-export-get-tags): Ignoes NO_NUMBER_TAGS. --- lisp/ox.el | 60 +++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/lisp/ox.el b/lisp/ox.el index d47c2e6..2fff14f 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -109,6 +109,7 @@ (:language "LANGUAGE" nil org-export-default-language t) (:select-tags "SELECT_TAGS" nil org-export-select-tags split) (:exclude-tags "EXCLUDE_TAGS" nil org-export-exclude-tags split) + (:no-number-tags "NO_NUMBER_TAGS" nil org-export-not-numbered-tags split) (:creator "CREATOR" nil org-export-creator-string) (:headline-levels nil "H" org-export-headline-levels) (:preserve-breaks nil "\\n" org-export-preserve-breaks) @@ -448,6 +449,18 @@ e.g. \"*:nil\"." :group 'org-export-general :type 'boolean) + +(defcustom org-export-not-numbered-tags '("nonumber") + "Tags that exclude trees from obtaining numbers. + +All trees carrying any of these tags will be excluded from +receiving a number. This includes subtress. + +This option can also be set in files with the NO_NUMBER_TAGS +keyword." + :group 'org-export-general + :type '(repeat (string :tag "Tag"))) + (defcustom org-export-exclude-tags '("noexport") "Tags that exclude a tree from export. @@ -1993,7 +2006,8 @@ for a footnotes section." (let ((numbering (make-vector org-export-max-depth 0))) (org-element-map data '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 ((relative-level (1- (org-export-get-relative-level headline options)))) (cons @@ -3785,9 +3799,12 @@ INFO is a plist holding contextual information." (defun org-export-numbered-headline-p (headline info) "Return a non-nil value if HEADLINE element should be numbered. INFO is a plist used as a communication channel." - (let ((sec-num (plist-get info :section-numbers)) + (let ((tags (org-export--recursive-tags headline info)) + (sec-num (plist-get info :section-numbers)) (level (org-export-get-relative-level headline info))) - (if (wholenump sec-num) (<= level sec-num) sec-num))) + (unless (loop for k in (plist-get info :no-number-tags) + thereis (member k tags)) + (if (wholenump sec-num) (<= level sec-num) sec-num)))) (defun org-export-number-to-roman (n) "Convert integer N into a roman numeral." @@ -3805,14 +3822,33 @@ INFO is a plist used as a communication channel." (pop roman))) res))) +(defun org-export--recursive-tags (element info) + "Return the full list of recursive tags associated with ELEMENT. + +ELEMENT has either an `headline' or an `inlinetask' type. INFO +is a plist used as a communication channel." + (let ((current-tag-list (org-element-property :tags element))) + (mapc + (lambda (parent) + (mapc + (lambda (tag) + (when (and (memq (org-element-type parent) '(headline inlinetask)) + (not (member tag current-tag-list))) + (push tag current-tag-list))) + (org-element-property :tags parent))) + (org-export-get-genealogy element)) + ;; Add FILETAGS keywords and return results. + (org-uniquify (append (plist-get info :filetags) current-tag-list)))) + (defun org-export-get-tags (element info &optional tags inherited) "Return list of tags associated to ELEMENT. ELEMENT has either an `headline' or an `inlinetask' type. INFO is a plist used as a communication channel. -Select tags (see `org-export-select-tags') and exclude tags (see -`org-export-exclude-tags') are removed from the list. +Select tags (see `org-export-select-tags'), exclude tags (see +`org-export-exclude-tags') and no-number tags (see +`org-export-no-number-tags') are removed from the list. When non-nil, optional argument TAGS should be a list of strings. Any tag belonging to this list will also be removed. @@ -3822,21 +3858,11 @@ inherited from parent headlines and FILETAGS keywords." (org-remove-if (lambda (tag) (or (member tag (plist-get info :select-tags)) (member tag (plist-get info :exclude-tags)) + (member tag (plist-get info :no-number-tags)) (member tag tags))) (if (not inherited) (org-element-property :tags element) ;; Build complete list of inherited tags. - (let ((current-tag-list (org-element-property :tags element))) - (mapc - (lambda (parent) - (mapc - (lambda (tag) - (when (and (memq (org-element-type parent) '(headline inlinetask)) - (not (member tag current-tag-list))) - (push tag current-tag-list))) - (org-element-property :tags parent))) - (org-export-get-genealogy element)) - ;; Add FILETAGS keywords and return results. - (org-uniquify (append (plist-get info :filetags) current-tag-list)))))) + (org-export--recursive-tags (element info))))) (defun org-export-get-node-property (property blob &optional inherited) "Return node PROPERTY value for BLOB. -- 2.0.4 --=-=-=--