Example #1
0
 def role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
     text = utils.unescape(text)
     has_explicit_title, title, url = split_explicit_title(text)
     # NOTE: not using urlparse.urljoin() here, to allow something like
     # base_url = 'bugs.python.org/issue'  and  url = '1024'
     full_url = base_url + url
     if not has_explicit_title:
         if prefix is None:
             title = full_url
         else:
             title = prefix + url
     pnode = nodes.reference(title, title, refuri=full_url)
     return [pnode], []
Example #2
0
def ext_ref_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
    """
    A role that allows referencing external links defined in the config file.
    This allows urls to be easily updated without changing all the documentation.
    
    Define 'external_links' as a dictionary in your config file and link to using `:extref:`referance_name``
    If the reference text contains a forward slash it will be split and the first part used as reference, with the 
    second part appended to the generated link.
    
    Example::
        
        # conf.py
        # ---------------
        external_links = {"Rodin": "http://drddocs/drd/software/int/apps/Rodin/v00_00_09/docs/_build/html/" }
        
        
        # intro.rst
        .. seealso:: 
            
            :extref:`Rodin Documentation <Rodin>`
            :extref:`Rodin User Docs <Rodin/user>`
            
    """
    env = inliner.document.settings.env
    text = utils.unescape(text)
    
    # split any title, link
    has_explicit_title, title, target = split_explicit_title(text)
    
    # check if target contains a slash
    extra = None
    if "/" in target:
        target, extra = target.split("/", 1)
    
    # now find the linked target
    link = env.config.external_links.get(target, None)
    if not link:
        msg = inliner.reporter.warning("No external link specified in config for target '%s'" % target, line=lineno)
        prb = inliner.problematic(rawtext, rawtext, msg)
        return [prb], [msg]
    else:
        # display a uri link reference with given title
        if extra:
            link = "%s/%s" % (link, extra)
            
        pnode = nodes.reference(title, title, refuri=link)
        pnode.lineno = lineno
        return [pnode], []
Example #3
0
def asset_role(
    name: str,
    rawtext: str,
    text: str,
    lineno: int,
    inliner: Inliner,
    options: Dict = {},
    content: List[str] = []
) -> Tuple[Sequence[AssetNode], List[system_message]]:
    """
	Adds a link to an asset.

	:param name: The local name of the interpreted role, the role name actually used in the document.
	:param rawtext: A string containing the entire interpreted text input, including the role and markup.
	:param text: The interpreted text content.
	:param lineno: The line number where the interpreted text begins.
	:param inliner: The :class:`docutils.parsers.rst.states.Inliner` object that called :func:`~.source_role`.
		It contains the several attributes useful for error reporting and document tree access.
	:param options: A dictionary of directive options for customization (from the ``role`` directive),
		to be interpreted by the function.
		Used for additional attributes for the generated elements and other functionality.
	:param content: A list of strings, the directive content for customization (from the ``role`` directive).
		To be interpreted by the function.

	:return: A list containing the created node, and a list containing any messages generated during the function.
	"""

    has_t, title, target = split_explicit_title(text)
    title = nodes.unescape(title)
    target = nodes.unescape(target)

    if not has_t:
        if target.startswith('~'):
            target = target[1:]
            title = pathlib.PurePosixPath(text[1:]).name

    app = inliner.document.settings.env.app
    base = app.config.assets_dir
    node = AssetNode(rawtext,
                     title,
                     refuri=target,
                     source_file=PathPlus(base) / target,
                     **options)

    return [node], []
