Org-Mode Export of Scheme-less Absolute Path Links

I sometimes turn Org format notes into blog posts (as in the case of this one), and when doing so it's good to be mindful of how Org links get translated on export. In some cases we want the output link to have the absolute path of the resource (for the site, not the file system), but no URL scheme or authority part.

Emacs Org mode (as of version 9) interprets scheme-less links with an absolute path as file: links of the same path. That is, if we HTML export the link [[/deft/]] we end up with

<a href="file:///deft/">file:///deft/</a>

Should we instead want our link with a “bare”, scheme-less path, i.e., should we want our <a> element to be emitted as

<a href="/deft/">/deft/</a>

then one solution is to use a custom Org link type.

For example, we can write our link as [[bare:/deft/]] and then define that link type as follows:

(org-link-set-parameters "bare"
 :follow 'my-org-follow-bare-link
 :export 'my-org-export-bare-link)

(defvar my-org-follow-bare-link-base-url nil
  "Base URL to be used by `my-org-follow-bare-link'.
If nil, \"bare:\" links cannot be followed.")

(defun my-org-follow-bare-link (path)
  "Follow a \"bare:\" link, or not.
Link PATH is the sole argument."
  (if my-org-follow-bare-link-base-url
      (browse-url (concat my-org-follow-bare-link-base-url path))
    (message "Cannot follow \"bare:\" link: %s" path)))

(defun my-org-export-bare-link (path description backend)
  "Export a \"bare:\" link.
Link PATH, DESCRIPTION, and export BACKEND are expected as
arguments. Only HTML export is supported. Parent paragraph export
attributes are not supported \(see `org-export-read-attribute')."
   ((eq backend 'html)
    (let ((path (org-link-unescape path)))
      (format "<a href=\"%s\">%s</a>"
              (url-encode-url path)
               (or description path)))))))

I don't know all the details of escaping and encoding of Org links, URLs, HTML attribute values and element content, and thus wouldn't rely on the above implementation of my-org-export-bare-link getting exotic inputs translated correctly.