Emacs: Move Image File 🚀

By Xah Lee. Date: . Last updated: .

Here's a emacs command that moves image file from download directory to your blog directory and create a html image link to it.

You can customize which directories to search, and a list of regex to match the file you want to move.

This command is useful if you write a blog and often want to include screenshots or photos you have taken, or images from internet.

(defvar xah-html-move-image-file-from-dirs nil "A list of dir paths used by `xah-html-move-image-file' to search for image files to move from. Each should be full path, and end in a slash.")
(setq xah-html-move-image-file-from-dirs
      '(
        "~/Downloads/"
        "~/Videos/Captures/"
        "~/Pictures/Screenshots/"
        "~/Pictures/"
        "~/Desktop/"
        "~/"
        "/tmp/"
        ))

(defvar xah-html-move-image-file-regex-list nil "A list of regex strings used by `xah-html-move-image-file' to search for temp image files.")
(setq
 xah-html-move-image-file-regex-list
 '(
   "^tt"
   "^ee"
   "unknown\\.jpg"
   "unknown\\.png"
   "image\\.png"
   "^[A-Za-z0-9]\\{15\\}\\.\\(png\\|jpg\\)$"

   "^IMG.+?\\.\\(png\\|jpg\\)$"
   "^IMG_.+?\\.\\(png\\|jpg\\)$"
   "^DSC_.+?\\.\\(png\\|jpg\\)$"
   "^capture.*?\\.\\(png\\|jpg\\)$"
   "^Screen Shot.+?\\.\\(png\\|jpg\\)$"
   "^Screenshot.+?\\.\\(png\\|jpg\\)$"
   "^screenshot.+?\\.\\(png\\|jpg\\)$"

   " PM\\.\\(png\\|jpg\\)$"
   " AM\\.\\(png\\|jpg\\)$"
   ;; amazon pic
   ;; 718XHsTfXcL.__AC_SX300_SY300_QL70_FMwebp_.webp
   ;; 61-UjxyNjgL._AC_SL1500_.jpg
   ;; 81IVDfmw4KL._AC_SL1500_.jpg
   "[-+0-9A-Za-z]\\{11\\}\._+[A-Z]\\{2\\}.+\.\\(jpg\\|webp\\)"
   ;; "[+0-9A-Za-z]\\{11\\}\._+[A-Z]\\{2\\}_[A-Z].+\.\\(jpg\\|webp\\)"
   ))

(defun xah-html-move-image-file (ToDirName)
  "Move image file to another dir.

Search a list of dirs by a list of regex. If a match is found, move it into a new file path, by prompting user to type it.

The from dirs is defined in `xah-html-move-image-file-from-dirs'
The regex list is defined in `xah-html-move-image-file-regex-list'

A random string attached (as id) is added to file name, and any uppercase file extension name is lowercased, e.g. .JPG becomes .jpg. Space in filename is replaced by the lowline char _.

Automatically call `xah-dired-remove-all-metadata' and `xah-dired-optimize-png' afterwards.

URL `http://xahlee.info/emacs/emacs/move_image_file.html'
Version: 2019-01-11 2022-05-20 2022-06-15 2023-01-26"
  (interactive (list (expand-file-name (read-directory-name "Move img to dir:") )))
  (let* (($m0 (make-marker))
         ($dirs xah-html-move-image-file-from-dirs)
         ($regexes xah-html-move-image-file-regex-list)
         $fromPath $ext $newName $toPath)
    (set-marker $m0 (point))
    (setq $fromPath
          (catch 'found57804
            (dolist (xdir $dirs)
              (when (file-exists-p xdir)
                (let (($dirFiles (directory-files xdir t (mapconcat 'identity $regexes "\\|"))))
                  (when $dirFiles (throw 'found57804 (car $dirFiles))))))))
    (when (not $fromPath) (error "%s: No file name matched regexes `xah-html-move-image-file-regex-list' at dirs `xah-html-move-image-file-from-dirs'" real-this-command))
    (setq $ext
          (let (($x (file-name-extension $fromPath)))
            (if $x
                (if (seq-some (lambda ($y) (string-equal $y $x)) '("jpg-large" "jpg_large" "jpg_medium" "jpeg" "jfif"))
                    "jpg"
                  (downcase $x))
              "")))
    (setq $newName
          (let (($x (list (file-name-nondirectory (file-name-sans-extension $fromPath))))
                ($randStr
                 (let* (($charset "bcdfghjkmnpqrstvwxyz23456789BCDFGHJKMNPQRSTVWXYZ")
                        ($len (length $charset))
                        ($randlist nil))
                   (dotimes (_ 5)
                     (push (char-to-string (elt $charset (random $len))) $randlist))
                   (mapconcat 'identity $randlist ""))))
            (push (replace-regexp-in-string "^tt[0-9]*" "" (car $x)) $x)
            (push (replace-regexp-in-string "Screen Shot" "screenshot" (car $x)) $x)
            ;; Screen Shot 2018-07-25 at 2.46.36 AM.png
            (push (read-string "new name:" (car $x) nil (car $x)) $x)
            (push (replace-regexp-in-string ",\\| \\|\\+\\|(\\|)" "_" (car $x)) $x)
            (push (concat (car $x) "_" $randStr) $x)
            (car $x)))
    (setq $toPath (concat (file-name-as-directory ToDirName) $newName "." $ext))
    (message "xah-html-move-image-file: from path is 「%s」\n to path is 「%s」 " $fromPath $toPath)
    (if (file-exists-p $toPath)
        (error "Target path exist: %s" $toPath)
      (progn
        (rename-file $fromPath $toPath)
        (when (string-equal major-mode "dired-mode")
          (revert-buffer))
        (if (string-equal major-mode "xah-html-mode")
            (progn
              (kill-new $toPath)
              (goto-char $m0)
              (insert "\n\n"  $toPath "\n\n")
              (backward-word)
              (xah-html-any-to-link))
          (progn
            (goto-char $m0)
            (insert "\n\n" $toPath "\n\n")))
        (when (fboundp 'xah-dired-remove-all-metadata)
          (xah-dired-remove-all-metadata (list $toPath) t))
        (when (and (string-equal $ext "png") (fboundp 'xah-dired-optimize-png))
          (xah-dired-optimize-png (list $toPath)))))))

you probably also want to install Emacs: xah-dired.el