Пример #1
0
    def handle_typedef_table(self, table, tpm_alg_ids):
        table_dependence = utils.find_alg_constraints(table.short_name)
        if table_dependence:  # if table dependence {*} found in table name
            self.tpm_types_h_file_content += "#ifdef      TPM_ALG_" + table_dependence + "\n"

        for row in table.rows:
            base_type = row[0]
            name = row[1]

            # check for !ALG
            alg_ids_list = utils.expand_alg_macro(name, tpm_alg_ids,
                                                  table_dependence)
            # if new type name contains algorithm type, create type definition for all corresponding IDs
            if alg_ids_list:
                for alg in alg_ids_list:
                    new_type = utils.replace_alg_placeholder(
                        name, alg.short_name)
                    self.tpm_types_h_file_content += "typedef  " + base_type + utils.indent(
                        base_type) + new_type + ";\n"
            else:  # else create type definition for table name
                self.tpm_types_h_file_content += "typedef  " + base_type + utils.indent(
                    base_type) + name + ";\n"
        # end of loop - for row in table.rows:

        if table_dependence:  # if table dependence {*} found in table name
            self.tpm_types_h_file_content += "#endif   // TPM_ALG_" + table_dependence + "\n"
        # end of if else - if table dependence found

        self.marshaller.handle_simple_type_structures_new(table, tpm_alg_ids)
    def handle_typedef_union_struct(self, table, typedef_name):
        self.tpm_types_h_file_content += "typedef union {\n"
        self.tpm_types_h_file_content += "    struct {\n"

        for row in table.rows:
            parameter = row[0].replace("=", "")
            member_type = row[1].replace("+", "")

            if "#" in parameter:
                continue

            # find constraints and remove them if found
            constraints = utils.find_alg_constraints(parameter)
            if constraints:
                parameter = parameter.replace("{" + constraints + "}", "").replace(" ", "")
                constraints = constraints.replace(":", "")

            # find array size and include it in typedef struct if found
            size = utils.find_array_size(parameter)
            if size:
                parameter = parameter.replace(size, "")
                self.tpm_types_h_file_content += "        " + member_type + utils.indent(member_type, 1) + \
                                                 parameter + "[" + constraints.strip() + "]" + ";\n"
            else:
                self.tpm_types_h_file_content += "        " + member_type + utils.indent(member_type, 1) + \
                                                 parameter + ";\n"
        # end of loop - for row in table.rows:

        self.tpm_types_h_file_content += "    }            t;\n"
        self.tpm_types_h_file_content += "    " + "TPM2B" + "        b;\n"
        self.tpm_types_h_file_content += "} " + typedef_name + ";\n"

        self.marshaller.handle_structures_table(typedef_name, table)
Пример #3
0
    def handle_typedef_union_struct(self, table, typedef_name):
        self.tpm_types_h_file_content += "typedef union {\n"
        self.tpm_types_h_file_content += "    struct {\n"

        for row in table.rows:
            parameter = row[0].replace("=", "")
            member_type = row[1].replace("+", "")

            if "#" in parameter:
                continue

            # find constraints and remove them if found
            constraints = utils.find_alg_constraints(parameter)
            if constraints:
                parameter = parameter.replace("{" + constraints + "}",
                                              "").replace(" ", "")
                constraints = constraints.replace(":", "")

            # find array size and include it in typedef struct if found
            size = utils.find_array_size(parameter)
            if size:
                parameter = parameter.replace(size, "")
                self.tpm_types_h_file_content += "        " + member_type + utils.indent(member_type, 1) + \
                                                 parameter + "[" + constraints.strip() + "]" + ";\n"
            else:
                self.tpm_types_h_file_content += "        " + member_type + utils.indent(member_type, 1) + \
                                                 parameter + ";\n"
        # end of loop - for row in table.rows:

        self.tpm_types_h_file_content += "    }            t;\n"
        self.tpm_types_h_file_content += "    " + "TPM2B" + "        b;\n"
        self.tpm_types_h_file_content += "} " + typedef_name + ";\n"

        self.marshaller.handle_structures_table(typedef_name, table)
    def handle_typedef_table(self, table, tpm_alg_ids):
        table_dependence = utils.find_alg_constraints(table.short_name)
        if table_dependence:  # if table dependence {*} found in table name
            self.tpm_types_h_file_content += "#ifdef      TPM_ALG_" + table_dependence + "\n"

        for row in table.rows:
            base_type = row[0]
            name = row[1]

            # check for !ALG
            alg_ids_list = utils.expand_alg_macro(name, tpm_alg_ids, table_dependence)
            # if new type name contains algorithm type, create type definition for all corresponding IDs
            if alg_ids_list:
                for alg in alg_ids_list:
                    new_type = utils.replace_alg_placeholder(name, alg.short_name)
                    self.tpm_types_h_file_content += "typedef  " + base_type + utils.indent(base_type) + new_type + ";\n"
            else:  # else create type definition for table name
                self.tpm_types_h_file_content += "typedef  " + base_type + utils.indent(base_type) + name + ";\n"
        # end of loop - for row in table.rows:

        if table_dependence:  # if table dependence {*} found in table name
            self.tpm_types_h_file_content += "#endif   // TPM_ALG_" + table_dependence + "\n"
        # end of if else - if table dependence found

        self.marshaller.handle_simple_type_structures_new(table, tpm_alg_ids)
