Guide on Using LaTeX, XeTeX, LuaTeX with Anki

Guide on Using LaTeX, XeTeX, LuaTeX with Anki

Disclaimer: Please take this 'Guide' with a grain of salt, I just tried to write this guide hoping it would help someone avoid the time of figuring all this out for themselves, as well as collecting a lot of the answers to various problems I had along the way in one place.

Table of Contents

Links to Complementary Guides

Here are a few links to stuff I didn't have time for or are already well explained.

  • For including custom commands in your LaTeX note types I can recommend this guide by Cathy Wu. Also see here, for why you can't use \def or \input.

Links to other interesting complementary guides:

  • This advanced formatting guide for AnkiDroid, might be interesting for a few styling tips in general.

Why LaTeX is Still Relevant for Anki

While I love the added Mathjax support for Anki, and I jumped ship from LaTeX to MathJax a while ago, I have found myself on occasion in need of LaTeX, the main reasons being: + Greater support for obscure packages, e. g. simplewick.sty for Wick contractions in quantum field theory. + Speed. Since you generate everything beforehand and save them as images, you don't need to wait everytime your MathJax code is processed. I have cards for math and physics proofs with a lot of MathJax on them, with loading times > 2s on my phone. Although this is less of a problem on PC and on better phones, it can still be useful to substitute MathJax with LaTeX completely or mix LaTeX and MathJax to improve the loading time.

Probably one of the main hurdles for LaTeX and currently one of the main advantages for MathJax is the ease of setup, since MathJax (with the AnkiDroid 2.9 beta and Anki 2.1) comes already integrated. I hope that this guide eliminates a lot of the work and can collect a majority of the things you need to know in one place, lessening the burden on getting started.

One of the things to keep in mind, is that with MathJax you have the ability to edit cards on the fly on your phone and directly view the result, since Ankidroid has no native LaTeX rendering capabilities you lose this ability with LaTeX.

As you might have guessed I am still a huge fan of MathJax but the need for LaTeX in Anki probably won't disappear for a while yet.

Quick Start Guide

  • Choose a LaTeX starter pack for your note type's LaTeX Header field
  • Copy and paste the starter pack into your note type options and tick the correct checkbox for .png or .svg
  • Install the 'Edit LaTeX build process add-on'
  • Select a image conversion route from here
  • Copy and paste it into the add-ons configuration

Example for LuaTeX and .pdf.svg: (my recommendation)

Go to ToolsManage Note Types → select your note type → Options… and copy this

\documentclass[a4paper,10pt]{article}

\usepackage{fontspec}

\usepackage{amsmath}   % You can't live without these math commands
\usepackage{amssymb}   % A lot of math symbols
\usepackage{mathtools} % Extension for amsmath
\usepackage{xfrac}     % For better inline \frac {1}{2} use \sfrac {1}{2}

\usepackage{unicode-math} % Allows Unicode input for both XeTeX and LuaTeX,
                          %e. g. α instead of \alpha

\setmathfont{Latin Modern Math} %A working open type math font
                                %see link below for a list of other available fonts

\pagestyle{empty} %to supress page numbering which hinders proper trimming

\begin{document}

into the Header field. Your Footer field should be \end{document}, if not, adjust that field as well.

Still in Options… tick the checkbox 'Create scalable images with dvisvgm', so that the checkbox is checked.

Go to ToolsAdd-onsGet Add-ons… → enter the code found on the 'Edit LaTeX build process' add-on page.

After you have thus installed the add-on, find it in the add-on list and click on Config on the right hand side of the window.

Copy this, or alternatively only the .svg section,

{
    "pngCommands": [
        [
            "lualatex",
            "-interaction=nonstopmode",
            "tmp.tex"
        ],
        [
            "convert",
            "-density",
            "200",
            "-trim",
            "tmp.pdf",
            "tmp.png"
        ]
    ],
    "svgCommands": [
        [
            "lualatex",
            "-interaction=nonstopmode",
            "tmp.tex"
        ],
        [
            "pdfcrop",
            "tmp.pdf",
            "tmp.pdf"
        ],
        [
            "pdf2svg",
            "tmp.pdf",
            "tmp.svg"
        ]
    ]
}

into the window you found under the add-ons config page.

You can find pdfcrop here and pdf2svg here.

Now you should be all set. If you have additional questions or don't know what to do, please check the rest of the article to see whether it can answer your questions, as well as the troubleshooting section and there the read first part, where I collect stuff you should know from the Anki manual.

Anki's LaTeX Process

You can find out how and what exactly Anki does in the latex.py file in Anki's source code, which is the main reference for this section.

LaTeX Delimiters

