Emacs: HTML Image Path to Img Tag

By Xah Lee. Date: . Last updated: .

Emacs lisp command that changes a image path into a HTML image link.

Problem

You have this under cursor:

/home/xah/web/cat.jpg

you want it to be this:

<img src="cat.jpg" alt="cat" width="600" height="400" />

Solution

Get Image Dimensions

First, here's the code for getting the image width and height.

(defun xah-get-image-dimensions (@file-path)
  "Returns a vector [width height] of a image's dimension.
The elements are integer datatype.
Support png jpg svg gif and any image type emacs supports.
If it's svg, and dimension cannot be determined, it returns [0 0]

URL `http://ergoemacs.org/emacs/elisp_image_tag.html'
Version 2017-01-11"
  (let (($x nil)
        ($y nil))
    (cond
     ((string-match "\.svg$" @file-path)
      (progn
        (with-temp-buffer
          ;; hackish. grab the first occurrence of width height in file
          (insert-file-contents @file-path)
          (goto-char (point-min))
          (when (search-forward-regexp "width=\"\\([0-9]+\\).*\"" nil "NOERROR")
            (setq $x (match-string 1 )))
          (goto-char (point-min))
          (if (search-forward-regexp "height=\"\\([0-9]+\\).*\"" nil "NOERROR")
              (setq $y (match-string 1 ))))
        (if (and (not (null $x)) (not (null $y)))
            (progn (vector (string-to-number $x) (string-to-number $y)))
          (progn [0 0]))))
     (t
      (let ($xy )
        (progn
          (clear-image-cache t)
          (setq $xy (image-size
                     (create-image
                      (if (file-name-absolute-p @file-path)
                          @file-path
                        (concat default-directory @file-path)))
                     t)))
        (vector (car $xy) (cdr $xy)))))))

If emacs isn't compiled with image support, then we can make a shell call to ImageMagick.

(defun xah-get-image-dimensions-imk (@img-file-path)
  "Returns a image file's width and height as a vector.
This function requires ImageMagick's “identify” shell command.
See also: `xah-get-image-dimensions'.
URL `http://ergoemacs.org/emacs/elisp_image_tag.html'
Version 2015-05-12"
  (let (($width-height
         (split-string
          (shell-command-to-string
           (concat
            "identify -format \"%w %h\" "
            @img-file-path)))))
    (vector
     (string-to-number (elt $width-height 0))
     (string-to-number (elt $width-height 1)))))

This function makes a shell call to the ImageMagick's identify command. [see Linux: ImageMagick Command Line Tutorial]

Image Path to HTML Image Link

Here's the main code.

(defun xah-html-image-linkify ()
  "Replace image file path under cursor to HTML img inline link.
Example:
 img/my_cats.jpg
become
 <img src=\"img/my_cats.jpg\" alt=\"my cats\" />

If `univers-argument' is called before, add width and height attribute, e.g.:

 <img src=\"img/my_cats.jpg\" alt=\"my cats\" width=\"470\" height=\"456\" />

Returns the string used in the alt attribute.

URL `http://ergoemacs.org/emacs/elisp_image_tag.html'
Version 2017-09-04"
  (interactive)
  (let ( $p1 $p2 $imgPath
             $hrefValue $altText $imgWH $width $height)
    (save-excursion
      ;; get image file path begin end pos
      (let ($p0)
        (setq $p0 (point))
        ;; chars that are likely to be delimiters of full path, e.g. space, tabs, brakets.
        (skip-chars-backward "^  \"\t\n'|()[]{}<>〔〕“”〈〉《》【】〖〗«»‹›·。\\`")
        (setq $p1 (point))
        (goto-char $p0)
        (skip-chars-forward "^  \"\t\n'|()[]{}<>〔〕“”〈〉《》【】〖〗«»‹›·。\\'")
        (setq $p2 (point))
        (goto-char $p0)))

    (setq $imgPath
          (if (and (fboundp 'xahsite-web-path-to-filepath)
                   (fboundp 'xah-local-url-to-file-path))
              (xahsite-web-path-to-filepath
               (xah-local-url-to-file-path
                (buffer-substring-no-properties $p1 $p2 )))
            (buffer-substring-no-properties $p1 $p2 )))
    (when (not (file-exists-p $imgPath))
      (user-error "file not exist at %s"  $imgPath))
    (setq $hrefValue
          (file-relative-name
           $imgPath
           (file-name-directory (or (buffer-file-name) default-directory))))
    (setq $altText
          (replace-regexp-in-string
           "-" " "
           (replace-regexp-in-string
            "_" " "
            (replace-regexp-in-string
             "\\.[A-Za-z]\\{3,4\\}$" "" (file-name-nondirectory $imgPath) t t) t t)))

    (if current-prefix-arg
        (progn
          (setq $imgWH (xah-html--get-image-dimensions $imgPath))
          (setq $width (number-to-string (elt $imgWH 0)))
          (setq $height (number-to-string (elt $imgWH 1)))

          (delete-region $p1 $p2)
          (insert
           (if (or (equal $width "0") (equal $height "0"))
               (concat
                "<img src=\""
                $hrefValue
                "\"" " " "alt=\"" $altText "\"" " />")
             (concat
              "<img src=\""
              $hrefValue
              "\"" " " "alt=\"" $altText "\""
              " width=\"" $width "\""
              " height=\"" $height "\" />"))))
      (progn
        (delete-region $p1 $p2)
        (insert
         (concat
          "<img src=\""
          $hrefValue
          "\"" " " "alt=\"" $altText "\"" " />"))))
    $altText
    ))

You can give this command a key such as F5. [see Emacs: How to Define Keys]

Like my tutorial? Put $5 at patreon

Or Buy Xah Emacs Tutorial

Or buy a nice keyboard: Best Keyboard for Emacs

Ask me question on patreon