Commit 143bc9a3 authored by Pierre Neidhardt's avatar Pierre Neidhardt

publish.el: Use git creation and last update dates

parent dc5983e3
;; Inspiration:
;; TODO: Load this file as .dir-locals for .org files so that we can org-publish from there?
;; TODO: Use Git time-stamps.
(require 'ox-publish)
(require 'seq)
......@@ -9,6 +8,9 @@
(add-to-list 'load-path ".")
(require 'feed-builder)
(defvar ambrevar/repository "")
(defvar ambrevar/root (expand-file-name "."))
;; Timestamps can be used to avoid rebuilding everything.
;; This is useful locally for testing.
;; It won't work on Gitlab when stored in ./: the timestamps file should
......@@ -27,17 +29,68 @@
org-export-with-tags 'not-in-toc
org-export-with-toc t)
(defun ambrevar/git-creation-date (file)
"Return the first commit date of FILE.
Format is %Y-%m-%d."
(call-process "git" nil t nil "log" "--reverse" "--date=short" "--pretty=format:%cd" file)
(goto-char (point-min))
(buffer-substring-no-properties (line-beginning-position) (line-end-position))))
(defun ambrevar/git-last-update-date (file)
"Return the last commit date of FILE.
Format is %Y-%m-%d."
(with-current-buffer standard-output
(call-process "git" nil t nil "log" "-1" "--date=short" "--pretty=format:%cd" file))))
(defun ambrevar/org-html-format-spec (info)
"Return format specification for preamble and postamble.
INFO is a plist used as a communication channel.
Just like `org-html-format-spec' but uses git to return creation and last update
The extra `u` specifier displays the creation date along with the last update
date only if they differ."
(let* ((timestamp-format (plist-get info :html-metadata-timestamp-format))
(file (plist-get info :input-file))
(meta-date (org-export-data (org-export-get-date info timestamp-format)
(creation-date (if (string= "" meta-date)
(ambrevar/git-creation-date file)
(last-update-date (ambrevar/git-last-update-date file)))
`((?t . ,(org-export-data (plist-get info :title) info))
(?s . ,(org-export-data (plist-get info :subtitle) info))
(?d . ,creation-date)
(?T . ,(format-time-string timestamp-format))
(?a . ,(org-export-data (plist-get info :author) info))
(?e . ,(mapconcat
(lambda (e) (format "<a href=\"mailto:%s\">%s</a>" e e))
(split-string (plist-get info :email) ",+ *")
", "))
(?c . ,(plist-get info :creator))
(?C . ,last-update-date)
(?v . ,(or (plist-get info :html-validation-link) ""))
(?u . ,(if (string= creation-date last-update-date)
(format "%s (<a href=%s>Last update: %s</a>)"
(format "%s/commits/master/%s" ambrevar/repository (file-relative-name file ambrevar/root))
(advice-add 'org-html-format-spec :override 'ambrevar/org-html-format-spec)
(setq ;; org-html-divs '((preamble "header" "top")
;; (content "main" "content")
;; (postamble "footer" "postamble"))
org-html-postamble t
;; TODO: Link last update to commit history of file.
org-html-postamble-format '(("en" "<p class=\"comments\"><a href=\"\">Comments</a></p>
<p class=\"date\">Date: %d (Last update: %C)</p>
org-html-postamble-format `(("en" ,(concat "<p class=\"comments\"><a href=\""
ambrevar/repository "/issues\">Comments</a></p>
<p class=\"date\">Date: %u</p>
<p class=\"creator\">Made with %c</p>
<p class=\"license\">
<a rel=\"license\" href=\"\"><img alt=\"Creative Commons License\" style=\"border-width:0\" src=\"\" /></a>
;; TODO: Use relative links.
org-html-preamble-format '(("en" "<a href=\"\">About</a>
<a href=\"\">Articles</a>
......@@ -75,15 +128,20 @@ See `org-publish-sitemap-default'. "
(org-list-to-org list)))
;; TODO: Sitemap should contain last update date.
(defun org-publish-sitemap-ambrevar-entry (entry style project)
"Custom format for site map ENTRY, as a string.
See `org-publish-sitemap-default-entry'."
(cond ((not (directory-name-p entry))
(format "[[file:%s][%s]]^{ (%s)}"
(org-publish-find-title entry project)
(format-time-string "%Y-%m-%d" (org-publish-find-date entry project))))
(let ((creation-date (format-time-string "%Y-%m-%d" (org-publish-find-date entry project)))
(last-date (ambrevar/git-last-update-date
(expand-file-name entry
(org-publish-property :base-directory project)))))
(format "[[file:%s][%s]]^{ (%s)}"
(org-publish-find-title entry project)
(if (string= creation-date last-date)
(format "%s, updated %s" creation-date last-date)))))
((eq style 'tree)
;; Return only last subdir.
(capitalize (file-name-nondirectory (directory-file-name entry))))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment