Org Export Hooks
Tags: emacs, orgmode
Published: 2018-03-23 01:43:31

---
title: Org Export Hooks
published: true
tags: [emacs, orgmode]
canonical_url: http://www.gonsie.com/blorg/ox-hook.html
---

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!

## Hooks and Useful Functions

I can think of some functions and/or variables I will need:

- [StackOverflow: org-export-preprocess-final-hook](https://stackoverflow.com/questions/34397046/org-export-hook-does-not-trigger#34397363)
- [Org mode timestamp format](http://www.howtobuildsoftware.com/index.php/how-do/c0Og/datetime-emacs-org-mode-org-mode-timestamp-format-when-exported)
- Interesting functions from `C-h f org-insert-TAB`: 
  - `org-insert-comment`
  - `org-insert-time-stamp`
  - `end-of-buffer` which references `(goto-char (point-max))`

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 `org-set-property` function.

```
(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”.

## StackExchange to the Rescue

[This StackExchange Question](https://emacs.stackexchange.com/questions/21459/programmatically-read-and-set-buffer-wide-org-mode-property) 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 attribute<sup><a id="fnr.1" href="#fn.1">1</a></sup>. 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](https://orgmode.org/worg/doc.html#hooks), it seems like each hook operates on a copy of the current buffer, not what I want.

## Hooking on to Something

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.

# Footnotes

<sup><a id="fn.1" href="#fnr.1">1</a></sup> I found the author, Tobias Zawada, and put the [code on GitHub](https://github.com/gonsie/org-global-prop.el).