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
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.
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.
- 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 Tools → Manage 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 Tools → Add-ons → Get 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.
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.
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.
First let's look at your LaTeX settings, which are set for each note type. You can find them under Tools → Manage Note Types → Options (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
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
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.
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 Tools → Check 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.
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.
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:
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.
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.
- 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)
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.
The default, see previous section, works well.
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.
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 Tools → Add-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.
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": [
…
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",
]
]
}
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
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.
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](/anki/Troubleshooting-PNGs-DifferentSizesOnSmallScreens/PNG-Big-Narrow-Screen.png)
Example of how it should look like on wide screen:
![PNG scaling example - big font - wide screen](/anki/Troubleshooting-PNGs-DifferentSizesOnSmallScreens/PNG-Big-Wide.png)
Image of the example with smaller resolution (you get the same for a similarly small font) on a narrow screen.
Image of the example with smaller resolution (you get the same for a similarly small font) on a wide screen.
Image of the example as a .svg
file, on a narrow screen.
Image of the example as a .svg
file, on a 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)
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](/anki/Inline-Vertical-Alignment-Problems/LaTeX-Unaligned.png)
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. (Tools → Manage 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](/anki/Inline-Vertical-Alignment-Problems/LaTeX-Aligned.png)
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
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.