ox-texinfo: Change Texinfo class definition

* lisp/ox-texinfo.el (org-texinfo-classes): Change default value and
  structure.
(org-texinfo--structuring-command): New function.
(org-texinfo-headline): Use new function.

The new structure handles properly appendices at sub-levels.
This commit is contained in:
Nicolas Goaziou 2017-06-22 11:54:16 +02:00
parent a0d1ad325d
commit 20795aae27
2 changed files with 82 additions and 90 deletions

View File

@ -49,6 +49,10 @@ You can now find them here :
- https://github.com/sabof/org-bullets - https://github.com/sabof/org-bullets
- https://github.com/org-mime/org-mime - https://github.com/org-mime/org-mime
*** Change ~org-texinfo-classes~ value
The value cannot support functions to create sectionning commands
anymore. Also, the sectionning commands should include commands for
appendices. See the docstring for more information.
*** Removal of ~:sitemap-sans-extension~ *** Removal of ~:sitemap-sans-extension~
The publishing property is no longer recognized, as a consequence of The publishing property is no longer recognized, as a consequence of

View File

@ -146,17 +146,19 @@ If nil it will default to `buffer-file-coding-system'."
(defcustom org-texinfo-classes (defcustom org-texinfo-classes
'(("info" '(("info"
"@documentencoding AUTO\n@documentlanguage AUTO" "@documentencoding AUTO\n@documentlanguage AUTO"
("@chapter %s" . "@unnumbered %s") ("@chapter %s" "@unnumbered %s" "@appendix %s")
("@section %s" . "@unnumberedsec %s") ("@section %s" "@unnumberedsec %s" "@appendixsec %s")
("@subsection %s" . "@unnumberedsubsec %s") ("@subsection %s" "@unnumberedsubsec %s" "@appendixsubsec %s")
("@subsubsection %s" . "@unnumberedsubsubsec %s"))) ("@subsubsection %s" "@unnumberedsubsubsec %s" "@appendixsubsubsec %s")))
"Alist of Texinfo classes and associated header and structure. "Alist of Texinfo classes and associated header and structure.
If #+TEXINFO_CLASS is set in the buffer, use its value and the If #+TEXINFO_CLASS is set in the buffer, use its value and the
associated information. Here is the structure of each cell: associated information. Here is the structure of a class
definition:
(class-name (class-name
header-string header-string
(numbered-section . unnumbered-section) (numbered-1 unnumbered-1 appendix-1)
(numbered-2 unnumbered-2 appendix-2)
...) ...)
@ -188,25 +190,19 @@ The sectioning structure
The sectioning structure of the class is given by the elements The sectioning structure of the class is given by the elements
following the header string. For each sectioning level, a number following the header string. For each sectioning level, a number
of strings is specified. A %s formatter is mandatory in each of strings is specified. A %s formatter is mandatory in each
section string and will be replaced by the title of the section. section string and will be replaced by the title of the section."
Instead of a list of sectioning commands, you can also specify
a function name. That function will be called with two
parameters, the reduced) level of the headline, and a predicate
non-nil when the headline should be numbered. It must return
a format string in which the section title will be added."
:group 'org-export-texinfo :group 'org-export-texinfo
:version "24.4" :version "26.1"
:package-version '(Org . "8.2") :package-version '(Org . "9.1")
:type '(repeat :type '(repeat
(list (string :tag "Texinfo class") (list (string :tag "Texinfo class")
(string :tag "Texinfo header") (string :tag "Texinfo header")
(repeat :tag "Levels" :inline t (repeat :tag "Levels" :inline t
(choice (choice
(cons :tag "Heading" (list :tag "Heading"
(string :tag " numbered") (string :tag " numbered")
(string :tag "unnumbered")) (string :tag "unnumbered")
(function :tag "Hook computing sectioning")))))) (string :tag " appendix")))))))
;;;; Headline ;;;; Headline
@ -833,38 +829,40 @@ plist holding contextual information."
;;;; Headline ;;;; Headline
(defun org-texinfo--structuring-command (headline info)
"Return Texinfo structuring command string for HEADLINE element.
Return nil if HEADLINE is to be ignored, `plain-list' if it
should be exported as a plain-list item. INFO is a plist holding
contextual information."
(cond
((org-element-property :footnote-section-p headline) nil)
((org-not-nil (org-export-get-node-property :COPYING headline t)) nil)
((org-export-low-level-p headline info) 'plain-list)
(t
(let ((class (plist-get info :texinfo-class)))
(pcase (assoc class (plist-get info :texinfo-classes))
(`(,_ ,_ . ,sections)
(pcase (nth (1- (org-export-get-relative-level headline info))
sections)
(`(,numbered ,unnumbered ,appendix)
(cond
((org-not-nil (org-export-get-node-property :APPENDIX headline t))
appendix)
((org-not-nil (org-export-get-node-property :INDEX headline t))
unnumbered)
((org-export-numbered-headline-p headline info) numbered)
(t unnumbered)))
(`nil 'plain-list)
(_ (user-error "Invalid Texinfo class specification: %S" class))))
(_ (user-error "Invalid Texinfo class specification: %S" class)))))))
(defun org-texinfo-headline (headline contents info) (defun org-texinfo-headline (headline contents info)
"Transcode a HEADLINE element from Org to Texinfo. "Transcode a HEADLINE element from Org to Texinfo.
CONTENTS holds the contents of the headline. INFO is a plist CONTENTS holds the contents of the headline. INFO is a plist
holding contextual information." holding contextual information."
(let* ((class (plist-get info :texinfo-class)) (let ((section-fmt (org-texinfo--structuring-command headline info)))
(level (org-export-get-relative-level headline info)) (when section-fmt
(numberedp (org-export-numbered-headline-p headline info)) (let* ((todo
(class-sectioning (assoc class (plist-get info :texinfo-classes)))
;; Find the index type, if any.
(index (org-element-property :INDEX headline))
;; Create node info, to insert it before section formatting.
;; Use custom menu title if present.
(node (format "@node %s\n" (org-texinfo--get-node headline info)))
;; Section formatting will set two placeholders: one for the
;; title and the other for the contents.
(section-fmt
(if (org-not-nil (org-element-property :APPENDIX headline))
"@appendix %s\n%s"
(let ((sec (if (and (symbolp (nth 2 class-sectioning))
(fboundp (nth 2 class-sectioning)))
(funcall (nth 2 class-sectioning) level numberedp)
(nth (1+ level) class-sectioning))))
(cond
;; No section available for that LEVEL.
((not sec) nil)
;; Section format directly returned by a function.
((stringp sec) sec)
;; (numbered-section . unnumbered-section)
((not (consp (cdr sec)))
(concat (if (or index (not numberedp)) (cdr sec) (car sec))
"\n%s"))))))
(todo
(and (plist-get info :with-todo-keywords) (and (plist-get info :with-todo-keywords)
(let ((todo (org-element-property :todo-keyword headline))) (let ((todo (org-element-property :todo-keyword headline)))
(and todo (org-export-data todo info))))) (and todo (org-export-data todo info)))))
@ -875,40 +873,30 @@ holding contextual information."
(org-element-property :priority headline))) (org-element-property :priority headline)))
(text (org-texinfo--sanitize-title (text (org-texinfo--sanitize-title
(org-element-property :title headline) info)) (org-element-property :title headline) info))
(full-text (funcall (plist-get info :texinfo-format-headline-function) (full-text
(funcall (plist-get info :texinfo-format-headline-function)
todo todo-type priority text tags)) todo todo-type priority text tags))
(contents (if (org-string-nw-p contents) (concat "\n" contents) ""))) (contents
(cond (concat (if (org-string-nw-p contents)
;; Case 1: This is a footnote section: ignore it. (concat "\n" contents)
((org-element-property :footnote-section-p headline) nil) "")
;; Case 2: This is the `copying' section: ignore it (let ((index (org-element-property :INDEX headline)))
;; This is used elsewhere.
((org-not-nil (org-element-property :COPYING headline)) nil)
;; Case 3: An index. If it matches one of the known indexes,
;; print it as such following the contents, otherwise
;; print the contents and leave the index up to the user.
(index
(concat node
(format
section-fmt
full-text
(concat contents
(and (member index '("cp" "fn" "ky" "pg" "tp" "vr")) (and (member index '("cp" "fn" "ky" "pg" "tp" "vr"))
(concat "\n@printindex " index)))))) (format "\n@printindex %s\n" index))))))
;; Case 4: This is a deep sub-tree: export it as a list item. (cond
;; Also export as items headlines for which no section ((eq section-fmt 'plain-list)
;; format has been found. (let ((numbered? (org-export-numbered-headline-p headline info)))
((or (not section-fmt) (org-export-low-level-p headline info))
;; Build the real contents of the sub-tree.
(concat (and (org-export-first-sibling-p headline info) (concat (and (org-export-first-sibling-p headline info)
(format "@%s\n" (if numberedp 'enumerate 'itemize))) (format "@%s\n" (if numbered? 'enumerate 'itemize)))
"@item\n" full-text "\n" "@item\n" full-text "\n"
contents contents
(if (org-export-last-sibling-p headline info) (if (org-export-last-sibling-p headline info)
(format "@end %s" (if numberedp 'enumerate 'itemize)) (format "@end %s" (if numbered? 'enumerate 'itemize))
"\n"))) "\n"))))
;; Case 5: Standard headline. Export it as a section. (t
(t (concat node (format section-fmt full-text contents)))))) (concat (format "@node %s\n" (org-texinfo--get-node headline info))
(format section-fmt full-text)
contents)))))))
(defun org-texinfo-format-headline-default-function (defun org-texinfo-format-headline-default-function
(todo _todo-type priority text tags) (todo _todo-type priority text tags)