Month: January 2016

Speed up pdf export from org-mode with latexmk

These days I write almost everything (e.g. research papers, lecture notes and slides) in org-mode, and then export to pdf (see my posts on org-mode here). This is a really pleasant and efficient way to create documents, but when working on a long document, it can take several seconds for emacs to compile the exported latex to pdf. During that time, emacs is hung up waiting for the compilation to finish, which is annoying.

I thought I’d share my workflow for streamlining this process. The key ingredient is not part of emacs. I use latexmk which is a perl script that watches a latex file and compiles it if it changes (or any file that it depends on changes). It will repeat the compilation (including calling bibtex) as many times as needed to resolve all references.

So, if I am working on a file, say document.org, I will run latexmk on the corresponding tex file using

latexmk -pvc -pdf -view=none document.tex

Here, the -pcv option means to keep watching the file for changes and recompile as needed; the -pdf option means build a pdf from the latex using pdflatex, and -view=none tells latexmk not to open a pdf viewer to show the resulting pdf.

I then open the resulting document.pdf in skim, an excellent pdf viewer for the Mac (unfortunately hosted on sourceforge). The killer feature of skim compared to the built-in OS X preview app, is that it will automatically redisplay a pdf if the file changes (I believe evince or okular on linux do the same).

Putting the pieces together, I have latexmk running in a terminal, and an emacs window and skim window side by side. I then export my org file to latex with e.g. C-c C-e l l which happens almost instantly and gives me control back of emacs. The latex is compiled in the background by latexmk and then a few seconds later the pdf updates in skim and I can see my changes.

Advertisement

Aligning text

Emacs has a flexible tool, align-regexp, for aligning text but it is surprisingly fiddly to use. For example to align a section of text like this:

the quick brown fox
jumped over the lazy
dogs the quick brown

into columns like this:

the     quick  brown  fox
jumped  over   the    lazy
dogs    the    quick  brown

you would highlight the text and use C-u M-x align-regexp \(\s-*\)\s- RET 1 RET 0 RET y. See what I mean!

The function is of course documented (use C-h f align-regexp to read it), but I found it a bit hard to follow. The \(\s-*\)\s- string is the regular expression that is used to align on, and the final \s- in that string tells emacs to align on a whitespace character. You could replace that with e.g. & to align on & characters. The other three options (i) control how the columns are justified (generally can leave this as 1); (ii) add spaces between columns; and (iii) repeat the alignment throughout the line.

To make life easier, I wrote a couple of simple wrappers around align-regexp for common tasks. The first aligns on whitespace, and the second aligns on & (useful for LaTeX tables).

(defun bjm/align-whitespace (start end)
  "Align columns by whitespace"
  (interactive "r")
  (align-regexp start end
                "\\(\\s-*\\)\\s-" 1 0 t))

(defun bjm/align-& (start end)
  "Align columns by ampersand"
  (interactive "r")
  (align-regexp start end
                "\\(\\s-*\\)&" 1 1 t))

Email templates in mu4e with yasnippet

This is the second in a series of posts on using mu4e for email in emacs. When I moved from thunderbird to mu4e, there were some thunderbird extensions that I missed. One was quicktext which I used to create simple email templates for common sorts of emails. This is easily replicated in emacs using yasnippet.

As a simple example, I made a snippet to expand the key all into

Hi all,

Cheers,

Ben

The snippet is

# -*- mode: snippet -*-
# name: hi all
# key: all
# --
Hi all,

$0

Cheers,
 Ben

This snippet is saved in the message-mode subdirectory of my snippets directory, since message-mode is the major mode for email composition in mu4e.

We can be a bit smarter than this with a snippet that takes the name of the email recipient and adds that to the template. The following is close to binchen’s instructions with a few small modifications. There are two parts to this: a snippet that expands out as normal, and a lisp function that it calls when it expands to extract the recipient’s name.

First, the lisp function

;; function to return first name of email recipients
;; used by yasnippet
;; inspired by
;;http://blog.binchen.org/posts/how-to-use-yasnippets-to-produce-email-templates-in-emacs.html
(defun bjm/mu4e-get-names-for-yasnippet ()
  "Return comma separated string of names for an email"
  (interactive)
  (let ((email-name "") str email-string email-list email-name2 tmpname)
    (save-excursion
      (goto-char (point-min))
      ;; first line in email could be some hidden line containing NO to field
      (setq str (buffer-substring-no-properties (point-min) (point-max))))
    ;; take name from TO field - match series of names
    (when (string-match "^To: \"?\\(.+\\)" str)
      (setq email-string (match-string 1 str)))
    ;;split to list by comma
    (setq email-list (split-string email-string " *, *"))
    ;;loop over emails
    (dolist (tmpstr email-list)
      ;;get first word of email string
      (setq tmpname (car (split-string tmpstr " ")))
      ;;remove whitespace or ""
      (setq tmpname (replace-regexp-in-string "[ \"]" "" tmpname))
      ;;join to string
      (setq email-name
            (concat email-name ", " tmpname)))
    ;;remove initial comma
    (setq email-name (replace-regexp-in-string "^, " "" email-name))

    ;;see if we want to use the name in the FROM field
    ;;get name in FROM field if available, but only if there is only
    ;;one name in TO field
    (if (< (length email-list) 2)
        (when (string-match "^\\([^ ,\n]+\\).+writes:$" str)
          (progn (setq email-name2 (match-string 1 str))
                 ;;prefer name in FROM field if TO field has "@"
                 (when (string-match "@" email-name)
                   (setq email-name email-name2))
                 )))
    email-name))

