def generate_examples_sidebar(app, fromdocname, container): toc = nodes.bullet_list() ref = nodes.reference('', '') ref['refuri'] = app.builder.get_relative_uri(fromdocname, "examples/index") ref.append(nodes.Text("Examples")) module_item = nodes.list_item('', addnodes.compact_paragraph('', '', ref), classes=["toctree-l1"]) if fromdocname.startswith("examples/"): module_item["classes"].append('current') toc += module_item subtree = nodes.bullet_list() module_item += subtree examples = Path(__file__).absolute().parent.parent / "examples" for example in sorted(examples.rglob("*/index.md"), key=lambda x: x.parent.name): ref = nodes.reference('', '') ref['refuri'] = app.builder.get_relative_uri(fromdocname, str(example).replace(str(examples), "examples").replace("index.md", "index")) ref.append(nodes.Text(example.parent.name)) class_item = nodes.list_item('', addnodes.compact_paragraph('', '', ref), classes=["toctree-l2"]) if fromdocname == ref['refuri'].replace(".html", ""): class_item['classes'].append('current') subtree += class_item container += toc
def generate_examples_sidebar(app, fromdocname, container): examples = Path(__file__).absolute().parent.parent / "examples" container += nodes.caption("Examples", '', *[nodes.Text("Examples")]) for example_groups in [examples / group for group in ["basics", "advanced", "datasets"]]: if example_groups.is_dir(): toc = nodes.bullet_list() ref = nodes.reference('', '') ref['refuri'] = app.builder.get_relative_uri(fromdocname, "examples/" + example_groups.name + "/README") ref.append(nodes.Text(example_groups.name.capitalize())) module_item = nodes.list_item('', addnodes.compact_paragraph('', '', ref), classes=["toctree-l1"]) if fromdocname.startswith("examples/" + example_groups.name): module_item["classes"].append('current') toc += module_item subtree = nodes.bullet_list() module_item += subtree for example in sorted(example_groups.rglob("*/README.md"), key=lambda x: x.parent.name): ref = nodes.reference('', '') ref['refuri'] = app.builder.get_relative_uri(fromdocname, str(example).replace(str(examples), "examples").replace("README.md", "README")) ref.append(nodes.Text(example.parent.name)) class_item = nodes.list_item('', addnodes.compact_paragraph('', '', ref), classes=["toctree-l2"]) if fromdocname == ref['refuri'].replace(".html", ""): class_item['classes'].append('current') subtree += class_item container += toc
def process_authorlists(app, doctree, fromdocname): """Build list of authors sorted by contribution count.""" env = app.builder.env authors = set( itertools.chain(*[authors for authors in env.author_list.values()])) guides_by_author = { a: set(g for g, guide_authors in env.author_list.items() if a in guide_authors) for a in authors } count_by_author = {a: len(guides_by_author[a]) for a in authors} for node in doctree.traverse(allauthors): author_list = nodes.enumerated_list(classes=["hof__list"]) for author, count in sorted(count_by_author.items(), key=lambda x: (-x[1], x[0].lower())): # list entry author_entry = nodes.list_item(classes=["hof__entry"]) author_list += author_entry # counter counter_div = nodes.container(classes=["hof__counter"]) counter_div += addnodes.compact_paragraph(text=count) author_entry += counter_div # author author_div = nodes.container(classes=["hof__author"]) author_div += addnodes.compact_paragraph(text=author) author_entry += author_div # guide list guides_div = nodes.container(classes=["hof__guides"]) author_entry += guides_div # linklist guides_list = nodes.bullet_list(classes=["hof__guide_list"]) guides_div += guides_list for guide in sorted(guides_by_author[author]): # guide link_entry = nodes.list_item(classes=["hof__guide"]) guides_list += link_entry # I can't figure out a way to get the link and title from a page name.. link = '/' + guide + '.html' title = guide.partition("_")[2].title() link_wrapper = addnodes.compact_paragraph() link_wrapper += nodes.reference("", "", nodes.Text(title), internal=True, refuri=link, anchorname="") link_entry += link_wrapper node.replace_self([author_list])
def run(self): self.assert_has_content() content = ''.join(self.content).strip() icon_classes = self.options.get('icon-classes', '') icon_classes = icon_classes.split(' ') container_classes = self.options.get('box-classes', '') container_classes = container_classes.split(' ') icons = span(classes=icon_classes) node = nodes.container(classes=container_classes) node.children.append(icons) parsed, _messages = self.state.inline_text(content, self.content_offset) parsed_ = parsed[0] for p in parsed[1:]: parsed_.children.append(p) cp = compact_paragraph('', '', parsed_) node.children.append(cp) return [node]
def run(self): self.assert_has_content() node = tabs() node.document = self.state.document set_source_info(self, node) try: if self.arguments: node['classes'] += directives.class_option(self.arguments[0]) except ValueError: # pragma: no cover val_error = 'Invalid class attribute value for "%s" directive: "%s".' raise self.error(val_error % (self.name, self.arguments[0])) node['classes'] += self.options.get('class', []) self.state.nested_parse(self.content, self.content_offset, node) self.add_name(node) wrapper = nodes.container() wrapper['classes'] += ['tab-content'] wrapper += node.children nav_list = nodes.bullet_list() nav_list['classes'] += ['nav', 'nav-tabs'] nav_list['html_attributes'] = {'role': 'tablist'} has_active_class = False for child_tab in wrapper.children: if not isinstance(child_tab, tab): raise self.error('.. tabs can only have .. tab children.') if 'active' in child_tab['classes']: has_active_class = True item = nodes.list_item() item['html_attributes'] = {'role': 'presentation'} html_attributes = {'role': 'tab', 'data-toggle': 'tab'} ref_opts = { 'internal': True, 'refid': child_tab['tab_id'], 'html_attributes': html_attributes, } reference = nodes.reference('', '', **ref_opts) reference += child_tab['tab_title'] para = addnodes.compact_paragraph('', '', reference) item += [para] nav_list += item if not has_active_class: wrapper.children[0]['classes'] += ['active'] nav_list.children[0]['classes'] += ['active'] node.clear() node.insert(0, nav_list) node.insert(1, wrapper) return [node]
def extract_toc(fulltoc, selectors): entries = [] def matches(ref, selector): if selector.endswith('/*'): return ref.rsplit('/', 1)[0] == selector[:-2] return ref == selector for refnode in fulltoc.traverse(nodes.reference): container = refnode.parent.parent if any(cls[:4] == 'ref-' and any( matches(cls[4:], s) for s in selectors) for cls in container['classes']): parent = container.parent new_parent = parent.deepcopy() del new_parent.children[:] new_parent += container entries.append(new_parent) parent.remove(container) if not parent.children: parent.parent.remove(parent) newnode = addnodes.compact_paragraph('', '') newnode.extend(entries) newnode['toctree'] = True return newnode
def run(self): self.assert_has_content() content = ''.join(self.content).strip() icon_classes = self.options.get('icon-classes', '') icon_classes = icon_classes.split(' ') container_classes = self.options.get('box-classes', '') container_classes = container_classes.split(' ') icons = span(classes=icon_classes) node = nodes.container(classes=container_classes) node.children.append(icons) parsed, _messages = self.state.inline_text( content, self.content_offset ) parsed_ = parsed[0] for p in parsed[1:]: parsed_.children.append(p) cp = compact_paragraph('', '', parsed_) node.children.append(cp) return [node]
def apply(self): # type: () -> None env = self.document.settings.env if env.config.html_compact_lists: return def check_refonly_list(node): # type: (nodes.Node) -> bool """Check for list with only references in it.""" visitor = RefOnlyListChecker(self.document) try: node.walk(visitor) except nodes.NodeFound: return False else: return True for node in self.document.traverse(nodes.bullet_list): if check_refonly_list(node): for item in node.traverse(nodes.list_item): para = item[0] ref = para[0] compact_para = addnodes.compact_paragraph() compact_para += ref item.replace(para, compact_para)
def get_navtree(app, pagename, collapse=True, **kwargs): shift_toc = app.config.navtree_shift root_links = app.config.navtree_root_links maxdepth = app.config.navtree_maxdepth try: maxdepth.setdefault('default', kwargs.pop('maxdepth', MAXDEPTH_DEFAULT)) except AttributeError: maxdepth = {'default': maxdepth} toctree = app.env.get_toctree_for(pagename, app.builder, collapse=False, **kwargs) navtree = addnodes.compact_paragraph() navtree['toctree'] = True for bullet_list, caption in iter_toctree(toctree): process_toctree_list(navtree, bullet_list, caption, app, collapse, maxdepth, shift_toc, root_links) if shift_toc: update_navtree_classes(navtree) return app.builder.render_partial(navtree)['fragment']
def _has_toc_yaml(self, subnode, tocdict, depth): """ constructs toc nodes from globaltoc dict """ depth += 1 for key, val in tocdict.items(): if key == "header": header = self._handle_toc_header(subnode, val, depth) subnode["classes"].append("ls-none") subnode.append(header) if key in ["file", "url"]: if "title" in tocdict: title = tocdict["title"] else: if val not in self.env.titles: continue title = clean_astext(self.env.titles[val]) if key == "url": if "http" in val: val = val internal = False else: # since "file" key will be anyways for each "url" key continue else: val = "/" + val + self.env.app.builder.out_suffix internal = True reference = nodes.reference("", "", internal=internal, refuri=val, anchorname="", *[nodes.Text(title)]) para = addnodes.compact_paragraph("", "", reference) item = nodes.list_item("", para) item["classes"].append("tableofcontents-l%d" % (depth)) subnode.append(item) if key == "sections": sectionlist = nodes.bullet_list().deepcopy() sectionheader = None headerlist = None for item in val: if "header" in item: if headerlist: sectionlist["classes"].append("ls-none") sectionlist.append(sectionheader) sectionlist.append(headerlist) headerlist = nodes.bullet_list().deepcopy() sectionheader = self._handle_toc_header( sectionlist, item["header"], depth) else: if headerlist: self._has_toc_yaml(headerlist, item, depth) else: self._has_toc_yaml(sectionlist, item, depth) # handling for last header in the section if headerlist: sectionlist["classes"].append("ls-none") sectionlist.append(sectionheader) sectionlist.append(headerlist) subnode.append(sectionlist)
def extract_toc(fulltoc, selectors): entries = [] def matches(ref, selector): if selector.endswith('/*'): return ref.rsplit('/', 1)[0] == selector[:-2] return ref == selector for refnode in fulltoc.traverse(nodes.reference): container = refnode.parent.parent if any( cls[:4] == 'ref-' and any( matches(cls[4:], s) for s in selectors ) for cls in container['classes'] ): parent = container.parent new_parent = parent.deepcopy() del new_parent.children[:] new_parent += container entries.append(new_parent) parent.remove(container) if not parent.children: parent.parent.remove(parent) newnode = addnodes.compact_paragraph('', '') newnode.extend(entries) newnode['toctree'] = True return newnode
def handle_signature(self, sig, signode): #synopsis = unicodedata.normalize('NFD', self.options.get('synopsis')) synopsis = self.options.get('synopsis') module = self.env.temp_data.get('nscp:module') fullname = 'TODO' if self.objtype == 'query': fullname = '%s.%s'%(module, sig) signode['fullname'] = fullname signode += addnodes.desc_addname(module, module) signode += addnodes.desc_name(sig, sig) signode += addnodes.desc_content('') signode += addnodes.compact_paragraph(synopsis, synopsis) elif self.objtype == 'option': command = self.env.temp_data.get('nscp:command') fullname = '%s.%s:%s'%(module, command, sig) signode['fullname'] = fullname ann = ' (%s, %s)'%(module, command) signode += addnodes.desc_name(sig, sig) signode += addnodes.desc_annotation(ann, ann) elif self.objtype == 'confpath': fullname = '%s:%s'%(module, sig) signode['fullname'] = fullname ann = ' (%s)'%(module) signode += addnodes.desc_name(sig, sig) signode += addnodes.desc_annotation(ann, ann) elif self.objtype == 'confkey': confpath = self.env.temp_data.get('nscp:confpath', '') fullname = '%s:%s:%s'%(module, confpath, sig) signode['fullname'] = fullname ann = ' (%s, %s)'%(module, confpath) signode += addnodes.desc_name(sig, sig) signode += addnodes.desc_annotation(ann, ann) #print 'handle_signature(%s, %s) => %s'%(sig, signode, fullname) return fullname, sig
def handle_toc_header(val: str) -> nodes.Element: """Constructs node for the headers in globaltoc :param val: value of the node """ para = addnodes.compact_paragraph("", "", nodes.Text(val)) item = nodes.list_item("", para) item["classes"].append("fs-1-2") return item
def _handle_toc_header(self, subnode, val, depth): """ Constructs node for the headers in globaltoc """ if val in self.env.titles: title = clean_astext(self.env.titles[val]) val = "/" + val + self.env.app.builder.out_suffix reference = nodes.reference("", "", internal=False, refuri=val, anchorname="", *[nodes.Text(title)]) para = addnodes.compact_paragraph("", "", reference) else: para = addnodes.compact_paragraph("", "", nodes.Text(val)) item = nodes.list_item("", para) item["classes"].append("fs-1-2") return item
def getArgsContent(Args): Container = desc('', desc_signature(text='Args'), objtype="Args") for name, Arg in Args.items(): Content = desc_content() Content.append(desc_name(text='%s: ' % name)) Content.append(compact_paragraph(text=getArgDesc(Arg))) Container.append(Content) return Container
def build_toc(node, depth=1): # type: (nodes.Node, int) -> List[nodes.Node] entries = [] for sectionnode in node: # find all toctree nodes in this section and add them # to the toc (just copying the toctree node which is then # resolved in self.get_and_resolve_doctree) if isinstance(sectionnode, addnodes.only): onlynode = addnodes.only(expr=sectionnode['expr']) blist = build_toc(sectionnode, depth) if blist: onlynode += blist.children # type: ignore entries.append(onlynode) continue if not isinstance(sectionnode, nodes.section): for toctreenode in traverse_in_section( sectionnode, addnodes.toctree): item = toctreenode.copy() entries.append(item) # important: do the inventory stuff TocTree(app.env).note(docname, toctreenode) continue title = sectionnode[0] # copy the contents of the section title, but without references # and unnecessary stuff visitor = SphinxContentsFilter(doctree) title.walkabout(visitor) nodetext = visitor.get_entry_text() if not numentries[0]: # for the very first toc entry, don't add an anchor # as it is the file's title anyway anchorname = '' else: anchorname = '#' + sectionnode['ids'][0] numentries[0] += 1 # make these nodes: # list_item -> compact_paragraph -> reference reference = nodes.reference('', '', internal=True, refuri=docname, anchorname=anchorname, *nodetext) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) sub_item = build_toc(sectionnode, depth + 1) item += sub_item entries.append(item) if entries: return nodes.bullet_list('', *entries) return []
def has_toc_yaml(self, subnode: nodes.Element, tocdict: Dict[str, nodes.Element], depth: int) -> None: """constructs toc nodes from globaltoc dict :param subnode: node to which toc constructed here is appended to :param tocdict: dictionary of toc entries :param depth: current toclevel depth """ depth += 1 for key, val in tocdict.items(): if key in ["file", "url"]: internal = False if "title" in tocdict: title = tocdict["title"] else: if val not in self.env.titles: continue title = clean_astext(self.env.titles[val]) if "url" in tocdict: if "http" in tocdict["url"]: internal = False else: continue else: val = "%" + val internal = True reference = nodes.reference( "", "", internal=internal, refuri=val, anchorname="", *[nodes.Text(title)], ) para = addnodes.compact_paragraph("", "", reference) item = nodes.list_item("", para) item["classes"].append("tableofcontents-l%d" % (depth)) subnode.append(item) if key in ["sections"]: sectionlist = nodes.bullet_list().deepcopy() sectionheader = None for item in val: if "part" in item: sectionheader = handle_toc_header(item["part"]) sectionlist.append(sectionheader) del item["part"] has_toc_yaml(self, sectionlist, item, depth) else: has_toc_yaml(self, sectionlist, item, depth) subnode.append(sectionlist)
def parse_node(env, text, node): args = text.split("^") name = args[0].strip() node += addnodes.literal_strong(name, name) if len(args) > 2: default = f"={args[2].strip()}" node += nodes.literal(text=default) if len(args) > 1: content = f"({args[1].strip()})" node += addnodes.compact_paragraph(text=content) return name # this will be the link
def _build_toc_node(docname, anchor='anchor', text='test text', bullet=False): """ Create the node structure that Sphinx expects for TOC Tree entries. The ``bullet`` argument wraps it in a ``nodes.bullet_list``, which is how you nest TOC Tree entries. """ reference = nodes.reference('', '', internal=True, refuri=docname, anchorname='#' + anchor, *[nodes.Text(text, text)]) para = addnodes.compact_paragraph('', '', reference) ret_list = nodes.list_item('', para) if not bullet: return ret_list else: return nodes.bullet_list('', ret_list)
def generate_collapsible_classlist(app, fromdocname, classes, container, caption, module_index): entries = defaultdict(list) prefix = ".".join(classes[0][0].split(".")[:module_index]) + "." for e in classes: module = e[0].split(".")[module_index] entries[module].append(e) #print("t", fromdocname) toc = nodes.bullet_list() toc += nodes.caption(caption, '', *[nodes.Text(caption)]) for module, class_list in entries.items(): #print("t2", "src." + prefix + module) ref = nodes.reference('', '') ref['refuri'] = app.builder.get_relative_uri(fromdocname, prefix + module) ref.append(nodes.Text(module.capitalize())) module_item = nodes.list_item('', addnodes.compact_paragraph('', '', ref), classes=["toctree-l1"]) if fromdocname.startswith(prefix + module): module_item["classes"].append('current') toc += module_item subtree = nodes.bullet_list() module_item += subtree for e in class_list: ref = nodes.reference('', '') ref['refdocname'] = e[3] ref['refuri'] = app.builder.get_relative_uri(fromdocname, e[3]) ref['refuri'] += '#' + e[4] ref.append(nodes.Text(e[0].split(".")[-1])) class_item = nodes.list_item('', addnodes.compact_paragraph('', '', ref), classes=["toctree-l2"]) if fromdocname.startswith(e[3]): class_item['classes'].append('current') subtree += class_item container += toc
def class_results_to_node(key, elements): title = attributetabletitle(key, key) ul = nodes.bullet_list('') for element in elements: ref = nodes.reference('', '', internal=True, refuri='#' + element.fullname, anchorname='', *[nodes.Text(element.label)]) para = addnodes.compact_paragraph('', '', ref) if element.badge is not None: ul.append(attributetable_item('', element.badge, para)) else: ul.append(attributetable_item('', para)) return attributetablecolumn('', title, ul)
def build_toc(node, depth=1): # type: (nodes.Element, int) -> nodes.bullet_list entries = [] # type: List[nodes.Element] for sectionnode in node: # find all toctree nodes in this section and add them # to the toc (just copying the toctree node which is then # resolved in self.get_and_resolve_doctree) if isinstance(sectionnode, nodes.section): title = sectionnode[0] # copy the contents of the section title, but without references # and unnecessary stuff visitor = SphinxContentsFilter(doctree) title.walkabout(visitor) nodetext = visitor.get_entry_text() if not numentries[0]: # for the very first toc entry, don't add an anchor # as it is the file's title anyway anchorname = '' else: anchorname = '#' + sectionnode['ids'][0] numentries[0] += 1 # make these nodes: # list_item -> compact_paragraph -> reference reference = nodes.reference( '', '', internal=True, refuri=docname, anchorname=anchorname, *nodetext) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) # type: nodes.Element sub_item = build_toc(sectionnode, depth + 1) if sub_item: item += sub_item entries.append(item) elif isinstance(sectionnode, addnodes.only): onlynode = addnodes.only(expr=sectionnode['expr']) blist = build_toc(sectionnode, depth) if blist: onlynode += blist.children entries.append(onlynode) elif isinstance(sectionnode, nodes.Element): for toctreenode in traverse_in_section(sectionnode, addnodes.toctree): item = toctreenode.copy() entries.append(item) # important: do the inventory stuff TocTree(app.env).note(docname, toctreenode) if entries: return nodes.bullet_list('', *entries) return None
def _build_toc_node(docname, anchor="anchor", text="test text", bullet=False): """ Create the node structure that Sphinx expects for TOC Tree entries. The ``bullet`` argument wraps it in a ``nodes.bullet_list``, which is how you nest TOC Tree entries. """ reference = nodes.reference("", "", internal=True, refuri=docname, anchorname="#" + anchor, *[nodes.Text(text, text)]) para = addnodes.compact_paragraph("", "", reference) ret_list = nodes.list_item("", para) return nodes.bullet_list("", ret_list) if bullet else ret_list
def build_toc(node, depth=1, main=False, title_visited=False): entries = [] for sectionnode in node: # EV: added or condition on 'main' and 'title_visited' # find all toctree nodes in this section and add them # to the toc (just copying the toctree node which is then # resolved in self.get_and_resolve_doctree) if isinstance(sectionnode, addnodes.only): onlynode = addnodes.only(expr=sectionnode['expr']) blist = build_toc(sectionnode, depth) if blist: onlynode += blist.children entries.append(onlynode) if not isinstance(sectionnode, nodes.section) or (main and title_visited): for toctreenode in traverse_in_section(sectionnode, addnodes.toctree): item = toctreenode.copy() entries.append(item) # important: do the inventory stuff self.note_toctree(docname, toctreenode) continue title = sectionnode[0] # copy the contents of the section title, but without references # and unnecessary stuff visitor = SphinxContentsFilter(document) title.walkabout(visitor) nodetext = visitor.get_entry_text() if not numentries[0]: # for the very first toc entry, don't add an anchor # as it is the file's title anyway anchorname = '' else: anchorname = '#' + sectionnode['ids'][0] numentries[0] += 1 reference = nodes.reference( '', '', internal=True, refuri=docname, anchorname=anchorname, *nodetext) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) if maxdepth == 0 or depth < maxdepth: # EV: set 'main' and 'title_visited' args item += build_toc(sectionnode, depth+1, main=main, title_visited=True) entries.append(item) if entries: return nodes.bullet_list('', *entries) return []
def sub(title, lst): if not lst: return None item, res, tmp = nodes.list_item(), addnodes.compact_paragraph(), [] res += nodes.strong(text=(title + ': ')) kwargs = { 'refdomain': 'cpp', 'refexplicit': False, 'reftype': 'class', } for it in lst: kwargs['reftarget'] = unicode(it.name) node = addnodes.pending_xref('', **kwargs) node += nodes.literal(text=it.name) tmp.extend([node, nodes.Text(', ')]) res.extend(tmp[:-1]) item += res return item
def class_results_to_node( key: str, elements: list[TableElement]) -> attributetablecolumn: title = attributetabletitle(key, key) ul = nodes.bullet_list("") for element in elements: ref = nodes.reference("", "", internal=True, refuri=f"#{element.fullname}", anchorname="", *[nodes.Text(element.label)]) para = addnodes.compact_paragraph("", "", ref) if element.badge is not None: ul.append(attributetable_item("", element.badge, para)) else: ul.append(attributetable_item("", para)) return attributetablecolumn("", title, ul)
def _build_toc_node(docname, anchor="anchor", text="test text", bullet=False): """ Create the node structure that Sphinx expects for TOC Tree entries. The ``bullet`` argument wraps it in a ``nodes.bullet_list``, which is how you nest TOC Tree entries. """ reference = nodes.reference( "", "", internal=True, refuri=docname, anchorname="#" + anchor, *[nodes.Text(text, text)] ) para = addnodes.compact_paragraph("", "", reference) ret_list = nodes.list_item("", para) return nodes.bullet_list("", ret_list) if bullet else ret_list
def run(self): populated = CPPAutoDocObject._populate(self) self.name = 'function' res, obj = CPPFunctionObject.run(self), self._get_obj() if populated: fieldlist, _empty = nodes.field_list(), True doc_args = [it for it in obj.signature if obj.brief('param_' + str(it.get_name()))] if doc_args: tmp = [] for it in doc_args: param_name = 'param_' + str(it.get_name()) node = addnodes.compact_paragraph() if obj.param_ways.get(param_name, None) is not None: node += nodes.literal(text='[{}] '.format( obj.param_ways[param_name] )) node += nodes.Text(obj.brief(param_name)[0]) tmp.append((it.name, node)) fieldlist += self.doc_field_types[0].make_field( [], # [it.type for it in doc_args], self._get_domain(), tmp, ) _empty = False def _simple_field(fieldlist, name, nb_): if obj.brief(name): fieldlist += self.doc_field_types[nb_].make_field( None, self._get_domain(), (None, [nodes.Text(it) for it in obj.brief(name)]) ) return False return True _empty =_simple_field(fieldlist, 'return', 1) and _empty _empty = _simple_field(fieldlist, 'pre', 3) and _empty _empty = _simple_field(fieldlist, 'post', 4) and _empty if not _empty: res[1][1].insert(0, fieldlist) if obj.details() and not _empty: para = nodes.paragraph() para += nodes.emphasis(text='Brief: ') para += nodes.Text(''.join(obj.brief())) res[1][1].insert(0, para) return res
def toc_insert(self, docname: str, tocnode: nodes.Node, node: nodes.Node, heading: List[nodes.Node]) -> None: for child in tocnode.children: if isinstance(child, nodes.bullet_list): blist = child break else: blist = nodes.bullet_list('') tocnode += blist reference = nodes.reference('', '', internal=True, refuri=docname, anchorname="#" + self.get_ref(node), *heading) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) # FIXME: find correct location blist.append(item)
def run(self) -> List[Node]: ncolumns = self.options.get('columns', 2) node = addnodes.compact_paragraph() node.document = self.state.document self.state.nested_parse(self.content, self.content_offset, node) if len(node.children) != 1 or not isinstance(node.children[0], nodes.bullet_list): reporter = self.state.document.reporter raise SphinxError('table_from_list content is not a list') fulllist = node.children[0] # fill list with empty items to have a number of entries # that is divisible by ncolumns if (len(fulllist) % ncolumns) != 0: missing = int(ncolumns - (len(fulllist) % ncolumns)) for i in range(0, missing): fulllist += list_item() table = nodes.table() tgroup = nodes.tgroup(cols=ncolumns) table += tgroup for i in range(ncolumns): tgroup += nodes.colspec(colwidth=1) tbody = nodes.tbody() tgroup += tbody current_row = nodes.row() for idx, cell in enumerate(fulllist.children): if len(current_row.children) == ncolumns: tbody += current_row current_row = nodes.row() entry = nodes.entry() current_row += entry if len(cell.children) > 0: entry += cell.children[0] tbody += current_row return [table]
def apply(self, **kwargs: Any) -> None: if self.config.html_compact_lists: return def check_refonly_list(node: Node) -> bool: """Check for list with only references in it.""" visitor = RefOnlyListChecker(self.document) try: node.walk(visitor) except nodes.NodeFound: return False else: return True for node in self.document.traverse(nodes.bullet_list): if check_refonly_list(node): for item in node.traverse(nodes.list_item): para = cast(nodes.paragraph, item[0]) ref = cast(nodes.reference, para[0]) compact_para = addnodes.compact_paragraph() compact_para += ref item.replace(para, compact_para)
def build_toc(node): entries = [] for subnode in node: if isinstance(subnode, addnodes.toctree): # just copy the toctree node which is then resolved # in self.get_and_resolve_doctree item = subnode.copy() entries.append(item) # do the inventory stuff self.note_toctree(docname, subnode) continue if not isinstance(subnode, nodes.section): continue title = subnode[0] # copy the contents of the section title, but without references # and unnecessary stuff visitor = SphinxContentsFilter(document) title.walkabout(visitor) nodetext = visitor.get_entry_text() if not numentries[0]: # for the very first toc entry, don't add an anchor # as it is the file's title anyway anchorname = '' else: anchorname = '#' + subnode['ids'][0] numentries[0] += 1 reference = nodes.reference('', '', refuri=docname, anchorname=anchorname, *nodetext) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) item += build_toc(subnode) entries.append(item) if entries: return nodes.bullet_list('', *entries) return []
def apply(self): env = self.document.settings.env if env.config.html_compact_lists: return def check_refonly_list(node): """Check for list with only references in it.""" visitor = RefOnlyListChecker(self.document) try: node.walk(visitor) except nodes.NodeFound: return False else: return True for node in self.document.traverse(nodes.bullet_list): if check_refonly_list(node): for item in node.traverse(nodes.list_item): para = item[0] ref = para[0] compact_para = addnodes.compact_paragraph() compact_para += ref item.replace(para, compact_para)
def extract_toc(fulltoc, selectors): entries = [] for refnode in fulltoc.traverse(nodes.reference): container = refnode.parent.parent if any(cls[:4] == 'ref-' and cls[4:] in selectors for cls in container['classes']): parent = container.parent new_parent = parent.deepcopy() del new_parent.children[:] new_parent += container entries.append(new_parent) parent.remove(container) if not parent.children: parent.parent.remove(parent) newnode = addnodes.compact_paragraph('', '') newnode.extend(entries) newnode['toctree'] = True return newnode
def run(self) -> List[Node]: ncolumns = self.options.get('columns', 2) node = addnodes.compact_paragraph() node.document = self.state.document self.state.nested_parse(self.content, self.content_offset, node) if len(node.children) != 1 or not isinstance(node.children[0], nodes.bullet_list): reporter = self.state.document.reporter raise SphinxError('table_from_list content is not a list') fulllist = node.children[0] if (len(fulllist) % ncolumns) != 0: raise SphinxError('number of list elements not a multiple of column number') table = nodes.table() tgroup = nodes.tgroup(cols=ncolumns) table += tgroup for i in range(ncolumns): tgroup += nodes.colspec(colwidth=1) tbody = nodes.tbody() tgroup += tbody current_row = nodes.row() for idx, cell in enumerate(fulllist.children): if len(current_row.children) == ncolumns: tbody += current_row current_row = nodes.row() entry = nodes.entry() current_row += entry if len(cell.children) > 0: entry += cell.children[0] tbody += current_row return [table]
def apply(self, **kwargs): # type: (Any) -> None if self.config.html_compact_lists: return def check_refonly_list(node): # type: (nodes.Node) -> bool """Check for list with only references in it.""" visitor = RefOnlyListChecker(self.document) try: node.walk(visitor) except nodes.NodeFound: return False else: return True for node in self.document.traverse(nodes.bullet_list): if check_refonly_list(node): for item in node.traverse(nodes.list_item): para = cast(nodes.paragraph, item[0]) ref = cast(nodes.reference, para[0]) compact_para = addnodes.compact_paragraph() compact_para += ref item.replace(para, compact_para)
def _entries_from_toctree(toctreenode, separate=False, subtree=False): """Return TOC entries for a toctree node.""" refs = [(e[0], to_unicode(e[1])) for e in toctreenode['entries']] entries = [] for (title, ref) in refs: try: if url_re.match(ref): reference = nodes.reference('', '', internal=False, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) toc = nodes.bullet_list('', item) elif ref == 'self': # 'self' refers to the document from which this # toctree originates ref = toctreenode['parent'] if not title: title = clean_astext(self.titles[ref]) reference = nodes.reference('', '', internal=True, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) # don't show subitems toc = nodes.bullet_list('', item) else: toc = self.tocs[ref].deepcopy() self.process_only_nodes(toc, builder, ref) # added 1.1 if title and toc.children and len(toc.children) == 1: child = toc.children[0] for refnode in child.traverse(nodes.reference): if refnode['refuri'] == ref and \ not refnode['anchorname']: refnode.children = [nodes.Text(title)] if not toc.children: # empty toc means: no titles will show up in the toctree self.warn(docname, 'toctree contains reference to document ' '%r that doesn\'t have a title: no link ' 'will be generated' % ref, toctreenode.line) except KeyError: # this is raised if the included file does not exist self.warn(docname, 'toctree contains reference to ' 'nonexisting document %r' % ref, toctreenode.line) else: # if titles_only is given, only keep the main title and # sub-toctrees if titles_only: # delete everything but the toplevel title(s) # and toctrees for toplevel in toc: # nodes with length 1 don't have any children anyway if len(toplevel) > 1: subtrees = toplevel.traverse(addnodes.toctree) toplevel[1][:] = subtrees # resolve all sub-toctrees for toctreenode in toc.traverse(addnodes.toctree): i = toctreenode.parent.index(toctreenode) + 1 for item in _entries_from_toctree(toctreenode, subtree=True): toctreenode.parent.insert(i, item) i += 1 toctreenode.parent.remove(toctreenode) if separate: entries.append(toc) else: entries.extend(toc.children) if not subtree and not separate: ret = nodes.bullet_list() ret += entries return [ret] return entries
def resolve_toctree(env, docname, builder, toctree, collapse=False): def _toctree_add_classes(node): for subnode in node.children: if isinstance(subnode, (addnodes.compact_paragraph, nodes.list_item, nodes.bullet_list)): _toctree_add_classes(subnode) elif isinstance(subnode, nodes.reference): # for <a>, identify which entries point to the current # document and therefore may not be collapsed if subnode['refuri'] == docname: list_item = subnode.parent.parent if not subnode['anchorname']: # give the whole branch a 'current' class # (useful for styling it differently) branchnode = subnode while branchnode: branchnode['classes'].append('current') branchnode = branchnode.parent # mark the list_item as "on current page" if subnode.parent.parent.get('iscurrent'): # but only if it's not already done return while subnode: subnode['iscurrent'] = True subnode = subnode.parent # Now mark all siblings as well and also give the # innermost expansion an extra class. list_item['classes'].append('active') for node in list_item.parent.children: node['classes'].append('relevant') def _entries_from_toctree(toctreenode, parents, subtree=False): refs = [(e[0], e[1]) for e in toctreenode['entries']] entries = [] for (title, ref) in refs: refdoc = None if url_re.match(ref): raise NotImplementedError('Not going to implement this (url)') elif ref == 'env': raise NotImplementedError('Not going to implement this (env)') else: if ref in parents: env.warn(ref, 'circular toctree references ' 'detected, ignoring: %s <- %s' % (ref, ' <- '.join(parents))) continue refdoc = ref toc = env.tocs[ref].deepcopy() env.process_only_nodes(toc, builder, ref) if title and toc.children and len(toc.children) == 1: child = toc.children[0] for refnode in child.traverse(nodes.reference): if refnode['refuri'] == ref and \ not refnode['anchorname']: refnode.children = [nodes.Text(title)] if not toc.children: # empty toc means: no titles will show up in the toctree env.warn_node( 'toctree contains reference to document %r that ' 'doesn\'t have a title: no link will be generated' % ref, toctreenode) # delete everything but the toplevel title(s) # and toctrees for toplevel in toc: # nodes with length 1 don't have any children anyway if len(toplevel) > 1: subtrees = toplevel.traverse(addnodes.toctree) toplevel[1][:] = subtrees # resolve all sub-toctrees for subtocnode in toc.traverse(addnodes.toctree): i = subtocnode.parent.index(subtocnode) + 1 for item in _entries_from_toctree(subtocnode, [refdoc] + parents, subtree=True): subtocnode.parent.insert(i, item) i += 1 subtocnode.parent.remove(subtocnode) entries.extend(toc.children) if not subtree: ret = nodes.bullet_list() ret += entries return [ret] return entries tocentries = _entries_from_toctree(toctree, []) if not tocentries: return None newnode = addnodes.compact_paragraph('', '') newnode.extend(tocentries) newnode['toctree'] = True _toctree_add_classes(newnode) for refnode in newnode.traverse(nodes.reference): if not url_re.match(refnode['refuri']): refnode.parent.parent['classes'].append('ref-' + refnode['refuri']) refnode['refuri'] = builder.get_relative_uri( docname, refnode['refuri']) + refnode['anchorname'] return newnode
def new_resolve_toctree_v122(self, docname, builder, toctree, prune=True, maxdepth=0, titles_only=False, collapse=False, includehidden=False): """Resolve a *toctree* node into individual bullet lists with titles as items, returning None (if no containing titles are found) or a new node. If *prune* is True, the tree is pruned to *maxdepth*, or if that is 0, to the value of the *maxdepth* option on the *toctree* node. If *titles_only* is True, only toplevel document titles will be in the resulting tree. If *collapse* is True, all branches not containing docname will be collapsed. """ if toctree.get('hidden', False) and not includehidden: return None # photron: prepare reverse toctree lookup to avoid expaning the whole # tree every time. only expand the path to the current document if not hasattr(self, 'monkey_reverse_toctree'): self.monkey_reverse_toctree = self.monkey_get_reverse_toctree() # photron: end # For reading the following two helper function, it is useful to keep # in mind the node structure of a toctree (using HTML-like node names # for brevity): # # <ul> # <li> # <p><a></p> # <p><a></p> # ... # <ul> # ... # </ul> # </li> # </ul> # # The transformation is made in two passes in order to avoid # interactions between marking and pruning the tree (see bug #1046). def _toctree_prune_v122(node, depth, maxdepth): """Utility: Cut a TOC at a specified depth.""" for subnode in node.children[:]: if isinstance(subnode, (addnodes.compact_paragraph, nodes.list_item)): # for <p> and <li>, just recurse _toctree_prune_v122(subnode, depth, maxdepth) elif isinstance(subnode, nodes.bullet_list): # for <ul>, determine if the depth is too large or if the # entry is to be collapsed if maxdepth > 0 and depth > maxdepth: subnode.parent.replace(subnode, []) else: mindepth = 2 # photron: keep the first level expanded, was set to 1 before # cull sub-entries whose parents aren't 'current' if (collapse and depth > mindepth and 'iscurrent' not in subnode.parent): subnode.parent.remove(subnode) else: # recurse on visible children _toctree_prune_v122(subnode, depth+1, maxdepth) def _toctree_add_classes_v122(node, depth): """Add 'toctree-l%d' and 'current' classes to the toctree.""" # photron: start if not hasattr(self, 'monkey_breadcrumbs'): self.monkey_breadcrumbs = {} # photron: end for subnode in node.children: if isinstance(subnode, (addnodes.compact_paragraph, nodes.list_item)): # for <p> and <li>, indicate the depth level and recurse subnode['classes'].append('toctree-l%d' % (depth-1)) _toctree_add_classes_v122(subnode, depth) elif isinstance(subnode, nodes.bullet_list): # for <ul>, just recurse _toctree_add_classes_v122(subnode, depth+1) elif isinstance(subnode, nodes.reference): # for <a>, identify which entries point to the current # document and therefore may not be collapsed if subnode['refuri'] == docname: if not subnode['anchorname']: # photron: start breadcrumbs = [] # photron: end # give the whole branch a 'current' class # (useful for styling it differently) branchnode = subnode while branchnode: branchnode['classes'].append('current') branchnode = branchnode.parent # photron: collect current path in toctree as breadcrumbs if branchnode and isinstance(branchnode, nodes.list_item): for c in branchnode.traverse(nodes.reference): if len(c.children) == 0: raise Exception('Missing reference text node id breadcrumbs for ' + docname) breadcrumbs = [(c['refuri'], c['anchorname'], c.children[0].astext())] + breadcrumbs break # photron: end # photron: sanity check if docname in self.monkey_breadcrumbs and self.monkey_breadcrumbs[docname] != breadcrumbs: raise Exception('Different breadcrumbs for ' + docname) self.monkey_breadcrumbs[docname] = breadcrumbs # photron: end # mark the list_item as "on current page" if subnode.parent.parent.get('iscurrent'): # but only if it's not already done return while subnode: subnode['iscurrent'] = True subnode = subnode.parent def _entries_from_toctree_v122(toctreenode, parents, separate=False, subtree=False, # photron: add forced_expand option to force expansion # one sublevel below the path to the current document forced_expand=False): # photron: end """Return TOC entries for a toctree node.""" refs = [(e[0], e[1]) for e in toctreenode['entries']] entries = [] for (title, ref) in refs: if title != None and title.startswith('~'): continue try: refdoc = None if url_re.match(ref): reference = nodes.reference('', '', internal=False, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) toc = nodes.bullet_list('', item) elif ref == 'self': # 'self' refers to the document from which this # toctree originates ref = toctreenode['parent'] if not title: title = clean_astext(self.titles[ref]) reference = nodes.reference('', '', internal=True, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) # don't show subitems toc = nodes.bullet_list('', item) else: if ref in parents: self.warn(ref, 'circular toctree references ' 'detected, ignoring: %s <- %s' % (ref, ' <- '.join(parents))) continue refdoc = ref toc = self.tocs[ref].deepcopy() self.process_only_nodes(toc, builder, ref) if title and toc.children and len(toc.children) == 1: child = toc.children[0] for refnode in child.traverse(nodes.reference): if refnode['refuri'] == ref and \ not refnode['anchorname']: refnode.children = [nodes.Text(title)] if not toc.children: # empty toc means: no titles will show up in the toctree self.warn_node( 'toctree contains reference to document %r that ' 'doesn\'t have a title: no link will be generated' % ref, toctreenode) except KeyError: # this is raised if the included file does not exist self.warn_node( 'toctree contains reference to nonexisting document %r' % ref, toctreenode) else: # if titles_only is given, only keep the main title and # sub-toctrees if titles_only: # delete everything but the toplevel title(s) # and toctrees for toplevel in toc: # nodes with length 1 don't have any children anyway if len(toplevel) > 1: subtrees = toplevel.traverse(addnodes.toctree) toplevel[1][:] = subtrees # resolve all sub-toctrees for toctreenode in toc.traverse(addnodes.toctree): if not (toctreenode.get('hidden', False) and not includehidden): # photron: use the reverse toctree lookup to only expand # nodes along the way to the current document if docname != 'index': if docname not in self.monkey_reverse_toctree: continue if not forced_expand and refdoc not in self.monkey_reverse_toctree[docname]: continue # photron: end # photron: force sublevel for the index and other toplevel documents, # also force it for one sublevel below the path to the current document next_forced_expand = \ docname == 'index' or \ len(self.monkey_reverse_toctree[docname]) == 0 or \ refdoc == self.monkey_reverse_toctree[docname][-1] # photron: end i = toctreenode.parent.index(toctreenode) + 1 for item in _entries_from_toctree_v122( toctreenode, [refdoc] + parents, subtree=True, # photron: start forced_expand=next_forced_expand): # photron: end toctreenode.parent.insert(i, item) i += 1 toctreenode.parent.remove(toctreenode) if separate: entries.append(toc) else: entries.extend(toc.children) if not subtree and not separate: ret = nodes.bullet_list() ret += entries return [ret] return entries maxdepth = maxdepth or toctree.get('maxdepth', -1) if not titles_only and toctree.get('titlesonly', False): titles_only = True if not includehidden and toctree.get('includehidden', False): includehidden = True # NOTE: previously, this was separate=True, but that leads to artificial # separation when two or more toctree entries form a logical unit, so # separating mode is no longer used -- it's kept here for history's sake tocentries = _entries_from_toctree_v122(toctree, [], separate=False, # photron: add forced_expand option to force expansion forced_expand=True) # photron: end if not tocentries: return None newnode = addnodes.compact_paragraph('', '', *tocentries) newnode['toctree'] = True # prune the tree to maxdepth, also set toc depth and current classes _toctree_add_classes_v122(newnode, 1) _toctree_prune_v122(newnode, 1, prune and maxdepth or 0) # set the target paths in the toctrees (they are not known at TOC # generation time) for refnode in newnode.traverse(nodes.reference): if not url_re.match(refnode['refuri']): refnode['refuri'] = builder.get_relative_uri( docname, refnode['refuri']) + refnode['anchorname'] # photron: empty refuri doesn't work in IE, use a # instead if len(refnode['refuri']) == 0: refnode['refuri'] = '#' # photron: end return newnode
def _entries_from_toctree_v122(toctreenode, parents, separate=False, subtree=False, # photron: add forced_expand option to force expansion # one sublevel below the path to the current document forced_expand=False): # photron: end """Return TOC entries for a toctree node.""" refs = [(e[0], e[1]) for e in toctreenode['entries']] entries = [] for (title, ref) in refs: if title != None and title.startswith('~'): continue try: refdoc = None if url_re.match(ref): reference = nodes.reference('', '', internal=False, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) toc = nodes.bullet_list('', item) elif ref == 'self': # 'self' refers to the document from which this # toctree originates ref = toctreenode['parent'] if not title: title = clean_astext(self.titles[ref]) reference = nodes.reference('', '', internal=True, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) # don't show subitems toc = nodes.bullet_list('', item) else: if ref in parents: self.warn(ref, 'circular toctree references ' 'detected, ignoring: %s <- %s' % (ref, ' <- '.join(parents))) continue refdoc = ref toc = self.tocs[ref].deepcopy() self.process_only_nodes(toc, builder, ref) if title and toc.children and len(toc.children) == 1: child = toc.children[0] for refnode in child.traverse(nodes.reference): if refnode['refuri'] == ref and \ not refnode['anchorname']: refnode.children = [nodes.Text(title)] if not toc.children: # empty toc means: no titles will show up in the toctree self.warn_node( 'toctree contains reference to document %r that ' 'doesn\'t have a title: no link will be generated' % ref, toctreenode) except KeyError: # this is raised if the included file does not exist self.warn_node( 'toctree contains reference to nonexisting document %r' % ref, toctreenode) else: # if titles_only is given, only keep the main title and # sub-toctrees if titles_only: # delete everything but the toplevel title(s) # and toctrees for toplevel in toc: # nodes with length 1 don't have any children anyway if len(toplevel) > 1: subtrees = toplevel.traverse(addnodes.toctree) toplevel[1][:] = subtrees # resolve all sub-toctrees for toctreenode in toc.traverse(addnodes.toctree): if not (toctreenode.get('hidden', False) and not includehidden): # photron: use the reverse toctree lookup to only expand # nodes along the way to the current document if docname != 'index': if docname not in self.monkey_reverse_toctree: continue if not forced_expand and refdoc not in self.monkey_reverse_toctree[docname]: continue # photron: end # photron: force sublevel for the index and other toplevel documents, # also force it for one sublevel below the path to the current document next_forced_expand = \ docname == 'index' or \ len(self.monkey_reverse_toctree[docname]) == 0 or \ refdoc == self.monkey_reverse_toctree[docname][-1] # photron: end i = toctreenode.parent.index(toctreenode) + 1 for item in _entries_from_toctree_v122( toctreenode, [refdoc] + parents, subtree=True, # photron: start forced_expand=next_forced_expand): # photron: end toctreenode.parent.insert(i, item) i += 1 toctreenode.parent.remove(toctreenode) if separate: entries.append(toc) else: entries.extend(toc.children) if not subtree and not separate: ret = nodes.bullet_list() ret += entries return [ret] return entries
def get_and_resolve_doctree(self, docname, builder, doctree=None): """Read the doctree from the pickle, resolve cross-references and toctrees and return it.""" if doctree is None: doctree = self.get_doctree(docname) # resolve all pending cross-references self.resolve_references(doctree, docname, builder) # now, resolve all toctree nodes def _entries_from_toctree(toctreenode, separate=False): """Return TOC entries for a toctree node.""" includefiles = map(str, toctreenode['includefiles']) entries = [] for includefile in includefiles: try: toc = self.tocs[includefile].deepcopy() except KeyError: # this is raised if the included file does not exist self.warn(docname, 'toctree contains ref to nonexisting ' 'file %r' % includefile) else: # resolve all sub-toctrees for toctreenode in toc.traverse(addnodes.toctree): i = toctreenode.parent.index(toctreenode) + 1 for item in _entries_from_toctree(toctreenode): toctreenode.parent.insert(i, item) i += 1 toctreenode.parent.remove(toctreenode) if separate: entries.append(toc) else: entries.extend(toc.children) return entries def _walk_depth(node, depth, maxdepth, titleoverrides): """Utility: Cut a TOC at a specified depth.""" for subnode in node.children[:]: if isinstance(subnode, (addnodes.compact_paragraph, nodes.list_item)): _walk_depth(subnode, depth, maxdepth, titleoverrides) elif isinstance(subnode, nodes.bullet_list): if depth > maxdepth: subnode.parent.replace(subnode, []) else: _walk_depth(subnode, depth+1, maxdepth, titleoverrides) for toctreenode in doctree.traverse(addnodes.toctree): maxdepth = toctreenode.get('maxdepth', -1) titleoverrides = toctreenode.get('includetitles', {}) tocentries = _entries_from_toctree(toctreenode, separate=True) if tocentries: newnode = addnodes.compact_paragraph('', '', *tocentries) # prune the tree to maxdepth and replace titles if maxdepth > 0: _walk_depth(newnode, 1, maxdepth, titleoverrides) # replace titles, if needed if titleoverrides: for refnode in newnode.traverse(nodes.reference): if refnode.get('anchorname', None): continue if refnode['refuri'] in titleoverrides: newtitle = titleoverrides[refnode['refuri']] refnode.children = [nodes.Text(newtitle)] toctreenode.replace_self(newnode) else: toctreenode.replace_self([]) # set the target paths in the toctrees (they are not known # at TOC generation time) for node in doctree.traverse(nodes.reference): if node.hasattr('anchorname'): # a TOC reference node['refuri'] = builder.get_relative_uri( docname, node['refuri']) + node['anchorname'] return doctree
def my_resolve_toctree(self, docname, builder, toctree, prune=True, maxdepth=0, titles_only=False, collapse=False, includehidden=False): """alter 'sphinx.environment.BuildEnvironment.resolve_toctree'. Very long copied function but only to replace one str() with unicode() :-( Note: Difference of this function between 1.0.7 and 1.1pre is only 1 line. search to see "added 1.1". Original description is following: Resolve a *toctree* node into individual bullet lists with titles as items, returning None (if no containing titles are found) or a new node. If *prune* is True, the tree is pruned to *maxdepth*, or if that is 0, to the value of the *maxdepth* option on the *toctree* node. If *titles_only* is True, only toplevel document titles will be in the resulting tree. If *collapse* is True, all branches not containing docname will be collapsed. """ if toctree.get('hidden', False) and not includehidden: return None def _walk_depth(node, depth, maxdepth): """Utility: Cut a TOC at a specified depth.""" # For reading this function, it is useful to keep in mind the node # structure of a toctree (using HTML-like node names for brevity): # # <ul> # <li> # <p><a></p> # <p><a></p> # ... # <ul> # ... # </ul> # </li> # </ul> for subnode in node.children[:]: if isinstance(subnode, (addnodes.compact_paragraph, nodes.list_item)): # for <p> and <li>, just indicate the depth level and # recurse to children subnode['classes'].append('toctree-l%d' % (depth-1)) _walk_depth(subnode, depth, maxdepth) elif isinstance(subnode, nodes.bullet_list): # for <ul>, determine if the depth is too large or if the # entry is to be collapsed if maxdepth > 0 and depth > maxdepth: subnode.parent.replace(subnode, []) else: # to find out what to collapse, *first* walk subitems, # since that determines which children point to the # current page _walk_depth(subnode, depth+1, maxdepth) # cull sub-entries whose parents aren't 'current' if (collapse and depth > 1 and 'iscurrent' not in subnode.parent): subnode.parent.remove(subnode) elif isinstance(subnode, nodes.reference): # for <a>, identify which entries point to the current # document and therefore may not be collapsed if subnode['refuri'] == docname: if not subnode['anchorname']: # give the whole branch a 'current' class # (useful for styling it differently) branchnode = subnode while branchnode: branchnode['classes'].append('current') branchnode = branchnode.parent # mark the list_item as "on current page" if subnode.parent.parent.get('iscurrent'): # but only if it's not already done return while subnode: subnode['iscurrent'] = True subnode = subnode.parent def _entries_from_toctree(toctreenode, separate=False, subtree=False): """Return TOC entries for a toctree node.""" refs = [(e[0], to_unicode(e[1])) for e in toctreenode['entries']] entries = [] for (title, ref) in refs: try: if url_re.match(ref): reference = nodes.reference('', '', internal=False, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) toc = nodes.bullet_list('', item) elif ref == 'self': # 'self' refers to the document from which this # toctree originates ref = toctreenode['parent'] if not title: title = clean_astext(self.titles[ref]) reference = nodes.reference('', '', internal=True, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) # don't show subitems toc = nodes.bullet_list('', item) else: toc = self.tocs[ref].deepcopy() self.process_only_nodes(toc, builder, ref) # added 1.1 if title and toc.children and len(toc.children) == 1: child = toc.children[0] for refnode in child.traverse(nodes.reference): if refnode['refuri'] == ref and \ not refnode['anchorname']: refnode.children = [nodes.Text(title)] if not toc.children: # empty toc means: no titles will show up in the toctree self.warn(docname, 'toctree contains reference to document ' '%r that doesn\'t have a title: no link ' 'will be generated' % ref, toctreenode.line) except KeyError: # this is raised if the included file does not exist self.warn(docname, 'toctree contains reference to ' 'nonexisting document %r' % ref, toctreenode.line) else: # if titles_only is given, only keep the main title and # sub-toctrees if titles_only: # delete everything but the toplevel title(s) # and toctrees for toplevel in toc: # nodes with length 1 don't have any children anyway if len(toplevel) > 1: subtrees = toplevel.traverse(addnodes.toctree) toplevel[1][:] = subtrees # resolve all sub-toctrees for toctreenode in toc.traverse(addnodes.toctree): i = toctreenode.parent.index(toctreenode) + 1 for item in _entries_from_toctree(toctreenode, subtree=True): toctreenode.parent.insert(i, item) i += 1 toctreenode.parent.remove(toctreenode) if separate: entries.append(toc) else: entries.extend(toc.children) if not subtree and not separate: ret = nodes.bullet_list() ret += entries return [ret] return entries maxdepth = maxdepth or toctree.get('maxdepth', -1) if not titles_only and toctree.get('titlesonly', False): titles_only = True # NOTE: previously, this was separate=True, but that leads to artificial # separation when two or more toctree entries form a logical unit, so # separating mode is no longer used -- it's kept here for history's sake tocentries = _entries_from_toctree(toctree, separate=False) if not tocentries: return None newnode = addnodes.compact_paragraph('', '', *tocentries) newnode['toctree'] = True # prune the tree to maxdepth and replace titles, also set level classes _walk_depth(newnode, 1, prune and maxdepth or 0) # set the target paths in the toctrees (they are not known at TOC # generation time) for refnode in newnode.traverse(nodes.reference): if not url_re.match(refnode['refuri']): refnode['refuri'] = builder.get_relative_uri( docname, refnode['refuri']) + refnode['anchorname'] return newnode
def _entries_from_toctree(toctreenode, parents, separate=False, subtree=False): """Return TOC entries for a toctree node.""" refs = [(e[0], e[1]) for e in toctreenode['entries']] entries = [] for (title, ref) in refs: try: refdoc = None if url_re.match(ref): if title is None: title = ref reference = nodes.reference('', '', internal=False, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) toc = nodes.bullet_list('', item) elif ref == 'self': # 'self' refers to the document from which this # toctree originates ref = toctreenode['parent'] if not title: title = clean_astext(self.env.titles[ref]) reference = nodes.reference('', '', internal=True, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) # don't show subitems toc = nodes.bullet_list('', item) else: if ref in parents: logger.warning( 'circular toctree references ' 'detected, ignoring: %s <- %s', ref, ' <- '.join(parents), location=ref) continue refdoc = ref toc = self.tocs[ref].deepcopy() maxdepth = self.env.metadata[ref].get('tocdepth', 0) if ref not in toctree_ancestors or (prune and maxdepth > 0): self._toctree_prune(toc, 2, maxdepth, collapse) process_only_nodes(toc, builder.tags) if title and toc.children and len(toc.children) == 1: child = toc.children[0] for refnode in child.traverse(nodes.reference): if refnode['refuri'] == ref and \ not refnode['anchorname']: refnode.children = [nodes.Text(title)] if not toc.children: # empty toc means: no titles will show up in the toctree logger.warning( 'toctree contains reference to document %r that ' 'doesn\'t have a title: no link will be generated', ref, location=toctreenode) except KeyError: # this is raised if the included file does not exist logger.warning( 'toctree contains reference to nonexisting document %r', ref, location=toctreenode) else: # if titles_only is given, only keep the main title and # sub-toctrees if titles_only: # delete everything but the toplevel title(s) # and toctrees for toplevel in toc: # nodes with length 1 don't have any children anyway if len(toplevel) > 1: subtrees = toplevel.traverse(addnodes.toctree) if subtrees: toplevel[1][:] = subtrees else: toplevel.pop(1) # resolve all sub-toctrees for subtocnode in toc.traverse(addnodes.toctree): if not (subtocnode.get('hidden', False) and not includehidden): i = subtocnode.parent.index(subtocnode) + 1 for item in _entries_from_toctree( subtocnode, [refdoc] + parents, subtree=True): subtocnode.parent.insert(i, item) i += 1 subtocnode.parent.remove(subtocnode) if separate: entries.append(toc) else: entries.extend(toc.children) if not subtree and not separate: ret = nodes.bullet_list() ret += entries return [ret] return entries
def _entries_from_toctree(toctreenode, parents, separate=False, subtree=False): """Return TOC entries for a toctree node.""" refs = [(e[0], e[1]) for e in toctreenode['entries']] entries = [] for (title, ref) in refs: try: refdoc = None if url_re.match(ref): if title is None: title = ref reference = nodes.reference('', '', internal=False, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) toc = nodes.bullet_list('', item) elif ref == 'self': # 'self' refers to the document from which this # toctree originates ref = toctreenode['parent'] if not title: title = clean_astext(self.titles[ref]) reference = nodes.reference('', '', internal=True, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) # don't show subitems toc = nodes.bullet_list('', item) else: if ref in parents: self.env.warn(ref, 'circular toctree references ' 'detected, ignoring: %s <- %s' % (ref, ' <- '.join(parents))) continue refdoc = ref toc = self.tocs[ref].deepcopy() maxdepth = self.env.metadata[ref].get('tocdepth', 0) if ref not in toctree_ancestors or (prune and maxdepth > 0): self._toctree_prune(toc, 2, maxdepth, collapse) process_only_nodes(toc, builder.tags, warn_node=self.env.warn_node) if title and toc.children and len(toc.children) == 1: child = toc.children[0] for refnode in child.traverse(nodes.reference): if refnode['refuri'] == ref and \ not refnode['anchorname']: refnode.children = [nodes.Text(title)] if not toc.children: # empty toc means: no titles will show up in the toctree self.env.warn_node( 'toctree contains reference to document %r that ' 'doesn\'t have a title: no link will be generated' % ref, toctreenode) except KeyError: # this is raised if the included file does not exist self.env.warn_node( 'toctree contains reference to nonexisting document %r' % ref, toctreenode) else: # if titles_only is given, only keep the main title and # sub-toctrees if titles_only: # delete everything but the toplevel title(s) # and toctrees for toplevel in toc: # nodes with length 1 don't have any children anyway if len(toplevel) > 1: subtrees = toplevel.traverse(addnodes.toctree) if subtrees: toplevel[1][:] = subtrees else: toplevel.pop(1) # resolve all sub-toctrees for subtocnode in toc.traverse(addnodes.toctree): if not (subtocnode.get('hidden', False) and not includehidden): i = subtocnode.parent.index(subtocnode) + 1 for item in _entries_from_toctree( subtocnode, [refdoc] + parents, subtree=True): subtocnode.parent.insert(i, item) i += 1 subtocnode.parent.remove(subtocnode) if separate: entries.append(toc) else: entries.extend(toc.children) if not subtree and not separate: ret = nodes.bullet_list() ret += entries return [ret] return entries
def resolve_toctree(self, docname, builder, toctree, prune=True, maxdepth=0, titles_only=False, collapse=False, includehidden=False): # type: (unicode, Builder, addnodes.toctree, bool, int, bool, bool, bool) -> nodes.Node """Resolve a *toctree* node into individual bullet lists with titles as items, returning None (if no containing titles are found) or a new node. If *prune* is True, the tree is pruned to *maxdepth*, or if that is 0, to the value of the *maxdepth* option on the *toctree* node. If *titles_only* is True, only toplevel document titles will be in the resulting tree. If *collapse* is True, all branches not containing docname will be collapsed. """ if toctree.get('hidden', False) and not includehidden: return None # For reading the following two helper function, it is useful to keep # in mind the node structure of a toctree (using HTML-like node names # for brevity): # # <ul> # <li> # <p><a></p> # <p><a></p> # ... # <ul> # ... # </ul> # </li> # </ul> # # The transformation is made in two passes in order to avoid # interactions between marking and pruning the tree (see bug #1046). toctree_ancestors = self.get_toctree_ancestors(docname) def _toctree_add_classes(node, depth): """Add 'toctree-l%d' and 'current' classes to the toctree.""" for subnode in node.children: if isinstance(subnode, (addnodes.compact_paragraph, nodes.list_item)): # for <p> and <li>, indicate the depth level and recurse subnode['classes'].append('toctree-l%d' % (depth-1)) _toctree_add_classes(subnode, depth) elif isinstance(subnode, nodes.bullet_list): # for <ul>, just recurse _toctree_add_classes(subnode, depth+1) elif isinstance(subnode, nodes.reference): # for <a>, identify which entries point to the current # document and therefore may not be collapsed if subnode['refuri'] == docname: if not subnode['anchorname']: # give the whole branch a 'current' class # (useful for styling it differently) branchnode = subnode while branchnode: branchnode['classes'].append('current') branchnode = branchnode.parent # mark the list_item as "on current page" if subnode.parent.parent.get('iscurrent'): # but only if it's not already done return while subnode: subnode['iscurrent'] = True subnode = subnode.parent def _entries_from_toctree(toctreenode, parents, separate=False, subtree=False): """Return TOC entries for a toctree node.""" refs = [(e[0], e[1]) for e in toctreenode['entries']] entries = [] for (title, ref) in refs: try: refdoc = None if url_re.match(ref): if title is None: title = ref reference = nodes.reference('', '', internal=False, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) toc = nodes.bullet_list('', item) elif ref == 'self': # 'self' refers to the document from which this # toctree originates ref = toctreenode['parent'] if not title: title = clean_astext(self.titles[ref]) reference = nodes.reference('', '', internal=True, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) # don't show subitems toc = nodes.bullet_list('', item) else: if ref in parents: self.env.warn(ref, 'circular toctree references ' 'detected, ignoring: %s <- %s' % (ref, ' <- '.join(parents))) continue refdoc = ref toc = self.tocs[ref].deepcopy() maxdepth = self.env.metadata[ref].get('tocdepth', 0) if ref not in toctree_ancestors or (prune and maxdepth > 0): self._toctree_prune(toc, 2, maxdepth, collapse) process_only_nodes(toc, builder.tags, warn_node=self.env.warn_node) if title and toc.children and len(toc.children) == 1: child = toc.children[0] for refnode in child.traverse(nodes.reference): if refnode['refuri'] == ref and \ not refnode['anchorname']: refnode.children = [nodes.Text(title)] if not toc.children: # empty toc means: no titles will show up in the toctree self.env.warn_node( 'toctree contains reference to document %r that ' 'doesn\'t have a title: no link will be generated' % ref, toctreenode) except KeyError: # this is raised if the included file does not exist self.env.warn_node( 'toctree contains reference to nonexisting document %r' % ref, toctreenode) else: # if titles_only is given, only keep the main title and # sub-toctrees if titles_only: # delete everything but the toplevel title(s) # and toctrees for toplevel in toc: # nodes with length 1 don't have any children anyway if len(toplevel) > 1: subtrees = toplevel.traverse(addnodes.toctree) if subtrees: toplevel[1][:] = subtrees else: toplevel.pop(1) # resolve all sub-toctrees for subtocnode in toc.traverse(addnodes.toctree): if not (subtocnode.get('hidden', False) and not includehidden): i = subtocnode.parent.index(subtocnode) + 1 for item in _entries_from_toctree( subtocnode, [refdoc] + parents, subtree=True): subtocnode.parent.insert(i, item) i += 1 subtocnode.parent.remove(subtocnode) if separate: entries.append(toc) else: entries.extend(toc.children) if not subtree and not separate: ret = nodes.bullet_list() ret += entries return [ret] return entries maxdepth = maxdepth or toctree.get('maxdepth', -1) if not titles_only and toctree.get('titlesonly', False): titles_only = True if not includehidden and toctree.get('includehidden', False): includehidden = True # NOTE: previously, this was separate=True, but that leads to artificial # separation when two or more toctree entries form a logical unit, so # separating mode is no longer used -- it's kept here for history's sake tocentries = _entries_from_toctree(toctree, [], separate=False) if not tocentries: return None newnode = addnodes.compact_paragraph('', '') caption = toctree.attributes.get('caption') if caption: caption_node = nodes.caption(caption, '', *[nodes.Text(caption)]) caption_node.line = toctree.line caption_node.source = toctree.source caption_node.rawsource = toctree['rawcaption'] if hasattr(toctree, 'uid'): # move uid to caption_node to translate it caption_node.uid = toctree.uid del toctree.uid newnode += caption_node newnode.extend(tocentries) newnode['toctree'] = True # prune the tree to maxdepth, also set toc depth and current classes _toctree_add_classes(newnode, 1) self._toctree_prune(newnode, 1, prune and maxdepth or 0, collapse) if len(newnode[-1]) == 0: # No titles found return None # set the target paths in the toctrees (they are not known at TOC # generation time) for refnode in newnode.traverse(nodes.reference): if not url_re.match(refnode['refuri']): refnode['refuri'] = builder.get_relative_uri( docname, refnode['refuri']) + refnode['anchorname'] return newnode
def __init__(self, *args, **kwargs): StandaloneHTMLBuilder.__init__(self, *args, **kwargs) self.toctrees = {} self.index_node = nodes.list_item('', addnodes.compact_paragraph(''))
def resolve_toctree(self, docname, builder, toctree, prune=True, maxdepth=0, titles_only=False, collapse=False, includehidden=False): # type: (unicode, Builder, addnodes.toctree, bool, int, bool, bool, bool) -> nodes.Node """Resolve a *toctree* node into individual bullet lists with titles as items, returning None (if no containing titles are found) or a new node. If *prune* is True, the tree is pruned to *maxdepth*, or if that is 0, to the value of the *maxdepth* option on the *toctree* node. If *titles_only* is True, only toplevel document titles will be in the resulting tree. If *collapse* is True, all branches not containing docname will be collapsed. """ if toctree.get('hidden', False) and not includehidden: return None # For reading the following two helper function, it is useful to keep # in mind the node structure of a toctree (using HTML-like node names # for brevity): # # <ul> # <li> # <p><a></p> # <p><a></p> # ... # <ul> # ... # </ul> # </li> # </ul> # # The transformation is made in two passes in order to avoid # interactions between marking and pruning the tree (see bug #1046). toctree_ancestors = self.get_toctree_ancestors(docname) def _toctree_add_classes(node, depth): """Add 'toctree-l%d' and 'current' classes to the toctree.""" for subnode in node.children: if isinstance(subnode, (addnodes.compact_paragraph, nodes.list_item)): # for <p> and <li>, indicate the depth level and recurse subnode['classes'].append('toctree-l%d' % (depth - 1)) _toctree_add_classes(subnode, depth) elif isinstance(subnode, nodes.bullet_list): # for <ul>, just recurse _toctree_add_classes(subnode, depth + 1) elif isinstance(subnode, nodes.reference): # for <a>, identify which entries point to the current # document and therefore may not be collapsed if subnode['refuri'] == docname: if not subnode['anchorname']: # give the whole branch a 'current' class # (useful for styling it differently) branchnode = subnode while branchnode: branchnode['classes'].append('current') branchnode = branchnode.parent # mark the list_item as "on current page" if subnode.parent.parent.get('iscurrent'): # but only if it's not already done return while subnode: subnode['iscurrent'] = True subnode = subnode.parent def _entries_from_toctree(toctreenode, parents, separate=False, subtree=False): """Return TOC entries for a toctree node.""" refs = [(e[0], e[1]) for e in toctreenode['entries']] entries = [] for (title, ref) in refs: try: refdoc = None if url_re.match(ref): if title is None: title = ref reference = nodes.reference('', '', internal=False, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) toc = nodes.bullet_list('', item) elif ref == 'self': # 'self' refers to the document from which this # toctree originates ref = toctreenode['parent'] if not title: title = clean_astext(self.env.titles[ref]) reference = nodes.reference('', '', internal=True, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) # don't show subitems toc = nodes.bullet_list('', item) else: if ref in parents: logger.warning( 'circular toctree references ' 'detected, ignoring: %s <- %s', ref, ' <- '.join(parents), location=ref) continue refdoc = ref toc = self.tocs[ref].deepcopy() maxdepth = self.env.metadata[ref].get('tocdepth', 0) if ref not in toctree_ancestors or (prune and maxdepth > 0): self._toctree_prune(toc, 2, maxdepth, collapse) process_only_nodes(toc, builder.tags) if title and toc.children and len(toc.children) == 1: child = toc.children[0] for refnode in child.traverse(nodes.reference): if refnode['refuri'] == ref and \ not refnode['anchorname']: refnode.children = [nodes.Text(title)] if not toc.children: # empty toc means: no titles will show up in the toctree logger.warning( 'toctree contains reference to document %r that ' 'doesn\'t have a title: no link will be generated', ref, location=toctreenode) except KeyError: # this is raised if the included file does not exist logger.warning( 'toctree contains reference to nonexisting document %r', ref, location=toctreenode) else: # if titles_only is given, only keep the main title and # sub-toctrees if titles_only: # delete everything but the toplevel title(s) # and toctrees for toplevel in toc: # nodes with length 1 don't have any children anyway if len(toplevel) > 1: subtrees = toplevel.traverse(addnodes.toctree) if subtrees: toplevel[1][:] = subtrees else: toplevel.pop(1) # resolve all sub-toctrees for subtocnode in toc.traverse(addnodes.toctree): if not (subtocnode.get('hidden', False) and not includehidden): i = subtocnode.parent.index(subtocnode) + 1 for item in _entries_from_toctree( subtocnode, [refdoc] + parents, subtree=True): subtocnode.parent.insert(i, item) i += 1 subtocnode.parent.remove(subtocnode) if separate: entries.append(toc) else: entries.extend(toc.children) if not subtree and not separate: ret = nodes.bullet_list() ret += entries return [ret] return entries maxdepth = maxdepth or toctree.get('maxdepth', -1) if not titles_only and toctree.get('titlesonly', False): titles_only = True if not includehidden and toctree.get('includehidden', False): includehidden = True # NOTE: previously, this was separate=True, but that leads to artificial # separation when two or more toctree entries form a logical unit, so # separating mode is no longer used -- it's kept here for history's sake tocentries = _entries_from_toctree(toctree, [], separate=False) if not tocentries: return None newnode = addnodes.compact_paragraph('', '') caption = toctree.attributes.get('caption') if caption: caption_node = nodes.caption(caption, '', *[nodes.Text(caption)]) caption_node.line = toctree.line caption_node.source = toctree.source caption_node.rawsource = toctree['rawcaption'] if hasattr(toctree, 'uid'): # move uid to caption_node to translate it caption_node.uid = toctree.uid del toctree.uid newnode += caption_node newnode.extend(tocentries) newnode['toctree'] = True # prune the tree to maxdepth, also set toc depth and current classes _toctree_add_classes(newnode, 1) self._toctree_prune(newnode, 1, prune and maxdepth or 0, collapse) if len(newnode[-1]) == 0: # No titles found return None # set the target paths in the toctrees (they are not known at TOC # generation time) for refnode in newnode.traverse(nodes.reference): if not url_re.match(refnode['refuri']): refnode['refuri'] = builder.get_relative_uri( docname, refnode['refuri']) + refnode['anchorname'] return newnode
def _entries_from_toctree( toctreenode, parents, separate=False, subtree=False, # photron: add forced_expand option to force expansion # one sublevel below the path to the current document forced_expand=False): # photron: end """Return TOC entries for a toctree node.""" refs = [(e[0], e[1]) for e in toctreenode['entries']] entries = [] for (title, ref) in refs: try: refdoc = None if url_re.match(ref): reference = nodes.reference('', '', internal=False, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) toc = nodes.bullet_list('', item) elif ref == 'self': # 'self' refers to the document from which this # toctree originates ref = toctreenode['parent'] if not title: title = clean_astext(self.titles[ref]) reference = nodes.reference('', '', internal=True, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) # don't show subitems toc = nodes.bullet_list('', item) else: if ref in parents: self.warn( ref, 'circular toctree references ' 'detected, ignoring: %s <- %s' % (ref, ' <- '.join(parents))) continue refdoc = ref toc = self.tocs[ref].deepcopy() self.process_only_nodes(toc, builder, ref) if title and toc.children and len(toc.children) == 1: child = toc.children[0] for refnode in child.traverse(nodes.reference): if refnode['refuri'] == ref and \ not refnode['anchorname']: refnode.children = [nodes.Text(title)] if not toc.children: # empty toc means: no titles will show up in the toctree self.warn_node( 'toctree contains reference to document %r that ' 'doesn\'t have a title: no link will be generated' % ref, toctreenode) except KeyError: # this is raised if the included file does not exist self.warn_node( 'toctree contains reference to nonexisting document %r' % ref, toctreenode) else: # if titles_only is given, only keep the main title and # sub-toctrees if titles_only: # delete everything but the toplevel title(s) # and toctrees for toplevel in toc: # nodes with length 1 don't have any children anyway if len(toplevel) > 1: subtrees = toplevel.traverse(addnodes.toctree) toplevel[1][:] = subtrees # resolve all sub-toctrees for toctreenode in toc.traverse(addnodes.toctree): if not (toctreenode.get('hidden', False) and not includehidden): # photron: use the reverse toctree lookup to only expand # nodes along the way to the current document if docname != 'index': if docname not in self.monkey_reverse_toctree: continue if not forced_expand and refdoc not in self.monkey_reverse_toctree[ docname]: continue # photron: end # photron: force sublevel for the index and other toplevel documents, # also force it for one sublevel below the path to the current document next_forced_expand = \ docname == 'index' or \ len(self.monkey_reverse_toctree[docname]) == 0 or \ refdoc == self.monkey_reverse_toctree[docname][-1] # photron: end i = toctreenode.parent.index(toctreenode) + 1 for item in _entries_from_toctree( toctreenode, [refdoc] + parents, subtree=True, # photron: start forced_expand=next_forced_expand): # photron: end toctreenode.parent.insert(i, item) i += 1 toctreenode.parent.remove(toctreenode) if separate: entries.append(toc) else: entries.extend(toc.children) if not subtree and not separate: ret = nodes.bullet_list() ret += entries return [ret] return entries
def _entries_from_toctree(self, docname, toctreenode, separate=False, subtree=True): """ Copied from sphinx.environment. Modified to utilize list items instead of the old version which had an independent bullet_list for each entry. """ refs = [(e[0], str(e[1])) for e in toctreenode['entries']] # EV: instead of a [], use a bullet_list entries = nodes.bullet_list() for (title, ref) in refs: try: if url_re.match(ref): reference = nodes.reference('', '', internal=False, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) toc = nodes.bullet_list('', item) elif ref == 'self': # 'self' refers to the document from which this # toctree originates ref = toctreenode['parent'] if not title: title = clean_astext(self.titles[ref]) reference = nodes.reference('', '', internal=True, refuri=ref, anchorname='', *[nodes.Text(title)]) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) # don't show subitems toc = nodes.bullet_list('', item) else: # EV: get the tocs reference using self.env.main_tocs instead of just # self.tocs #toc = self.tocs[ref].deepcopy() toc = self.env.main_tocs[ref].deepcopy() if title and toc.children and len(toc.children) == 1: child = toc.children[0] for refnode in child.traverse(nodes.reference): if refnode['refuri'] == ref and not refnode['anchorname']: refnode.children = [nodes.Text(title)] if not toc.children: # empty toc means: no titles will show up in the toctree self.warn(docname, 'toctree contains reference to document ' '%r that doesn\'t have a title: no link ' 'will be generated' % ref) except KeyError: # this is raised if the included file does not exist self.warn(docname, 'toctree contains reference to ' 'nonexisting document %r' % ref) else: # EV: copied over from 0.6.3, but outside of Environment, we don't have the # titles_only var. # # if titles_only is given, only keep the main title and # # sub-toctrees # if titles_only: # # delete everything but the toplevel title(s) # # and toctrees # for toplevel in toc: # # nodes with length 1 don't have any children anyway # if len(toplevel) > 1: # subtrees = toplevel.traverse(addnodes.toctree) # toplevel[1][:] = subtrees # resolve all sub-toctrees for toctreenode in toc.traverse(addnodes.toctree): #i = toctreenode.parent.index(toctreenode) + 1 #for item in self._entries_from_toctree(toctreenode, subtree=True): # toctreenode.parent.insert(i, item) # i += 1 #toctreenode.parent.remove(toctreenode) toctreenode.parent.replace_self( self._entries_from_toctree(docname, toctreenode, subtree=True)) # EV: append each child as a list item in the bullet_list. #if separate: # entries.append(toc) #else: # entries.extend(toc.children) for child in toc.children: entries.append(child) # EV: pass the entries in as a single element instead of a list of elements. # if not subtree and not separate: # ret = nodes.bullet_list() # ret += entries # return [ret] # return entries return addnodes.compact_paragraph('', '', entries)
def get_entry(node): para = addnodes.compact_paragraph() para += node entry = nodes.entry() entry += para return entry