Beispiel #1
0
def find_first_matching_rule(container,
                             html_file_name,
                             raw_html,
                             class_data,
                             lnum_attr='data-lnum'):
    lnum, tags = class_data['sourceline_address']
    class_name = class_data['class']
    root = parse(raw_html,
                 decoder=lambda x: x.decode('utf-8'),
                 line_numbers=True,
                 linenumber_attribute=lnum_attr)
    tags_on_line = root.xpath(f'//*[@{lnum_attr}={lnum}]')
    barenames = [barename(tag.tag) for tag in tags_on_line]
    if barenames[:len(tags)] != tags:
        raise NoMatchingTagFound(
            f'No tag matching the specification was found in {html_file_name}')
    target_elem = tags_on_line[len(tags) - 1]
    select = Select(root, ignore_inappropriate_pseudo_classes=True)
    for tag in root.iter('*'):
        tn = barename(tag.tag)
        if tn == 'style' and tag.text and tag.get('type',
                                                  'text/css') == 'text/css':
            try:
                sheet = container.parse_css(tag.text)
            except Exception:
                continue
            res = find_first_rule_that_matches_elem(container, target_elem,
                                                    select, class_name,
                                                    sheet.cssRules,
                                                    html_file_name)
            if res is not None:
                return res._replace(style_tag_address=(int(tag.get(lnum_attr)),
                                                       ['style']))
        elif tn == 'link' and tag.get('href') and tag.get(
                'rel') == 'stylesheet':
            sname = container.href_to_name(tag.get('href'), html_file_name)
            try:
                sheet = container.parsed(sname)
            except Exception:
                continue
            if not hasattr(sheet, 'cssRules'):
                continue
            res = find_first_rule_that_matches_elem(container, target_elem,
                                                    select, class_name,
                                                    sheet.cssRules, sname)
            if res is not None:
                return res
    raise NoMatchingRuleFound(
        f'No CSS rules that apply to the specified tag in {html_file_name} with the class {class_name} found'
    )
Beispiel #2
0
 def in_table(elem):
     p = elem.getparent()
     if p is None:
         return False
     if barename(p.tag).lower() == 'table':
         return True
     return in_table(p)
Beispiel #3
0
 def in_table(elem):
     p = elem.getparent()
     if p is None:
         return False
     if barename(p.tag).lower() == 'table':
         return True
     return in_table(p)
Beispiel #4
0
    def insert_aid_attributes(self):
        self.id_map = {}
        for i, item in enumerate(self.oeb.spine):
            root = self.data(item)
            aidbase = i * int(1e6)
            j = 0
            for tag in root.iterdescendants(etree.Element):
                id_ = tag.attrib.get('id', None)
                if id_ is not None or barename(tag.tag).lower() in aid_able_tags:
                    aid = aidbase + j
                    tag.attrib['aid'] = to_base(aid, base=32)
                    if tag.tag == XHTML('body'):
                        self.id_map[(item.href, '')] = tag.attrib['aid']
                    if id_ is not None:
                        self.id_map[(item.href, id_)] = tag.attrib['aid']

                    j += 1
Beispiel #5
0
    def insert_aid_attributes(self):
        self.id_map = {}
        for i, item in enumerate(self.oeb.spine):
            root = self.data(item)
            aidbase = i * int(1e6)
            j = 0
            for tag in root.iterdescendants(etree.Element):
                id_ = tag.attrib.get('id', None)
                if id_ is not None or barename(
                        tag.tag).lower() in aid_able_tags:
                    aid = aidbase + j
                    tag.attrib['aid'] = to_base(aid, base=32)
                    if tag.tag == XHTML('body'):
                        self.id_map[(item.href, '')] = tag.attrib['aid']
                    if id_ is not None:
                        self.id_map[(item.href, id_)] = tag.attrib['aid']

                    j += 1
