summaryrefslogtreecommitdiff
path: root/lisp/org/ox-texinfo.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/org/ox-texinfo.el')
-rw-r--r--lisp/org/ox-texinfo.el111
1 files changed, 66 insertions, 45 deletions
diff --git a/lisp/org/ox-texinfo.el b/lisp/org/ox-texinfo.el
index 6e8d0d62141..8b949b361aa 100644
--- a/lisp/org/ox-texinfo.el
+++ b/lisp/org/ox-texinfo.el
@@ -2,6 +2,7 @@
;; Copyright (C) 2012-2021 Free Software Foundation, Inc.
;; Author: Jonathan Leech-Pepin <jonathan.leechpepin at gmail dot com>
+;; Maintainer: Nicolas Goaziou <n.goaziou at gmail dot com>
;; Keywords: outlines, hypermedia, calendar, wp
;; This file is part of GNU Emacs.
@@ -420,8 +421,8 @@ If two strings share the same prefix (e.g. \"ISO-8859-1\" and
(defun org-texinfo--normalize-headlines (tree _backend info)
"Normalize headlines in TREE.
-BACK-END is the symbol specifying back-end used for export. INFO
-is a plist used as a communication channel.
+BACK-END is the symbol specifying back-end used for export.
+INFO is a plist used as a communication channel.
Make sure every headline in TREE contains a section, since those
are required to install a menu. Also put exactly one blank line
@@ -489,16 +490,18 @@ node or anchor name is unique."
;; Org exports deeper elements before their parents. If two
;; node names collide -- e.g., they have the same title --
;; within the same hierarchy, the second one would get the
- ;; shorter node name. This is counter-intuitive.
- ;; Consequently, we ensure that every parent headline get
- ;; its node beforehand. As a recursive operation, this
+ ;; smaller node name. This is counter-intuitive.
+ ;; Consequently, we ensure that every parent headline gets
+ ;; its node beforehand. As a recursive operation, this
;; achieves the desired effect.
(let ((parent (org-element-lineage datum '(headline))))
(when (and parent (not (assq parent cache)))
(org-texinfo--get-node parent info)
(setq cache (plist-get info :texinfo-node-cache))))
- ;; Ensure NAME is unique and not reserved node name "Top".
- (while (or (equal name "Top") (rassoc name cache))
+ ;; Ensure NAME is unique and not reserved node name "Top",
+ ;; no matter what case is used.
+ (while (or (string-equal "Top" (capitalize name))
+ (rassoc name cache))
(setq name (concat basename (format " (%d)" (cl-incf salt)))))
(plist-put info :texinfo-node-cache (cons (cons datum name) cache))
name))))
@@ -559,6 +562,14 @@ strings (e.g., returned by `org-export-get-caption')."
(format "@float %s%s\n%s\n%s%s@end float"
type (if label (concat "," label) "") value caption-str short-str)))
+(defun org-texinfo--sectioning-structure (info)
+ "Return sectioning structure used in the document.
+INFO is a plist holding export options."
+ (let ((class (plist-get info :texinfo-class)))
+ (pcase (assoc class (plist-get info :texinfo-classes))
+ (`(,_ ,_ . ,sections) sections)
+ (_ (user-error "Unknown Texinfo class: %S" class)))))
+
;;; Template
(defun org-texinfo-template (contents info)
@@ -838,9 +849,17 @@ CONTENTS is nil. INFO is a plist holding contextual information."
FOOTNOTE is the footnote to define. CONTENTS is nil. INFO is a
plist holding contextual information."
- (let ((def (org-export-get-footnote-definition footnote info)))
+ (let* ((contents (org-export-get-footnote-definition footnote info))
+ (data (org-export-data contents info)))
(format "@footnote{%s}"
- (org-trim (org-export-data def info)))))
+ ;; It is invalid to close a footnote on a line starting
+ ;; with "@end". As a safety net, we leave a newline
+ ;; character before the closing brace. However, when the
+ ;; footnote ends with a paragraph, it is visually pleasing
+ ;; to move the brace right after its end.
+ (if (eq 'paragraph (org-element-type (org-last contents)))
+ (org-trim data)
+ data))))
;;;; Headline
@@ -858,25 +877,22 @@ holding contextual information."
(notoc? (org-export-excluded-from-toc-p headline info))
(command
(and
- (not (org-export-low-level-p headline info))
- (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 ,unnumbered-no-toc ,appendix)
- (cond
- ((org-not-nil
- (org-export-get-node-property :APPENDIX headline t))
- appendix)
- (numbered? numbered)
- (index unnumbered)
- (notoc? unnumbered-no-toc)
- (t unnumbered)))
- (`nil nil)
- (_ (user-error "Invalid Texinfo class specification: %S"
- class))))
- (_ (user-error "Unknown Texinfo class: %S" class))))))
+ (not (org-export-low-level-p headline info))
+ (let ((sections (org-texinfo--sectioning-structure info)))
+ (pcase (nth (1- (org-export-get-relative-level headline info))
+ sections)
+ (`(,numbered ,unnumbered ,unnumbered-no-toc ,appendix)
+ (cond
+ ((org-not-nil
+ (org-export-get-node-property :APPENDIX headline t))
+ appendix)
+ (numbered? numbered)
+ (index unnumbered)
+ (notoc? unnumbered-no-toc)
+ (t unnumbered)))
+ (`nil nil)
+ (_ (user-error "Invalid Texinfo class specification: %S"
+ (plist-get info :texinfo-class)))))))
(todo
(and (plist-get info :with-todo-keywords)
(let ((todo (org-element-property :todo-keyword headline)))
@@ -894,11 +910,12 @@ holding contextual information."
(contents
(concat "\n"
(if (org-string-nw-p contents) (concat "\n" contents) "")
- (and index (format "\n@printindex %s\n" index)))))
+ (and index (format "\n@printindex %s\n" index))))
+ (node (org-texinfo--get-node headline info)))
(if (not command)
(concat (and (org-export-first-sibling-p headline info)
(format "@%s\n" (if numbered? 'enumerate 'itemize)))
- "@item\n" full-text "\n"
+ (format "@item\n@anchor{%s}%s\n" node full-text)
contents
(if (org-export-last-sibling-p headline info)
(format "@end %s" (if numbered? 'enumerate 'itemize))
@@ -906,13 +923,12 @@ holding contextual information."
(concat
;; Even if HEADLINE is using @subheading and al., leave an
;; anchor so cross-references in the Org document still work.
- (format (if notoc? "@anchor{%s}\n" "@node %s\n")
- (org-texinfo--get-node headline info))
+ (format (if notoc? "@anchor{%s}\n" "@node %s\n") node)
(format command full-text)
contents))))))
(defun org-texinfo-format-headline-default-function
- (todo _todo-type priority text tags)
+ (todo _todo-type priority text tags)
"Default format function for a headline.
See `org-texinfo-format-headline-function' for details."
(concat (and todo (format "@strong{%s} " todo))
@@ -949,7 +965,7 @@ holding contextual information."
todo todo-type priority title tags contents)))
(defun org-texinfo-format-inlinetask-default-function
- (todo _todo-type priority title tags contents)
+ (todo _todo-type priority title tags contents)
"Default format function for inlinetasks.
See `org-texinfo-format-inlinetask-function' for details."
(let ((full-title
@@ -1111,7 +1127,9 @@ current state of the export, as a plist."
(path (org-element-property :path link))
(filename
(file-name-sans-extension
- (if (file-name-absolute-p path) (expand-file-name path) path)))
+ (if (file-name-absolute-p path)
+ (expand-file-name path)
+ (file-relative-name path))))
(extension (file-name-extension path))
(attributes (org-export-read-attribute :attr_texinfo parent))
(height (or (plist-get attributes :height) ""))
@@ -1192,7 +1210,7 @@ a plist containing contextual information."
;; Colons are used as a separator between title and node
;; name. Remove them.
(replace-regexp-in-string
- "[ \t]+:+" ""
+ "[ \t]*:+" ""
(org-texinfo--sanitize-title
(org-export-get-alt-title h info) info)))
(node (org-texinfo--get-node h info))
@@ -1215,12 +1233,15 @@ holding contextual information."
:texinfo-entries-cache)))
(cached-entries (gethash scope cache 'no-cache)))
(if (not (eq cached-entries 'no-cache)) cached-entries
- (puthash scope
- (cl-remove-if
- (lambda (h)
- (org-not-nil (org-export-get-node-property :COPYING h t)))
- (org-export-collect-headlines info 1 scope))
- cache))))
+ (let* ((sections (org-texinfo--sectioning-structure info))
+ (max-depth (length sections)))
+ (puthash scope
+ (cl-remove-if
+ (lambda (h)
+ (or (org-not-nil (org-export-get-node-property :COPYING h t))
+ (< max-depth (org-export-get-relative-level h info))))
+ (org-export-collect-headlines info 1 scope))
+ cache)))))
;;;; Node Property
@@ -1585,7 +1606,7 @@ channel."
(defun org-texinfo-verse-block (_verse-block contents _info)
"Transcode a VERSE-BLOCK element from Org to Texinfo.
-CONTENTS is verse block contents. INFO is a plist holding
+CONTENTS is verse block contents. INFO is a plist holding
contextual information."
(format "@display\n%s@end display" contents))
@@ -1594,7 +1615,7 @@ contextual information."
;;;###autoload
(defun org-texinfo-export-to-texinfo
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to a Texinfo file.
If narrowing is active in the current buffer, only export its
@@ -1645,7 +1666,7 @@ Usage: emacs -batch -f org-texinfo-export-to-texinfo-batch INFILE OUTFILE"
;;;###autoload
(defun org-texinfo-export-to-info
- (&optional async subtreep visible-only body-only ext-plist)
+ (&optional async subtreep visible-only body-only ext-plist)
"Export current buffer to Texinfo then process through to INFO.
If narrowing is active in the current buffer, only export its