Exemplo n.º 1
0
def _buildImg(deck, latex, fname, model):
    # add header/footer
    latex = (model.conf["latexPre"] + "\n" +
             latex + "\n" +
             model.conf["latexPost"])
    # write into a temp file
    log = open(namedtmp("latex_log.txt"), "w")
    texfile = file(namedtmp("tmp.tex"), "w")
    texfile.write(latex)
    texfile.close()
    # make sure we have a valid mediaDir
    mdir = deck.media.dir(create=True)
    oldcwd = os.getcwd()
    png = namedtmp("tmp.png")
    try:
        # generate dvi
        os.chdir(tmpdir())
        if call(latexCmd + ["tmp.tex"], stdout=log, stderr=log):
            return _errMsg("latex")
        # and png
        if call(latexDviPngCmd + ["tmp.dvi", "-o", "tmp.png"],
                stdout=log, stderr=log):
            return _errMsg("dvipng")
        # add to media
        shutil.copy2(png,
                     os.path.join(mdir, fname))
        return
    finally:
        os.chdir(oldcwd)
Exemplo n.º 2
0
def _buildImg(col, latex, fname, model):
    # add header/footer & convert to utf8
    latex = (model["latexPre"] + "\n" +
             latex + "\n" +
             model["latexPost"])
    latex = latex.encode("utf8")
    # it's only really secure if run in a jail, but these are the most common
    for bad in ("write18", "\\readline", "\\input", "\\include", "\\catcode",
                "\\openout", "\\write", "\\loop", "\\def", "\\shipout"):
        assert bad not in latex
    # write into a temp file
    log = open(namedtmp("latex_log.txt"), "w")
    texfile = file(namedtmp("tmp.tex"), "w")
    texfile.write(latex)
    texfile.close()
    mdir = col.media.dir()
    oldcwd = os.getcwd()
    png = namedtmp("tmp.png")
    try:
        # generate dvi
        os.chdir(tmpdir())
        if call(latexCmd + ["tmp.tex"], stdout=log, stderr=log):
            return _errMsg("latex")
        # and png
        if call(latexDviPngCmd + ["tmp.dvi", "-o", "tmp.png"],
                stdout=log, stderr=log):
            return _errMsg("dvipng")
        # add to media
        shutil.copyfile(png, os.path.join(mdir, fname))
        return
    finally:
        os.chdir(oldcwd)
Exemplo n.º 3
0
def _buildImg(col, latex, fname, model):
    # add header/footer & convert to utf8
    latex = (model["latexPre"] + "\n" +
             latex + "\n" +
             model["latexPost"])
    latex = latex.encode("utf8")
    # it's only really secure if run in a jail, but these are the most common
    for bad in ("write18", "\\readline", "\\input", "\\include", "\\catcode",
                "\\openout", "\\write", "\\loop", "\\def", "\\shipout"):
        assert bad not in latex
    # write into a temp file
    log = open(namedtmp("latex_log.txt"), "w")
    texfile = file(namedtmp("tmp.tex"), "w")
    texfile.write(latex)
    texfile.close()
    mdir = col.media.dir()
    oldcwd = os.getcwd()
    png = namedtmp("tmp.png")
    try:
        # generate dvi
        os.chdir(tmpdir())
        if call(latexCmd + ["tmp.tex"], stdout=log, stderr=log):
            return _errMsg("latex")
        # and png
        if call(latexDviPngCmd + ["tmp.dvi", "-o", "tmp.png"],
                stdout=log, stderr=log):
            return _errMsg("dvipng")
        # add to media
        shutil.copy2(png,
                     os.path.join(mdir, fname))
        return
    finally:
        os.chdir(oldcwd)
Exemplo n.º 4
0
def openFolder(path):
    if isWin:
        if isinstance(path, unicode):
            path = path.encode(sys.getfilesystemencoding())
        call(["explorer", path], wait=False)
    else:
        QDesktopServices.openUrl(QUrl("file://" + path))