Пример #5
0
    def handle_enum_table(self, table):
        base_type = utils.find_tpm_base_type_name(table.short_name)
        new_type = utils.find_tpm_type_name(table.short_name)

        self.tpm_types_h_file_content += "typedef  " + base_type + utils.indent(
            base_type) + new_type + ";\n"

        for row in table.rows:
            name = row[0]
            value = row[1].replace(" ", "")

            if name is u'' or "reserved" in name or "#" in name:  # skip those lines
                continue

            # write the define statement
            self.tpm_types_h_file_content += "#define  " + name + utils.indent(
                name) + "(" + new_type + ")(" + value + ")\n"

            # additionally write the TPM_RCS_* define
            if "RC_FMT1+" in value:
                name = name.replace("TPM_RC_", "TPM_RCS_")
                self.tpm_types_h_file_content += "#define  " + name + utils.indent(
                    name) + "(" + new_type + ")(" + value + ")\n"
        # end of loop - for row in table.rows:

        self.marshaller.handle_advanced_type_structures(table)
    def handle_interface_table(self, table, tpm_alg_ids):
        base_type = utils.find_tpm_base_type_name(table.short_name)
        new_type = utils.find_tpm_type_name(table.short_name)

        typedef_statement = "typedef  " + base_type + utils.indent(base_type) + new_type + ";\n"
        alg_dep = utils.find_alg_constraints(table.name)
        if alg_dep:
            alg_name = "TPM_ALG_" + alg_dep
            typedef_statement_alg_dep = ""

            # check for !ALG
            alg_ids_list = utils.expand_alg_macro(new_type, tpm_alg_ids, alg_dep)
            # if new type name contains algorithm type, create type definition for all corresponding IDs
            for alg in alg_ids_list:
                alg_name = alg.name
                final_new_type = utils.replace_alg_placeholder(new_type, alg.short_name)
                typedef_statement_alg_dep += "#ifdef      " + alg_name + "\n"  # for each algorithm
                typedef_statement_alg_dep += "typedef  " + base_type + utils.indent(base_type) + final_new_type + ";\n"
                typedef_statement_alg_dep += "#endif   // " + alg_name + "\n"  # for each algorithm

            # in case there is no !ALG, create type definition for type found in table name
            if not typedef_statement_alg_dep:
                typedef_statement_alg_dep = "#ifdef      " + alg_name + "\n"
                typedef_statement_alg_dep += "typedef  " + base_type + utils.indent(base_type) + new_type + ";\n"
                typedef_statement_alg_dep += "#endif   // " + alg_name + "\n"

            typedef_statement = typedef_statement_alg_dep

        self.tpm_types_h_file_content += typedef_statement

        self.marshaller.handle_interface_table(table, tpm_alg_ids)
Пример #7
0
    def write_buff_to_xml(self, filename):
        d = os.path.dirname(filename)
        if not os.path.exists(d):
            os.makedirs(d)

        parser = etree.XMLParser(encoding='utf-8')
        xml = etree.parse(io.StringIO(self.get_buff()), parser)
        indent(xml.getroot())
        xml.write(filename, encoding='utf-8', method='xml', xml_declaration=True)
