I often find myself wanting to save local copies of sites such as:


I need to store a local copy of it (to read in my favourite editor). One solution of course is to use eww, but I would like to be able to port it through to Orgmode syntax so I can annotate it. I tried Pandoc, but couldn't seem to get the right filters. I end up with either no whitespace; or hundreds of html src blocks.

Any solutions would be appreciate. Inline images are a must (or at least saved).


You could use eww and copy the region of interest into an Orgmode file. (Option: If you have org-eww you could use its specialized copy.)

Then mark the copy and call the following function org-inline-images-to-images-in-region. It stores copies of the inline-images as attachments and places links to them in the Org file.

+begin_src emacs-lisp

(require 'org)
(require 'org-attach)

(defun next-property-display-data (start limit)
  (let ((pos (next-property-change start nil limit)))
        (and (< pos limit)
             (let ((display-prop (plist-get (text-properties-at pos) 'display)))
               (or (not display-prop)
                   (not (plist-get (cdr display-prop) :data)))))
      (setq pos (next-property-change pos nil limit)))

(defun org-attach-inline-image-with-hashed-name (text-properties)
  (let ((display-data (cdr (plist-get text-properties 'display))))
    (when display-data
      (let* ((data (plist-get display-data :data)))
        (when data
          (let* ((basename (sha1 data))
                 (org-attach-filename (concat (org-attach-dir t) "/" basename)))
            (unless (file-exists-p org-attach-filename)
              (with-temp-file org-attach-filename
                (setq buffer-file-coding-system 'binary)
                (set-buffer-multibyte nil)
                (insert data)))

(defun org-inline-images-to-images-in-region (beg end)
  "Save the data of inline-images as attachment and insert a link to the attachment."
  (interactive "r")
  ;; I guess this should be refined.  todo: check out the
  ;; text-properties world!
    (goto-char beg)
    (when (and (plist-get (text-properties-at (point)) 'display)
           (plist-get (cdr (plist-get (text-properties-at (point)) 'display)) 'data))
      (let ((name (org-attach-inline-image-with-hashed-name
                   (text-properties-at (point)))))
        (goto-char (next-property-change (point) nil end))
        (insert "[[" name "]]" )))
    (let ((pos (next-property-display-data (point) end)))
      (while (< pos end)
        (goto-char pos)
        (let ((name (org-attach-inline-image-with-hashed-name
                     (text-properties-at (point)))))
          (goto-char (next-property-change (point) nil end))
          (insert "[[" name "]]" ))
        (setq pos (next-property-display-data (point) end))))))


Note that the stored images get their sha1-hashes as filenames.

To have Emacs recognize the images with the sha1-hash-names insert regexp "[1234567890abcdef]{40}" into config variable image-file-name-regexps. (E.g. via M-x customize-apropos image-file-name-regexps)

  • Meanwhile there is org-attach-embedded-images.el in the contrib directory of Org which is more or less the answer above.
    – Marco Wahl
    Jan 2 '20 at 17:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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