Exemplo n.º 5
0
def _buildImg(deck, latex, fname, model):
    # add header/footer
    latex = (model.conf["latexPre"] + "\n" + latex + "\n" +
             model.conf["latexPost"])
    # write into a temp file
    log = open(namedtmp("latex_log.txt"), "w")
    texfile = file(namedtmp("tmp.tex"), "w")
    texfile.write(latex)
    texfile.close()
    # make sure we have a valid mediaDir
    mdir = deck.media.dir(create=True)
    oldcwd = os.getcwd()
    png = namedtmp("tmp.png")
    try:
        # generate dvi
        os.chdir(tmpdir())
        if call(latexCmd + ["tmp.tex"], stdout=log, stderr=log):
            return _errMsg("latex")
        # and png
        if call(latexDviPngCmd + ["tmp.dvi", "-o", "tmp.png"],
                stdout=log,
                stderr=log):
            return _errMsg("dvipng")
        # add to media
        shutil.copy2(png, os.path.join(mdir, fname))
        return
    finally:
        os.chdir(oldcwd)
Exemplo n.º 6
0
def openFolder(path):
    if isWin:
        if isinstance(path, unicode):
            path = path.encode(sys.getfilesystemencoding())
        call(["explorer", path], wait=False)
    else:
        QDesktopServices.openUrl(QUrl("file://" + path))
Exemplo n.º 7
0
def _buildImg(col, latex, fname, model):
    # add header/footer & convert to utf8
    latex = (model["latexPre"] + "\n" +
             latex + "\n" +
             model["latexPost"])
    latex = latex.encode("utf8")
    # it's only really secure if run in a jail, but these are the most common
    tmplatex = latex.replace("\\includegraphics", "")
    for bad in ("write18", "\\readline", "\\input", "\\include", "\\catcode",
                "\\openout", "\\write", "\\loop", "\\def", "\\shipout"):
        if bad in tmplatex:
            return _("""\
For security reasons, '%s' is not allowed on cards. You can still use \
it by placing the command in a different package, and importing that \
package in the LaTeX header instead.""") % bad
    # write into a temp file
    log = open(namedtmp("latex_log.txt"), "w")
    texpath = namedtmp("tmp.tex")
    texfile = file(texpath, "w")
    texfile.write(latex)
    texfile.close()
    mdir = col.media.dir()
    oldcwd = os.getcwd()
    png = namedtmp("tmp.png")
    try:
        # generate png
        os.chdir(tmpdir())
        for latexCmd in latexCmds:
            if call(latexCmd, stdout=log, stderr=log):
                return _errMsg(latexCmd[0], texpath)
        # add to media
        shutil.copyfile(png, os.path.join(mdir, fname))
        return
    finally:
        os.chdir(oldcwd)
Exemplo n.º 8
0
def _buildImg(col, latex, fname, model):
    # add header/footer & convert to utf8
    latex = (model["latexPre"] + "\n" + latex + "\n" + model["latexPost"])
    latex = latex.encode("utf8")
    # it's only really secure if run in a jail, but these are the most common
    tmplatex = latex.replace("\\includegraphics", "")
    for bad in ("\\write18", "\\readline", "\\input", "\\include", "\\catcode",
                "\\openout", "\\write", "\\loop", "\\def", "\\shipout"):
        # don't mind if the sequence is only part of a command
        bad_re = "\\" + bad + "[^a-zA-Z]"
        if re.search(bad_re, tmplatex):
            return _("""\
For security reasons, '%s' is not allowed on cards. You can still use \
it by placing the command in a different package, and importing that \
package in the LaTeX header instead.""") % bad
    # write into a temp file
    log = open(namedtmp("latex_log.txt"), "w")
    texpath = namedtmp("tmp.tex")
    texfile = file(texpath, "w")
    texfile.write(latex)
    texfile.close()
    mdir = col.media.dir()
    oldcwd = os.getcwd()
    png = namedtmp("tmp.png")
    try:
        # generate png
        os.chdir(tmpdir())
        for latexCmd in latexCmds:
            if call(latexCmd, stdout=log, stderr=log):
                return _errMsg(latexCmd[0], texpath)
        # add to media
        shutil.copyfile(png, os.path.join(mdir, fname))
        return
    finally:
        os.chdir(oldcwd)