Anki supports three LaTeX delimiters out of the box (see Anki manual: * [latex] … [/latex] * [$] … [/$] * [$$] … [/$$]

Where: * [latex] … [/latex] is the general LaTeX delimiter. You can put anything you would put between begin{document} and end{document} in here. * [$] … [/$] corresponds to [latex]$ … $[/latex] or [latex]\begin{math} … \end{math}[/latex]. * [$$] … [/$$] corresponds to [latex]$$ … $$[/latex] or [latex]\begin{displaymath} … \end{displaymath}[/latex].

we will see why and how this comes to be shortly.

One thing to keep in mind, is that the LaTeX delimiters need to be inside a Anki field, i. e. [latex]…[/latex] in field {{front}} is okay, but [latex]{{front}}[/latex] in your card design is not. See the Anki manual and this later section.

LaTeX Settings

First let's look at your LaTeX settings, which are set for each note type. You can find them under ToolsManage Note TypesOptions (after you selected the note type of interest).

Notice the checkbox 'Create scalable images with dvisvgm', this will be important later for the discussion about producing .png and .svg images.

Below this checkbox you will find fields with the headings 'Header' and 'Footer' respectively. At the moment (Anki v2.1.15) the standard settings are

\documentclass[12pt]{article}
\special{papersize=3in,5in}
\usepackage[utf8]{inputenc}
\usepackage{amssymb,amsmath}
\pagestyle{empty}
\setlength{\parindent}{0in}
\begin{document}

for the 'Header' field and

\end{document}

for the 'Footer' field. Otherwise they contain whatever was in these fields when you made a clone of a previous note type or whatever you edited it to be.

.tex Generation

What is Generated

For every [latex] … [/latex] delimiter Anki will generate a file tmp.tex in your systems /tmp/anki_temp/ or /temp/anki_temp/ folder.

Location of ../anki_temp/ folders on various operating systems:
  • Mac Os : /var/folders/…/…/T/anki_temp/ (Not tested yet, just a good guess looking at this.)
    • Use echo $TMPDIR to find the exact path. [1]
    • Use open $TMPDIR to open the folder. [1]
    • Use cd $TMPDIR to change directory to the temporary folder in the command line. [1]
  • Ubuntu : /tmp/anki_temp/
  • Windows: C:\Users\YourNameHere\AppData\Local\Temp\anki_temp\ (From personal testing on Win 8.)
    • Obviously you need to change YourNameHere to the name of your Windows user name.
    • Also, \anki_temp\ is not in C:\Windows\Temp\.


Code generating the ../anki_temp/ folder:
    _tmpdir = None

    def tmpdir():
        "A reusable temp folder which we clean out on each program invocation."
        global _tmpdir
        if not _tmpdir:
            def cleanup():
                shutil.rmtree(_tmpdir)
            import atexit
            atexit.register(cleanup)
            _tmpdir = os.path.join(tempfile.gettempdir(), "anki_temp")
        if not os.path.exists(_tmpdir):
            os.mkdir(_tmpdir)
        return _tmpdir
Reference: /anki/utils.py (Retrieved: 2019.10.05, Anki v2.1.15)


tmp.tex will simply be the contents of the LaTeX 'Header' field of the corresponding note type, followed by whatever is inbetween the [latex] … [/latex] delimiters, followed by the LaTeX 'Footer' field (and a line break \n after header, delimiter and footer each). Analogously for [$] … [/$] and [$$] … [/$$], using the substitutions described in a previous section. You can verify this for yourself by visiting your systems /tmp/, \Temp\ folder locating your systems anki_temp folder and opening the tmp.tex file. This is also a great starting point for debugging your LaTeX troubles with Anki.

When is it Generated

If you've opened your systems tmp folder you might have noticed, that no anki_temp folder exists, this is because the folder will be deleted after you close Anki and will only be generated if Anki generates any temporary files. The tmp.tex files are generated whenever a display of the LaTeX code is needed. For instance when previewing a card or reviewing a card. Or in general whenever Anki needs to generate .png or .svg files from the LaTeX code.

Thus, by making small changes in between [Latex]…[/Latex], even adding a space before [/Latex] is enough, and then previewing the card, you can force Anki to make new images and not use the previously created and saved images. This is especially helpful to debug changes to your LaTeX code, that are not made in between Anki's LaTeX delimiters, e.g. when comparing different font sizes or changes to the Latex header or footer in general.

In general you will probably want to use ToolsCheck Media, which (aside from it's other functions) also forces Anki to check whether every LaTeX delimiter field has a corresponding .png or .svg (depending on the settings in your note type) image file in the media folder. You can use this to update image files for all cards with changes to their LaTeX code, e. g. for when you made a change on mobile in the latex code and want to generate the updated image file on your PC for use on your mobile device. This also means, that you don't have to search changed cards on your PC to preview and thus update the changes to your media folder. However this does not work when you have made changes to your 'Edit LaTeX build process', for these to register you can use this workaround.

.png and .svg Generation

To understand how Anki creates the images for each LaTeX code, one needs to look at this section in latex.py.

pngCommands = [
    ["latex", "-interaction=nonstopmode", "tmp.tex"],
    ["dvipng", "-D", "200", "-T", "tight", "tmp.dvi", "-o", "tmp.png"]
]

svgCommands = [
    ["latex", "-interaction=nonstopmode", "tmp.tex"],
    ["dvisvgm", "--no-fonts", "-Z", "2", "tmp.dvi", "-o", "tmp.svg"]
]

Depending on the checkbox 'Create scalable images with dvisvgm' either the command line instructions under 'pngCommands' or the ones under 'svgCommands' are executed (using Pythons call() function). This is the same as if you would execute these commands in the command line in the ../anki_temp/ folder after the tmp.tex file generation. For instance, for the pngCommands:

latex -interaction=nonstopmode tmp.tex
dvipng -D 200 -T tight tmp.dvi -o tmp.png

Editing these instructions using the 'Edit LaTeX build process' add-on, allows the customization of Anki's LaTeX handling, which will be helpful for using XeTeX and LuaTeX.

Image File Names

Anki generates a corresponding image for each LaTeX code and saves them in your /collection.media/ folder in order not to have to generate images for each LaTeX item, each time you review a card [*]. They are also used for display on the mobile versions of Anki which do not have LaTeX capabilities.

How does Anki know whether it has already created an image, how does it find the correct image for each LaTeX code and how does it know that the exact same image on another card yields the same image without having to do the whole image generation for that code again?

The answer is, Anki generates an SHA-1 hash for the LaTeX code, renaming the generated images with the hash.
def _imgLink(col, latex, model):
    "Return an img link for LATEX, creating if necesssary."
    txt = _latexFromHtml(col, latex)

    if model.get("latexsvg", False):
        ext = "svg"
    else:
        ext = "png"

    # is there an existing file?
    fname = "latex-%s.%s" % (checksum(txt.encode("utf8")), ext)
    link = '<img class=latex src="%s">' % fname
    if os.path.exists(fname):
        return link

    # building disabled?
    if not build:
        return "[latex]%s[/latex]" % latex

    err = _buildImg(col, txt, fname, model)
    if err:
        return err
    else:
        return link
Reference: [/anki/latex.py][latex.py] (Retrieved: 2019-10-06, Anki v2.1.15) The important line for the hash is:
fname = "latex-%s.%s" % (checksum(txt.encode("utf8")), ext)
def checksum(data):
    if isinstance(data, str):
        data = data.encode("utf-8")
    return sha1(data).hexdigest()
Reference: [/anki/utils.py][utils.py] (Retrieved: 2019-10-06, Anki v2.1.15)


This yields an almost unique image link (collisions are possible with the SHA-1 hash, since the input space is larger than the output space, but very unlikely) to the image file in the collection.media folder.

The generated file follows the following naming pattern:

latex-hash.ext

where hash needs to be substituted with the 40 character hash and ext is either png or svg.

When you have successfully generated images for your LaTeX code you can try finding them in your collection.media folder in your Anki profile folder. For the location see this section in the Anki manual.

[*]\: If you have ever previewed a card with LaTeX code you will know it saves you a lot of time.

pdfTeX, XeTeX and LuaTeX

In this section I want to give a short overview of the (for this article) relevant properties of these three TeX engines. As well as a short header snippet to get you started with math related subjects.

Overview

  • pdfTeX
  • No native Unicode input support [*]
  • DVI output
  • PDF output

  • XeTeX

  • Native Unicode support
  • XDV output (alternative to DVI files, works just as well with dvisvgm but not at all with dvipng)
  • PDF output

  • LuaTeX

  • Native Unicode support
  • DVI output (but broken with open type fonts, i. e. no Unicode support [**], see here)
  • PDF output

[*]\: \usepackage[utf8]{inputenc} is not sufficient, you probably need to do a few more things, to get Unicode support, but with XeTeX and LuaTeX it just works (if you use the corresponding starter pack), which is what I wanted to express with that point. [**]\: as far as I understand, I'm no expert at this.

Remarks: The error prone DVI output with LuaTeX won't be a problem, since I will show you later how to do everything with PDFs which work just as well, and are far less error prone, as far as I can see.

Anki encodes the .tex files it generates in the utf8 format, which is an important prerequisite for the Unicode input support for XeTeX and LuaTeX.

# write into a temp file
    log = open(namedtmp("latex_log.txt"), "w")
    texpath = namedtmp("tmp.tex")
    texfile = open(texpath, "w", encoding="utf8")
    texfile.write(latex)
    texfile.close()
    mdir = col.media.dir()
    oldcwd = os.getcwd()
    png = namedtmp("tmp.%s" % ext)

The important line is texfile = open(texpath, "w", encoding="utf8"). Although this is not the only instance where this occurs in Anki's source code, this indicates that Anki uses the utf8 encoding for it's .tex files.

Reference: /anki/latex.py (Retrieved: 2019.10.05, Anki v2.1.15)

Math Starter Packs

You can certainly do better than these, and I'm not really a TeX expert, I just hope to give a quick starting point to people who just want to get started.

pdfTeX

The default, see previous section, works well.

XeTeX and LuaTeX

Header:

\documentclass[a4paper,10pt]{article}

\usepackage{fontspec}

\usepackage{amsmath}   % You can't live without these math commands
\usepackage{amssymb}   % A lot of math symbols
\usepackage{mathtools} % Extension for amsmath
\usepackage{xfrac}     % For better inline \frac {1}{2} use \sfrac {1}{2}

\usepackage{unicode-math} % Allows Unicode input for both XeTeX and LuaTeX,
                          %e. g. α instead of \alpha

\setmathfont{Latin Modern Math} %A working open type math font
                                %see link below for a list of other available fonts

\pagestyle{empty} %to supress page numbering which hinders proper trimming

\begin{document}
Reference: I got these settings from [this][Dortmund-LaTeX-Workshop-Presentation] (only in German) great PDF, on LuaTeX and LaTeX in general, from [this workshop][Dortmund-LaTeX-Workshop].


Link to the unicode-math ctan page for a list of open type math fonts for \setmathfonts{…}.

Apparently there is also mathspec which you can use instead of unicode-math, but only for XeTeX and not for LuaTeX while unicode-math works for both, which is why I simply use unicode-math for both. Reference.

Adjusting Anki's LaTeX Build Process

You will want to be using the Edit LaTeX build process add-on for adjusting Anki's LaTeX build process, since it does what you want perfectly. For what this is compare this previous section.

A quick note, from my observations I noticed, that you need to restart Anki for changes in the 'Edit LaTeX build process' add-on to take effect.

Once installed you can configure your LaTeX build process through the add-on, by going to ToolsAdd-ons → select 'Edit LaTeX build process' → Config.

In the following sections I'm going to give you a selection of working conversion paths you can plug into your LaTeX build process in the add-on. If these do not work for you, you can, with the understanding from the previous sections, comparing the examples here and informing yourself about the program you want to use, rather easily customize your LaTeX build process yourself, to use any program suitable for the job.

Also, sorry to all those using Mac Os, can't test anything for you, don't know my way around Mac Os. I mainly tested these on Ubuntu, but they should also work on Windows.

A quick heads up: The argument "-no-pdf" with XeTeX sets the output to be .xdv instead of the standard .pdf output. See this answer on stackexchange for a nice overview of output options for LaTeX, XeTeX and LuaTeX.

Reminder: + For .png images do not forget to uncheck the 'Create scalable images with dvisvgm' checkbox. + For .svg images do not forget to check the 'Create scalable images with dvisvgm' checkbox. + Keep in mind, that the XeTeX, LuaTeX starter packs do not work with "latex" and the LaTeX starter pack does not work with "xelatex" or "lualatex".

Also I highly recommend .svg over .png since .svg files are scalable and .png files are not, which saves you a lot of problems (especially on mobile), to which I haven't found a solution yet (and I don't really think are solvable).

.dvi, .xdv.png

For a .dvi output you can use Anki's default process (clicking on the 'Restore Defaults' button in the 'Edit LaTeX build process' add-on, resets your configuration back to the default):

{
    "pngCommands": [
        [
            "latex",
            "-interaction=nonstopmode",
            "tmp.tex"
        ],
        [
            "dvipng",
            "-D",
            "200",
            "-T",
            "tight",
            "tmp.dvi",
            "-o",
            "tmp.png"
        ]
    ],
    "svgCommands": [
    …

For LuaTeX you should be able to use "dvilualatex" instead of "latex", but this does not work with the XeTeX, LuaTeX starter pack, since the generated .dvi files are broken.

You might have noticed, that this does not work for XeTeX's .xdv output. This is because 'dvipng' does not support .xdv or any .dvi version > 2. And I don't know of an easy alternative, thus I recommend you use the .pdf to .png route.

I tried using dvisvgm to output a .png file, but although dvisvgm seems to have the option to output a .png file, this is just a .svg file with an .png file ending, and as such Anki will only show a broken image file icon. You can test this with:
{
    "pngCommands": [
        [
            "xelatex",
            "-interaction=nonstopmode",
            "-no-pdf",
            "tmp.tex"
        ],
        [
            "dvisvgm",
            "--no-fonts",
            "-Z",
            "2",
            "tmp.xdv",
            "-o",
            "tmp.png"
        ]
    ],
    "svgCommands": [
    …

.dvi, .xdv.svg

Here you can again, use Anki's default process:

  ],
"svgCommands": [
    [
        "latex",
        "-interaction=nonstopmode",
        "tmp.tex"
    ],
    [
        "dvisvgm",
        "--no-fonts",
        "-Z",
        "2",
        "tmp.dvi",
        "-o",
        "tmp.svg"
    ]
  ]
}
For XeTeX simply change "latex" to "xelatex", add "-no-pdf", after "-interaction=nonstopmode", and change "tmp.dvi" to "tmp.xdv".
…
],
  "svgCommands": [
    [
        "xelatex",
        "-interaction=nonstopmode",
        "-no-pdf",
        "tmp.tex"
    ],
    [
        "dvisvgm",
        "--no-fonts",
        "-Z",
        "2",
        "tmp.xdv",
        "-o",
        "tmp.svg"
    ]
  ]
}


As in the previous section the .dvi files resulting from "dvilualatex" are broken. Here too I recommend the .pdf route. You can test this with:
  …
  ],
  "svgCommands": [
    [
        "dvilualatex",
        "-interaction=nonstopmode",
        "tmp.tex"
    ],
    [
        "dvisvgm",
        "--no-fonts",
        "-Z",
        "2",
        "tmp.dvi",
        "-o",
        "tmp.svg"
    ]
  ]
}

