Emacs Lisp: HTML image-link Command

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 2015-06-13"
  (let ((-x nil)
        (-y nil))
    (cond
     ((string-match "\.svg$" *file-path)
      (progn
        (with-temp-buffer
          ;; hackish. grab the first occurence 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

Final Code

Here's the main code.

(defun xah-html-image-linkify ()
  "Replace image file path under cursor to HTML img inline link.
Example:
 emacs_logo.png
become
 <img src=\"emacs_logo.png\" alt=\"emacs logo\" width=\"123\" height=\"456\" />

URL `http://ergoemacs.org/emacs/elisp_image_tag.html'
Version 2015-12-23"
  (interactive)
  (let ( -p1 -p2 -imgPath -hrefValue -altText -imgWH -width -height)
    (save-excursion
      (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 (buffer-substring-no-properties -p1 -p2 ))
      (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
              "\\.[A-Za-z]\\{3,4\\}$" "" (file-name-nondirectory -imgPath) t t) t t))
      (setq -imgWH (xah-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 "\" />")))))

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

Like it? Buy Xah Emacs Tutorial. Thanks.

or, buy something from Best Keyboard for Emacs