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
This commit is contained in:
Damien Elmes 2010-12-11 01:40:49 +09:00
parent 0c9672e7b8
commit 4d2d9eab81
3 changed files with 39 additions and 46 deletions

View file

@ -28,6 +28,7 @@ from anki.hooks import runHook, hookEmpty
from anki.template import render from anki.template import render
from anki.media import updateMediaCount, mediaFiles, \ from anki.media import updateMediaCount, mediaFiles, \
rebuildMediaDir rebuildMediaDir
import anki.latex # sets up hook
# ensure all the DB metadata in other files is loaded before proceeding # ensure all the DB metadata in other files is loaded before proceeding
import anki.models, anki.facts, anki.cards, anki.stats import anki.models, anki.facts, anki.cards, anki.stats

View file

@ -8,8 +8,9 @@ Latex support
""" """
__docformat__ = 'restructuredtext' __docformat__ = 'restructuredtext'
import re, tempfile, os, sys, subprocess, stat, time, shutil import re, tempfile, os, sys, shutil, cgi
from anki.utils import genID, checksum from anki.utils import genID, checksum, call
from anki.hooks import addHook
from htmlentitydefs import entitydefs from htmlentitydefs import entitydefs
latexPreamble = ("\\documentclass[12pt]{article}\n" latexPreamble = ("\\documentclass[12pt]{article}\n"
@ -56,24 +57,6 @@ def stripLatex(text):
text = text.replace(match.group(), "") text = text.replace(match.group(), "")
return text 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): def latexImgFile(deck, latexCode):
key = checksum(latexCode) key = checksum(latexCode)
return "latex-%s.png" % key return "latex-%s.png" % key
@ -87,27 +70,6 @@ def mungeLatex(latex):
latex = latex.encode("utf-8") latex = latex.encode("utf-8")
return latex 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): def buildImg(deck, latex):
log = open(os.path.join(tmpdir, "latex_log.txt"), "w+") log = open(os.path.join(tmpdir, "latex_log.txt"), "w+")
texpath = os.path.join(tmpdir, "tmp.tex") texpath = os.path.join(tmpdir, "tmp.tex")
@ -129,14 +91,20 @@ def buildImg(deck, latex):
si = None si = None
try: try:
os.chdir(tmpdir) os.chdir(tmpdir)
errmsg = _("Error executing %s.\n") + _( def errmsg(type):
"A log file is available here:\n%s") % tmpdir 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:
pass
return msg
if call(["latex", "-interaction=nonstopmode", if call(["latex", "-interaction=nonstopmode",
"tmp.tex"], stdout=log, stderr=log, startupinfo=si): "tmp.tex"], stdout=log, stderr=log, startupinfo=si):
return (False, errmsg % "latex") return (False, errmsg("latex"))
if call(latexDviPngCmd + ["tmp.dvi", "-o", "tmp.png"], if call(latexDviPngCmd + ["tmp.dvi", "-o", "tmp.png"],
stdout=log, stderr=log, startupinfo=si): stdout=log, stderr=log, startupinfo=si):
return (False, errmsg % "dvipng") return (False, errmsg("dvipng"))
# add to media # add to media
target = latexImgFile(deck, latex) target = latexImgFile(deck, latex)
shutil.copy2("tmp.png", os.path.join(deck.mediaDir(), target)) shutil.copy2("tmp.png", os.path.join(deck.mediaDir(), target))
@ -162,3 +130,9 @@ def imgLink(deck, latex, build=True):
return '<img src="%s">' % img return '<img src="%s">' % img
else: else:
return img return img
def formatQA(html, type, cid, mid, fact, tags, cm, deck):
return renderLatex(deck, html)
# setup q/a filter
addHook("formatQA", formatQA)

View file

@ -8,7 +8,7 @@ Miscellaneous utilities
""" """
__docformat__ = 'restructuredtext' __docformat__ = 'restructuredtext'
import re, os, random, time, types, math, htmlentitydefs import re, os, random, time, types, math, htmlentitydefs, subprocess
try: try:
import hashlib import hashlib
@ -269,3 +269,21 @@ def deleteTags(tagstr, tags):
def checksum(data): def checksum(data):
return md5(data).hexdigest() 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