Exemplo n.º 9
0
def buildImg(deck, latex):
    log = open(os.path.join(tmpdir, "latex_log.txt"), "w+")
    texpath = os.path.join(tmpdir, "tmp.tex")
    texfile = file(texpath, "w")
    texfile.write(latex)
    texfile.close()
    # make sure we have a valid mediaDir
    mdir = deck.mediaDir(create=True)
    oldcwd = os.getcwd()
    if sys.platform == "win32":
        si = subprocess.STARTUPINFO()
        try:
            si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        except:
            si.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW
    else:
        si = None
    try:
        os.chdir(tmpdir)

        def errmsg(type):
            msg = _("Error executing %s.\n") % type
            try:
                log = open(os.path.join(tmpdir, "latex_log.txt")).read()
                msg += "<small><pre>" + cgi.escape(log) + "</pre></small>"
            except:
                msg += _("Have you installed latex and dvipng?")
                pass
            return msg

        if call(["latex", "-interaction=nonstopmode", "tmp.tex"],
                stdout=log,
                stderr=log,
                startupinfo=si):
            return (False, errmsg("latex"))
        if call(latexDviPngCmd + ["tmp.dvi", "-o", "tmp.png"],
                stdout=log,
                stderr=log,
                startupinfo=si):
            return (False, errmsg("dvipng"))
        # add to media
        target = latexImgFile(deck, latex)
        shutil.copy2(os.path.join(tmpdir, "tmp.png"),
                     os.path.join(mdir, target))
        return (True, target)
    finally:
        os.chdir(oldcwd)
Exemplo n.º 10
0
def _save_latex_image(
    col: anki.collection.Collection,
    extracted: ExtractedLatex,
    header: str,
    footer: str,
    svg: bool,
) -> str | None:
    # add header/footer
    latex = f"{header}\n{extracted.latex_body}\n{footer}"
    # it's only really secure if run in a jail, but these are the most common
    tmplatex = latex.replace("\\includegraphics", "")
    for bad in (
            "\\write18",
            "\\readline",
            "\\input",
            "\\include",
            "\\catcode",
            "\\openout",
            "\\write",
            "\\loop",
            "\\def",
            "\\shipout",
    ):
        # don't mind if the sequence is only part of a command
        bad_re = f"\\{bad}[^a-zA-Z]"
        if re.search(bad_re, tmplatex):
            return col.tr.media_for_security_reasons_is_not(val=bad)

    # commands to use
    if svg:
        latex_cmds = svgCommands
        ext = "svg"
    else:
        latex_cmds = pngCommands
        ext = "png"

    # write into a temp file
    log = open(namedtmp("latex_log.txt"), "w", encoding="utf8")
    texpath = namedtmp("tmp.tex")
    texfile = open(texpath, "w", encoding="utf8")
    texfile.write(latex)
    texfile.close()
    oldcwd = os.getcwd()
    png_or_svg = namedtmp(f"tmp.{ext}")
    try:
        # generate png/svg
        os.chdir(tmpdir())
        for latex_cmd in latex_cmds:
            if call(latex_cmd, stdout=log, stderr=log):
                return _err_msg(col, latex_cmd[0], texpath)
        # add to media
        with open(png_or_svg, "rb") as file:
            data = file.read()
        col.media.write_data(extracted.filename, data)
        os.unlink(png_or_svg)
        return None
    finally:
        os.chdir(oldcwd)
        log.close()
Exemplo n.º 11
0
def buildImg(deck, latex):
    log = open(os.path.join(tmpdir, "latex_log.txt"), "w+")
    texpath = os.path.join(tmpdir, "tmp.tex")
    texfile = file(texpath, "w")
    texfile.write(latex)
    texfile.close()
    # make sure we have a valid mediaDir
    mdir = deck.mediaDir(create=True)
    oldcwd = os.getcwd()
    if sys.platform == "win32":
        si = subprocess.STARTUPINFO()
        try:
            si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        except:
            si.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW
    else:
        si = None
    try:
        os.chdir(tmpdir)
        def errmsg(type):
            msg = _("Error executing %s.\n") % type
            try:
                log = open(os.path.join(tmpdir, "latex_log.txt")).read()
                msg += "<small><pre>" + cgi.escape(log) + "</pre></small>"
            except:
                msg += _("Have you installed latex and dvipng?")
                pass
            return msg
        if call(["latex", "-interaction=nonstopmode",
                 "tmp.tex"], stdout=log, stderr=log, startupinfo=si):
            return (False, errmsg("latex"))
        if call(latexDviPngCmd + ["tmp.dvi", "-o", "tmp.png"],
                stdout=log, stderr=log, startupinfo=si):
            return (False, errmsg("dvipng"))
        # add to media
        target = latexImgFile(deck, latex)
        shutil.copy2(os.path.join(tmpdir, "tmp.png"),
                     os.path.join(mdir, target))
        return (True, target)
    finally:
        os.chdir(oldcwd)