Пример #8
0
    def write_buff_to_xhtml(self):
        filename = os.path.join(self.temp_content_dir, self.current_file)

        if not os.path.exists(self.temp_content_dir):
            os.makedirs(self.temp_content_dir)

        parser = etree.XMLParser(encoding='utf-8')
        xhtml = etree.parse(io.StringIO(self.get_buff()), parser)
        indent(xhtml.getroot())
        xhtml.write(filename, encoding='utf-8', method='xml', xml_declaration=True)
Пример #9
0
    def handle_typedef_union(self, table, typedef_name, tpm_alg_ids):
        self.tpm_types_h_file_content += "typedef union {\n"

        for row in table.rows:
            parameter = row[0]
            member_type = row[1].replace("+", "")
            selector = row[2]

            if member_type == "" or "null" in parameter:
                continue

            member_string = ""

            # check for !ALG (algorithm type)
            algs = utils.expand_alg_macro(parameter, tpm_alg_ids)
            for alg in algs:
                dependence = alg.dependence
                if len(dependence) == 0:
                    dependence = alg.short_name

                alg_placeholder = selector.replace("TPM_ALG_", "")  # !ALG.*
                base_type = utils.replace_alg_placeholder(
                    member_type, alg.short_name.upper())
                new_type = parameter.replace(
                    alg_placeholder + "_DIGEST_SIZE",
                    alg.short_name.upper() + "_DIGEST_SIZE").replace(" ", "")

                if alg_placeholder == "!ALG":  # fix for Table 2:144
                    new_type = alg.short_name.lower()
                else:
                    new_type = new_type.replace(alg_placeholder,
                                                alg.short_name.lower())

                member_string += "#ifdef      TPM_ALG_" + dependence + "\n"
                member_string += "    " + base_type + utils.indent(
                    member_type) + new_type + ";\n"
                member_string += "#endif   // TPM_ALG_" + dependence + "\n"
            # end of loop - for alg in algs:

            # in case there is no !ALG
            if not member_string:
                member_string = "    " + member_type + utils.indent(
                    member_type) + parameter + ";\n"

                if selector:  # enclose with ifdef + endif
                    member_string = "#ifdef      " + selector + "\n" + member_string
                    member_string += "#endif   // " + selector + "\n"
            # end of if - if not member_string:

            self.tpm_types_h_file_content += member_string
        # end of loop - for row in table.rows:
        self.tpm_types_h_file_content += "} " + typedef_name + ";\n"

        self.marshaller.handle_union_table(table, tpm_alg_ids)
Пример #10
0
    def handle_typedef_union(self, table, typedef_name, tpm_alg_ids):
        self.tpm_types_h_file_content += "typedef union {\n"

        for row in table.rows:
            parameter = row[0]
            member_type = row[1].replace("+", "")
            selector = row[2]

            if member_type == "" or "null" in parameter:
                continue

            member_string = ""

            # check for !ALG (algorithm type)
            algs = utils.expand_alg_macro(parameter, tpm_alg_ids)
            for alg in algs:
                dependence = alg.dependence
                if len(dependence) == 0:
                    dependence = alg.short_name

                alg_placeholder = selector.replace("TPM_ALG_", "")  # !ALG.*
                base_type = utils.replace_alg_placeholder(member_type, alg.short_name.upper())
                new_type = parameter.replace(alg_placeholder + "_DIGEST_SIZE", alg.short_name.upper() + "_DIGEST_SIZE").replace(" ", "")

                if alg_placeholder == "!ALG": # fix for Table 2:144
                    new_type = alg.short_name.lower()
                else:
                    new_type = new_type.replace(alg_placeholder, alg.short_name.lower())

                member_string += "#ifdef      TPM_ALG_" + dependence + "\n"
                member_string += "    " + base_type + utils.indent(member_type) + new_type + ";\n"
                member_string += "#endif   // TPM_ALG_" + dependence + "\n"
            # end of loop - for alg in algs:

            # in case there is no !ALG
            if not member_string:
                member_string = "    " + member_type + utils.indent(member_type) + parameter + ";\n"

                if selector:  # enclose with ifdef + endif
                    member_string = "#ifdef      " + selector + "\n" + member_string
                    member_string += "#endif   // " + selector + "\n"
            # end of if - if not member_string:

            self.tpm_types_h_file_content += member_string
        # end of loop - for row in table.rows:
        self.tpm_types_h_file_content += "} " + typedef_name + ";\n"

        self.marshaller.handle_union_table(table, tpm_alg_ids)
