Skip to Content

LaTeX Math expression to SVG

I found myself wanting to generate an SVG file from a LaTeX source expression. There are several online resources to do that. The resulting SVG file is usually generated by MathJax, and has stoke definitions specific to that implementation. I wanted something more flexible. And I wanted plain path definitions.

I don’t know a lot about SVG, so this desire may be simple prejudice. But I’ve found a solution that meets my goals and whose output is easily editable in Inkscape.

org-mode (in emacs), provides a mechanism to preview LaTeX fragments in the composition buffer. See section 11.8 in the org-mode manual. That mechanism leverages org-create-formula-image. That is the implementation the following function exploits.

(defun latex-to-svg (expr out-file)
  (interactive)
  (cl-letf* ((latex-header
              (concat
               (org-latex-make-preamble
                (org-export-get-environment (org-export-get-backend 'latex))
                org-format-latex-header
                'snippet)
               "\\usepackage{letltxmacro}\n"
               "\\makeatletter\n"
               "\\let\\oldr@@t\\r@@t\n"
               "\\def\\r@@t#1#2{%\n"
               "\\setbox0=\\hbox{$\\oldr@@t#1{#2\\,}$}\\dimen0=\\ht0\n"
               "\\advance\\dimen0-0.2\\ht0\n"
               "\\setbox2=\\hbox{\\vrule height\\ht0 depth -\\dimen0}%\n"
               "{\\box0\\lower0.4pt\\box2}}\n"
               "\\LetLtxMacro{\\oldsqrt}{\\sqrt}\n"
               "\\renewcommand*{\\sqrt}[2][\\ ]{\\oldsqrt[#1]{#2}}\n"
               "\\makeatother\n"))
             (org-preview-latex-process-alist
              (cons (append
                     '(custom)
                     (cdr (assoc 'dvisvgm org-preview-latex-process-alist))
                     `(:latex-header ,latex-header))
                    org-preview-latex-process-alist)))
    (org-create-formula-image expr out-file nil nil 'custom)))

(latex-to-svg  "$\\sqrt{-1}$" "/tmp/sqrt.svg")

The two bits to that function that set up the translation and format:

  • latex-header string, and
  • the dynamically rebound org-preview-latex-process-alist

org-create-formula-image generates a LaTeX file, feeds it to the latex command to convert it into a .dvi file. It then calls dvisvgm to convert the .dvi file to a .svg file.

The LaTeX source file that org-generate-formula-image generates is comprised of:

  • a header
  • document content
  • footer

This particular translation renders the LaTeX fragment “\sqrt{-1}“. We wanted to override the definition of the TeX sqrt function with a “closed” square root symbol. The place to insert the sqrt redefinition code in between the header and the document content. We do that by overriding the default header.

The default header for the image fragment generation is generated dynamically by org-latex-make-preamble. So we use the same org-latex-make-preamble the same way that org-generate-formula-image does, then concatenate the new definition to the original header. This ensures the redefinition occurs before the \document statement the starts the document content.

In order to coax org-generate-formula-image into adopting our new header, we build an alternate entry for org-preview-latex-process-alist, then we pass the modified alist and a “processing-type” parameter that selects our new addition to the alist. The new alist entry is based on the existing ‘dvisvgm entry. To that entry, we have simply added a :latex-header parameter.

Comment here.