Example #4
0
def source_role(
		name: str,
		rawtext: str,
		text: str,
		lineno: int,
		inliner: Inliner,
		options: Dict = {},
		content: List[str] = []
		) -> Tuple[Sequence[nodes.Node], List[system_message]]:
	"""
	Adds a link to the given Python source file in the documentation or on GitHub.

	:param name: The local name of the interpreted role, the role name actually used in the document.
	:param rawtext: A string containing the entire interpreted text input, including the role and markup.
	:param text: The interpreted text content.
	:param lineno: The line number where the interpreted text begins.
	:param inliner: The :class:`docutils.parsers.rst.states.Inliner` object that called :func:`~.source_role`.
		It contains the several attributes useful for error reporting and document tree access.
	:param options: A dictionary of directive options for customization (from the ``role`` directive),
		to be interpreted by the function.
		Used for additional attributes for the generated elements and other functionality.
	:param content: A list of strings, the directive content for customization (from the ``role`` directive).
		To be interpreted by the function.

	:return: A list containing the created node, and a list containing any messages generated during the function.

	.. versionchanged:: 2.8.0

		Now returns a sequence of :class:`nodes.reference <docutils.nodes.reference>` and
		:class:`addnodes.pending_xref <sphinx.addnodes.pending_xref>` as the first tuple element,
		rather than :class:`nodes.reference <docutils.nodes.reference>` and
		:class:`addnodes.pending_xref <sphinx.addnodes.only>` as in previous versions.
	"""

	has_t, title, target = split_explicit_title(text)
	title = nodes.unescape(title)
	target = nodes.unescape(target)

	env = inliner.document.settings.env
	config = env.app.config

	nodes_: List[nodes.Node] = []
	messages: List[system_message] = []
	refnode: nodes.Node

	if config.source_link_target == "sphinx":
		if target.endswith("/__init__.py"):
			pagename = "_modules/" + target.rsplit('/', 1)[0]
		else:
			pagename = "_modules/" + target.replace(".py", '')

		# refnode = addnodes.only(expr="html")
		# refnode += addnodes.pending_xref(

		refnode = _make_viewcode_node(
				title,
				pagename,
				env,
				)

		# refnode = addnodes.pending_xref(
		# 		title,
		# 		nodes.inline(title, title),
		# 		reftype="viewcode",
		# 		refdomain="std",
		# 		refexplicit=False,
		# 		reftarget=pagename,
		# 		refid=title,
		# 		refdoc=env.docname,
		# 		)

		nodes_.append(refnode)

	elif config.source_link_target == "github":
		refnode = nodes.reference(
				title,
				title,
				refuri=str(config.github_source_url / target),
				)

		nodes_.append(refnode)

	else:
		message = inliner.document.reporter.error(f"Unsupported source link target '{config.source_link_target}'.")
		messages.append(message)

	return nodes_, messages
Example #5
0
def xfileref_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
    env = inliner.document.settings.env
    if not typ:
        typ = env.config.default_role
    else:
        typ = typ.lower()
    text = utils.unescape(text)
    # if the first character is a bang, don't cross-reference at all
    if text[0:1] == '!':
        text = _fix_parens(typ, text[1:], env)
        return [innernodetypes.get(typ, nodes.literal)(
            rawtext, text, classes=['xref'])], []
    # we want a cross-reference, create the reference node
    nodeclass = (typ == 'download') and addnodes.download_reference or \
                addnodes.pending_xref
    pnode = nodeclass(rawtext, reftype=typ, refcaption=False,
                      modname=env.currmodule, classname=env.currclass)
    # we may need the line number for warnings
    pnode.line = lineno
    # look if explicit title and target are given with `foo <bar>` syntax
    has_explicit_title, title, target = split_explicit_title(text)
    if has_explicit_title:
        pnode['refcaption'] = True
    # special target for Python object cross-references
    if typ in ('data', 'exc', 'func', 'class', 'const', 'attr',
               'meth', 'mod', 'obj'):
        # fix-up parentheses in link title
        if not has_explicit_title:
            title = title.lstrip('.')   # only has a meaning for the target
            target = target.lstrip('~') # only has a meaning for the title
            title = _fix_parens(typ, title, env)
            # if the first character is a tilde, don't display the module/class
            # parts of the contents
            if title[0:1] == '~':
                title = title[1:]
                dot = title.rfind('.')
                if dot != -1:
                    title = title[dot+1:]
        # remove parentheses from the target too
        if target.endswith('()'):
            target = target[:-2]
        # if the first character is a dot, search more specific namespaces first
        # else search builtins first
        if target[0:1] == '.':
            target = target[1:]
            pnode['refspecific'] = True
    # some other special cases for the target
    elif typ == 'option':
        program = env.currprogram
        if not has_explicit_title:
            if ' ' in title and not (title.startswith('/') or
                                     title.startswith('-')):
                program, target = re.split(' (?=-|--|/)', title, 1)
                program = ws_re.sub('-', program)
                target = target.strip()
        elif ' ' in target:
            program, target = re.split(' (?=-|--|/)', target, 1)
            program = ws_re.sub('-', program)
        pnode['refprogram'] = program
    elif typ == 'term':
        # normalize whitespace in definition terms (if the term reference is
        # broken over a line, a newline will be in target)
        target = ws_re.sub(' ', target).lower()
    elif typ == 'ref':
        # reST label names are always lowercased
        target = ws_re.sub('', target).lower()
    elif typ == 'cfunc':
        # fix-up parens for C functions too
        if not has_explicit_title:
            title = _fix_parens(typ, title, env)
        # remove parentheses from the target too
        if target.endswith('()'):
            target = target[:-2]
    else:
        # remove all whitespace to avoid referencing problems
        target = ws_re.sub('', target)
    pnode['reftarget'] = target
    pnode += innernodetypes.get(typ, nodes.literal)(rawtext, title,
                                                    classes=['xref'])
    return [pnode], []
