Browse Source

Fix file links when using #+INCLUDE

Daniel Gomez 7 years ago
parent
commit
d81a1d088c
1 changed files with 41 additions and 7 deletions
  1. 41 7
      lisp/ox.el

+ 41 - 7
lisp/ox.el

@@ -3257,7 +3257,8 @@ avoid infinite recursion.  Optional argument DIR is the current
 working directory.  It is used to properly resolve relative
 working directory.  It is used to properly resolve relative
 paths.  Optional argument FOOTNOTES is a hash-table used for
 paths.  Optional argument FOOTNOTES is a hash-table used for
 storing and resolving footnotes.  It is created automatically."
 storing and resolving footnotes.  It is created automatically."
-  (let ((case-fold-search t)
+  (let ((includer-file (buffer-file-name (buffer-base-buffer)))
+	(case-fold-search t)
 	(file-prefix (make-hash-table :test #'equal))
 	(file-prefix (make-hash-table :test #'equal))
 	(current-prefix 0)
 	(current-prefix 0)
 	(footnotes (or footnotes (make-hash-table :test #'equal)))
 	(footnotes (or footnotes (make-hash-table :test #'equal)))
@@ -3370,10 +3371,12 @@ storing and resolving footnotes.  It is created automatically."
 		       (insert
 		       (insert
 			(org-export--prepare-file-contents
 			(org-export--prepare-file-contents
 			 file lines ind minlevel
 			 file lines ind minlevel
-			 (or
-			  (gethash file file-prefix)
-			  (puthash file (cl-incf current-prefix) file-prefix))
-			 footnotes)))
+			 (or (gethash file file-prefix)
+			     (puthash file
+				      (cl-incf current-prefix)
+				      file-prefix))
+			 footnotes
+			 includer-file)))
 		     (org-export-expand-include-keyword
 		     (org-export-expand-include-keyword
 		      (cons (list file lines) included)
 		      (cons (list file lines) included)
 		      (file-name-directory file)
 		      (file-name-directory file)
@@ -3451,7 +3454,7 @@ Return a string of lines to be included in the format expected by
 		       counter))))))))
 		       counter))))))))
 
 
 (defun org-export--prepare-file-contents
 (defun org-export--prepare-file-contents
-    (file &optional lines ind minlevel id footnotes)
+    (file &optional lines ind minlevel id footnotes includer)
   "Prepare contents of FILE for inclusion and return it as a string.
   "Prepare contents of FILE for inclusion and return it as a string.
 
 
 When optional argument LINES is a string specifying a range of
 When optional argument LINES is a string specifying a range of
@@ -3473,9 +3476,40 @@ This is useful to avoid conflicts when more than one Org file
 with footnotes is included in a document.
 with footnotes is included in a document.
 
 
 Optional argument FOOTNOTES is a hash-table to store footnotes in
 Optional argument FOOTNOTES is a hash-table to store footnotes in
-the included document."
+the included document.
+
+Optional argument INCLUDER is the file name where the inclusion
+is to happen."
   (with-temp-buffer
   (with-temp-buffer
     (insert-file-contents file)
     (insert-file-contents file)
+    ;; Adapt all file links within the included document that contain
+    ;; relative paths in order to make these paths relative to the
+    ;; base document, or absolute.
+    (goto-char (point-min))
+    (while (re-search-forward org-any-link-re nil t)
+      (let ((link (save-excursion
+		    (backward-char)
+		    (org-element-context))))
+	(when (string= "file" (org-element-property :type link))
+	  (let ((old-path (org-element-property :path link)))
+	    (unless (or (org-file-remote-p old-path)
+			(file-name-absolute-p old-path))
+	      (let ((new-path
+		     (let ((full (expand-file-name old-path
+						   (file-name-directory file))))
+		       (if (not includer) full
+			 (file-relative-name full
+					     (file-name-directory includer))))))
+		(insert (let ((new (org-element-copy link)))
+			  (org-element-put-property new :path new-path)
+			  (when (org-element-property :contents-begin link)
+			    (org-element-adopt-elements new
+			      (buffer-substring
+			       (org-element-property :contents-begin link)
+			       (org-element-property :contents-end link))))
+			  (delete-region (org-element-property :begin link)
+					 (org-element-property :end link))
+			  (org-element-interpret-data new)))))))))
     (when lines
     (when lines
       (let* ((lines (split-string lines "-"))
       (let* ((lines (split-string lines "-"))
 	     (lbeg (string-to-number (car lines)))
 	     (lbeg (string-to-number (car lines)))