Add simple org-attach support for org-publish with a post-processing function
Table of Contents
Publishing attachments with org-publish
I use org-attach and org-download to attach files and screenshots to my
documents. As far as I know, org-publish doesn’t support this out of the box. I
tried to fix this with a custom :publishing-function
, but this didn’t work
well when files were included using #+INCLUDE:
as we operate on a file-by-file
basis. I also didn’t want to modify the files directly or do a full copy of all
the files before modifying.
My solution was a :completion-function
which walks the published html files,
looks for local file://
links, symlinks the attachments over, and patches the
reference to point to the relative file instead.
The code
(defun simendsjo/org-publish-include-attachments (plist) "Fix published html for org-attach attached files. - Walks all html files - Copies attached files it finds to a local .attach folder - Fixes all src links to point to this new location" (let ((pattern (concat "src=\"file://\\(" (regexp-quote org-attach-id-dir) "\\)/\\([^\"]*\\)")) (pub-dir (plist-get plist :publishing-directory))) (dolist (file (directory-files-recursively pub-dir "\.html$" t)) (let ((buffer (find-file-noselect file))) (with-current-buffer buffer (goto-char (point-min)) (while (re-search-forward pattern nil t) (let* ((attach-part (match-string 1)) (file-part (match-string 2)) (srcfile (f-join attach-part file-part)) (dstfile-rel (f-join ".attach" file-part)) (dstfile (f-join pub-dir dstfile-rel))) ;; Make sure the directory exists as copy/symlink assumes it. (let ((dir (file-name-directory dstfile))) (unless (f-directory-p dir) (message "Attachment directory %s missing, creating it" dir) (make-directory dir t))) ;; Copy/symlink attachment (if IS-WINDOWS (copy-file srcfile dstfile) (make-symbolic-link srcfile dstfile t)) ;; Replace link to relative file ;; I assume the .attach folder is added at the root, and thus add ;; the / at the beginning (replace-match (concat "src=\"/" dstfile-rel "\"")))))))))
In action ATTACH
Screenshot of the document in emacs before attaching something