""" Replace Latex math mode/\\begin{}\\end{} blocks with html img tag after rendering $Id: ReplaceInlineLatex.py,v 1.11 2001/09/07 14:21:16 rsbowman Exp $ TODO: test a table/array use \\ref{shit} to make reference to equations. Convert \\ref{shit} to the appropriate (number): add negative match to latexPattern for \\ref, do a s/// after generating an equation with a \\label. Separate vertical alignment characters & into a new \\end{equation}\\begin{equation} and then render the separate images in a table to acheive vertical alignment. """ import re, os #from collections import deque from DocumentTemplate.html_quote import html_quote from util import fileNameFor, imagesPath, workingDir, getPngSize from string import strip, join, replace from latexWrapper import runCommand, log from ReplaceInlineAxiom import replaceInlineAxiom from ReplaceInlineReduce import replaceInlineReduce from ReplaceInlineMaxima import replaceInlineMaxima from ReplaceInlineHTML import replaceInlineHTML # This will fail on nested blocks \begin{array} \begin{array}...\end{array} \end{array} # It is necessary for this to be all one regex (unfortunately) so that we do # not pick up equations inside \begin{latex}...\end{latex}, rather only the # outer delimiters. #latexPattern = r'(? Some or all expressions may not have rendered properly, because Latex returned the following error:
%s
""" def findLatexCode(text): codeList = map(lambda x: x[0], latexPattern.findall(text)) return codeList def replaceInlineLatex(body, charheightpx, alignfudge, resfudge, latexTemplate=None): from latexWrapper import renderNonexistingImages global savePre savePre=[] reConsts = re.DOTALL+re.MULTILINE def hidePre(x): global savePre savePre.append(x.group(0)) return '
'

    def restorePre(x):
        global savePre
        first,savePre = savePre[0],savePre[1:]
        return first

    renumbered   = re.compile(r'[ \t]*\\begin{ *(math|equation|eqnarray) *}')
    reunnumbered = re.compile(r'[ \t]*(\\begin{ *((math|equation|eqnarray)\*|table|tabular|displaymath|array|latex) *}|\$\$)')
#    renumbered   = re.compile(r'\\begin{ *(math|equation|eqnarray) *}')
#    reunnumbered = re.compile(r'[ \t]*(\\begin{ *((math|equation|eqnarray)\*|table|tabular|displaymath|array|latex) *}|\\\[)')
    body = replaceInlineHTML(body) # do extended LaTeX to HTML conversions
    body = replaceInlineAxiom(body) # execute Axiom commands
    body = replaceInlineMaxima(body) # execute Maxima commands
    body = replaceInlineReduce(body) # execute Reduce commands
    # body = re.sub(r'.*?',hidePre,body,reConsts)
    latexCodeList = findLatexCode(body) # find the rest of the LaTeX
    newlatexCodeList = []
    eqnum = 0
    for code in latexCodeList:
        if code[0]=='!': 
# We need to identify if we're inside a '' block or an example:: block here.
            newcode = re.compile('^!', re.MULTILINE).sub('', code)
            # change the dollar sign so that the replace below does not hit
            # this code again (in the case of the same code appearing twice,
            # once escaped, once not)
            #newcode = re.compile('\$', re.MULTILINE).sub('$', newcode, 2)
            # prevent stx from mangling asterisks
            #newcode = re.compile('\*', re.MULTILINE).sub('*', newcode) 
            # and this will hide \(\), \[\], \begin...\end, including any
            # equations that may be hiding inside a \begin{latex}..\end{latex}
            newcode = re.compile(r'\\\[', re.MULTILINE).sub('\\![', newcode)
            #newcode = re.compile(r'\\', re.MULTILINE).sub('\', newcode)
            body = replace(body, code, newcode, 1)
            continue
        else:
            newlatexCodeList.append(code)
        oldcode = code
        renummatch = renumbered.match(code)
        if renummatch:
            eqnum = eqnum + 1
            code = renumbered.sub('\\\\begin{\\1*}\n\\label{eq%d}' %(eqnum), code, 1)
            kind = renummatch.group(1)
            code = re.compile('\\\\end{ *%s *}' %(kind)).sub('\\\\end{%s*}' %(kind), code, 1)
            code = renumbered.sub('\\\\begin{\\1*}\n\\label{eq%d}' %(eqnum), code, 1)
# FIXME we really shouldn't do this...it will recreate block equations with different numbers.
            newlatexCodeList[newlatexCodeList.index(oldcode)] = code
# FIXME This will also replace any escaped code :(
            body = replace(body, oldcode, code, 1)
    errors = renderNonexistingImages(newlatexCodeList, charheightpx, alignfudge, resfudge,
                                     latexTemplate=latexTemplate)
    
    if not errors:
        for code in newlatexCodeList:
            labelmatch = re.compile('\\\\label{eq(\\d+)}').search(code, 1)
            commentedcode = re.compile('^', re.MULTILINE).sub('!', html_quote(code))
# "--" inside a comment screws up browsers.  But in LaTeX math mode "--" and "- -" are equivalent.
            commentedcode = re.compile('--', re.MULTILINE).sub('- -', commentedcode)
            if labelmatch:
                eqnum = labelmatch.group(1)
                imageTag = '' %(eqnum)                           \
                    + '
' \ + getImageFor(code, charheightpx) \ + '(%s)
' %(eqnum) # + '\n\n' \ elif reunnumbered.match(code): imageTag = ''\ + '
' \ + getImageFor(code, charheightpx) \ + ' 
' # + '\n\n' \ else: imageTag = getImageFor(code, charheightpx) body = replace(body, code, imageTag, 1) # We try to match the > and < (or ^/$) from the preceeding and trailing tags, # so as not to catch the alt="..." from a latex equation # FIXME this is slow. Use something like perl's m/\G/g to iterate over (n) for i in range(1,int(eqnum)+1): body = re.compile(r'((?:>|^)(?:[^<]*\s|))\( *(?:[Ee][Qq]\.)?\s*(%d) *\)([^>]*(?:<|$))' %(i)).sub(r'\1(\2)\3', body) else: body = '
' + body + '
' + errorMessage %(errors) # Handle escaping of latex body = re.compile(r'(?',restorePre,body,reConsts) return body def getImageFor(latexCode, charheightpx): preamble, postamble = '', '' width, height = '', '' imageFile = fileNameFor(latexCode, charheightpx, '.png') imageUrl = imagesPath + imageFile width, height = getPngSize(os.path.join(workingDir, imageFile)) #src = html_quote(re.match(latexRemoveDelim, latexCode, re.MULTILINE|re.DOTALL). group(2)) src = 'LatexWiki Image' return '%s%s%s' %(preamble, src, imageUrl, width, height, postamble) #return '%s%s' %(preamble, # imageUrl, # width, # height, # postamble)