gave latex processing its own file, merged duplicate processing and

detection code
This commit is contained in:
Brendan Taylor 2009-01-09 19:55:26 +00:00
parent 9298312369
commit 898bc7c347
4 changed files with 153 additions and 152 deletions

View File

@ -83,7 +83,7 @@ class Cancelled(Exception):
pass pass
class LatexError(Exception): class LatexError(Exception):
'''sqlite2 raised pysqlite2.dbapi2.OperationalError''' '''LaTeX processing failed for some reason'''
def __init__(self, text=''): def __init__(self, text=''):
Exception.__init__(self) Exception.__init__(self)
self.text = text self.text = text

View File

@ -176,64 +176,8 @@ else:
if system('gpg -h >/dev/null 2>&1'): if system('gpg -h >/dev/null 2>&1'):
HAVE_GPG = False HAVE_GPG = False
import os import latex
import random HAVE_LATEX = latex.check_for_latex_support()
from tempfile import gettempdir
from subprocess import Popen
def check_for_latex_support():
'''check is latex is available and if it can create a picture.'''
exitcode = 0
random.seed()
tmpfile = os.path.join(gettempdir(), "gajimtex_" + \
random.randint(0,100).__str__())
# build latex string
texstr = '\\documentclass[12pt]{article}\\usepackage[dvips]{graphicx}'
texstr += '\\usepackage{amsmath}\\usepackage{amssymb}\\pagestyle{empty}'
texstr += '\\begin{document}\\begin{large}\\begin{gather*}test'
texstr += '\\end{gather*}\\end{large}\\end{document}'
file_ = open(os.path.join(tmpfile + ".tex"), "w+")
file_.write(texstr)
file_.flush()
file_.close()
try:
if os.name == 'nt':
# CREATE_NO_WINDOW
p = Popen(['latex', '--interaction=nonstopmode', tmpfile + '.tex'],
creationflags=0x08000000, cwd=gettempdir())
else:
p = Popen(['latex', '--interaction=nonstopmode', tmpfile + '.tex'],
cwd=gettempdir())
exitcode = p.wait()
except Exception:
exitcode = 1
if exitcode == 0:
try:
if os.name == 'nt':
# CREATE_NO_WINDOW
p = Popen(['dvipng', '-bg', 'white', '-T', 'tight',
tmpfile + '.dvi', '-o', tmpfile + '.png'],
creationflags=0x08000000, cwd=gettempdir())
else:
p = Popen(['dvipng', '-bg', 'white', '-T', 'tight',
tmpfile + '.dvi', '-o', tmpfile + '.png'], cwd=gettempdir())
exitcode = p.wait()
except Exception:
exitcode = 1
extensions = ['.tex', '.log', '.aux', '.dvi', '.png']
for ext in extensions:
try:
os.remove(tmpfile + ext)
except Exception:
pass
if exitcode == 0:
return True
return False
HAVE_LATEX = check_for_latex_support()
gajim_identity = {'type': 'pc', 'category': 'client', 'name': 'Gajim'} gajim_identity = {'type': 'pc', 'category': 'client', 'name': 'Gajim'}
gajim_common_features = [xmpp.NS_BYTESTREAM, xmpp.NS_SI, xmpp.NS_FILE, gajim_common_features = [xmpp.NS_BYTESTREAM, xmpp.NS_SI, xmpp.NS_FILE,

148
src/common/latex.py Normal file
View File

@ -0,0 +1,148 @@
# -*- coding:utf-8 -*-
## src/common/latex.py
##
## Copyright (C) 2005 Norman Rasmussen <norman AT rasmussen.co.za>
## Copyright (C) 2005-2006 Alex Mauer <hawke AT hawkesnest.net>
## Travis Shirk <travis AT pobox.com>
## Copyright (C) 2005-2007 Nikos Kouremenos <kourem AT gmail.com>
## Copyright (C) 2005-2008 Yann Leboulanger <asterix AT lagaule.org>
## Copyright (C) 2006 Dimitur Kirov <dkirov AT gmail.com>
## Copyright (C) 2006-2008 Jean-Marie Traissard <jim AT lapin.org>
## Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
## Julien Pivotto <roidelapluie AT gmail.com>
## Stephan Erb <steve-e AT h3c.de>
##
## This file is part of Gajim.
##
## Gajim is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 3 only.
##
## Gajim is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
##
import os
import random
from tempfile import gettempdir
from subprocess import Popen
import gajim
from exceptions import LatexError
# some latex commands are really bad
blacklist = ['\\def', '\\let', '\\futurelet',
'\\newcommand', '\\renewcomment', '\\else', '\\fi', '\\write',
'\\input', '\\include', '\\chardef', '\\catcode', '\\makeatletter',
'\\noexpand', '\\toksdef', '\\every', '\\errhelp', '\\errorstopmode',
'\\scrollmode', '\\nonstopmode', '\\batchmode', '\\read', '\\csname',
'\\newhelp', '\\relax', '\\afterground', '\\afterassignment',
'\\expandafter', '\\noexpand', '\\special', '\\command', '\\loop',
'\\repeat', '\\toks', '\\output', '\\line', '\\mathcode', '\\name',
'\\item', '\\section', '\\mbox', '\\DeclareRobustCommand', '\\[',
'\\]']
# True if the string matches the blacklist
def check_blacklist(str_):
for word in blacklist:
if word in str_:
return True
return False
def get_tmpfile_name():
random.seed()
int_ = random.randint(0, 100)
return os.path.join(gettempdir(), 'gajimtex_' + int_.__str__())
def write_latex(filename, str_):
texstr = '\\documentclass[12pt]{article}\\usepackage[dvips]{graphicx}'
texstr += '\\usepackage{amsmath}\\usepackage{amssymb}'
texstr += '\\pagestyle{empty}'
texstr += '\\begin{document}\\begin{large}\\begin{gather*}'
texstr += str_
texstr += '\\end{gather*}\\end{large}\\end{document}'
file_ = open(filename, "w+")
file_.write(texstr)
file_.flush()
file_.close()
# a wrapper for Popen so that no window gets opened on Windows
def popen_nt_friendly(command):
if os.name == 'nt':
# CREATE_NO_WINDOW
return Popen(command, creationflags=0x08000000, cwd=gettempdir())
else:
return Popen(command, cwd=gettempdir())
def check_for_latex_support():
'''check is latex is available and if it can create a picture.'''
try:
filename = latex_to_image("test")
if filename:
# we have a file, conversion succeeded
os.remove(filename)
return True
return False
except LatexError:
return False
def latex_to_image(str_):
result = None
exitcode = 0
# filter latex code with bad commands
if check_blacklist(str_):
# we triggered the blacklist, immediately return None
return None
tmpfile = get_tmpfile_name()
# build latex string
write_latex(os.path.join(tmpfile + '.tex'), str_)
# convert TeX to dvi
try:
p = popen_nt_friendly(['latex', '--interaction=nonstopmode',
tmpfile + '.tex'])
exitcode = p.wait()
except Exception, e:
exitcode = _('Error executing "%(command)s": %(error)s') % {
'command': 'latex --interaction=nonstopmode %s.tex' % tmpfile,
'error': str(e)}
if exitcode == 0:
# convert dvi to png
latex_png_dpi = gajim.config.get('latex_png_dpi')
try:
p = popen_nt_friendly(['dvipng', '-bg', 'rgb 1.0 1.0 1.0', '-T',
'tight', '-D', latex_png_dpi, tmpfile + '.dvi', '-o',
tmpfile + '.png'])
exitcode = p.wait()
except Exception, e:
exitcode = _('Error executing "%(command)s": %(error)s') % {
'command': 'dvipng -bg rgb 1.0 1.0 1.0 -T tight -D %s %s.dvi -o '
'%s.png' % (latex_png_dpi, tmpfile, tmpfile), 'error': str(e)}
# remove temp files created by us and TeX
extensions = ['.tex', '.log', '.aux', '.dvi']
for ext in extensions:
try:
os.remove(tmpfile + ext)
except Exception:
pass
if isinstance(exitcode, (unicode, str)):
raise LatexError(exitcode)
if exitcode == 0:
result = tmpfile + '.png'
return result
# vim: se ts=3:

View File

@ -27,9 +27,6 @@
## along with Gajim. If not, see <http://www.gnu.org/licenses/>. ## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
## ##
import random
from tempfile import gettempdir
from subprocess import Popen
from threading import Timer # for smooth scrolling from threading import Timer # for smooth scrolling
import gtk import gtk
@ -45,6 +42,7 @@ import Queue
import gtkgui_helpers import gtkgui_helpers
from common import gajim from common import gajim
from common import helpers from common import helpers
from common import latex
from calendar import timegm from calendar import timegm
from common.fuzzyclock import FuzzyClock from common.fuzzyclock import FuzzyClock
@ -959,95 +957,6 @@ class ConversationTextview:
return index # the position after *last* special text return index # the position after *last* special text
def latex_to_image(self, str_):
result = None
exitcode = 0
# some latex commands are really bad
blacklist = ['\\def', '\\let', '\\futurelet',
'\\newcommand', '\\renewcomment', '\\else', '\\fi', '\\write',
'\\input', '\\include', '\\chardef', '\\catcode', '\\makeatletter',
'\\noexpand', '\\toksdef', '\\every', '\\errhelp', '\\errorstopmode',
'\\scrollmode', '\\nonstopmode', '\\batchmode', '\\read', '\\csname',
'\\newhelp', '\\relax', '\\afterground', '\\afterassignment',
'\\expandafter', '\\noexpand', '\\special', '\\command', '\\loop',
'\\repeat', '\\toks', '\\output', '\\line', '\\mathcode', '\\name',
'\\item', '\\section', '\\mbox', '\\DeclareRobustCommand', '\\[',
'\\]']
str_ = str_[2:len(str_)-2]
# filter latex code with bad commands
for word in blacklist:
if word in str_:
exitcode = 1
break
if exitcode == 0:
random.seed()
tmpfile = os.path.join(gettempdir(), 'gajimtex_' + random.randint(0,
100).__str__())
# build latex string
texstr = '\\documentclass[12pt]{article}\\usepackage[dvips]{graphicx}'
texstr += '\\usepackage{amsmath}\\usepackage{amssymb}'
texstr += '\\pagestyle{empty}'
texstr += '\\begin{document}\\begin{large}\\begin{gather*}'
texstr += str_
texstr += '\\end{gather*}\\end{large}\\end{document}'
file_ = open(os.path.join(tmpfile + '.tex'), 'w+')
file_.write(texstr)
file_.flush()
file_.close()
try:
if os.name == 'nt':
# CREATE_NO_WINDOW
p = Popen(['latex', '--interaction=nonstopmode',
tmpfile + '.tex'], creationflags=0x08000000, cwd=gettempdir())
else:
p = Popen(['latex', '--interaction=nonstopmode',
tmpfile + '.tex'], cwd=gettempdir())
exitcode = p.wait()
except Exception, e:
exitcode = _('Error executing "%(command)s": %(error)s') % {
'command': 'latex --interaction=nonstopmode %s.tex' % tmpfile,
'error': str(e)}
if exitcode == 0:
latex_png_dpi = gajim.config.get('latex_png_dpi')
try:
if os.name == 'nt':
# CREATE_NO_WINDOW
p = Popen(['dvipng', '-bg', 'rgb 1.0 1.0 1.0', '-T', 'tight',
'-D', latex_png_dpi, tmpfile + '.dvi', '-o',
tmpfile + '.png'], creationflags=0x08000000, cwd=gettempdir())
else:
p = Popen(['dvipng', '-bg', 'rgb 1.0 1.0 1.0', '-T', 'tight',
'-D', latex_png_dpi, tmpfile + '.dvi', '-o',
tmpfile + '.png'], cwd=gettempdir())
exitcode = p.wait()
except Exception, e:
exitcode = _('Error executing "%(command)s": %(error)s') % {
'command': 'dvipng -bg rgb 1.0 1.0 1.0 -T tight -D %s %s.dvi -o '
'%s.png' % (latex_png_dpi, tmpfile, tmpfile), 'error': str(e)}
extensions = ['.tex', '.log', '.aux', '.dvi']
for ext in extensions:
try:
os.remove(tmpfile + ext)
except Exception:
pass
if isinstance(exitcode, (unicode, str)):
raise LatexError(exitcode)
if exitcode == 0:
result = tmpfile + '.png'
return result
def print_special_text(self, special_text, other_tags): def print_special_text(self, special_text, other_tags):
'''is called by detect_and_print_special_text and prints '''is called by detect_and_print_special_text and prints
special text (emots, links, formatting)''' special text (emots, links, formatting)'''
@ -1144,7 +1053,7 @@ class ConversationTextview:
elif gajim.HAVE_LATEX and special_text.startswith('$$') and \ elif gajim.HAVE_LATEX and special_text.startswith('$$') and \
special_text.endswith('$$'): special_text.endswith('$$'):
try: try:
imagepath = self.latex_to_image(special_text) imagepath = latex.latex_to_image(special_text[2:-2])
except LatexError, e: except LatexError, e:
# print the error after the line has been written # print the error after the line has been written
gobject.idle_add(self.print_conversation_line, str(e), '', 'info', gobject.idle_add(self.print_conversation_line, str(e), '', 'info',