mirror of
https://git.savannah.gnu.org/git/emacs/org-mode.git
synced 2024-09-29 18:36:26 +00:00
Implement `org-export-custom-protocol-maybe' and use it
* lisp/ox.el (org-export-custom-protocol-maybe): New function. * contrib/lisp/ox-groff.el (org-groff-link): * lisp/ox-ascii.el (org-ascii-link): * lisp/ox-beamer.el (org-beamer-link): * lisp/ox-html.el (org-html-link): * lisp/ox-latex.el (org-latex-link): * lisp/ox-man.el (org-man-link): * lisp/ox-md.el (org-md-link): * lisp/ox-odt.el (org-odt-link): * lisp/ox-texinfo.el (org-texinfo-link): Use new function. * testing/lisp/test-ox.el (test-org-export/custom-protocol-maybe): New test.
This commit is contained in:
parent
8ce845ba6c
commit
3900155788
|
@ -1255,9 +1255,9 @@ INFO is a plist holding contextual information. See
|
|||
(concat type ":" raw-path))
|
||||
((and (string= type "file") (file-name-absolute-p raw-path))
|
||||
(concat "file://" raw-path))
|
||||
(t raw-path)))
|
||||
protocol)
|
||||
(t raw-path))))
|
||||
(cond
|
||||
((org-export-custom-protocol-maybe link desc info))
|
||||
;; Image file.
|
||||
(imagep (org-groff-link--inline-image link info))
|
||||
;; import groff files
|
||||
|
|
|
@ -1520,6 +1520,7 @@ DESC is the description part of the link, or the empty string.
|
|||
INFO is a plist holding contextual information."
|
||||
(let ((type (org-element-property :type link)))
|
||||
(cond
|
||||
((org-export-custom-protocol-maybe link desc info))
|
||||
((string= type "coderef")
|
||||
(let ((ref (org-element-property :path link)))
|
||||
(format (org-export-get-coderef-format ref desc)
|
||||
|
@ -1545,10 +1546,6 @@ INFO is a plist holding contextual information."
|
|||
(org-export-data
|
||||
(org-element-property :title destination)
|
||||
info)))))))))
|
||||
((let ((protocol (nth 2 (assoc type org-link-protocols)))
|
||||
(path (org-element-property :path link)))
|
||||
(and (functionp protocol)
|
||||
(funcall protocol (org-link-unescape path) desc 'ascii))))
|
||||
(t
|
||||
(let ((raw-link (org-element-property :raw-link link)))
|
||||
(if (not (org-string-nw-p desc)) (format "[%s]" raw-link)
|
||||
|
|
|
@ -689,8 +689,10 @@ CONTENTS is the description part of the link. INFO is a plist
|
|||
used as a communication channel."
|
||||
(let ((type (org-element-property :type link))
|
||||
(path (org-element-property :path link)))
|
||||
;; Use \hyperlink command for all internal links.
|
||||
(cond
|
||||
;; Link type is handled by a special function.
|
||||
((org-export-custom-protocol-maybe link contents info))
|
||||
;; Use \hyperlink command for all internal links.
|
||||
((equal type "radio")
|
||||
(let ((destination (org-export-resolve-radio-link link info)))
|
||||
(if (not destination) contents
|
||||
|
|
|
@ -2765,9 +2765,10 @@ INFO is a plist holding contextual information. See
|
|||
(org-export-read-attribute :attr_html parent))))
|
||||
(attributes
|
||||
(let ((attr (org-html--make-attribute-string attributes-plist)))
|
||||
(if (org-string-nw-p attr) (concat " " attr) "")))
|
||||
protocol)
|
||||
(if (org-string-nw-p attr) (concat " " attr) ""))))
|
||||
(cond
|
||||
;; Link type is handled by a special function.
|
||||
((org-export-custom-protocol-maybe link desc info))
|
||||
;; Image file.
|
||||
((and (plist-get info :html-inline-images)
|
||||
(org-export-inline-image-p
|
||||
|
@ -2856,9 +2857,6 @@ INFO is a plist holding contextual information. See
|
|||
attributes
|
||||
(format (org-export-get-coderef-format path desc)
|
||||
(org-export-resolve-coderef path info)))))
|
||||
;; Link type is handled by a special function.
|
||||
((functionp (setq protocol (nth 2 (assoc type org-link-protocols))))
|
||||
(funcall protocol (org-link-unescape path) desc 'html))
|
||||
;; External link with a description part.
|
||||
((and path desc) (format "<a href=\"%s\"%s>%s</a>" path attributes desc))
|
||||
;; External link without a description part.
|
||||
|
|
|
@ -1965,9 +1965,10 @@ INFO is a plist holding contextual information. See
|
|||
(concat type ":" raw-path))
|
||||
((and (string= type "file") (file-name-absolute-p raw-path))
|
||||
(concat "file:" raw-path))
|
||||
(t raw-path)))
|
||||
protocol)
|
||||
(t raw-path))))
|
||||
(cond
|
||||
;; Link type is handled by a special function.
|
||||
((org-export-custom-protocol-maybe link desc info))
|
||||
;; Image file.
|
||||
(imagep (org-latex--inline-image link info))
|
||||
;; Radio link: Transcode target's contents and use them as link's
|
||||
|
@ -2023,9 +2024,6 @@ INFO is a plist holding contextual information. See
|
|||
((string= type "coderef")
|
||||
(format (org-export-get-coderef-format path desc)
|
||||
(org-export-resolve-coderef path info)))
|
||||
;; Link type is handled by a special function.
|
||||
((functionp (setq protocol (nth 2 (assoc type org-link-protocols))))
|
||||
(funcall protocol (org-link-unescape path) desc 'latex))
|
||||
;; External link with a description part.
|
||||
((and path desc) (format "\\href{%s}{%s}" path desc))
|
||||
;; External link without a description part.
|
||||
|
|
|
@ -657,6 +657,8 @@ INFO is a plist holding contextual information. See
|
|||
(t raw-path)))
|
||||
protocol)
|
||||
(cond
|
||||
;; Link type is handled by a special function.
|
||||
((org-export-custom-protocol-maybe link desc info))
|
||||
;; External link with a description part.
|
||||
((and path desc) (format "%s \\fBat\\fP \\fI%s\\fP" path desc))
|
||||
;; External link without a description part.
|
||||
|
|
|
@ -313,6 +313,8 @@ a communication channel."
|
|||
raw-path))))
|
||||
(type (org-element-property :type link)))
|
||||
(cond
|
||||
;; Link type is handled by a special function.
|
||||
((org-export-custom-protocol-maybe link contents info))
|
||||
((member type '("custom-id" "id"))
|
||||
(let ((destination (org-export-resolve-id-link link info)))
|
||||
(if (stringp destination) ; External file.
|
||||
|
@ -358,13 +360,6 @@ a communication channel."
|
|||
;; BUG: shouldn't headlines have a form like [ref](name) in md?
|
||||
(org-export-data
|
||||
(org-element-property :title destination) info))))))))
|
||||
;; Link type is handled by a special function.
|
||||
((let ((protocol (nth 2 (assoc type org-link-protocols))))
|
||||
(and (functionp protocol)
|
||||
(funcall protocol
|
||||
(org-link-unescape (org-element-property :path link))
|
||||
contents
|
||||
'md))))
|
||||
(t (let* ((raw-path (org-element-property :path link))
|
||||
(path
|
||||
(cond
|
||||
|
|
|
@ -2736,9 +2736,10 @@ INFO is a plist holding contextual information. See
|
|||
(concat "file:" raw-path))
|
||||
(t raw-path)))
|
||||
;; Convert & to & for correct XML representation
|
||||
(path (replace-regexp-in-string "&" "&" path))
|
||||
protocol)
|
||||
(path (replace-regexp-in-string "&" "&" path)))
|
||||
(cond
|
||||
;; Link type is handled by a special function.
|
||||
((org-export-custom-protocol-maybe link desc info))
|
||||
;; Image file.
|
||||
((and (not desc) (org-export-inline-image-p
|
||||
link (plist-get info :odt-inline-image-rules)))
|
||||
|
@ -2820,9 +2821,6 @@ INFO is a plist holding contextual information. See
|
|||
(format
|
||||
"<text:bookmark-ref text:reference-format=\"number\" text:ref-name=\"OrgXref.%s\">%s</text:bookmark-ref>"
|
||||
href line-no))))
|
||||
;; Link type is handled by a special function.
|
||||
((functionp (setq protocol (nth 2 (assoc type org-link-protocols))))
|
||||
(funcall protocol (org-link-unescape path) desc 'odt))
|
||||
;; External link with a description part.
|
||||
((and path desc)
|
||||
(let ((link-contents (org-element-contents link)))
|
||||
|
|
|
@ -915,9 +915,9 @@ INFO is a plist holding contextual information. See
|
|||
(concat type ":" raw-path))
|
||||
((and (string= type "file") (file-name-absolute-p raw-path))
|
||||
(concat "file:" raw-path))
|
||||
(t raw-path)))
|
||||
protocol)
|
||||
(t raw-path))))
|
||||
(cond
|
||||
((org-export-custom-protocol-maybe link desc info))
|
||||
((equal type "radio")
|
||||
(let ((destination (org-export-resolve-radio-link link info)))
|
||||
(if (not destination) desc
|
||||
|
@ -976,9 +976,6 @@ INFO is a plist holding contextual information. See
|
|||
(format "@email{%s}"
|
||||
(concat (org-texinfo--sanitize-content path)
|
||||
(and desc (concat "," desc)))))
|
||||
((let ((protocol (nth 2 (assoc type org-link-protocols))))
|
||||
(and (functionp protocol)
|
||||
(funcall protocol (org-link-unescape path) desc 'texinfo))))
|
||||
;; External link with a description part.
|
||||
((and path desc) (format "@uref{%s,%s}" path desc))
|
||||
;; External link without a description part.
|
||||
|
|
25
lisp/ox.el
25
lisp/ox.el
|
@ -3862,6 +3862,9 @@ meant to be translated with `org-export-data' or alike."
|
|||
|
||||
;;;; For Links
|
||||
;;
|
||||
;; `org-export-custom-protocol-maybe' handles custom protocol defined
|
||||
;; with `org-add-link-type', which see.
|
||||
;;
|
||||
;; `org-export-solidify-link-text' turns a string into a safer version
|
||||
;; for links, replacing most non-standard characters with hyphens.
|
||||
;;
|
||||
|
@ -3888,6 +3891,28 @@ meant to be translated with `org-export-data' or alike."
|
|||
(save-match-data
|
||||
(mapconcat 'identity (org-split-string s "[^a-zA-Z0-9_.-:]+") "-")))
|
||||
|
||||
(defun org-export-custom-protocol-maybe (link desc info)
|
||||
"Try exporting LINK with a dedicated function.
|
||||
|
||||
DESC is its description, as a string, or nil. INFO is the plist
|
||||
containing export state. Return output as a string, or nil if no
|
||||
protocol handles LINK.
|
||||
|
||||
A custom protocol is expected to have precedence over regular
|
||||
back-end export. The function ignores links with an implicit
|
||||
type (e.g., \"custom-id\")."
|
||||
(let ((type (org-element-property :type link))
|
||||
(backend (let ((b (plist-get info :back-end)))
|
||||
(and b (org-export-backend-name b)))))
|
||||
(unless (or (member type '("coderef" "custom-id" "fuzzy" "radio"))
|
||||
(not backend))
|
||||
(let ((protocol (nth 2 (assoc type org-link-protocols))))
|
||||
(and (functionp protocol)
|
||||
(funcall protocol
|
||||
(org-link-unescape (org-element-property :path link))
|
||||
desc
|
||||
backend))))))
|
||||
|
||||
(defun org-export-get-coderef-format (path desc)
|
||||
"Return format string for code reference link.
|
||||
PATH is the link path. DESC is its description."
|
||||
|
|
|
@ -2026,6 +2026,53 @@ Paragraph[fn:1]"
|
|||
|
||||
;;; Links
|
||||
|
||||
(ert-deftest test-org-export/custom-protocol-maybe ()
|
||||
"Test `org-export-custom-protocol-maybe' specifications."
|
||||
(should
|
||||
(string-match
|
||||
"success"
|
||||
(let ((org-link-types (copy-sequence org-link-types)))
|
||||
(org-add-link-type "foo" nil (lambda (p d f) "success"))
|
||||
(org-export-string-as
|
||||
"[[foo:path]]"
|
||||
(org-export-create-backend
|
||||
:name 'test
|
||||
:transcoders '((section . (lambda (s c i) c))
|
||||
(paragraph . (lambda (p c i) c))
|
||||
(link . (lambda (l c i)
|
||||
(or (org-export-custom-protocol-maybe l c i)
|
||||
"failure")))))))))
|
||||
(should-not
|
||||
(string-match
|
||||
"success"
|
||||
(let ((org-link-types (copy-sequence org-link-types)))
|
||||
(org-add-link-type
|
||||
"foo" nil (lambda (p d f) (and (eq f 'test) "success")))
|
||||
(org-export-string-as
|
||||
"[[foo:path]]"
|
||||
(org-export-create-backend
|
||||
:name 'no-test
|
||||
:transcoders '((section . (lambda (s c i) c))
|
||||
(paragraph . (lambda (p c i) c))
|
||||
(link . (lambda (l c i)
|
||||
(or (org-export-custom-protocol-maybe l c i)
|
||||
"failure")))))))))
|
||||
;; Ignore anonymous back-ends.
|
||||
(should-not
|
||||
(string-match
|
||||
"success"
|
||||
(let ((org-link-types (copy-sequence org-link-types)))
|
||||
(org-add-link-type
|
||||
"foo" nil (lambda (p d f) (and (eq f 'test) "success")))
|
||||
(org-export-string-as
|
||||
"[[foo:path]]"
|
||||
(org-export-create-backend
|
||||
:transcoders '((section . (lambda (s c i) c))
|
||||
(paragraph . (lambda (p c i) c))
|
||||
(link . (lambda (l c i)
|
||||
(or (org-export-custom-protocol-maybe l c i)
|
||||
"failure"))))))))))
|
||||
|
||||
(ert-deftest test-org-export/get-coderef-format ()
|
||||
"Test `org-export-get-coderef-format' specifications."
|
||||
;; A link without description returns "%s"
|
||||
|
|
Loading…
Reference in a new issue