Browse Source

ox: Tolerate included file names without double quotes

* lisp/ox.el (org-export-expand-include-keyword): Tolerate included
  file names without double quotes.
Nicolas Goaziou 4 years ago
parent
commit
bd27a005bb
1 changed files with 73 additions and 65 deletions
  1. 73 65
      lisp/ox.el

+ 73 - 65
lisp/ox.el

@@ -3256,73 +3256,81 @@ working directory.  It is used to properly resolve relative
 paths."
   (let ((case-fold-search t))
     (goto-char (point-min))
-    (while (re-search-forward "^[ \t]*#\\+INCLUDE: +\\(.*\\)[ \t]*$" nil t)
-      (when (eq (org-element-type (save-match-data (org-element-at-point)))
-		'keyword)
-	(beginning-of-line)
-	;; Extract arguments from keyword's value.
-	(let* ((value (match-string 1))
-	       (ind (org-get-indentation))
-	       (file (and (string-match "^\"\\(\\S-+\\)\"" value)
-			  (prog1 (expand-file-name (match-string 1 value) dir)
-			    (setq value (replace-match "" nil nil value)))))
-	       (lines
-		(and (string-match
-		      ":lines +\"\\(\\(?:[0-9]+\\)?-\\(?:[0-9]+\\)?\\)\"" value)
-		     (prog1 (match-string 1 value)
-		       (setq value (replace-match "" nil nil value)))))
-	       (env (cond ((string-match "\\<example\\>" value) 'example)
-			  ((string-match "\\<src\\(?: +\\(.*\\)\\)?" value)
-			   (match-string 1 value))))
-	       ;; Minimal level of included file defaults to the child
-	       ;; level of the current headline, if any, or one.  It
-	       ;; only applies is the file is meant to be included as
-	       ;; an Org one.
-	       (minlevel
-		(and (not env)
-		     (if (string-match ":minlevel +\\([0-9]+\\)" value)
-			 (prog1 (string-to-number (match-string 1 value))
-			   (setq value (replace-match "" nil nil value)))
-		       (let ((cur (org-current-level)))
-			 (if cur (1+ (org-reduced-level cur)) 1))))))
-	  ;; Remove keyword.
-	  (delete-region (point) (progn (forward-line) (point)))
-	  (cond
-	   ((not file) (error "Invalid syntax in INCLUDE keyword"))
-	   ((not (file-readable-p file)) (error "Cannot include file %s" file))
-	   ;; Check if files has already been parsed.  Look after
-	   ;; inclusion lines too, as different parts of the same file
-	   ;; can be included too.
-	   ((member (list file lines) included)
-	    (error "Recursive file inclusion: %s" file))
-	   (t
+    (while (re-search-forward "^[ \t]*#\\+INCLUDE:" nil t)
+      (let ((element (save-match-data (org-element-at-point))))
+	(when (eq (org-element-type element) 'keyword)
+	  (beginning-of-line)
+	  ;; Extract arguments from keyword's value.
+	  (let* ((value (org-element-property :value element))
+		 (ind (org-get-indentation))
+		 (file (let ((f (if (eq (aref value 0) ?\") (read value)
+				  (and (string-match "^\\S-+" value)
+				       (match-string 0 value)))))
+			 (setq value
+			       (progn
+				 (string-match (format "^\"?%s\"?[ \t]*" f)
+					       value)
+				 (replace-match "" nil nil value)))
+			 (expand-file-name f dir)))
+		 (lines
+		  (and (string-match
+			":lines +\"\\(\\(?:[0-9]+\\)?-\\(?:[0-9]+\\)?\\)\""
+			value)
+		       (prog1 (match-string 1 value)
+			 (setq value (replace-match "" nil nil value)))))
+		 (env (cond ((string-match "\\<example\\>" value) 'example)
+			    ((string-match "\\<src\\(?: +\\(.*\\)\\)?" value)
+			     (match-string 1 value))))
+		 ;; Minimal level of included file defaults to the child
+		 ;; level of the current headline, if any, or one.  It
+		 ;; only applies is the file is meant to be included as
+		 ;; an Org one.
+		 (minlevel
+		  (and (not env)
+		       (if (string-match ":minlevel +\\([0-9]+\\)" value)
+			   (prog1 (string-to-number (match-string 1 value))
+			     (setq value (replace-match "" nil nil value)))
+			 (let ((cur (org-current-level)))
+			   (if cur (1+ (org-reduced-level cur)) 1))))))
+	    ;; Remove keyword.
+	    (delete-region (point) (progn (forward-line) (point)))
 	    (cond
-	     ((eq env 'example)
-	      (insert
-	       (let ((ind-str (make-string ind ? ))
-		     (contents
-		      (org-escape-code-in-string
-		       (org-export--prepare-file-contents file lines))))
-		 (format "%s#+BEGIN_EXAMPLE\n%s%s#+END_EXAMPLE\n"
-			 ind-str contents ind-str))))
-	     ((stringp env)
-	      (insert
-	       (let ((ind-str (make-string ind ? ))
-		     (contents
-		      (org-escape-code-in-string
-		       (org-export--prepare-file-contents file lines))))
-		 (format "%s#+BEGIN_SRC %s\n%s%s#+END_SRC\n"
-			 ind-str env contents ind-str))))
+	     ((not file) nil)
+	     ((not (file-readable-p file))
+	      (error "Cannot include file %s" file))
+	     ;; Check if files has already been parsed.  Look after
+	     ;; inclusion lines too, as different parts of the same file
+	     ;; can be included too.
+	     ((member (list file lines) included)
+	      (error "Recursive file inclusion: %s" file))
 	     (t
-	      (insert
-	       (with-temp-buffer
-		 (let ((org-inhibit-startup t)) (org-mode))
-		 (insert
-		  (org-export--prepare-file-contents file lines ind minlevel))
-		 (org-export-expand-include-keyword
-		  (cons (list file lines) included)
-		  (file-name-directory file))
-		 (buffer-string))))))))))))
+	      (cond
+	       ((eq env 'example)
+		(insert
+		 (let ((ind-str (make-string ind ? ))
+		       (contents
+			(org-escape-code-in-string
+			 (org-export--prepare-file-contents file lines))))
+		   (format "%s#+BEGIN_EXAMPLE\n%s%s#+END_EXAMPLE\n"
+			   ind-str contents ind-str))))
+	       ((stringp env)
+		(insert
+		 (let ((ind-str (make-string ind ? ))
+		       (contents
+			(org-escape-code-in-string
+			 (org-export--prepare-file-contents file lines))))
+		   (format "%s#+BEGIN_SRC %s\n%s%s#+END_SRC\n"
+			   ind-str env contents ind-str))))
+	       (t
+		(insert
+		 (with-temp-buffer
+		   (let ((org-inhibit-startup t)) (org-mode))
+		   (insert
+		    (org-export--prepare-file-contents file lines ind minlevel))
+		   (org-export-expand-include-keyword
+		    (cons (list file lines) included)
+		    (file-name-directory file))
+		   (buffer-string)))))))))))))
 
 (defun org-export--prepare-file-contents (file &optional lines ind minlevel)
   "Prepare the contents of FILE for inclusion and return them as a string.