Emacs Lisp: Writing a image-linkify Function

Buy Xah Emacs Tutorial. Master emacs benefits for life.
, , …,

A emacs lisp command that changes a image path into a HTML image link.

Problem

Write a emacs command that change this under cursor:

/home/xah/web/ergoemacs_org/emacs/i/lisp_logo_latte_art.jpg

to this:

<img src="i/lisp_logo_latte_art.jpg" alt="lisp logo latte art" width="600" height="800" />

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 image file's width and height as a vector.
Support png jpg svg gif and any image type emacs supports.
Bug: for large size png, sometimes this returns a wrong dimension 30×30.
URL `http://ergoemacs.org/emacs/elisp_image_tag.html'
Version 2015-05-12"
  (let (ξx ξy)
    (cond
     ;; ((string-match "\.gif$" φfile-path) (xah-get-image-dimensions-imk φfile-path))
     ((string-match "\.svg$" φfile-path)
      (with-temp-buffer
        (insert-file-contents φfile-path)
        (goto-char (point-min))
        (search-forward-regexp "width=\"\\([0-9]+\\).*\"")
        (setq ξx (match-string 1 ))
        (goto-char (point-min))
        (search-forward-regexp "height=\"\\([0-9]+\\).*\"")
        (setq ξy (match-string 1 ))
        (vector (string-to-number ξx) (string-to-number ξy))))
     (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)))))))

Emacs lisp can get the image's width & height without making a shell call.

However, it depends on whether your emacs is compiled to support images. On Microsoft Windows, usually not.

Get Image Dimensions Using ImageMagick

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. 〔➤ Linux: ImageMagick Command Line Tutorial

Final Code

Here's the main code.

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

This function requires the 「identify」 command from ImageMagick.
URL `http://ergoemacs.org/emacs/elisp_image_tag.html'
Version 2015-05-15"
  (interactive)
  (let* ((ξbounds (bounds-of-thing-at-point 'filename))
         (ξp1 (car ξbounds))
         (ξp2 (cdr ξbounds))
         (ξimgPath (buffer-substring-no-properties ξp1 ξp2 ))
         (ξhrefValue
          (file-relative-name
           ξimgPath
           (file-name-directory (or (buffer-file-name) default-directory))))
         (ξaltText
          (replace-regexp-in-string
           "_" " "
           (replace-regexp-in-string
            "\\.[A-Za-z]\\{3,4\\}$" "" (file-name-nondirectory ξimgPath) t t) t t))
         (ξimgWH (xah-get-image-dimensions ξimgPath))
         (ξwidth (number-to-string (elt ξimgWH 0)))
         (ξheight (number-to-string (elt ξimgWH 1))))
    (delete-region ξp1 ξp2)
    (insert
     (concat
      "<img src=\""
      ξhrefValue
      "\"" " " "alt=\"" ξaltText "\"" " " "width=\"" ξwidth "\" " "height=\"" ξheight "\" />"))))

Now, assign this function a key such as F5. 〔➤ Emacs: How to Define Keys

then, insert a image path in buffer:

emacs_logo.png

press F5, then get:

<img src="emacs_logo.png" alt="emacs logo" width="65" height="82">

Emacs ♥

Note: emacs's html-mode provides the command html-imageCtrl+c Ctrl+c i】. But it doesn't let you nagivate the path, and doesn't add width and height attributes.

Like it?
Buy Xah Emacs Tutorial
or share
blog comments powered by Disqus