Example #1
0
def toctree_directive(dirname, arguments, options, content, lineno,
                      content_offset, block_text, state, state_machine):

    node = nodes.admonition()
    node['classes'] += ['admonition-toctree']
    node += nodes.title('', 'Toctree')

    para = nodes.paragraph('')
    node += para
    
    ul = nodes.bullet_list()
    para += ul
    
    for line in content:
        line = line.strip()
        if not line or line.startswith(':'): continue

        try:
            uri, name = resolve_name(line, state.inliner)
            title = name
            try:
                doc = models.Docstring.on_site.get(name=name)
                if doc.title:
                    title = doc.title
            except models.Docstring.DoesNotExist:
                pass
            entry = nodes.reference('', title, refuri=uri)
        except ValueError:
            entry = nodes.reference('', line, name=line,
                                    refname=':ref:`%s`' % line)

        ul += nodes.list_item('', nodes.paragraph('', '', entry))

    return [node]
Example #2
0
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], []
Example #3
0
 def generate_footer(self):
     # @@@ Text is hard-coded for now.
     # Should be made dynamic (language-dependent).
     settings = self.document.settings
     if settings.generator or settings.datestamp or settings.source_link or settings.source_url:
         text = []
         if settings.source_link and settings._source or settings.source_url:
             if settings.source_url:
                 source = settings.source_url
             else:
                 source = utils.relative_path(settings._destination, settings._source)
             text.extend([nodes.reference("", "View document source", refuri=source), nodes.Text(".\n")])
         if settings.datestamp:
             datestamp = time.strftime(settings.datestamp, time.gmtime())
             text.append(nodes.Text("Generated on: " + datestamp + ".\n"))
         if settings.generator:
             text.extend(
                 [
                     nodes.Text("Generated by "),
                     nodes.reference("", "Docutils", refuri="http://docutils.sourceforge.net/"),
                     nodes.Text(" from "),
                     nodes.reference("", "reStructuredText", refuri="http://" "docutils.sourceforge.net/rst.html"),
                     nodes.Text(" source.\n"),
                 ]
             )
         return [nodes.paragraph("", "", *text)]
     else:
         return None
Example #4
0
def filebrief_replace_node(app, doctree, itemtype, items):
    """ where does the scene take place?
        here sir, here!!! I saw chaisaw, acid, and the like.
        what? this is just python code idiot!
    """
    env = app.builder.env
    nodefuncmap = dict()

    if itemtype == "functions":
        nodefuncmap = filebrief_nodefuncmap(doctree)

    listnode = nodes.bullet_list()
    for refname, (docname, type, theid) in sorted(items.iteritems()):
        pnode   = nodes.paragraph()
        if itemtype == "classes":
            pnode   = nodes.paragraph("class ", "class ")
        refnode = nodes.reference(refname, refname, refdocname=docname, refid=theid)

        retnode = refnode
        cnode = nodefuncmap.get(theid)
        if cnode:
            (_, fname) = split_func_name(refname)
            refnode = nodes.reference(fname, fname, refdocname=docname, refid=theid)
            i = cnode[0].first_child_matching_class(addnodes.desc_name)
            cnode[0][i] = refnode
            cnode.children = cnode[0].children
            retnode = cnode
        pnode.append(retnode)
        listnode.append(pnode)
    return listnode
Example #5
0
 def generate_footer(self):
     # @@@ Text is hard-coded for now.
     # Should be made dynamic (language-dependent).
     settings = self.document.settings
     if settings.generator or settings.datestamp or settings.source_link \
            or settings.source_url:
         text = []
         if settings.source_link and settings._source \
                or settings.source_url:
             if settings.source_url:
                 source = settings.source_url
             else:
                 source = utils.relative_path(settings._destination,
                                              settings._source)
             text.extend([
                 nodes.reference('', 'View document source',
                                 refuri=source),
                 nodes.Text('.\n')])
         if settings.datestamp:
             datestamp = time.strftime(settings.datestamp, time.gmtime())
             text.append(nodes.Text('Generated on: ' + datestamp + '.\n'))
         if settings.generator:
             text.extend([
                 nodes.Text('Generated by '),
                 nodes.reference('', 'Docutils', refuri=
                                 'http://docutils.sourceforge.net/'),
                 nodes.Text(' from '),
                 nodes.reference('', 'reStructuredText', refuri='http://'
                                 'docutils.sourceforge.net/rst.html'),
                 nodes.Text(' source.\n')])
         return [nodes.paragraph('', '', *text)]
     else:
         return None
Example #6
0
def test_get_full_qualified_name():
    env = Mock(domaindata={})
    domain = JavaScriptDomain(env)

    # non-js references
    node = nodes.reference()
    assert domain.get_full_qualified_name(node) is None

    # simple reference
    node = nodes.reference(reftarget='func')
    assert domain.get_full_qualified_name(node) == 'func'

    # with js:module context
    kwargs = {'js:module': 'module1'}
    node = nodes.reference(reftarget='func', **kwargs)
    assert domain.get_full_qualified_name(node) == 'module1.func'

    # with js:object context
    kwargs = {'js:object': 'Class'}
    node = nodes.reference(reftarget='func', **kwargs)
    assert domain.get_full_qualified_name(node) == 'Class.func'

    # with both js:module and js:object context
    kwargs = {'js:module': 'module1', 'js:object': 'Class'}
    node = nodes.reference(reftarget='func', **kwargs)
    assert domain.get_full_qualified_name(node) == 'module1.Class.func'
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)
Example #8
0
File: xref.py Project: OpenUAS/wasp
def xref( typ, rawtext, text, lineno, inliner, options={}, content=[] ):

    title = target = text
    titleistarget = True
    # look if explicit title and target are given with `foo <bar>` syntax
    brace = text.find('<')
    if brace != -1:
        titleistarget = False
        m = caption_ref_re.match(text)
        if m:
            target = m.group(2)
            title = m.group(1)
        else:
            # fallback: everything after '<' is the target
            target = text[brace+1:]
            title = text[:brace]

    link = xref.links[target]

    if brace != -1:
        pnode = nodes.reference(target, title, refuri=link[1])
    else:
        pnode = nodes.reference(target, link[0], refuri=link[1])

    return [pnode], []
Example #9
0
def test_get_full_qualified_name():
    env = Mock(domaindata={})
    domain = PythonDomain(env)

    # non-python references
    node = nodes.reference()
    assert domain.get_full_qualified_name(node) is None

    # simple reference
    node = nodes.reference(reftarget='func')
    assert domain.get_full_qualified_name(node) == 'func'

    # with py:module context
    kwargs = {'py:module': 'module1'}
    node = nodes.reference(reftarget='func', **kwargs)
    assert domain.get_full_qualified_name(node) == 'module1.func'

    # with py:class context
    kwargs = {'py:class': 'Class'}
    node = nodes.reference(reftarget='func', **kwargs)
    assert domain.get_full_qualified_name(node) == 'Class.func'

    # with both py:module and py:class context
    kwargs = {'py:module': 'module1', 'py:class': 'Class'}
    node = nodes.reference(reftarget='func', **kwargs)
    assert domain.get_full_qualified_name(node) == 'module1.Class.func'
Example #10
0
File: images.py Project: xcore/xdoc
    def run(self):
        if 'align' in self.options:
            if isinstance(self.state, states.SubstitutionDef):
                # Check for align_v_values.
                if self.options['align'] not in self.align_v_values:
                    raise self.error(
                        'Error in "%s" directive: "%s" is not a valid value '
                        'for the "align" option within a substitution '
                        'definition.  Valid values for "align" are: "%s".'
                        % (self.name, self.options['align'],
                           '", "'.join(self.align_v_values)))
            elif self.options['align'] not in self.align_h_values:
                raise self.error(
                    'Error in "%s" directive: "%s" is not a valid value for '
                    'the "align" option.  Valid values for "align" are: "%s".'
                    % (self.name, self.options['align'],
                       '", "'.join(self.align_h_values)))
        messages = []
        reference = directives.uri(self.arguments[0])
        self.options['uri'] = reference
        reference_node = None
        if 'target' in self.options:
            block = states.escape2null(
                self.options['target']).splitlines()
            block = [line for line in block]
            target_type, data = self.state.parse_target(
                block, self.block_text, self.lineno)
            if target_type == 'refuri':
                reference_node = nodes.reference(refuri=data)
            elif target_type == 'refname':
                reference_node = nodes.reference(
                    refname=fully_normalize_name(data),
                    name=whitespace_normalize_name(data))
                reference_node.indirect_reference_name = data
                self.state.document.note_refname(reference_node)
            else:                           # malformed target
                messages.append(data)       # data is a system message
            del self.options['target']


        image_node = nodes.image(self.block_text, **self.options)

        if 'iconmargin' in self.options:
            image_node['classes'].append('iconmargin')

        set_classes(self.options)

        if 'iconmarginheight' in self.options:
            image_node['iconmarginheight'] = \
               int(self.options['iconmarginheight'])

        if 'iconmarginraise' in self.options:
            image_node['iconmarginraise'] = True


        if reference_node:
            reference_node += image_node
            return messages + [reference_node]
        else:
            return messages + [image_node]
Example #11
0
    def validator(name, raw_text, text, lineno, inliner):
        """
        Link to the JSON Schema documentation for a validator.

        Arguments:

            name (str):

                the name of the role in the document

            raw_source (str):

                the raw text (role with argument)

            text (str):

                the argument given to the role

            lineno (int):

                the line number

            inliner (docutils.parsers.rst.states.Inliner):

                the inliner

        Returns:

            tuple:

                a 2-tuple of nodes to insert into the document and an
                iterable of system messages, both possibly empty

        """

        if text == "$ref":
            return [nodes.reference(raw_text, text, refuri=ref_url)], []
        elif text == "$schema":
            return [nodes.reference(raw_text, text, refuri=schema_url)], []

        # find the header in the validation spec containing matching text
        header = spec.xpath("//h1[contains(text(), '{0}')]".format(text))

        if len(header) == 0:
            inliner.reporter.warning(
                "Didn't find a target for {0}".format(text),
            )
            uri = base_url
        else:
            if len(header) > 1:
                inliner.reporter.info(
                    "Found multiple targets for {0}".format(text),
                )

            # get the href from link in the header
            uri = base_url + header[0].find("a").attrib["href"]

        reference = nodes.reference(raw_text, text, refuri=uri)
        return [reference], []
Example #12
0
def _parse_ref(rawtext, text, link, inliner):
    uri, name = resolve_name(link, inliner, postpone=True)
    if uri:
        return nodes.reference(text, text, refuri=uri)
    else:
        # postpone resolution to generate warnings about failing links
        ref = nodes.reference(text, text, name=link, refname=':ref:`%s`'%link)
        return ref
Example #13
0
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], []
Example #14
0
def review_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
    """Role linking to a docstring, and displaying its review status"""
    name = text.strip()
    try:
        uri, real_name = resolve_name(name, inliner)
        doc = models.Docstring.on_site.get(name=real_name)
        ref = nodes.reference('', name, refuri=uri)
        cls = models.REVIEW_STATUS_CODES.get(doc.review)
        if cls:
            ref['classes'].append(cls)
    except (models.Docstring.DoesNotExist, ValueError):
        ref = nodes.reference('', name, name=name, refname=':review:`%s`'%name)
    return [ref], []
