More Elisp Examples

Xah Lee, 2005-11-01

If you have no idea of elisp, goto: elisp basics.

For basic elisp examples, goto: Basic Elisp Examples.


The following example shows the definition of “fold”. A very useful function in functional programing, but doesn't exist in elisp. For a example fold in Mathematica, see: http://documents.wolfram.com/mathematica/functions/Fold

Also, we use fold to define replace-string-pairs, which does string replacement by a given list of find-replace pairs.

(defun fold (f x li)
"Recursively applies (f x i) where i is the ith element in the list li.
For example, (fold f x '(1 2)) returns (f (f x 1) 2)"
(let ((li2 li) (ele) (x2 x))
  (while (setq ele (pop li2))
    (setq x2 (funcall f x2 ele))
    )
  x2
  )
)

(defun replace-string-pairs (str pairs)
"replace the string str repeatedy by the list pairs.
Example: (replace-string-pairs \"abcdefg\" '( (\"a\" \"1\") (\"b\" \"2\") (\"c\" \"3\")) ) ⇒  123defg" 
(fold (lambda (x y) "" (replace-regexp-in-string (nth 0 y) (nth 1 y) x) ) str pairs)
)

This shows how to call a shell command and process its output.

For a detailed lesson, see: Linkify A Image Path.

(defun get-image-dimensions (img-file-path)
  "Returns a image file's width and height as a list.
This function requires ImageMagick's “identity” shell command."
  (let (cmd-name sh-output width height)
    (setq cmd-name "identify")
    (setq sh-output (shell-command-to-string (concat cmd-name " " img-file-path)) )
; sample output from “identify”:
; some.png PNG 520x429+0+0 DirectClass 8-bit 9.1k 0.0u 0:01
(string-match "^[^ ]+ [^ ]+ \\([0-9]+\\)x\\([0-9]+\\)" sh-output)
(setq width (match-string 1 sh-output))
(setq height (match-string 2 sh-output))
    (list (string-to-number width) (string-to-number height))
))
(defun tag-image ()
  "Replace a image file name with a HTML img tag.
   Example, if cursor is on the word “emacs_logo.png”, then it will became
   “<img src=\"emacs_logo.png\" alt=\"emacs logo\" width=\"123\" height=\"456\">”.
   This function requires the “identify” command from ImageMagick.com."
  (interactive)
  (let 
    (img-file-path bounds img-dim width height altText myResult)
    (setq img-file-path (thing-at-point 'filename))
    (setq bounds (bounds-of-thing-at-point 'filename))
    (setq altText img-file-path)
    (setq altText (replace-regexp-in-string "\\.[A-Za-z]\\{3,4\\}$" "" altText t t))
    (setq altText (replace-regexp-in-string "_" " " altText t t))
    (setq img-dim (get-image-dimensions2 img-file-path))
    (setq width (number-to-string (car img-dim)))
    (setq height (number-to-string (car (last img-dim))))
    (setq myResult (concat "<img src=\"" img-file-path "\""
                           " "
                           "alt=\"" altText "\""
                           " "
                           "width=\"" width "\" "
                           "height=\"" height "\">"))
    (save-excursion
      (delete-region (car bounds) (cdr bounds))
      (insert myResult))
    ))

; In Mac OS X, open current buffer in TextEdit,
; if it is dired, open it in Finder.
(defun open-with-osx ()
  "open the current dir in Finder or TextEdit"
  (interactive)
  (if (eq 'dired-mode major-mode)
    (shell-command "open .")
    (shell-command (concat "open -a /Applications/TextWrangler.app/ " buffer-file-name))))

The following example is the solution to this challenge:

Define a function f, such that (f "simple sexp") returns the argument as a lisp's list. Example: (f "(a (b) c)") returns “(a (b) c)”.

This problem is a simple example of a parser. The program reads a string that represents a tree, and turn this string into a actual tree structure.

The following code is given by Jorgen Schäfer↗, 2006.

(defun parse-string (s)
  (with-temp-buffer
    (insert s)
    (goto-char (point-min))
    (parse)))

(defun parse ()
  (cond
   ((looking-at "\\s-*(\\s-*")
    (goto-char (match-end 0))
    (let ((exprs nil)
          (this nil))
      (while (and (not (looking-at "\\s-*)\\s-*"))
                  (setq this (parse)))
        (setq exprs (cons this exprs)))
      (goto-char (match-end 0))
      (apply 'list (reverse exprs))))
   ((looking-at "\\s-*\\([a-z]+\\)\\s-*")
    (goto-char (match-end 0))
    (intern (match-string 1)))
   (else
    (error "Syntax error"))))

; sample usage
(parse-string "(a (b (h h)) (c d))")

See also:

Page created: 2005-10.
© 2005 by Xah Lee.
Xah Signet