.pdf.png

For Linux (tested for Ubuntu) I prefer to use convert from ImageMagick, for Windows this can get quite annoying to properly get working, since Windows has another program called convert in it's system libraries, see here and here. Thus I use Ghostscript for Windows, the idea for which I got from here.

Also with convert you might run into this error

convert-im6.q16: not authorized 'tmp.pdf' @ error/constitute.c/ReadImage/412.

or something similar. In that case this might help.

Linux

Instead of "latex" one needs to use "pdflatex" to get a .pdf output.

{
  "pngCommands": [
    [
        "pdflatex",
        "-interaction=nonstopmode",
        "tmp.tex"
    ],
    [
        "convert",
        "-density",
        "50",
        "-trim",
        "tmp.pdf",
        "tmp.png"
    ]
  ],
  "svgCommands": [
  …
For XeTeX it is the same, you just need to change "pdflatex" to "xelatex".
{
  "pngCommands": [
    [
        "xelatex",
        "-interaction=nonstopmode",
        "tmp.tex"
    ],
    [
        "convert",
        "-density",
        "50",
        "-trim",
        "tmp.pdf",
        "tmp.png"
    ]
  ],
  "svgCommands": [
  …
For LuaTeX it is the same, you just need to change "pdflatex" to "lualatex".
{
  "pngCommands": [
    [
        "lualatex",
        "-interaction=nonstopmode",
        "tmp.tex"
    ],
    [
        "convert",
        "-density",
        "50",
        "-trim",
        "tmp.pdf",
        "tmp.png"
    ]
  ],
  "svgCommands": [
  …


You can also use Ghostscript:

{
  "pngCommands": [
    [
      "pdflatex",
      "-interaction=nonstopmode",
      "tmp.tex"
    ],
    [
      "gswin32c",
      "-dNOPAUSE",
      "-sDEVICE=pngalpha",
      "-r300",
      "-dBATCH",
      "-dSAFER",
      "-sOutputFile=\"tmp.png\"",
      "tmp.pdf"
    ]
  ],
  "svgCommands": [
  …

Windows

For a 32-bit Windows installation you can use:

{
  "pngCommands": [
    [
      "pdflatex",
      "-interaction=nonstopmode",
      "tmp.tex"
    ],
    [
      "gswin32c",
      "-dNOPAUSE",
      "-sDEVICE=pngalpha",
      "-r300",
      "-dBATCH",
      "-dSAFER",
      "-sOutputFile=\"tmp.png\"",
      "tmp.pdf"
    ]
  ],
  "svgCommands": [
  …

Reference (Retrieved: 2019-10-07)

For a 64-bit Windows installation, you just need to change "gswin32c" to "gswin64c" (see here).
{
  "pngCommands": [
    [
      "pdflatex",
      "-interaction=nonstopmode",
      "tmp.tex"
    ],
    [
      "gswin32c",
      "-dNOPAUSE",
      "-sDEVICE=pngalpha",
      "-r300",
      "-dBATCH",
      "-dSAFER",
      "-sOutputFile=\"tmp.png\"",
      "tmp.pdf"
    ]
  ],
  "svgCommands": [
  …


Again, for XeTeX or LuaTeX you just need to change "pdflatex" to "xelatex" or "lualatex".

.pdf.svg

My go to programs for these steps are pdfcrop and pdf2svg. I also use pdfcrop to crop PDFs I use, create, thus I'm using it here. Again there are multiple options, which you can easily find on the web.

Instead of "latex" one needs to use "pdflatex" to get a .pdf output.

  …
  ],
  "svgCommands": [
    [
        "pdflatex",
        "-interaction=nonstopmode",
        "tmp.tex"
    ],
    [
        "pdfcrop",
        "tmp.pdf",
        "tmp.pdf"
    ],
    [
        "pdf2svg",
        "tmp.pdf",
        "tmp.svg"
    ]
  ]
}

You can do additional adjustments using optional arguments for pdfcrop and pdf2svg but I have found, that this already works quite well. You can find pdfcrop here and pdf2svg here.

For XeTeX it is the same, you just need to change "pdflatex" to "xelatex".
  …
  ],
  "svgCommands": [
    [
      "xelatex",
      "-interaction=nonstopmode",
      "tmp.tex"
    ],
    [
      "pdfcrop",
      "tmp.pdf",
      "tmp.pdf"
    ],
    [
      "pdf2svg",
      "tmp.pdf",
      "tmp.svg"
    ]
  ]
}
For LuaTeX it is the same, you just need to change "pdflatex" to "lualatex".
  …
  ],
  "svgCommands": [
    [
      "lualatex",
      "-interaction=nonstopmode",
      "tmp.tex"
    ],
    [
      "pdfcrop",
      "tmp.pdf",
      "tmp.pdf"
    ],
    [
      "pdf2svg",
      "tmp.pdf",
      "tmp.svg"
    ]
  ]
}


Additionally I can recommend using svgcleaner to reduce the size of the .svg files, to reduce the size of the collection.media folder. After the pdf2svg part just append this:
[
  "svgcleaner",
  "tmp.svg",
  "tmp.svg",
]
In total this would look like this, for pdfTeX:
  …
  ],
  "svgCommands": [
    [
      "pdflatex",
      "-interaction=nonstopmode",
      "tmp.tex"
    ],
    [
      "pdfcrop",
      "tmp.pdf",
      "tmp.pdf"
    ],
    [
      "pdf2svg",
      "tmp.pdf",
      "tmp.svg"
    ],
    [
      "svgcleaner",
      "tmp.svg",
      "tmp.svg",
    ]
  ]
}

Troubleshooting

Read First

Don’t use [Latex]{{Anki-Field}}[/Latex] in your card design, [Latex]…[/Latex] needs to surround the material within the {{Anki-Field}}. See this section in the Anki manual.

What you can do though, is, for example, use [Latex]…[/Latex] {{Anki-Field}} before the field reference. [*]

Here you need to take care, not to have {{ or }} (or I suppose {{{ and }}}), since these are reserved for field references like {{Anki-Field}}. Adding {{=<% %>=}} on your cards front and back template and then changing every {{Anki-Field}} to <%Anki-Field%> remedies that problem, see [*] and here and here for an explanation.

This does not work with cloze deletion however. [*] As far as I can tell, from testing, using {{=<% %>=}} on your front or back template completely breaks the cloze deletion function. For this, or in general you can simply change }} to } } which does not affect the result of your LaTeX, or MathJax code but makes it work with field references and cloze deletion.