Example #15
0
def ref_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
    """Reimplementation of Sphinx's ref role, but just links unconditionally."""

    msg_list = []
    match = _ref_re.match(text)
    if match is not None:
        text = match.groups()[0].strip()
        target = "#" + match.groups()[1]
        pnode = nodes.reference(text, text, internal=True, refuri=target)
    else:

        class RefVisitor(nodes.NodeVisitor, object):

            text = None

            def __init__(self, document, label):
                self._label = label
                super(RefVisitor, self).__init__(document)

            def visit_target(self, node):
                if self._label not in node.attributes["ids"]:
                    return
                else:
                    sibs = node.parent.children
                    next_sib = sibs[sibs.index(node) + 1]
                    # text has to be the figure caption
                    if isinstance(next_sib, nodes.figure):
                        self.text = [
                            x for x in next_sib.children if isinstance(x, nodes.caption)
                        ][0].astext()
                    elif isinstance(
                        next_sib, nodes.section
                    ):  # text has to be the title
                        self.text = next_sib.attributes["names"][0].title()

            def unknown_visit(self, node):
                pass

        visitor = RefVisitor(inliner.document, text)
        inliner.document.walk(visitor)
        if visitor.text is None:
            visitor.text = text.replace("-", " ").title()
            logger.info(
                'ref label {} is missing or not known yet at this point in the document or not immediately before figure or section. Proceeding anyway but title "{}" in this ref may be wrong.'.format(
                    text, visitor.text
                )
            )
        target = "#" + text
        pnode = nodes.reference(text, visitor.text, internal=True, refuri=target)
    pnode["classes"] = ["reference"]
    return [pnode], msg_list
Example #16
0
File: dox.py Project: mosra/m.css
def dox(name, rawtext, text, lineno, inliner: Inliner, options={}, content=[]):
    title, target, hash = parse_link(text)

    # Otherwise adding classes to the options behaves globally (uh?)
    _options = dict(options)
    set_classes(_options)
    # Avoid assert on adding to undefined member later
    if 'classes' not in _options: _options['classes'] = []

    # Try linking to the whole docs first
    for basename, url, css_classes in tagfile_basenames:
        if basename == target:
            if not title:
                # TODO: extract title from index page in the tagfile
                logger.warning("Link to main page `{}` requires a title".format(target))
                title = target

            _options['classes'] += css_classes
            node = nodes.reference(rawtext, title, refuri=url + hash, **_options)
            return [node], []

    for prefix in symbol_prefixes:
        if prefix + target in symbol_mapping:
            link_title, url, css_classes = symbol_mapping[prefix + target]
            if title:
                use_title = title
            elif link_title:
                use_title = link_title
            else:
                if link_title is not None:
                    logger.warning("Doxygen anchor `{}` has no title, using its ID as link title".format(target))

                use_title = target

            _options['classes'] += css_classes
            node = nodes.reference(rawtext, use_title, refuri=url + hash, **_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)
    if title:
        logger.warning("Doxygen symbol `{}` not found, rendering just link title".format(target))
        node = nodes.inline(rawtext, title, **_options)
    else:
        logger.warning("Doxygen symbol `{}` not found, rendering as monospace".format(target))
        node = nodes.literal(rawtext, target, **_options)
    return [node], []
Example #17
0
def mkYrefNode(target,text,rawtext,role,explicitText,lineno,options={}):
	"""Create hyperlink to yade target. Targets starting with literal 'yade.' are absolute, but the leading 'yade.' will be stripped from the link text. Absolute tergets are supposed to live in page named yade.[module].html, anchored at #yade.[module2].[rest of target], where [module2] is identical to [module], unless mapped over by moduleMap.
	
	Other targets are supposed to live in yade.wrapper (such as c++ classes)."""

	writer=__builtin__.writer # to make sure not shadowed by a local var
	import string
	if target.startswith('yade.'):
		module='.'.join(target.split('.')[0:2])
		module2=(module if module not in moduleMap.keys() else moduleMap[module])
		if target==module: target='' # to reference the module itself
		uri=('%%%s#%s'%(module2,target) if writer=='latex' else '%s.html#%s'%(module2,target))
		if not explicitText and module!=module2:
			text=module2+'.'+'.'.join(target.split('.')[2:])
		text=string.replace(text,'yade.','',1)
	elif target.startswith('external:'):
		exttarget=target.split(':',1)[1]
		if not explicitText: text=exttarget
		target=exttarget if '.' in exttarget else 'module-'+exttarget
		uri=(('%%external#%s'%target) if writer=='latex' else 'external.html#%s'%target)
	else:
		uri=(('%%yade.wrapper#yade.wrapper.%s'%target) if writer=='latex' else 'yade.wrapper.html#yade.wrapper.%s'%target)
		#print writer,uri
	if 0:
		refnode=addnodes.pending_xref(rawtext,reftype=role,refexplicit=explicitText,reftarget=target)
		#refnode.line=lineno
		#refnode+=nodes.literal(rawtext,text,classes=['ref',role])
		return [refnode],[]
		#ret.rawtext,reftype=role,
	else:
		return nodes.reference(rawtext,docutils.utils.unescape(text),refuri=uri,**options)
Example #18
0
def ref_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
    # match :ref:`Bar! <link/link/link>` from rawText
    p = re.search('`(.*) <(.*)>`', rawtext)
    if(p):
        return [nodes.reference(rawtext, p.group(1), refuri= cherrypy.request.script_name + "/" + p.group(2), **options)], []   
    else:
        return [], []
Example #19
0
def issues_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
    """
    Use: :issue|bug|feature|support:`ticket number`

    When invoked as :issue:, turns into just a "#NN" hyperlink to Github.

    When invoked otherwise, turns into "[Type] <#NN hyperlink>: ".
    """
    # Old-style 'just the issue link' behavior
    issue_no = utils.unescape(text)
    ref = "https://github.com/fabric/fabric/issues/" + issue_no
    link = nodes.reference(rawtext, '#' + issue_no, refuri=ref, **options)
    ret = [link]
    # Additional 'new-style changelog' stuff
    if name in issue_types:
        which = '[<span class="changelog-%s">%s</span>]' % (
            name, name.capitalize()
        )
        ret = [
            nodes.raw(text=which, format='html'),
            nodes.inline(text=" "),
            link,
            nodes.inline(text=":")
        ]
    return ret, []
Example #20
0
    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()
        # 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
Example #21
0
def blogref_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
    """
    Inserts a reference to the blog entry of the specified date.
    
    Instead of writing ``:doc:`/blog/2011/0406```
    it is better to write ``:blogref:`20110406```
    because the latter works between Sphinx trees and also supports archived blog entries.
    
    """
    # thanks to http://docutils.sourceforge.net/docs/howto/rst-roles.html
    # this code originally from roles.pep_reference_role
    #~ print 20130315, rawtext, text, utils.unescape(text)
    has_explicit_title, title, target = split_explicit_title(text)
    try:
        date = i2d(int(target))
    except ValueError:
        msg = inliner.reporter.error(
            'Invalid text %r: must be an integer date of style "20130315" .'
            % text, line=lineno)
        prb = inliner.problematic(rawtext, rawtext, msg)
        return [prb], [msg]
    #~ print repr(env)
    #~ raise Exception(20130315)
    #~ ref = inliner.document.settings.pep_base_url
           #~ + inliner.document.settings.pep_file_url_template % date)
    roles.set_classes(options)
    #~ from django.conf import settings
    #~ shown_text = settings.SITE.dtos(date)
    env = inliner.document.settings.env
    if not has_explicit_title:
        title = date.strftime(env.settings.get('today_fmt', '%Y-%m-%d'))
    title = utils.unescape(title)
    return [nodes.reference(rawtext, title,
                            refuri=get_blog_url(date),
                            **options)], []
Example #22
0
def coderef_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
    text = utils.unescape(text)
    has_explicit_title, title, target = split_explicit_title(text)
    try:
        modname, name = target.rsplit('.', 1)
    except ValueError:
        raise Exception("Don't know how to import name %s" % target)
    mod = import_module(modname)

    try:
        value = getattr(mod, name, None)
    except AttributeError:
        raise Exception("No name '%s' in module '%s'" % (name, modname))
    #~ raise Exception("20130908 %s " % lines)
    if isinstance(value, type):
        if value.__module__ != modname:
            raise Exception("20130908 %r != %r" % (value.__module__, modname))

    url = srcref(mod)

    lines, line_no = inspect.getsourcelines(value)
    if line_no:
        url += "#" + str(line_no)
    if not has_explicit_title:
        pass
    pnode = nodes.reference(title, title, internal=False, refuri=url)
    return [pnode], []
Example #23
0
def make_link_node(rawtext, app, type, slug, options):
    """Create a link to a github resource.

    :param rawtext: Text being replaced with link node.
    :param app: Sphinx application context
    :param type: Link type (issues, changeset, etc.)
    :param slug: ID of the thing to link to
    :param options: Options dictionary passed to role func.
    """

    try:
        base = app.config.github_project_url
        if not base:
            raise AttributeError
        if not base.endswith('/'):
            base += '/'
    except AttributeError as err:
        raise ValueError('github_project_url configuration value is not set (%s)' % str(err))

    ref = base + type + '/' + slug + '/'
    set_classes(options)
    prefix = "#"
    if type == 'pull':
        prefix = "PR " + prefix
    node = nodes.reference(rawtext, prefix + utils.unescape(slug), refuri=ref,
                           **options)
    return node
Example #24
0
 def make_target_footnote(self, refuri, refs, notes):
     if refuri in notes:  # duplicate?
         footnote = notes[refuri]
         assert len(footnote['names']) == 1
         footnote_name = footnote['names'][0]
     else:                           # original
         footnote = nodes.footnote()
         footnote_id = self.document.set_id(footnote)
         # Use uppercase letters and a colon; they can't be
         # produced inside names by the parser.
         footnote_name = 'TARGET_NOTE: ' + footnote_id
         footnote['auto'] = 1
         footnote['names'] = [footnote_name]
         footnote_paragraph = nodes.paragraph()
         footnote_paragraph += nodes.reference('', refuri, refuri=refuri)
         footnote += footnote_paragraph
         self.document.note_autofootnote(footnote)
         self.document.note_explicit_target(footnote, footnote)
     for ref in refs:
         if isinstance(ref, nodes.target):
             continue
         refnode = nodes.footnote_reference(refname=footnote_name, auto=1)
         refnode['classes'] += self.classes
         self.document.note_autofootnote_ref(refnode)
         self.document.note_footnote_ref(refnode)
         index = ref.parent.index(ref) + 1
         reflist = [refnode]
         if not utils.get_trim_footnote_ref_space(self.document.settings):
             if self.classes:
                 reflist.insert(0, nodes.inline(text=' ', Classes=self.classes))
             else:
                 reflist.insert(0, nodes.Text(' '))
         ref.parent.insert(index, reflist)
     return footnote
