Browse Source

Extend export tooling in link parameters

* lisp/ol.el (org-link-parameters): Allow a fourth "info" argument for
`:export' property.  Expound docstring.
* lisp/ox.el (org-export-custom-protocol-maybe): Accept a fourth
optional argument.
* lisp/ox-ascii.el (org-ascii--describe-links):
(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-org.el (org-org-link):
* lisp/ox-texinfo.el (org-texinfo-link):
* contrib/lisp/ox-groff.el (org-groff-link): Provide expected fourth
argument.
* lisp/ox.el (org-export-link-as-file): New function.
* lisp/ol.el (org-link-parameters): Add reference to new function in docstring.
* testing/lisp/test-ox.el (test-org-export/link-as-file): Add tests.
(test-org-export/custom-protocol-maybe): Update tests.
Nicolas Goaziou 5 years ago
parent
commit
ab9166ad29
13 changed files with 147 additions and 48 deletions
  1. 1 1
      contrib/lisp/ox-groff.el
  2. 76 24
      lisp/ol.el
  3. 2 2
      lisp/ox-ascii.el
  4. 1 1
      lisp/ox-beamer.el
  5. 1 1
      lisp/ox-html.el
  6. 1 1
      lisp/ox-latex.el
  7. 2 2
      lisp/ox-man.el
  8. 1 1
      lisp/ox-md.el
  9. 1 1
      lisp/ox-odt.el
  10. 2 2
      lisp/ox-org.el
  11. 1 1
      lisp/ox-texinfo.el
  12. 29 8
      lisp/ox.el
  13. 29 3
      testing/lisp/test-ox.el

+ 1 - 1
contrib/lisp/ox-groff.el

@@ -1248,7 +1248,7 @@ INFO is a plist holding contextual information.  See
                 ((string= type "file") (org-export-file-uri raw-path))
                 (t raw-path))))
     (cond
-     ((org-export-custom-protocol-maybe link desc 'groff))
+     ((org-export-custom-protocol-maybe link desc 'groff info))
      ;; Image file.
      (imagep (org-groff-link--inline-image link info))
      ;; import groff files

+ 76 - 24
lisp/ol.el

@@ -86,42 +86,94 @@
   :group 'org)
 
 (defcustom org-link-parameters nil
-  "An alist of properties that defines all the links in Org mode.
+  "Alist of properties that defines all the links in Org mode.
+
 The key in each association is a string of the link type.
-Subsequent optional elements make up a plist of link properties.
+Subsequent optional elements make up a property list for that
+type.
+
+All properties ar optional.  However, the most important ones
+are, in this order, `:follow', `:export', and `:store', described
+below.
+
+`:follow'
+
+  Function that takes the link path (a string) as an argument and
+  \"opens\" the link.
+
+`:export'
+
+  Function that accepts four arguments:
+  - the path, as a string,
+  - the description as a string, or nil,
+  - the export back-end,
+  - the export communication channel, as a plist.
+
+  If the new link type is meant to be exported as a \"file\"-link
+  (or as an image), consider using `org-export-link-as-file',
+  either as an helper function, or as a value for this parameter.
+
+  When nil, export for that type of link is delegated to the
+  back-end.
+
+`:store'
+
+  Function responsible for storing the link.  See the function
+  `org-store-link-functions' for a description of the expected
+  arguments.
+
+Additional properties provide more specific control over the
+link.
+
+`:activate-func'
+
+  Function to run at the end of Font Lock activation.  It must
+  accept four arguments:
+  - the buffer position at the start of the link,
+  - the buffer position at its end,
+  - the path, as a string,
+  - a boolean, non-nil when the link has brackets.
+
+`:complete'
+
+  Function that inserts a link with completion.  The function
+  takes one optional prefix argument.
+
+`:display'
+
+  Value for `invisible' text property on the hidden parts of the
+  link.  The most useful value is `full', which will not fold the
+  link in descriptive display.  Default is `org-link'.
+
+`:face'
 
-:follow - A function that takes the link path as an argument.
+  Face for the link, or a function returning a face.  The
+  function takes one argument, which is the path.
 
-:export - A function that takes the link path, description and
-export-backend as arguments.
+  The default face is `org-link'.
 
-:store - A function responsible for storing the link.  See the
-function `org-store-link-functions'.
+`:help-echo'
 
-:complete - A function that inserts a link with completion.  The
-function takes one optional prefix argument.
+  String or function used as a value for the `help-echo' text
+  property.  The function is called with one argument, the help
+  string to display, and should return a string.
 
-:face - A face for the link, or a function that returns a face.
-The function takes one argument which is the link path.  The
-default face is `org-link'.
+`:htmlize-link'
 
-:mouse-face - The mouse-face. The default is `highlight'.
+  Function or plist for the `htmlize-link' text property.  The
+  function takes no argument.
 
-:display - `full' will not fold the link in descriptive
-display.  Default is `org-link'.
+  Default is (:uri \"type:path\")
 
-:help-echo - A string or function that takes (window object position)
-as arguments and returns a string.
+`:keymap'
 
