I use some code to export org-mode images embedded as base64, courtesy of I believe originally John Kitchin - from this post here.

However, I should say, I do not yet fully understand all of it! It overwrites org-html--format-image, from ox-html.

Here it is:

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

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

I amended it to include the image file name (source) as a class on the image tag. That way it can be accessed in css by escaping the .. Example: image\.jpg {width:50%;}.

The problem is that org-html export wraps images in figures, and those are difficult to style, since they seem to add IDs that change when the document structure changes, which is all the time.

Keep in mind, the embedded base64 approach above, strips the attributes added to the image tag from the org-html export syntax: example: #+ATTR_HTML: :class img-1 will get stripped in the export.

I've been attempting to use the source of the image as the ID for the figure, instead of I guess the 'info' argument that is passed in as parameter to the following function:

(defun org-html--wrap-image (contents info &optional caption label)
  "Wrap CONTENTS string within an appropriate environment for images.
INFO is a plist used as a communication channel.  When optional
arguments CAPTION and LABEL are given, use them for caption and
\"id\" attribute."
  (let ((html5-fancy (org-html--html5-fancy-p info)))
    (format (if html5-fancy "\n<figure%s>\n%s%s\n</figure>"
          "\n<div%s class=\"figure\">\n%s%s\n</div>")
        ;; ID.
        (if (org-string-nw-p label) (format " id=\"%s\"" label) "")
        ;; Contents.
        (if html5-fancy contents (format "<p>%s</p>" contents))
        ;; Caption.
        (if (not (org-string-nw-p caption)) ""
          (format (if html5-fancy "\n<figcaption>%s</figcaption>"

Essentially, I'd like to pass the 'source' in, in the same way it's passed in org-html--format-image. Then it could be included here:

(format " id=\"%s\"" label)

%s is the placeholder for, I think the info argument?

Any ideas how to achieve this?

  • emacs.stackexchange.com/tags/elisp/info
    – Drew
    Nov 11, 2022 at 22:39
  • defun has an implicit progn.
    – Drew
    Nov 11, 2022 at 22:41
  • The definition of embed-org-html-images looks incomplete. Also I cannot find the code you are describing in the linked page: are you sure the link is correct?
    – NickD
    Nov 11, 2022 at 23:03
  • 1
    You can set org-html-prefer-user-labels to t if you want to use your own labels. Do C-h v org-html-prefer-user-labels for the details.
    – NickD
    Nov 11, 2022 at 23:09
  • Good to know progn is implicit. The approach used in the post (added correct link) strips attributes from <img> in conversion to base64. However, the real challenge is anyway to change the <figure> element that wraps <img> in html export. This post refers to <p> tags, and those are today <figure> tags, but it seems the best approach. To just remove the wrapping <figure> element, if possible. org-html-prefer-user-labels would apply, if the tags weren't getting stripped. Nov 12, 2022 at 17:34


Your Answer

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

Browse other questions tagged or ask your own question.