Example #25
0
	def generate_uri_role( role_name, aliases,
					anchor_text, base_url,
					interpret_url, validator):
		'''Creates and register a uri based "interpreted role".

		Those are similar to the RFC, and PEP ones, and take
		role_name:
			name that will be registered
		aliases:
			list of alternate names
		anchor_text:
			text that will be used, together with the role
		base_url:
			base url for the link
		interpret_url:
			this, modulo the validated text, will be added to it
		validator:
			should return the validated text, or raise ValueError 
		'''
		def uri_reference_role(role, rawtext, text, lineno, inliner,
			options={}, content=[]):
			try:
				valid_text = validator(text)
			except ValueError, e:
				msg = inliner.reporter.error( e.message % dict(text=text), line=lineno)
				prb = inliner.problematic(rawtext, rawtext, msg)
				return [prb], [msg]
			ref = base_url + interpret_url % valid_text
			set_classes(options)
			node = nodes.reference(rawtext, anchor_text + utils.unescape(text), refuri=ref,
					**options)
			return [node], []
Example #26
0
def ghcommit_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
    """Link to a GitHub commit.

    Returns 2 part tuple containing list of nodes to insert into the
    document and a list of system messages.  Both are allowed to be
    empty.

    :param name: The role name used in the document.
    :param rawtext: The entire markup snippet, with role.
    :param text: The text marked with the role.
    :param lineno: The line number where rawtext appears in the input.
    :param inliner: The inliner instance that called us.
    :param options: Directive options for customization.
    :param content: The directive content for customization.
    """
    app = inliner.document.settings.env.app
    #app.info('user link %r' % text)
    try:
        base = app.config.github_project_url
        if not base:
            raise AttributeError
        if not base.endswith('/'):
            base += '/'
    except AttributeError as err:
        raise ValueError('github_project_url configuration value is not set (%s)' % str(err))

    ref = base + text
    node = nodes.reference(rawtext, text[:6], refuri=ref, **options)
    return [node], []
Example #27
0
 def build_contents(self, node, level=0):
     level += 1
     sections = [sect for sect in node if isinstance(sect, nodes.section)]
     entries = []
     autonum = 0
     depth = self.startnode.details.get('depth', sys.maxsize)
     for section in sections:
         title = section[0]
         auto = title.get('auto')    # May be set by SectNum.
         entrytext = self.copy_and_filter(title)
         reference = nodes.reference('', '', refid=section['ids'][0],
                                     *entrytext)
         ref_id = self.document.set_id(reference)
         entry = nodes.paragraph('', '', reference)
         item = nodes.list_item('', entry)
         if ( self.backlinks in ('entry', 'top')
              and title.next_node(nodes.reference) is None):
             if self.backlinks == 'entry':
                 title['refid'] = ref_id
             elif self.backlinks == 'top':
                 title['refid'] = self.toc_id
         if level < depth:
             subsects = self.build_contents(section, level)
             item += subsects
         entries.append(item)
     if entries:
         contents = nodes.bullet_list('', *entries)
         if auto:
             contents['classes'].append('auto-toc')
         return contents
     else:
         return []
Example #28
0
    def _replace_pattern(self, pattern, url_format):
        project = self.document.settings.env.config.github_project

        for node in self.document.traverse(nodes.Text):
            parent = node.parent
            if isinstance(parent, (nodes.literal, nodes.FixedTextElement)):
                continue

            text = str(node)
            new_nodes = []
            last_ref_end = 0
            for match in pattern.finditer(text):
                head = text[last_ref_end:match.start()]
                if head:
                    new_nodes.append(nodes.Text(head))

                last_ref_end = match.end()
                ref = url_format.format(project, match.group(1))
                link = nodes.reference(
                    match.group(0),
                    match.group(0),
                    refuri=ref
                )
                new_nodes.append(link)

            if not new_nodes:
                continue

            tail = text[last_ref_end:]
            if tail:
                new_nodes.append(nodes.Text(tail))

            parent.replace(node, new_nodes)
Example #29
0
def user_role(name, rawtext, text, lineno, inliner, options=None, content=None):
    """Sphinx role for linking to a user profile. Defaults to linking to
    Github profiles, but the profile URIS can be configured via the
    ``issues_user_uri`` config value.

    Examples: ::

        :user:`sloria`

    Anchor text also works: ::

        :user:`Steven Loria <sloria>`
    """
    options = options or {}
    content = content or []
    has_explicit_title, title, target = split_explicit_title(text)

    target = utils.unescape(target).strip()
    title = utils.unescape(title).strip()
    config = inliner.document.settings.env.app.config
    if config.issues_user_uri:
        ref = config.issues_user_uri.format(user=target)
    else:
        ref = "https://github.com/{0}".format(target)
    if has_explicit_title:
        text = title
    else:
        text = "@{0}".format(target)

    link = nodes.reference(text=text, refuri=ref, **options)
    return [link], []
Example #30
0
File: xlink.py Project: nltk/epydoc
    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], []
Example #31
0
def process_req_nodes(app, doctree, fromdocname):
    for node in doctree.traverse(req):
        if not app.config.req_include_reqs:
            node.parent.remove(node)

    # Replace all reqtrace nodes with a list of the collected reqs.
    # Augment each req with a backlink to the original location.
    env = app.builder.env

    for node in doctree.traverse(reqtrace):
        if not app.config.req_include_reqs:
            node.replace_self([])
            continue

        content = []

        reqtable = nodes.table(classes=['reqtable'])

        tgroup = nodes.tgroup(cols=3)
        reqtable += tgroup

        tgroup += nodes.colspec(colwidth=15, classes=['reqid'])
        tgroup += nodes.colspec(colwidth=15, classes=['section'])
        tgroup += nodes.colspec(colwidth=70, classes=['evidence'])

        thead = nodes.thead()
        tgroup += thead
        append_row(thead, ['Req', 'Section', 'Evidence'])

        tbody = nodes.tbody()
        tgroup += tbody

        sorted_req = sorted(env.req_all_reqs, key=lambda req: req['reqid'])

        for req_info in sorted_req:

            refpara = nodes.paragraph()
            refpara += nodes.Text('', '')

            # Create a reference
            try:
                newnode = nodes.reference('', '')
                section = req_info['section']
                section_name = ''
                pprint(section)
                if section.get('secnumber'):
                    section_name += (('%s' + self.secnumber_suffix) %
                                     '.'.join(map(str, node['secnumber'])))
                section_name += section[section.first_child_matching_class(
                    title)][0].astext()
                innernode = nodes.emphasis(section_name, section_name)
                newnode['refdocname'] = req_info['docname']
                newnode['refuri'] = app.builder.get_relative_uri(
                    fromdocname, req_info['docname'])
                newnode['refuri'] += '#' + req_info['target']['refid']
                newnode.append(innernode)
                refpara += newnode
                refpara += nodes.Text('', '')
            except:
                continue

            append_row(tbody,
                       [req_info['reqid'], refpara, req_info['evidence']])

        content.append(reqtable)

        node.replace_self(content)
Example #32
0
def commit_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
    ref = 'https://github.com/scrapy/scrapy/commit/' + text
    set_classes(options)
    node = nodes.reference(rawtext, 'commit ' + text, refuri=ref, **options)
    return [node], []
Example #33
0
def rev_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
    ref = 'http://hg.scrapy.org/scrapy/changeset/' + text
    set_classes(options)
    node = nodes.reference(rawtext, 'r' + text, refuri=ref, **options)
    return [node], []
Example #34
0
def view_meta_admonition(admonition_name, name=None):
    """List all found admonition from all the rst files found in directory

    view_meta_admonition is called by the 'meta' url: /__XXXXXXX__
    where XXXXXXX represents and admonition name, like:

    * todo
    * warning
    * danger
    * ...

    .. note:: this function may works for any docutils node, not only
       admonition

    Keyword Arguments:

        :admonition_name: (str) -- name of the admonition
    """
    print(("meta admo: %s - %s" % (admonition_name, name)))
    admonition = None

    if admonition_name == 'todo':
        admonition = todo
    elif admonition_name == 'done':
        admonition = done
    elif hasattr(nodes, admonition_name):
        admonition = getattr(nodes, admonition_name)
    else:
        return abort(404)

    doc2_content = ""

    doc2_output, doc2_pub = docutils.core.publish_programmatically(
        source_class=io.StringInput,
        source=doc2_content,
        source_path=None,
        destination_class=io.StringOutput,
        destination=None,
        destination_path=None,
        reader=None,
        reader_name='standalone',
        parser=None,
        parser_name='restructuredtext',
        writer=HisWriter(),
        writer_name=None,
        settings=None,
        settings_spec=None,
        settings_overrides=None,
        config_section=None,
        enable_exit_status=False)

    section1 = nodes.section("{0}_list_file".format(admonition_name))
    doc2_pub.reader.document.append(section1)
    title1 = nodes.title("{0} LIST".format(admonition_name.upper()),
                         "{0} LIST".format(admonition_name.upper()))
    doc2_pub.reader.document.append(title1)
    if name is None:
        rst_files = [
            filename[2:-4] for filename in sorted(glob.glob("./*.rst"))
        ]
        rst_files.reverse()
    else:
        rst_files = [
            filename[2:-4]
            for filename in sorted(glob.glob("./{0}.rst".format(name)))
        ]
    for file in rst_files:
        file_title = False
        file_handle = open(file + '.rst', 'r', encoding='utf-8')
        file_content = file_handle.read()
        file_handle.close()
        file_content = file_content

        output, pub = docutils.core.publish_programmatically(
            source_class=io.StringInput,
            source=file_content,
            source_path=None,
            destination_class=io.StringOutput,
            destination=None,
            destination_path=None,
            reader=None,
            reader_name='standalone',
            parser=None,
            parser_name='restructuredtext',
            writer=None,
            writer_name='html',
            settings=None,
            settings_spec=None,
            settings_overrides=None,
            config_section=None,
            enable_exit_status=False)

        my_settings = pub.get_settings()
        parser = docutils.parsers.rst.Parser()
        document = docutils.utils.new_document('test', my_settings)
        parser.parse(file_content, document)
        for node in document.traverse(admonition):
            if not file_title:
                file_title = True
                # new section
                section2 = nodes.section(file)
                doc2_pub.reader.document.append(section2)
                # add link to the originating file
                paragraph = nodes.paragraph()
                file_target = nodes.target(ids=[file],
                                           names=[file],
                                           refuri="/" + file)
                file_ref = nodes.reference(file,
                                           file,
                                           name=file,
                                           refuri="/" + file)
                paragraph.append(nodes.Text("in "))
                paragraph.append(file_ref)
                paragraph.append(file_target)
                paragraph.append(nodes.Text(":"))
                doc2_pub.reader.document.append(paragraph)
                #doc2_pub.reader.document.append(file_target)

            doc2_pub.reader.document.append(node)
        doc2_pub.apply_transforms()

    doc2_pub.writer.write(doc2_pub.document, doc2_pub.destination)
    doc2_pub.writer.assemble_parts()
    if name is None:
        display_file_name = '__{0}__'.format(admonition_name)
        extended_name = None
    else:
        display_file_name = '{0}'.format(name)
        extended_name = '__{0}__'.format(admonition_name)
    return template('page',
                    type="view",
                    name=display_file_name,
                    content=doc2_pub.writer.parts['html_body'])
