예제 #1
0
파일: sphinxext.py 프로젝트: epruesse/ymp
 def get_ref(self, node: nodes.Node) -> Optional[nodes.Node]:
     while node is not None:
         if not node.get('ids'):
             # In Sphinx domain descriptions, the ID is in the
             # first child node, the desc_signature.
             # We can take that, but to make the JS handling
             # the TOC sidebar work properly, we need it to
             # be in the hierarchy. So create an ID for the
             # desc node.
             if node[0].get('ids'):
                 node['ids'] = [node[0].get('ids')[0] + '-tocentry']
         if node.get('ids'):
             return node['ids'][0]
         node = node.parent
예제 #2
0
def _add_pending_back_reference(app: Sphinx, signode: Node,
                                fullname: str) -> None:
    """
    Updates the ``doc_links`` entry of the modules stored in
    ``_viewcode_c_modules`` so that they can later be added to the source
    code listings as links to the documentation locations.

    Args:
        app (Sphinx):
            The sphinx app currently doing the processing.
        signode (Node):
            The signature node to create the back reference to.
        fullname (str):
            The name of the construct, i.e. function name, variable name etc.
    """
    module = signode.get("module")
    if module is None:
        return

    env = app.builder.env
    code_listing = env._viewcode_c_modules.get(module)  # type: ignore
    if code_listing is None:
        return

    doc_links = code_listing.doc_links
    doc_links.setdefault(fullname,
                         DocumentationReference(env.docname, module, fullname))
예제 #3
0
 def visit_doctest_block(self, node: Node) -> None:
     pysrc = node[0].astext()
     if node.get('codeblock'):
         self.body.append(flatten(colorize_codeblock(pysrc)))
     else:
         self.body.append(flatten(colorize_doctest(pysrc)))
     raise SkipNode()
예제 #4
0
def is_translatable(node: Node) -> bool:
    if isinstance(node, addnodes.translatable):
        return True

    # image node marked as translatable or having alt text
    if isinstance(node, nodes.image) and (node.get('translatable')
                                          or node.get('alt')):
        return True

    if isinstance(node,
                  nodes.Inline) and 'translatable' not in node:  # type: ignore
        # inline node must not be translated if 'translatable' is not set
        return False

    if isinstance(node, nodes.TextElement):
        if not node.source:
            logger.debug('[i18n] SKIP %r because no node.source: %s',
                         get_full_module_name(node), repr_domxml(node))
            return False  # built-in message
        if isinstance(node, IGNORED_NODES) and 'translatable' not in node:
            logger.debug(
                "[i18n] SKIP %r because node is in IGNORED_NODES "
                "and no node['translatable']: %s", get_full_module_name(node),
                repr_domxml(node))
            return False
        if not node.get('translatable', True):
            # not(node['translatable'] == True or node['translatable'] is None)
            logger.debug("[i18n] SKIP %r because not node['translatable']: %s",
                         get_full_module_name(node), repr_domxml(node))
            return False
        # <field_name>orphan</field_name>
        # XXX ignore all metadata (== docinfo)
        if isinstance(node, nodes.field_name) and node.children[0] == 'orphan':
            logger.debug('[i18n] SKIP %r because orphan node: %s',
                         get_full_module_name(node), repr_domxml(node))
            return False
        return True

    if is_pending_meta(node) or isinstance(node, addnodes.meta):
        # docutils-0.17 or older
        return True
    elif isinstance(node, addnodes.docutils_meta):
        # docutils-0.18+
        return True

    return False
예제 #5
0
파일: sphinxext.py 프로젝트: epruesse/ymp
 def locate_in_toc(self, app: Sphinx,
                   node: nodes.Node) -> Optional[nodes.Node]:
     toc = app.env.tocs[app.env.docname]
     ref = self.get_ref(node)
     for node in toc.traverse(nodes.reference):
         node_ref = node.get('anchorname')
         if not node_ref or node_ref[0] != "#":
             continue
         if node_ref[1:] == ref:
             return node.parent.parent
