From 7a69052334416309802c861a7b6b72865c331a37 Mon Sep 17 00:00:00 2001 From: Matt Lundin Date: Wed, 25 Nov 2015 20:23:39 -0600 Subject: [PATCH] Speed up publishing by caching included file data * lisp/ox-publish.el: (org-publish-cache-get-included-files): New function (org-publish-org-to): Use new function (org-publish-cache-file-needs-publishing): Use cache instead of visiting every file in a project. Org-publish can now quickly determine a) whether an org source includes other files and b) whether those files have changed. This speeds up the publishing process and makes tracking of changes in included files more reliable. --- lisp/ox-publish.el | 62 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/lisp/ox-publish.el b/lisp/ox-publish.el index 90f307c..ba85c7e 100644 --- a/lisp/ox-publish.el +++ b/lisp/ox-publish.el @@ -574,6 +574,7 @@ Return output file name." (let ((output-file (org-export-output-file-name extension nil pub-dir)) (body-p (plist-get plist :body-only))) + (when org-publish-cache (org-publish-cache-get-included-files)) (org-export-to-file backend output-file nil nil nil body-p ;; Add `org-publish--collect-references' and @@ -1227,36 +1228,41 @@ the file including them will be republished as well." (unless org-publish-cache (error "`org-publish-cache-file-needs-publishing' called, but no cache present")) - (let* ((case-fold-search t) - (key (org-publish-timestamp-filename filename pub-dir pub-func)) + (let* ((key (org-publish-timestamp-filename filename pub-dir pub-func)) (pstamp (org-publish-cache-get key)) - (org-inhibit-startup t) - (visiting (find-buffer-visiting filename)) - included-files-ctime buf) - (when (equal (file-name-extension filename) "org") - (setq buf (find-file (expand-file-name filename))) - (with-current-buffer buf - (goto-char (point-min)) - (while (re-search-forward "^[ \t]*#\\+INCLUDE:" nil t) - (let* ((element (org-element-at-point)) - (included-file - (and (eq (org-element-type element) 'keyword) - (let ((value (org-element-property :value element))) - (and value - (string-match "^\\(\".+?\"\\|\\S-+\\)" value) - ;; Ignore search suffix. - (car (split-string - (org-remove-double-quotes - (match-string 1 value))))))))) - (when included-file - (push (org-publish-cache-ctime-of-src - (expand-file-name included-file)) - included-files-ctime))))) - (unless visiting (kill-buffer buf))) + (ctime (when pstamp (org-publish-cache-ctime-of-src filename)))) (or (null pstamp) - (let ((ctime (org-publish-cache-ctime-of-src filename))) - (or (< pstamp ctime) - (cl-some (lambda (ct) (< ctime ct)) included-files-ctime)))))) + (< pstamp ctime) + (cl-some (lambda (incl) + ;; See if cached time is before modification time. + (< (cdr incl) + (org-publish-cache-ctime-of-src (car incl)))) + (org-publish-cache-get-file-property filename :includes))))) + +(defun org-publish-cache-get-included-files () + "Get names and last modified times of included files in current buffer." + (let ((case-fold-search t) + included) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "^[ \t]*#\\+INCLUDE:" nil t) + (let* ((element (org-element-at-point)) + (included-file + (and (eq (org-element-type element) 'keyword) + (let ((value (org-element-property :value element))) + (and value + (string-match "^\\(\".+?\"\\|\\S-+\\)" value) + ;; Ignore search suffix. + (car (split-string + (org-remove-double-quotes + (match-string 1 value))))))))) + (when included-file + (let ((iname (expand-file-name included-file))) + (push (cons iname (org-publish-cache-ctime-of-src + (expand-file-name iname))) + included)))))) + (org-publish-cache-set-file-property (buffer-file-name) + :includes included))) (defun org-publish-cache-set-file-property (filename property value &optional project-name) -- 2.6.2