-:keymap - A keymap that is active on the link.  The default is
-`org-mouse-map'.
+  Active keymap when point is on the link.  Default is
+  `org-mouse-map'.
 
-:htmlize-link - A function for the htmlize-link.  Defaults
-to (list :uri \"type:path\")
+`:mouse-face'
 
-:activate-func - A function to run at the end of font-lock
-activation.  The function must accept (link-start link-end path bracketp)
-as arguments."
+  Face used when hovering over the link.  Default is
+  `highlight'."
   :group 'org-link
   :package-version '(Org . "9.1")
   :type '(alist :tag "Link display parameters"

+ 2 - 2
lisp/ox-ascii.el

@@ -957,7 +957,7 @@ channel."
 	((not (org-element-contents link)) nil)
 	;; Do not add a link already handled by custom export
 	;; functions.
-	((org-export-custom-protocol-maybe link anchor 'ascii) nil)
+	((org-export-custom-protocol-maybe link anchor 'ascii info) nil)
 	(t
 	 (concat
 	  (org-ascii--fill-string
@@ -1579,7 +1579,7 @@ INFO is a plist holding contextual information."
 		 (concat type ":" raw-path))
 		(t (concat type ":" raw-path)))))
     (cond
-     ((org-export-custom-protocol-maybe link desc 'ascii))
+     ((org-export-custom-protocol-maybe link desc 'ascii info))
      ((string= type "coderef")
       (format (org-export-get-coderef-format path desc)
 	      (org-export-resolve-coderef path info)))

+ 1 - 1
lisp/ox-beamer.el

@@ -731,7 +731,7 @@ channel."
   "Transcode a LINK object into Beamer code.
 CONTENTS is the description part of the link.  INFO is a plist
 used as a communication channel."
-  (or (org-export-custom-protocol-maybe link contents 'beamer)
+  (or (org-export-custom-protocol-maybe link contents 'beamer info)
       ;; Fall-back to LaTeX export.  However, prefer "\hyperlink" over
       ;; "\hyperref" since the former handles overlay specifications.
       (let ((latex-link (org-export-with-backend 'latex link contents info)))

+ 1 - 1
lisp/ox-html.el

@@ -3049,7 +3049,7 @@ INFO is a plist holding contextual information.  See
 	    (if (org-string-nw-p attr) (concat " " attr) ""))))
     (cond
      ;; Link type is handled by a special function.
-     ((org-export-custom-protocol-maybe link desc 'html))
+     ((org-export-custom-protocol-maybe link desc 'html info))
      ;; Image file.
      ((and (plist-get info :html-inline-images)
 	   (org-export-inline-image-p

+ 1 - 1
lisp/ox-latex.el

@@ -2541,7 +2541,7 @@ INFO is a plist holding contextual information.  See
 		       raw-path)))))
     (cond
      ;; Link type is handled by a special function.
-     ((org-export-custom-protocol-maybe link desc 'latex))
+     ((org-export-custom-protocol-maybe link desc 'latex info))
      ;; Image file.
      (imagep (org-latex--inline-image link info))
      ;; Radio link: Transcode target's contents and use them as link's

+ 2 - 2
lisp/ox-man.el

@@ -603,7 +603,7 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
 ;;; Link
 
 
-(defun org-man-link (link desc _info)
+(defun org-man-link (link desc info)
   "Transcode a LINK object from Org to Man.
 
 DESC is the description part of the link, or the empty string.
@@ -623,7 +623,7 @@ INFO is a plist holding contextual information.  See
                 (t raw-path))))
     (cond
      ;; Link type is handled by a special function.
-     ((org-export-custom-protocol-maybe link desc 'man))
+     ((org-export-custom-protocol-maybe link desc 'man 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.

+ 1 - 1
lisp/ox-md.el

@@ -412,7 +412,7 @@ INFO is a plist holding contextual information.  See
 		(t raw-path))))
     (cond
      ;; Link type is handled by a special function.
-     ((org-export-custom-protocol-maybe link desc 'md))
+     ((org-export-custom-protocol-maybe link desc 'md info))
      ((member type '("custom-id" "id" "fuzzy"))
       (let ((destination (if (string= type "fuzzy")
 			     (org-export-resolve-fuzzy-link link info)

+ 1 - 1
lisp/ox-odt.el

@@ -2715,7 +2715,7 @@ INFO is a plist holding contextual information.  See
 	 (path (replace-regexp-in-string "&" "&" path)))
     (cond
      ;; Link type is handled by a special function.
-     ((org-export-custom-protocol-maybe link desc 'odt))
+     ((org-export-custom-protocol-maybe link desc 'odt info))
      ;; Image file.
      ((and (not desc) imagep) (org-odt-link--inline-image link info))
      ;; Formula file.

+ 2 - 2
lisp/ox-org.el

@@ -165,11 +165,11 @@ CONTENTS is nil.  INFO is ignored."
 		    '("AUTHOR" "CREATOR" "DATE" "EMAIL" "OPTIONS" "TITLE"))
       (org-element-keyword-interpreter keyword nil))))
 
-(defun org-org-link (link contents _info)
+(defun org-org-link (link contents info)
   "Transcode LINK object back into Org syntax.
 CONTENTS is the description of the link, as a string, or nil.
 INFO is a plist containing current export state."
-  (or (org-export-custom-protocol-maybe link contents 'org)
+  (or (org-export-custom-protocol-maybe link contents 'org info)
       (org-element-link-interpreter link contents)))
 
 (defun org-org-template (contents info)

+ 1 - 1
lisp/ox-texinfo.el

@@ -1065,7 +1065,7 @@ INFO is a plist holding contextual information.  See
 		 (org-export-file-uri raw-path))
 		(t raw-path))))
     (cond
-     ((org-export-custom-protocol-maybe link desc 'texinfo))
+     ((org-export-custom-protocol-maybe link desc 'texinfo info))
      ((org-export-inline-image-p link org-texinfo-inline-image-rules)
       (org-texinfo--inline-image link info))
      ((equal type "radio")

+ 29 - 8
lisp/ox.el

@@ -4185,8 +4185,23 @@ meant to be translated with `org-export-data' or alike."
 
 (org-define-error 'org-link-broken "Unable to resolve link; aborting")
 
-(defun org-export-custom-protocol-maybe (link desc backend)
-  "Try exporting LINK with a dedicated function.
+(defun org-export-link-as-file (path description backend info)
+  "Pretend PATH is a file name, and export it.
+
+DESCRIPTION, when non-nil, is the description of the link, as
+a string.  BACKEND is the symbol representing the back-end used
+for export.  INFO is the communication channel, as a plist.
+
+This function is meant to be used as a possible tool for
+`:export' property in `org-link-parameters'."
+  (org-export-data-with-backend
+   (org-element-parse-secondary-string
+    (org-link-make-string (concat "file:" path) description) '(link))
+   backend
+   info))
+
+(defun org-export-custom-protocol-maybe (link desc backend &optional info)
+  "Try exporting LINK object with a dedicated function.
 
 DESC is its description, as a string, or nil.  BACKEND is the
 back-end used for export, as a symbol.
@@ -4197,14 +4212,20 @@ A custom protocol has 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)))
-    (unless (or (member type '("coderef" "custom-id" "fuzzy" "radio"))
+    (unless (or (member type '("coderef" "custom-id" "fuzzy" "radio" nil))
 		(not backend))
-      (let ((protocol (org-link-get-parameter type :export)))
+      (let ((protocol (org-link-get-parameter type :export))
+	    (path (org-element-property :path link)))
 	(and (functionp protocol)
-	     (funcall protocol
-		      (org-element-property :path link)
-		      desc
-		      backend))))))
+	     (condition-case nil
+		 (funcall protocol path desc backend info)
+	       ;; XXX: The function used (< Org 9.4) to accept only
+	       ;; three mandatory arguments.  Type-specific `:export'
+	       ;; functions in the wild may not handle current
+	       ;; signature.  Provide backward compatibility support
+	       ;; for them.
+	       (wrong-number-of-arguments
+		(funcall protocol path desc backend))))))))
 
 (defun org-export-get-coderef-format (path desc)
   "Return format string for code reference link.

+ 29 - 3
testing/lisp/test-ox.el

@@ -2965,6 +2965,32 @@ Para2"
 
 ;;; Links
 
+(ert-deftest test-org-export/link-as-file ()
+  "Test `org-export-link-as-file' specifications."
+  ;; Export path as a "file"-type link.
+  (should
+   (equal "success"
+	  (let ((backend
+		 (org-export-create-backend
+		  :name 'test
+		  :transcoders
+		  '((link . (lambda (l _c _i)
+			      (if (equal "file" (org-element-property :type l))
+				  "success"
+				"failure")))))))
+	    (org-export-link-as-file "foo.org" nil backend nil))))
+  ;; Exported path handles "file"-type specific properties,
+  ;; e.g., :search-option.
+  (should
+   (equal "bar"
+	  (let ((backend
+		 (org-export-create-backend
+		  :name 'test
+		  :transcoders
+		  '((link . (lambda (l _c _i)
+			      (org-element-property :search-option l)))))))
+	    (org-export-link-as-file "foo.org::bar" nil backend nil)))))
+
 (ert-deftest test-org-export/custom-protocol-maybe ()
   "Test `org-export-custom-protocol-maybe' specifications."
   (should
@@ -2980,7 +3006,7 @@ Para2"
 	'((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 'test)
+		    (or (org-export-custom-protocol-maybe l c 'test i)
 			"failure")))))))))
   (should-not
    (string-match
@@ -2996,7 +3022,7 @@ Para2"
 	'((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 'no-test)
+		    (or (org-export-custom-protocol-maybe l c 'no-test i)
 			"failure")))))))))
   ;; Ignore anonymous back-ends.
   (should-not
@@ -3012,7 +3038,7 @@ Para2"
 	'((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 nil)
+		    (or (org-export-custom-protocol-maybe l c nil i)
 			"failure"))))))))))
 
 (ert-deftest test-org-export/get-coderef-format ()