Example #6
0
def xfileref_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
    env = inliner.document.settings.env
    if not typ:
        typ = env.config.default_role
    else:
        typ = typ.lower()
    text = utils.unescape(text)
    # if the first character is a bang, don't cross-reference at all
    if text[0:1] == '!':
        text = _fix_parens(typ, text[1:], env)
        return [
            innernodetypes.get(typ, nodes.literal)(rawtext,
                                                   text,
                                                   classes=['xref'])
        ], []
    # we want a cross-reference, create the reference node
    nodeclass = (typ == 'download') and addnodes.download_reference or \
                addnodes.pending_xref
    pnode = nodeclass(rawtext,
                      reftype=typ,
                      refcaption=False,
                      modname=env.currmodule,
                      classname=env.currclass)
    # we may need the line number for warnings
    pnode.line = lineno
    # look if explicit title and target are given with `foo <bar>` syntax
    has_explicit_title, title, target = split_explicit_title(text)
    if has_explicit_title:
        pnode['refcaption'] = True
    # special target for Python object cross-references
    if typ in ('data', 'exc', 'func', 'class', 'const', 'attr', 'meth', 'mod',
               'obj'):
        # fix-up parentheses in link title
        if not has_explicit_title:
            title = title.lstrip('.')  # only has a meaning for the target
            target = target.lstrip('~')  # only has a meaning for the title
            title = _fix_parens(typ, title, env)
            # if the first character is a tilde, don't display the module/class
            # parts of the contents
            if title[0:1] == '~':
                title = title[1:]
                dot = title.rfind('.')
                if dot != -1:
                    title = title[dot + 1:]
        # remove parentheses from the target too
        if target.endswith('()'):
            target = target[:-2]
        # if the first character is a dot, search more specific namespaces first
        # else search builtins first
        if target[0:1] == '.':
            target = target[1:]
            pnode['refspecific'] = True
    # some other special cases for the target
    elif typ == 'option':
        program = env.currprogram
        if not has_explicit_title:
            if ' ' in title and not (title.startswith('/')
                                     or title.startswith('-')):
                program, target = re.split(' (?=-|--|/)', title, 1)
                program = ws_re.sub('-', program)
                target = target.strip()
        elif ' ' in target:
            program, target = re.split(' (?=-|--|/)', target, 1)
            program = ws_re.sub('-', program)
        pnode['refprogram'] = program
    elif typ == 'term':
        # normalize whitespace in definition terms (if the term reference is
        # broken over a line, a newline will be in target)
        target = ws_re.sub(' ', target).lower()
    elif typ == 'ref':
        # reST label names are always lowercased
        target = ws_re.sub('', target).lower()
    elif typ == 'cfunc':
        # fix-up parens for C functions too
        if not has_explicit_title:
            title = _fix_parens(typ, title, env)
        # remove parentheses from the target too
        if target.endswith('()'):
            target = target[:-2]
    else:
        # remove all whitespace to avoid referencing problems
        target = ws_re.sub('', target)
    pnode['reftarget'] = target
    pnode += innernodetypes.get(typ, nodes.literal)(rawtext,
                                                    title,
                                                    classes=['xref'])
    return [pnode], []