'Pre-process presentation MathML from ASCIIMathML to make it more
acceptable for SnuggleTeX, and also to accomodate some sympy
conventions (eg hat(i) for \hat{i}).
This method would be a good spot to look for an integral and convert
it, if possible...'

def preprocess_pmathml(self, xml):

    if isinstance(xml, (str, unicode)):
        xml = etree.fromstring(xml)
    xml = self.fix_greek_in_mathml(xml)
    def gettag(expr):
        return re.sub('{http://[^}]+}', '', expr.tag)
    def fix_pmathml(xml):
        '\n                                                f    and    g    are    processed    as    functions    by    asciimathml,    eg    "f-2"    turns\n                                                into    "<mrow><mi>f</mi><mo>-</mo></mrow><mn>2</mn>"    this    is\n                                                really    terrible    for    turning    into    cmathml.        undo    this    here.\n                                                '
        for k in xml:
            tag = gettag(k)
            if (tag == 'mrow'):
                if (len(k) == 2):
                    if ((gettag(k[0]) == 'mi') and (k[0].text in ['f', 'g']) and (gettag(k[1]) == 'mo')):
                        idx = xml.index(k)
                        xml.insert(idx, deepcopy(k[0]))
                        xml.insert((idx + 1), deepcopy(k[1]))
                        xml.remove(k)
            fix_pmathml(k)
    fix_pmathml(xml)
    def fix_hat(xml):
        '\n                                                hat    i    is    turned    into    <mover><mi>i</mi><mo>^</mo></mover>    ;    mangle\n                                                this    into    <mi>hat(f)</mi>    hat    i    also    somtimes    turned    into\n                                                <mover><mrow>    <mi>j</mi>    </mrow><mo>^</mo></mover>\n                                                '
        for k in xml:
            tag = gettag(k)
            if (tag == 'mover'):
                if (len(k) == 2):
                    if ((gettag(k[0]) == 'mi') and (gettag(k[1]) == 'mo') and (str(k[1].text) == '^')):
                        newk = etree.Element('mi')
                        newk.text = ('hat(%s)' % k[0].text)
                        xml.replace(k, newk)
                    if ((gettag(k[0]) == 'mrow') and (gettag(k[0][0]) == 'mi') and (gettag(k[1]) == 'mo') and (str(k[1].text) == '^')):
                        newk = etree.Element('mi')
                        newk.text = ('hat(%s)' % k[0][0].text)
                        xml.replace(k, newk)
            fix_hat(k)
    fix_hat(xml)
    def flatten_pmathml(xml):
        "\n                                                Give    the    text    version    of    certain    PMathML    elements\n\n                                                Sometimes    MathML    will    be    given    with    each    letter    separated    (it\n                                                doesn't    know    if    its    implicit    multiplication    or    what).    From    an    xml\n                                                node,    find    the    (text    only)    variable    name    it    represents.    So    it    takes\n                                                <mrow>\n                                                        <mi>m</mi>\n                                                        <mi>a</mi>\n                                                        <mi>x</mi>\n                                                </mrow>\n                                                and    returns    'max',    for    easier    use    later    on.\n                                                "
        tag = gettag(xml)
        if (tag == 'mn'):
            return xml.text
        elif (tag == 'mi'):
            return xml.text
        elif (tag == 'mrow'):
            return ''.join([flatten_pmathml(y) for y in xml])
        raise Exception(('[flatten_pmathml]    unknown    tag    %s' % tag))
    def fix_mathvariant(parent):
        '\n                                                Fix    certain    kinds    of    math    variants\n\n                                                Literally    replace    <mstyle    mathvariant="script"><mi>N</mi></mstyle>\n                                                with    \'scriptN\'.    There    have    been    problems    using    script_N    or    script(N)\n                                                '
        for child in parent:
            if ((gettag(child) == 'mstyle') and (child.get('mathvariant') == 'script')):
                newchild = etree.Element('mi')
                newchild.text = ('script%s' % flatten_pmathml(child[0]))
                parent.replace(child, newchild)
            fix_mathvariant(child)
    fix_mathvariant(xml)
    def fix_superscripts(xml):
        "    Look    for    and    replace    sup    elements    with    'X__Y'    or    'X_Y__Z'\n\n                                                In    the    javascript,    variables    with    '__X'    in    them    had    an    invisible\n                                                character    inserted    into    the    sup    (to    distinguish    from    powers)\n                                                E.g.    normal:\n                                                <msubsup>\n                                                        <mi>a</mi>\n                                                        <mi>b</mi>\n                                                        <mi>c</mi>\n                                                </msubsup>\n                                                to    be    interpreted    '(a_b)^c'    (nothing    done    by    this    method)\n\n                                                And    modified:\n                                                <msubsup>\n                                                        <mi>b</mi>\n                                                        <mi>x</mi>\n                                                        <mrow>\n                                                                <mo>&#x200B;</mo>\n                                                                <mi>d</mi>\n                                                        </mrow>\n                                                </msubsup>\n                                                to    be    interpreted    'a_b__c'\n\n                                                also:\n                                                <msup>\n                                                        <mi>x</mi>\n                                                        <mrow>\n                                                                <mo>&#x200B;</mo>\n                                                                <mi>B</mi>\n                                                        </mrow>\n                                                </msup>\n                                                to    be    'x__B'\n                                                "
        for k in xml:
            tag = gettag(k)
            if ((tag == 'msup') and (len(k) == 2) and (gettag(k[1]) == 'mrow') and (gettag(k[1][0]) == 'mo') and (k[1][0].text == u'\u200b')):
                k[1].remove(k[1][0])
                newk = etree.Element('mi')
                newk.text = ('%s__%s' % (flatten_pmathml(k[0]), flatten_pmathml(k[1])))
                xml.replace(k, newk)
            if ((tag == 'msubsup') and (len(k) == 3) and (gettag(k[2]) == 'mrow') and (gettag(k[2][0]) == 'mo') and (k[2][0].text == u'\u200b')):
                k[2].remove(k[2][0])
                newk = etree.Element('mi')
                newk.text = ('%s_%s__%s' % (flatten_pmathml(k[0]), flatten_pmathml(k[1]), flatten_pmathml(k[2])))
                xml.replace(k, newk)
            fix_superscripts(k)
    fix_superscripts(xml)
    def fix_msubsup(parent):
        '\n                                                Snuggle    returns    an    error    when    it    sees    an    <msubsup>    replace    such\n                                                elements    with    an    <msup>,    except    the    first    element    is    of\n                                                the    form    a_b.    I.e.    map    a_b^c    =>    (a_b)^c\n                                                '
        for child in parent:
            if ((gettag(child) == 'msubsup') and (len(child) == 3)):
                newchild = etree.Element('msup')
                newbase = etree.Element('mi')
                newbase.text = ('%s_%s' % (flatten_pmathml(child[0]), flatten_pmathml(child[1])))
                newexp = child[2]
                newchild.append(newbase)
                newchild.append(newexp)
                parent.replace(child, newchild)
            fix_msubsup(child)
    fix_msubsup(xml)
    self.xml = xml
    return self.xml
