Browse Source

ox: Add link localisation feature using persist

* lisp/ox.el (org-export-link-remote-p): A new function to determine
whether a link refers to a remote resource.
(org-export-link--remote-local-copy): Download and return the local
location of a remote resource link.
(org-export-link-localise): Transform remote links to refer to a local
copy of the resource.

* lisp/ox-latex.el (org-latex-link, org-latex-inline-image-rules): Make
use of the new functions for remote resources in ox.el to support
embedding https and tramp -linked files.
TEC 3 years ago
parent
commit
6ee45518f3
2 changed files with 47 additions and 3 deletions
  1. 6 3
      lisp/ox-latex.el
  2. 41 0
      lisp/ox.el

+ 6 - 3
lisp/ox-latex.el

@@ -755,8 +755,11 @@ environment."
 
 (defcustom org-latex-inline-image-rules
   `(("file" . ,(rx "."
-		   (or "pdf" "jpeg" "jpg" "png" "ps" "eps" "tikz" "pgf" "svg")
-		   eos)))
+                   (or "pdf" "jpeg" "jpg" "png" "ps" "eps" "tikz" "pgf" "svg")
+                   eos))
+    ("https" . ,(rx "."
+                    (or "jpeg" "jpg" "png" "ps" "eps" "tikz" "pgf" "svg")
+                    eos)))
   "Rules characterizing image files that can be inlined into LaTeX.
 
 A rule consists in an association whose key is the type of link
@@ -2588,7 +2591,7 @@ INFO is a plist holding contextual information.  See
      ;; Link type is handled by a special function.
      ((org-export-custom-protocol-maybe link desc 'latex info))
      ;; Image file.
-     (imagep (org-latex--inline-image link info))
+     (imagep (org-latex--inline-image (org-export-link-localise link) info))
      ;; Radio link: Transcode target's contents and use them as link's
      ;; description.
      ((string= type "radio")

+ 41 - 0
lisp/ox.el

@@ -4446,6 +4446,47 @@ Return value can be an object or an element:
 	   (concat (if (string-prefix-p "/" fullname) "file://" "file:///")
 		   fullname)))))
 
+(defun org-export-link-remote-p (link)
+  "Returns non-nil if the link refers to a remote resource."
+  (or (member (org-element-property :type link) '("http" "https" "ftp"))
+      (and (string= (org-element-property :type link) "file")
+           (file-remote-p (org-element-property :path link)))))
+
+(defun org-export-link--remote-local-copy (link)
+  "Download the remote resource specified by LINK, and return its local path."
+  ;; TODO work this into ol.el as a link parameter, say :download.
+  (let* ((location-type
+          (pcase (org-element-property :type link)
+            ((or "http" "https" "ftp") 'url)
+            ((and "file" (guard (file-remote-p
+                                 (org-element-property :path link))))
+             'file)
+            (_ (error "Cannot copy %s:%s to a local file"
+                      (org-element-property :type link)
+                      (org-element-property :path link)))))
+         (path
+          (pcase location-type
+            ('url
+             (concat (org-element-property :type link)
+                     ":" (org-element-property :path link)))
+            ('file
+             (org-element-property :path link)))))
+    (or (org-persist-read location-type path)
+        (org-persist-register location-type path
+                              :write-immediately t))))
+
+(defun org-export-link-localise (link)
+  "If LINK refers to a remote resource, modify it to point to a local downloaded copy."
+  (when (org-export-link-remote-p link)
+    (let* ((local-path (org-export-link--remote-local-copy link)))
+      (setcdr link
+              (thread-first (cadr link)
+                            (plist-put :type "file")
+                            (plist-put :path local-path)
+                            (plist-put :raw-link (concat "file:" local-path))
+                            list))))
+  link)
+
 ;;;; For References
 ;;
 ;; `org-export-get-reference' associate a unique reference for any