我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用docutils.nodes.section()。
def update_section_numbers(self, node, prefix=(), depth=0): depth += 1 if prefix: sectnum = 1 else: sectnum = self.startvalue for child in node: if isinstance(child, nodes.section): numbers = prefix + (str(sectnum),) title = child[0] # Use for spacing: generated = nodes.generated( '', (self.prefix + '.'.join(numbers) + self.suffix + u'\u00a0' * 3), classes=['sectnum']) title.insert(0, generated) title['auto'] = 1 if depth < self.maxdepth: self.update_section_numbers(child, numbers, depth) sectnum += 1
def apply(self): pending = self.startnode parent = pending.parent child = pending while parent: # Check for appropriate following siblings: for index in range(parent.index(child) + 1, len(parent)): element = parent[index] if (isinstance(element, nodes.Invisible) or isinstance(element, nodes.system_message)): continue element['classes'] += pending.details['class'] pending.parent.remove(pending) return else: # At end of section or container; apply to sibling child = parent parent = parent.parent error = self.document.reporter.error( 'No suitable element following "%s" directive' % pending.details['directive'], nodes.literal_block(pending.rawsource, pending.rawsource), line=pending.line) pending.replace_self(error)
def visit_table(self, node): self.requirements['table'] = PreambleCmds.table if self.active_table.is_open(): self.table_stack.append(self.active_table) # nesting longtable does not work (e.g. 2007-04-18) self.active_table = Table(self,'tabular') # A longtable moves before \paragraph and \subparagraph # section titles if it immediately follows them: if (self.active_table._latex_type == 'longtable' and isinstance(node.parent, nodes.section) and node.parent.index(node) == 1 and self.d_class.section(self.section_level).find('paragraph') != -1): self.out.append('\\leavevmode') self.active_table.open() self.active_table.set_table_style(self.settings.table_style, node['classes']) if 'align' in node: self.active_table.set('align', node['align']) if self.active_table.borders == 'booktabs': self.requirements['booktabs'] = r'\usepackage{booktabs}' self.push_output_collector([])
def new_subsection(self, title, lineno, messages): """Append new subsection to document tree. On return, check level.""" memo = self.memo mylevel = memo.section_level memo.section_level += 1 section_node = nodes.section() self.parent += section_node textnodes, title_messages = self.inline_text(title, lineno) titlenode = nodes.title(title, '', *textnodes) name = normalize_name(titlenode.astext()) section_node['names'].append(name) section_node += titlenode section_node += messages section_node += title_messages self.document.note_implicit_target(section_node, section_node) offset = self.state_machine.line_offset + 1 absoffset = self.state_machine.abs_line_offset() + 1 newabsoffset = self.nested_parse( self.state_machine.input_lines[offset:], input_offset=absoffset, node=section_node, match_titles=True) self.goto_line(newabsoffset) if memo.section_level <= mylevel: # can't handle next section? raise EOFError # bubble up to supersection # reset section_level; next pass will detect it properly memo.section_level = mylevel
def line(self, match, context, next_state): """Section title overline or transition marker.""" if self.state_machine.match_titles: return [match.string], 'Line', [] elif match.string.strip() == '::': raise statemachine.TransitionCorrection('text') elif len(match.string.strip()) < 4: msg = self.reporter.info( 'Unexpected possible title overline or transition.\n' "Treating it as ordinary text because it's so short.", line=self.state_machine.abs_line_number()) self.parent += msg raise statemachine.TransitionCorrection('text') else: blocktext = self.state_machine.line msg = self.reporter.severe( 'Unexpected section title or transition.', nodes.literal_block(blocktext, blocktext), line=self.state_machine.abs_line_number()) self.parent += msg return [], next_state, []
def new_subsection(self, title, lineno, messages, source, style): memo = self.memo mylevel = memo.section_level memo.section_level += 1 section_node = nodes.section() self.parent += section_node textnodes, title_messages = self.inline_text(title, lineno) titlenode = nodes.title(title, '', *textnodes) titlenode.realsource = source titlenode.style = style name = normalize_name(titlenode.astext()) section_node['names'].append(name) section_node += titlenode section_node += messages section_node += title_messages self.document.note_implicit_target(section_node, section_node) offset = self.state_machine.line_offset + 1 absoffset = self.state_machine.abs_line_offset() + 1 newabsoffset = self.nested_parse( self.state_machine.input_lines[offset:], input_offset=absoffset, node=section_node, match_titles=True) self.goto_line(newabsoffset) if memo.section_level <= mylevel: raise EOFError memo.section_level = mylevel
def run(self): # pragma: no cover """Called by Sphinx to generate documentation for this directive.""" if self.directive_name is None: raise NotImplementedError('directive_name must be implemented by ' 'subclasses of BaseDirective') env, state = self._prepare_env() state.doc_names.add(env.docname) directive_name = '<{}>'.format(self.directive_name) node = nodes.section() node.document = self.state.document result = ViewList() for line in self._render_rst(): if line.startswith(HEADING_TOKEN): # Remove heading token, then append 2 lines, one with # the heading text, and the other with the dashes to # underline the heading. heading = line[HEADING_TOKEN_LENGTH:] result.append(heading, directive_name) result.append('-' * len(heading), directive_name) else: result.append(line, directive_name) nested_parse_with_titles(self.state, result, node) return node.children
def visit_table(self, node): self.requirements['table'] = PreambleCmds.table if self.active_table.is_open(): self.table_stack.append(self.active_table) # nesting longtable does not work (e.g. 2007-04-18) self.active_table = Table(self,'tabular',self.settings.table_style) # A longtable moves before \paragraph and \subparagraph # section titles if it immediately follows them: if (self.active_table._latex_type == 'longtable' and isinstance(node.parent, nodes.section) and node.parent.index(node) == 1 and self.d_class.section(self.section_level).find('paragraph') != -1): self.out.append('\\leavevmode') self.active_table.open() for cls in node['classes']: self.active_table.set_table_style(cls) if self.active_table._table_style == 'booktabs': self.requirements['booktabs'] = r'\usepackage{booktabs}' self.push_output_collector([])
def create_title_from(self, docname, document): """Add a title node to the document (just copy the first section title), and store that title in the environment. """ titlenode = nodes.title() longtitlenode = titlenode # explicit title set with title directive; use this only for # the <title> tag in HTML output if 'title' in document: longtitlenode = nodes.title() longtitlenode += nodes.Text(document['title']) # look for first section title and use that as the title for node in document.traverse(nodes.section): visitor = SphinxContentsFilter(document) node[0].walkabout(visitor) titlenode += visitor.get_entry_text() break else: # document has no title titlenode += nodes.Text('<no title>') self.titles[docname] = titlenode self.longtitles[docname] = longtitlenode
def process_autosummary_toc(app, doctree): """Insert items described in autosummary:: to the TOC tree, but do not generate the toctree:: list. """ env = app.builder.env crawled = {} def crawl_toc(node, depth=1): crawled[node] = True for j, subnode in enumerate(node): try: if (isinstance(subnode, autosummary_toc) and isinstance(subnode[0], addnodes.toctree)): env.note_toctree(env.docname, subnode[0]) continue except IndexError: continue if not isinstance(subnode, nodes.section): continue if subnode not in crawled: crawl_toc(subnode, depth+1) crawl_toc(doctree)
def collect_node_menus(self): """Collect the menu entries for each "node" section.""" node_menus = self.node_menus for node in ([self.document] + self.document.traverse(nodes.section)): assert 'node_name' in node and node['node_name'] entries = [s['node_name'] for s in find_subsections(node)] node_menus[node['node_name']] = entries # try to find a suitable "Top" node title = self.document.next_node(nodes.title) top = (title and title.parent) or self.document if not isinstance(top, (nodes.document, nodes.section)): top = self.document if top is not self.document: entries = node_menus[top['node_name']] entries += node_menus['Top'][1:] node_menus['Top'] = entries del node_menus[top['node_name']] top['node_name'] = 'Top' # handle the indices for name, content in self.indices: node_menus[name] = () node_menus['Top'].append(name)
def visit_title(self, node): if not self.seen_title: self.seen_title = 1 raise nodes.SkipNode parent = node.parent if isinstance(parent, nodes.table): return if isinstance(parent, (nodes.Admonition, nodes.sidebar, nodes.topic)): raise nodes.SkipNode elif not isinstance(parent, nodes.section): self.builder.warn( 'encountered title node not in section, topic, table, ' 'admonition or sidebar', (self.curfilestack[-1], node.line)) self.visit_rubric(node) else: try: heading = self.headings[self.section_level] except IndexError: heading = self.headings[-1] self.body.append('\n%s ' % heading)
def visit_target(self, node): # postpone the labels until after the sectioning command parindex = node.parent.index(node) try: try: next = node.parent[parindex+1] except IndexError: # last node in parent, look at next after parent # (for section of equal level) next = node.parent.parent[node.parent.parent.index(node.parent)] if isinstance(next, nodes.section): if node.get('refid'): self.next_section_ids.add(node['refid']) self.next_section_ids.update(node['ids']) return except IndexError: pass if 'refuri' in node: return if node.get('refid'): self.add_anchor(node['refid'], node) for id in node['ids']: self.add_anchor(id, node)
def update_section_numbers(self, node, prefix=(), depth=0): depth += 1 if prefix: sectnum = 1 else: sectnum = self.startvalue for child in node: if isinstance(child, nodes.section): numbers = prefix + (str(sectnum),) title = child[0] # Use for spacing: generated = nodes.generated( '', (self.prefix + '.'.join(numbers) + self.suffix + '\u00a0' * 3), classes=['sectnum']) title.insert(0, generated) title['auto'] = 1 if depth < self.maxdepth: self.update_section_numbers(child, numbers, depth) sectnum += 1
def run(self): env = self.state.document.settings.env relpath, abspath = env.relfn2path(directives.path(self.arguments[0])) # Add OpenAPI spec as a dependency to the current document. That means # the document will be rebuilt if the spec is changed. env.note_dependency(relpath) # Read the spec using encoding passed to the directive or fallback to # the one specified in Sphinx's config. encoding = self.options.get('encoding', env.config.source_encoding) with io.open(abspath, 'rt', encoding=encoding) as stream: spec = yaml.load(stream, _YamlOrderedLoader) # URI parameter is crucial for resolving relative references. So # we need to set this option properly as it's used later down the # stack. self.options.setdefault('uri', 'file://%s' % abspath) # reStructuredText DOM manipulation is pretty tricky task. It requires # passing dozen arguments which is not easy without well-documented # internals. So the idea here is to represent OpenAPI spec as # reStructuredText in-memory text and parse it in order to produce a # real DOM. viewlist = ViewList() for line in openapi2httpdomain(spec, **self.options): viewlist.append(line, '<openapi>') # Parse reStructuredText contained in `viewlist` and return produced # DOM nodes. node = nodes.section() node.document = self.state.document nested_parse_with_titles(self.state, viewlist, node) return node.children
def autohelp_directive(dirname, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """produces rst from nose help""" config = Config(parserClass=OptBucket, plugins=BuiltinPluginManager()) parser = config.getParser(TestProgram.usage()) rst = ViewList() for line in parser.format_help().split('\n'): rst.append(line, '<autodoc>') rst.append('Options', '<autodoc>') rst.append('-------', '<autodoc>') rst.append('', '<autodoc>') for opt in parser: rst.append(opt.options(), '<autodoc>') rst.append(' \n', '<autodoc>') rst.append(' ' + opt.help + '\n', '<autodoc>') rst.append('\n', '<autodoc>') node = nodes.section() node.document = state.document surrounding_title_styles = state.memo.title_styles surrounding_section_level = state.memo.section_level state.memo.title_styles = [] state.memo.section_level = 0 state.nested_parse(rst, 0, node, match_titles=1) state.memo.title_styles = surrounding_title_styles state.memo.section_level = surrounding_section_level return node.children
def write_doc(self, docname, doctree): self.current_docname = docname # remove title from page contents if self.config.confluence_remove_title: idx = doctree.first_child_matching_class(nodes.section) if not idx == None and not idx == -1: first_section = doctree[idx] idx = first_section.first_child_matching_class(nodes.title) if not idx == None and not idx == -1: doctitle = first_section[idx].astext() if doctitle: first_section.remove(first_section[idx]) # This method is taken from TextBuilder.write_doc() # with minor changes to support :confval:`rst_file_transform`. destination = StringOutput(encoding='utf-8') self.writer.write(doctree, destination) outfilename = path.join(self.outdir, self.file_transform(docname)) if self.writer.output: ensuredir(path.dirname(outfilename)) try: with io.open(outfilename, 'w', encoding='utf-8') as file: file.write(self.writer.output) except (IOError, OSError) as err: ConfluenceLogger.warn("error writing file " "%s: %s" % (outfilename, err))
def depart_title(self, node): if isinstance(node.parent, nodes.section): char = self._title_char else: char = '^' text = ''.join(x[1] for x in self.states.pop() if x[0] == -1) self.stateindent.pop() self.states[-1].append((0, ['%s %s' % (char, text), '']))
def apply(self): self.maxdepth = self.startnode.details.get('depth', None) self.startvalue = self.startnode.details.get('start', 1) self.prefix = self.startnode.details.get('prefix', '') self.suffix = self.startnode.details.get('suffix', '') self.startnode.parent.remove(self.startnode) if self.document.settings.sectnum_xform: if self.maxdepth is None: self.maxdepth = sys.maxint self.update_section_numbers(self.document) else: # store details for eventual section numbering by the writer self.document.settings.sectnum_depth = self.maxdepth self.document.settings.sectnum_start = self.startvalue self.document.settings.sectnum_prefix = self.prefix self.document.settings.sectnum_suffix = self.suffix
def apply(self): try: # let the writer (or output software) build the contents list? toc_by_writer = self.document.settings.use_latex_toc except AttributeError: toc_by_writer = False details = self.startnode.details if 'local' in details: startnode = self.startnode.parent.parent while not (isinstance(startnode, nodes.section) or isinstance(startnode, nodes.document)): # find the ToC root: a direct ancestor of startnode startnode = startnode.parent else: startnode = self.document self.toc_id = self.startnode.parent['ids'][0] if 'backlinks' in details: self.backlinks = details['backlinks'] else: self.backlinks = self.document.settings.toc_backlinks if toc_by_writer: # move customization settings to the parent node self.startnode.parent.attributes.update(details) self.startnode.parent.remove(self.startnode) else: contents = self.build_contents(startnode) if len(contents): self.startnode.replace_self(contents) else: self.startnode.parent.parent.remove(self.startnode.parent)
def build_contents(self, node, level=0): level += 1 sections = [sect for sect in node if isinstance(sect, nodes.section)] entries = [] autonum = 0 depth = self.startnode.details.get('depth', sys.maxint) for section in sections: title = section[0] auto = title.get('auto') # May be set by SectNum. entrytext = self.copy_and_filter(title) reference = nodes.reference('', '', refid=section['ids'][0], *entrytext) ref_id = self.document.set_id(reference) entry = nodes.paragraph('', '', reference) item = nodes.list_item('', entry) if ( self.backlinks in ('entry', 'top') and title.next_node(nodes.reference) is None): if self.backlinks == 'entry': title['refid'] = ref_id elif self.backlinks == 'top': title['refid'] = self.toc_id if level < depth: subsects = self.build_contents(section, level) item += subsects entries.append(item) if entries: contents = nodes.bullet_list('', *entries) if auto: contents['classes'].append('auto-toc') return contents else: return []
def apply(self): unfiltered = self.document.transform_messages threshold = self.document.reporter.report_level messages = [] for msg in unfiltered: if msg['level'] >= threshold and not msg.parent: messages.append(msg) if messages: section = nodes.section(classes=['system-messages']) # @@@ get this from the language module? section += nodes.title('', 'Docutils System Messages') section += messages self.document.transform_messages[:] = [] self.document += section
def candidate_index(self, node): """ Find and return the promotion candidate and its index. Return (None, None) if no valid candidate was found. """ index = node.first_child_not_matching_class( nodes.PreBibliographic) if index is None or len(node) > (index + 1) or \ not isinstance(node[index], nodes.section): return None, None else: return node[index], index
def apply(self): if not getattr(self.document.settings, 'sectsubtitle_xform', 1): return for section in self.document.traverse(nodes.section): # On our way through the node tree, we are deleting # sections, but we call self.promote_subtitle for those # sections nonetheless. To do: Write a test case which # shows the problem and discuss on Docutils-develop. self.promote_subtitle(section)
def cleanup_callback(self, pending): """ Remove an empty "References" section. Called after the `references.TargetNotes` transform is complete. """ if len(pending.parent) == 2: # <title> and <pending> pending.parent.parent.remove(pending.parent)
def append_header(self): """append header with .TH and .SH NAME""" # NOTE before everything # .TH title_upper section date source manual if self.header_written: return self.head.append(self.header()) self.head.append(MACRO_DEF) self.header_written = 1
def indent(self, by=0.5): # if we are in a section ".SH" there already is a .RS step = self._indent[-1] self._indent.append(by) self.body.append(self.defs['indent'][0] % step)
def visit_subtitle(self, node): if isinstance(node.parent, nodes.sidebar): self.body.append(self.defs['strong'][0]) elif isinstance(node.parent, nodes.document): self.visit_docinfo_item(node, 'subtitle') elif isinstance(node.parent, nodes.section): self.body.append(self.defs['strong'][0])
def visit_section(self, node): if not self.section_count: self.body.append('\n</div>\n') self.section_count += 1 self.section_level += 1 if self.section_level > 1: # dummy for matching div's self.body.append(self.starttag(node, 'div', CLASS='section')) else: self.body.append(self.starttag(node, 'div', CLASS='slide'))
def visit_subtitle(self, node): if isinstance(node.parent, nodes.sidebar): self.body.append(self.starttag(node, 'p', '', CLASS='sidebar-subtitle')) self.context.append('</p>\n') elif isinstance(node.parent, nodes.document): self.body.append(self.starttag(node, 'h2', '', CLASS='subtitle')) self.context.append('</h2>\n') self.in_document_title = len(self.body) elif isinstance(node.parent, nodes.section): tag = 'h%s' % (self.section_level + self.initial_header_level - 1) self.body.append( self.starttag(node, tag, '', CLASS='section-subtitle') + self.starttag({}, 'span', '', CLASS='section-subtitle')) self.context.append('</span></%s>\n' % tag)
def depart_footnote_reference(self, node): self.body.append('</a>') # Docutils-generated text: put section numbers in a span for CSS styling:
def visit_generated(self, node): if 'sectnum' in node['classes']: # get section number (strip trailing no-break-spaces) sectnum = node.astext().rstrip(u' ') # print sectnum.encode('utf-8') self.body.append('<span class="sectnum">%s</span> ' % self.encode(sectnum)) # Content already processed: raise nodes.SkipNode
def depart_rubric(self, node): self.body.append('</p>\n') # TODO: use the new HTML 5 element <section>?
def visit_section(self, node): self.section_level += 1 self.body.append( self.starttag(node, 'div', CLASS='section'))
def visit_subtitle(self, node): if isinstance(node.parent, nodes.sidebar): classes = 'sidebar-subtitle' elif isinstance(node.parent, nodes.document): classes = 'subtitle' self.in_document_title = len(self.body) elif isinstance(node.parent, nodes.section): classes = 'section-subtitle' self.body.append(self.starttag(node, 'p', '', CLASS=classes))