Пример #11
0
    def handle_bits_table(self, table):
        typedef_struct_name = utils.find_tpm_type_name(table.short_name)

        self.tpm_types_h_file_content += "typedef union {\n"
        self.tpm_types_h_file_content += "    struct {\n"

        size = 0
        for row in table.rows:
            bit = row[0]
            bitname = row[1]

            if "#" in bitname:
                continue

            nr_of_bits = 1
            if ":" in bit:
                values = bit.split(":")
                from_value = int(values[1])
                to_value = int(values[0])
                nr_of_bits = to_value - from_value + 1

            if "Reserved" in bitname:
                bitname = "Reserved_from_" + str(size)

            self.tpm_types_h_file_content += "        unsigned    " + bitname + utils.indent(bitname) + ": " + str(nr_of_bits) + ";\n"
            size += nr_of_bits
        # end of loop - for row in table.rows:

        self.tpm_types_h_file_content += "    };\n"
        self.tpm_types_h_file_content += "    UINT" + str(size) + " val;\n"
        self.tpm_types_h_file_content += "} " + typedef_struct_name + ";\n"

        self.marshaller.handle_bits_table(table)
Пример #12
0
    def handle_enum_table(self, table):
        base_type = utils.find_tpm_base_type_name(table.short_name)
        new_type = utils.find_tpm_type_name(table.short_name)

        self.tpm_types_h_file_content += "typedef  " + base_type + utils.indent(base_type) + new_type + ";\n"

        for row in table.rows:
            name = row[0]
            value = row[1].replace(" ", "")

            if name is u'' or "reserved" in name or "#" in name:  # skip those lines
                continue

            # write the define statement
            self.tpm_types_h_file_content += "#define  " + name + utils.indent(name) + "(" + new_type + ")(" + value + ")\n"

            # additionally write the TPM_RCS_* define
            if "RC_FMT1+" in value:
                name = name.replace("TPM_RC_", "TPM_RCS_")
                self.tpm_types_h_file_content += "#define  " + name + utils.indent(name) + "(" + new_type + ")(" + value + ")\n"
        # end of loop - for row in table.rows:

        self.marshaller.handle_advanced_type_structures(table)
Пример #13
0
    def handle_interface_table(self, table, tpm_alg_ids):
        base_type = utils.find_tpm_base_type_name(table.short_name)
        new_type = utils.find_tpm_type_name(table.short_name)

        typedef_statement = "typedef  " + base_type + utils.indent(
            base_type) + new_type + ";\n"
        alg_dep = utils.find_alg_constraints(table.name)
        if alg_dep:
            alg_name = "TPM_ALG_" + alg_dep
            typedef_statement_alg_dep = ""

            # check for !ALG
            alg_ids_list = utils.expand_alg_macro(new_type, tpm_alg_ids,
                                                  alg_dep)
            # if new type name contains algorithm type, create type definition for all corresponding IDs
            for alg in alg_ids_list:
                alg_name = alg.name
                final_new_type = utils.replace_alg_placeholder(
                    new_type, alg.short_name)
                typedef_statement_alg_dep += "#ifdef      " + alg_name + "\n"  # for each algorithm
                typedef_statement_alg_dep += "typedef  " + base_type + utils.indent(
                    base_type) + final_new_type + ";\n"
                typedef_statement_alg_dep += "#endif   // " + alg_name + "\n"  # for each algorithm

            # in case there is no !ALG, create type definition for type found in table name
            if not typedef_statement_alg_dep:
                typedef_statement_alg_dep = "#ifdef      " + alg_name + "\n"
                typedef_statement_alg_dep += "typedef  " + base_type + utils.indent(
                    base_type) + new_type + ";\n"
                typedef_statement_alg_dep += "#endif   // " + alg_name + "\n"

            typedef_statement = typedef_statement_alg_dep

        self.tpm_types_h_file_content += typedef_statement

        self.marshaller.handle_interface_table(table, tpm_alg_ids)
Пример #14
0
    def create_base_types_h_file(self, table):
        base_types_h_file_content = BaseTypes.BASETYPE_HEADER
        base_types_h_file_content += "// Part 2, " + table.name + "\n"

        for row in table.rows:
            base_type = row[0]
            new_type = row[1]
            line = "typedef  " + base_type + utils.indent(base_type) + new_type + ";\n"
            base_types_h_file_content += str(line)

        base_types_h_file_content += "\n\n"

        self.marshaller.handle_simple_type_structures_new(table)

        base_types_h_file_content += BaseTypes.BASETYPE_FOOTER

        FileHandling.write_file(constants.TPM_INCLUDE_PATH + "BaseTypes.h", base_types_h_file_content)
