def run(self): # import pprint; pprint.pprint(self.__dict__) module_path = self.arguments[0] self.module = importlib.import_module(module_path) parent = os.path.dirname(self.module.__file__) collection = invoke.Collection.from_module(self.module, loaded_from=parent) parser = Parser(contexts=collection.to_contexts()) # output the name of the collection module_title = nodes.subtitle() self.state.nested_parse( StringList([':mod:`{}` *tasks*'.format(collection.name)]), 0, module_title ) # sort tasks alphabetically, except default task should be first. tasks = [(not t.is_default, name, t, parser.contexts[name]) for name, t in collection.tasks.items()] tasks.sort() if not tasks: return [] res = [module_title] for _, name, t, ctx in tasks: res += self._document_task(name, t, ctx) return res
def topic(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine, node_class=nodes.topic): if not (state_machine.match_titles or isinstance(state_machine.node, nodes.sidebar)): error = state_machine.reporter.error( 'The "%s" directive may not be used within topics ' 'or body elements.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [error] if not content: warning = state_machine.reporter.warning( 'Content block expected for the "%s" directive; none found.' % name, nodes.literal_block(block_text, block_text), line=lineno) return [warning] title_text = arguments[0] textnodes, messages = state.inline_text(title_text, lineno) titles = [nodes.title(title_text, '', *textnodes)] # sidebar uses this code if options.has_key('subtitle'): textnodes, more_messages = state.inline_text(options['subtitle'], lineno) titles.append(nodes.subtitle(options['subtitle'], '', *textnodes)) messages.extend(more_messages) text = '\n'.join(content) node = node_class(text, *(titles + messages)) node['classes'] += options.get('class', []) if text: state.nested_parse(content, content_offset, node) return [node]
def _build_details(self, matrix, content): """Constructs the docutils content for the details of the support matrix. This is generated as a bullet list of features. Against each feature we provide the description of the feature and then the details of the hypervisor impls, with any driver specific notes that exist """ detailstitle = nodes.subtitle(text="Details") details = nodes.bullet_list() content.append(detailstitle) content.append(details) # One list entry for each feature we're reporting on for feature in matrix.features: item = nodes.list_item() status = feature.status if feature.group is not None: status += "(" + feature.group + ")" # The hypervisor target name linked from summary table id = re.sub("[^a-zA-Z0-9_]", "_", feature.key) # Highlight the feature title name item.append(nodes.strong(text=feature.title, ids=[id])) para = nodes.paragraph() para.append(nodes.strong(text="Status: " + status + ". ")) if feature.notes is not None: para.append(nodes.inline(text=feature.notes)) item.append(para) # A sub-list giving details of each hypervisor target impls = nodes.bullet_list() for key in feature.implementations: target = matrix.targets[key] impl = feature.implementations[key] subitem = nodes.list_item() id = re.sub("[^a-zA-Z0-9_]", "_", feature.key + "_" + key) subitem += [ nodes.strong(text=target.title + ": "), nodes.literal(text=impl.status, classes=["sp_impl_" + impl.status], ids=[id]), ] if impl.notes is not None: subitem.append(nodes.paragraph(text=impl.notes)) impls.append(subitem) item.append(impls) details.append(item)
def _build_backend_detail(self, matrix, content): detailstitle = nodes.subtitle(text="Backend Details") content.append(detailstitle) for key in six.iterkeys(matrix.backends): content.append( nodes.subtitle(text=matrix.backends[key].title)) content.append( self._build_backend_detail_table( matrix.backends[key], matrix)) content.append(nodes.line()) return content
def write_usage(self, prog, args='', prefix='Usage: '): """Writes a usage line into the buffer. :param prog: the program name. :param args: whitespace separated list of arguments. :param prefix: the prefix for the first line. """ title = nodes.subtitle() title.append(nodes.literal('', '{} {}'.format(self._topname, prog))) usage = nodes.paragraph() usage.append(nodes.Text(prefix)) usage.append(nodes.literal('', '{} {} {}'.format(self._topname, prog, args))) self._node.append(title) self._node.append(usage)
def _build_grade_listing(self, matrix, content): summarytitle = nodes.subtitle(text="Grades") content.append(nodes.raw(text="Grades", attributes={'tagname': 'h2'})) content.append(summarytitle) table = nodes.table() table.set_class("table") table.set_class("table-condensed") grades = matrix.grades tablegroup = nodes.tgroup(cols=2) summarybody = nodes.tbody() summaryhead = nodes.thead() for i in range(2): tablegroup.append(nodes.colspec(colwidth=1)) tablegroup.append(summaryhead) tablegroup.append(summarybody) table.append(tablegroup) content.append(table) header = nodes.row() blank = nodes.entry() blank.append(nodes.strong(text="Grade")) header.append(blank) blank = nodes.entry() blank.append(nodes.strong(text="Description")) header.append(blank) summaryhead.append(header) for grade in grades: item = nodes.row() namecol = nodes.entry() class_name = "label-%s" % grade.css_class status_text = nodes.paragraph(text=grade.title) status_text.set_class(class_name) status_text.set_class("label") namecol.append(status_text) item.append(namecol) notescol = nodes.entry() notescol.append(nodes.paragraph(text=grade.notes)) item.append(notescol) summarybody.append(item) return content
def make_plugin_section(plugin_group): elements = [] for item in plugin_group["items"]: name = item["name"].title() if "SLA" != item["name"] else item["name"] elements.append(nodes.subtitle( text="%ss [%s]" % (name, plugin_group["group"]))) for p in _get_plugin_info(item): elements.append(nodes.rubric( text="%s [%s]" % (p["name"], item["name"]))) elements.append(nodes.doctest_block(text=p["description"])) return elements
def _build_notes(self, content): """Constructs a list of notes content for the support matrix. This is generated as a bullet list. """ notes_title = nodes.subtitle(text="Notes:") notes = nodes.bullet_list() content.append(notes_title) content.append(notes) for note in ["This document is a continuous work in progress"]: item = nodes.list_item() item.append(nodes.strong(text=note)) notes.append(item)
def run(self): self.load_agx_config() agx_defs = self.read_agx() ret = list() old_name = self.name self.name = 'autofunction' for transform in agx_defs: for generator in transform['generators']: sec = nodes.section() sec['ids'].append(generator['name']) text = "%s" % generator['name'].replace('.', ' - ') gen = nodes.subtitle(text=text) sec.append(gen) ret.append(sec) description = generator['description'] if description: desc = nodes.paragraph(text=description) sec.append(desc) for handler in generator['handler']: name = handler['name'] self.arguments = [handler['package_path']] doc = AutoDirective.run(self) sec += doc body = doc[1].children[-1] position = len(doc[1].children[-1]) - 2 dl = nodes.definition_list() body.insert(position, dl) iname = name[:name.find('.')] dl.append(self._definition_item('Transform', iname)) iname = name[name.find('.') + 1:name.rfind('.')] dl.append(self._definition_item('Generator', iname)) scope = handler['scope'] if scope is not None: modulename = scope['class'].__module__ classname = scope['class'].__name__ iname = "%s.%s" % (modulename, classname) dl.append(self._definition_item('Scope', iname)) iname = handler['order'] dl.append(self._definition_item('Order', iname)) self.name = old_name return ret
def _doc_widget(self, widgetname): sec = nodes.section() sec['ids'].append(widgetname) # set a title: sec.append(nodes.subtitle(text=widgetname)) # fetch main documentation maindoc = factory.doc['blueprint'].get(widgetname, None) if maindoc is not None: sec.append(self._rest2node(maindoc)) else: sec.append(nodes.paragraph( text='This widget is currently undocumented.')) # build table of callables used rub = nodes.rubric(text='Chains') sec.append(rub) table= """ +------------+----------------+---------------+----------+-------------------+ | extractors | edit renderers | preprocessors | builders | display renderers | +============+================+===============+==========+===================+ | replace | replace | replace | replace | replace | +------------+----------------+---------------+----------+-------------------+ """ table = self._rest2node(table) rub.append(table) row = table.children[0].children[0].children[6].children[0] for idx in range(0,5): row[idx].children = [] row[idx].append(self._doc_chain(widgetname, idx)) # document properties rub = nodes.rubric(text='Properties') sec.append(rub) table= """ +----------+---------+-------------+ | property | default | description | +==========+=========+=============+ | replace | replace | replace | +----------+---------+-------------+ """ table = self._rest2node(table) table.children[0].children[0].children[4].children = [] rub.append(table) for prop in self._managed_props_of(widgetname): table.children[0].children[0].children[4].append( self._doc_property(prop)) return sec
def promote_subtitle(self, node): """ Transform the following node tree:: <node> <title> <section> <title> ... into :: <node> <title> <subtitle> ... """ # Type check if not isinstance(node, nodes.Element): raise TypeError("node must be of Element-derived type.") subsection, index = self.candidate_index(node) if index is None: return None subtitle = nodes.subtitle() # Transfer the subsection's attributes to the new subtitle # NOTE: Change second parameter to False to NOT replace # attributes that already exist in node with those in # section # NOTE: Remove third parameter to NOT copy the 'source' # attribute from section subtitle.update_all_atts_concatenating(subsection, True, True) # Transfer the contents of the subsection's title to the # subtitle: subtitle[:] = subsection[0][:] node[:] = ( node[:1] # title + [subtitle] # everything that was before the section: + node[1:index] # everything that was in the subsection: + subsection[1:] ) return 1
def promote_document_subtitle(self): subsection, index = self.candidate_index() if index is None: return None subtitle = nodes.subtitle() # Transfer the subsection's attributes to the new subtitle: subtitle.attributes.update(subsection.attributes) # Transfer the contents of the subsection's title to the subtitle: subtitle[:] = subsection[0][:] document = self.document document[:] = (document[:1] # document title + [subtitle] # everything that was before the section: + document[1:index] # everything that was in the subsection: + subsection[1:]) return 1
def run(self): if not (self.state_machine.match_titles or isinstance(self.state_machine.node, nodes.sidebar)): raise self.error('The "%s" directive may not be used within ' "topics or body elements." % self.name) self.assert_has_content() title_text = self.arguments[0] textnodes, messages = self.state.inline_text(title_text, self.lineno) titles = [nodes.title(title_text, "", *textnodes)] # Sidebar uses this code. if self.options.has_key("subtitle"): textnodes, more_messages = self.state.inline_text(self.options["subtitle"], self.lineno) titles.append(nodes.subtitle(self.options["subtitle"], "", *textnodes)) messages.extend(more_messages) text = "\n".join(self.content) node = self.node_class(text, *(titles + messages)) node["classes"] += self.options.get("class", []) if text: self.state.nested_parse(self.content, self.content_offset, node) return [node]
def run(self): env = self.state.document.settings.env code = '\n'.join(self.content) literal = nodes.literal_block(code, code) literal['language' ] = 'html' print env.docname doc_dir = os.path.dirname(env.docname) relative_static_path = os.path.relpath(env.config.html_static_path[0], doc_dir) prelude = RAW_CODE_PRELUDE % relative_static_path raw_html_code = nodes.raw(code, prelude + code + '</br>', format='html') set_source_info(self, literal) set_source_info(self, raw_html_code) return [raw_html_code, nodes.subtitle('', 'Source Code'), literal]
def _build_notes(self, content): """Constructs a list of notes content for the support matrix. This is generated as a bullet list. """ notestitle = nodes.subtitle(text="Notes") notes = nodes.bullet_list() content.append(notestitle) content.append(notes) NOTES = [ "Virtuozzo was formerly named Parallels in this document" ] for note in NOTES: item = nodes.list_item() item.append(nodes.strong(text=note)) notes.append(item)
def promote_subtitle(self, node): """ Transform the following node tree:: <node> <title> <section> <title> ... into :: <node> <title> <subtitle> ... """ subsection, index = self.candidate_index(node) if index is None: return None subtitle = nodes.subtitle() # Transfer the subsection's attributes to the new subtitle: # This causes trouble with list attributes! To do: Write a # test case which catches direct access to the `attributes` # dictionary and/or write a test case which shows problems in # this particular case. subtitle.attributes.update(subsection.attributes) # We're losing the subtitle's attributes here! To do: Write a # test case which shows this behavior. # Transfer the contents of the subsection's title to the # subtitle: subtitle[:] = subsection[0][:] node[:] = ( node[:1] # title + [subtitle] # everything that was before the section: + node[1:index] # everything that was in the subsection: + subsection[1:] ) return 1
def run(self): if not (self.state_machine.match_titles or isinstance(self.state_machine.node, nodes.sidebar)): raise self.error('The "%s" directive may not be used within ' 'topics or body elements.' % self.name) self.assert_has_content() title_text = self.arguments[0] textnodes, messages = self.state.inline_text(title_text, self.lineno) titles = [nodes.title(title_text, '', *textnodes)] # Sidebar uses this code. if 'subtitle' in self.options: textnodes, more_messages = self.state.inline_text( self.options['subtitle'], self.lineno) titles.append(nodes.subtitle(self.options['subtitle'], '', *textnodes)) messages.extend(more_messages) text = '\n'.join(self.content) node = self.node_class(text, *(titles + messages)) node['classes'] += self.options.get('class', []) self.add_name(node) if text: self.state.nested_parse(self.content, self.content_offset, node) return [node]
def run(self): module_name = self.options['module'] mod = __import__(module_name, globals(), locals()) classes = inspect.getmembers(sys.modules[module_name], inspect.isclass) classes_names = [cl[0] for cl in classes] commands = _get_command(classes_names) items = [] for cl in classes: parser = cl[1](None, None).get_parser(None) parser.prog = commands[cl[0]] items.append(nodes.subtitle(text=commands[cl[0]])) result = ext.parse_parser( parser, skip_default_values='nodefault' in self.options) result = ext.parser_navigate(result, '') nested_content = ext.nodes.paragraph() self.state.nested_parse( self.content, self.content_offset, nested_content) nested_content = nested_content.children for item in nested_content: if not isinstance(item, ext.nodes.definition_list): items.append(item) if 'description' in result: items.append(self._nested_parse_paragraph(result['description'])) items.append(ext.nodes.literal_block(text=result['usage'])) items.append(ext.print_command_args_and_opts( ext.print_arg_list(result, nested_content), ext.print_opt_list(result, nested_content), ext.print_subcommand_list(result, nested_content) )) if 'epilog' in result: items.append(self._nested_parse_paragraph(result['epilog'])) return items
def process_gen_nodes_list(app, doctree, fromdocname): # Replace all gen_nodelist nodes with a list of the collected gen_nodes. # Augment each gen_node with a backlink to the original location. env = app.builder.env for elt in NODES: if not NODES[elt]['show_list']: for node in doctree.traverse(NODES[elt]['node_gen']): node.parent.remove(node) if not hasattr(env, NODES[elt]['env_all']): setattr(env, NODES[elt]['env_all'], []) for node in doctree.traverse(NODES[elt]['node_gen']): if not NODES[elt]['show_list']: node.replace_self([]) continue content = [] for gen_node_info in getattr(env, NODES[elt]['env_all']): if NODES[elt]['group_title_doc']: if gen_node_info['target']['refid'] == 'index-0': group = None group = nodes.subtitle(classes=['%s-group' % elt]) group += nodes.Text(gen_node_info['docname']) content.append(group) #para_desc para_desc = nodes.paragraph(classes=['%s-source' % elt]) description = _('(The <<original entry>> is located in ' ' %s, line %d.)') % \ (gen_node_info['source'], gen_node_info['lineno']) desc1 = description[:description.find('<<')] desc2 = description[description.find('>>') + 2:] para_desc += nodes.Text(desc1, desc1) # Create a reference newnode = nodes.reference('', '', internal=True) innernode = nodes.emphasis(_(elt), _(elt)) try: newnode['refuri'] = app.builder.get_relative_uri( fromdocname, gen_node_info['docname']) newnode['refuri'] += '#' + gen_node_info['target']['refid'] except NoUri: # ignore if no URI can be determined, e.g. for LaTeX output pass newnode.append(innernode) para_desc += newnode para_desc += nodes.Text(desc2, desc2) # (Recursively) resolve references in the gen_node content gen_node_entry = gen_node_info[elt] env.resolve_references(gen_node_entry, gen_node_info['docname'], app.builder) # Insert into the gen_nodelist gen_node_info[elt].children[0].children[0]=newnode content.append(gen_node_entry) if NODES[elt]['show_desc_paragraph']: content.append(para_desc) node.replace_self(content)
def _build_summary(self, matrix, content): """Constructs the docutils content for the summary of the support matrix. The summary consists of a giant table, with one row for each feature, and a column for each hypervisor driver. It provides an 'at a glance' summary of the status of each driver """ summarytitle = nodes.subtitle(text="Summary") summary = nodes.table() cols = len(matrix.targets.keys()) cols += 2 summarygroup = nodes.tgroup(cols=cols) summarybody = nodes.tbody() summaryhead = nodes.thead() for i in range(cols): summarygroup.append(nodes.colspec(colwidth=1)) summarygroup.append(summaryhead) summarygroup.append(summarybody) summary.append(summarygroup) content.append(summarytitle) content.append(summary) # This sets up all the column headers - two fixed # columns for feature name & status header = nodes.row() blank = nodes.entry() blank.append(nodes.emphasis(text="Feature")) header.append(blank) blank = nodes.entry() blank.append(nodes.emphasis(text="Status")) header.append(blank) summaryhead.append(header) # then one column for each hypervisor driver impls = list(matrix.targets.keys()) impls.sort() for key in impls: target = matrix.targets[key] implcol = nodes.entry() header.append(implcol) implcol.append(nodes.strong(text=target.title)) # We now produce the body of the table, one row for # each feature to report on for feature in matrix.features: item = nodes.row() # the hyperlink target name linking to details id = re.sub("[^a-zA-Z0-9_]", "_", feature.key) # first the to fixed columns for title/status keycol = nodes.entry() item.append(keycol) keyref = nodes.reference(refid=id) keytxt = nodes.inline() keycol.append(keytxt) keytxt.append(keyref) keyref.append(nodes.strong(text=feature.title)) statuscol = nodes.entry() item.append(statuscol) statuscol.append(nodes.inline( text=feature.status, classes=["sp_feature_" + feature.status])) # and then one column for each hypervisor driver impls = list(matrix.targets.keys()) impls.sort() for key in impls: target = matrix.targets[key] impl = feature.implementations[key] implcol = nodes.entry() item.append(implcol) id = re.sub("[^a-zA-Z0-9_]", "_", feature.key + "_" + key) implref = nodes.reference(refid=id) impltxt = nodes.inline() implcol.append(impltxt) impltxt.append(implref) status = "" if impl.status == SupportMatrixImplementation.STATUS_COMPLETE: status = u"\u2714" elif impl.status == SupportMatrixImplementation.STATUS_MISSING: status = u"\u2716" elif impl.status == SupportMatrixImplementation.STATUS_PARTIAL: status = u"\u2714" elif impl.status == SupportMatrixImplementation.STATUS_UKNOWN: status = u"?" implref.append(nodes.literal( text=status, classes=["sp_impl_summary", "sp_impl_" + impl.status])) summarybody.append(item)
def run(self): indnode = [] for indname in sorted(Indicator._indcol.keys()): # indnode.append(nodes.section()) indcls = Indicator._indcol[indname] # Title section (indicator name) indname = indcls.__name__ indtitle = nodes.subtitle(indname, indname) indnode.append(indtitle) # Get the docstring and prepare it for parsing # a list is returned indclsdoc = indcls.__doc__ or '' # __doc__ could be None inddoc = prepare_docstring(indclsdoc) # Alias section indaliases = getattr(indcls, 'alias', []) if indaliases: inddoc.insert(0, u'Alias:') purgedaliases = [] for indalias in indaliases: if not isinstance(indalias, six.string_types): indalias = indalias[0] purgedaliases.append(indalias) aliastxt = u' - %s' % ', '.join(purgedaliases) inddoc.insert(1, aliastxt) inddoc.insert(2, u'') # Lines section indlines = indcls.lines._getlines() if indlines: inddoc.append(u'Lines:') for i, indline in enumerate(indlines): inddoc.append(u' - %s' % indcls.lines._getlinealias(i)) # Params section indparams = indcls.params._getpairs() if indparams: inddoc.append(u'Params:') for pkey, pvalue in indcls.params._getitems(): try: if issubclass(pvalue, Indicator): pvalue = pvalue.__name__ except: pass inddoc.append(u' - %s (%s)' % (pkey, str(pvalue))) # Plotinfo section # indplotinfo = indcls.plotinfo._getpairs() if len(indcls.plotinfo._getpairs()): inddoc.append(u'PlotInfo:') for pkey, pvalue in indcls.plotinfo._getitems(): inddoc.append(u' - %s (%s)' % (pkey, str(pvalue))) # PlotLines Section if len(indcls.plotlines._getpairs()): inddoc.append(u'PlotLines:') for pkey, pvalue in indcls.plotlines._getitems(): if isinstance(pvalue, AutoInfoClass): inddoc.append(u' - %s:' % pkey) for plkey, plvalue in pvalue._getitems(): inddoc.append(u' - %s (%s)' % (plkey, plvalue)) elif isinstance(pvalue, (dict, OrderedDict)): inddoc.append(u' - %s:' % pkey) for plkey, plvalue in pvalue.items(): inddoc.append(u' - %s (%s)' % (plkey, plvalue)) else: inddoc.append(u' - %s (%s):' % pkey, str(pvalue)) # create the indicator node, add it to a viewlist and parse indsubnode = nodes.container() inddocview = ViewList(inddoc, indname) nested_parse_with_titles(self.state, inddocview, indsubnode) # Add the indicator subnode to the list of nodes to be returned indnode.append(indsubnode) return indnode
def _construct_manpage_specific_structure(self, parser_info): """ Construct a typical man page consisting of the following elements: NAME (automatically generated, out of our control) SYNOPSIS DESCRIPTION OPTIONS FILES SEE ALSO BUGS """ items = [] # SYNOPSIS section synopsis_section = nodes.section( '', nodes.title(text='Synopsis'), nodes.literal_block(text=parser_info["bare_usage"]), ids=['synopsis-section']) items.append(synopsis_section) # DESCRIPTION section if 'nodescription' not in self.options: description_section = nodes.section( '', nodes.title(text='Description'), nodes.paragraph(text=parser_info.get( 'description', parser_info.get('help', "undocumented").capitalize())), ids=['description-section']) nested_parse_with_titles(self.state, self.content, description_section) items.append(description_section) if parser_info.get('epilog') and 'noepilog' not in self.options: # TODO: do whatever sphinx does to understand ReST inside # docstrings magically imported from other places. The nested # parse method invoked above seem to be able to do this but # I haven't found a way to do it for arbitrary text if description_section: description_section += nodes.paragraph( text=parser_info['epilog']) else: description_section = nodes.paragraph( text=parser_info['epilog']) items.append(description_section) # OPTIONS section options_section = nodes.section('', nodes.title(text='Options'), ids=['options-section']) if 'args' in parser_info: options_section += nodes.paragraph() options_section += nodes.subtitle(text='Positional arguments:') options_section += self._format_positional_arguments(parser_info) for action_group in parser_info['action_groups']: if 'options' in parser_info: options_section += nodes.paragraph() options_section += nodes.subtitle(text=action_group['title']) options_section += self._format_optional_arguments( action_group) # NOTE: we cannot generate NAME ourselves. It is generated by # docutils.writers.manpage # TODO: items.append(files) # TODO: items.append(see also) # TODO: items.append(bugs) if len(options_section.children) > 1: items.append(options_section) if 'nosubcommands' not in self.options: # SUBCOMMANDS section (non-standard) subcommands_section = nodes.section( '', nodes.title(text='Sub-Commands'), ids=['subcommands-section']) if 'children' in parser_info: subcommands_section += self._format_subcommands(parser_info) if len(subcommands_section) > 1: items.append(subcommands_section) if os.getenv("INCLUDE_DEBUG_SECTION"): import json # DEBUG section (non-standard) debug_section = nodes.section( '', nodes.title(text="Argparse + Sphinx Debugging"), nodes.literal_block(text=json.dumps(parser_info, indent=' ')), ids=['debug-section']) items.append(debug_section) return items
def _build_summary(self, matrix, content): """Constructs the docutils content for the summary of the support matrix. The summary consists of a giant table, with one row for each feature, and a column for each hypervisor driver. It provides an 'at a glance' summary of the status of each driver """ summarytitle = nodes.subtitle(text="Summary") summary = nodes.table() cols = len(matrix.targets.keys()) cols += 2 summarygroup = nodes.tgroup(cols=cols) summarybody = nodes.tbody() summaryhead = nodes.thead() for i in range(cols): summarygroup.append(nodes.colspec(colwidth=1)) summarygroup.append(summaryhead) summarygroup.append(summarybody) summary.append(summarygroup) content.append(summarytitle) content.append(summary) # This sets up all the column headers - two fixed # columns for feature name & status header = nodes.row() blank = nodes.entry() blank.append(nodes.emphasis(text="Feature")) header.append(blank) blank = nodes.entry() blank.append(nodes.emphasis(text="Status")) header.append(blank) summaryhead.append(header) # then one column for each hypervisor driver impls = list(matrix.targets.keys()) impls.sort() for key in impls: target = matrix.targets[key] implcol = nodes.entry() header.append(implcol) implcol.append(nodes.strong(text=target.title)) # We now produce the body of the table, one row for # each feature to report on for feature in matrix.features: item = nodes.row() # the hyperlink target name linking to details id = re.sub("[^a-zA-Z0-9_]", "_", feature.key) # first the to fixed columns for title/status keycol = nodes.entry() item.append(keycol) keyref = nodes.reference(refid=id) keytxt = nodes.inline() keycol.append(keytxt) keytxt.append(keyref) keyref.append(nodes.strong(text=feature.title)) statuscol = nodes.entry() item.append(statuscol) statuscol.append( nodes.inline(text=feature.status, classes=["sp_feature_" + feature.status])) # and then one column for each hypervisor driver impls = list(matrix.targets.keys()) impls.sort() for key in impls: target = matrix.targets[key] impl = feature.implementations[key] implcol = nodes.entry() item.append(implcol) id = re.sub("[^a-zA-Z0-9_]", "_", feature.key + "_" + key) implref = nodes.reference(refid=id) impltxt = nodes.inline() implcol.append(impltxt) impltxt.append(implref) status = "" if impl.status == SupportMatrixImplementation.STATUS_COMPLETE: status = u"\u2714" elif impl.status == SupportMatrixImplementation.STATUS_MISSING: status = u"\u2716" elif impl.status == SupportMatrixImplementation.STATUS_PARTIAL: status = u"\u2714" elif impl.status == SupportMatrixImplementation.STATUS_UKNOWN: status = u"?" implref.append( nodes.literal( text=status, classes=["sp_impl_summary", "sp_impl_" + impl.status])) summarybody.append(item)
def _build_details(self, matrix, content): """Constructs the docutils content for the details of the support matrix. """ details_title = nodes.subtitle(text="Details") details = nodes.bullet_list() content.append(details_title) content.append(details) # One list entry for each feature we're reporting on for feature in matrix.features: item = nodes.list_item() status = feature.status if feature.group is not None: status += "({})".format(feature.group) feature_id = re.sub(RE_PATTERN, "_", feature.key) # Highlight the feature title name item.append(nodes.strong(text=feature.title, ids=[feature_id])) # Add maturity status para = nodes.paragraph() para.append(nodes.strong(text="Status: {} ".format(status))) item.append(para) # If API Alias exists add it if feature.api is not None: para = nodes.paragraph() para.append( nodes.strong(text="API Alias: {} ".format(feature.api))) item.append(para) if feature.cli: item.append(self._create_cli_paragraph(feature)) if feature.notes is not None: item.append(self._create_notes_paragraph(feature.notes)) para_divers = nodes.paragraph() para_divers.append(nodes.strong(text="Driver Support:")) # A sub-list giving details of each backend driver target impls = nodes.bullet_list() for key in feature.implementations: target = matrix.targets[key] impl = feature.implementations[key] subitem = nodes.list_item() key_id = re.sub(RE_PATTERN, "_", "{}_{}".format(feature.key, key)) subitem += [ nodes.strong(text="{}: ".format(target.title)), nodes.literal(text=impl.status, classes=["sp_impl_{}".format(impl.status)], ids=[key_id]), ] if impl.notes is not None: subitem.append(self._create_notes_paragraph(impl.notes)) impls.append(subitem) para_divers.append(impls) item.append(para_divers) details.append(item)
def _build_summary(self, matrix, content): """Constructs the docutils content for the summary of the support matrix. The summary consists of a giant table, with one row for each feature, and a column for each backend driver. It provides an 'at a glance' summary of the status of each driver """ summary_title = nodes.subtitle(text="Summary") summary = nodes.table() cols = len(matrix.targets.keys()) cols += 2 summary_group = nodes.tgroup(cols=cols) summary_body = nodes.tbody() summary_head = nodes.thead() for i in range(cols): summary_group.append(nodes.colspec(colwidth=1)) summary_group.append(summary_head) summary_group.append(summary_body) summary.append(summary_group) content.append(summary_title) content.append(summary) # This sets up all the column headers - two fixed # columns for feature name & status header = nodes.row() blank = nodes.entry() blank.append(nodes.emphasis(text="Feature")) header.append(blank) blank = nodes.entry() blank.append(nodes.emphasis(text="Status")) header.append(blank) summary_head.append(header) # then one column for each backend driver impls = matrix.targets.keys() impls = sorted(impls) for key in impls: target = matrix.targets[key] implcol = nodes.entry() header.append(implcol) if target.link: uri = target.link target_ref = nodes.reference("", refuri=uri) target_txt = nodes.inline() implcol.append(target_txt) target_txt.append(target_ref) target_ref.append(nodes.strong(text=target.title)) else: implcol.append(nodes.strong(text=target.title)) # We now produce the body of the table, one row for # each feature to report on for feature in matrix.features: item = nodes.row() # the hyperlink target name linking to details feature_id = re.sub(RE_PATTERN, "_", feature.key) # first the fixed columns for title/status key_col = nodes.entry() item.append(key_col) key_ref = nodes.reference(refid=feature_id) key_txt = nodes.inline() key_col.append(key_txt) key_txt.append(key_ref) key_ref.append(nodes.strong(text=feature.title)) status_col = nodes.entry() item.append(status_col) status_col.append(nodes.inline( text=feature.status, classes=["sp_feature_" + feature.status])) # and then one column for each backend driver impls = matrix.targets.keys() impls = sorted(impls) for key in impls: target = matrix.targets[key] impl = feature.implementations[key] impl_col = nodes.entry() item.append(impl_col) key_id = re.sub(RE_PATTERN, "_", "{}_{}".format(feature.key, key)) impl_ref = nodes.reference(refid=key_id) impl_txt = nodes.inline() impl_col.append(impl_txt) impl_txt.append(impl_ref) status = STATUS_DICT.get(impl.status, "") impl_ref.append(nodes.literal( text=status, classes=["sp_impl_summary", "sp_impl_" + impl.status])) summary_body.append(item)
def _construct_manpage_specific_structure(self, parser_info): """ Construct a typical man page consisting of the following elements: NAME (automatically generated, out of our control) SYNOPSIS DESCRIPTION OPTIONS FILES SEE ALSO BUGS """ # SYNOPSIS section synopsis_section = nodes.section( '', nodes.title(text='Synopsis'), nodes.literal_block(text=parser_info["bare_usage"]), ids=['synopsis-section']) # DESCRIPTION section description_section = nodes.section( '', nodes.title(text='Description'), nodes.paragraph(text=parser_info.get( 'description', parser_info.get( 'help', "undocumented").capitalize())), ids=['description-section']) nested_parse_with_titles( self.state, self.content, description_section) if parser_info.get('epilog'): # TODO: do whatever sphinx does to understand ReST inside # docstrings magically imported from other places. The nested # parse method invoked above seem to be able to do this but # I haven't found a way to do it for arbitrary text description_section += nodes.paragraph( text=parser_info['epilog']) # OPTIONS section options_section = nodes.section( '', nodes.title(text='Options'), ids=['options-section']) if 'args' in parser_info: options_section += nodes.paragraph() options_section += nodes.subtitle(text='Positional arguments:') options_section += self._format_positional_arguments(parser_info) if 'options' in parser_info: options_section += nodes.paragraph() options_section += nodes.subtitle(text='Optional arguments:') options_section += self._format_optional_arguments(parser_info) items = [ # NOTE: we cannot generate NAME ourselves. It is generated by # docutils.writers.manpage synopsis_section, description_section, # TODO: files # TODO: see also # TODO: bugs ] if len(options_section.children) > 1: items.append(options_section) if 'nosubcommands' not in self.options: # SUBCOMMANDS section (non-standard) subcommands_section = nodes.section( '', nodes.title(text='Sub-Commands'), ids=['subcommands-section']) if 'children' in parser_info: subcommands_section += self._format_subcommands(parser_info) if len(subcommands_section) > 1: items.append(subcommands_section) if os.getenv("INCLUDE_DEBUG_SECTION"): import json # DEBUG section (non-standard) debug_section = nodes.section( '', nodes.title(text="Argparse + Sphinx Debugging"), nodes.literal_block(text=json.dumps(parser_info, indent=' ')), ids=['debug-section']) items.append(debug_section) return items
def _build_details(self, matrix, content): """Constructs the docutils content for the details of the feature matrix. This is generated as a bullet list of features. Against each feature we provide the description of the feature and then the details of the hypervisor impls, with any driver specific notes that exist """ detailstitle = nodes.subtitle(text="Details") details = nodes.bullet_list() content.append(detailstitle) content.append(details) # One list entry for each feature we're reporting on for feature in matrix.features: item = nodes.list_item() # The hypervisor target name linked from summary table id = re.sub("[^a-zA-Z0-9_]", "_", feature.key) # Highlight the feature title name item.append(nodes.strong(text=feature.title, ids=[id])) if feature.notes is not None: para_notes = nodes.paragraph() para_notes.append(nodes.inline(text=feature.notes)) item.append(para_notes) self._add_feature_info(item, feature) if feature.cli: item.append(self._create_cli_paragraph(feature)) para_divers = nodes.paragraph() para_divers.append(nodes.strong(text="drivers:")) # A sub-list giving details of each hypervisor target impls = nodes.bullet_list() for key in feature.implementations: target = matrix.targets[key] impl = feature.implementations[key] subitem = nodes.list_item() id = re.sub("[^a-zA-Z0-9_]", "_", feature.key + "_" + key) subitem += [ nodes.strong(text=target.title + ": "), nodes.literal(text=impl.status, classes=["fm_impl_" + impl.status], ids=[id]), ] if impl.release: release_letter = impl.release.upper() release_text = \ ' (updated in "%s" release)' % release_letter subitem.append(nodes.inline(text=release_text)) if impl.notes is not None: subitem.append(self._create_notes_paragraph(impl.notes)) impls.append(subitem) para_divers.append(impls) item.append(para_divers) details.append(item)
def run(self): indnode = [] for indname in sorted(self.RefCls._indcol.keys()): # indnode.append(nodes.section()) indcls = self.RefCls._indcol[indname] # Title section (indicator name) indname = indcls.__name__ indtitle = nodes.subtitle(indname, indname) indnode.append(indtitle) # Get the docstring and prepare it for parsing # a list is returned indclsdoc = indcls.__doc__ or '' # __doc__ could be None inddoc = prepare_docstring(indclsdoc) # Alias section indaliases = getattr(indcls, 'alias', []) if indaliases: inddoc.insert(0, u'Alias:') purgedaliases = [] for indalias in indaliases: if not isinstance(indalias, six.string_types): indalias = indalias[0] purgedaliases.append(indalias) aliastxt = u' - %s' % ', '.join(purgedaliases) inddoc.insert(1, aliastxt) inddoc.insert(2, u'') # Lines section indlines = indcls.lines._getlines() if indlines: inddoc.append(u'Lines:') for i, indline in enumerate(indlines): inddoc.append(u' - %s' % indcls.lines._getlinealias(i)) # Params section indparams = indcls.params._getpairs() if indparams: inddoc.append(u'Params:') for pkey, pvalue in indcls.params._getitems(): try: if issubclass(pvalue, self.RefCls): pvalue = pvalue.__name__ except: pass inddoc.append(u' - %s (%s)' % (pkey, str(pvalue))) if self.RefPlot: # Plotinfo section # indplotinfo = indcls.plotinfo._getpairs() if len(indcls.plotinfo._getpairs()): inddoc.append(u'PlotInfo:') for pkey, pvalue in indcls.plotinfo._getitems(): inddoc.append(u' - %s (%s)' % (pkey, str(pvalue))) # PlotLines Section if len(indcls.plotlines._getpairs()): inddoc.append(u'PlotLines:') for pkey, pvalue in indcls.plotlines._getitems(): if isinstance(pvalue, AutoInfoClass): inddoc.append(u' - %s:' % pkey) for plkey, plvalue in pvalue._getitems(): inddoc.append(u' - %s (%s)' % (plkey, plvalue)) elif isinstance(pvalue, (dict, OrderedDict)): inddoc.append(u' - %s:' % pkey) for plkey, plvalue in pvalue.items(): inddoc.append(u' - %s (%s)' % (plkey, plvalue)) else: inddoc.append(u' - %s (%s):' % pkey, str(pvalue)) # create the indicator node, add it to a viewlist and parse indsubnode = nodes.container() inddocview = ViewList(inddoc, indname) nested_parse_with_titles(self.state, inddocview, indsubnode) # Add the indicator subnode to the list of nodes to be returned indnode.append(indsubnode) return indnode
def _build_grade_table(self, matrix, content): summarytitle = nodes.subtitle(text="Backends - Summary") summary = nodes.table() summary.set_class("table") summary.set_class("table-condensed") cols = len(list(six.iterkeys(matrix.backends))) cols += 2 summarygroup = nodes.tgroup(cols=cols) summarybody = nodes.tbody() summaryhead = nodes.thead() for i in range(cols): summarygroup.append(nodes.colspec(colwidth=1)) summarygroup.append(summaryhead) summarygroup.append(summarybody) summary.append(summarygroup) content.append(summarytitle) content.append(summary) header = nodes.row() blank = nodes.entry() blank.append(nodes.strong(text="Backend")) header.append(blank) blank = nodes.entry() blank.append(nodes.strong(text="Status")) header.append(blank) blank = nodes.entry() blank.append(nodes.strong(text="Type")) header.append(blank) blank = nodes.entry() blank.append(nodes.strong(text="In Tree")) header.append(blank) blank = nodes.entry() blank.append(nodes.strong(text="Notes")) header.append(blank) summaryhead.append(header) grades = matrix.grades impls = list(six.iterkeys(matrix.backends)) impls.sort() for grade in grades: for backend in impls: if matrix.backends[backend].status == grade.key: item = nodes.row() namecol = nodes.entry() namecol.append( nodes.paragraph(text=matrix.backends[backend].title)) item.append(namecol) statuscol = nodes.entry() class_name = "label-%s" % grade.css_class status_text = nodes.paragraph(text=grade.title) status_text.set_class(class_name) status_text.set_class("label") statuscol.append(status_text) item.append(statuscol) typecol = nodes.entry() type_text = nodes.paragraph( text=matrix.backends[backend].type) type_text.set_class("label") type_text.set_class("label-info") typecol.append(type_text) item.append(typecol) if bool(matrix.backends[backend].in_tree): status = u"\u2714" intree = nodes.paragraph(text=status) intree.set_class("label") intree.set_class("label-success") else: status = u"\u2716" intree = nodes.paragraph(text=status) intree.set_class("label") intree.set_class("label-danger") intreecol = nodes.entry() intreecol.append(intree) item.append(intreecol) notescol = nodes.entry() notescol.append(nodes.paragraph( text=matrix.backends[backend].notes)) item.append(notescol) summarybody.append(item) return content