def _render_service(self, path, service, methods): env = self.state.document.settings.env service_id = "service-%d" % env.new_serialno('service') service_node = nodes.section(ids=[service_id]) service_node += nodes.title(text='Service at %s' % service.route_name) if service.description is not None: service_node += rst2node(_dedent(service.description)) for method, info in methods.items(): method_id = '%s-%s' % (service_id, method) method_node = nodes.section(ids=[method_id]) method_node += nodes.title(text=method) docstring = info['func'].__doc__ or "" if 'validator' in info: validators = to_list(info['validator']) for validator in validators: if validator.__doc__ is not None: if docstring is not None: docstring += '\n' + validator.__doc__.strip() if 'accept' in info: accept = info['accept'] if callable(accept): if accept.__doc__ is not None: docstring += accept.__doc__.strip() else: accept = to_list(accept) accept_node = nodes.strong(text='Accepted content types:') node_accept_list = nodes.bullet_list() accept_node += node_accept_list for item in accept: temp = nodes.list_item() temp += nodes.inline(text=item) node_accept_list += temp method_node += accept_node node = rst2node(docstring) if node is not None: method_node += node renderer = info['renderer'] if renderer == 'simplejson': renderer = 'json' response = nodes.paragraph() response += nodes.strong(text='Response: %s' % renderer) method_node += response service_node += method_node return service_node
def _build_markup(self, commits): list_node = nodes.definition_list() for commit in commits: date_str = datetime.fromtimestamp(commit.authored_date) if '\n' in commit.message: message, detailed_message = commit.message.split('\n', 1) else: message = commit.message detailed_message = None item = nodes.list_item() item += [ nodes.emphasis(text="Last Updated by "), nodes.strong(text=str(commit.author)), nodes.inline(text=" at "), nodes.emphasis(text=str(date_str)), nodes.inline(text=" with message "), nodes.strong(text=message), ] if detailed_message: detailed_message = detailed_message.strip() if self.options.get('detailed-message-pre', False): item.append( nodes.literal_block(text=detailed_message)) else: item.append(nodes.paragraph(text=detailed_message)) list_node.append(item) return [list_node]
def indexmarkup_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): """Role for PEP/RFC references that generate an index entry.""" env = inliner.document.settings.env if not typ: typ = env.config.default_role else: typ = typ.lower() has_explicit_title, title, target = split_explicit_title(text) # type: bool, unicode, unicode # NOQA title = utils.unescape(title) target = utils.unescape(target) targetid = 'index-%s' % env.new_serialno('index') indexnode = addnodes.index() targetnode = nodes.target('', '', ids=[targetid]) inliner.document.note_explicit_target(targetnode) if typ == 'pep': indexnode['entries'] = [ ('single', _('Python Enhancement Proposals; PEP %s') % target, targetid, '', None)] anchor = '' # type: unicode anchorindex = target.find('#') if anchorindex > 0: target, anchor = target[:anchorindex], target[anchorindex:] if not has_explicit_title: title = "PEP " + utils.unescape(title) try: pepnum = int(target) except ValueError: msg = inliner.reporter.error('invalid PEP number %s' % target, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] ref = inliner.document.settings.pep_base_url + 'pep-%04d' % pepnum sn = nodes.strong(title, title) rn = nodes.reference('', '', internal=False, refuri=ref+anchor, classes=[typ]) rn += sn return [indexnode, targetnode, rn], [] elif typ == 'rfc': indexnode['entries'] = [ ('single', 'RFC; RFC %s' % target, targetid, '', None)] anchor = '' anchorindex = target.find('#') if anchorindex > 0: target, anchor = target[:anchorindex], target[anchorindex:] if not has_explicit_title: title = "RFC " + utils.unescape(title) try: rfcnum = int(target) except ValueError: msg = inliner.reporter.error('invalid RFC number %s' % target, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] ref = inliner.document.settings.rfc_base_url + inliner.rfc_url % rfcnum sn = nodes.strong(title, title) rn = nodes.reference('', '', internal=False, refuri=ref+anchor, classes=[typ]) rn += sn return [indexnode, targetnode, rn], []
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 make_process_node(self, process): """Fill the content of process definiton node. :param dict process: process data as given from yaml.load function :return: process node """ name = process['name'] slug = process['slug'] typ = process['type'] version = process['version'] description = process.get('description', '') source_uri = process['source_uri'] inputs = process.get('input', []) outputs = process.get('output', []) # Make process name a section title: section = nodes.section(ids=['process-' + slug]) section += nodes.title(name, name) # Make process header: section += self.make_process_header(slug, typ, version, source_uri, description, inputs) # Make inputs section: container_node = nodes.container(classes=['toggle']) container_header = nodes.paragraph(classes=['header']) container_header += nodes.strong(text='Input arguments') container_node += container_header container_body = nodes.container() for field_schema, _, path in iterate_schema({}, inputs, ''): container_body += nodes.strong(text=path) container_body += self.make_properties_list(field_schema) container_node += container_body section += container_node # Make outputs section: container_node = nodes.container(classes=['toggle']) container_header = nodes.paragraph(classes=['header']) container_header += nodes.strong(text='Output results') container_node += container_header container_body = nodes.container() for field_schema, _, path in iterate_schema({}, outputs, ''): container_body += nodes.strong(text=path) container_body += self.make_properties_list(field_schema) container_node += container_body section += container_node return [section, addnodes.index(entries=[('single', name, 'process-' + slug, '', None)])]
def indexmarkup_role(typ, rawtext, etext, lineno, inliner, options={}, content=[]): env = inliner.document.settings.env if not typ: typ = env.config.default_role text = utils.unescape(etext) targetid = 'index-%s' % env.index_num env.index_num += 1 indexnode = addnodes.index() targetnode = nodes.target('', '', ids=[targetid]) inliner.document.note_explicit_target(targetnode) if typ == 'envvar': env.note_index_entry('single', text, targetid, text) env.note_index_entry('single', 'environment variable; %s' % text, targetid, text) indexnode['entries'] = [('single', text, targetid, text), ('single', 'environment variable; %s' % text, targetid, text)] xref_nodes = xfileref_role(typ, rawtext, etext, lineno, inliner, options, content)[0] return [indexnode, targetnode] + xref_nodes, [] elif typ == 'pep': env.note_index_entry('single', 'Python Enhancement Proposals!PEP %s' % text, targetid, 'PEP %s' % text) indexnode['entries'] = [('single', 'Python Enhancement Proposals!PEP %s' % text, targetid, 'PEP %s' % text)] try: pepnum = int(text) except ValueError: msg = inliner.reporter.error('invalid PEP number %s' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] ref = inliner.document.settings.pep_base_url + 'pep-%04d' % pepnum sn = nodes.strong('PEP '+text, 'PEP '+text) rn = nodes.reference('', '', refuri=ref) rn += sn return [indexnode, targetnode, rn], [] elif typ == 'rfc': env.note_index_entry('single', 'RFC; RFC %s' % text, targetid, 'RFC %s' % text) indexnode['entries'] = [('single', 'RFC; RFC %s' % text, targetid, 'RFC %s' % text)] try: rfcnum = int(text) except ValueError: msg = inliner.reporter.error('invalid RFC number %s' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] ref = inliner.document.settings.rfc_base_url + inliner.rfc_url % rfcnum sn = nodes.strong('RFC '+text, 'RFC '+text) rn = nodes.reference('', '', refuri=ref) rn += sn return [indexnode, targetnode, rn], []
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 role(name, rawtext, text, lineno, inliner, options={}, content=[]): env = inliner.document.settings.env # Generic index entries indexnode = addnodes.index() indexnode['entries'] = [] try: platform, version = text.split(' ', 1) targetid = 'os-{}-{}-{}'.format(platform, version, env.new_serialno('os')) indexnode['entries'].append([ 'single', 'Platform; {}; {}'.format(platform, version), targetid, '', None ]) except ValueError: platform = text version = '' targetid = 'os-{}-{}-{}'.format(platform, version, env.new_serialno('os')) indexnode['entries'].append([ 'single', 'Platform; {}'.format(platform), targetid, '', None ]) targetnode = nodes.target('', '', ids=[targetid]) text_node = nodes.strong(text='{}'.format(text)) return [targetnode, text_node, indexnode], []
def formatComponent(self, moduleName, name, X): # no class bases available from repository scanner CLASSNAME = self.formatClassStatement(name, X.bases) CLASSDOC = self.docString(X.doc) INBOXES = self.boxes(name,"Inboxes", X.inboxes) OUTBOXES = self.boxes(name,"Outboxes", X.outboxes) if self.config.includeMethods and len(X.listAllFunctions()): METHODS = [ nodes.section('', nodes.title('', 'Methods defined here'), boxright('', nodes.paragraph('', '', nodes.strong('', nodes.Text("Warning!")) ), nodes.paragraph('', '', nodes.Text("You should be using the inbox/outbox interface, not these methods (except construction). This documentation is designed as a roadmap as to their functionalilty for maintainers and new component developers.") ), ), * self.formatMethodDocStrings(name,X) ) ] else: METHODS = [] return \ nodes.section('', * [ nodes.title('', CLASSNAME, ids=["symbol-"+name]) ] + CLASSDOC + [ INBOXES, OUTBOXES ] + METHODS + [ self.formatInheritedMethods(name,X) ] )
def print_subcommand_list(data, nested_content): definitions = map_nested_definitions(nested_content) items = [] if 'children' in data: for child in data['children']: my_def = [nodes.paragraph( text=child['help'])] if child['help'] else [] name = child['name'] my_def = apply_definition(definitions, my_def, name) if len(my_def) == 0: my_def.append(nodes.paragraph(text='Undocumented')) my_def.append(nodes.literal_block(text=child['usage'])) my_def.append(print_command_args_and_opts( print_arg_list(child, nested_content), print_opt_list(child, nested_content), text_from_rst(child.get('description', ""), is_rst=True), print_subcommand_list(child, nested_content), )) items.append( nodes.definition_list_item( '', nodes.term('', '', nodes.strong(text=name)), nodes.definition('', *my_def) ) ) return nodes.definition_list('', *items)
def attach_function(self, node, func): owner, name = func.name.split_owner() if owner is not None: owner = unicode(owner) + '::' node += addnodes.desc_addname(owner, owner) # cast operator is special. in this case the return value # is reversed. if isinstance(name, CastOpDefExpr): node += addnodes.desc_name('operator', 'operator') node += nodes.Text(u' ') self.attach_type(node, name.typename) else: funcname = unicode(name) node += addnodes.desc_name(funcname, funcname) paramlist = addnodes.desc_parameterlist() for arg in func.signature: param = addnodes.desc_parameter('', '', noemph=True) if arg.type is not None: self.attach_type(param, arg.type) param += nodes.Text(u' ') #param += nodes.emphasis(unicode(arg.name), unicode(arg.name)) param += nodes.strong(unicode(arg.name), unicode(arg.name)) if arg.default is not None: def_ = u'=' + unicode(arg.default) #param += nodes.emphasis(def_, def_) param += nodes.Text(def_) paramlist += param node += paramlist if func.const: node += addnodes.desc_addname(' const', ' const') if func.pure_virtual: node += addnodes.desc_addname(' = 0', ' = 0')
def menuitem(role, rawtext, text, lineno, inliner, options={}, content={}): items = text.split(',') ret = [] for i in range(len(items)): item = items[i] if current_builder == 'xdehtml': c = nodes.inline() n = nodes.Text(item) # print dir(n) c +=n if i != len(items)-1: c['classes'].append('menuitem') else: c['classes'].append('menuitemlast') ret.append(c) else: s = nodes.strong() s += nodes.Text(item) ret.append(s) if i != len(items)-1: ret.append(nodes.Text(' ')); sub = nodes.substitution_reference() sub['refname'] = 'submenu' ret.append(sub) return ret, []
def run(self): env = self.state.document.settings.env config = env.config repodir = env.srcdir + '/' + config["git_repository_root"] doc_path = env.srcdir + '/' + env.docname + config["source_suffix"] if self.options.get('dir', False) == None: doc_path = '/'.join(doc_path.split('/')[:-1]) repo = Repo(repodir) commits = repo.iter_commits(paths=doc_path) l = nodes.bullet_list() revisions_to_display = self.options.get('revisions', 10) for commit in list(commits)[:revisions_to_display]: date_str = datetime.fromtimestamp(commit.authored_date) if '\n' in commit.message: message, detailed_message = commit.message.split('\n', 1) else: message = commit.message detailed_message = None item = nodes.list_item() item += [ nodes.strong(text=message), nodes.inline(text=" by "), nodes.emphasis(text=str(commit.author)), nodes.inline(text=" at "), nodes.emphasis(text=str(date_str)) ] if detailed_message: item.append(nodes.caption(text=detailed_message.strip())) l.append(item) return [l]
def run(self): env = self.state.document.settings.env repo = Repo(env.srcdir) commits = repo.iter_commits() l = nodes.bullet_list() for commit in list(commits)[:10]: date_str = datetime.fromtimestamp(commit.authored_date) if '\n' in commit.message: message, detailed_message = commit.message.split('\n', 1) else: message = commit.message detailed_message = None item = nodes.list_item() item += [ nodes.strong(text=message), nodes.inline(text=" by "), nodes.emphasis(text=str(commit.author)), nodes.inline(text=" at "), nodes.emphasis(text=str(date_str)) ] if detailed_message: item.append(nodes.caption(text=detailed_message.strip())) l.append(item) return [l]
def replace_blog_post_lists(app, doctree, fromdocname): """ Replace blog_post_list nodes with ordered list-o-links to posts. """ # Obtain blog posts post_names = filter(lambda x: x.startswith('blog/'), app.env.found_docs) posts = map(lambda x: (x, app.env.get_doctree(x)), post_names) # Build "list" of links/etc post_links = [] for post, doc, title, date, opener in get_posts(app): # Link itself uri = app.builder.get_relative_uri(fromdocname, post) link = nodes.reference('', '', refdocname=post, refuri=uri) # Title, bolded. TODO: use 'topic' or something maybe? link.append(nodes.strong('', title)) date = date.strftime("%Y-%m-%d") # Meh @ not having great docutils nodes which map to this. html = '<div class="timestamp"><span>%s</span></div>' % date timestamp = nodes.raw(text=html, format='html') # NOTE: may group these within another element later if styling # necessitates it group = [timestamp, nodes.paragraph('', '', link), opener] post_links.extend(group) # Replace temp node(s) w/ expanded list-o-links for node in doctree.traverse(blog_post_list): node.replace_self(post_links)
def role(name, rawtext, text, lineno, inliner, options={}, content=[]): env = inliner.document.settings.env try: command, parameter = text.split(' ', 1) except ValueError: command = text parameter = '' indexstring = 'Console; Command; {}'.format(command) targetid = 'bcommand-{}-{}'.format(command, env.new_serialno('bcommand')) # Generic index entries indexnode = addnodes.index() indexnode['entries'] = [] indexnode['entries'].append([ 'single', indexstring, targetid, '', None ]) targetnode = nodes.target('', '', ids=[targetid]) text_node = nodes.strong(text='{}'.format(text)) return [targetnode, text_node, indexnode], []
def auto_list(app, doctree, fromdocname): """ Generate a listing for classes, methods and functions described in the file """ env = app.builder.env for node in doctree.traverse(autolisting_node): content = [] sidebar = nodes.sidebar() para = nodes.paragraph() part_title = nodes.strong() part_title += nodes.Text('Code Listing') para += part_title sidebar += para items = collect_items_for_autolisting(doctree) listings = generate_autolisting(items) for entry in listings: sidebar += entry # only show sidebar if sidebar has content if listings: content.append(sidebar) node.replace_self(content) break
def handle_signature(self, sig, signode): attrtype = self.options.get('type', _(u"объект")) typedef = self.options.get('type', 'str').split() typemap = { 'object': u"объект", 'int': u"целое число", 'str': u"строка", 'list': u"список", 'bool': u"истина/ложь", } if typedef[0] not in typemap: self.env.warn(self.env.docname, "%d: Unknown pilot attr type: %s, defaulting to object" % (self.env.lineno, typedef[0])) typedef[0] = 'object' t = u", " + typemap[typedef[0]] if typedef[0] == 'list': if len(typedef) > 1: t += u", тип элемента: %s" % typemap[typedef[1]] if len(typedef) > 2: t += u", не менее %s элемента" % typedef[2] if 'comment' in self.options: t += u", %s" % self.options['comment'] if 'required' not in self.options: t += u", опциональный параметр" signode += nodes.strong(sig, sig) signode += nodes.emphasis(t, t) return sig
def run(self): env = self.state.document.settings.env name = self.content[0].strip() expr = '\n'.join(self.content[1:]).strip() targetid = "syntax-%s" % name targetnode = nodes.target('', '', ids=[targetid]) label = nodes.paragraph('', '', nodes.strong(text=name)) ix = addnodes.index(entries=[ ("single", "syntax; " + name, targetid, False)]) try: it = eval(expr, railroad_diagrams.__dict__) except Exception as ex: print >>stderr, "@@eek!", self.content print >>stderr, "@@", ex raise diag = RailroadDiagram(railroad_diagrams.Diagram(it)) if env.config.syntax_fp: out = env.config.syntax_fp dump({'name': name, 'expr': expr}, out) out.write(",\n\n") return [targetnode, ix, label, diag]
def _get_column_node(m): if m.group('name'): node = addnodes.desc_parameter() if m.group('key'): node += nodes.Text("#", "#") key = nodes.strong(m.group('name'), m.group('name')) key['classes'].append('arg-key') node += key if m.group('type'): node += nodes.Text(" : ", " : ") value = nodes.inline(m.group('type'), m.group('type')) value['classes'].append('arg-value') # FIXME: should vbe arg type probably node += value if m.group('optional'): node += nodes.Text("? ", "?") # FIXME: find a better type if m.group('reference'): value = nodes.inline(m.group('reference'), m.group('reference')) value['classes'].append('arg-value') # FIXME: should vbe arg type probably node += value return node else: return addnodes.desc_parameter(m.group(0), m.group(0))
def _render_service(self, path, service, methods): env = self.state.document.settings.env service_id = "service-%d" % env.new_serialno('service') service_node = nodes.section(ids=[service_id]) service_node += nodes.title(text='Service at %s' % service.route_name) if service.description is not None: service_node += rst2node(_dedent(service.description)) for method, info in methods.items(): method_id = '%s-%s' % (service_id, method) method_node = nodes.section(ids=[method_id]) method_node += nodes.title(text=method) node = rst2node(_dedent(info['docstring'])) if node is not None: method_node += node renderer = info['renderer'] if renderer == 'simplejson': renderer = 'json' response = nodes.paragraph() response += nodes.strong(text='Response: %s' % renderer) method_node += response service_node += method_node return service_node
def run(self): # Raise an error if the directive does not have contents. self.assert_has_content() self.document = self.state_machine.document text = '\n'.join(self.content) # Create the admonition node, to be populated by `nested_parse`. self.name=self.arguments[0].strip() term = nodes.term() term += nodes.strong(text=self.arguments[0]) targetnode = self.make_targetnode() deflist = nodes.definition_list() configuration_def = nodes.definition_list_item() configuration_def += term defn = nodes.definition() configuration_def += defn deflist += configuration_def # Parse the directive contents. self.state.nested_parse(self.content, self.content_offset, defn) option_map = {} option_map['features'] = 'Required for features' field_list = self.options_to_field_list(option_map) if (field_list != None): defn += field_list self.parsed('configuration').append(self) return [targetnode, deflist]
def process_usecase_nodes(app, doctree, fromdocname): if not app.config.usecases_include_usecases: for node in doctree.traverse(usecase): node.parent.remove(node) # Replace all usecaselist nodes with a list of the collected usecases. # Argument each usecase with a backlink to the original location. env = app.builder.env if not hasattr(env, "usecase_all_usecases"): return for node in doctree.traverse(usecaselist): if not app.config.usecases_include_usecases: node.replace_self([]) continue content = [] for usecase_info in env.usecase_all_usecases: para = nodes.paragraph() # Create a reference if app.config.usecases_simple_usecaseslist: para += nodes.strong("UseCase: ", "UseCase: ") # description = ( # _('%s ') % # (usecase_info['usecase-name'])) # para += nodes.Text(description, description) newnode = nodes.reference("", "") innernode = nodes.emphasis(_(usecase_info["usecase-name"]), _(usecase_info["usecase-name"])) newnode["refdocname"] = usecase_info["docname"] newnode["refuri"] = app.builder.get_relative_uri(fromdocname, usecase_info["docname"]) newnode["refuri"] += "#" + usecase_info["target"]["refid"] newnode.append(innernode) para += newnode content.append(para) else: filename = env.doc2path(usecase_info["docname"], base=None) description = _("(The original entry is located in %s, line %d and can be found ") % ( filename, usecase_info["lineno"], ) para += nodes.Text(description, description) newnode = nodes.reference("", "") innernode = nodes.emphasis(_("here"), _("here")) newnode["refdocname"] = usecase_info["docname"] newnode["refuri"] = app.builder.get_relative_uri(fromdocname, usecase_info["docname"]) # newnode['refuri'] += '#' + usecase_info['target']['refid'] newnode.append(innernode) para += newnode para += nodes.Text(".)", ".)") # Insert into the usecaselist content.append(usecase_info["usecase"]) content.append(para) node.replace_self(content)
def _generate_rows(self, sensors): vendor_name = None for s in sensors: # only generate one row for each vendor name that serves as a group heading if 'vendor_name' in s and vendor_name != s['vendor_name']: vendor_name = s['vendor_name'] strong = nodes.strong(text=vendor_name) para = nodes.paragraph() para += strong entry = nodes.entry(morecols=5) entry += para row = nodes.row() row += entry yield row # then generate one row for each sensor yield self._row([ self._link(s.get('vendor_website', None), s.get('vendor_part_number', '')), ':ref:`{} <{}>`'.format(s.get('vendor_part_name', s.get('vendor_part_number', '')), s['url_name']), '``{}``'.format(s['name']), self._pretty_sensor_type(s['sensor_type']), self._auto_detect(s['name'], s['sensor_type']), ])
def handle_signature(self, sig, signode): name = sig if sig.find("::") > 0: signode += nodes.strong("", name) return name
def run(self): if self.name in self.state.document.settings.dir_ignore: return [] children = [] if self.name not in self.state.document.settings.dir_notitle: children.append(nodes.strong(self.name, u"%s: " % self.name)) # keep the arguments, drop the options for a in self.arguments: if a.startswith(':') and a.endswith(':'): break children.append(nodes.emphasis(a, u"%s " % a)) if self.name in self.state.document.settings.dir_nested: if self.content: container = nodes.Element() self.state.nested_parse(self.content, self.content_offset, container) children.extend(container.children) else: content = u'\n'.join(self.content) children.append(nodes.literal_block(content, content)) node = any_directive(self.block_text, '', *children, dir_name=self.name) return [node]
def _create_notes_paragraph(self, notes): """Constructs a paragraph which represents the implementation notes The paragraph consists of text and clickable URL nodes if links were given in the notes. """ para = nodes.paragraph() para.append(nodes.strong(text="Notes: ")) # links could start with http:// or https:// link_idxs = [m.start() for m in re.finditer('https?://', notes)] start_idx = 0 for link_idx in link_idxs: # assume the notes start with text (could be empty) para.append(nodes.inline(text=notes[start_idx:link_idx])) # create a URL node until the next text or the end of the notes link_end_idx = notes.find(" ", link_idx) if link_end_idx == -1: # In case the notes end with a link without a blank link_end_idx = len(notes) uri = notes[link_idx:link_end_idx + 1] para.append(nodes.reference("", uri, refuri=uri)) start_idx = link_end_idx + 1 # get all text after the last link (could be empty) or all of the # text if no link was given para.append(nodes.inline(text=notes[start_idx:])) return para
def _add_feature_info(self, item, feature): para_info = nodes.paragraph() para_info.append(nodes.strong(text="info:")) info_list = nodes.bullet_list() maturity_literal = nodes.literal(text=feature.maturity, classes=["fm_maturity_" + feature.maturity]) self._append_info_list_item(info_list, "Maturity", items=[maturity_literal]) self._append_info_list_item(info_list, "API Docs", link=feature.api_doc_link) self._append_info_list_item(info_list, "Admin Docs", link=feature.admin_doc_link) tempest_items = [] if feature.tempest_test_uuids: for uuid in feature.tempest_test_uuids.split(";"): base = "https://github.com/openstack/tempest/search?q=%s" link = base % uuid inline_ref = self._get_uri_ref(link, text=uuid) tempest_items.append(inline_ref) tempest_items.append(nodes.inline(text=", ")) # removing trailing punctuation tempest_items = tempest_items[:-1] self._append_info_list_item(info_list, "Tempest tests", items=tempest_items) para_info.append(info_list) item.append(para_info)
def _build_markup(self, commits): list_node = nodes.bullet_list() for commit in commits: date_str = datetime.fromtimestamp(commit.authored_date) if '\n' in commit.message: message, detailed_message = commit.message.split('\n', 1) else: message = commit.message detailed_message = None item = nodes.list_item() item += nodes.strong(text=message) if not self.options.get('hide_author'): item += [nodes.inline(text=" by "), nodes.emphasis(text=six.text_type(commit.author))] if not self.options.get('hide_date'): item += [nodes.inline(text=" at "), nodes.emphasis(text=str(date_str))] if detailed_message and not self.options.get('hide_details'): detailed_message = detailed_message.strip() if self.options.get('detailed-message-pre', False): item.append( nodes.literal_block(text=detailed_message)) else: item.append(nodes.paragraph(text=detailed_message)) list_node.append(item) return [list_node]
def role_ftype(name, rawtext, text, lineno, inliner, options={}, content=[]): node = nodes.strong(text, text) assert text.count('(') in (0, 1) assert text.count('(') == text.count(')') assert ')' not in text or text.endswith(')') m = re.search(r'\((.*?)\)', text) node['ids'] = [m.group(1) if m else text] return [node], []
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 write_autosummaries(app, doctree): for idx, node in enumerate(doctree.traverse(nodes.section)): immediate_autodoc_nodes = [ n for n in node.traverse(addnodes.desc) if n.parent is node and n.attributes.get("objtype", None) in ("attribute", "data", "class", "function") ] if not immediate_autodoc_nodes: continue where = node.index(immediate_autodoc_nodes[0]) immediate_autodoc_nodes = sorted( immediate_autodoc_nodes, key=lambda node: node[0].attributes["fullname"].lower(), ) table = nodes.table("", classes=["longtable"]) group = nodes.tgroup("", cols=2) table.append(group) group.append(nodes.colspec("", colwidth=10)) group.append(nodes.colspec("", colwidth=90)) header = nodes.thead("") header.append( nodes.row( "", nodes.entry("", nodes.Text("Object Name", "Object Name")), nodes.entry("", nodes.Text("Description", "Description")), ) ) group.append(header) body = nodes.tbody("") group.append(body) for ad_node in immediate_autodoc_nodes: # what = ad_node.attributes["objtype"] sig = ad_node.children[0] ids = sig.attributes.get("ids", [None]) if not ids: continue refid = ids[0] if not refid: continue row = nodes.row("") obj = _track_autodoced.get(refid, None) if inspect.isfunction(obj): param_str = _quick_inspect_sig(*inspect.getfullargspec(obj)) else: param_str = "" name_node = list(sig.traverse(addnodes.desc_name)) if name_node: name_node = name_node[0] else: continue name_node = name_node.deepcopy() # nodes.literal( # "", *[c.copy() for c in name_node.children] # ) p = nodes.paragraph( "", "", # nodes.Text(what + " ", what + " "), nodes.reference( "", "", name_node, refid=refid, classes=["reference", "internal"], ), nodes.Text(param_str, param_str), ) row.append( nodes.entry("", p, classes=["nowrap", "autosummary-name"]) ) try: para = ad_node[1][0] if isinstance(para, nodes.paragraph): text = para.deepcopy() else: text = nodes.Text("", "") except IndexError: text = nodes.Text("", "") if ad_node.attributes.get("objtype") == "class": member_nodes = [] for attr_desc in ad_node.traverse(addnodes.desc): objtype = attr_desc.attributes.get("objtype") if objtype not in ("classmethod", "method", "attribute"): continue attr_sig = attr_desc.children[0] attr_ids = attr_sig.attributes.get("ids", [None]) if not attr_ids: continue attr_ref_id = attr_ids[0] if not attr_ref_id: continue attr_name_node = list( attr_desc.traverse(addnodes.desc_name) )[0] attr_name_node = attr_name_node.deepcopy() if objtype in ("classmethod", "method"): attr_name_node.append(nodes.Text("()")) attr_ref = nodes.reference( "", "", attr_name_node, refid=attr_ref_id, classes=["reference", "internal"], ) member_nodes.append(attr_ref) if member_nodes: method_list = nodes.paragraph("", "", member_nodes[0]) for ref in member_nodes[1:]: method_list.append(nodes.Text(", ")) method_list.append(ref) method_box = nodes.container( "", nodes.paragraph( "", "", nodes.strong("", nodes.Text("Members")) ), method_list, classes=["class-members"], ) content = ad_node.traverse(addnodes.desc_content) if content: content = list(content)[0] for i, n in enumerate(content.children): if isinstance(n, (addnodes.index, addnodes.desc)): content.insert(i - 1, method_box) break entry = nodes.entry("", text) row.append(entry) body.append(row) if where > 0: node.insert(where, table)
def _render_service(self, service): service_id = "service-%d" % self.env.new_serialno('service') service_node = nodes.section(ids=[service_id]) service_node += nodes.title(text='Service at %s' % service.path) if service.description is not None: service_node += rst2node(trim(service.description)) for method, view, args in service.definitions: method_id = '%s-%s' % (service_id, method) method_node = nodes.section(ids=[method_id]) method_node += nodes.title(text=method) docstring = trim(view.__doc__ or "") + '\n' if 'schema' in args: schema = args['schema'] attrs_node = nodes.inline() for location in ('headers', 'querystring', 'body'): attributes = schema.get_attributes(location=location) if attributes: attrs_node += nodes.inline( text='values in the %s' % location) location_attrs = nodes.bullet_list() for attr in attributes: temp = nodes.list_item() desc = "%s : " % attr.name if hasattr(attr, 'type'): desc += " %s, " % attr.type if attr.required: desc += "required " else: desc += "optional " temp += nodes.inline(text=desc) location_attrs += temp attrs_node += location_attrs method_node += attrs_node for validator in args.get('validators', ()): if validator.__doc__ is not None: docstring += trim(validator.__doc__) if 'accept' in args: accept = to_list(args['accept']) if callable(accept): if accept.__doc__ is not None: docstring += accept.__doc__.strip() else: accept_node = nodes.strong(text='Accepted content types:') node_accept_list = nodes.bullet_list() accept_node += node_accept_list for item in accept: temp = nodes.list_item() temp += nodes.inline(text=item) node_accept_list += temp method_node += accept_node node = rst2node(docstring) DocFieldTransformer(self).transform_all(node) if node is not None: method_node += node renderer = args['renderer'] if renderer == 'simplejson': renderer = 'json' response = nodes.paragraph() response += nodes.strong(text='Response: %s' % renderer) method_node += response service_node += method_node return service_node
def run(self): return [nodes.strong(text='from class: %s' % self.options['opt'])]
def _doc_property(self, wpname): blueprint_name, prop = wpname.split('.') table = """ +----------+---------+-------------+ | name | default | description | +==========+=========+=============+ | replace | replace | replace | +----------+---------+-------------+ """ table = self._rest2node(table) row = table.children[0].children[0].children[4].children[0] row[0].children = [] row[1].children = [] row[2].children = [] row[0].append(nodes.paragraph(text=prop)) default = factory.defaults.get(wpname, _marker) if default is not _marker: row[1].append(nodes.literal(text=repr(default))) else: default = factory.defaults.get(prop, _marker) if default is not _marker: row[1].append(nodes.literal(text=repr(default))) row[1].append(nodes.emphasis(text=' global')) else: row[1].append(nodes.emphasis(text='required/ not set')) doc = factory.doc['props'].get(wpname, factory.doc['props'].get(prop, _marker)) if doc is not _marker: row[2].append(self._rest2node(doc)) else: row[2].append(nodes.paragraph('(not documented)')) # this does not log. bullshit. no idea how to make sphinx log print("YAFOWIL property '%s' is not documented!" % wpname) ul = nodes.bullet_list() used = [] def add_chain_for_property(chain): for el in chain: if prop not in getattr(el, '__yafowil_managed_props__', []): #if getattr(el, '__yafowil_managed_props__', True): #print ('YAFOWIL callable %s has no ' % el, # 'managed props decorator!') continue li = nodes.list_item() if hasattr(el, 'func_name'): # function name = el.func_name else: # class name = el.__class__.__name__ if name in used: continue used.append(name) li.append(nodes.paragraph(text=name)) ul.append(li) add_chain_for_property(factory.extractors(blueprint_name)) add_chain_for_property(factory.edit_renderers(blueprint_name)) add_chain_for_property(factory.display_renderers(blueprint_name)) add_chain_for_property(factory.builders(blueprint_name)) add_chain_for_property(factory.preprocessors(blueprint_name)) if not used: print("YAFOWIL property '%s' is not handled by managed props!" % \ wpname) if (len(ul)): row[2].append(nodes.strong(text='Used by:')) row[2].append(ul) return row
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)
class ExcelTableDirective(ListTable, DirectiveTemplate): """ ExcelTableDirective implements the directive. Directive allows to create RST tables from the contents of the Excel sheet. The functionality is very similar to csv-table (docutils) and xmltable (:mod:`sphinxcontrib.xmltable`). Example of the directive: .. code-block:: rest .. exceltable:: :file: path/to/document.xls :header: 1 """ #required_arguments = 0 #optional_arguments = 0 has_content = False option_spec = { 'file': directives.path, 'selection': directives.unchanged_required, 'encoding': directives.unchanged, 'header': directives.unchanged, 'sheet': directives.unchanged, 'class': directives.class_option, 'widths': directives.unchanged, } def run(self): """ Implements the directive """ # Get content and options file_path = self.options.get('file', None) selection = self.options.get('selection', 'A1:') sheet = self.options.get('sheet', '0') header = self.options.get('header', '0') col_widths = self.options.get('widths', None) # Divide the selection into from and to values if u':' not in selection: selection += ':' fromcell, tocell = selection.split(':') if not fromcell: fromcell = 'A1' if not tocell: tocell = None #print selection, fromcell, tocell if not file_path: return [self._report('file_path -option missing')] # Header option header_rows = 0 if header and header.isdigit(): header_rows = int(header) # Transform the path suitable for processing file_path = self._get_directive_path(file_path) print 'file path: %s' % file_path try: et = ExcelTable(open(file_path)) table = et.create_table(fromcell=fromcell, tocell=tocell, nheader=header_rows, sheet=sheet) except Exception, e: return [msgr.error('Error occured while creating table: %s' % e)] pass #print table title, messages = self.make_title() #node = nodes.Element() # anonymous container for parsing #self.state.nested_parse(self.content, self.content_offset, node) # If empty table is created if not table: self._report('The table generated from queries is empty') return [nodes.paragraph(text='')] try: table_data = [] # If there is header defined, set the header-rows param and # append the data in row =>. build_table_from_list handles the header generation if header and not header.isdigit(): # Otherwise expect the header to be string with column names defined in # it, separating the values with comma header_rows = 1 table_data.append([ nodes.paragraph(text=hcell.strip()) for hcell in header.split(',') ]) # Put the given data in rst elements: paragraph for row in table['headers']: table_data.append( [nodes.paragraph(text=cell['value']) for cell in row]) # Iterates rows: put the given data in rst elements for row in table['rows']: row_data = [] for cell in row: class_data = [''] # Node based on formatting rules # NOTE: rst does not support nested, use class attribute instead if cell['italic']: class_data.append('italic') if cell['bold']: node = nodes.strong(text=cell['value']) else: node = nodes.paragraph(text=cell['value']) # Add additional formatting as class attributes node['classes'] = class_data row_data.append([node]) # FIXME: style attribute does not get into writer if cell['bgcolor']: rgb = [str(val) for val in cell['bgcolor']] node.attributes[ 'style'] = 'background-color: rgb(%s);' % ','.join( rgb) #print node table_data.append(row_data) # If there is no data at this point, throw an error if not table_data: return [msgr.error('Selection did not return any data')] # Get params from data num_cols = len(table_data[0]) # Get the widths for the columns: # 1. Use provided info, if available # 2. Use widths from the excelsheet # 3. Use default widths (equal to all) # # Get content widths from the first row of the table # if it fails, calculate default column widths if col_widths: col_widths = [int(width) for width in col_widths.split(',')] else: col_widths = [int(col['width']) for col in table['rows'][0]] col_width_total = sum(col_widths) col_widths = [ int(width * 100 / col_width_total) for width in col_widths ] # If still empty for some reason, use default widths if not col_widths: col_widths = self.get_column_widths(num_cols) stub_columns = 0 # Sanity checks # Different amount of cells in first and second row (possibly header and 1 row) if type(header) is not int: if len(table_data) > 1 and len(table_data[0]) != len( table_data[1]): error = msgr.error( 'Data amount mismatch: check the directive data and params' ) return [error] self.check_table_dimensions(table_data, header_rows, stub_columns) except SystemMessagePropagation, detail: return [detail.args[0]]
def _build_markup(self, notifications): content = [] cols = ['Event type', 'Notification class', 'Payload class', 'Sample'] table = nodes.table() content.append(table) group = nodes.tgroup(cols=len(cols)) table.append(group) head = nodes.thead() group.append(head) for _ in cols: group.append(nodes.colspec(colwidth=1)) body = nodes.tbody() group.append(body) # fill the table header row = nodes.row() body.append(row) for col_name in cols: col = nodes.entry() row.append(col) text = nodes.strong(text=col_name) col.append(text) # fill the table content, one notification per row for name, payload, sample_file in notifications: event_type = sample_file[0:-5].replace('-', '.') row = nodes.row() body.append(row) col = nodes.entry() row.append(col) text = nodes.literal(text=event_type) col.append(text) col = nodes.entry() row.append(col) text = nodes.literal(text=name) col.append(text) col = nodes.entry() row.append(col) text = nodes.literal(text=payload) col.append(text) col = nodes.entry() row.append(col) with open(self.SAMPLE_ROOT + sample_file, 'r') as f: sample_content = f.read() event_type = sample_file[0:-5] html_str = self.TOGGLE_SCRIPT % ((event_type, ) * 3) html_str += ("<input type='button' id='%s-hideshow' " "value='hide/show sample'>" % event_type) html_str += ("<div id='%s-div'><pre>%s</pre></div>" % (event_type, sample_content)) raw = nodes.raw('', html_str, format="html") col.append(raw) return content
def run(self): env = self.state.document.settings.env # generate the linkback node for this option targetid = "option-%s" % self.options['config'] targetnode = nodes.target('', '', ids=[targetid]) # Each option will be outputted as a single-item definition list # (just like it was doing before we used this extension) dl = nodes.definition_list() dl['classes'].append('mrjob-opt') dli = nodes.definition_list_item() term = nodes.term() # config option shall be bold if 'config' in self.options: cfg = self.options['config'] term.append(nodes.strong(cfg, cfg)) if 'switch' in self.options: term.append(nodes.Text(' (', ' (')) # switch shall be comma-separated literals if 'switch' in self.options: switches = self.options['switch'].split(', ') for i, s in enumerate(switches): if i > 0: term.append(nodes.Text(', ', ', ')) term.append(nodes.literal(s, s)) if 'config' in self.options: term.append(nodes.Text(')', ')')) dli.append(term) # classifier is either plain text or a link to some more docs, so parse # its contents classifier = nodes.classifier() type_nodes, messages = self.state.inline_text( self.options.get('type', ''), self.lineno) classifier.extend(type_nodes) dli.append(classifier) # definition holds the description defn = nodes.definition() # add a default if any default_nodes = [] if 'default' in self.options: default_par = nodes.paragraph() default_par.append(nodes.strong('Default: ', 'Default: ')) textnodes, messages = self.state.inline_text( self.options['default'], self.lineno) default_nodes = textnodes default_par.extend(textnodes) defn.append(default_par) # parse the description like a nested block (see # sphinx.compat.make_admonition) desc_par = nodes.paragraph() self.state.nested_parse(self.content, self.content_offset, desc_par) defn.append(desc_par) dli.append(defn) dl.append(dli) if not hasattr(env, 'optionlist_all_options'): env.optionlist_all_options = [] env.optionlist_indexed_options = {} # store info for the optionlist traversal to find info = { 'docname': env.docname, 'lineno': self.lineno, 'options': self.options, 'content': self.content, 'target': targetnode, 'type_nodes': type_nodes, 'default_nodes': default_nodes, } env.optionlist_all_options.append(info) env.optionlist_indexed_options[self.options['config']] = info return [targetnode, dl]
def run(self): """ Main directive entry function, called by docutils upon encountering the directive. This directive is meant to be quite easily subclassable, so it delegates to several additional methods. What it does: * find out if called as a domain-specific directive, set self.domain * create a `desc` node to fit all description inside * parse standard options, currently `noindex` * create an index node if needed as self.indexnode * parse all given signatures (as returned by self.get_signatures()) using self.handle_signature(), which should either return a name or raise ValueError * add index entries using self.add_target_and_index() * parse the content and handle doc fields in it """ if ':' in self.name: self.domain, self.objtype = self.name.split(':', 1) else: self.domain, self.objtype = '', self.name self.env = self.state.document.settings.env self.indexnode = addnodes.index(entries=[]) self.length = self.options.get('length', 4) node = addnodes.desc() node.document = self.state.document node['domain'] = self.domain # 'desctype' is a backwards compatible attribute node['objtype'] = node['desctype'] = self.objtype node['noindex'] = noindex = ('noindex' in self.options) self.names = [] signatures = self.get_signatures() for i, sig in enumerate(signatures): # add a signature node for each signature in the current unit # and add a reference target for it signode = addnodes.desc_signature(sig, '') signode['first'] = False node.append(signode) try: # name can also be a tuple, e.g. (classname, objname); # this is strictly domain-specific (i.e. no assumptions may # be made in this base class) name = self.handle_signature(sig, signode) #print name except ValueError: # signature parsing failed signode.clear() signode += addnodes.desc_name(sig, sig) continue # we don't want an index entry here if name not in self.names: self.names.append(name) if not noindex: # only add target and index entry if this is the first # description of the object with this name in this desc block self.add_target_and_index(name, sig, signode) ##################### # options processing ##################### # default try: mydef = self.options['default'] valnode = nodes.inline(mydef, mydef) boldnode = nodes.strong('Default: ', 'Default: ') #defnode = nodes.paragraph() defnode = addnodes.desc_content() defnode += boldnode defnode += valnode node += defnode except KeyError: pass ##################### # content processing ##################### contentnode = addnodes.desc_content() node.append(contentnode) # build node if self.names: # needed for association of version{added,changed} directives self.env.temp_data['object'] = self.names[0] self.before_content() self.state.nested_parse(self.content, self.content_offset, contentnode) DocFieldTransformer(self).transform_all(contentnode) self.env.temp_data['object'] = None self.after_content() return [self.indexnode, node]
def doctree_resolved(app, doctree, docname): # replace numfig nodes with links if app.builder.name in ('html', 'singlehtml', 'epub'): env = app.builder.env docname_figs = getattr(env, 'docname_figs', {}) docnames_by_figname = env.docnames_by_figname figids = getattr(env, 'figids', {}) secnums = [] fignames_by_secnum = {} for figdocname, figurelist in env.docname_figs.iteritems(): if figdocname not in env.toc_secnumbers: continue secnum = env.toc_secnumbers[figdocname][''] secnums.append(secnum) fignames_by_secnum[secnum] = figurelist last_secnum = 0 secnums = sorted(secnums) figid = 1 for secnum in secnums: if secnum[0] != last_secnum: figid = 1 for figname, subfigs in fignames_by_secnum[secnum].iteritems(): figids[figname] = str(secnum[0]) + '.' + str(figid) for i, subfigname in enumerate(subfigs): subfigid = figids[figname] + chr(ord('a') + i) figids[subfigname] = subfigid figid += 1 last_secnum = secnum[0] env.figids = figids for figure_info in doctree.traverse(lambda n: isinstance(n, nodes.figure) or \ isinstance(n, subfig.subfigend) or \ isinstance(n, figtable.figtable)): id = figure_info['ids'][0] fignum = figids[id] for cap in figure_info.traverse(nodes.caption): cap.insert(1, nodes.Text(" %s" % cap[0])) if fignum[-1] in map(str, range(10)): boldcaption = "%s %s:" % (app.config.figure_caption_prefix, fignum) else: boldcaption = "(%s)" % fignum[-1] cap[0] = nodes.strong('', boldcaption) for ref_info in doctree.traverse(num_ref): if '#' in ref_info['reftarget']: label, target = ref_info['reftarget'].split('#') labelfmt = label + " %s" else: labelfmt = '%s' target = ref_info['reftarget'] if target not in docnames_by_figname: app.warn('Target figure not found: %s' % target) link = "#%s" % target linktext = target else: target_doc = docnames_by_figname[target] if app.builder.name == 'singlehtml': link = "#%s" % target else: link = "%s#%s" % (app.builder.get_relative_uri( docname, target_doc), target) linktext = labelfmt % figids[target] html = '<a href="%s">%s</a>' % (link, linktext) ref_info.replace_self(nodes.raw(html, html, format='html'))
def run(self): secid = [self.arguments[0].lower().replace(' ', '-')] section = nodes.section(ids=secid) section.document = self.state.document section += nodes.title(text=self.arguments[0]) # parse the 'text' option into the section, as a paragraph. self.state.nested_parse( StringList([self.options['text']], parent=self), 0, section) node = self.create_progtable() section.children[-1] += node head = node.children[0].children[-2].children[0] body = node.children[0].children[-1] comps = collections.OrderedDict() cur = "" for line in self.content: # new list nl = re.match(r'^:(?P<component>.+):$', line) if nl is not None: if cur != "": # finish up shrow self.add_progbar(shrow, len([c for c in comps[cur] if c is True]), len(comps[cur])) cur = nl.groupdict()['component'] if cur not in comps: comps[cur] = [] # shrow is the section header row shrow = self.create_headrow(cur, classes=['field-name']) body += shrow continue nl = re.match( r'^\s+- (?P<item>[^,]+),\s+(?P<value>(True|False))(, (?P<description>.+)$)?', line) if nl is not None: nl = nl.groupdict() comps[cur].append(True if nl['value'] == "True" else False) tr = nodes.row() tr += nodes.description( '', nodes.inline(text="\u2713" if comps[cur][-1] else " "), classes=['field-name', 'progress-checkbox']) text_description = nodes.inline() self.state.nested_parse( StringList([ '{:s}'.format(nl['description'].lstrip( ) if nl['description'] is not None else ' ') ], parent=self), 0, text_description) tr += nodes.description( '', nodes.strong(text='{:s} '.format(nl['item'])), text_description, classes=['field-value']) body += tr if self.content: # finish up the final hrow self.add_progbar(shrow, len([c for c in comps[cur] if c == True]), len(comps[cur])) # and fill in the end of mrow self.add_progbar( head, len([c for r in comps.values() for c in r if c == True]), len([c for r in comps.values() for c in r])) return [section]
def functional_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): return [nodes.strong(text='from function: %s' % options['opt'])]
def build_links_table(self, resource): is_list = 'is-list' in self.options table = nodes.table() tgroup = nodes.tgroup(cols=3) table += tgroup tgroup += nodes.colspec(colwidth=25) tgroup += nodes.colspec(colwidth=15) tgroup += nodes.colspec(colwidth=60) thead = nodes.thead() tgroup += thead append_row(thead, ['Name', 'Method', 'Resource']) tbody = nodes.tbody() tgroup += tbody request = DummyRequest() if is_list: child_resources = resource.list_child_resources else: child_resources = resource.item_child_resources names_to_resource = {} for child in child_resources: names_to_resource[child.name_plural] = (child, True) if not is_list and resource.model: child_keys = {} create_fake_resource_path(request, resource, child_keys, True) obj = resource.get_queryset(request, **child_keys)[0] else: obj = None related_links = resource.get_related_links(request=request, obj=obj) for key, info in related_links.iteritems(): names_to_resource[key] = \ (info['resource'], info.get('list-resource', False)) links = resource.get_links(child_resources, request=DummyRequest(), obj=obj) for linkname in sorted(links.iterkeys()): info = links[linkname] child, is_child_link = \ names_to_resource.get(linkname, (resource, is_list)) paragraph = nodes.paragraph() paragraph += get_ref_to_resource(child, is_child_link) append_row( tbody, [nodes.strong(text=linkname), info['method'], paragraph]) return table
def _render_service(self, service): service_id = "service-%d" % self.env.new_serialno('service') service_node = nodes.section(ids=[service_id]) title = '%s service at %s' % (service.name.title(), service.path) service_node += nodes.title(text=title) if service.description is not None: service_node += rst2node(trim(service.description)) for method, view, args in service.definitions: if method == 'HEAD': # Skip head - this is essentially duplicating the get docs. continue method_id = '%s-%s' % (service_id, method) method_node = nodes.section(ids=[method_id]) method_node += nodes.title(text=method) if is_string(view): if 'klass' in args: ob = args['klass'] view_ = getattr(ob, view.lower()) docstring = trim(view_.__doc__ or "") + '\n' else: docstring = trim(view.__doc__ or "") + '\n' if 'schema' in args: schema = args['schema'] attrs_node = nodes.inline() for location in ('header', 'querystring', 'body'): attributes = schema.get_attributes(location=location) if attributes: attrs_node += nodes.inline(text='values in the %s' % location) location_attrs = nodes.bullet_list() for attr in attributes: temp = nodes.list_item() # Get attribute data-type if hasattr(attr, 'type'): attr_type = attr.type elif hasattr(attr, 'typ'): attr_type = attr.typ.__class__.__name__ else: attr_type = None temp += nodes.strong(text=attr.name) if attr_type is not None: temp += nodes.inline(text=' (%s)' % attr_type) if not attr.required or attr.description: temp += nodes.inline(text=' - ') if not attr.required: if attr.missing is not None: default = json.dumps(attr.missing) temp += nodes.inline( text='(default: %s) ' % default) else: temp += nodes.inline( text='(optional) ') if attr.description: temp += nodes.inline(text=attr.description) location_attrs += temp attrs_node += location_attrs method_node += attrs_node for validator in args.get('validators', ()): if validator.__doc__ is not None: docstring += trim(validator.__doc__) if 'accept' in args: accept = to_list(args['accept']) if callable(accept): if accept.__doc__ is not None: docstring += accept.__doc__.strip() else: accept_node = nodes.strong(text='Accepted content types:') node_accept_list = nodes.bullet_list() accept_node += node_accept_list for item in accept: temp = nodes.list_item() temp += nodes.inline(text=item) node_accept_list += temp method_node += accept_node node = rst2node(docstring) DocFieldTransformer(self).transform_all(node) if node is not None: method_node += node renderer = args['renderer'] if renderer == 'simplejson': renderer = 'json' response = nodes.paragraph() response += nodes.strong(text='Response: %s' % renderer) method_node += response service_node += method_node return service_node
def strong(inlines): strong_node = nodes.strong() append_inlines(strong_node, inlines) return strong_node
def visit_strong(self, node): return nodes.strong()
def render_strong(self, token: SyntaxTreeNode) -> None: node = nodes.strong() self.add_line_and_source_path(node, token) with self.current_node_context(node, append=True): self.render_children(token)
def render_strong_open(self, token: NestedTokens): node = nodes.strong() self.add_line_and_source_path(node, token) with self.current_node_context(node, append=True): self.render_children(token)
def indexmarkup_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): # type: (unicode, unicode, unicode, int, Inliner, Dict, List[unicode]) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA """Role for PEP/RFC references that generate an index entry.""" env = inliner.document.settings.env if not typ: assert env.temp_data['default_role'] typ = env.temp_data['default_role'].lower() else: typ = typ.lower() has_explicit_title, title, target = split_explicit_title(text) title = utils.unescape(title) target = utils.unescape(target) targetid = 'index-%s' % env.new_serialno('index') indexnode = addnodes.index() targetnode = nodes.target('', '', ids=[targetid]) inliner.document.note_explicit_target(targetnode) if typ == 'pep': indexnode['entries'] = [ ('single', _('Python Enhancement Proposals; PEP %s') % target, targetid, '', None) ] anchor = '' # type: unicode anchorindex = target.find('#') if anchorindex > 0: target, anchor = target[:anchorindex], target[anchorindex:] if not has_explicit_title: title = "PEP " + utils.unescape(title) try: pepnum = int(target) except ValueError: msg = inliner.reporter.error('invalid PEP number %s' % target, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] ref = inliner.document.settings.pep_base_url + 'pep-%04d' % pepnum sn = nodes.strong(title, title) rn = nodes.reference('', '', internal=False, refuri=ref + anchor, classes=[typ]) rn += sn return [indexnode, targetnode, rn], [] elif typ == 'rfc': indexnode['entries'] = [('single', 'RFC; RFC %s' % target, targetid, '', None)] anchor = '' anchorindex = target.find('#') if anchorindex > 0: target, anchor = target[:anchorindex], target[anchorindex:] if not has_explicit_title: title = "RFC " + utils.unescape(title) try: rfcnum = int(target) except ValueError: msg = inliner.reporter.error('invalid RFC number %s' % target, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] ref = inliner.document.settings.rfc_base_url + inliner.rfc_url % rfcnum sn = nodes.strong(title, title) rn = nodes.reference('', '', internal=False, refuri=ref + anchor, classes=[typ]) rn += sn return [indexnode, targetnode, rn], [] else: raise ValueError('unknown role type: %s' % typ)
def run(self): # Tests don't have to have contents now, so check for it but don't assert: self.document = self.state_machine.document text = [] if self.content: text = '\n'.join(self.content) # Create the admonition node, to be populated by `nested_parse`. self.name = self.arguments[0] if 'test_time' in self.options: self.test_time = self.options['test_time'] # test_procedure name #if 'test_procedure' in self.options: if 'test_procedure' in self.options: self.test_procedure = self.options['test_procedure'] else: self.assert_has_content() proc = TestProcedure(self.name + "_procedure") self.test_procedure = proc.name if 'setup' in self.options: proc.setup = self.options['setup'] else: proc.setup = "" proc.content = self.content self.parsed('test_procedure').append(proc) term = nodes.term() term += nodes.strong(text=self.arguments[0]) targetnode = self.make_targetnode() deflist = nodes.definition_list() test_def = nodes.definition_list_item() test_def += term defn = nodes.definition() test_def += defn deflist += test_def if 'parameters' in self.options: params = self.parse_parameters() defn += nodes.paragraph(text="Parameters:") for param in params: name = param['param'] field_list = nodes.field_list() param_field = nodes.field() param_field_name = nodes.field_name() param_field_name += nodes.Text(name) param_field += param_field_name param_field_body = nodes.field_body() choices_str = param['choices_str'] if (len(choices_str) < 50): param_field_body += nodes.paragraph(text=choices_str) else: choices = param['choices'] param_field_body += nodes.raw('', ' \\ \n\n', format="latex") for choice in choices: param_field_body += nodes.paragraph(text=choice) param_field += param_field_body field_list += param_field name = self.arguments[0].strip() + "param" + name param_target = nodes.target('', '', ids=[nodes.make_id(name)]) name = nodes.fully_normalize_name(name) param_target['names'].append(name) self.state_machine.document.note_explicit_target( param_target, param_target) defn += param_target defn += field_list # Parse the directive contents. self.state.nested_parse(self.content, self.content_offset, defn) option_map = {} option_map['configurations'] = 'Valid configurations' option_map['setup'] = 'Required setup' option_map['test_time'] = 'Test time (min)' option_map['priority'] = 'Priority' option_map['test_procedure'] = 'Test procedure' field_list = self.options_to_field_list(option_map) if (field_list != None): defn += field_list self.parsed('test').append(self) return [targetnode, deflist]
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 = 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 = 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): # Content is optional, so don't raise an error if it's missing... # print self.state_machine.document.current_source self.document = self.state_machine.document self.is_config_option = False text = '\n'.join(self.content) # Create the admonition node, to be populated by `nested_parse`. self.name = self.arguments[0].strip() title = self.arguments[0] if 'parent' in self.options: title += " (" + self.options['parent'] + ")" term = nodes.term() n = nodes.strong(text=title) term += n targetnode = self.make_targetnode() deflist = nodes.definition_list() feature_def = nodes.definition_list_item() feature_def += term defn = nodes.definition() feature_def += defn deflist += feature_def # Parse the directive contents. self.state.nested_parse(self.content, self.content_offset, defn) option_map = {} option_map['parents'] = 'Parent features' option_map['config_options'] = 'Options' field_list = self.options_to_field_list(option_map) if 'parents' in self.options: self.parents = [] for p in self.options['parents'].split(","): found = False for f in self.parsed('feature'): if p.strip() == f.name: found = True if not found: sys.stderr.write("ERROR: Feature `" + self.name + "' refers to unknown parent `" + p.strip() + "'") if self.check_errors(): exit(1) for p in self.options['parents'].split(","): self.parents.extend( [f for f in self.parsed('feature') if p.strip() == f.name]) ancestors = set(self.parents) for p in self.parents: ancestors = ancestors | set(p.ancestors) self.ancestors = list(ancestors) else: self.parents = [] self.ancestors = [] self.summarize = ('summarize' in self.options) if 'config_options' in self.options: self.choices = [] found_default = False optstr = self.options['config_options'].strip() p = re.compile("(.*), *default *= *(.*)") m = p.match(optstr) if m: optstr = m.groups(0)[0] default = m.groups(0)[1] else: default = None p = re.compile("(.*)\.\.(.*)") m = p.match(optstr) if m: lb = int(m.groups(0)[0]) ub = int(m.groups(0)[1]) name = self.name + "__RANGE" choice = Feature(name) choice.summarize = ('summarize_options' in self.options) self.choices.append(choice) self.parsed('feature').append(choice) choice.is_range = True choice.is_config_option = True choice.is_default = False choice.parents = [self] choice.ancestors = [self] choice.ancestors.extend(self.ancestors) else: for o in self.options['config_options'].split('|'): p = re.compile("(.*) \(default\)") is_default = False name = o.strip() if (p.match(name)): name = p.match(name).groups(0)[0] name = name.strip() is_default = True found_default = True if (name == default): is_default = True found_default = True name = self.name + "_" + name choice = Feature(name) choice.is_range = False choice.is_default = is_default choice.summarize = ('summarize_options' in self.options) self.choices.append(choice) self.parsed('feature').append(choice) choice.is_config_option = True choice.parents = [self] choice.ancestors = [self] choice.ancestors.extend(self.ancestors) if not found_default: self.choices[0].is_default = True else: self.choices = [] if (field_list != None): defn += field_list self.parsed('feature').append(self) return [targetnode, deflist]
def _render_service(self, path, service, methods): env = self.state.document.settings.env service_id = "service-%d" % env.new_serialno('service') service_node = nodes.section(ids=[service_id]) service_node += nodes.title(text='Service at %s' % service.route_name) if service.description is not None: service_node += rst2node(trim(service.description)) for method, info in methods.items(): method_id = '%s-%s' % (service_id, method) method_node = nodes.section(ids=[method_id]) method_node += nodes.title(text=method) if 'attr' in info: docstring = getattr(info['func'], info['attr']).__doc__ or "" else: docstring = info['func'].__doc__ or "" docstring = trim(docstring) + '\n' if method in service.schemas: schema = service.schemas[method] attrs_node = nodes.inline() for location in ('headers', 'querystring', 'body'): attributes = schema.get_attributes(location=location) if attributes: attrs_node += nodes.inline(text='values in the %s' % location) location_attrs = nodes.bullet_list() for attr in attributes: temp = nodes.list_item() desc = "%s : " % attr.name if hasattr(attr, 'type'): desc += " %s, " % attr.type if attr.required: desc += "required " else: desc += "optional " temp += nodes.inline(text=desc) location_attrs += temp attrs_node += location_attrs method_node += attrs_node if 'validators' in info: for validator in info['validators']: if validator.__doc__ is not None: if docstring is not None: doc = trim(validator.__doc__) docstring += '\n' + doc if 'accept' in info: accept = info['accept'] if callable(accept): if accept.__doc__ is not None: docstring += accept.__doc__.strip() else: accept = to_list(accept) accept_node = nodes.strong(text='Accepted content types:') node_accept_list = nodes.bullet_list() accept_node += node_accept_list for item in accept: temp = nodes.list_item() temp += nodes.inline(text=item) node_accept_list += temp method_node += accept_node node = rst2node(docstring) DocFieldTransformer(self).transform_all(node) if node is not None: method_node += node renderer = info['renderer'] if renderer == 'simplejson': renderer = 'json' response = nodes.paragraph() response += nodes.strong(text='Response: %s' % renderer) method_node += response service_node += method_node return service_node
def visit_strong(self, _): n = nodes.strong() self.current_node.append(n) self.current_node = n
def indexmarkup_role(typ, rawtext, etext, lineno, inliner, options={}, content=[]): env = inliner.document.settings.env text = utils.unescape(etext) targetid = 'index-%s' % env.index_num env.index_num += 1 indexnode = addnodes.index() targetnode = nodes.target('', '', ids=[targetid]) inliner.document.note_explicit_target(targetnode) if typ == 'envvar': env.note_index_entry('single', text, targetid, text) env.note_index_entry('single', 'environment variable; %s' % text, targetid, text) indexnode['entries'] = [('single', text, targetid, text), ('single', 'environment variable; %s' % text, targetid, text)] xref_nodes = xfileref_role(typ, rawtext, etext, lineno, inliner, options, content)[0] return [indexnode, targetnode] + xref_nodes, [] elif typ == 'pep': env.note_index_entry('single', 'Python Enhancement Proposals!PEP %s' % text, targetid, 'PEP %s' % text) indexnode['entries'] = [ ('single', 'Python Enhancement Proposals!PEP %s' % text, targetid, 'PEP %s' % text) ] try: pepnum = int(text) except ValueError: msg = inliner.reporter.error('invalid PEP number %s' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] ref = inliner.document.settings.pep_base_url + 'pep-%04d' % pepnum sn = nodes.strong('PEP ' + text, 'PEP ' + text) rn = nodes.reference('', '', refuri=ref) rn += sn return [indexnode, targetnode, rn], [] elif typ == 'rfc': env.note_index_entry('single', 'RFC; RFC %s' % text, targetid, 'RFC %s' % text) indexnode['entries'] = [('single', 'RFC; RFC %s' % text, targetid, 'RFC %s' % text)] try: rfcnum = int(text) except ValueError: msg = inliner.reporter.error('invalid RFC number %s' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] ref = inliner.document.settings.rfc_base_url + inliner.rfc_url % rfcnum sn = nodes.strong('RFC ' + text, 'RFC ' + text) rn = nodes.reference('', '', refuri=ref) rn += sn return [indexnode, targetnode, rn], []
def build_fields_table(self, fields, required_fields={}, show_requirement_labels=False): def get_type_name(field_type): # We may be dealing with a forward-declared class. if isinstance(field_type, basestring) and field_type is not str: field_type = self.get_resource_class(field_type) if type(field_type) is list: return [nodes.inline(text='List of ')] + \ get_type_name(field_type[0]) elif type(field_type) is tuple: value_nodes = [] for value in field_type: if value_nodes: value_nodes.append(nodes.inline(text=', ')) value_nodes.append(nodes.literal(text=value)) return [nodes.inline(text='One of ')] + value_nodes elif (inspect.isclass(field_type) and issubclass(field_type, WebAPIResource)): return [get_ref_to_resource(field_type, False)] elif field_type in self.type_mapping: return [nodes.inline(text=self.type_mapping[field_type])] else: print "Unknown type %s" % (field_type, ) assert False table = nodes.table(classes=['resource-fields']) tgroup = nodes.tgroup(cols=3) table += tgroup tgroup += nodes.colspec(colwidth=25, classes=['field']) tgroup += nodes.colspec(colwidth=15, classes=['type']) tgroup += nodes.colspec(colwidth=60, classes=['description']) thead = nodes.thead() tgroup += thead append_row(thead, ['Field', 'Type', 'Description']) tbody = nodes.tbody() tgroup += tbody if isinstance(fields, dict): for field in sorted(fields.iterkeys()): info = fields[field] name_node = nodes.inline() name_node += nodes.strong(text=field) if show_requirement_labels: if field in required_fields: name_node += nodes.inline(text=" (required)") else: name_node += nodes.inline(text=" (optional)") type_node = nodes.inline() type_node += get_type_name(info['type']) append_row(tbody, [ name_node, type_node, parse_text(self, info['description'], where='%s field description' % field) ]) else: for field in sorted(fields): name = field if show_requirement_labels: if field in required_fields: name += " (required)" else: name += " (optional)" append_row(tbody, [name, "", ""]) return table
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
def _build_backend_detail_table(self, backend, matrix): table = nodes.table() table.set_class("table") table.set_class("table-condensed") tgroup = nodes.tgroup(cols=2) tbody = nodes.tbody() for i in range(2): tgroup.append(nodes.colspec(colwidth=1)) tgroup.append(tbody) table.append(tgroup) graderow = nodes.row() gradetitle = nodes.entry() gradetitle.append(nodes.strong(text="Grade")) gradetext = nodes.entry() class_name = "label-%s" % matrix.grade_classes[backend.status] status_text = nodes.paragraph(text=matrix.grade_names[backend.status]) status_text.set_class(class_name) status_text.set_class("label") gradetext.append(status_text) graderow.append(gradetitle) graderow.append(gradetext) tbody.append(graderow) treerow = nodes.row() treetitle = nodes.entry() treetitle.append(nodes.strong(text="In Tree")) if bool(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") status = u"\u2714" treetext = nodes.entry() treetext.append(intree) treerow.append(treetitle) treerow.append(treetext) tbody.append(treerow) maintrow = nodes.row() mainttitle = nodes.entry() mainttitle.append(nodes.strong(text="Maintainers")) mainttext = nodes.entry() mainttext.append(nodes.paragraph(text=backend.maintainers)) maintrow.append(mainttitle) maintrow.append(mainttext) tbody.append(maintrow) reporow = nodes.row() repotitle = nodes.entry() repotitle.append(nodes.strong(text="Repository")) repotext = nodes.entry() repotext.append(nodes.paragraph(text=backend.repository)) reporow.append(repotitle) reporow.append(repotext) tbody.append(reporow) noterow = nodes.row() notetitle = nodes.entry() notetitle.append(nodes.strong(text="Notes")) notetext = nodes.entry() notetext.append(nodes.paragraph(text=backend.notes)) noterow.append(notetitle) noterow.append(notetext) tbody.append(noterow) return table