def from_headings(body, log, namespace): ' Create a TOC from headings in the document ' XPath, descendants = namespace.XPath, namespace.descendants headings = ('h1', 'h2', 'h3') tocroot = TOC() xpaths = [XPath('//%s' % x) for x in headings] level_prev = {i + 1: None for i in xrange(len(xpaths))} level_prev[0] = tocroot level_item_map = { i + 1: frozenset(xp(body)) for i, xp in enumerate(xpaths) } item_level_map = { e: i for i, elems in level_item_map.iteritems() for e in elems } idcount = Count() def ensure_id(elem): ans = elem.get('id', None) if not ans: idcount.val += 1 ans = 'toc_id_%d' % idcount.val elem.set('id', ans) return ans for item in descendants(body, *headings): lvl = plvl = item_level_map.get(item, None) if lvl is None: continue parent = None while parent is None: plvl -= 1 parent = level_prev[plvl] lvl = plvl + 1 elem_id = ensure_id(item) text = elem_to_toc_text(item) toc = parent.add_item('index.html', elem_id, text) level_prev[lvl] = toc for i in xrange(lvl + 1, len(xpaths) + 1): level_prev[i] = None if len(tuple(tocroot.flat())) > 1: log('Generating Table of Contents from headings') return tocroot
def create_toc(self): ' Create a TOC from headings in the document ' root = self.body headings = ('h1', 'h2', 'h3') tocroot = TOC() xpaths = [XPath('//%s' % x) for x in headings] level_prev = {i + 1: None for i in xrange(len(xpaths))} level_prev[0] = tocroot level_item_map = { i + 1: frozenset(xp(root)) for i, xp in enumerate(xpaths) } item_level_map = { e: i for i, elems in level_item_map.iteritems() for e in elems } self.idcount = 0 def ensure_id(elem): ans = elem.get('id', None) if not ans: self.idcount += 1 ans = 'toc_id_%d' % self.idcount elem.set('id', ans) return ans for item in root.iterdescendants(*headings): lvl = plvl = item_level_map.get(item, None) if lvl is None: continue parent = None while parent is None: plvl -= 1 parent = level_prev[plvl] lvl = plvl + 1 elem_id = ensure_id(item) text = elem_to_toc_text(item) toc = parent.add_item('index.html', elem_id, text) level_prev[lvl] = toc for i in xrange(lvl + 1, len(xpaths) + 1): level_prev[i] = None if len(tuple(tocroot.flat())) > 1: return tocroot
def from_headings(body, log, namespace, num_levels=3): ' Create a TOC from headings in the document ' tocroot = TOC() all_heading_nodes = body.xpath('//*[@data-heading-level]') level_prev = {i + 1: None for i in range(num_levels)} level_prev[0] = tocroot level_item_map = { i: frozenset(x for x in all_heading_nodes if int(x.get('data-heading-level')) == i) for i in range(1, num_levels + 1) } item_level_map = { e: i for i, elems in iteritems(level_item_map) for e in elems } idcount = count() def ensure_id(elem): ans = elem.get('id', None) if not ans: ans = 'toc_id_%d' % (next(idcount) + 1) elem.set('id', ans) return ans for item in all_heading_nodes: lvl = plvl = item_level_map.get(item, None) if lvl is None: continue parent = None while parent is None: plvl -= 1 parent = level_prev[plvl] lvl = plvl + 1 elem_id = ensure_id(item) text = elem_to_toc_text(item) toc = parent.add_item('index.html', elem_id, text) level_prev[lvl] = toc for i in range(lvl + 1, num_levels + 1): level_prev[i] = None if len(tuple(tocroot.flat())) > 1: log('Generating Table of Contents from headings') return tocroot
def from_headings(body, log, namespace): ' Create a TOC from headings in the document ' XPath, descendants = namespace.XPath, namespace.descendants headings = ('h1', 'h2', 'h3') tocroot = TOC() xpaths = [XPath('//%s' % x) for x in headings] level_prev = {i+1:None for i in xrange(len(xpaths))} level_prev[0] = tocroot level_item_map = {i+1:frozenset(xp(body)) for i, xp in enumerate(xpaths)} item_level_map = {e:i for i, elems in level_item_map.iteritems() for e in elems} idcount = Count() def ensure_id(elem): ans = elem.get('id', None) if not ans: idcount.val += 1 ans = 'toc_id_%d' % idcount.val elem.set('id', ans) return ans for item in descendants(body, *headings): lvl = plvl = item_level_map.get(item, None) if lvl is None: continue parent = None while parent is None: plvl -= 1 parent = level_prev[plvl] lvl = plvl + 1 elem_id = ensure_id(item) text = elem_to_toc_text(item) toc = parent.add_item('index.html', elem_id, text) level_prev[lvl] = toc for i in xrange(lvl+1, len(xpaths)+1): level_prev[i] = None if len(tuple(tocroot.flat())) > 1: log('Generating Table of Contents from headings') return tocroot
def create_toc(self): " Create a TOC from headings in the document " root = self.body headings = ("h1", "h2", "h3") tocroot = TOC() xpaths = [XPath("//%s" % x) for x in headings] level_prev = {i + 1: None for i in xrange(len(xpaths))} level_prev[0] = tocroot level_item_map = {i + 1: frozenset(xp(root)) for i, xp in enumerate(xpaths)} item_level_map = {e: i for i, elems in level_item_map.iteritems() for e in elems} self.idcount = 0 def ensure_id(elem): ans = elem.get("id", None) if not ans: self.idcount += 1 ans = "toc_id_%d" % self.idcount elem.set("id", ans) return ans for item in root.iterdescendants(*headings): lvl = plvl = item_level_map.get(item, None) if lvl is None: continue parent = None while parent is None: plvl -= 1 parent = level_prev[plvl] lvl = plvl + 1 elem_id = ensure_id(item) text = elem_to_toc_text(item) toc = parent.add_item("index.html", elem_id, text) level_prev[lvl] = toc for i in xrange(lvl + 1, len(xpaths) + 1): level_prev[i] = None if len(tuple(tocroot.flat())) > 1: return tocroot