def transform(self, dom):
        # Currency
        for currencyNode in dom.xpath("//currency"):
            latexMode = utils.etree_in_context(currencyNode, "latex")
            symbolNode = currencyNode.find("symbol")
            if symbolNode is None:
                symbol = "R"
                symbolLocation = "front"
            else:
                symbol = symbolNode.text.strip()
                symbolLocation = symbolNode.attrib.get("location", "front")
            numberNode = currencyNode.find("number")
            if numberNode.text is None:
                numberNode.text = ""
            # Set default precision to 0 if number is an int, and to 2 if it is a float
            try:
                int(numberNode.text.strip())
                defaultPrecision = 0
            except ValueError:
                defaultPrecision = 2
            currencyPrecision = int(currencyNode.attrib.get("precision", defaultPrecision))
            numberNode.text = ("%%.%if" % currencyPrecision) % float(numberNode.text.strip())

            replacementNode = etree.Element("dummy")
            if symbolLocation == "front":
                if latexMode:
                    replacementNode.text = r"\text{" + symbol + " }"
                else:
                    replacementNode.text = symbol + u"\u00a0"
                replacementNode.append(numberNode)
            else:
                replacementNode.append(numberNode)
                if latexMode:
                    replacementNode.tail = r"\text{ " + symbol + "}"
                else:
                    replacementNode.tail = u"\u00a0" + symbol
            utils.etree_replace_with_node_list(currencyNode.getparent(), currencyNode, replacementNode)

        # Percentage
        for percentageNode in dom.xpath("//percentage"):
            latexMode = utils.etree_in_context(percentageNode, "latex")
            percentageNode.tag = "number"
            if percentageNode.tail is None:
                percentageNode.tail = ""
            if latexMode:
                percentageNode.tail = r"\%" + percentageNode.tail
            else:
                percentageNode.tail = "%" + percentageNode.tail

        # United numbers: ensure that units follow numbers
        for node in dom.xpath("//unit_number"):
            if (len(node) == 2) and (node[0].tag == "unit") and (node[1].tag == "number"):
                unitNode = node[0]
                numberNode = node[1]
                del node[0]
                del node[0]
                node.append(numberNode)
                node.append(unitNode)

        # Numbers
        for numberNode in dom.xpath("//number"):
            # Avoid shortcode exercise numbers
            if (numberNode.getparent().tag == "entry") and (numberNode.getparent().getparent().tag == "shortcodes"):
                continue
            latexMode = utils.etree_in_context(numberNode, "latex")
            if (len(numberNode) == 0) and ("e" in numberNode.text):
                # Number in exponential notation: convert to <coeff> and <exp>
                numberText = numberNode.text
                float(numberText)  # Check that it is really a float
                numberNode.text = None
                numberNode.append(etree.Element("coeff"))
                pos = numberText.find("e")
                numberNode[-1].text = numberText[:pos]
                numberNode.append(etree.Element("exp"))
                numberNode[-1].text = str(int(numberText[pos + 1 :]))

            if len(numberNode) == 0:
                # No children, means it's just a plain number
                coeffText = utils.format_number(numberNode.text.strip())
                try:
                    if latexMode:
                        dummyNode = etree.fromstring(r"<dummy>\text{" + coeffText + "}</dummy>")
                    else:
                        dummyNode = etree.fromstring("<dummy>" + coeffText + "</dummy>")
                except etree.XMLSyntaxError, msg:
                    print repr(coeffText)
                    raise etree.XMLSyntaxError, msg
            else:
                # Scientific or exponential notation: parse out coefficient, base and exponent
                coeffNode = numberNode.find("coeff")
                expNode = numberNode.find("exp")
                baseNode = numberNode.find("base")
                if coeffNode is None:
                    # Exponential
                    if baseNode is None:
                        baseText = utils.format_number("10")
                    else:
                        baseText = utils.format_number(baseNode.text.strip())
                    assert expNode is not None, etree.tostring(numberNode)
                    expText = utils.format_number(expNode.text.strip())
                    if latexMode:
                        dummyNode = etree.fromstring(
                            r"<dummy>\text{" + baseText + r"}^{\text{" + expText + r"}}</dummy>"
                        )
                    else:
                        dummyNode = etree.fromstring("<dummy>" + baseText + "<sup>" + expText + "</sup></dummy>")
                else:
                    # Scientific notation or plain number (<coeff> only)
                    coeffText = utils.format_number(coeffNode.text.strip())
                    if expNode is None:
                        assert baseNode is None
                        try:
                            if latexMode:
                                dummyNode = etree.fromstring(r"<dummy>\text{" + coeffText + "}</dummy>")
                            else:
                                dummyNode = etree.fromstring("<dummy>" + coeffText + "</dummy>")
                        except etree.XMLSyntaxError, msg:
                            print repr(coeffText)
                            raise etree.XMLSyntaxError, msg
                    else:
                        if baseNode is None:
    def transform(self, dom):
        # Currency
        for currencyNode in dom.xpath('//currency'):
            latexMode = utils.etree_in_context(currencyNode, 'latex')
            symbolNode = currencyNode.find('symbol')
            if symbolNode is None:
                symbol = 'R'
                symbolLocation = 'front'
            else:
                symbol = symbolNode.text.strip()
                symbolLocation = symbolNode.attrib.get('location', 'front')
            numberNode = currencyNode.find('number')
            if numberNode.text is None:
                numberNode.text = ''
            # Set default precision to 0 if number is an int, and to 2 if it is a float
            try:
                int(numberNode.text.strip())
                defaultPrecision = 0
            except ValueError:
                defaultPrecision = 2
            currencyPrecision = int(currencyNode.attrib.get('precision', defaultPrecision))
            numberNode.text = ("%%.%if"%currencyPrecision)%float(numberNode.text.strip())

            replacementNode = etree.Element('dummy')
            if symbolLocation == 'front':
                if latexMode:
                    replacementNode.text = r'\text{' + symbol + ' }'
                else:
                    replacementNode.text = symbol + u'\u00a0'
                replacementNode.append(numberNode)
            else:
                replacementNode.append(numberNode)
                if latexMode:
                    replacementNode.tail = r'\text{ ' + symbol + '}'
                else:
                    replacementNode.tail = u'\u00a0' + symbol
            utils.etree_replace_with_node_list(currencyNode.getparent(), currencyNode, replacementNode)

        # Percentage
        for percentageNode in dom.xpath('//percentage'):
            latexMode = utils.etree_in_context(percentageNode, 'latex')
            percentageNode.tag = 'number'
            if percentageNode.tail is None:
                percentageNode.tail = ''
            if latexMode:
                percentageNode.tail = r'\%' + percentageNode.tail
            else:
                percentageNode.tail = '%' + percentageNode.tail

        # United numbers: ensure that units follow numbers
        for node in dom.xpath('//unit_number'):
            if (len(node) == 2) and (node[0].tag == 'unit') and (node[1].tag == 'number'):
                unitNode = node[0]
                numberNode = node[1]
                del node[0]
                del node[0]
                node.append(numberNode)
                node.append(unitNode)

        # Numbers
        for numberNode in dom.xpath('//number'):
            # Avoid shortcode exercise numbers
            if (numberNode.getparent().tag == 'entry') and (numberNode.getparent().getparent().tag == 'shortcodes'):
                continue
            latexMode = utils.etree_in_context(numberNode, 'latex')
            if (len(numberNode) == 0) and ('e' in numberNode.text):
                # Number in exponential notation: convert to <coeff> and <exp>
                numberText = numberNode.text
                float(numberText) # Check that it is really a float
                numberNode.text = None
                numberNode.append(etree.Element('coeff'))
                pos = numberText.find('e')
                numberNode[-1].text = numberText[:pos]
                numberNode.append(etree.Element('exp'))
                numberNode[-1].text = str(int(numberText[pos+1:]))

            if len(numberNode) == 0:
                # No children, means it's just a plain number
                coeffText = utils.format_number(numberNode.text.strip())
                try:
                    if latexMode:
                        dummyNode = etree.fromstring(r'<dummy>\text{' + coeffText + '}</dummy>')
                    else:
                        dummyNode = etree.fromstring('<dummy>' + coeffText + '</dummy>')
                except etree.XMLSyntaxError, msg:
                    print repr(coeffText)
                    raise etree.XMLSyntaxError, msg
            else:
                # Scientific or exponential notation: parse out coefficient, base and exponent
                coeffNode = numberNode.find('coeff')
                expNode = numberNode.find('exp')
                baseNode = numberNode.find('base')
                if coeffNode is None:
                    # Exponential
                    if baseNode is None:
                        baseText = utils.format_number('10')
                    else:
                        baseText = utils.format_number(baseNode.text.strip())
                    assert expNode is not None, etree.tostring(numberNode)
                    expText = utils.format_number(expNode.text.strip())
                    if latexMode:
                        dummyNode = etree.fromstring(r'<dummy>\text{' + baseText + r'}^{\text{' + expText + r'}}</dummy>')
                    else:
                        dummyNode = etree.fromstring('<dummy>' + baseText + '<sup>' + expText + '</sup></dummy>')
                else:
                    # Scientific notation or plain number (<coeff> only)
                    coeffText = utils.format_number(coeffNode.text.strip())
                    if expNode is None:
                        assert baseNode is None
                        try:
                            if latexMode:
                                dummyNode = etree.fromstring(r'<dummy>\text{' + coeffText + '}</dummy>')
                            else:
                                dummyNode = etree.fromstring('<dummy>' + coeffText + '</dummy>')
                        except etree.XMLSyntaxError, msg:
                            print repr(coeffText)
                            raise etree.XMLSyntaxError, msg
                    else:
                        if baseNode is None:
                                + coeffText
                                + r" } &#215; \text{ "
                                + baseText
                                + r"}^{\text{"
                                + expText
                                + r"}}</dummy>"
                            )
                        else:
                            dummyNode = etree.fromstring(
                                "<dummy>" + coeffText + " &#215; " + baseText + "<sup>" + expText + "</sup></dummy>"
                            )
            utils.etree_replace_with_node_list(numberNode.getparent(), numberNode, dummyNode)

        # Units
        for unitNode in dom.xpath("//unit"):
            latexMode = utils.etree_in_context(unitNode, "latex")
            if unitNode.text is None:
                unitNode.text = ""
            unitNode.text = unitNode.text.lstrip()
            if latexMode:
                unitNode.text = r"\text{" + unitNode.text
            if len(unitNode) == 0:
                unitNode.text = unitNode.text.rstrip()
                if latexMode:
                    unitNode.text += "}"
            else:
                if unitNode[-1].tail is None:
                    unitNode[-1].tail = ""
                unitNode[-1].tail = unitNode[-1].tail.rstrip()
                if latexMode:
                    unitNode[-1].tail += "}"
                            raise etree.XMLSyntaxError, msg
                    else:
                        if baseNode is None:
                            baseText = utils.format_number('10')
                        else:
                            baseText = utils.format_number(baseNode.text.strip())
                        expText = utils.format_number(expNode.text.strip())
                        if latexMode:
                            dummyNode = etree.fromstring(r'<dummy>\text{' + coeffText + r' } &#215; \text{ ' + baseText + r'}^{\text{' + expText + r'}}</dummy>')
                        else:
                            dummyNode = etree.fromstring('<dummy>' + coeffText + ' &#215; ' + baseText + '<sup>' + expText + '</sup></dummy>')
            utils.etree_replace_with_node_list(numberNode.getparent(), numberNode, dummyNode)

        # Units
        for unitNode in dom.xpath('//unit'):
            latexMode = utils.etree_in_context(unitNode, 'latex')
            if unitNode.text is None:
                unitNode.text = ''
            unitNode.text = unitNode.text.lstrip()
            if latexMode:
                unitNode.text = r'\text{' + unitNode.text
            if len(unitNode) == 0:
                unitNode.text = unitNode.text.rstrip()
                if latexMode:
                    unitNode.text += '}'
            else:
                if unitNode[-1].tail is None:
                    unitNode[-1].tail = ''
                unitNode[-1].tail = unitNode[-1].tail.rstrip()
                if latexMode:
                    unitNode[-1].tail += '}'