# How to write a hook to transform each image reference on export?

This question https://emacs.stackexchange.com/a/27065/13217 explains perfectly how to embed base64 image inside of an HTML exported document, and it works great.

I wonder now how could I automate this process for each image file referenced in my document ?

Adding a pre-export task replacing all file references with the base64 encoded image seems the way to go, but I don't have any practice with elisp. Can anyone help me out ?

I found out some ideas in this documentation : http://orgmode.org/manual/Advanced-configuration.html which seems a good starting point. But I fail to manipulate correctly the input text.

This is what I came out with :

(defun html-base64-images (text backend info)
(when (org-export-derived-backend-p backend 'html)
(message "The text is: %S" text)
(setq filename (replace-regexp-in-string "\\\"$$.*$$+\\\"" "\1" text))
(message "The filename is: %S" filename)
(setq output-text (replace-regexp-in-string "img src=\".*\"" "img src=\"data:image/png;base64," text))
(concat output-text tob64(filename))
(message "The new text is %S" output-text)
output-text
)
)

'html-base64-images)


So in the Messages buffer I can see my messages, but I have problems to manipulate the TEXT string correctly. The output looks like :

The text is: "<img src=\"./GN_moissonnage2.png\" alt=\"GN_moissonnage2.png\" />"
The filename is: "<img src=\"./GN_moissonnage2.png\" alt=\"GN_moissonnage2.png\" />"
The new text is "<img src=\"data:image/png;base64, />"


I need to :

1. get the filename
2. replace it with my base64 URI

I'm not used to elisp at all ... maybe I'm doing it the wrong way ...

• Can you show the output that you get when a link is processed? – NickD Oct 12 '17 at 2:23
• You probably don't want to use replace-regexp-in-string at all: you want to extract the filename somehow (that's why I wanted to see the output: that'll depend on what the text looks like) and you want to construct the output string from scratch, not replace anything in text: the (format ...) in the linked answer is probably close to what you need (with the extracted filename replacing the hardwired name that's used in that answer). – NickD Oct 12 '17 at 2:35

Thanks to @Nick's usefull comments, I managed to get what I wanted.

This function will insert base64 images in my HTML exported org document, making it completely standalone (and quite bigger of course).

(defun tob64 (filename)
"Transforms a file FILENAME in base64."
(base64-encode-string
(with-temp-buffer
(insert-file-contents filename)
(buffer-string))))

(defun html-base64-images (text backend info)
"Replaces files links in TEXT with appropriate html string when BACKEND is html. INFO is ignored."
(when (org-export-derived-backend-p backend 'html)
(when (string-match "^<img" text)
(let ((filename (replace-regexp-in-string ".*=\"" "" (replace-regexp-in-string "\\\" .*" "" text))))
(format  "<img src=\"data:image/png;base64,%s\">" (tob64 filename)))
)
)
)


• One more thing: you should use a (let ((filename ...)) (format ...)) form so that filename is locally bound in the function. See Local Variables in the Emacs Lisp manual. – NickD Oct 12 '17 at 12:24