13

Since I have been struggling with this for some time and the issue is nowhere to be found on the Web, I thought to ease up some people's lives by posting this question here.


Assumption:

Basic LaTeX text and equations in AnkiSRS are generated correctly. For setting this up, please see AnkiDoc. I am running Windows 7 64-bit, for other systems the commands may vary.

Problem:

The AnkiSRS allows the user to input LaTeX code. However, when the user includes a TikZ or TikZ-based package, the generated document is wrong.

Example:

Include \usepackage{chemfig} in the preamble and try generating simple chemical diagram with \chemfig{A-B}. The result is this:
wrong
as opposed to what should have been the output:
correct

How to remedy this situation?

PeV
  • 453

2 Answers2

12

tl dr; Putting it all together

Little background first

Anki uses latex compiler to create .dvi intermediate documents from the input LaTeX code, which are then converted to .png bitmap image using dvipng converter. Anki is only able to work with .png picture format!

Now, TikZ is (in vast majority of cases) only able to be compiled with pdflatex compiler, which does not create .dvi document, but .pdf document right away. That of course implies that all packages built on top of TikZ (e.g. chemfig) are also only compiled with pdflatex.

To convert a .pdf document to a .png file, we have to have an external program. My choice is Imagemagick, which provides a command to do what we want (convert).

So with following commands in command line we should typeset a correct LateX .pdf document and then convert it to .png picture outside AnkiSRS:

pdflatex tmp
convert -trim -density 300 tmp.pdf tmp.png

However, for some reason Anki does not support entering command line after typesetting LaTeX document, so we need to make pdflatex skip to command line itself and invoke the convert so it can give Anki the expected output (.png). This is done in two steps.

Firstly, we need to use standalone document class. I used following command which needs a little explanation:

\documentclass[convert={convertexe={convert}}]{standalone}

The standalone package with option convert tries to make conversion of the .pdf file via Imagemagick. Sadly, Imagemagick's command convert uses the same word as Windows system's command convert which converts file allocation tables from FAT32 to NTFS.
Mr.Scharrer, creator of the package, realized this issue and that is why the package calls imgconvert instead of convert to avoid problems on machines running Windows.

One can either rename the Imagemagick program to imgconvert, or call the standalone class with convert={convertexe={convert}} option. I chose the latter after experiencing problems with the former. However, I cannot recommend it for machines running Windows Server 2008 or Windows Vista.

Secondly, the compiler has to be enabled escaping to command line, like this:

pdflatex tmp -shell-escape

At this point, this command should typeset a .pdf document and convert it to .png. Even though the compiler will report an error, the .png is correct. This might be fine with command line, but in Anki it crashes. For reason I still don't fully understand it can be fixed by including

\providecommand{\pgfsyspdfmark}[3]{}

at the beginning of document. For more details, please see this thread.

Putting it all together

Now let's take a look at Anki. We need to install add-on Edit LaTeX build process. When we open it for editing, this code pops up:

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

make the changes

import anki.latex anki.latex.latexCmds = newLaTeX

I suggest editing it like this:

# original setting
#newLaTeX = \
#[
#  ["latex", "-interaction=nonstopmode", "tmp.tex"],
#  ["dvipng", "-D", "200", "-T", "tight", "tmp.dvi", "-o", "tmp.png"]
#]

#===================================

TikZ compliant setting

newLaTeX =
[ ["pdflatex", "-interaction=nonstopmode", "--shell-escape", "tmp.tex"] ]

make the changes

import anki.latex anki.latex.latexCmds = newLaTeX

Since I wasn't able to find any help for the syntax, I assume that # is a line comment and don't have any idea about whether it is possible co select compiler conditionally if there was the need.

Now, update LaTeX header of all your notes like this:

\providecommand{\pgfsyspdfmark}[3]{}
\documentclass[convert={convertexe={convert}},border=2]{standalone}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{amssymb,amsmath}
\usepackage{xcolor}
\usepackage{chemfig}
\pagestyle{empty}
\setlength{\parindent}{0in}
\begin{document}

It should work (if tl dr; install Imagemagick).

PeV
  • 453
0

There is a slightly easier approach than PeV's answer, which is working for me (MacTeX 2023).

This relies on the following commands:

pdflatex -output-format=dvi -shell-escape -interaction=nonstopmode tmp.tex

dvisvgm --no-fonts -Z 2 tmp.dvi -o tmp.svg

Changing the Header/Preamble

Go to Tools >> Manage Note Types >> <select a note type> >> Options. Here you can adjust the header and footer that will wrap you LaTeX code when it is compiled by Anki.

There is a checkbox titled Create scalable images with dvisvgm. Tick that box (this is preferable because svg images can be rescaled more nicely than png's).

Change \documentclass{...} to \documentclass[dvisvgm]{standalone}. The dvisvgm option tells the LaTeX compiler you want it to produce a file that can be converted into an svg file.

Ensure you have \usepackage{tikz} somewhere in the header.

Changing the compiler invocation

Go to Tools >> Add-ons. Double-click on Edit LaTeX build process. Set the "svgCommands" part as below.

{
    "pngCommands": [
        [
            "latex",
            "-shell-escape",
            "-interaction=nonstopmode",
            "tmp.tex"
        ],
        [
            "dvipng",
            "-D",
            "200",
            "-T",
            "tight",
            "tmp.dvi",
            "-o",
            "tmp.png"
        ]
    ],
    "svgCommands": [
        [
            "pdflatex",
            "-output-format=dvi",
            "-shell-escape",
            "-interaction=nonstopmode",
            "tmp.tex"
        ],
        [
            "dvisvgm",
            "--no-fonts",
            "-Z",
            "2",
            "tmp.dvi",
            "-o",
            "tmp.svg"
        ]
    ]
}