1 # Copyright (c) Twisted Matrix Laboratories.
2 # See LICENSE for details.
5 LaTeX-defined image support for Lore documents.
9 from xml.dom import minidom as dom
11 from twisted.web import domhelpers
12 import latex, tree, lint, default
15 class MathLatexSpitter(latex.LatexSpitter):
17 start_html = '\\documentclass{amsart}\n'
19 def visitNode_div_latexmacros(self, node):
20 self.writer(domhelpers.getNodeText(node))
22 def visitNode_span_latexformula(self, node):
24 self.writer(domhelpers.getNodeText(node))
27 def formulaeToImages(document, dir, _system=os.system):
30 for node in domhelpers.findElementsWithAttribute(document, 'class',
32 macros += domhelpers.getNodeText(node)
33 node.parentNode.removeChild(node)
35 for node in domhelpers.findElementsWithAttribute(document, 'class',
37 latexText='''\\documentclass[12pt]{amsart}%s
38 \\begin{document}\[%s\]
39 \\end{document}''' % (macros, domhelpers.getNodeText(node))
40 # This file really should be cleaned up by this function, or placed
41 # somewhere such that the calling code can find it and clean it up.
42 file = tempfile.mktemp()
43 f = open(file+'.tex', 'w')
46 _system('latex %s.tex' % file)
47 _system('dvips %s.dvi -o %s.ps' % (os.path.basename(file), file))
48 baseimgname = 'latexformula%d.png' % i
49 imgname = os.path.join(dir, baseimgname)
51 _system('pstoimg -type png -crop a -trans -interlace -out '
52 '%s %s.ps' % (imgname, file))
53 newNode = dom.parseString(
54 '<span><br /><img src="%s" /><br /></span>' % (
55 baseimgname,)).documentElement
56 node.parentNode.replaceChild(newNode, node)
59 def doFile(fn, docsdir, ext, url, templ, linkrel='', d=None):
61 doc = tree.parseFileAndReport(fn)
62 formulaeToImages(doc, os.path.dirname(fn))
63 cn = templ.cloneNode(1)
64 tree.munge(doc, cn, linkrel, docsdir, fn, ext, url, d)
65 cn.writexml(open(os.path.splitext(fn)[0]+ext, 'wb'))
68 class ProcessingFunctionFactory(default.ProcessingFunctionFactory):
70 latexSpitters = {None: MathLatexSpitter}
75 def getLintChecker(self):
76 checker = lint.getDefaultChecker()
77 checker.allowedClasses = checker.allowedClasses.copy()
78 oldDiv = checker.allowedClasses['div']
79 oldSpan = checker.allowedClasses['span']
80 checker.allowedClasses['div'] = lambda x:oldDiv(x) or x=='latexmacros'
81 checker.allowedClasses['span'] = (lambda x:oldSpan(x) or
85 factory = ProcessingFunctionFactory()