Пример #15
0
    def create_base_types_h_file(self, table):
        base_types_h_file_content = BaseTypes.BASETYPE_HEADER
        base_types_h_file_content += "// Part 2, " + table.name + "\n"

        for row in table.rows:
            base_type = row[0]
            new_type = row[1]
            line = "typedef  " + base_type + utils.indent(
                base_type) + new_type + ";\n"
            base_types_h_file_content += str(line)

        base_types_h_file_content += "\n\n"

        self.marshaller.handle_simple_type_structures_new(table)

        base_types_h_file_content += BaseTypes.BASETYPE_FOOTER

        FileHandling.write_file(constants.TPM_INCLUDE_PATH + "BaseTypes.h",
                                base_types_h_file_content)
Пример #16
0
    def handle_bits_table(self, table):
        typedef_struct_name = utils.find_tpm_type_name(table.short_name)

        self.tpm_types_h_file_content += "typedef union {\n"
        self.tpm_types_h_file_content += "    struct {\n"

        size = 0
        for row in table.rows:
            bit = row[0]
            bitname = row[1]

            if "#" in bitname:
                continue

            nr_of_bits = 1
            if ":" in bit:
                values = bit.split(":")
                from_value = int(values[1])
                to_value = int(values[0])
                nr_of_bits = to_value - from_value + 1

            if "Reserved" in bitname:
                bitname = "Reserved_from_" + str(size)

            pos = bitname.find(" ".encode())
            if pos != -1 and (bitname[pos - 1] in string.ascii_lowercase
                              or bitname[pos - 1] in string.ascii_uppercase):
                if (bitname[pos + 1] in string.ascii_lowercase
                        or bitname[pos + 1] in string.ascii_uppercase):
                    bitname = bitname.replace(" ".encode(), "".encode())

            self.tpm_types_h_file_content += "        unsigned    " + bitname + utils.indent(
                bitname) + ": " + str(nr_of_bits) + ";\n"
            size += nr_of_bits
        # end of loop - for row in table.rows:

        self.tpm_types_h_file_content += "    };\n"
        self.tpm_types_h_file_content += "    UINT" + str(size) + " val;\n"
        self.tpm_types_h_file_content += "} " + typedef_struct_name + ";\n"

        self.marshaller.handle_bits_table(table)
Пример #17
0
    def process(self):

        #        stdout = sys.stdout
        #        sys.stdout = codecs.open('stdout.txt', 'w', 'utf-8')

        # get uuid if any
        for node in self.root.iter('{*}identifier'):
            try:
                self.book_uuid = uuid.UUID(node.text)
            except:
                pass
            break
        # Lookup series/sequences data if any
        for node in self.root.iter('{*}meta'):
            attributes = node.attrib
            if 'name' in attributes:
                if attributes['name'].endswith('series_index'):
                    self.book_series_num = attributes['content']
                elif attributes['name'].endswith('series'):
                    self.book_series = attributes['content']

        # And reformat book title accordingly
        if self.book_series != '':
            for node in self.root.iter('{*}title'):
                self.book_title = node.text
                abbr = ''.join(word[0] for word in self.book_series.split())
                title = self.bookseriestitle
                title = title.replace('#series', '' if not self.book_series else self.book_series.strip())
                title = title.replace('#number', '' if not self.book_series_num else self.book_series_num.strip())
                title = title.replace('#padnumber', '' if not self.book_series_num else self.book_series_num.strip().zfill(2))
                title = title.replace('#title', '' if not self.book_title else self.book_title.strip())
                title = title.replace('#abbrseries', '' if not abbr else abbr.lower())
                if self.transliterate_author_and_title:
                    title = transliterate(title)
                node.text = title

        for node in self.root.iter('{*}language'):
            self.book_lang = pyphen.language_fallback(node.text)

        self.hyphenator = pyphen.Pyphen(lang=self.book_lang)

        indent(self.root)
        self.tree.write(self.opffile, encoding='utf-8', method='xml', xml_declaration=True)

        # See if we have items to correct and process
        for node in self.root.iter('{*}item'):
            attributes = node.attrib
            if 'href' in attributes and 'media-type' in attributes:
                if attributes['media-type'] == 'application/xhtml+xml':
                    filename = os.path.join(self.path, attributes['href'])
                    self.log.debug('Processing {}'.format(filename))
                    # Proper XML encoding needed by kndlegen
                    xhtml = etree.parse(filename, parser=etree.XMLParser(recover=True))
                    if self.hyphenate:
                        # Do hyphenation if desiried
                        for body in xhtml.getroot().iter('{*}body'):
                            for elem in body.iter('{*}p', '{*}div'):
                                if elem.text:
                                    elem.text = save_html(self.insert_hyphenation(elem.text))
                                if elem.tail:
                                    elem.tail = save_html(self.insert_hyphenation(elem.tail))
                                for child in elem.iterchildren(tag=etree.Element):
                                    if not child.tag.endswith('pre'):
                                        if child.text:
                                            child.text = save_html(self.insert_hyphenation(child.text))
                                        if child.tail:
                                            child.tail = save_html(self.insert_hyphenation(child.tail))
                    xhtml.write(filename, encoding='utf-8', method='xml', xml_declaration=True)