Example #35
0
def github_link_node(name, rawtext, options=()):
    try:
        base = github_project_url
        if not base:
            raise AttributeError
    except AttributeError, err:
        raise ValueError(
            'github_project_url configuration value is not set (%s)' %
            str(err))
    slash = '/' if base[-1] != '/' else ''
    ref = base + slash + rawtext
    if not options:
        options = {}
    set_classes(options)
    node = nodes.reference(name, utils.unescape(name), refuri=ref, **options)
    return node


# Return filename for example ex in the current language.
def xapian_code_example_filename(ex):
    return "code/%s/%s%s" % (highlight_language, ex, ext)


# Return the command to show in the generated docs.
def xapian_code_example_command(ex):
    if highlight_language == 'lua':
        return "lua %s" % xapian_code_example_filename(ex)
    elif highlight_language == 'perl':
        return "perl %s" % xapian_code_example_filename(ex)
    elif highlight_language == 'php':
Example #36
0
    def assemble_doctree(self, docname, title, author, appendices):

        # FIXME: use the new inline_all_trees from Sphinx.
        # check how the LaTeX builder does it.

        self.docnames = set([docname])
        self.info(darkgreen(docname) + " ", nonl=1)

        def process_tree(docname, tree):
            tree = tree.deepcopy()
            for toctreenode in tree.traverse(addnodes.toctree):
                newnodes = []
                includefiles = map(str, toctreenode['includefiles'])
                for includefile in includefiles:
                    try:
                        self.info(darkgreen(includefile) + " ", nonl=1)
                        subtree = process_tree(
                            includefile, self.env.get_doctree(includefile))
                        self.docnames.add(includefile)
                    except Exception:
                        self.warn('%s: toctree contains ref to nonexisting file %r'\
                                                     % (docname, includefile))
                    else:
                        sof = addnodes.start_of_file(docname=includefile)
                        sof.children = subtree.children
                        newnodes.append(sof)
                toctreenode.parent.replace(toctreenode, newnodes)
            return tree

        tree = self.env.get_doctree(docname)
        tree = process_tree(docname, tree)

        self.docutils_languages = {}
        if self.config.language:
            self.docutils_languages[self.config.language] = \
                get_language_available(self.config.language)[2]

        if self.opts.get('pdf_use_index', self.config.pdf_use_index):
            # Add index at the end of the document

            # This is a hack. create_index creates an index from
            # ALL the documents data, not just this one.
            # So, we preserve a copy, use just what we need, then
            # restore it.
            #from pudb import set_trace; set_trace()
            t = copy(self.env.indexentries)
            try:
                self.env.indexentries = {
                    docname: self.env.indexentries[docname + '-gen']
                }
            except KeyError:
                self.env.indexentries = {}
                for dname in self.docnames:
                    self.env.indexentries[dname] = t.get(dname, [])
            genindex = self.env.create_index(self)
            self.env.indexentries = t
            # EOH (End Of Hack)

            if genindex:  # No point in creating empty indexes
                index_nodes = genindex_nodes(genindex)
                tree.append(
                    nodes.raw(text='OddPageBreak twoColumn', format='pdf'))
                tree.append(index_nodes)

        # This is stolen from the HTML builder's prepare_writing function
        self.domain_indices = []
        # html_domain_indices can be False/True or a list of index names
        indices_config = self.config.pdf_domain_indices
        if indices_config and hasattr(self.env, 'domains'):
            for domain in self.env.domains.itervalues():
                for indexcls in domain.indices:
                    indexname = '%s-%s' % (domain.name, indexcls.name)
                    if isinstance(indices_config, list):
                        if indexname not in indices_config:
                            continue
                    # deprecated config value
                    if indexname == 'py-modindex' and \
                           not self.config.pdf_use_modindex:
                        continue
                    content, collapse = indexcls(domain).generate()
                    if content:
                        self.domain_indices.append(
                            (indexname, indexcls, content, collapse))

        # self.domain_indices contains a list of indices to generate, like
        # this:
        # [('py-modindex',
        #    <class 'sphinx.domains.python.PythonModuleIndex'>,
        #   [(u'p', [[u'parrot', 0, 'test', u'module-parrot', 'Unix, Windows',
        #   '', 'Analyze and reanimate dead parrots.']])], True)]

        # Now this in the HTML builder is passed onto write_domain_indices.
        # We handle it right here

        for indexname, indexcls, content, collapse in self.domain_indices:
            indexcontext = dict(
                indextitle=indexcls.localname,
                content=content,
                collapse_index=collapse,
            )
            # In HTML this is handled with a Jinja template, domainindex.html
            # We have to generate docutils stuff right here in the same way.
            self.info(' ' + indexname, nonl=1)
            print

            output = ['DUMMY', '=====', '', '.. _modindex:\n\n']
            t = indexcls.localname
            t += '\n' + '=' * len(t) + '\n'
            output.append(t)

            for letter, entries in content:
                output.append('.. cssclass:: heading4\n\n%s\n\n' % letter)
                for (name, grouptype, page, anchor, extra, qualifier,
                     description) in entries:
                    if qualifier:
                        q = '[%s]' % qualifier
                    else:
                        q = ''

                    if extra:
                        e = '(%s)' % extra
                    else:
                        e = ''
                    output.append('`%s <#%s>`_ %s %s' % (name, anchor, e, q))
                    output.append('    %s' % description)
                output.append('')

            dt = docutils.core.publish_doctree('\n'.join(output))[1:]
            dt.insert(0, nodes.raw(text='OddPageBreak twoColumn',
                                   format='pdf'))
            tree.extend(dt)

        if appendices:
            tree.append(
                nodes.raw(text='OddPageBreak %s' % self.page_template,
                          format='pdf'))
            self.info()
            self.info('adding appendixes...', nonl=1)
            for docname in appendices:
                self.info(darkgreen(docname) + " ", nonl=1)
                appendix = self.env.get_doctree(docname)
                appendix['docname'] = docname
                tree.append(appendix)
            self.info('done')

        self.info()
        self.info("resolving references...")
        #print tree
        #print '--------------'
        self.env.resolve_references(tree, docname, self)
        #print tree

        for pendingnode in tree.traverse(addnodes.pending_xref):
            # This needs work, need to keep track of all targets
            # so I don't replace and create hanging refs, which
            # crash
            if pendingnode.get('reftarget',None) == 'genindex'\
                and self.config.pdf_use_index:
                pendingnode.replace_self(
                    nodes.reference(text=pendingnode.astext(),
                                    refuri=pendingnode['reftarget']))
            # FIXME: probably need to handle dangling links to domain-specific indexes
            else:
                # FIXME: This is from the LaTeX builder and I still don't understand it
                # well, and doesn't seem to work

                # resolve :ref:s to distant tex files -- we can't add a cross-reference,
                # but append the document name
                docname = pendingnode['refdocname']
                sectname = pendingnode['refsectname']
                newnodes = [nodes.emphasis(sectname, sectname)]
                for subdir, title in self.titles:
                    if docname.startswith(subdir):
                        newnodes.append(nodes.Text(_(' (in '), _(' (in ')))
                        newnodes.append(nodes.emphasis(title, title))
                        newnodes.append(nodes.Text(')', ')'))
                        break
                else:
                    pass
                pendingnode.replace_self(newnodes)
            #else:
            #pass
        return tree
    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)
Example #38
0
    def make_document(self, doc_strings):
        """make doctree representation of collected fragments"""

        opt = self.opt

        big_doc = publish_doctree("")
        self.document = big_doc
        big_doc += nodes.title(text="Plugins listing generated %s" %
                               time.asctime())

        contents = nodes.container()
        if opt.include_contents:
            big_doc += nodes.topic('', nodes.title(text='Contents'), contents)

        if not opt.no_summary:
            def_list = nodes.definition_list()
            alpha_list = nodes.paragraph()
            big_doc += nodes.section('', nodes.title(text="Plugins summary"),
                                     alpha_list, def_list)

        last_alpha = ''

        for doc in doc_strings:

            section = nodes.section()
            big_doc += section
            section += nodes.title(text=doc[0])

            self.add_ids(section)

            if not opt.no_summary:
                firstpara = (self.first_text(doc[2])
                             or nodes.paragraph(text='No summary found'))
                reference = nodes.reference('',
                                            refid=section['ids'][0],
                                            name=doc[0],
                                            anonymous=1)
                reference += nodes.Text(doc[0])
                def_list += nodes.definition_list_item(
                    '', nodes.term('', '', reference),
                    nodes.definition('', firstpara))

                # add letter quick index entry if needed
                if doc[0][0].upper() != last_alpha:
                    last_alpha = doc[0][0].upper()
                    self.add_ids(reference)
                    alpha_list += nodes.reference('',
                                                  nodes.Text(last_alpha + ' '),
                                                  refid=reference['ids'][0],
                                                  name=doc[0],
                                                  anonymous=1)

            for element in doc[2]:
                # if the docstring has titles, we need another level
                if element.tagname == 'title':
                    subsection = nodes.section()
                    section += subsection
                    section = subsection
                    break

            for element in doc[2]:
                try:
                    section += element.deepcopy()
                except TypeError:
                    err('Element.deepcopy() failed, dropped element for %s\n' %
                        doc[0])

        if opt.include_contents:
            contents.details = {'text': 'Contents here'}

            self.add_ids(big_doc)
            transform = Contents(big_doc, contents)
            transform.apply()

        return big_doc
Example #39
0
 def role(name, rawtext, text, lineno, inliner, options={}, content=[]):
     url = urlpattern.format(text)
     xtext = textpattern.format(text)
     node = nodes.reference(rawtext, xtext, refuri=url, **options)
     return [node], []
