Wednesday, December 07, 2016

Changing imaxima's Output Font

I use imaxima from Emacs to interact with the Maxima symbolic algebra system. imaxima produces nicely typeset output from the results of Maxima, instead of crude ASCII graphics, and also supports embedding plots and drawings directly in an Emacs buffer. imaxima works by running LaTeX on the output of each Maxima command you enter; it then uses Ghostscript to produce an image that is displayed in the output buffer.

I also use the Solarized color theme with Emacs, which I find quite easy on my eyes. However, there is a problem: imaxima output, which uses Computer Modern fonts by default, becomes quite hard for me to read:

cm-cropped.png

The anti-aliasing performed by Ghostscript interacts with the Solarized colors in a way that makes small letters wash out.

1 Changing the font

Fortunately, it's not too hard to change the font used for imaxima's LaTeX output, but there are a couple of gotchas to keep in mind. This StackExchange question is a good starting point for choosing a font that should work nicely on the screen. The variable imaxima-latex-preamble is defined for just this purpose; in fact, the documentation says "This can be used to change, say, the document font." However, changing this variable's value won't change the font during an imaxima session. It turns out that, at the start of a session, imaxima loads several packages and and definitions into LaTeX and then creates a "LaTeX format file," which is a dump of the LaTeX state. This format file is used when LaTeX is invoked to process each line of Maxima output because this is much faster than loading packages every time. The value of imaxima-latex-preamble is included when the format file is loaded and dumped, so if you change it you need to kill your imaxima buffer and restart before seeing different results.

I chose the Libertine font, which looks nice:

libertine-cropped.png

I achieved this by following the example of that StackExchange page:

(setq imaxima-latex-preamble "\\usepackage{libertine} \\usepackage[libertine]{newtxmath}")

But this leads to the second gotcha.

(%i8) v1:matrix([x,y,z]);

LaTeX error in: \pmatrix{x&\linebreak[0]y&\linebreak[0]z\cr }

The problem is caused by the newtxmath package, which loads the AMS-LaTeX package. Somewhere in there the pmatrix is redefined in an incompatible way. Luckily we can work around this! The maxima distribution comes with a file mactex-utilities.lisp that redefines the function that translates matrix expressions to LaTeX. The new definition emits a call to pmatrix that is compatible with the AMS-LaTeX version.

We could load this file using the Maxima initialization file maxima-init.mac (usually found in the .maxima directory), but we might not want this change for every use of Maxima. I've instead chosen to load the file using a startup hook from Emacs to send the loading command to the imaxima process:

(add-hook 'imaxima-startup-hook
          (lambda ()
            (let ((b (get-buffer "*imaxima*"))
                  (p (get-process "imaxima")))
              (if (and b p)
                  (apply comint-input-sender
                         (list (get-process "imaxima")
                               "load(\"mactex-utilities\");"))))))

Let the math hacking commence!

mactex-utilities-cropped.png