This function takes the first name of the email recipient from the “To:” field of the message. It also looks for a name in the “Joe Bloggs writes:” text that mu4e generates when you reply to an email. This is populated from the “From:” field of the email being replied to and sometimes gives a better match for the name. The function compares the two name strings and prefers the “To:” name unless it contains an “@” in which case it chooses the “From:” name (this is the addition I made to binchen‘s version). You could make this more sophisticated but it works pretty well for me as is.

Now we need a snippet to expand:

# -*- mode: snippet -*-
# name: dear name
# key: dear
# --
Dear ${1:`(bjm/mu4e-get-names-for-yasnippet)`},

$0

Best wishes,
 Ben

Note how our function is straightforwardly called by the snippet to give “Dear NAME”.

Hopefully this gives you some ideas of how to make useful email templates with yasnippet. In future posts I’ll talk about how I have added attachment reminders and delayed sending features to mu4e.

Update 11/3/2016

I updated the code to give a comma separated list of names in the case of more than one recipient.

Open recent directories in dired

I find myself doing more and more of my file system tasks in emacs with dired. The package dired+ adds some extra features to dired, one of which I discovered today.

The command diredp-dired-recent-dirs, bound to C-x R by default, presents you with a list of recent directories that you can then choose to open in dired. I have found to be a really quick way to find the directory I want to open, especially when combined with ivy-mode (or one of the other completion packages).

Dired+ can be installed from the normal package repositories.

Update

This post is superseded by this one.

Smart text templates with yasnippet

We looked before at expanding text with abbreviations which is great for simple things, but you can do a whole lot more using yasnippet. This is a smart template system for emacs, which is best explained with a simple example.

In the animation below I first of all use a snippet to write a fraction in latex by typing frac and hitting TAB which expands to \frac{numerator}{denominator} and places the cursor in the numerator field. I then type 1 and TAB to get to the next field and type 2 and TAB again to exit the snippet.

smart-text-templates-yasnippet.gif

In the second part of the animation I typed begin and hit TAB to expand the snippet, creating a latex environment. In this example, note how the environment field is mirrored in the begin and end lines so I only type itemize once.

If you use my recommended setup, prelude then you already have yasnippet installed as well as a bunch of useful snippets, so you can get started right away. Otherwise you can install yasnippet from one of the package repositories. In either case you can add

(require 'yasnippet)
(yas-global-mode 1)

to your emacs config file to turn on yasnippet globally so it works in all buffers.

If you install from one of the repositories, you won’t get many snippets, but you can download sets of them from the official git repository and write your own (see below). Snippets are defined in simple text files that you put (by default) in ~/.emacs.d/snippets/ in subdirectories named after the major mode for those snippets. So e.g. ~/.emacs.d/snippets/latex-mode/ contains my snippets that will be active in latex mode.

Writing a snippet is really simple. The fraction snippet I used above looks like this:

# -*- mode: snippet -*-
# name: frac
# key: frac
# --
\frac{${1:numerator}}{${2:denominator}}$0

The name can be whatever you like, but the key is the thing you type and TAB to expand out the snippet. You can see that the ${1:numerator} represents the first field the cursor moves to, with the placeholder text, and similarly for the second field. $0 indicates where the cursor goes when the final TAB exits the snippet.

The snippet for the latex environment in the second example is similarly simple:

# -*- mode: snippet -*-
# name: begin
# key: begin
# --
\begin{${1:environment}}
$0
\end{$1}

The repeated $1 mirrors the environment field.

After you have written a snippet, it should also be saved with the key as the file name in the appropriate subdirectory for the major mode you want. You’ll then need to use the commands yas-recompile-all and yas-reload-all to load the new snippets.

These are simple examples and yasnippet can do a lot more, such as include lisp code that is activated when the snippet expands. I’ll show an example of using this to generate email templates in a future post. There are some other sophisticated examples in this video from emacs rocks.