Changes
[emacs.git] / .emacs.d / elisp / org / ox-publish.el
index 1dc790d..d450c0e 100644 (file)
@@ -1,5 +1,5 @@
 ;;; ox-publish.el --- Publish Related Org Mode Files as a Website
-;; Copyright (C) 2006-2014 Free Software Foundation, Inc.
+;; Copyright (C) 2006-2015 Free Software Foundation, Inc.
 
 ;; Author: David O'Toole <dto@gnu.org>
 ;; Maintainer: Carsten Dominik <carsten DOT dominik AT gmail DOT com>
   "This will cache timestamps and titles for files in publishing projects.
 Blocks could hash sha1 values here.")
 
+(defvar org-publish-after-publishing-hook nil
+  "Hook run each time a file is published.
+Every function in this hook will be called with two arguments:
+the name of the original file and the name of the file
+produced.")
+
 (defgroup org-publish nil
   "Options for publishing a set of Org-mode and related files."
   :tag "Org Publishing"
@@ -169,7 +175,9 @@ included.  See the back-end documentation for more information.
   :with-footnotes           `org-export-with-footnotes'
   :with-inlinetasks         `org-export-with-inlinetasks'
   :with-latex               `org-export-with-latex'
+  :with-planning            `org-export-with-planning'
   :with-priority            `org-export-with-priority'
+  :with-properties          `org-export-with-properties'
   :with-smart-quotes        `org-export-with-smart-quotes'
   :with-special-strings     `org-export-with-special-strings'
   :with-statistics-cookies' `org-export-with-statistics-cookies'
@@ -179,7 +187,7 @@ included.  See the back-end documentation for more information.
   :with-tags                `org-export-with-tags'
   :with-tasks               `org-export-with-tasks'
   :with-timestamps          `org-export-with-timestamps'
-  :with-planning            `org-export-with-planning'
+  :with-title               `org-export-with-title'
   :with-todo-keywords       `org-export-with-todo-keywords'
 
 The following properties may be used to control publishing of
@@ -599,11 +607,12 @@ publishing directory.
 Return output file name."
   (unless (file-directory-p pub-dir)
     (make-directory pub-dir t))
-  (or (equal (expand-file-name (file-name-directory filename))
-            (file-name-as-directory (expand-file-name pub-dir)))
-      (copy-file filename
-                (expand-file-name (file-name-nondirectory filename) pub-dir)
-                t)))
+  (let ((output (expand-file-name (file-name-nondirectory filename) pub-dir)))
+    (or (equal (expand-file-name (file-name-directory filename))
+              (file-name-as-directory (expand-file-name pub-dir)))
+       (copy-file filename output t))
+    ;; Return file name.
+    output))
 
 
 \f
@@ -624,8 +633,10 @@ See `org-publish-projects'."
         (project-plist (cdr project))
         (ftname (expand-file-name filename))
         (publishing-function
-         (or (plist-get project-plist :publishing-function)
-             (error "No publishing function chosen")))
+         (let ((fun (plist-get project-plist :publishing-function)))
+           (cond ((null fun) (error "No publishing function chosen"))
+                 ((listp fun) fun)
+                 (t (list fun)))))
         (base-dir
          (file-name-as-directory
           (expand-file-name
@@ -647,19 +658,14 @@ See `org-publish-projects'."
           (concat pub-dir
                   (and (string-match (regexp-quote base-dir) ftname)
                        (substring ftname (match-end 0))))))