Exemplo n.º 12
0
def export_audio(output_folder, field_names, model_ids, cards_per_batch,
                 num_batches, num_loops, include_separator):
    "Save all audio files into one large audio file"
    audio_files = get_card_audio(cards_per_batch * num_batches, field_names,
                                 model_ids)

    # get files on machine
    audio_files = [
        os.path.join(mw.col.media.dir(), field) for field in audio_files
    ]

    for batch_id in range(num_batches):
        audio_files_in_batch = audio_files[batch_id *
                                           cards_per_batch:(batch_id + 1) *
                                           cards_per_batch]
        output_file = os.path.join(output_folder, "batch%d.mp3" % batch_id)
        audio_list_tmp_file = namedtmp("studyahead_audio_list.txt")

        separator_audio = os.path.join(mw.pm.addonFolder(), 'Studyahead_Audio',
                                       'file_separator.mp3')
        with codecs.open(audio_list_tmp_file, "w", "utf-8") as f:
            for i, audio_file in enumerate(audio_files_in_batch):
                for j in range(num_loops):
                    f.write("file '%s'\n" % os.path.relpath(
                        audio_file,
                        os.path.dirname(audio_list_tmp_file)).replace(
                            "\\", "/"))
                if i < len(audio_files_in_batch) and include_separator:
                    f.write("file '%s'\n" % os.path.relpath(
                        separator_audio,
                        os.path.dirname(audio_list_tmp_file)).replace(
                            "\\", "/"))

        output_command = [
            "ffmpeg", "-y", "-f", "concat", "-safe", "0", "-i",
            audio_list_tmp_file.replace("\\", "/"), "-vcodec", "copy",
            output_file
        ]
        with open(namedtmp("studyahead_audio_log.txt"), "w") as log:
            call(output_command, wait=True, stdout=log, stderr=log)
def _buildSnd(col, abc, fname):
    '''Build the sound MP3 file itself and add it to the media dir'''
    abcfile = open(abcFile, "w")
    abcfile.write(abc)
    abcfile.close()

    log = open(abcFile+".log", "w")

    if call(abc2midiCmd, stdout=log, stderr=log):
        return _errMsg("abc2midi")

    if call(timidityCmd, stdout=log, stderr=log):
        return _errMsg("timidity")

    if call(lameCmd, stdout=log, stderr=log):
        return _errMsg("lame")

    # add to media
    try:
        shutil.move(mp3File, os.path.join(col.media.dir(), fname))
    except:
        return _("Could not move MP3 file to media dir. No output?<br>")+_errMsg("move")
Exemplo n.º 14
0
def _buildSnd(col, abc, fname):
    '''Build the sound MP3 file itself and add it to the media dir'''
    abcfile = open(abcFile, "w")
    abcfile.write(abc)
    abcfile.close()

    log = open(abcFile + ".log", "w")

    if call(abc2midiCmd, stdout=log, stderr=log):
        return _errMsg("abc2midi")

    if call(timidityCmd, stdout=log, stderr=log):
        return _errMsg("timidity")

    if call(lameCmd, stdout=log, stderr=log):
        return _errMsg("lame")

    # add to media
    try:
        shutil.move(mp3File, os.path.join(col.media.dir(), fname))
    except:
        return _("Could not move MP3 file to media dir. No output?<br>"
                 ) + _errMsg("move")