Beispiel #6
0
    def insert_aid_attributes(self):
        self.id_map = {}
        cid = 0
        for i, item in enumerate(self.oeb.spine):
            root = self.data(item)
            aidbase = i * int(1e6)
            j = 0

            def in_table(elem):
                p = elem.getparent()
                if p is None:
                    return False
                if barename(p.tag).lower() == 'table':
                    return True
                return in_table(p)

            for tag in root.iterdescendants(etree.Element):
                id_ = tag.attrib.get('id', None)
                if id_ is None and tag.tag == XHTML('a'):
                    # Can happen during tweaking
                    id_ = tag.attrib.get('name', None)
                    if id_ is not None:
                        tag.attrib['id'] = id_
                tagname = barename(tag.tag).lower()
                if id_ is not None or tagname in aid_able_tags:
                    if tagname == 'table' or in_table(tag):
                        # The Kindle renderer barfs on large tables that have
                        # aid on any of their tags. See
                        # https://bugs.launchpad.net/bugs/1489495
                        if id_:
                            cid += 1
                            val = 'c%d' % cid
                            self.id_map[(item.href, id_)] = val
                            tag.set('cid', val)
                    else:
                        aid = to_base(aidbase + j, base=32)
                        tag.set('aid', aid)
                        if tag.tag == XHTML('body'):
                            self.id_map[(item.href, '')] = aid
                        if id_ is not None:
                            self.id_map[(item.href, id_)] = aid

                        j += 1
Beispiel #7
0
    def insert_aid_attributes(self):
        self.id_map = {}
        cid = 0
        for i, item in enumerate(self.oeb.spine):
            root = self.data(item)
            aidbase = i * int(1e6)
            j = 0

            def in_table(elem):
                p = elem.getparent()
                if p is None:
                    return False
                if barename(p.tag).lower() == 'table':
                    return True
                return in_table(p)
            for tag in root.iterdescendants(etree.Element):
                id_ = tag.attrib.get('id', None)
                if id_ is None and tag.tag == XHTML('a'):
                    # Can happen during tweaking
                    id_ = tag.attrib.get('name', None)
                    if id_ is not None:
                        tag.attrib['id'] = id_
                tagname = barename(tag.tag).lower()
                if id_ is not None or tagname in aid_able_tags:
                    if tagname == 'table' or in_table(tag):
                        # The Kindle renderer barfs on large tables that have
                        # aid on any of their tags. See
                        # https://bugs.launchpad.net/bugs/1489495
                        if id_:
                            cid += 1
                            val = 'c%d' % cid
                            self.id_map[(item.href, id_)] = val
                            tag.set('cid', val)
                    else:
                        aid = to_base(aidbase + j, base=32)
                        tag.set('aid', aid)
                        if tag.tag == XHTML('body'):
                            self.id_map[(item.href, '')] = aid
                        if id_ is not None:
                            self.id_map[(item.href, id_)] = aid

                        j += 1
Beispiel #8
0
    def insert_aid_attributes(self):
        self.id_map = {}
        for i, item in enumerate(self.oeb.spine):
            root = self.data(item)
            aidbase = i * int(1e6)
            j = 0
            for tag in root.iterdescendants(etree.Element):
                id_ = tag.attrib.get('id', None)
                if id_ is None and tag.tag == XHTML('a'):
                    # Can happen during tweaking
                    id_ = tag.attrib.get('name', None)
                    if id_ is not None:
                        tag.attrib['id'] = id_
                if id_ is not None or barename(tag.tag).lower() in aid_able_tags:
                    aid = to_base(aidbase + j, base=32)
                    tag.set('aid', aid)
                    if tag.tag == XHTML('body'):
                        self.id_map[(item.href, '')] = aid
                    if id_ is not None:
                        self.id_map[(item.href, id_)] = aid

                    j += 1
Beispiel #9
0
    def insert_aid_attributes(self):
        self.id_map = {}
        for i, item in enumerate(self.oeb.spine):
            root = self.data(item)
            aidbase = i * int(1e6)
            j = 0
            for tag in root.iterdescendants(etree.Element):
                id_ = tag.attrib.get('id', None)
                if id_ is None and tag.tag == XHTML('a'):
                    # Can happen during tweaking
                    id_ = tag.attrib.get('name', None)
                    if id_ is not None:
                        tag.attrib['id'] = id_
                if id_ is not None or barename(tag.tag).lower() in aid_able_tags:
                    aid = to_base(aidbase + j, base=32)
                    tag.set('aid', aid)
                    if tag.tag == XHTML('body'):
                        self.id_map[(item.href, '')] = aid
                    if id_ is not None:
                        self.id_map[(item.href, id_)] = aid

                    j += 1