| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
""" |
|---|
| 5 |
LaTeX-defined image support for Lore documents. |
|---|
| 6 |
""" |
|---|
| 7 |
|
|---|
| 8 |
import os, tempfile |
|---|
| 9 |
from xml.dom import minidom as dom |
|---|
| 10 |
|
|---|
| 11 |
from twisted.web import domhelpers |
|---|
| 12 |
import latex, tree, lint, default |
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
class MathLatexSpitter(latex.LatexSpitter): |
|---|
| 16 |
|
|---|
| 17 |
start_html = '\\documentclass{amsart}\n' |
|---|
| 18 |
|
|---|
| 19 |
def visitNode_div_latexmacros(self, node): |
|---|
| 20 |
self.writer(domhelpers.getNodeText(node)) |
|---|
| 21 |
|
|---|
| 22 |
def visitNode_span_latexformula(self, node): |
|---|
| 23 |
self.writer('\[') |
|---|
| 24 |
self.writer(domhelpers.getNodeText(node)) |
|---|
| 25 |
self.writer('\]') |
|---|
| 26 |
|
|---|
| 27 |
def formulaeToImages(document, dir, _system=os.system): |
|---|
| 28 |
|
|---|
| 29 |
macros = '' |
|---|
| 30 |
for node in domhelpers.findElementsWithAttribute(document, 'class', |
|---|
| 31 |
'latexmacros'): |
|---|
| 32 |
macros += domhelpers.getNodeText(node) |
|---|
| 33 |
node.parentNode.removeChild(node) |
|---|
| 34 |
i = 0 |
|---|
| 35 |
for node in domhelpers.findElementsWithAttribute(document, 'class', |
|---|
| 36 |
'latexformula'): |
|---|
| 37 |
latexText='''\\documentclass[12pt]{amsart}%s |
|---|
| 38 |
\\begin{document}\[%s\] |
|---|
| 39 |
\\end{document}''' % (macros, domhelpers.getNodeText(node)) |
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 |
file = tempfile.mktemp() |
|---|
| 43 |
f = open(file+'.tex', 'w') |
|---|
| 44 |
f.write(latexText) |
|---|
| 45 |
f.close() |
|---|
| 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) |
|---|
| 50 |
i += 1 |
|---|
| 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) |
|---|
| 57 |
|
|---|
| 58 |
|
|---|
| 59 |
def doFile(fn, docsdir, ext, url, templ, linkrel='', d=None): |
|---|
| 60 |
d = d or {} |
|---|
| 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')) |
|---|
| 66 |
|
|---|
| 67 |
|
|---|
| 68 |
class ProcessingFunctionFactory(default.ProcessingFunctionFactory): |
|---|
| 69 |
|
|---|
| 70 |
latexSpitters = {None: MathLatexSpitter} |
|---|
| 71 |
|
|---|
| 72 |
def getDoFile(self): |
|---|
| 73 |
return doFile |
|---|
| 74 |
|
|---|
| 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 |
|---|
| 82 |
x=='latexformula') |
|---|
| 83 |
return checker |
|---|
| 84 |
|
|---|
| 85 |
factory = ProcessingFunctionFactory() |
|---|