예제 #6
0
    def resolve_any_xref(
            self, env: BuildEnvironment, from_doc_name: str, builder: Builder,
            target: str, node: nodes.Node,
            cont_node: nodes.Node) -> List[Tuple[str, nodes.Node]]:
        modname = node.get('lua:module')
        class_name = node.get('lua:class')
        results: List[Tuple[str, nodes.Node]] = []

        # always search in "refspecific" mode with the :any: role
        matches = self.find_obj(env, modname, class_name, target, None, 1)
        for name, obj in matches:
            if obj[1] == 'module':
                results.append(
                    ('lua:mod',
                     self._make_module_refnode(builder, from_doc_name, name,
                                               cont_node)))
            else:
                results.append(('lua:' + self.role_for_objtype(obj[1]),
                                make_refnode(builder, from_doc_name, obj[0],
                                             name, cont_node, name)))
        return results
예제 #7
0
    def get_enumerable_node_type(self, node: Node) -> str:
        """Get type of enumerable nodes."""
        def has_child(node: Element, cls: "Type") -> bool:
            return any(isinstance(child, cls) for child in node)

        if isinstance(node, nodes.section):
            return 'section'
        elif isinstance(node, nodes.container):
            if node.get('literal_block') and has_child(node, nodes.literal_block):
                return 'code-block'
            else:
                return None
        else:
            figtype, _ = self.enumerable_nodes.get(node.__class__, (None, None))
            return figtype
예제 #8
0
def _add_pending_source_cross_reference(app: Sphinx, signode: Node,
                                        fullname: str) -> None:
    """
    Adds a pending source cross reference to the signature in the doctree, `signode`.

    The viewcode and linkcode extensions walk the doctree once parsed and
    then add this node, however since sphinx_c_autodoc already has to add
    logic, the `module` option to the directives it seems more practical to
    just create the full pending cross reference here, and then viewcode is
    an extension which will populate this cross refernce.

    Args:
        app (Sphinx):
            The sphinx app currently doing the processing.
        signode (Node):
            The signature node to apply the source code cross reference to.
        fullname (str):
            The dotted fullname of the C construct.
    """
    module = signode.get("module")
    if module is None:
        return

    source_page = _get_source_page_name(module)

    # Using the `viewcode-link` to be consistent with the python versions in
    # case someone else wants to walk the tree and do other links
    inline = nodes.inline("", "[source]", classes=["viewcode-link"])

    # Limit this cross referencing only to html
    html_node = addnodes.only(expr="html")
    html_node += addnodes.pending_xref(
        "",
        inline,
        reftype=f"{C_DOMAIN_LINK_PREFIX}viewcode",
        refdomain="std",
        refexplicit=False,
        reftarget=source_page,
        refid=f"{C_DOMAIN_LINK_PREFIX}{fullname}",
        refdoc=app.builder.env.docname,
        module=module,
        fullname=fullname,
    )

    signode += html_node
def handle_missing_xref(app: Sphinx, env, node: nodes.Node,
                        contnode: nodes.Node) -> None:
    # Ignore missing reference warnings for the wheel_filename module
    if node.get("reftarget", '').startswith("docutils."):
        raise NoUri

    if node.get("reftarget", '').startswith("sphinx.ext.autodoc."):
        raise NoUri

    if node.get("reftarget", '').startswith("sphinx.ext.autosummary."):
        raise NoUri

    if node.get("reftarget",
                '').startswith("sphinx_toolbox._data_documenter."):
        # TODO: redirect
        raise NoUri

    if node.get("reftarget", '') in {
            "spam",
            "lobster",
            "foo",
            "typing_extensions",
            "bs4.BeautifulSoup",
            "pytest_regressions.file_regression.FileRegressionFixture",
            "sphinx_toolbox.patched_autosummary",
            "sphinx_toolbox.autodoc_augment_defaults",
            "sphinx_toolbox.autodoc_typehints",
            "sphinx_toolbox.autotypeddict",
            "sphinx_toolbox.autoprotocol",
            "sphinx_toolbox.utils._T",
            "sphinx_toolbox.testing.EventManager",  # TODO
            "sphinx.registry.SphinxComponentRegistry",
            "sphinx.config.Config",
            "sphinx.config.Config.latex_elements",
            "sphinx.util.docfields.TypedField",
            "sphinx.writers.html.HTMLTranslator",
            "sphinx.writers.latex.LaTeXTranslator",
            "sphinx.domains.python.PyXRefRole",
            "sphinx.domains.std.GenericObject",
            "sphinx.domains.changeset.VersionChange",
            "sphinx.directives.code.CodeBlock",
            "sphinx.roles.Abbreviation",
            "autodoc.Documenter",  # TODO: why not sphinx.ext.autodoc.Documenter?
    }:
        raise NoUri

    if node.get("reftarget",
                '').startswith("consolekit.terminal_colours.Fore."):
        raise NoUri