Пример #18
0
    def process(self):

        #        stdout = sys.stdout
        #        sys.stdout = codecs.open('stdout.txt', 'w', 'utf-8')

        # get uuid if any
        for node in self.root.iter('{*}identifier'):
            try:
                self.book_uuid = uuid.UUID(node.text)
            except:
                pass
            break
        # Lookup series/sequences data if any
        for node in self.root.iter('{*}meta'):
            attributes = node.attrib
            if 'name' in attributes:
                if attributes['name'].endswith('series_index'):
                    self.book_series_num = attributes['content']
                elif attributes['name'].endswith('series'):
                    self.book_series = attributes['content']

        # And reformat book title accordingly
        if self.book_series != '':
            for node in self.root.iter('{*}title'):
                self.book_title = node.text
                abbr = ''.join(word[0] for word in self.book_series.split())
                title = self.bookseriestitle
                title = title.replace(
                    '#series',
                    '' if not self.book_series else self.book_series.strip())
                title = title.replace(
                    '#number', '' if not self.book_series_num else
                    self.book_series_num.strip())
                title = title.replace(
                    '#padnumber', '' if not self.book_series_num else
                    self.book_series_num.strip().zfill(2))
                title = title.replace(
                    '#title',
                    '' if not self.book_title else self.book_title.strip())
                title = title.replace('#abbrseries',
                                      '' if not abbr else abbr.lower())
                if self.transliterate_author_and_title:
                    title = transliterate(title)
                node.text = title

        for node in self.root.iter('{*}language'):
            self.book_lang = node.text
        self.hyphenator.set_language(self.book_lang)

        indent(self.root)
        self.tree.write(self.opffile,
                        encoding='utf-8',
                        method='xml',
                        xml_declaration=True)

        # See if we have items to correct and process
        for node in self.root.iter('{*}item'):
            attributes = node.attrib
            if 'href' in attributes and 'media-type' in attributes:
                if attributes['media-type'] == 'application/xhtml+xml':
                    filename = os.path.join(self.path, attributes['href'])
                    self.log.debug('Processing {}'.format(filename))
                    # Proper XML encoding needed by kndlegen
                    xhtml = etree.parse(filename,
                                        parser=etree.XMLParser(recover=True))
                    if self.hyphenate:
                        # Do hyphenation if desiried
                        for body in xhtml.getroot().iter('{*}body'):
                            for elem in body.iter('{*}p', '{*}div'):
                                if elem.text:
                                    elem.text = save_html(
                                        self.insert_hyphenation(elem.text))
                                if elem.tail:
                                    elem.tail = save_html(
                                        self.insert_hyphenation(elem.tail))
                                for child in elem.iterchildren(
                                        tag=etree.Element):
                                    if not child.tag.endswith('pre'):
                                        if child.text:
                                            child.text = save_html(
                                                self.insert_hyphenation(
                                                    child.text))
                                        if child.tail:
                                            child.tail = save_html(
                                                self.insert_hyphenation(
                                                    child.tail))
                    xhtml.write(filename,
                                encoding='utf-8',
                                method='xml',
                                xml_declaration=True)