Quickly insert hand-drawn figures in a LaTeX document in Emacs

Nov 1, 2021 · 1087 words · 6 minute read

Introduction

Ever since I started doing most of my work on an iPad, one of the things I love is the ability to quickly make nice figures. So when writing notes in a TeX document, I found myself wanting to insert these hand-drawn figures quickly. My ideal setup for taking notes in LaTeX would be: as I am typing and I find the need to have a figure, I quickly draw it on my the iPad and it magically shows up in my LaTeX document immediately. The question is how to achieve this, while being as frictionless as possible.

Here I’d like to share what I came up with. It is far from perfect, but it currently works for me. I’d love to hear if you have any suggestions. There are three components to my setup:

  • Drawing the figures: The “Goodotes” app on iPad
  • Capturing the figure on my laptop: Dropbox, zathura PDF viewer, and xclip
  • Inserting the figure in the TeX document: A bit of elisp in Emacs

Let’s talk about each.

Drawing the figures on the iPad

Even though I primarily use Notabilty on my iPad, I had to use Goodnotes for the simple reason that I need the figures I draw to immediately be available on my laptop. The nice thing about Goodnotes that it can do a realtime sync with Dropbox. All you have to do is enable dropbox syncing. Then, as I draw in Goodnotes in a document called, say, Figure, a PDF appears at ~/Dropbox/Apps/GoodNotes 5/Goodnotes/Figure.pdf. If I make changes to the Figure in Goodnotes, the PDF file gets updated in real-time with a few seconds delay.

Capturing the figure on my laptop

I use zathura pdf viewer on my Arch Linux laptop. One important feature of zathura is that it immediately refreshes an open PDF if the file changes. For us, this means that if I open the Figure.pdf in zathura, I can see almost a live view of what I am drawing in Goodnotes on the iPad.

The only downside is that this is not instantaneous – there is a few seconds delay between me changing the figure on Goodnotes, and the updated figure showing up on zathura. Ideally, I would like to get rid of this delay too.

Inserting the figure in the TeX document in Emacs

Now we just need to get this figure into the our tex document. For this, I have two keystrokes. The first one lets me capture a screenshot into clipboard. I use this on the zathura window and select the region containing the figure.

The second happens in an Emacs TeX buffer. I have my cursor where I’d like the inserted figure to appear in a TeX buffer. I then call a function which copies the image from clipboard into the local project directory and inserts an \includegraphics command with the relevant filename.

Screenshot to Clipboard

The first step is to take a screenshot of a region and copy it to clipboard. I have this bound to Win+PrtSc. So I hit Win+PrtSc and this lets me select a region aroung the figure in my zathura window. Once I select the region, it copies the figure into the clipboard.

First, create a bash script at, say, ~/scripts/screenshot_to_clipboard.sh with the following contents:

#!/bin/bash
import png:- | xclip -selection clipboard -t image/png

The import command is provided by imagemagick which takes a screenshot, and we pipe the output to xclip to copy it to clipboard. Make sure you have imagemagick and xclip installed. On Arch, you can simply do,

$ pacman -S imagemagick xclip

in case you don’t have them already.

I have this script bound to Win+PrtSc. I use Awesome window manager, so my rc.lua config for this keybinding looks like:

globalkeys = awful.util.table.join(
    ...
    -- Take a screenshot 
    awful.key({modkey, }, "Print", function () awful.util.spawn(homedir .. '/scripts/screenshot_to_clipboard.sh') end,
    ...
)
    

Clipboard to TeX

Finally, I have an elisp function called insert-latex-figure in Emacs bound to SPC m i. Let’s say I have a tex file open in Emacs. Once I have captured the figure into clipboard using Win+PrtSc, I hit SPC m i in the emacs buffer to execute the function insert-latex-figure. It does two things:

  • asks for a figure name in the and copies the image into the clipboard into a file img/<figure_name>.png in the current TeX project directory
  • inserts a latex includegraphics snippet pointing to this file

So the figure appears in the TeX document.

(defvar latex/insert-figure-format "\\begin{center}\\includegraphics[width=\\linewidth]{%s}\\end{center}")

(defun latex/insert-image-from-clipboard ()
  (interactive)
  (let* 
    ;; Ask for a filename
    ((image-name (read-string "image-name: "))
    (image-file-location (concat (TeX-master-directory) "img/" image-name ".png")))

    ;; Make the "img" directory if it does not exist
    (make-directory (concat (TeX-master-directory) "img") t)

    ;; Copy the image in clipboard to "img/" directory
    (shell-command (concat "xclip -selection clipboard -t image/png -o > " image-file-location))

    ;; Insert the latex snippet to include the figure
    (insert (format latex/insert-figure-format (concat "img/" (file-name-nondirectory image-file-location) )))))

Conclusions

There you go. This is what I came up to get figures from IPad to a LaTeX document in as few steps as possible. However, there are clearly many shortcomings of this method. One is that there are many moving parts, so many possibilities of things going wrong. So far it has been working for me.

Secondly, and this is a big one, the updates to the PDF are not instantaneous. So I do have to wait for a few seconds after updating the figure on the IPad. This is perhaps the place where I can most easily imagine improving this method.

Finally, taking screenshots means that if I update a figure, I just have to repeat the process. Ideally, I would have a way of automatically updating a given figure. Earlier, I did try another method where I would make a new document for each figure and then have a script to include the figure directly from the goodnotes folder. I think the overhead of making a new document was too much. This is especially true because I moving towards having lots of small hand-drawn figures in my notes. So I don’t want to keep creating a new document every time.

Overall, this is working for me and has allowed me to do what I wanted, which was to allow me quickly insert figures into my LaTeX notes. As I mentioned above, I’d love to hear if you have any suggestions!