In my quest for a simplified, org-based publishing scheme, I would like to add some information to a file when I export it. Namely, I would like to add some metadata within the file, something like:
#+property: exported: 2018-01-30
Let’s see if I can prototype this functionality through Org-mode!
I can think of some functions and/or variables I will need:
- StackOverflow: org-export-preprocess-final-hook
- Org mode timestamp format
- Interesting functions from
C-h f org-insert-TAB:
Let’s put them together into an elisp snippet.
(add-hook 'org-export-preprocess-final-hook (save-excursion (goto-char (point-max)) (insert "\n#+property: exported: ") (org-insert-time-stamp (current-time)) (insert "\n")))
I think that does the thing that I want. Ideally the property would go near (but not at) the top of my document, but that seems overly hard for the moment. Notice that executing the block puts the
#+property at the end of the document. That is the behavior we want, BUT it should not be happening when executing the block rather it should happen on export. Also, this function will keep inserting more text, rather than update an existing property.
That seems like a rather hacky way to set properties. There must be something included with org. Let’s try the
(save-excursion (goto-char (point-min)) (org-set-property "exported:" (format-time-string (car org-time-stamp-formats) (current-time))))
Gross. Without going to the beginning of the file, it just adds a property drawer to the current subtree. Going to the beginning of the file just inserts the timestamp with the error: “Before first headline in position 1”.
This StackExchange Question leads me in the direction of the powerful
org-element-parse-buffer. Actually, there is one solution which includes a rather elegant set of
org-global-prop functions that I want to properly package up and attribute1. Let’s try them out:
(org-global-prop-set "exported:" (format-time-string (car org-time-stamp-formats) (current-time)))
That function works! What about as a hook?
(add-hook 'org-export-before-parsing-hook '(org-global-prop-set "exported:" (format-time-string (car org-time-stamp-formats) (current-time))))
Ugh, hooks are dead. Reading through the official org documenatation, it seems like each hook operates on a copy of the current buffer, not what I want.
That’s fine, I can hack in another way. Let’s just rebind the keys that do the exporting to a new function which will do the export property update.
;; add exported: property with date to org files when exporting (defun my/org-export-dispatch () "updateds the exported: property before opening the dispatch" (org-global-prop-set "exported:" (format-time-string (car org-time-stamp-formats) (current-time))) (org-export-dispatch)) (add-hook 'org '(local-set-key (kbd "C-c C-e") 'my/org-export-dispatch))
Not perfect (the spaces/newlines after the property are globbed) but good enough for now. Someday I’ll have to work on integrating this functionality into the publishing process (rather than this hack), but hey, it works.