Example #40
0
def get_javadoc_ref(app, rawtext, text):
    javadoc_url_map = app.config.javadoc_url_map

    # Add default Java SE sources
    if not javadoc_url_map.get("java"):
        javadoc_url_map["java"] = ("http://docs.oracle.com/javase/6/docs/api",
                                   'javadoc')
    if not javadoc_url_map.get("javax"):
        javadoc_url_map["javax"] = ("http://docs.oracle.com/javase/6/docs/api",
                                    'javadoc')
    if not javadoc_url_map.get("org.xml"):
        javadoc_url_map["org.xml"] = (
            "http://docs.oracle.com/javase/6/docs/api", 'javadoc')
    if not javadoc_url_map.get("org.w3c"):
        javadoc_url_map["org.w3c"] = (
            "http://docs.oracle.com/javase/6/docs/api", 'javadoc')

    source = None
    package = ''
    method = None

    if '(' in text:
        # If the javadoc contains a line like this:
        # {@link #sort(List)}
        # there is no package so the text.rindex will fail
        try:
            split_point = text.rindex('.', 0, text.index('('))
            method = text[split_point + 1:]
            text = text[:split_point]
        except ValueError:
            pass

    for pkg, (baseurl, ext_type) in javadoc_url_map.items():
        if text.startswith(pkg + '.') and len(pkg) > len(package):
            source = baseurl, ext_type
            package = pkg

    if not source:
        return None

    baseurl, ext_type = source

    package_parts = []
    cls_parts = []

    for part in text.split('.'):
        if cls_parts or part[0].isupper():
            cls_parts.append(part)
        else:
            package_parts.append(part)

    package = '.'.join(package_parts)
    cls = '.'.join(cls_parts)

    if not baseurl.endswith('/'):
        baseurl = baseurl + '/'

    if ext_type == 'javadoc':
        if not cls:
            cls = 'package-summary'
        source = baseurl + package.replace('.', '/') + '/' + cls + '.html'
        if method:
            source = source + '#' + method
    elif ext_type == 'sphinx':
        if not cls:
            cls = 'package-index'
        source = baseurl + package.replace('.', '/') + '/' + cls.replace(
            '.', '-') + '.html'
        if method:
            source = source + '#' + package + '.' + cls + '.' + method
    else:
        raise ValueError('invalid target specifier ' + ext_type)

    title = '.'.join(filter(None, (package, cls, method)))
    node = nodes.reference(rawtext, '')
    node['refuri'] = source
    node['reftitle'] = title

    return node
Example #41
0
def source_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
    has_t, title, target = split_explicit_title(text)
    title = utils.unescape(title)
    target = utils.unescape(target)
    refnode = nodes.reference(title, title, refuri=SOURCE_URI % target)
    return [refnode], []
Example #42
0
def issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
    issue = utils.unescape(text)
    text = 'bpo-' + issue
    refnode = nodes.reference(text, text, refuri=ISSUE_URI % issue)
    return [refnode], []
Example #43
0
    def get_reference_node(self, ref):
        node = nodes.inline(' ', ' ', classes=[ref.type, 'bibcite'])

        namestyler = pybtex.style.names.plain.NameStyle()
        namestyler = pybtex.style.names.lastfirst.NameStyle()
        plaintext = pybtex.backends.plaintext.Backend()

        # Authors
        authors = ref.persons.get('author', [])
        for i, author in enumerate(authors):
            authortext = namestyler.format(
                author, abbr=True).format().render(plaintext)
            authortext = authortext.replace('{', '')
            authortext = authortext.replace('}', '')
            authortext = authortext.decode('latex')
            text = authortext

            text = text.strip()
            auth_node = latex_to_nodes(text)
            auth_node['classes'].append('author')
            node += auth_node

            if i + 1 < len(authors):
                node += nodes.inline(', ', ', ')
            else:
                ending = '%s  ' % ('' if text.endswith('.') else '.')
                node += nodes.inline(ending, ending)

        # Title
        title = ref.fields.get('title')
        if title is None:
            title = ref.fields.get('key')
        if title:
            title = title.decode('latex')
            title = title.replace('{', '')
            title = title.replace('}', '')
            node += nodes.inline(title, title, classes=['bib_title'])
            node += nodes.inline('.  ', '.  ')

        # @phdthesis
        if ref.type == 'phdthesis':
            school = ref.fields.get('school')
            school = school.decode('latex')
            text = 'PhD Thesis, %s, ' % school
            node += nodes.inline(text, text)

        # Publication
        pub = ref.fields.get('journal')
        if not pub:
            pub = ref.fields.get('booktitle')
        if pub:
            pub = pub.decode('latex')
            pub = pub.replace('{', '')
            pub = pub.replace('}', '')
            node += nodes.emphasis(pub, pub, classes=['publication'])
            node += nodes.inline(' ', ' ')

        vol = ref.fields.get('volume')
        pages = ref.fields.get('pages')
        year = ref.fields.get('year')
        url = ref.fields.get('url')

        if pub is None:
            howpub = ref.fields.get('howpublished')
            if howpub is not None and howpub.startswith('\url{'):
                url = howpub[5:-1]
                refnode = nodes.reference('', '', internal=False, refuri=url)
                refnode += nodes.Text(url, url)
                node += refnode
                if vol or pages or year:
                    node += nodes.inline(', ', ', ')

        if vol:
            vol = vol.decode('latex')
            node += nodes.inline(vol, vol, classes=['bib_vol'])
            node += nodes.inline(':', ':')

        if pages:
            pages = pages.decode('latex')
            node += nodes.inline(pages, pages, classes=['pages'])

        if year:
            year = year.decode('latex')
            node += nodes.inline(' (', ' (')
            node += nodes.inline(year, year, classes=['year'])
            node += nodes.inline(')', ')')

        if pub is not None and url:
            if url.startswith('{') and url.endswith('}'):
                url = url[1:-1]
            refnode = nodes.reference('', '', internal=False, refuri=url)
            node += nodes.inline(' ', ' ')
            refnode += nodes.Text(url, url)
            node += refnode

        node += nodes.inline('.', '.')
        return node
Example #44
0
def url_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
    uri = text
    display = 'url'
    node = nodes.literal('', '')
    node += nodes.reference(rawtext, name, refuri=uri, **options)
    return [node], []
    def run(self):
        """
        builds the todo text
        """
        sett = self.state.document.settings
        language_code = sett.language_code
        lineno = self.lineno

        env = self.state.document.settings.env if hasattr(
            self.state.document.settings, "env") else None
        docname = None if env is None else env.docname
        if docname is not None:
            docname = docname.replace("\\", "/").split("/")[-1]
            legend = "{0}:{1}".format(docname, lineno)
        else:
            legend = ''

        if not self.options.get('class'):
            self.options['class'] = ['admonition-todoext']

        # link to issue
        issue = self.options.get('issue', "").strip()
        if issue is not None and len(issue) > 0:
            if hasattr(sett, "extlinks"):
                extlinks = sett.extlinks
            elif env is not None and hasattr(env.config, "extlinks"):
                extlinks = env.config.extlinks
            else:  # pragma: no cover
                available = "\n".join(sorted(sett.__dict__.keys()))
                available2 = "\n".join(sorted(
                    env.config.__dict__.keys())) if env is not None else "-"
                mes = (
                    "extlinks (wih a key 'issue') is not defined in the "
                    "documentation settings, available in sett\n{0}\nCONFIG\n{1}"
                )
                raise ValueError(  # pragma: no cover
                    mes.format(available, available2))

            if "issue" not in extlinks:
                raise KeyError(  # pragma: no cover
                    "key 'issue' is not present in extlinks")
            url, label = extlinks["issue"]
            url = url % str(issue)
            lab = label.format(issue)
            linkin = nodes.reference(lab, locale_(lab), refuri=url)
            link = nodes.paragraph()
            link += linkin
        else:
            link = None

        # cost
        cost = self.options.get('cost', "").strip()
        if cost:  # pragma: no cover
            try:
                fcost = float(cost)
            except ValueError:
                raise ValueError(
                    "unable to convert cost '{0}' into float".format(cost))
        else:
            fcost = 0.0

        # priority
        prio = self.options.get('priority', "").strip()

        # hidden
        hidden = self.options.get(
            'hidden', "false").strip().lower() in {'true', '1', ''}

        # body
        (todoext, ) = super(TodoExt, self).run()
        if isinstance(todoext, nodes.system_message):
            return [todoext]

        # link
        if link:
            todoext += link

        # title
        title = self.options.get('title', "").strip()
        todotag = self.options.get('tag', '').strip()
        if len(title) > 0:
            title = ": " + title

        # prefix
        prefix = TITLES[language_code]["todo"]
        tododate = self.options.get('date', "").strip()
        todorelease = self.options.get('release', "").strip()
        infos = []
        if len(todotag) > 0:
            infos.append(todotag)
        if len(prio) > 0:
            infos.append('P=%s' % prio)
        if fcost > 0:
            if int(fcost) == fcost:
                infos.append('C=%d' % int(fcost))
            else:
                infos.append('C=%1.1f' % fcost)
        if todorelease:
            infos.append('v{0}'.format(todorelease))
        if tododate:
            infos.append(tododate)
        if infos:
            prefix += "({0})".format(" - ".join(infos))

        # main node
        title = nodes.title(text=locale_(prefix + title))
        todoext.insert(0, title)
        todoext['todotag'] = todotag
        todoext['todocost'] = fcost
        todoext['todoprio'] = prio
        todoext['todohidden'] = hidden
        todoext['tododate'] = tododate
        todoext['todorelease'] = todorelease
        todoext['todotitle'] = self.options.get('title', "").strip()
        set_source_info(self, todoext)

        if hidden:
            todoext['todoext_copy'] = todoext.deepcopy()
            todoext.clear()

        if env is not None:
            targetid = 'indextodoe-%s' % env.new_serialno('indextodoe')
            targetnode = nodes.target(legend, '', ids=[targetid])
            set_source_info(self, targetnode)
            self.state.add_target(targetid, '', targetnode, lineno)

            # index node
            index = self.options.get('index', None)
            if index is not None:
                indexnode = addnodes.index()
                indexnode['entries'] = ne = []
                indexnode['inline'] = False
                set_source_info(self, indexnode)
                for entry in index.split(","):
                    ne.extend(process_index_entry(entry, targetid))
            else:
                indexnode = None
        else:
            targetnode = None
            indexnode = None

        return [a for a in [indexnode, targetnode, todoext] if a is not None]
Example #46
0
def missing_reference(app, env, node, contnode):
    # type: (Sphinx, BuildEnvironment, nodes.Node, nodes.Node) -> None
    """Attempt to resolve a missing reference via intersphinx references."""
    target = node['reftarget']
    inventories = InventoryAdapter(env)
    objtypes = None  # type: List[unicode]
    if node['reftype'] == 'any':
        # we search anything!
        objtypes = ['%s:%s' % (domain.name, objtype)
                    for domain in env.domains.values()
                    for objtype in domain.object_types]
        domain = None
    else:
        domain = node.get('refdomain')
        if not domain:
            # only objects in domains are in the inventory
            return
        objtypes = env.get_domain(domain).objtypes_for_role(node['reftype'])
        if not objtypes:
            return
        objtypes = ['%s:%s' % (domain, objtype) for objtype in objtypes]
    if 'std:cmdoption' in objtypes:
        # until Sphinx-1.6, cmdoptions are stored as std:option
        objtypes.append('std:option')
    to_try = [(inventories.main_inventory, target)]
    if domain:
        full_qualified_name = env.get_domain(domain).get_full_qualified_name(node)
        if full_qualified_name:
            to_try.append((inventories.main_inventory, full_qualified_name))
    in_set = None
    if ':' in target:
        # first part may be the foreign doc set name
        setname, newtarget = target.split(':', 1)
        if setname in inventories.named_inventory:
            in_set = setname
            to_try.append((inventories.named_inventory[setname], newtarget))
            if domain:
                node['reftarget'] = newtarget
                full_qualified_name = env.get_domain(domain).get_full_qualified_name(node)
                if full_qualified_name:
                    to_try.append((inventories.named_inventory[setname], full_qualified_name))
    for inventory, target in to_try:
        for objtype in objtypes:
            if objtype not in inventory or target not in inventory[objtype]:
                continue
            proj, version, uri, dispname = inventory[objtype][target]
            if '://' not in uri and node.get('refdoc'):
                # get correct path in case of subdirectories
                uri = path.join(relative_path(node['refdoc'], '.'), uri)
            if version:
                reftitle = _('(in %s v%s)') % (proj, version)
            else:
                reftitle = _('(in %s)') % (proj,)
            newnode = nodes.reference('', '', internal=False, refuri=uri, reftitle=reftitle)
            if node.get('refexplicit'):
                # use whatever title was given
                newnode.append(contnode)
            elif dispname == '-' or \
                    (domain == 'std' and node['reftype'] == 'keyword'):
                # use whatever title was given, but strip prefix
                title = contnode.astext()
                if in_set and title.startswith(in_set + ':'):
                    newnode.append(contnode.__class__(title[len(in_set) + 1:],
                                                      title[len(in_set) + 1:]))
                else:
                    newnode.append(contnode)
            else:
                # else use the given display name (used for :ref:)
                newnode.append(contnode.__class__(dispname, dispname))
            return newnode
    # at least get rid of the ':' in the target if no explicit title given
    if in_set is not None and not node.get('refexplicit', True):
        if len(contnode) and isinstance(contnode[0], nodes.Text):
            contnode[0] = nodes.Text(newtarget, contnode[0].rawsource)
