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:
- Create an elisp file containing instructions for
emacs-directorto run. - Run emacs with this file and the
emacs-directorbootstrap file. - Capture the output with
asciinema. - Convert the
asciinemafile to an animated gif usingasciicast2gif.
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:
There are a few little gotchas:
- The finished gif will be based on the size of terminal where
makewas 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-startthere 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:
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.