Exemplo n.º 15
0
def _buildImg(col, latex, fname, model):
    # add header/footer & convert to utf8
    latex = (model["latexPre"] + "\n" +
             latex + "\n" +
             model["latexPost"])
    latex = latex.encode("utf8")
    # it's only really secure if run in a jail, but these are the most common
    for bad in ("write18", "\\readline", "\\input", "\\include", "\\catcode",
                "\\openout", "\\write", "\\loop", "\\def", "\\shipout"):
        if bad in latex:
            return _("""\
For security reasons, '%s' is not allowed on cards. You can still use \
it by placing the command in a different package, and importing that \
package in the LaTeX header instead.""") % bad
    # write into a temp file
    log = open(namedtmp("latex_log.txt"), "w")
    texpath = namedtmp("tmp.tex")
    texfile = file(texpath, "w")
    texfile.write(latex)
    texfile.close()
    mdir = col.media.dir()
    oldcwd = os.getcwd()
    png = namedtmp("tmp.png")
    try:
        # generate dvi
        os.chdir(tmpdir())
        if call(latexCmd + ["tmp.tex"], stdout=log, stderr=log):
            return _errMsg("latex", texpath)
        # and png
        if call(latexDviPngCmd + ["tmp.dvi", "-o", "tmp.png"],
                stdout=log, stderr=log):
            return _errMsg("dvipng", texpath)
        # add to media
        shutil.copyfile(png, os.path.join(mdir, fname))
        return
    finally:
        os.chdir(oldcwd)
Exemplo n.º 16
0
def _buildImg(col, ly, fname):
    '''Build the image PNG file itself and add it to the media dir.'''
    lyfile = open(lilypondFile, "w")
    lyfile.write(ly)
    lyfile.close()

    log = open(lilypondFile+".log", "w")

    if call(lilypondCmd, stdout=log, stderr=log):
        return _errMsg("lilypond")

    # add to media
    try:
        shutil.move(lilypondFile+".png", os.path.join(col.media.dir(), fname))
    except:
        return _("Could not move LilyPond PNG file to media dir. No output?<br>")+_errMsg("lilypond")
Exemplo n.º 17
0
def _buildImg(col, latex, fname, model):
    # add header/footer
    latex = (model["latexPre"] + "\n" +
             latex + "\n" +
             model["latexPost"])
    # it's only really secure if run in a jail, but these are the most common
    tmplatex = latex.replace("\\includegraphics", "")
    for bad in ("\\write18", "\\readline", "\\input", "\\include",
                "\\catcode", "\\openout", "\\write", "\\loop",
                "\\def", "\\shipout"):
        # don't mind if the sequence is only part of a command
        bad_re = "\\" + bad + "[^a-zA-Z]"
        if re.search(bad_re, tmplatex):
            return _("""\
For security reasons, '%s' is not allowed on cards. You can still use \
it by placing the command in a different package, and importing that \
package in the LaTeX header instead.""") % bad

    # commands to use?
    if model.get("latexsvg", False):
        latexCmds = svgCommands
        ext = "svg"
    else:
        latexCmds = pngCommands
        ext = "png"

    # 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)
    try:
        # generate png
        os.chdir(tmpdir())
        for latexCmd in latexCmds:
            if call(latexCmd, stdout=log, stderr=log):
                return _errMsg(latexCmd[0], texpath)
        # add to media
        shutil.copyfile(png, os.path.join(mdir, fname))
        return
    finally:
        os.chdir(oldcwd)
        log.close()
Exemplo n.º 18
0
def _buildImg(col, ly, fname):
    '''Build the image PNG file itself and add it to the media dir.'''
    lyfile = open(lilypondFile, "w")
    lyfile.write(ly)
    lyfile.close()

    log = open(lilypondFile + ".log", "w")

    if call(lilypondCmd, stdout=log, stderr=log):
        return _errMsg("lilypond")

    # add to media
    try:
        shutil.move(lilypondFile + ".png",
                    os.path.join(col.media.dir(), fname))
    except:
        return _(
            "Could not move LilyPond PNG file to media dir. No output?<br>"
        ) + _errMsg("lilypond")
Exemplo n.º 19
0
def _build_img(ly, fname):
    """
        Build the image file itself and add it to the media dir.
    :param ly: LilyPond code
    :param fname: Filename for rendered image
    :return: None if successful, else error message
    """
    lyfile = open(TEMP_FILE, "w")
    lyfile.write(ly)
    lyfile.close()

    log = open(TEMP_FILE + ".log", "w")

    if call(LILYPOND_CMD, stdout=log, stderr=log):
        return _err_msg("lilypond")

    # add to media
    try:
        shutil.move(TEMP_FILE + OUTPUT_FILE_EXT,
                    os.path.join(mw.col.media.dir(), fname))
    except:
        return _(
            "Could not move LilyPond image file to media dir. No output?<br>"
        ) + _err_msg("lilypond")