-    (if (listp publishing-function)
-       ;; allow chain of publishing functions
-       (mapc (lambda (f)
-               (when (org-publish-needed-p
-                      filename pub-dir f tmp-pub-dir base-dir)
-                 (funcall f project-plist filename tmp-pub-dir)
-                 (org-publish-update-timestamp filename pub-dir f base-dir)))
-             publishing-function)
-      (when (org-publish-needed-p
-            filename pub-dir publishing-function tmp-pub-dir base-dir)
-       (funcall publishing-function project-plist filename tmp-pub-dir)
-       (org-publish-update-timestamp
-        filename pub-dir publishing-function base-dir)))
+    ;; Allow chain of publishing functions.
+    (dolist (f publishing-function)
+      (when (org-publish-needed-p filename pub-dir f tmp-pub-dir base-dir)
+       (let ((output (funcall f project-plist filename tmp-pub-dir)))
+         (org-publish-update-timestamp filename pub-dir f base-dir)
+         (run-hook-with-args 'org-publish-after-publishing-hook
+                             filename
+                             output))))
     (unless no-cache (org-publish-write-cache-file))))
 
 (defun org-publish-projects (projects)
@@ -833,17 +839,15 @@ time in `current-time' format."
           (date (plist-get
                  (with-current-buffer file-buf
                    (if visiting
-                       (org-export-with-buffer-copy (org-export-get-environment))
+                       (org-export-with-buffer-copy
+                        (org-export-get-environment))
                      (org-export-get-environment)))
                  :date)))
       (unless visiting (kill-buffer file-buf))
-      ;; DATE is either a timestamp object or a secondary string.  If it
-      ;; is a timestamp or if the secondary string contains a timestamp,
+      ;; DATE is a secondary string.  If it contains a timestamp,
       ;; convert it to internal format.  Otherwise, use FILE
       ;; modification time.
-      (cond ((eq (org-element-type date) 'timestamp)
-            (org-time-string-to-time (org-element-interpret-data date)))
-           ((let ((ts (and (consp date) (assq 'timestamp date))))
+      (cond ((let ((ts (and (consp date) (assq 'timestamp date))))
               (and ts
                    (let ((value (org-element-interpret-data ts)))
                      (and (org-string-nw-p value)
@@ -870,25 +874,28 @@ When optional argument FORCE is non-nil, force publishing all
 files in PROJECT.  With a non-nil optional argument ASYNC,
 publishing will be done asynchronously, in another process."
   (interactive
-   (list
-    (assoc (org-icompleting-read
-           "Publish project: "
-           org-publish-project-alist nil t)
-          org-publish-project-alist)
-    current-prefix-arg))
-  (let ((project-alist  (if (not (stringp project)) (list project)
-                         ;; If this function is called in batch mode,
-                         ;; project is still a string here.
-                         (list (assoc project org-publish-project-alist)))))
-    (if async
-       (org-export-async-start 'ignore
-         `(let ((org-publish-use-timestamps-flag
-                 (if ',force nil ,org-publish-use-timestamps-flag)))
-            (org-publish-projects ',project-alist)))
-      (save-window-excursion
-       (let* ((org-publish-use-timestamps-flag
-               (if force nil org-publish-use-timestamps-flag)))
-         (org-publish-projects project-alist))))))
+   (list (assoc (org-icompleting-read "Publish project: "
+                                     org-publish-project-alist nil t)
+               org-publish-project-alist)
+        current-prefix-arg))
+  (let ((project (if (not (stringp project)) project
+                  ;; If this function is called in batch mode,
+                  ;; PROJECT is still a string here.
+                  (assoc project org-publish-project-alist))))
+    (cond
+     ((not project))
+     (async
+      (org-export-async-start (lambda (results) nil)
+       `(let ((org-publish-use-timestamps-flag
+               ,(and (not force) org-publish-use-timestamps-flag)))
+          ;; Expand components right now as external process may not
+          ;; be aware of complete `org-publish-project-alist'.
+          (org-publish-projects
+           ',(org-publish-expand-projects (list project))))))
+     (t (save-window-excursion
+         (let ((org-publish-use-timestamps-flag
+                (and (not force) org-publish-use-timestamps-flag)))
+           (org-publish-projects (list project))))))))
 
 ;;;###autoload
 (defun org-publish-all (&optional force async)
@@ -899,7 +906,7 @@ optional argument ASYNC, publishing will be done asynchronously,
 in another process."
   (interactive "P")
   (if async
-      (org-export-async-start 'ignore
+      (org-export-async-start (lambda (results) nil)
        `(progn
           (when ',force (org-publish-remove-all-timestamps))
           (let ((org-publish-use-timestamps-flag
@@ -921,7 +928,7 @@ asynchronously, in another process."
   (interactive "P")
   (let ((file (buffer-file-name (buffer-base-buffer))))
     (if async
-       (org-export-async-start 'ignore
+       (org-export-async-start (lambda (results) nil)
          `(let ((org-publish-use-timestamps-flag
                  (if ',force nil ,org-publish-use-timestamps-flag)))
             (org-publish-file ,file)))
@@ -1164,22 +1171,30 @@ the file including them will be republished as well."
         (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
-               "^#\\+INCLUDE:[ \t]+\"\\([^\t\n\r\"]*\\)\"[ \t]*.*$" nil t)
-         (let* ((included-file (expand-file-name (match-string 1))))
-           (add-to-list 'included-files-ctime
-                        (org-publish-cache-ctime-of-src included-file) t))))
+       (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)
+                             (org-remove-double-quotes
+                              (match-string 1 value)))))))
+           (when included-file
+             (add-to-list 'included-files-ctime
+                          (org-publish-cache-ctime-of-src
+                           (expand-file-name included-file))
+                          t)))))
       (unless visiting (kill-buffer buf)))
     (if (null pstamp) t
       (let ((ctime (org-publish-cache-ctime-of-src filename)))
        (or (< pstamp ctime)
            (when included-files-ctime
-             (not (null (delq nil (mapcar (lambda(ct) (< ctime ct))
+             (not (null (delq nil (mapcar (lambda (ct) (< ctime ct))
                                           included-files-ctime))))))))))
 
 (defun org-publish-cache-set-file-property