My last post about sorting lines had a couple of animated gifs to show how the feature worked. They were created using a combination of emacs-director, asciinema, and asciicast2gif. Here's how I made them.

The process

Creating a gif using this setup works like this:

  1. Create an elisp file containing instructions for emacs-director to run.
  2. Run emacs with this file and the emacs-director bootstrap file.
  3. Capture the output with asciinema.
  4. Convert the asciinema file to an animated gif using asciicast2gif.

I created a small Makefile to handle these steps, so all I need to do is write the instruction file and then use make to create the actual gif.

Let's create a really simple gif that says "Hello, World!".

Step 1 - Creating the instruction file

This is divided into two parts: a director-bootstrap command that tells emacs-director some basic information about the environment, and the director-run section that contains a full list of instructions.

For the bootstrap we can either use an existing user directory - useful if things need to be setup a certain way - or use the tmp directory.

The fun part is all contained in director-run, which tells Emacs exactly which steps to follow. Let's say hello!

(director-bootstrap
 :user-dir "/tmp/director-demo")

(director-run
 :version 1
 :before-start (lambda ()
		 (switch-to-buffer (get-buffer-create "*say-hello*"))
		 (menu-bar-mode -1))
 :steps '((:type "Hello, World!"))
 :typing-style 'human
 :delay-between-steps 1
 :after-end (lambda () (kill-emacs 0))
 :on-error  (lambda () (kill-emacs 1)))

The :before-start section can be used to set up buffers, switch the major mode, and run any other code that we don't want to look like it is being typed.

Step 2 - Turning it into a gif

Here's the Makefile I use:

%.gif: %.cast
    asciicast2gif $< $@

%.cast: %.el
    asciinema rec $@ -c 'emacs -nw -Q -l util/director-bootstrap.el -l $<'

Calling make hello-world.gif will convert a file called hello-world.el into a .cast file, which will then be turned into an animated gif.

The finished image looks like this:

Saying hello with emacs

There are a few little gotchas:

  • The finished gif will be based on the size of terminal where make was executed. If you create the gif from a fullscreen terminal you'll end up with a pretty big image.
  • This process uses the terminal version of Emacs, so showing things involving the gui is not possible.
  • When running code in :before-start there will be a frame or two before it is executed which can look a little weird.

None of these detract from the overall package, and it's a really easy way to create animated gifs of Emacs behaviour.

We'll finish with a slightly more complex gif:

Saying hello with emacs lisp

This uses the same director-bootstrap as before, but has a few more steps:

(director-run
 :version 1
 :before-start (lambda ()
		 (menu-bar-mode -1)
		 (switch-to-buffer (get-buffer-create "*say-hello*"))
		 (emacs-lisp-mode))
 :steps '((:type "(defun say-hello ()\r")
	  (:type "\"Say hello to the world.\"\r")
	  (:type "(interactive)\r")
	  (:type "(message \"Hello, World!\"))\r")
	  (:type "\C-x\C-e")
	  (:wait 2)
	  (:type "\M-x")
	  (:type "say-hello")
	  (:type [return]))
 :typing-style 'human
 :delay-between-steps 1
 :after-end (lambda () (sleep-for 5) (kill-emacs 0))
 :on-error  (lambda () (kill-emacs 1)))

Normally to create a gif like this I would type everything by hand and record the screen with licecap or recordMyDesktop, so being able to automate things is a huge time saver.