Jelajahi Sumber

Publishing: Remember how and where a file was published.

This commit implements better support for publishing the same file in
multiple ways.  For example when publishing a Org file both as HTML
and as a plain text or htmlized source file.

It does this by including information about the target directory and
about the publishing function used into the hash that is used as a
file name to keep a time stamp.
Carsten Dominik 16 tahun lalu
induk
melakukan
d27f15e6bb
2 mengubah file dengan 67 tambahan dan 42 penghapusan
  1. 12 0
      lisp/ChangeLog
  2. 55 42
      lisp/org-publish.el

+ 12 - 0
lisp/ChangeLog

@@ -1,3 +1,15 @@
+2009-07-03  Carsten Dominik  <carsten.dominik@gmail.com>
+
+	* org-publish.el (org-publish-timestamp-filename): Additional
+	arguments PUB-DIR and PUB-FUNC, which are included in the hash.
+	(org-publish-needed-p): Additional arguments PUB-DIR PUB-FUNC
+	TRUE-PUB-DIR.  Pass them through to
+	`org-publish-timestamp-filename'.
+	(org-publish-update-timestamp): Additional arguments PUB-DIR and
+	PUB-FUNC, which are included in the hash.
+	(org-publish-file): Delay timestamp test until the publishing
+	function is known.
+
 2009-07-02  Carsten Dominik  <carsten.dominik@gmail.com>
 
 	* org-agenda.el (org-agenda-bulk-action): Add scheduling and

+ 55 - 42
lisp/org-publish.el

@@ -192,13 +192,20 @@ Any changes made by this hook will be saved."
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Timestamp-related functions
 
-(defun org-publish-timestamp-filename (filename)
+(defun org-publish-timestamp-filename (filename &optional pub-dir pub-func)
   "Return path to timestamp file for filename FILENAME."
+  (setq filename (concat filename "::" (or pub-dir "") "::"
+			 (format "%s" (or pub-func ""))))
   (concat (file-name-as-directory org-publish-timestamp-directory)
 	  "X" (if (fboundp 'sha1) (sha1 filename) (md5 filename))))
 
-(defun org-publish-needed-p (filename)
-  "Return `t' if FILENAME should be published."
+(defun org-publish-needed-p (filename &optional pub-dir pub-func true-pub-dir)
+  "Return `t' if FILENAME should be published in PUB-DIR using PUB-FUNC.
+TRUE-PUB-DIR is there the file will truely end up.  Currently we are not using
+this - maybe it can eventually be used to check if the file is present at
+the target location, and how old it is.  Right ow we cannot do this, because
+we do not know under what file name the file will be stored - the publishing
+function can still decide about that independently."
   (let ((rtn
 	 (if org-publish-use-timestamps-flag
 	     (if (file-exists-p org-publish-timestamp-directory)
@@ -208,20 +215,22 @@ Any changes made by this hook will be saved."
 			    org-publish-timestamp-directory)
 		   ;; there is a timestamp, check if FILENAME is newer
 		   (file-newer-than-file-p
-		    filename (org-publish-timestamp-filename filename)))
+		    filename (org-publish-timestamp-filename
+			      filename pub-dir pub-func)))
 	       (make-directory org-publish-timestamp-directory)
 	       t)
 	   ;; don't use timestamps, always return t
 	   t)))
     (if rtn
-	(message "Publishing file %s" filename)
+	(message "Publishing file %s using `%s'" filename pub-func)
       (message   "Skipping unmodified file %s" filename))
     rtn))
 
-(defun org-publish-update-timestamp (filename)
+(defun org-publish-update-timestamp (filename &optional pub-dir pub-func)
   "Update publishing timestamp for file FILENAME.
 If there is no timestamp, create one."
-  (let ((timestamp-file (org-publish-timestamp-filename filename))
+  (let ((timestamp-file (org-publish-timestamp-filename
+			 filename pub-dir pub-func))
 	newly-created-timestamp)
     (if (not (file-exists-p timestamp-file))
 	;; create timestamp file if needed
@@ -452,41 +461,45 @@ See `org-publish-org-to' to the list of arguments."
 
 (defun org-publish-file (filename &optional project)
   "Publish file FILENAME from PROJECT."
-  (when (org-publish-needed-p filename)
-    (let* ((project
-	    (or project
-		(or (org-publish-get-project-from-filename filename)
-		    (if (y-or-n-p
-			 (format "%s is not in a project.  Re-read the list of projects files? "
-				 (abbreviate-file-name filename)))
-			;; If requested, re-initialize the list of projects files
-			(progn (org-publish-initialize-files-alist t)
-			       (or (org-publish-get-project-from-filename filename)
-				   (error "File %s not part of any known project"
-					  (abbreviate-file-name filename))))
-		      (error "Can't publish file outside of a project")))))
-	   (project-plist (cdr project))
-	   (ftname (file-truename filename))
-	   (publishing-function
-	    (or (plist-get project-plist :publishing-function)
-		'org-publish-org-to-html))
-	   (base-dir (file-name-as-directory
-		      (file-truename (plist-get project-plist :base-directory))))
-	   (pub-dir (file-name-as-directory
-		     (file-truename (plist-get project-plist :publishing-directory))))
-	   tmp-pub-dir)
-      (setq tmp-pub-dir
-	    (file-name-directory
-	     (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)
-		  (funcall f project-plist filename tmp-pub-dir))
-		publishing-function)
-	(funcall publishing-function project-plist filename tmp-pub-dir)))
-    (org-publish-update-timestamp filename)))
+  (let* ((project
+	  (or project
+	      (or (org-publish-get-project-from-filename filename)
+		  (if (y-or-n-p
+		       (format "%s is not in a project.  Re-read the list of projects files? "
+			       (abbreviate-file-name filename)))
+		      ;; If requested, re-initialize the list of projects files
+		      (progn (org-publish-initialize-files-alist t)
+			     (or (org-publish-get-project-from-filename filename)
+				 (error "File %s not part of any known project"
+					(abbreviate-file-name filename))))
+		    (error "Can't publish file outside of a project")))))
+	 (project-plist (cdr project))
+	 (ftname (file-truename filename))
+	 (publishing-function
+	  (or (plist-get project-plist :publishing-function)
+	      'org-publish-org-to-html))
+	 (base-dir (file-name-as-directory
+		    (file-truename (plist-get project-plist :base-directory))))
+	 (pub-dir (file-name-as-directory
+		   (file-truename (plist-get project-plist :publishing-directory))))
+	 tmp-pub-dir)
+    (setq tmp-pub-dir
+	  (file-name-directory
+	   (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)
+		  (funcall f project-plist filename tmp-pub-dir)
+		  (org-publish-update-timestamp filename pub-dir f)))
+	      publishing-function)
+      (when (org-publish-needed-p filename pub-dir publishing-function
+				  tmp-pub-dir)
+	(funcall publishing-function project-plist filename tmp-pub-dir)
+	(org-publish-update-timestamp
+	 filename pub-dir publishing-function)))))
 
 (defun org-publish-projects (projects)
   "Publish all files belonging to the PROJECTS alist.