Exemplo n.º 20
0
def _buildImg(col, latex, fname, model):
    """Generate an image file from latex code

    latex's header and foot is added as in the model. The image is
    named fname and added to the media folder of this collection.    

    The compiled file is in tmp.tex and its output (err and std) in
    latex_log.tex, replacing previous files of the same name. Both of
    those file are in the tmpdir as in utils.py

    Compiles to svg if latexsvg is set to true in the model, otherwise
    to png. The compilation commands are given above.

    In case of error, return an error message to be displayed instead
    of the LaTeX document. (Note that this image is not displayed in
    AnkiDroid. It is probably shown only in computer mode)

    Keyword arguments:
    col -- the current collection. It deals with media folder
    latex -- the code LaTeX to compile, as given in fields
    fname -- the name given to the generated png
    model -- the model in which is compiled the note. It deals with
    the header/footer, and the image file format
    """
    # add header/footer
    latex = (model["latexPre"] + "\n" +
             latex + "\n" +
             model["latexPost"])
    # it's only really secure if run in a jail, but these are the most common
    tmplatex = latex.replace("\\includegraphics", "")
    for bad in ("\\write18", "\\readline", "\\input", "\\include",
                "\\catcode", "\\openout", "\\write", "\\loop",
                "\\def", "\\shipout"):
        # don't mind if the sequence is only part of a command
        bad_re = "\\" + bad + "[^a-zA-Z]"
        if re.search(bad_re, tmplatex):
            return _("""\
For security reasons, '%s' is not allowed on cards. You can still use \
it by placing the command in a different package, and importing that \
package in the LaTeX header instead.""") % bad

    # commands to use?
    if model.get("latexsvg", False):
        latexCmds = svgCommands
        ext = "svg"
    else:
        latexCmds = pngCommands
        ext = "png"

    # 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)
    try:
        # generate an image
        os.chdir(tmpdir())
        for latexCmd in latexCmds:
            if call(latexCmd, stdout=log, stderr=log):
                return _errMsg(latexCmd[0], texpath)
        # add the image to the media folder
        shutil.copyfile(png, os.path.join(mdir, fname))
        return
    finally:
        os.chdir(oldcwd)
        log.close()
Exemplo n.º 21
0
def _save_latex_image(
    col: anki.collection.Collection,
    extracted: ExtractedLatex,
    header: str,
    footer: str,
    svg: bool,
) -> Optional[str]:
    # add header/footer
    latex = header + "\n" + extracted.latex_body + "\n" + footer
    # it's only really secure if run in a jail, but these are the most common
    tmplatex = latex.replace("\\includegraphics", "")
    for bad in (
            "\\write18",
            "\\readline",
            "\\input",
            "\\include",
            "\\catcode",
            "\\openout",
            "\\write",
            "\\loop",
            "\\def",
            "\\shipout",
    ):
        # don't mind if the sequence is only part of a command
        bad_re = "\\" + bad + "[^a-zA-Z]"
        if re.search(bad_re, tmplatex):
            return (_("""\
For security reasons, '%s' is not allowed on cards. You can still use \
it by placing the command in a different package, and importing that \
package in the LaTeX header instead.""") % bad)

    # commands to use
    if svg:
        latexCmds = svgCommands
        ext = "svg"
    else:
        latexCmds = pngCommands
        ext = "png"

    # 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()
    oldcwd = os.getcwd()
    png_or_svg = namedtmp("tmp.%s" % ext)
    try:
        # generate png/svg
        os.chdir(tmpdir())
        for latexCmd in latexCmds:
            if call(latexCmd, stdout=log, stderr=log):
                return _errMsg(latexCmd[0], texpath)
        # add to media
        with open(png_or_svg, "rb") as file:
            data = file.read()
        col.media.write_data(extracted.filename, data)
        os.unlink(png_or_svg)
        return None
    finally:
        os.chdir(oldcwd)
        log.close()