예제 #10
0
 def dispatch_visit(self, node: Node) -> None:
     if isinstance(node, nodes.comment):
         raise nodes.SkipNode
     elif isinstance(node, nodes.raw):
         if 'html' in node.get('format', '').split():
             # Some people might put content in raw HTML that should be searched,
             # so we just amateurishly strip HTML tags and index the remaining
             # content
             nodetext = re.sub(r'(?is)<style.*?</style>', '', node.astext())
             nodetext = re.sub(r'(?is)<script.*?</script>', '', nodetext)
             nodetext = re.sub(r'<[^<]+?>', '', nodetext)
             self.found_words.extend(self.lang.split(nodetext))
         raise nodes.SkipNode
     elif isinstance(node, nodes.Text):
         self.found_words.extend(self.lang.split(node.astext()))
     elif isinstance(node, nodes.title):
         self.found_title_words.extend(self.lang.split(node.astext()))
     elif isinstance(node, addnodes.meta) and self.is_meta_keywords(node):
         keywords = node['content']
         keywords = [keyword.strip() for keyword in keywords.split(',')]
         self.found_words.extend(keywords)
예제 #11
0
파일: nodes.py 프로젝트: vh999/sphinx
    def match(self, node: Node) -> bool:
        try:
            if self.classes and not isinstance(node, self.classes):
                return False

            if self.attrs:
                if not isinstance(node, nodes.Element):
                    return False

                for key, value in self.attrs.items():
                    if key not in node:
                        return False
                    elif value is Any:
                        continue
                    elif node.get(key) != value:
                        return False

            return True
        except Exception:
            # for non-Element nodes
            return False
예제 #12
0
def is_gettext_additional_targets(node: Node) -> bool:
    # This func judges if passed `node` is one of the following, which can be
    # tranlated by `gettext_addtional_targets` setting and is not supported by
    # this sphinx extension:
    # - toctree (with hidden attribute as True)
    # - literal-block
    # - raw
    # - image

    # hidden toc element
    if isinstance(node, toctree) and node.get("hidden", None) is True:
        return True

    # literal_block / raw / image nodes are not supported since they are not
    # supported due to implementation issue, e.g. compatibility with code-block
    # highlight HTML writing
    elif (isinstance(node, literal_block) or isinstance(node, raw)
          or isinstance(node, image)):
        return True
    else:
        return False
예제 #13
0
 def get_refnodes(self, doctree: Node, result: List[Dict[str, Any]]) -> List[Dict[str, Any]]:  # NOQA
     """Collect section titles, their depth in the toc and the refuri."""
     # XXX: is there a better way than checking the attribute
     # toctree-l[1-8] on the parent node?
     if isinstance(doctree, nodes.reference) and doctree.get('refuri'):
         refuri = doctree['refuri']
         if refuri.startswith('http://') or refuri.startswith('https://') \
            or refuri.startswith('irc:') or refuri.startswith('mailto:'):
             return result
         classes = doctree.parent.attributes['classes']
         for level in range(8, 0, -1):  # or range(1, 8)?
             if (self.toctree_template % level) in classes:
                 result.append({
                     'level': level,
                     'refuri': html.escape(refuri),
                     'text': ssp(html.escape(doctree.astext()))
                 })
                 break
     elif isinstance(doctree, nodes.Element):
         for elem in doctree:
             result = self.get_refnodes(elem, result)
     return result
예제 #14
0
def visit_container(self, node: nodes.Node):
    classes = "docutils container"
    if node.get("is_div", False):
        # we don't want the CSS for container for these nodes
        classes = "docutils"
    self.body.append(self.starttag(node, "div", CLASS=classes))
예제 #15
0
 def match(self, node: nodes.Node) -> bool:
     uri = node.get('uri', '')
     return bool(url_to_file_id(uri))
def visit_togglereveal(self, node: nodes.Node) -> None:
    classes = " ".join(node.get("classes", []))
    self.body.append(f'<div class="togglereveal {classes}">')
    self.body.append('<details class="admonition-body">')
    self.body.append("<summary></summary>")