summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2017-10-14 12:29:52 +0200
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2017-10-14 12:29:52 +0200
commit827af5987348665edd4a632e827925b947c00f96 (patch)
treeb032f42d67bea3f81d50e563b8797afacbf5b578
parent025dbd7f3130244d5ac3d03c299e81cc795eeed2 (diff)
downloadorg-mode-827af5987348665edd4a632e827925b947c00f96.tar.gz
Fix links without contents in table of contents' entries
* lisp/ox.el (org-export-toc-entry-backend): New function. * lisp/ox-html.el (org-html--format-toc-headline): * lisp/ox-md.el (org-md--build-toc): * lisp/ox-odt.el (org-odt-toc): Use new function. * lisp/ox-texinfo.el (org-texinfo--sanitize-title): (org-texinfo--wrap-float): Handle links without contents. * testing/lisp/test-ox.el (test-org-export/toc-entry-backend): New test. Reported-by: ConcreteVitamin <concretevitamin@gmail.com> <http://lists.gnu.org/archive/html/emacs-orgmode/2017-10/msg00235.html>
-rw-r--r--lisp/ox-html.el10
-rw-r--r--lisp/ox-md.el11
-rw-r--r--lisp/ox-odt.el8
-rw-r--r--lisp/ox-texinfo.el33
-rw-r--r--lisp/ox.el31
-rw-r--r--testing/lisp/test-ox.el70
6 files changed, 127 insertions, 36 deletions
diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index 8ce4fb6..fe82099 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -2328,15 +2328,7 @@ INFO is a plist used as a communication channel."
(org-element-property :priority headline)))
(text (org-export-data-with-backend
(org-export-get-alt-title headline info)
- ;; Create an anonymous back-end that will ignore any
- ;; footnote-reference, link, radio-target and target
- ;; in table of contents.
- (org-export-create-backend
- :parent 'html
- :transcoders '((footnote-reference . ignore)
- (link . (lambda (object c i) c))
- (radio-target . (lambda (object c i) c))
- (target . ignore)))
+ (org-export-toc-entry-backend 'html)
info))
(tags (and (eq (plist-get info :with-tags) t)
(org-export-get-tags headline info))))
diff --git a/lisp/ox-md.el b/lisp/ox-md.el
index 8a25f1b..1218838 100644
--- a/lisp/ox-md.el
+++ b/lisp/ox-md.el
@@ -582,16 +582,7 @@ contents according to the current headline."
(format "[%s](#%s)"
(org-export-data-with-backend
(org-export-get-alt-title headline info)
- ;; Create an anonymous back-end that will
- ;; ignore any footnote-reference, link,
- ;; radio-target and target in table of
- ;; contents.
- (org-export-create-backend
- :parent 'md
- :transcoders '((footnote-reference . ignore)
- (link . (lambda (object c i) c))
- (radio-target . (lambda (object c i) c))
- (target . ignore)))
+ (org-export-toc-entry-backend 'md)
info)
(or (org-element-property :CUSTOM_ID headline)
(org-export-get-reference headline info))))
diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el
index f00fd99..d585636 100644
--- a/lisp/ox-odt.el
+++ b/lisp/ox-odt.el
@@ -1159,12 +1159,8 @@ table of contents as a string, or nil."
;; Likewise, links, footnote references and regular targets are also
;; suppressed.
(let* ((headlines (org-export-collect-headlines info depth scope))
- (backend (org-export-create-backend
- :parent (org-export-backend-name (plist-get info :back-end))
- :transcoders '((footnote-reference . ignore)
- (link . (lambda (object c i) c))
- (radio-target . (lambda (object c i) c))
- (target . ignore)))))
+ (backend (org-export-toc-entry-backend
+ (org-export-backend-name (plist-get info :back-end)))))
(when headlines
(org-odt--format-toc
(and (not scope) (org-export-translate "Table of Contents" :utf-8 info))
diff --git a/lisp/ox-texinfo.el b/lisp/ox-texinfo.el
index b5903a5..e6aa3e5 100644
--- a/lisp/ox-texinfo.el
+++ b/lisp/ox-texinfo.el
@@ -499,8 +499,12 @@ export state, as a plist."
(org-export-create-backend
:parent 'texinfo
:transcoders '((footnote-reference . ignore)
- (link . (lambda (object c i) c))
- (radio-target . (lambda (object c i) c))
+ (link . (lambda (l c i)
+ (or c
+ (org-export-data
+ (org-element-property :raw-link l)
+ i))))
+ (radio-target . (lambda (_r c _i) c))
(target . ignore)))
info))
@@ -519,18 +523,27 @@ strings (e.g., returned by `org-export-get-caption')."
(let* ((backend
(org-export-create-backend
:parent 'texinfo
- :transcoders '((link . (lambda (object c i) c))
- (radio-target . (lambda (object c i) c))
+ :transcoders '((link . (lambda (l c i)
+ (or c
+ (org-export-data
+ (org-element-property :raw-link l)
+ i))))
+ (radio-target . (lambda (_r c _i) c))
(target . ignore))))
(short-backend
(org-export-create-backend
:parent 'texinfo
- :transcoders '((footnote-reference . ignore)
- (inline-src-block . ignore)
- (link . (lambda (object c i) c))
- (radio-target . (lambda (object c i) c))
- (target . ignore)
- (verbatim . ignore))))
+ :transcoders
+ '((footnote-reference . ignore)
+ (inline-src-block . ignore)
+ (link . (lambda (l c i)
+ (or c
+ (org-export-data
+ (org-element-property :raw-link l)
+ i))))
+ (radio-target . (lambda (_r c _i) c))
+ (target . ignore)
+ (verbatim . ignore))))
(short-str
(if (and short caption)
(format "@shortcaption{%s}\n"
diff --git a/lisp/ox.el b/lisp/ox.el
index 1c43577..8277874 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -5176,7 +5176,7 @@ return nil."
info 'first-match)))
-;;;; For Tables Of Contents
+;;;; For Tables of Contents
;;
;; `org-export-collect-headlines' builds a list of all exportable
;; headline elements, maybe limited to a certain depth. One can then
@@ -5186,6 +5186,9 @@ return nil."
;; Once the generic function `org-export-collect-elements' is defined,
;; `org-export-collect-tables', `org-export-collect-figures' and
;; `org-export-collect-listings' can be derived from it.
+;;
+;; `org-export-toc-entry-backend' builds a special anonymous back-end
+;; useful to export table of contents' entries.
(defun org-export-collect-headlines (info &optional n scope)
"Collect headlines in order to build a table of contents.
@@ -5271,6 +5274,32 @@ INFO is a plist used as a communication channel.
Return a list of src-block elements with a caption."
(org-export-collect-elements 'src-block info))
+(defun org-export-toc-entry-backend (parent &rest transcoders)
+ "Return an export back-end appropriate for table of contents entries.
+
+PARENT is an export back-end the returned back-end should inherit
+from.
+
+By default, the back-end removes footnote references and targets.
+It also changes links and radio targets into regular text.
+TRANSCODERS optional argument, when non-nil, specifies additional
+transcoders. A transcoder follows the pattern (TYPE . FUNCTION)
+where type is an element or object type and FUNCTION the function
+transcoding it."
+ (declare (indent 1))
+ (org-export-create-backend
+ :parent parent
+ :transcoders
+ (append transcoders
+ `((footnote-reference . ,#'ignore)
+ (link . ,(lambda (l c i)
+ (or c
+ (org-export-data
+ (org-element-property :raw-link l)
+ i))))
+ (radio-target . ,(lambda (_r c _) c))
+ (target . ,#'ignore)))))
+
;;;; Smart Quotes
;;
diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el
index 72b6c8c..6b5e3a3 100644
--- a/testing/lisp/test-ox.el
+++ b/testing/lisp/test-ox.el
@@ -4320,6 +4320,76 @@ Another text. (ref:text)
(let ((scope (org-element-map tree 'headline #'identity info t)))
(length (org-export-collect-headlines info 1 scope)))))))
+(ert-deftest test-org-export/toc-entry-backend ()
+ "Test `org-export-toc-entry-backend' specifications."
+ ;; Ignore targets.
+ (should
+ (equal "H \n"
+ (org-test-with-temp-text "* H <<target>>"
+ (let (org-export-registered-backends)
+ (org-export-define-backend 'test
+ '((headline . (lambda (h _c i) (org-export-data-with-backend
+ (org-element-property :title h)
+ (org-export-toc-entry-backend 'test)
+ i)))))
+ (org-export-as 'test)))))
+ ;; Ignore footnote references.
+ (should
+ (equal "H \n"
+ (org-test-with-temp-text "[fn:1] Definition\n* H [fn:1]"
+ (let (org-export-registered-backends)
+ (org-export-define-backend 'test
+ '((headline . (lambda (h _c i) (org-export-data-with-backend
+ (org-element-property :title h)
+ (org-export-toc-entry-backend 'test)
+ i)))))
+ (org-export-as 'test)))))
+ ;; Replace plain links with contents, or with path.
+ (should
+ (equal "H Org mode\n"
+ (org-test-with-temp-text "* H [[http://orgmode.org][Org mode]]"
+ (let (org-export-registered-backends)
+ (org-export-define-backend 'test
+ '((headline . (lambda (h _c i) (org-export-data-with-backend
+ (org-element-property :title h)
+ (org-export-toc-entry-backend 'test)
+ i)))))
+ (org-export-as 'test)))))
+ (should
+ (equal "H http://orgmode.org\n"
+ (org-test-with-temp-text "* H [[http://orgmode.org]]"
+ (let (org-export-registered-backends)
+ (org-export-define-backend 'test
+ '((headline . (lambda (h _c i) (org-export-data-with-backend
+ (org-element-property :title h)
+ (org-export-toc-entry-backend 'test)
+ i)))))
+ (org-export-as 'test)))))
+ ;; Replace radio targets with contents.
+ (should
+ (equal "H radio\n"
+ (org-test-with-temp-text "* H <<<radio>>>"
+ (let (org-export-registered-backends)
+ (org-export-define-backend 'test
+ '((headline . (lambda (h _c i) (org-export-data-with-backend
+ (org-element-property :title h)
+ (org-export-toc-entry-backend 'test)
+ i)))))
+ (org-export-as 'test)))))
+ ;; With optional argument TRANSCODERS, specify other
+ ;; transformations.
+ (should
+ (equal "H bold\n"
+ (org-test-with-temp-text "* H *bold*"
+ (let (org-export-registered-backends)
+ (org-export-define-backend 'test
+ '((headline . (lambda (h _c i) (org-export-data-with-backend
+ (org-element-property :title h)
+ (org-export-toc-entry-backend 'test
+ '(bold . (lambda (_b c _i) c)))
+ i)))))
+ (org-export-as 'test))))))
+
;;; Templates