Example #47
0
    def cite(self, cmd, refuri, global_keys=None):
        """
    Return a docutils Node consisting of properly formatted citations children
    nodes.
    """
        if global_keys is not None:
            self.global_keys = global_keys
        bo, bc = self.config['brackets']
        sep = u'%s ' % self.config['separator']
        style = self.config['style']
        all_auths = (cmd.endswith('s'))
        alt = (cmd.startswith('alt') or \
                    (cmd.startswith('alp')) or \
                    (style == 'citeyear'))

        if (cmd.startswith('p') or cmd == 'yearpar') and style != 'super':
            node = nodes.inline(bo, bo, classes=['citation'])
        else:
            node = nodes.inline('', '', classes=['citation'])

        if self.pre:
            pre = u"%s " % self.pre.decode('latex')
            node += nodes.inline(pre, pre, classes=['pre'])

        for i, ref in enumerate(self.refs):
            authors = ref.persons.get('author', [])
            author_text = self.get_author(authors, all_auths).decode('latex')
            lrefuri = refuri + '#citation-' + nodes.make_id(ref.key)

            if i > 0 and i < len(self.refs):
                if style == "authoryear":
                    node += nodes.inline(sep, sep)
                else:
                    if style == "super":
                        node += nodes.superscript(', ', ', ')
                    else:
                        node += nodes.inline(', ', ', ')

            if cmd == 'title':
                title = ref.fields.get('title')
                if title is None:
                    title = ref.fields.get('key', '')
                author_text = title

            if (style == "authoryear" and (cmd.startswith('p') or cmd.startswith('alp'))) or \
               (cmd.startswith('t') or cmd.startswith('alt') or cmd.startswith('author')):
                node += nodes.reference(author_text,
                                        author_text,
                                        internal=True,
                                        refuri=lrefuri)

                if cmd.startswith('p') or cmd.startswith('alp'):
                    node += nodes.inline(', ', ', ')
                else:
                    node += nodes.inline(' ', ' ')

            # Add in either the year or the citation number
            if cmd == 'title':
                pass
            elif cmd.startswith('author'):
                pass
            else:
                if style != 'authoryear':
                    num = self.get_ref_num(ref.key)
                else:
                    num = ref.fields.get('year')

                refnode = nodes.reference(str(num),
                                          str(num),
                                          internal=True,
                                          refuri=lrefuri)

                if cmd.startswith('t') and style != 'super':
                    node += nodes.inline(bo, bo)

                if style == 'super':
                    node += nodes.superscript('', '', refnode)
                else:
                    node += refnode

                if cmd.startswith('t') and style != 'super':
                    node += nodes.inline(bc, bc)

        if self.post:
            post = u", %s" % self.post.decode('latex')
            node += nodes.inline(post, post, classes=['post'])

        if (cmd.startswith('p') or cmd == 'yearpar') and style != 'super':
            node += nodes.inline(bc, bc, classes=['citation'])

        return node
Example #48
0
    def run(self):
        env = self.state.document.settings.env

        items = []

        data = list(csv.reader(self.content))
        for row in data:
            if not row:
                continue
            name, page, image = row
            link = page.strip()
            if not link.startswith('http') and not link.startswith('/'):
                link = '/{}'.format(link)
            if '.html' not in link:
                link += '.html'
            items.append({
                'name': name.strip(),
                'link': link,
                'image': '/images/{}'.format(image.strip()),
            })

        col_widths = self.get_column_widths(3)
        title, messages = self.make_title()
        table = nodes.table()

        # Set up column specifications based on widths
        tgroup = nodes.tgroup(cols=3)
        table += tgroup
        tgroup.extend(
            nodes.colspec(colwidth=col_width) for col_width in col_widths)

        tbody = nodes.tbody()
        tgroup += tbody
        rows = []
        for value in grouper(3, items):
            trow = nodes.row()
            for cell in value:
                entry = nodes.entry()
                if cell is None:
                    entry += nodes.paragraph()
                    trow += entry
                    continue
                name = cell['name']
                link = cell['link']
                image = cell['image']
                reference_node = nodes.reference(refuri=link)
                img = nodes.image(uri=directives.uri(image), alt=name)
                img['classes'].append('component-image')
                reference_node += img
                para = nodes.paragraph()
                para += reference_node
                entry += para
                trow += entry
            rows.append(trow)

            trow = nodes.row()
            for cell in value:
                entry = nodes.entry()
                if cell is None:
                    entry += nodes.paragraph()
                    trow += entry
                    continue
                name = cell['name']
                link = cell['link']
                ref = nodes.reference(name, name, refuri=link)
                para = nodes.paragraph()
                para += ref
                entry += para
                trow += entry
            rows.append(trow)
        tbody.extend(rows)

        table['classes'] += []
        self.add_name(table)
        if title:
            table.insert(0, title)

        return [table] + messages
Example #49
0
def pegboard_directive(*args):

    pegtable = build_pegtable()
    pegtable.sort(pegcmp)

    # Python doesn't like this, as 'class' is reserved
    # table = nodes.table(class='pegboard')
    table = nodes.table()
    table['class'] = 'pegboard'
    tgroup = nodes.tgroup(cols=6)
    table += tgroup

    thead = nodes.thead()
    tgroup += thead
    row = nodes.row()
    thead += row

    for col in ['Status', 'Name', 'Topic', 'Authors',
                'Stakeholders', 'Files']:
        entry = nodes.entry()
        row += entry
        para = nodes.paragraph()
        entry += para
        para += nodes.Text(col)

    tbody = nodes.tbody()
    tgroup += tbody

    for peg in pegtable:
        status = peg['status'].split()

        row = nodes.row()
        if status:
            peg_class = 'peg-' + status[0].lower()
            # Python doesn't like this, as 'class' is reserved
            # row = nodes.row(class=peg_class)
            row['class'] = peg_class
            
        tbody += row

        def get_author(s):
            if config.pegboard_authors.has_key(s):
                return config.pegboard_authors[s]
            else: return s

        _authors = [get_author(s) for s in peg['authors']]
        _stakeholders = [get_author(s) for s in peg['stakeholders']]

        ref = nodes.reference(refuri=peg['dir']+'/'+peg['html'])
        text = nodes.Text(peg['dir'].split('--')[0])
        ref += text

        status_field = peg['status'].split()
        status_comment = nodes.Text(string.join(status_field[1:]))
        status_emph = nodes.emphasis()
        status_emph += status_comment
        
        status = [
            nodes.Text(status_field[0] + ' '),
            status_emph
        ]
        
        # massive uglification here because cpython doesn't like 
        # the use of the reserved word 'class'. ;-/. Gotta think of
        # something cuter.
        #row += td(status, class='peg_status_field')
        #row += td(ref, class='peg_name_field')
        #row += td(peg['topic'].split(':')[-1], class='peg_topic_field')
        #row += td(string.join(_authors, ', '), class='peg_authors_field')
        #row += td(string.join(_stakeholders, ', '), class='peg_stakeholders_field')
	temp = td(status); temp['class'] = 'peg_status_field'
        row += temp

        temp = td(ref); temp['class'] = 'peg_name_field'
        row += temp

        temp = td(peg['topic'].split(':')[-1]); temp['class'] = 'peg_topic_field'
        row += temp

        temp = td(string.join(_authors, ', ')); temp['class'] = 'peg_authors_field'
        row += temp

        temp = td(string.join(_stakeholders, ', ')); temp['class'] = 'peg_stakeholders_field'
        row += temp

        row += make_files(peg)
    
    return [table]
def process_todoext_nodes(app, doctree, fromdocname):
    """
    process_todoext_nodes
    """
    if not app.config['todoext_include_todosext']:
        for node in doctree.traverse(todoext_node):
            node.parent.remove(node)

    # Replace all todoextlist nodes with a list of the collected todosext.
    # Augment each todoext with a backlink to the original location.
    env = app.builder.env
    if hasattr(env, "settings") and hasattr(env.settings, "language_code"):
        lang = env.settings.language_code
    else:
        lang = "en"

    orig_entry = TITLES[lang]["original entry"]
    todomes = TITLES[lang]["todomes"]
    allowed_tsort = {'date', 'prio', 'title', 'release', 'source'}

    if not hasattr(env, 'todoext_all_todosext'):
        env.todoext_all_todosext = []

    for ilist, node in enumerate(doctree.traverse(todoextlist)):
        if 'ids' in node:
            node['ids'] = []
        if not app.config['todoext_include_todosext']:
            node.replace_self([])
            continue

        nbtodo = 0
        fcost = 0
        content = []
        todotag = node["todotag"]
        tsort = node["todosort"]
        if tsort == '':
            tsort = 'source'
        if tsort not in allowed_tsort:
            raise ValueError("option sort must in {0}, '{1}' is not".format(
                allowed_tsort, tsort))

        double_list = [(info.get('todo%s' % tsort,
                                 ''), info.get('todotitle', ''), info)
                       for info in env.todoext_all_todosext]
        double_list.sort(key=lambda x: x[:2])
        for n, todoext_info_ in enumerate(double_list):
            todoext_info = todoext_info_[2]
            if todoext_info["todotag"] != todotag:
                continue

            nbtodo += 1
            fcost += todoext_info.get("todocost", 0.0)

            para = nodes.paragraph(classes=['todoext-source'])
            if app.config['todoext_link_only']:
                description = locale_('<<%s>>' % orig_entry)
            else:
                description = (
                    locale_(todomes) %
                    (orig_entry, os.path.split(
                        todoext_info['source'])[-1], todoext_info['lineno']))
            desc1 = description[:description.find('<<')]
            desc2 = description[description.find('>>') + 2:]
            para += nodes.Text(desc1, desc1)

            # Create a reference
            newnode = nodes.reference('', '', internal=True)
            innernode = nodes.emphasis('', locale_(orig_entry))
            try:
                newnode['refuri'] = app.builder.get_relative_uri(
                    fromdocname, todoext_info['docname'])
                try:
                    newnode['refuri'] += '#' + todoext_info['target']['refid']
                except Exception as e:  # pragma: no cover
                    raise KeyError("refid in not present in '{0}'".format(
                        todoext_info['target'])) from e
            except NoUri:  # pragma: no cover
                # ignore if no URI can be determined, e.g. for LaTeX output
                pass
            newnode.append(innernode)
            para += newnode
            para += nodes.Text(desc2, desc2)

            # (Recursively) resolve references in the todoext content
            todoext_entry = todoext_info.get('todoext_copy', None)
            if todoext_entry is None:
                todoext_entry = todoext_info['todoext']
            todoext_entry["ids"] = ["index-todoext-%d-%d" % (ilist, n)]
            # it apparently requires an attributes ids

            if not hasattr(todoext_entry, "settings"):
                todoext_entry.settings = Values()
                todoext_entry.settings.env = env
            # If an exception happens here, see blog 2017-05-21 from the
            # documentation.
            env.resolve_references(todoext_entry, todoext_info['docname'],
                                   app.builder)

            # Insert into the todoextlist
            content.append(todoext_entry)
            content.append(para)

        if fcost > 0:  # pragma: no cover
            cost = nodes.paragraph()
            lab = "{0} items, cost: {1}".format(nbtodo, fcost)
            cost += nodes.Text(lab)
            content.append(cost)
        else:
            cost = nodes.paragraph()
            lab = "{0} items".format(nbtodo)
            cost += nodes.Text(lab)
            content.append(cost)

        node.replace_self(content)
