From 4d2d9eab81927c15705f5365c209bd0b602981f4 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sat, 11 Dec 2010 01:40:49 +0900 Subject: [PATCH] generate latex at fact modification, not review - latex now slots in to the formatQA hook to render images in the q/a - moved call() to utils - cache/uncache latex have been obsoleted. User can delete manually, and images will be regenerated with a DB check --- anki/deck.py | 1 + anki/latex.py | 64 +++++++++++++++------------------------------------ anki/utils.py | 20 +++++++++++++++- 3 files changed, 39 insertions(+), 46 deletions(-) diff --git a/anki/deck.py b/anki/deck.py index 48f3c5632..33d9e2d06 100644 --- a/anki/deck.py +++ b/anki/deck.py @@ -28,6 +28,7 @@ from anki.hooks import runHook, hookEmpty from anki.template import render from anki.media import updateMediaCount, mediaFiles, \ rebuildMediaDir +import anki.latex # sets up hook # ensure all the DB metadata in other files is loaded before proceeding import anki.models, anki.facts, anki.cards, anki.stats diff --git a/anki/latex.py b/anki/latex.py index 1db827ff0..9c25ee739 100644 --- a/anki/latex.py +++ b/anki/latex.py @@ -8,8 +8,9 @@ Latex support """ __docformat__ = 'restructuredtext' -import re, tempfile, os, sys, subprocess, stat, time, shutil -from anki.utils import genID, checksum +import re, tempfile, os, sys, shutil, cgi +from anki.utils import genID, checksum, call +from anki.hooks import addHook from htmlentitydefs import entitydefs latexPreamble = ("\\documentclass[12pt]{article}\n" @@ -56,24 +57,6 @@ def stripLatex(text): text = text.replace(match.group(), "") return text -def call(argv, wait=True, **kwargs): - try: - o = subprocess.Popen(argv, **kwargs) - except OSError: - # command not found - return -1 - if wait: - while 1: - try: - ret = o.wait() - except OSError: - # interrupted system call - continue - break - else: - ret = 0 - return ret - def latexImgFile(deck, latexCode): key = checksum(latexCode) return "latex-%s.png" % key @@ -87,27 +70,6 @@ def mungeLatex(latex): latex = latex.encode("utf-8") return latex -def deleteAllLatexImages(deck): - mdir = deck.mediaDir() - if not mdir: - return - deck.startProgress() - for c, f in enumerate(os.listdir(mdir)): - if f.startswith("latex-"): - os.unlink(os.path.join(mdir, f)) - if c % 100 == 0: - deck.updateProgress() - deck.finishProgress() - -def cacheAllLatexImages(deck): - deck.startProgress() - fields = deck.s.column0("select value from fields") - for c, field in enumerate(fields): - if c % 10 == 0: - deck.updateProgress() - renderLatex(deck, field) - deck.finishProgress() - def buildImg(deck, latex): log = open(os.path.join(tmpdir, "latex_log.txt"), "w+") texpath = os.path.join(tmpdir, "tmp.tex") @@ -129,14 +91,20 @@ def buildImg(deck, latex): si = None try: os.chdir(tmpdir) - errmsg = _("Error executing %s.\n") + _( - "A log file is available here:\n%s") % tmpdir + def errmsg(type): + msg = _("Error executing %s.\n") % type + try: + log = open(os.path.join(tmpdir, "latex_log.txt")).read() + msg += "
" + cgi.escape(log) + "
" + except: + pass + return msg if call(["latex", "-interaction=nonstopmode", "tmp.tex"], stdout=log, stderr=log, startupinfo=si): - return (False, errmsg % "latex") + return (False, errmsg("latex")) if call(latexDviPngCmd + ["tmp.dvi", "-o", "tmp.png"], stdout=log, stderr=log, startupinfo=si): - return (False, errmsg % "dvipng") + return (False, errmsg("dvipng")) # add to media target = latexImgFile(deck, latex) shutil.copy2("tmp.png", os.path.join(deck.mediaDir(), target)) @@ -162,3 +130,9 @@ def imgLink(deck, latex, build=True): return '' % img else: return img + +def formatQA(html, type, cid, mid, fact, tags, cm, deck): + return renderLatex(deck, html) + +# setup q/a filter +addHook("formatQA", formatQA) diff --git a/anki/utils.py b/anki/utils.py index cd93845a5..7c3488d62 100644 --- a/anki/utils.py +++ b/anki/utils.py @@ -8,7 +8,7 @@ Miscellaneous utilities """ __docformat__ = 'restructuredtext' -import re, os, random, time, types, math, htmlentitydefs +import re, os, random, time, types, math, htmlentitydefs, subprocess try: import hashlib @@ -269,3 +269,21 @@ def deleteTags(tagstr, tags): def checksum(data): return md5(data).hexdigest() + +def call(argv, wait=True, **kwargs): + try: + o = subprocess.Popen(argv, **kwargs) + except OSError: + # command not found + return -1 + if wait: + while 1: + try: + ret = o.wait() + except OSError: + # interrupted system call + continue + break + else: + ret = 0 + return ret