2013-04-25

So, now I'm trying to make Org-mode to generate a sitemap of my project files. As per documentation, all I have to do is add a couple properties to the project definition:

:auto-sitemap t
:sitemap-sort-files chronologically

Ordering the files chronologically by the date specified in the file itself (because file modification won't work if I ever update a file) seems to be the right thing™ to do. But guess what?! Nothing ever works!

I first tried inserting the timestamps with C-u C-c ! key, and Org-mode was getting really confused about the self-inserted timestamps. So, after half an hour chasing around the sources and useless backtraces I gave up, and removed the angle brackets from the timestamps. Org-mode seemed less confused.

Now, one problem would not be enough, right? Another problem is that the org-publish-find-date function (used to find out the date of the file) does not care what file it's looking at. And publishing machinery is happily giving it all the files, including static files mentioned in another part of the project definition. And this function is happily visiting those files, with all the emacs mode setup machinery happily wasting my CPU cycles.

OK, less whining, at least I don't have to chase around to fix this problem. Monkeypatched the function to look at the file extension, and do the file processing only if it actually is an .org file. Otherwise just look at the file modification date. Here's the function with the outer if added by me (this is just for testing purposes, OK?):

(defun org-publish-find-date (file)
  "Find the date of FILE in project.
If FILE provides a DATE keyword use it else use the file system's
modification time.  Return time in `current-time' format."
  (if (string-match "\\.org$" file)
      (let* ((org-inhibit-startup t)
             (visiting (find-buffer-visiting file))
             (file-buf (or visiting (find-file-noselect file nil)))
             (date (plist-get
                    (with-current-buffer file-buf
                      (org-mode)
                      (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,
        ;; 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))))
                 (and ts (org-string-nw-p (org-element-interpret-data ts)))))
              ((file-exists-p file) (nth 5 (file-attributes file)))
              (t (error "No such file: \"%s\"" file))))
    (if (file-exists-p file)
        (nth 5 (file-attributes file))
      (error "No such file: \"%s\"" file))))

Force publish project again, and… whatever. Files not sorted chronologically by the specified dates. What did I expect, anyway?

So I give up. And write this article. I think there are better things to do at 01:22 at night than getting frustrated with broken stuff… like sleeping.

<2013-09-15 Sun 11:53>

Guess what, now it works. Gotta love the opensource fairy. Investigation on who did what will have to wait for another time. Just for the record, it works in release_8.1.1-29-gc5f2ae7 (and did not work in 8.0.2, IIRC).

<2013-09-15 Sun 12:09>

Well, scratch that. I now re-organized the org files so that everything that I want to be made public is in a public folder, and then, under that I have blog folder. Because there will be a blog, and then there will be other stuff, like journal and maybe something wiki-like.

Anyway, the thing I wanted to note is that now org-mode generates two sitemap files, one in the public folder, and one in the blog subfolder. The one in public contains links to all files (in the folder itself, and in the blog subfolder, including sitemap). The blog subfolder only contains links to its own files (not including sitemap), and in correct chronological order. But the sitemap file in public does not care about chronological order of entries in blog. Go figure. I think I should just do without the sitemap file…