Example #51
0
def process_postlist(app, doctree, docname):
    """Replace `PostList` nodes with lists of posts. Also, register all posts
    if they have not been registered yet."""

    blog = Blog(app)
    if not blog:
        register_posts(app)

    for node in doctree.traverse(PostList):
        colls = []
        for cat in ['tags', 'author', 'category', 'location', 'language']:
            for coll in node[cat]:
                if coll in blog.catalogs[cat].collections:
                    colls.append(blog.catalogs[cat].collections[coll])

        if colls:
            posts = set(blog.posts)
            for coll in colls:
                posts = posts & set(coll)
            posts = list(posts)
            posts.sort(reverse=True)
            posts = posts[:node.attributes['length']]
        else:
            posts = list(blog.recent(node.attributes['length'], docname,
                                     **node.attributes))

        if node.attributes['sort']:
            posts.sort()  # in reverse chronological order, so no reverse=True

        fmts = list(Formatter().parse(node.attributes['format']))
        not_in = set(['date', 'title', 'author', 'location', 'language',
                      'category', 'tags', None])
        for text, key, __, __ in fmts:
            if key not in not_in:
                raise KeyError('{} is not recognized in postlist format'
                               .format(key))

        excerpts = node.attributes['excerpts']
        date_format = node.attributes['date'] or _(blog.post_date_format_short)
        bl = nodes.bullet_list()
        bl.attributes['classes'].append('postlist-style-' + node['list-style'])
        bl.attributes['classes'].append('postlist')
        for post in posts:
            bli = nodes.list_item()
            bl.append(bli)
            par = nodes.paragraph()
            bli.append(par)

            for text, key, __, __ in fmts:
                if text:
                    par.append(nodes.Text(text))
                if key is None:
                    continue
                if key == 'date':
                    par.append(nodes.Text(post.date.strftime(date_format)))
                else:
                    if key == 'title':
                        items = [post]
                    else:
                        items = getattr(post, key)

                    for i, item in enumerate(items, start=1):
                        if key == 'title':
                            ref = nodes.reference()
                            ref['refuri'] = app.builder.get_relative_uri(docname, item.docname)
                            ref['ids'] = []
                            ref['backrefs'] = []
                            ref['dupnames'] = []
                            ref['classes'] = []
                            ref['names'] = []
                            ref['internal'] = True
                            ref.append(nodes.Text(text_type(item)))
                        else:
                            ref = _missing_reference(app, item.xref, docname)
                        par.append(ref)
                        if i < len(items):
                            par.append(nodes.Text(', '))
            if excerpts and post.excerpt:
                for enode in post.excerpt:
                    enode = enode.deepcopy()
                    revise_pending_xrefs(enode, docname)
                    app.env.resolve_references(enode, docname, app.builder)
                    enode.parent = bli.parent
                    bli.append(enode)

        node.replace_self(bl)
Example #52
0
 def role(name, rawtext, text, lineno, inliner, options={}, content=[]):
     url = pattern % (text, )
     node = nodes.reference(rawtext, text, refuri=url, **options)
     return [node], []
Example #53
0
 def build_toc(node, depth=1):
     # type: (nodes.Node, int) -> List[nodes.Node]
     entries = []
     for sectionnode in node:
         # find all toctree nodes in this section and add them
         # to the toc (just copying the toctree node which is then
         # resolved in self.get_and_resolve_doctree)
         if isinstance(sectionnode, addnodes.only):
             onlynode = addnodes.only(expr=sectionnode['expr'])
             blist = build_toc(sectionnode, depth)
             if blist:
                 onlynode += blist.children  # type: ignore
                 entries.append(onlynode)
             continue
         if not isinstance(sectionnode, nodes.section):
             # Extension code starts here.
             for tabnode in traverse_in_section(
                 sectionnode, nxt_tab_head):
                 if tabnode.tab_toc:
                     nodetext = [nodes.Text(tabnode)]
                     anchorname = '#' + tabnode.label_id
                     numentries[0] += 1
                     reference = nodes.reference(
                         '', '', internal=True, refuri=docname,
                         anchorname=anchorname, *nodetext)
                     para = addnodes.compact_paragraph('', '',
                                                       reference)
                     item = nodes.list_item('', para)
                     entries.append(item)
             # Extension code ends here.
             for toctreenode in traverse_in_section(sectionnode,
                                                    addnodes.toctree):
                 item = toctreenode.copy()
                 entries.append(item)
                 # important: do the inventory stuff
                 TocTree(app.env).note(docname, toctreenode)
             continue
         title = sectionnode[0]
         # copy the contents of the section title, but without references
         # and unnecessary stuff
         visitor = SphinxContentsFilter(doctree)
         title.walkabout(visitor)
         nodetext = visitor.get_entry_text()
         if not numentries[0]:
             # for the very first toc entry, don't add an anchor
             # as it is the file's title anyway
             anchorname = ''
         else:
             anchorname = '#' + sectionnode['ids'][0]
         numentries[0] += 1
         # make these nodes:
         # list_item -> compact_paragraph -> reference
         reference = nodes.reference(
             '', '', internal=True, refuri=docname,
             anchorname=anchorname, *nodetext)
         para = addnodes.compact_paragraph('', '', reference)
         item = nodes.list_item('', para)
         sub_item = build_toc(sectionnode, depth + 1)
         item += sub_item
         entries.append(item)
     if entries:
         return nodes.bullet_list('', *entries)
     return []
Example #54
0
def find_sage_dangling_links(app, env, node, contnode):
    """
    Try to find dangling link in local module imports or all.py.
    """
    debug_inf(app, "==================== find_sage_dangling_links ")

    reftype = node['reftype']
    reftarget  = node['reftarget']
    try:
        doc = node['refdoc']
    except KeyError:
        debug_inf(app, "-- no refdoc in node %s"%node)
        return None

    debug_inf(app, "Searching %s from %s"%(reftarget, doc))

    # Workaround: in Python's doc 'object', 'list', ... are documented as a
    # function rather than a class
    if reftarget in base_class_as_func and reftype == 'class':
        node['reftype'] = 'func'

    res = call_intersphinx(app, env, node, contnode)
    if res:
        debug_inf(app, "++ DONE %s"%(res['refuri']))
        return res

    if node.get('refdomain') != 'py': # not a python file
       return None

    try:
        module = node['py:module']
        cls    = node['py:class']
    except KeyError:
        debug_inf(app, "-- no module or class for :%s:%s"%(reftype, reftarget))
        return None

    basename = reftarget.split(".")[0]
    try:
        target_module = getattr(sys.modules['sage.all'], basename).__module__
    except AttributeError:
        debug_inf(app, "-- %s not found in sage.all"%(basename))
        return None
    if target_module is None:
        target_module = ""
        debug_inf(app, "?? found in None !!!")

    debug_inf(app, "++ found %s using sage.all in %s"%(basename, target_module))

    newtarget = target_module+'.'+reftarget
    node['reftarget'] = newtarget

    # adapted  from sphinx/domains/python.py
    builder = app.builder
    searchmode = node.hasattr('refspecific') and 1 or 0
    matches =  builder.env.domains['py'].find_obj(
        builder.env, module, cls, newtarget, reftype, searchmode)
    if not matches:
        debug_inf(app, "?? no matching doc for %s"%newtarget)
        return call_intersphinx(app, env, node, contnode)
    elif len(matches) > 1:
        env.warn(target_module,
                 'more than one target found for cross-reference '
                 '%r: %s' % (newtarget,
                             ', '.join(match[0] for match in matches)),
                 node.line)
    name, obj = matches[0]
    debug_inf(app, "++ match = %s %s"%(name, obj))

    from docutils import nodes
    newnode = nodes.reference('', '', internal=True)
    if name == target_module:
        newnode['refid'] = name
    else:
        newnode['refuri'] = builder.get_relative_uri(node['refdoc'], obj[0])
        newnode['refuri'] += '#' + name
        debug_inf(app, "++ DONE at URI %s"%(newnode['refuri']))
    newnode['reftitle'] = name
    newnode.append(contnode)
    return newnode
Example #55
0
    def run(self):
        repo = self.arguments[0]
        env = self.state.document.settings.env

        try:
            repo_user, repo_name = repo.split('/')
            repo = gh.repository(repo_user, repo_name)
        except Exception as e:
            raise self.error("GitHub API error: %s" % e.message)

        tpl = gh_repo_tpl
        html = tpl.format(**repo.__dict__)

        if not hasattr(env, 'github_repo_all_repos'):
            env.github_repo_all_repos = []
            env.github_repo_all_repos.append({
                'docname': env.docname,
                'lineno': self.lineno,
                'repo': repo,
            })

        repo_link = nodes.reference('', 'github', refuri=repo.html_url)

        title = nodes.paragraph()
        title += repo_link,
        if 'travis' in self.options:
            title += nodes.inline('', ' - ')
            title += nodes.reference(
                '', 'travis', refuri=self.options.get('travis'))

        if 'docs' in self.options:
            title += nodes.inline('', ' - ')
            title += nodes.reference(
                '', 'docs', refuri=self.options.get('docs'))

        if 'api' in self.options:
            title += nodes.inline('', ' - ')
            title += nodes.reference(
                '', 'api', refuri=self.options.get('api'))

        if 'pypi' in self.options:
            title += nodes.inline('', ' - ')
            title += nodes.reference(
                '', 'pypi', refuri=self.options.get('pypi'))

        if 'homepage' in self.options:
            title += nodes.inline('', ' - ')
            title += nodes.reference(
                '', 'homepage', refuri=self.options.get('homepage'))

        if repo.watchers > 10:
            title += nodes.inline('', ' - %s watchers' % str(repo.watchers))

        if repo.forks > 10:
            title += nodes.inline('', ' -  %s forks' % str(repo.forks))

        new_nodes = [title]

        if 'use_gh_description' in self.options:
            new_nodes.append(nodes.paragraph('', repo.description))

        return new_nodes
