11

The goal is to make a self-contained html file when exporting from orgmode so that the images are intrinsic to the file and a single html file will can be distributed (I am trying to do this for a class I teach and want to give students a single html they can open in a browser).

I found a snippet of code on line that gives the idea of what I want:

#+BEGIN_SRC python :results output html :exports results
with open('/home/britt/Pictures/Britt0001.jpg', 'rb') as image:
    data = image.read()
    print '<img src="data:image/jpg;base64,%s">' % data.encode("base64")
#+END_SRC

And I am trying to get it into elisp and thus remove the dependancy on python and as a step to creating my own elisp function that could have some more detail.

Here is what I have gotten to. Advice appreciated.

#+BEGIN_src elisp :results output html :exports results
    (setq myim (concat "<img src=\\"data:image/jpg;base64," (tob64 "/home/britt/Pictures/Britt0001.jpg") ">"))
     (print myim)
#+END_SRC

and where tob64 is

(defun tob64 (filename)
  (base64-encode-string
   (with-temp-buffer
     (insert-file-contents filename)
     (buffer-string))))

This doesn't give the correct formatting and quoting.

The goal to be worked toward is some variant of org-html-export-to-html where the elisp function could live and be invoked when an option like #+OPTIONS: embed-images-on-html-export:t was invoked.

And as an aside, why doesn't the functionality of exporting to html with embedded images already exist in org-mode? Is there some bigger issue that makes this problematic for me to be working towards?

3 Answers 3

5

See http://kitchingroup.cheme.cmu.edu/blog/2015/05/09/Another-approach-to-embedding-org-source-in-html/.

You may also find this: https://github.com/KitchinHUB/kitchingroup-66/blob/master/manuscript.org#the-custom-export-code-labelexport-code an interesting way to encode base64 data in html.

Your code works for me:

#+BEGIN_SRC emacs-lisp :results html :exports both
(defun tob64 (filename)
  (base64-encode-string
   (with-temp-buffer
     (insert-file-contents filename)
     (buffer-string))))

(format "<img src=\"data:image/png;base64,%s\">"
    (tob64 "/Users/jkitchin/t.png"))
#+END_SRC

outputs a base64 encoded image I can see in the export.

To get this to work automatically in export, you probably want to use a function in org-export-before-processing-hook that will go through and replace your file links with an html block containing the output of a function like the one above.

2
  • Thanks for taking the time. The problem for me was that I kept trying to print or insert. Will now read up on format. Hard to know what to look for when you don't know the names of things. Will explore your advice on using the hook. Doesn't this sound like something worth having though? Sep 14, 2016 at 17:14
  • It would be nice way to create a standalone html file that could be emailed or simply transferred. Sep 14, 2016 at 18:15
4

As an alternative, you can use the ox-pandoc package. Pandoc itself has a command line option called --self-contained which will embed images in html.

To you use this for just the pandoc HTML5 exporter, by putting this in your .emacs:

(setq org-pandoc-options-for-html5 '((standalone . t) (self-contained . t)))

Also, you could have it for html4 instead/as well:

(setq org-pandoc-options-for-html5 '((standalone . t) (self-contained . t)))

Or to use --self-contained for all pandoc:

(setq org-pandoc-options '((standalone . t) (self-contained . t)))

Note that the (standalone . t) part is optional, I include only because this then replicates the defaults that pandoc has. You could remove it if you like, or replace it with your own set of options.

Finally, you can do the same thing for a single file by using the header:

#+PANDOC_OPTIONS: self-contained:t

1
  • I just add #+PANDOC_OPTIONS: self-contained:t to the top of my file, then use Pandoc to export to HTML. It works with emacs/Doom
    – Yu Shen
    Jul 6, 2020 at 4:44
3

From the reddit thread https://www.reddit.com/r/orgmode/comments/7dyywu/creating_a_selfcontained_html/

(defun replace-in-string (what with in)
  (replace-regexp-in-string (regexp-quote what) with in nil 'literal))

(defun org-html--format-image (source attributes info)
  (progn
    (setq source (replace-in-string "%20" " " source))
    (format "<img src=\"data:image/%s;base64,%s\"%s />"
            (or (file-name-extension source) "")
            (base64-encode-string
             (with-temp-buffer
               (insert-file-contents-literally source)
              (buffer-string)))
            (file-name-nondirectory source))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.