Also, you can't use \def or \input in your cards, which means, you also can't define your own LaTeX commands directly in the header, but need to use a workaround, see here. Reference for this is this section in the Anki manual [*] (Retrieved: 2019.10.05):

Anki prohibits certain commands like \input or \def from being used on cards or in templates, because allowing them could allow malicious shared decks to damage your system. (To be on the safe side, these commands are prohibited even in comments, so if you’re getting this error but don’t think you’ve used one, please double-check any comments you have in your headers, templates, and cards.) If you need to use these commands, please add them to a system package and import that package as described in the previous section.

Furthermore, I'm certain, I have seen somewhere, that you should not use % in your LaTeX fields, but I can't find it anymore. If this were true, it would explain some errors I had when commenting stuff within the LaTeX delimiters.

[*]\: Reference

Broken Image Files Don't Get Replaced After Using ToolsCheck Media

I had this happen to me while testing, when I had created broken .svg files using dvilualatex and my XeTeX, LuaTeX starter pack. I noticed what had gone wrong, fixed the built process in the add-on, restarted, and noticed that Check Media didn't do anything. This is because Anki checks, whether there are already images with the corresponding hash and the correct file ending (in this case .svg). A easy solution is to switch to .png files in your note type options, use Check Media and delete unused media files, switch back to .svg and use Check Media again, which should have solved the problem because it deletes the unused .svg files, allowing us to replace them with the correct ones.

