summaryrefslogtreecommitdiffstats
path: root/equations/signals.py
diff options
context:
space:
mode:
Diffstat (limited to 'equations/signals.py')
-rw-r--r--equations/signals.py65
1 files changed, 65 insertions, 0 deletions
diff --git a/equations/signals.py b/equations/signals.py
new file mode 100644
index 0000000..0fecc34
--- /dev/null
+++ b/equations/signals.py
@@ -0,0 +1,65 @@
+from django.conf import settings
+
+def update_render(sender, instance, signal, *args, **kwargs):
+ """Renders an object's .png representation using LaTeX and puts it
+ in the right directory. Requires latex, dvipng, etc"""
+ import os, shutil, tempfile, subprocess
+ def call_command_in_dir(app, args, targetdir):
+ cwd = os.getcwd()
+ try:
+ os.chdir(targetdir)
+ p = subprocess.Popen(app + ' ' + ' '.join(args), shell=True)
+ sts = os.waitpid(p.pid, 0)
+ # FIXME -- should we raise an exception of status is non-zero?
+ finally:
+ # Restore working directory
+ os.chdir(cwd)
+
+ rawlatex = instance.latex
+ dstdir = settings.MEDIA_ROOT + instance.renderdir
+ dstfile = "%s.png" % instance.id
+ dst = "%s" % instance.id
+
+ prologue = ""
+ latex_template = r'''
+ \documentclass[12pt]{article}
+ \pagestyle{empty}
+ %(prologue)s
+ \begin{document}
+ $$%(raw)s$$
+ \end{document}
+ '''
+ max_pages = 1
+ MAX_RUN_TIME = 5 # seconds
+ latex = "latex"
+ dvipng = "dvipng"
+ latex_args = ("--interaction=nonstopmode", "%s.tex")
+ dvipng_args = ("-q", "-bgTransparent", "-Ttight", "--noghostscript",
+ "-l%s" % max_pages, "%s.dvi")
+ tex = latex_template % { 'raw': rawlatex, 'prologue': prologue }
+
+ tmpdir = tempfile.mkdtemp()
+ try:
+ data = open("%s/%s.tex" % (tmpdir, dst), "w")
+ data.write(tex)
+ data.close()
+ args = list(latex_args)
+ args[-1] = args[-1] % dst
+ res = call_command_in_dir(latex, args, tmpdir)
+ if not res is None:
+ # FIXME need to return some sort of error
+ return []
+ args = list(dvipng_args)
+ args[-1] = args[-1] % dst
+ res = call_command_in_dir(dvipng, args, tmpdir)
+ if not res is None:
+ # FIXME need to return some sort of error
+ return []
+
+ if os.access("%s/%s1.png" % (tmpdir, dst), os.R_OK):
+ shutil.copyfile("%s/%s1.png" % (tmpdir, dst),
+ dstdir + dstfile)
+ finally:
+ # FIXME do some tidy up here
+ instance.render = instance.renderdir + dstfile
+ shutil.rmtree(tmpdir)