Example #56
0
 def apply(self):
     if not len(self.document):
         # @@@ replace these DataErrors with proper system messages
         raise DataError('Document tree is empty.')
     header = self.document[0]
     if not isinstance(header, nodes.field_list) or \
           'rfc2822' not in header['classes']:
         raise DataError('Document does not begin with an RFC-2822 '
                         'header; it is not a PEP.')
     pep = None
     for field in header:
         if field[0].astext().lower() == 'pep': # should be the first field
             value = field[1].astext()
             try:
                 pep = int(value)
                 cvs_url = self.pep_cvs_url % pep
             except ValueError:
                 pep = value
                 cvs_url = None
                 msg = self.document.reporter.warning(
                     '"PEP" header must contain an integer; "%s" is an '
                     'invalid value.' % pep, base_node=field)
                 msgid = self.document.set_id(msg)
                 prb = nodes.problematic(value, value or '(none)',
                                         refid=msgid)
                 prbid = self.document.set_id(prb)
                 msg.add_backref(prbid)
                 if len(field[1]):
                     field[1][0][:] = [prb]
                 else:
                     field[1] += nodes.paragraph('', '', prb)
             break
     if pep is None:
         raise DataError('Document does not contain an RFC-2822 "PEP" '
                         'header.')
     if pep == 0:
         # Special processing for PEP 0.
         pending = nodes.pending(PEPZero)
         self.document.insert(1, pending)
         self.document.note_pending(pending)
     if len(header) < 2 or header[1][0].astext().lower() != 'title':
         raise DataError('No title!')
     for field in header:
         name = field[0].astext().lower()
         body = field[1]
         if len(body) > 1:
             raise DataError('PEP header field body contains multiple '
                             'elements:\n%s' % field.pformat(level=1))
         elif len(body) == 1:
             if not isinstance(body[0], nodes.paragraph):
                 raise DataError('PEP header field body may only contain '
                                 'a single paragraph:\n%s'
                                 % field.pformat(level=1))
         elif name == 'last-modified':
             date = time.strftime(
                   '%d-%b-%Y',
                   time.localtime(os.stat(self.document['source'])[8]))
             if cvs_url:
                 body += nodes.paragraph(
                     '', '', nodes.reference('', date, refuri=cvs_url))
         else:
             # empty
             continue
         para = body[0]
         if name == 'author':
             for node in para:
                 if isinstance(node, nodes.reference):
                     node.replace_self(mask_email(node))
         elif name == 'discussions-to':
             for node in para:
                 if isinstance(node, nodes.reference):
                     node.replace_self(mask_email(node, pep))
         elif name in ('replaces', 'replaced-by', 'requires'):
             newbody = []
             space = nodes.Text(' ')
             for refpep in re.split(r',?\s+', body.astext()):
                 pepno = int(refpep)
                 newbody.append(nodes.reference(
                     refpep, refpep,
                     refuri=(self.document.settings.pep_base_url
                             + self.pep_url % pepno)))
                 newbody.append(space)
             para[:] = newbody[:-1] # drop trailing space
         elif name == 'last-modified':
             utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions)
             if cvs_url:
                 date = para.astext()
                 para[:] = [nodes.reference('', date, refuri=cvs_url)]
         elif name == 'content-type':
             pep_type = para.astext()
             uri = self.document.settings.pep_base_url + self.pep_url % 12
             para[:] = [nodes.reference('', pep_type, refuri=uri)]
         elif name == 'version' and len(body):
             utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions)
Example #57
0
def github_pr_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
    """Here are some docs.

    :param rawtext: Text being replaced with link node.
    :param app: Sphinx application context
    :param type: Link type (issue, changeset, etc.)
    :param slug: ID of the thing to link to
    :param options: Options dictionary passed to role func.
    """

    try:
        pr = text
        if not pr or len(pr) <= 0 or not isinstance(text, basestring):
            raise ValueError
    except ValueError:
        msg = inliner.reporter.error(
            'pull request should be in the format of /:user/:repo/pull/:pull_id'
            '"%s" is invalid.' % text, line=lineno)
        prb = inliner.problematic(rawtext, rawtext, msg)
        return [prb], [msg]

    set_classes(options)

    repo_user, repo_name, pull, pull_id = pr.split('/')

    repo = gh.repository(repo_user, repo_name)
    pull = repo.pull_request(pull_id)

    tpl = gh_pr_tpl
    attributes = pull.__dict__
    attributes['repo_name'] = pull.repository[1]
    pr_details = gh_pr_tpl.format(attributes)

    # <a href={{repo.html_url}}>repo_name</a>
    repo_link = nodes.reference(
        rawtext, repo_name, refuri=repo.html_url, **options)
    # <em>pull.title</em>
    pr_title_emphasized = nodes.emphasis(rawtext, pull.title, **options)
    # ./tpl/gh_pr.rst
    pr_details_node = nodes.emphasis(rawtext, pr_details, **options)
    pr_number_link = nodes.reference(rawtext, '#' + str(
        pull.number), refuri=pull.html_url, **options)
    pr_additions = nodes.inline(rawtext, str(pull.additions) + ' additions(+)')
    pr_deletions = nodes.inline(rawtext, str(pull.deletions) + ' deletions(-)')
    pr_created_at = nodes.inline(rawtext, pull.created_at.strftime('%Y-%m-%d'))

    title = nodes.paragraph()
    title += repo_link,
    title += nodes.inline(rawtext, ' ')
    title += nodes.inline(rawtext, ' (')
    title += pr_number_link
    title += nodes.inline(rawtext, ') ')
    title += nodes.inline(rawtext, ' '),
    title += pr_title_emphasized,

    details = nodes.paragraph()
    details += pr_additions
    details += nodes.inline(rawtext, ', ')
    details += pr_deletions
    details += nodes.inline(rawtext, ' '),
    details += pr_created_at

    return [title, details], []
Example #58
0
def missing_reference(app, env, node, contnode):
    """Attempt to resolve a missing reference via intersphinx references."""
    target = node['reftarget']
    if node['reftype'] == 'any':
        # we search anything!
        objtypes = [
            '%s:%s' % (domain.name, objtype)
            for domain in env.domains.values()
            for objtype in domain.object_types
        ]
        domain = None
    elif node['reftype'] == 'doc':
        domain = 'std'  # special case
        objtypes = ['std:doc']
    else:
        domain = node.get('refdomain')
        if not domain:
            # only objects in domains are in the inventory
            return
        elif domain == 'mongodb':
            if node['reftype'] in mdb_objs['prepend']:
                node['reftarget'] = '.'.join(
                    [mdb_objs['prepend'][node['reftype']], node['reftarget']])
                if node['reftype'] == 'program':
                    node['reftype'] = 'binary'

        objtypes = env.domains[domain].objtypes_for_role(node['reftype'])
        if not objtypes:
            return
        objtypes = ['%s:%s' % (domain, objtype) for objtype in objtypes]
    to_try = [(env.intersphinx_inventory, target)]
    in_set = None
    if ':' in target:
        # first part may be the foreign doc set name
        setname, newtarget = target.split(':', 1)
        if setname in env.intersphinx_named_inventory:
            in_set = setname
            to_try.append(
                (env.intersphinx_named_inventory[setname], newtarget))
    for inventory, target in to_try:
        for objtype in objtypes:
            if objtype not in inventory or target not in inventory[objtype]:
                continue
            proj, version, uri, dispname = inventory[objtype][target]
            if '://' not in uri and node.get('refdoc'):
                # get correct path in case of subdirectories
                uri = path.join(relative_path(node['refdoc'], env.srcdir), uri)
            newnode = nodes.reference('',
                                      '',
                                      internal=False,
                                      refuri=uri,
                                      reftitle=_('(in %s v%s)') %
                                      (proj, version))
            if node.get('refexplicit'):
                # use whatever title was given
                newnode.append(contnode)
            elif dispname == '-' or \
                    (domain == 'std' and node['reftype'] == 'keyword'):
                # use whatever title was given, but strip prefix
                title = contnode.astext()
                if in_set and title.startswith(in_set + ':'):
                    newnode.append(
                        contnode.__class__(title[len(in_set) + 1:],
                                           title[len(in_set) + 1:]))
                else:
                    newnode.append(contnode)
            else:
                # else use the given display name (used for :ref:)
                newnode.append(contnode.__class__(dispname, dispname))
            return newnode
    # at least get rid of the ':' in the target if no explicit title given
    if in_set is not None and not node.get('refexplicit', True):
        if len(contnode) and isinstance(contnode[0], nodes.Text):
            contnode[0] = nodes.Text(newtarget, contnode[0].rawsource)
Example #59
0
def process_audit_events(app, doctree, fromdocname):
    for node in doctree.traverse(audit_event_list):
        break
    else:
        return

    env = app.builder.env

    table = nodes.table(cols=3)
    group = nodes.tgroup(
        '',
        nodes.colspec(colwidth=30),
        nodes.colspec(colwidth=55),
        nodes.colspec(colwidth=15),
        cols=3,
    )
    head = nodes.thead()
    body = nodes.tbody()

    table += group
    group += head
    group += body

    row = nodes.row()
    row += nodes.entry('', nodes.paragraph('', nodes.Text('Audit event')))
    row += nodes.entry('', nodes.paragraph('', nodes.Text('Arguments')))
    row += nodes.entry('', nodes.paragraph('', nodes.Text('References')))
    head += row

    for name in sorted(getattr(env, "all_audit_events", ())):
        audit_event = env.all_audit_events[name]

        row = nodes.row()
        node = nodes.paragraph('', nodes.Text(name))
        row += nodes.entry('', node)

        node = nodes.paragraph()
        for i, a in enumerate(audit_event['args']):
            if i:
                node += nodes.Text(", ")
            node += nodes.literal(a, nodes.Text(a))
        row += nodes.entry('', node)

        node = nodes.paragraph()
        backlinks = enumerate(sorted(set(audit_event['source'])), start=1)
        for i, (doc, label) in backlinks:
            if isinstance(label, str):
                ref = nodes.reference("", nodes.Text("[{}]".format(i)), internal=True)
                try:
                    ref['refuri'] = "{}#{}".format(
                        app.builder.get_relative_uri(fromdocname, doc),
                        label,
                    )
                except NoUri:
                    continue
                node += ref
        row += nodes.entry('', node)

        body += row

    for node in doctree.traverse(audit_event_list):
        node.replace_self(table)
def make_headerlink_node(attribute_name, options):
    ref = '#' + attribute_name
    node = nodes.reference('', '¶', refuri=ref, reftitle="Permalink to this headline", classes=['headerlink'], **options)
    return node