Broken .dvi Files with LuaTeX

For LuaTeX you should be able to use "dvilualatex" instead of "latex", but this does not work, since the resulting .dvi file seems to be broken.

You can test this with:
{
    "pngCommands": [
        [
            "dvilualatex",
            "-interaction=nonstopmode",
            "tmp.tex"
        ],
        [
            "dvipng",
            "-D",
            "200",
            "-T",
            "tight",
            "tmp.dvi",
            "-o",
            "tmp.png"
        ]
    ],
    "svgCommands": [
    …
I also used the XeTeX, LuaTeX starter pack from [here](#xetex-and-luatex).


This seems to be, because .dvi does not support open type fonts, i. e. you can not use \usepackage{fontspec} in your LaTeX header field or things using open type fonts, which, in my opinion, is one of the major reasons for using LuaTeX, since this allows Unicode input support (as far as I understand).

Thus you can either use an engine other than LuaTeX, not use open type fonts or use a .pdf → … route. The latter being my clear recommendation, since it comes with no real downsides.

latex-….svg Images Not Showing on AnkiDroid

If you have AnkiDroid v2.8.4 or anything below AnkiDroid v2.9 alpha 12, you won't be able to view your .svg image files on AnkiDroid, since support in AnkiDroid for Anki's 'Create scalable images with dvisvgm' checkbox was only implemented then, according to here.

I can confirm, that in the current AnkiDroid v2.9 beta latex-….svg files just work as expected. Also, as far as I can see, the beta is very stable and if you backup regularly I don't see a reason why you shouldn't just switch to the beta. See here in the AnkiDroid manual on how to join the beta. Alternatively you can always just get the latest .apk from here.

Permission / Authorization Problems with 'convert'

With convert I ran into this error:

convert-im6.q16: not authorized 'tmp.pdf' @ error/constitute.c/ReadImage/412.

(Note: im6.q16 is my ImageMagick program version, so you'll probably have something different here.)

In my case this was, because for security reasons ImageMagick imposes restrictions on which files it is allowed to read and write, see here.

To check, whether this is a problem for you, or to fix it, you need to find ImageMagick's policy.xml file. On Ubuntu you can find this in /etc/ImageMagick-6/ (clear, find the ImageMagick version you use). Here you need to find line

  <policy domain="coder" rights="none" pattern="PDF" />

and change it to

  <policy domain="coder" rights="read" pattern="PDF" />

This was the error I had when I was trying to convert tmp.pdf to tmp.png, depending on what you where doing (intending on doing) you might have to change a different line.

latex-….png Images Having Different Sizes on Small Screens

Problem

Example of the problem on narrow screens: PNG scaling example - big font - narrow screen

Example of how it should look like on wide screen: PNG scaling example - big font - wide screen

Image of the example with smaller resolution (you get the same for a similarly small font) on a narrow screen. PNG scaling example - tiny font - narrow screen
Image of the example with smaller resolution (you get the same for a similarly small font) on a wide screen. PNG scaling example - tiny font - wide screen
Image of the example as a .svg file, on a narrow screen. SVG scaling example - narrow screen
Image of the example as a .svg file, on a wide screen. SVG scaling example - wide screen


The narrow screen and wide screen examples are each roughly the same size on screen (taken as screenshots, so compare image sizes).

Settings for the examples:

Settings for .png files:

{
    "pngCommands": [
        [
            "lualatex",
            "-interaction=nonstopmode",
            "tmp.tex"
        ],
        [
            "convert",
            "-density",
            "200",
            "-trim",
            "tmp.pdf",
            "tmp.png"
        ]
    ],
    "svgCommands": [
    …

For small .png files, I changed "200" to "50".

Settings for .svg files:

    …
    ],
    "svgCommands": [
        [
            "lualatex",
            "-interaction=nonstopmode",
            "tmp.tex"
        ],
        [
            "pdfcrop",
            "tmp.pdf",
            "tmp.pdf"
        ],
        [
            "pdf2svg",
            "tmp.pdf",
            "tmp.svg"
        ]
    ]
}

I also used the XeTeX, LuaTeX starter pack from here.


For me the error appears on mobile and on the desktop version, but only if the screen isn’t big enough to fit the whole picture width on the screen, then it rescales the too large picture while preserving it’s ratio while the other not too large pictures are not rescaled, which leads to the difference in size.

This does not occur with MathJax where they are not rescaled or wrapped (if they are not broken up in smaller parts), but just go over the edge, which forces you to pan or crop out.

Solutions

  • Switch to .svg (they can also scale without loss of resolution)
  • Use \tiny (but be prepared for horrendous resolution)
  • Reduce the image size or resolution (again, pixelation follows)
  • Only view your cards on big screens, or more accurate wide screens
  • On mobile you can try switching to landscape mode
  • Surround everything with [latex]…[/latex]

If you can, I would always recommend switching to .svg images since these are better in every regard (when available!, not everything can be efficiently vectorized though, your LaTeX output can be though). If that is not an option, a combination of reducing your resolution or image size and using bigger screens is your only hope, as far as I know. Or MathJax, since that would be a great use for it.

Using \tiny

In order for your cards to use \tiny (or begin{tiny} and end{tiny} to affect a larger scope) you can change your LaTeX Header to

\begin{document}
\begin{tiny} %notice that it’s »tiny« not »\tiny«

and your Footer to

\end{tiny}
\end{document}

I got this solution from here and here.

In my experience \scriptsize is not small enough, to make .png properly behave on my phone, so you will likely need to use \tiny. For a good overview of corresponding pt sizes see here.

Another problem with \tiny is, that you need to adjust the density settings in the cropping process, otherwise the resulting .png files, have a low resolution. Increasing the resolution solves the pixelation problem, but you again have images, that are too large. Thus you end up with the same problem you tried to solve by using \tiny in the first place.

Changing the size in

\documentclass[a4paper,10pt]{article}

is apparently also not an easy option, since LaTeX only supports 10pt, 11pt and 12pt without using any special packages (see here, but you can easily test this yourself).

Changing the Resolution

You would do this by, for example changing "200" to "50" in

[
    "dvipng",
    "-D",
    "200",
    "-T",
    "tight",
    "tmp.dvi",
    "-o",
    "tmp.png"
]

which roughly corresponds to using \tiny, or by changing "200" to "50" in

[
    "convert",
    "-density",
    "200",
    "-trim",
    "tmp.pdf",
    "tmp.png"
]
Surround Everything with [latex]…[/latex]

This makes Front and Back one huge LaTeX document. It mostly works, as long as it's not too long, since at some point Anki resizes differently again. This was my go to solution in the past, but it obviously doesn't really work with cloze deletion cards. I was reminded about this option due to this stackexchange answer.

Inline Vertical Alignment Problems

One of the great things about MathJax is, that it solved all the vertical alignment problems. Compare this image using MathJax (also please imagine , are instead of what is depicted) Inline Vertical Alignment Problem - MathJax example

Source code:

Symbols like \(ρ\) or \(β\), which have \(\text{elements,}\) unlike \(A\) or \(α\), which go below the line are not correctly aligned.
Similarly with longer Elements, like the above or \(π = 3.14\).


to this image using LaTeX

Inline Vertical Alignment Problem - Unaligned LaTeX example

Source code:
Symbols like [$]ρ[/$] or [$]β[/$], which have [$]\text{elements,}[/$] unlike [$]A[/$] or [$]α[/$], which go below the line are not correctly aligned.
Similarly with longer Elements, like the above or [$]π = 3.14[/$].
Settings:
    …
    ],
    "svgCommands": [
        [
            "lualatex",
            "-interaction=nonstopmode",
            "tmp.tex"
        ],
        [
            "pdfcrop",
            "tmp.pdf",
            "tmp.pdf"
        ],
        [
            "pdf2svg",
            "tmp.pdf",
            "tmp.svg"
        ]
    ]
}
I also used the XeTeX, LuaTeX starter pack from [here](#xetex-and-luatex).


A nice option for 'fixing' the vertical alignment property I found here and here is adding

img[src*="latex"] {
  vertical-align: middle;
}

to the styling section on your card. (ToolsManage Note Types → select your note type → Cards… → paste the above into the Styling (shared between cards) field e. g. directly after .card {…}.)

This made the above example look like this: Inline Vertical Alignment Problem - Aligned LaTeX example

As you can see the above script for fixing the vertical alignment problem is not perfect like MathJax, but it makes it tolerable. Also some elements like the A get worse, but most get better.

LaTeX Images Are to Big or Too Small

A great solution for this I found here and here, was to use

.latex {
  zoom: 100%;
}

in your cards styling section, which allows you to control the zoom, i. e. the size the images appear for you in Anki.

You can also combine this with platform specific CSS, see this section in the manual. I have found that this works for me:

.mobile .latex {
  zoom: 100%;
}

You can add both of these to your styling section, to control the size the LaTeX images appear in Anki, AnkiDroid and AnkiMobile. Apparently, .mobile .latex {…} and .latex {…} are not multiplicative i. e. .latex { zoom: 1000%; } and .mobile .latex {zoom: 10%; } together don't yield a normal 100% zoom on mobile, so you don't even need to specify a platform other than .mobile ….

In a similar manner you should be able to combine .PlatformYouWant .latex {…} with any platform or browser to control the size of the LaTex images there.

Tips for Debugging

In the end I want to leave you with a few tips, to help you find and solve errors you encounter.

  • Obvious, but still important to mention: Use the search engine of your choice to find information on the problem in general or better yet, to find a specific error message you got or found in the logs.
  • To solve a specific problem in the image generation process the place with all the information, aside maybe from your LaTeX build process, will be the /anki_temp/ folder, see here for the location.
  • In your /anki_temp/ folder look at the .log file to determine where in Anki's image generation process the error is. Scroll down to the bottom, find the last program used as well as the error message.
  • If your error is with the .tex file you can try opening it with the .tex IDE of your choice and try to compile it to find errors, or doing it directly in the command line.
  • Try looking at the resulting .pdf, .dvi, .xdv files or the resulting .png or .svg file to identify things that could lead to errors or bugs somewhere in your image generation process, e. g. page numbers in your .pdf file.