def literal(node): """ Inline code """ rendered = [] try: if node.info is not None: l = Lexer(node.literal, node.info, tokennames="long") for _ in l: rendered.append(node.inline(classes=_[0], text=_[1])) except: pass classes = ['code'] if node.info is not None: classes.append(node.info) if len(rendered) > 0: o = nodes.literal(classes=classes) for element in rendered: o += element else: o = nodes.literal(text=node.literal, classes=classes) for n in MarkDown(node): o += n return o
def run(self): if ValueTableDirective.values[0].description is None: list = nodes.bullet_list() for v in ValueTableDirective.values: item = nodes.list_item() item += nodes.literal(v.value, v.value) list += item return [list] table = nodes.table() tgroup = nodes.tgroup() tbody = nodes.tbody() for v in ValueTableDirective.values: row = nodes.row() entry = nodes.entry() entry += nodes.literal(v.value, v.value) row += entry entry = nodes.entry() entry += nodes.paragraph(text=v.description) row += entry tbody += row tgroup += nodes.colspec(colwidth=10) tgroup += nodes.colspec(colwidth=90) tgroup += tbody table += tgroup return [table]
def xapian_class_role(typ, rawtext, etext, lineno, inliner, options=(), content=[]): c = utils.unescape(etext) if highlight_language == 'c++': return [nodes.literal(text = 'Xapian::' + c)], [] elif highlight_language == 'csharp': return [nodes.literal(text = 'Xapian.' + c)], [] elif highlight_language == 'java': return [nodes.literal(text = 'org.xapian.' + c)], [] elif highlight_language == 'lua': return [nodes.literal(text = 'xapian.' + c)], [] elif highlight_language == 'perl': return [nodes.literal(text = 'Search::Xapian::' + c)], [] elif highlight_language == 'php': return [nodes.literal(text = 'Xapian' + c)], [] elif highlight_language == 'python': return [nodes.literal(text = 'xapian.' + c)], [] elif highlight_language == 'python3': return [nodes.literal(text = 'xapian.' + c)], [] elif highlight_language == 'ruby': return [nodes.literal(text = 'Xapian::' + c)], [] elif highlight_language == 'tcl': return [nodes.literal(text = 'xapian::' + c)], [] else: print "Unhandled highlight_language '%s'" % highlight_language sys.exit(1)
def inline_roles(role, raw, text, *args): if role == 'kbd': return [nodes.literal('kbd', text)], [] elif role == 'var': return [nodes.literal('var', text)], [] elif role == 'abbr': return [nodes.literal('abbr', text)], []
def code(role, rawtext, text, lineno, inliner, options={}, content=[]): # In order to properly preserve backslashes i = rawtext.find('`') text = rawtext.split('`')[1] set_classes(options) classes = [] if 'classes' in options: classes += options['classes'] del options['classes'] # If language is not specified, render a simple literal if not 'language' in options: content = nodes.raw('', utils.unescape(text), format='html') node = nodes.literal(rawtext, '', **options) node.append(content) return [node], [] language = options['language'] del options['language'] # Not sure why language is duplicated in classes? if language in classes: classes.remove(language) class_, highlighted = _highlight(utils.unescape(text), language, options, is_block=False) classes += [class_] content = nodes.raw('', highlighted, format='html') node = nodes.literal(rawtext, '', classes=classes, **options) node.append(content) return [node], []
def missing_reference_handler(app, env, node, contnode): if not hasattr(env, 'class_name_mapping'): env.class_name_mapping = {} mapping = env.class_name_mapping reftype = node['reftype'] reftarget = node['reftarget'] if reftype in ('obj', 'class', 'exc', 'meth'): reftarget = node['reftarget'] suffix = '' if reftarget not in mapping: if '.' in reftarget: front, suffix = reftarget.rsplit('.', 1) else: suffix = reftarget if suffix.startswith('_') and not suffix.startswith('__'): # If this is a reference to a hidden class or method, # we can't link to it, but we don't want to have a # nitpick warning. return node[0].deepcopy() if reftype in ('obj', 'meth') and '.' in reftarget: if front in mapping: reftarget = front suffix = '.' + suffix if (reftype in ('class', ) and '.' in reftarget and reftarget not in mapping): if '.' in front: reftarget, _ = front.rsplit('.', 1) suffix = '.' + suffix reftarget = reftarget + suffix prefix = reftarget.rsplit('.')[0] inventory = env.intersphinx_named_inventory if (reftarget not in mapping and prefix in inventory): if reftarget in inventory[prefix]['py:class']: newtarget = inventory[prefix]['py:class'][reftarget][2] if not node['refexplicit'] and \ '~' not in node.rawsource: contnode = literal(text=reftarget) newnode = reference('', '', internal=True) newnode['reftitle'] = reftarget newnode['refuri'] = newtarget newnode.append(contnode) return newnode if reftarget in mapping: newtarget = mapping[reftarget] + suffix if not node['refexplicit'] and '~' not in node.rawsource: contnode = literal(text=newtarget) newnode = env.domains['py'].resolve_xref( env, node['refdoc'], app.builder, 'class', newtarget, node, contnode) if newnode is not None: newnode['reftitle'] = reftarget return newnode
def xapian_variable_role(typ, rawtext, etext, lineno, inliner, options=(), content=[]): m = utils.unescape(etext) if highlight_language in ('perl', 'php', 'ruby'): return [nodes.literal(text = '$' + m)], [] # Correct for: c++ csharp java lua python python3 # FIXME: I think tcl is going to need cleverer handling return [nodes.literal(text = m)], []
def get_value_list(vals): rv = nodes.paragraph() if vals: rv.append(nodes.literal(vals[0], vals[0])) for i in range(1, len(vals)): rv.append(text(" | ")) rv.append(nodes.literal(vals[i], vals[i])) return rv
def get_attrs(self, el, context=None): cnode = el while context is None and cnode is not None: context = cnode.get('name') cnode = cnode.getparent() rows = [] for attr in el.xpath("xs:attribute[@name]", namespaces=NSMAP): name = attr.get("name") if self.ns_name: fqname = "%s:%s" % (self.ns_name, name) else: fqname = name if (self.options['onlyattrs'] and name not in self.options['onlyattrs'] and fqname not in self.options['onlyattrs']): continue tag = attr.tag[len(XS_NS):] row = [build_paragraph(self.target_node(tag, self.ns_name, context, name), nodes.literal(fqname, fqname))] row.append(self.get_doc(attr)) if attr.get("type") is not None: row.append(build_paragraph( self.get_values_from_type(entity=attr))) else: try: atype = attr.xpath("xs:simpleType", namespaces=NSMAP)[0] row.append(self.get_values_from_simpletype(atype)) except IndexError: # todo: warn about no type found pass reqd = 0 if (name in self.options['requiredattrs'] or attr.get("use", "optional") == "required"): row.append("Yes") reqd = 1 else: row.append("No") default = attr.get("default") if default is None: row.append("None") else: row.append(nodes.literal(default, default)) # we record name and required separately to make sorting # easier rows.append((name, reqd, build_table_row(*row))) rows.sort(key=operator.itemgetter(0)) rows.sort(key=operator.itemgetter(1), reverse=True) if not self.options['onlyattrs'] or '*' in self.options['onlyattrs']: try: anyattr = el.xpath("xs:anyAttribute", namespaces=NSMAP)[0] rows.append((None, None, build_table_row('*', self.get_doc(anyattr), "Any", "No", "None"))) except IndexError: pass return [r[2] for r in rows]
def epydoc_role(role, rawtext, text, lineno, inliner, options={}, content=[]): """ Actual role callback """ # pylint: disable = too-many-branches match = caption_ref_re.match(text) if match: extra, (text, ref) = True, match.group(1, 2) text = text.strip() if text.startswith('|') and text.endswith('|'): text = text[1:-1] extra = False else: extra, text, ref = False, None, text if ref.endswith('()'): ref = ref[:-2].strip() parens = text is None else: parens = False if '/' in ref: chunks = ref.split('/', 1) if not chunks[0]: # Main page uri = 'index.html' else: uri = apis.get(''.join(chunks)) if text is None: text = chunks[1] else: uri = apis.get(ref) if not text: text = ref if parens: text += '()' if uri is None: node = nodes.literal(rawtext, text) else: baseuri = relpath( epydoc, os.path.dirname(inliner.document.current_source) ).split(os.path.sep) for idx, elem in enumerate(baseuri): if elem == os.path.curdir: baseuri[idx] = '.' elif elem == os.path.pardir: baseuri[idx] = '..' baseuri = '/'.join(baseuri) uri = posixpath.join(baseuri, uri) if not extra: text = u'\u2192\xa0' + text # pylint: disable = redefined-variable-type node = nodes.reference(rawtext, text, refuri=uri, **options) if not extra: node = nodes.literal(rawtext, '', node) return [node], []
def xapian_method_role(typ, rawtext, etext, lineno, inliner, options=(), content=[]): cm = utils.unescape(etext) if highlight_language == 'c++': return [nodes.literal(text = 'Xapian::' + cm)], [] elif highlight_language == 'csharp': # FIXME: Need to adjust method names for csharp cm = re.sub(r'::', r'.', cm) return [nodes.literal(text = 'Xapian.' + cm)], [] elif highlight_language == 'java': # FIXME: Need to adjust method names for java cm = re.sub(r'::', r'.', cm) return [nodes.literal(text = 'org.xapian.' + cm)], [] elif highlight_language == 'lua': return [nodes.literal(text = 'xapian.' + cm)], [] elif highlight_language == 'perl': # Add a $ in front of each parameter. cm = decorate_variables(cm) return [nodes.literal(text = 'Search::Xapian::' + cm)], [] elif highlight_language == 'php': # Add a $ in front of each parameter. cm = decorate_variables(cm) return [nodes.literal(text = 'Xapian' + cm)], [] elif highlight_language.startswith('python'): cm = re.sub(r'::', r'.', cm) return [nodes.literal(text = 'xapian.' + cm)], [] elif highlight_language == 'ruby': # FIXME: Need to adjust method names for ruby return [nodes.literal(text = 'Xapian::' + cm)], [] elif highlight_language == 'tcl': return [nodes.literal(text = 'xapian::' + cm)], [] else: print "Unhandled highlight_language '%s'" % highlight_language sys.exit(1)
def epylink_role(role, rawtext, text, lineno, inliner, options={}, content=[]): epyDir = inliner.document.settings.env.app.config.epylink_api_dir if not epyDir: inliner.reporter.error("Configuration value 'epylink_api_dir' " "is not set in conf.py") outDir = inliner.document.settings.env.app.config.epylink_output_dir if not outDir: inliner.reporter.error("Configuration value 'epylink_output_dir' " "is not set in conf.py") sections = text.rsplit(".", 1) if text[0] == "~": text = text[1:] sections[0] = sections[0][1:] name = sections[1] if len(sections) == 2 else text else: name = text found = False url = "%s/%s-module.html" % (epyDir, text) if os.path.isfile(os.path.join(outDir, url)): found = True else: url = "%s/%s-class.html" % (epyDir, text) if os.path.isfile(os.path.join(outDir, url)): found = True else: if len(sections) == 2: for tag in ("class", "module"): url = "%s/%s-%s.html" % (epyDir, sections[0], tag) fullUrl = os.path.join(outDir, url) if os.path.isfile(fullUrl): f = None try: f = open(fullUrl) html = f.read() if "<a name=\"%s\">" % sections[1] in html: url = "%s#%s" % (url, sections[1]) found = True if re.search( "<a href=\"%s\".*summary-sig-name.*</a>(\(" ".*summary-sig-arg|\(\))" % os.path.split(url)[1], html): name += "()" break finally: if f: f.close() if found: node = nodes.reference(rawtext, "", refuri=url, **options) node += nodes.literal(rawtext, name, classes=['xref']) else: inliner.reporter.warning("Target document not found for '%s'" % text, line=lineno) node = nodes.literal(rawtext, name) return [node], []
def xapian_class_role(typ, rawtext, etext, lineno, inliner, options=(), content=[]): c = utils.unescape(etext) if highlight_language == 'python': return [nodes.literal(text = 'xapian.' + c)], [] elif highlight_language == 'php': return [nodes.literal(text = 'Xapian' + c)], [] elif highlight_language == 'c++': return [nodes.literal(text = 'Xapian::' + c)], [] else: print "Unhandled highlight_language" sys.exit(1)
def create_title_node(self, traceable): if traceable.has_title(): title_content = nodes.inline() title_content += nodes.literal(text=traceable.tag) title_content += nodes.inline(text=" -- ") title_content += nodes.inline(text=traceable.title) else: title_content = nodes.literal(text=traceable.tag) title_node = nodes.inline() title_node += title_content return [title_node]
def emph_literal_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): text = utils.unescape(text) retnodes = [] pos = 0 for m in _litvar_re.finditer(text): if m.start() > pos: txt = text[pos:m.start()] retnodes.append(nodes.literal(txt, txt)) retnodes.append(nodes.emphasis('', '', nodes.literal(m.group(1), m.group(1)))) pos = m.end() if pos < len(text): retnodes.append(nodes.literal(text[pos:], text[pos:])) return retnodes, []
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_details_table(self, error_obj): table = nodes.table() tgroup = nodes.tgroup(cols=2) table += tgroup tgroup += nodes.colspec(colwidth=20) tgroup += nodes.colspec(colwidth=80) tbody = nodes.tbody() tgroup += tbody # API Error Code append_detail_row(tbody, 'API Error Code', nodes.literal(text=error_obj.code)) # HTTP Status Code ref = parse_text(self, ':http:`%s`' % error_obj.http_status) append_detail_row(tbody, 'HTTP Status Code', ref) # Error Text append_detail_row(tbody, 'Error Text', nodes.literal(text=error_obj.msg)) if error_obj.headers: if callable(error_obj.headers): headers = error_obj.headers(DummyRequest()) # HTTP Headers if len(headers) == 1: content = nodes.literal(text=headers.keys()[0]) else: content = nodes.bullet_list() for header in headers.iterkeys(): item = nodes.list_item() content += item literal = nodes.literal(text=header) item += literal append_detail_row(tbody, 'HTTP Headers', content) # Description append_detail_row( tbody, 'Description', parse_text(self, '\n'.join(self.content), where='API error %s description' % error_obj.code)) return table
def _build_markup(self, notifications): content = [] cols = ['Notification class', 'Payload class', 'Sample file link'] table = nodes.table() content.append(table) group = nodes.tgroup(cols=len(cols)) table.append(group) head = nodes.thead() group.append(head) for i in range(len(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 in notifications: row = nodes.row() body.append(row) 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) ref = nodes.reference(refuri=self.LINK_PREFIX + self.SAMPLE_ROOT + sample) txt = nodes.inline() col.append(txt) txt.append(ref) ref.append(nodes.literal(text=sample)) return content
def xapian_method_role(typ, rawtext, etext, lineno, inliner, options=(), content=[]): cm = utils.unescape(etext) # Correct for Python, PHP and C++: if highlight_language == 'python': cm = re.sub(r'::', r'.', cm) return [nodes.literal(text = 'xapian.' + cm)], [] elif highlight_language == 'php': return [nodes.literal(text = 'Xapian' + cm)], [] elif highlight_language == 'c++': return [nodes.literal(text = 'Xapian::' + cm)], [] else: print "Unhandled highlight_language" sys.exit(1)
def epydoc_role(role, rawtext, text, lineno, inliner, options={}, content=[]): """ Actual role callback """ match = caption_ref_re.match(text) if match: extra, (text, ref) = True, match.group(1, 2) text = text.strip() if text.startswith("|") and text.endswith("|"): text = text[1:-1] extra = False else: extra, text, ref = False, None, text if ref.endswith("()"): ref = ref[:-2].strip() parens = text is None else: parens = False if "/" in ref: chunks = ref.split("/", 1) if not chunks[0]: # Main page uri = "index.html" else: uri = apis.get("".join(chunks)) if text is None: text = chunks[1] else: uri = apis.get(ref) if not text: text = ref if parens: text += "()" if uri is None: node = nodes.literal(rawtext, text) else: baseuri = relpath(epydoc, os.path.dirname(inliner.document.current_source)).split(os.path.sep) for idx, elem in enumerate(baseuri): if elem == os.path.curdir: baseuri[idx] = "." elif elem == os.path.pardir: baseuri[idx] = ".." baseuri = "/".join(baseuri) uri = posixpath.join(baseuri, uri) if not extra: text = u"\u2192\xa0" + text node = nodes.reference(rawtext, text, refuri=uri, **options) if not extra: node = nodes.literal(rawtext, "", node) return [node], []
def code_role(role, rawtext, text, lineno, inliner, options={}, content=[]): set_classes(options) language = options.get('language', '') classes = ['code'] if 'classes' in options: classes.extend(options['classes']) if language and language not in classes: classes.append(language) try: tokens = Lexer(utils.unescape(text, 1), language, inliner.document.settings.syntax_highlight) except LexerError as error: msg = inliner.reporter.warning(error) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] node = nodes.literal(rawtext, '', classes=classes) # analyze content and add nodes for every token for classes, value in tokens: # print (classes, value) if classes: node += nodes.inline(value, value, classes=classes) else: # insert as Text to decrease the verbosity of the output node += nodes.Text(value, value) return [node], []
def run(self): """Create a type list.""" config = self.state.document.settings.env.config # Group processes by category processes = get_processes(config.autoprocess_process_dir, config.autoprocess_source_base_url) processes.sort(key=itemgetter('type')) processes_by_types = {k: list(g) for k, g in groupby(processes, itemgetter('type'))} listnode = nodes.bullet_list() for typ in sorted(processes_by_types.keys()): par = nodes.paragraph() par += nodes.literal(typ, typ) par += nodes.Text(' - ') processes = sorted(processes_by_types[typ], key=itemgetter('name')) last_process = processes[-1] for process in processes: node = nodes.reference('', process['name'], internal=True) node['refuri'] = config.autoprocess_definitions_uri + '#process-' + process['slug'] node['reftitle'] = process['name'] par += node if process != last_process: par += nodes.Text(', ') listnode += nodes.list_item('', par) return [listnode]
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 trac_changeset_role(name, rawtext, text, lineno, inliner, options={}, content=[]): app = inliner.document.settings.env.app try: base = app.config.trac_url if not base: raise AttributeError except AttributeError: #, err: msg = 'trac_url configuration value is not set (%s)' raise ValueError(msg % str(err)) slash = '/' if base[-1] != '/' else '' unescaped = utils.unescape(text) prefix = 'changeset ' node = nodes.literal(prefix, prefix) # Hard-coded for NetworkX if unescaped.endswith('networkx-svn-archive'): # Use the integer display = unescaped.split('/')[0] else: # hg: use the first 12 hash characters display = unescaped[:12] uri = base + slash + 'changeset/' + text node += nodes.reference(rawtext, display, refuri=uri, **options) return [node], []
def insert_callback(parameters_node): # We need to know what params are here already parameter_names = get_parameter_names(parameters_node) if 'callback' not in parameter_names: if '*args' in parameter_names: args_pos = parameter_names.index('*args') else: args_pos = len(parameter_names) if '**kwargs' in parameter_names: kwargs_pos = parameter_names.index('**kwargs') else: kwargs_pos = len(parameter_names) doc = ( " (optional): function taking (result, error), executed when" " operation completes") new_item = list_item( '', paragraph( '', '', literal('', 'callback'), # literal(text='callback'), Text(doc))) # Insert "callback" before *args and **kwargs parameters_node.insert(min(args_pos, kwargs_pos), new_item)
def resolve_api_name(n, rawtext, text, lineno, inliner, options={}, content=[]): if docutils is None: raise AssertionError('requires docutils') # Check if there's separate text & targets m = _TARGET_RE.match(text) if m: text, target = m.groups() else: target = text # node in monotype font text = utils.unescape(text) node = nodes.literal(rawtext, text, **options) # Get the resolver from the register and create an url from it. try: url = api_register[name].get_url(target) except IndexError as exc: msg = inliner.reporter.warning(str(exc), line=lineno) if problematic: prb = inliner.problematic(rawtext, text, msg) return [prb], [msg] else: return [node], [] if url is not None: node = nodes.reference(rawtext, '', node, refuri=url, **options) return [node], []
def handle_signature(self, sig, signode): m = sig.split() name = m[0] args = m[1:] if len(m) > 1 else [] for a in args: if a.startswith("t:"): signode += addnodes.literal_emphasis("", a[2:]) elif a.startswith("a:"): signode += addnodes.literal_emphasis("", a[2:]) elif a.startswith("op:"): signode += nodes.literal("", a[3:]) elif a.startswith("x:"): signode += nodes.emphasis("", a[2:].replace("-", " ")) elif a == "<sp>": signode += nodes.inline("", " ") else: signode += nodes.inline("", a) return name
def run(self): env = self.state.document.settings.env # Default language language = self.options.get('language') # Build the file text cwd = self.options.get('cwd', self.default_cwd) # Get the filename, possibly from first line of contents fname_raw, content = self.get_filename() file_content = u'\n'.join(content) + '\n' # Write the file if not fname_raw.startswith('/'): if cwd == '/': fname_sphinx = cwd + fname_raw else: fname_sphinx = cwd + '/' + fname_raw else: fname_sphinx = fname_raw _, fname = env.relfn2path(fname_sphinx) with open(fname, 'wt') as fobj: fobj.write(file_content) if 'hide' in self.options: return [nodes.comment(file_content, file_content)] literal = nodes.literal_block(file_content, file_content) literal['language'] = (self.options['highlighter'] if 'highlighter' in self.options else 'none' if language is None else language) literal['linenos'] = 'linenos' in self.options para = FileContents() para += nodes.emphasis(text='Contents of ') para += nodes.literal(text=fname_raw) para += literal return [para]
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
def process_see_nodes(app, doctree, fromdocname): for node in doctree.traverse(see): content = [] para = nodes.paragraph() para += nodes.Text("See also:", "See also:") for name in node.refs: join_str = " " if name != node.refs[0]: join_str = ", " link_txt = join_str + name; if name not in app.env.domaindata['bro']['idtypes']: # Just create the text and issue warning app.env.warn(fromdocname, 'unknown target for ".. bro:see:: %s"' % (name)) para += nodes.Text(link_txt, link_txt) else: # Create a reference typ = app.env.domaindata['bro']['idtypes'][name] todocname = app.env.domaindata['bro']['objects'][(typ, name)] newnode = nodes.reference('', '') innernode = nodes.literal(_(name), _(name)) newnode['refdocname'] = todocname newnode['refuri'] = app.builder.get_relative_uri( fromdocname, todocname) newnode['refuri'] += '#' + typ + '-' + name newnode.append(innernode) para += nodes.Text(join_str, join_str) para += newnode content.append(para) node.replace_self(content)
def _nodes_for_ifcond(self, ifcond, with_if=True): """Return list of Text, literal nodes for the ifcond Return a list which gives text like ' (If: condition)'. If with_if is False, we don't return the "(If: " and ")". """ doc = ifcond.docgen() if not doc: return [] doc = nodes.literal('', doc) if not with_if: return [doc] nodelist = [nodes.Text(' ('), nodes.strong('', 'If: ')] nodelist.append(doc) nodelist.append(nodes.Text(')')) return nodelist
def run(self, **kwargs: Any) -> None: matcher = NodeMatcher(nodes.literal, classes=["kbd"]) for node in self.document.traverse(matcher): # type: nodes.literal parts = self.pattern.split(node[-1].astext()) if len(parts) == 1: continue node.pop() while parts: key = parts.pop(0) node += nodes.literal('', key, classes=["kbd"]) try: # key separator (ex. -, +, ^) sep = parts.pop(0) node += nodes.Text(sep) except IndexError: pass
def trac_ticket_role(name, rawtext, text, lineno, inliner, options={}, content=[]): app = inliner.document.settings.env.app try: base = app.config.trac_url if not base: raise AttributeError except AttributeError as err: msg = 'trac_url configuration value is not set (%s)' raise ValueError(msg % str(err)) slash = '/' if base[-1] != '/' else '' prefix = 'ticket ' node = nodes.literal(prefix, prefix) display = utils.unescape(text) uri = base + slash + 'ticket/' + text node += nodes.reference(rawtext, display, refuri=uri, **options) return [node], []
def python_supported_versions_role(typ, rawtext, text, lineno, inliner, options=None, content=None): """Up to date supported python versions for each build image.""" image = '{}:{}'.format(settings.DOCKER_DEFAULT_IMAGE, text) image_settings = settings.DOCKER_IMAGE_SETTINGS[image] python_versions = image_settings['python']['supported_versions'] node_list = [] separator = ', ' for i, version in enumerate(python_versions): node_list.append(nodes.literal(version, version)) if i < len(python_versions) - 1: node_list.append(nodes.Text(separator)) return (node_list, [])
def token_xrefs(text): # type: (unicode) -> List[nodes.Node] retnodes = [] pos = 0 for m in token_re.finditer(text): # type: ignore if m.start() > pos: txt = text[pos:m.start()] retnodes.append(nodes.Text(txt, txt)) refnode = addnodes.pending_xref(m.group(1), reftype='token', refdomain='std', reftarget=m.group(1)) refnode += nodes.literal(m.group(1), m.group(1), classes=['xref']) retnodes.append(refnode) pos = m.end() if pos < len(text): retnodes.append(nodes.Text(text[pos:], text[pos:])) return retnodes
def dox(name, rawtext, text, lineno, inliner: Inliner, options={}, content=[]): title, target = parse_link(text) if not title: title = target for prefix in symbol_prefixes: if prefix + target in symbol_mapping: url = symbol_mapping[prefix + target] node = nodes.reference(rawtext, title, refuri=url, **options) return [node], [] # TODO: print file and line #msg = inliner.reporter.warning( #'Doxygen symbol %s not found' % target, line=lineno) #prb = inliner.problematic(rawtext, rawtext, msg) logger.warning('Doxygen symbol `%s` not found, rendering as monospace' % target) node = nodes.literal(rawtext, title, **options) return [node], []
def _add_doc(self, typ, sections): """Add documentation for a command/object/enum... We assume we're documenting the thing defined in self._cur_doc. typ is the type of thing being added ("Command", "Object", etc) sections is a list of nodes for sections to add to the definition. """ doc = self._cur_doc snode = nodes.section(ids=[self._sphinx_directive.new_serialno()]) snode += nodes.title('', '', *[nodes.literal(doc.symbol, doc.symbol), nodes.Text(' (' + typ + ')')]) self._parse_text_into_node(doc.body.text, snode) for s in sections: if s is not None: snode += s self._add_node_to_current_heading(snode)
def generate_flag_summary(flags, category): summary_node = nodes.definition_list_item() term_node = nodes.term(text=categories[category]) summary_node += term_node block = nodes.definition() summary_node += block # Fill block with flags for flag_info in flags: for name in flag_info['names']: block += nodes.literal(text=name) block += nodes.inline(text=' ') block += nodes.inline(text='\n') return summary_node
def handle_cross_reference(self, token, destination): from sphinx import addnodes wrap_node = addnodes.pending_xref( reftarget=unquote(destination), reftype="any", refdomain=None, # Added to enable cross-linking refexplicit=len(token.children) > 0, refwarn=True, ) self.add_line_and_source_path(wrap_node, token) if token.title: wrap_node["title"] = token.title self.current_node.append(wrap_node) text_node = nodes.literal("", "", classes=["xref", "any"]) wrap_node.append(text_node) with self.current_node_context(text_node): self.render_children(token)
def run(self): module_name = self.options['module'] # FIXME Check for nested modules? Currently caught in # ComponentTranslator below but we should probably do it here. env = self.state.document.settings.env if not hasattr(env, 'litmodel_components'): env.litmodel_components = {} env.litmodel_components[env.docname] = module_name note_node = note() paragraph_node = paragraph('', '', Text('This section defines the component '), literal('', module_name), Text('.')) note_node += paragraph_node return [note_node]
def code_role(name, rawtext, text, lineno, inliner, options={}, content=[]): """ This function creates an inline code block as defined in the twitter bootstrap documentation overrides the default behaviour of the code role *usage:* :code:`<your code>` *Example:* :code:`<section>` This code is not highlighted """ new_element = nodes.literal(rawtext, text) new_element.set_class('code') return [new_element], []
def visit_code(self, node): parent = self.parse_stack_r[-1] if node.text: node.text = html.unescape(node.text) if len(parent) == 1 and parent.tag == "p" and not parent.text: x = self.pop_node() assert isinstance(x, nodes.paragraph) block = nodes.literal_block() # note: this isn't yet activated because fenced_code extension # outputs raw html block, not a regular markdown ast tree. instead # what is actually run is the hacky workaround in append_text lang = node.attrib.get("class", "") if lang: node.attrib.pop("class") block["language"] = lang return block else: return nodes.literal()
def meth_ref_node(docname, ref_to, title=None): """Generate a node that references a :py:meth:""" if title is None: title = ref_to txt = Text(title, rawsource=title) newchild = literal(':py:meth:`%s`' % ref_to, '', txt, classes=['xref', 'py', 'py-meth']) newnode = pending_xref(':py:meth:`%s`' % ref_to, newchild, reftype='meth', refwarn='True', reftarget=ref_to, refexplicit='False', refdomain='py', refdoc=docname) return newnode
def NotationRole(role, rawtext, text, lineno, inliner, options={}, content=[]): #pylint: disable=unused-argument, dangerous-default-value """Any text using the notation syntax (``@id``, ``{+, …}``, etc.). Use this to explain tactic equivalences. For example, you might write this:: :n:`generalize @term as @ident` is just like :n:`generalize @term`, but it names the introduced hypothesis :token:`ident`. Note that this example also uses ``:token:``. That's because ``ident`` is defined in the Coq manual as a grammar production, and ``:token:`` creates a link to that. When referring to a placeholder that happens to be a grammar production, ``:token:`…``` is typically preferable to ``:n:`@…```. """ notation = utils.unescape(text, 1) position = inliner.reporter.get_source_and_line(lineno) return [nodes.literal(rawtext, '', parse_notation(notation, *position, rawtext=rawtext))], []
def token_xrefs(text, env): retnodes = [] pos = 0 for m in token_re.finditer(text): if m.start() > pos: txt = text[pos:m.start()] retnodes.append(nodes.Text(txt, txt)) refnode = addnodes.pending_xref(m.group(1)) refnode['reftype'] = 'token' refnode['reftarget'] = m.group(1) refnode['modname'] = env.currmodule refnode['classname'] = env.currclass refnode += nodes.literal(m.group(1), m.group(1), classes=['xref']) retnodes.append(refnode) pos = m.end() if pos < len(text): retnodes.append(nodes.Text(text[pos:], text[pos:])) return retnodes
def tag_role(role, rawtext, text, lineno, inliner, options={}, content=[]): categories = { 'pymorse': ('middleware', 'pymorse'), 'ros': ('middleware', 'user/middlewares/ros'), 'pocolibs': ('middleware', 'user/middlewares/pocolibs'), 'yarp_json': ('middleware', 'user/middlewares/yarp'), 'text': ('middleware', 'user/middlewares/text'), 'socket': ('middleware', 'user/middlewares/socket'), 'yarp': ('middleware', 'user/middlewares/yarp'), 'moos': ('middleware', 'user/middlewares/moos'), 'mavlink': ('middleware', 'user/middlewares/mavlink'), 'hla': ('middleware', 'user/middlewares/hla', 'multinode'), 'pprzlink': ('middleware', 'user/middlewares/pprzlink'), 'builder': ('api', 'user/builder'), 'datastream': ('access', None), 'service': ('access', 'dev/services') } if text not in categories: msg = inliner.reporter.error( 'Unknown category for tag "%s". Check exts/tag.py ' 'for available categories' % text, line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] # deseperately tried to generate a relative path to the doc root # but it's a failure. # inliner.document.settings.env may be a good starting point #url = categories[text][1] #node = None #if url: # import pdb;pdb.set_trace() # node = nodes.reference(rawtext, text, refuri = url + ".html") #else: # node = nodes.literal(rawtext, text) node = nodes.literal(rawtext, text) node['classes'].append("tag") node['classes'].append("tag-" + categories[text][0]) node['classes'].append("tag-" + text) return [node], []
def markup_func_ref_sphinx3(docname, app, match): class_str = ['c-func', 'c-macro'] reftype_str = ['function', 'macro'] cdom = app.env.domains['c'] # # Go through the dance of getting an xref out of the C domain # base_target = match.group(2) target_text = nodes.Text(match.group(0)) xref = None possible_targets = [base_target] # Check if this document has a namespace, and if so, try # cross-referencing inside it first. if c_namespace: possible_targets.insert(0, c_namespace + "." + base_target) if base_target not in Skipnames: for target in possible_targets: if target not in Skipfuncs: for class_s, reftype_s in zip(class_str, reftype_str): lit_text = nodes.literal(classes=['xref', 'c', class_s]) lit_text += target_text pxref = addnodes.pending_xref('', refdomain='c', reftype=reftype_s, reftarget=target, modname=None, classname=None) # # XXX The Latex builder will throw NoUri exceptions here, # work around that by ignoring them. # try: xref = cdom.resolve_xref(app.env, docname, app.builder, reftype_s, target, pxref, lit_text) except NoUri: xref = None if xref: return xref return target_text
def row(self, prop, tbody): row = nodes.row() anchor = '{},{},{}'.format(self.arguments[0].split('/')[-1], self.options.get('pointer', ''), prop.name) cell = nodes.entry('', nodes.target(ids=[anchor], names=[anchor]), nodes.literal('', nodes.Text(prop.name)), morecols=1) row += cell row += self.cell(prop.type) row += self.cell(prop.format or '') row += self.cell('Required' if prop.required else '') tbody += row row = nodes.row() row += self.cell(prop.title) if prop.description: cell = self.cell(prop.description or '', morecols=3) if 'nocrossref' not in self.options: ref = None if hasattr(prop.attributes, '__reference__'): ref = prop.attributes.__reference__['$ref'] elif hasattr(prop.items, '__reference__'): ref = prop.items.__reference__['$ref'] if ref: # just use the name at the end of the ref ref = ref.split('/')[-1] reference = nodes.reference('', '', nodes.Text(ref), internal=False, refuri='#' + ref.lower(), anchorname='') cell += nodes.paragraph('', nodes.Text('\n\nSee '), reference) if prop.deprecated: cell += nodes.paragraph( '', nodes.Text( 'This property was deprecated in version {}'. format(prop.deprecated['deprecatedVersion']))) cell += nodes.paragraph( '', nodes.Text(prop.deprecated['description'])) row += cell tbody += row
def template_field_role( app, typ, # pylint: disable=unused-argument rawtext, text, lineno, inliner, options=None, # pylint: disable=unused-argument content=None): # pylint: disable=unused-argument """ A role that allows you to include a list of template fields in the middle of the text. This is especially useful when writing guides describing how to use the operator. The result is a list of fields where each field is shorted in the literal block. Sample usage:: :template-fields:`airflow.operators.bash.BashOperator` For further information look at: * [http://docutils.sourceforge.net/docs/howto/rst-roles.html](Creating reStructuredText Interpreted Text Roles) """ if options is None: options = {} if content is None: content = [] text = utils.unescape(text) try: template_fields = get_template_field(app.env, text) except RoleException as e: msg = inliner.reporter.error(f"invalid class name {text} \n{e}", line=lineno) prb = inliner.problematic(rawtext, rawtext, msg) return [prb], [msg] node = nodes.inline(rawtext=rawtext) for i, field in enumerate(template_fields): if i != 0: node += nodes.Text(", ") node += nodes.literal(field, "", nodes.Text(field)) return [node], []
def run(self): tc_type = self.arguments[0] try: registry = TEST_CASE_REGISTRIES[tc_type] except KeyError: raise Exception( "test-case-documentation first argument must be {}".format( " or ".join(TEST_CASE_REGISTRIES.keys()))) test_cases = [( tc_function.__name__, dedent(inspect.getdoc(tc_function)), inspect.getsourcefile(tc_function), ) for tc_function in registry.iter_registered_functions()] out = [] for tc_name, tc_docs, tc_file in sorted(test_cases): # This is a crude hack (i.e. creating the directive by adding some # RST to a string...) but docutils/sphinx are sufficiently # poorly documented to make this the only viable option after # several hours of searching... section = nodes.section( ids=["test-case-{}-{}".format(tc_type, tc_name)]) title = nodes.title() title += nodes.Text("{} test case: ".format(tc_type.title())) title += nodes.literal(text=tc_name) section += title section += nodes.Text("") # Required to make ref below work... nested_parse_with_titles( self.state, ViewList(tc_docs.splitlines(), tc_file), section, ) out.append( make_from_rst(self.state, ".. {}-test-case:: {}".format(tc_type, tc_name))) out.append(section) return out
def list_entry(self, name, data): "Build an entry for the list of parameters." p1 = nodes.paragraph() p1 += nodes.target('', '', ids=[make_id(name)]) p1 += nodes.literal("", name) fl = nodes.field_list() if True: f = nodes.field() f += [nodes.field_name("", "Type"), nodes.field_body("", nodes.Text(" " + data["type"]))] fl += f f = nodes.field() value = nodes.paragraph() value += self.format_value(data["value"], data["type"]) if "units" in data: value += nodes.emphasis("", " ({})".format(data["units"])) f += [nodes.field_name("", "Default value"), nodes.field_body("", value)] fl += f if "choices" in data: choices = self.format_value(data["choices"], "keyword") f = nodes.field() f += [nodes.field_name("", "Choices"), nodes.field_body("", nodes.paragraph("", "", choices))] fl += f if "option" in data: option = self.format_value("-" + data["option"], "keyword") f = nodes.field() f += [nodes.field_name("", "Option"), nodes.field_body("", nodes.paragraph("", "", option))] fl += f p2 = nodes.paragraph() doc, _ = self.state.inline_text(data["doc"], self.lineno) p2 += doc p2 += fl return [p1, p2]
def gettendril(name, tendrils, isparam): d = {} if len(tendrils) == 0: return nodes.paragraph() section = nodes.title(text=name) lst = nodes.bullet_list() section += lst for k, v in tendrils: entry = nodes.list_item() lst += entry para = nodes.paragraph() entry += para d[k] = dict(doc=v.doc, type_name=v.type_name, required=v.required) if v.has_default: try: default = str(v.val) except TypeError, e: default = '[not visible from python]' para += [ nodes.strong(k, k), nodes.literal('', ' '), nodes.emphasis('', ' type: '), nodes.literal('', v.type_name + " ") ] para += nodes.literal('', ' ') if isparam: if not v.required: para += nodes.emphasis('', ' not ') para += nodes.emphasis('', 'required') para += nodes.literal('', ' ') if v.has_default: para += [ nodes.emphasis('', " default: "), nodes.literal('', default) ] else: para += nodes.emphasis('', ' no default value') try: if is_bp_enum(v.val): valpara = nodes.paragraph() valpara += nodes.emphasis('', 'Legal Values: ') for thevalue, thename in v.val.values.iteritems(): valpara += nodes.literal( '', "%s (%d) " % (str(thename), thevalue)) para += valpara except TypeError, e: pass # didn't convert to python, but okay. maybe v.val was boost::posix_time::ptime or something.
def fix_up_autodoc_headers(app, doctree): for idx, node in enumerate(doctree.traverse(addnodes.desc)): objtype = node.attributes.get("objtype") if objtype in ("method", "attribute"): sig = node.children[0] modname = sig.attributes["module"] clsname = sig.attributes["class"] qualified = "%s.%s." % (modname, clsname) start_index = 0 if sig[0].rawsource == "async ": start_index = 1 sig.insert( start_index, nodes.reference( "", "", nodes.literal(qualified, qualified), refid="%s.%s" % (modname, clsname), ), ) sig.insert( start_index, addnodes.desc_annotation( objtype, nodes.Text(objtype + " ", objtype + " ")), ) elif objtype == "function": sig = node.children[0] start_index = 0 if sig[0].rawsource == "async ": start_index = 1 sig.insert( start_index, addnodes.desc_annotation( objtype, nodes.Text(objtype + " ", objtype + " ")), )
def _add_reference_list(node, title, target_list, fromdocname, app): if target_list: para = nodes.paragraph() para += nodes.emphasis(text=title) items = nodes.bullet_list() para += items for item in sorted(target_list, key=by_filename): list_item = nodes.list_item() items += list_item refnode = nodes.reference('', '') innernode = nodes.literal(text=item[2]) refnode['refdocname'] = item[0] refnode['refuri'] = "{}#{}".format( app.builder.get_relative_uri(fromdocname, item[0]), item[1]) refnode += innernode refpara = nodes.paragraph() refpara += refnode list_item += refpara node.insert(-1, para)
def make_not_python_section(tree,parent_name=None): """Return a docutils tree constructed from this NotPython (file) sub-tree """ if parent_name: tree_name = "%s.%s"%(parent_name,tree.filename) else: tree_name = tree.filename title = "File %s"%(tree_name) # @@@ Same considerations on id/name as above section = nodes.section(CLASS="file",id=nodes.make_id(title), name=nodes.fully_normalize_name(title)) title = nodes.title(text=title) section.append(title) paragraph = nodes.paragraph(text="File ") paragraph.append(nodes.literal(text=tree.filename)) paragraph.append(nodes.Text(" is not a Python module.")) section.append(paragraph) return section
def handle_method(signature_node, module, object_name, cache): """ Styles ``automethod`` entries. Adds ``abstract`` prefix to abstract methods. Adds link to originating class for inherited methods. """ cls_name, attr_name = object_name.split(".") class_ = getattr(module, cls_name, None) if class_ is None: return attr = getattr(class_, attr_name) try: inspected_attr = cache[class_][attr_name] defining_class = inspected_attr.defining_class except KeyError: # TODO: This is a hack to handle bad interaction between enum and inspect defining_class = class_ if defining_class is not class_: reftarget = "{}.{}".format(defining_class.__module__, defining_class.__name__) xref_node = addnodes.pending_xref("", refdomain="py", refexplicit=True, reftype="class", reftarget=reftarget) name_node = nodes.literal("", "{}".format(defining_class.__name__), classes=["descclassname"]) xref_node.append(name_node) desc_annotation = list( signature_node.traverse(addnodes.desc_annotation)) index = len(desc_annotation) class_annotation = addnodes.desc_addname() class_annotation.extend([nodes.Text("("), xref_node, nodes.Text(").")]) class_annotation["xml:space"] = "preserve" signature_node.insert(index, class_annotation) if getattr(attr, "__isabstractmethod__", False): emphasis = nodes.emphasis("abstract ", "abstract ", classes=["property"]) signature_node.insert(0, emphasis)
def php_namespace_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): text = utils.unescape(text) env = inliner.document.settings.env has_explicit_title, title, namespace = split_explicit_title(text) if len(re.findall(r'[^\\]\\[^\\]', rawtext)) > 0: env.warn(env.docname, 'backslash not escaped in %s' % rawtext, lineno) full_url = build_url('namespace', namespace, None, None, inliner) if not has_explicit_title: name = namespace.lstrip('\\') ns = name.rfind('\\') if ns != -1: name = name[ns+1:] title = name list = [nodes.reference(title, title, internal=False, refuri=full_url, reftitle=namespace)] pnode = nodes.literal('', '', *list) return [pnode], []
def run(self): """Run the role.""" # get a path relative to the current document self.env: BuildEnvironment path = Path(self.env.mystnb_config.output_folder).joinpath( # type: ignore *(self.env.docname.split("/")[:-1] + self.target.split("/")) ) reftarget = ( path.as_posix() if os.name == "nt" else ("/" + os.path.relpath(path, self.env.app.srcdir)) ) node = download_reference(self.rawtext, reftarget=reftarget) self.set_source_info(node) title = self.title if self.has_explicit_title else self.target node += nodes.literal( self.rawtext, title, classes=["xref", "download", "myst-nb"] ) return [node], []
def token_xrefs(text: str, productionGroup: str = '') -> List[Node]: if len(productionGroup) != 0: productionGroup += ':' retnodes = [] # type: List[Node] pos = 0 for m in token_re.finditer(text): if m.start() > pos: txt = text[pos:m.start()] retnodes.append(nodes.Text(txt, txt)) refnode = pending_xref(m.group(1), reftype='token', refdomain='std', reftarget=productionGroup + m.group(1)) refnode += nodes.literal(m.group(1), m.group(1), classes=['xref']) retnodes.append(refnode) pos = m.end() if pos < len(text): retnodes.append(nodes.Text(text[pos:], text[pos:])) return retnodes
def emph_literal_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): text = utils.unescape(text) pos = 0 retnode = nodes.literal(role=typ) for m in _litvar_re.finditer(text): if m.start() > pos: txt = text[pos:m.start()] retnode += nodes.Text(txt, txt) retnode += nodes.emphasis(m.group(1), m.group(1)) pos = m.end() if pos < len(text): retnode += nodes.Text(text[pos:], text[pos:]) return [retnode], []