Exemple #1
0
def sphinx_env(app_env: SphinxAppEnv):
    """This context enters the standard sphinx contexts,
    then registers the roles, directives and nodes saved in the app_env.

    The standard sphinx contexts:

    - Patch docutils.languages.get_language(), to suppress reporter warnings
    - Temporarily sets `os.environ['DOCUTILSCONFIG']` to the sphinx confdir
    - Saves copies of roles._roles and directives._directives & resets them on exit
    - Un-registers additional nodes (set via `register_node`) on exit
      (by deleting `GenericNodeVisitor` visit/depart methods)
    - Patches roles.roles and directives.directives functions to also look in domains
    """
    with patch_docutils(
            app_env.app.confdir), docutils_namespace(), sphinx_domains(
                app_env.app.env):
        from docutils.parsers.rst import directives, roles
        from sphinx.util.docutils import register_node

        if app_env.roles:
            roles._roles.update(app_env.roles)
        if app_env.directives:
            directives._directives.update(app_env.directives)
        for node in app_env.additional_nodes:
            register_node(node)
        # TODO how to make `unregister_node` thread safe

        yield
Exemple #2
0
def test_register_node():
    class custom_node(nodes.Element):
        pass

    with docutils_namespace():
        register_node(custom_node)

        # check registered
        assert hasattr(nodes.GenericNodeVisitor, 'visit_custom_node')
        assert hasattr(nodes.GenericNodeVisitor, 'depart_custom_node')
        assert hasattr(nodes.SparseNodeVisitor, 'visit_custom_node')
        assert hasattr(nodes.SparseNodeVisitor, 'depart_custom_node')

    # check unregistered outside namespace
    assert not hasattr(nodes.GenericNodeVisitor, 'visit_custom_node')
    assert not hasattr(nodes.GenericNodeVisitor, 'depart_custom_node')
    assert not hasattr(nodes.SparseNodeVisitor, 'visit_custom_node')
    assert not hasattr(nodes.SparseNodeVisitor, 'depart_custom_node')
Exemple #3
0
    def add_node(self, node, **kwds):
        # type: (nodes.Node, Any) -> None
        """Register a Docutils node class.

        This is necessary for Docutils internals.  It may also be used in the
        future to validate nodes in the parsed documents.

        Node visitor functions for the Sphinx HTML, LaTeX, text and manpage
        writers can be given as keyword arguments: the keyword should be one or
        more of ``'html'``, ``'latex'``, ``'text'``, ``'man'``, ``'texinfo'``
        or any other supported translators, the value a 2-tuple of ``(visit,
        depart)`` methods.  ``depart`` can be ``None`` if the ``visit``
        function raises :exc:`docutils.nodes.SkipNode`.  Example:

        .. code-block:: python

           class math(docutils.nodes.Element): pass

           def visit_math_html(self, node):
               self.body.append(self.starttag(node, 'math'))
           def depart_math_html(self, node):
               self.body.append('</math>')

           app.add_node(math, html=(visit_math_html, depart_math_html))

        Obviously, translators for which you don't specify visitor methods will
        choke on the node when encountered in a document to translate.

        .. versionchanged:: 0.5
           Added the support for keyword arguments giving visit functions.
        """
        logger.debug('[app] adding node: %r', (node, kwds))
        if not kwds.pop('override',
                        False) and docutils.is_node_registered(node):
            logger.warning(__(
                'while setting up extension %s: node class %r is '
                'already registered, its visitors will be overridden'),
                           self._setting_up_extension,
                           node.__name__,
                           type='app',
                           subtype='add_node')
        docutils.register_node(node)
        self.registry.add_translation_handlers(node, **kwds)
Exemple #4
0
    def add_node(
        self,
        node: Type[nodes.Element],
        override: bool = False,
        **kwargs: Tuple[Callable, Callable],
    ) -> None:
        r"""
		Register a Docutils node class.

		The registered values are stored in the ``additional_nodes`` set returned by
		:func:`~sphinx_toolbox.testing.run_setup`
		(:class:`typing.Set`\[:class:`typing.Type`\[:class:`docutils.nodes.Node`\]]).
		"""

        if not override and docutils.is_node_registered(node):
            raise ValueError(
                f"node class {node.__name__!r} is already registered, its visitors will be overridden"
            )

        docutils.register_node(node)
        self.registry.add_translation_handlers(node, **kwargs)
Exemple #5
0
    def add_node(self, node, override=False, **kwds):
        # type: (nodes.Node, bool, Any) -> None
        """Register a Docutils node class.

        This is necessary for Docutils internals.  It may also be used in the
        future to validate nodes in the parsed documents.

        Node visitor functions for the Sphinx HTML, LaTeX, text and manpage
        writers can be given as keyword arguments: the keyword should be one or
        more of ``'html'``, ``'latex'``, ``'text'``, ``'man'``, ``'texinfo'``
        or any other supported translators, the value a 2-tuple of ``(visit,
        depart)`` methods.  ``depart`` can be ``None`` if the ``visit``
        function raises :exc:`docutils.nodes.SkipNode`.  Example:

        .. code-block:: python

           class math(docutils.nodes.Element): pass

           def visit_math_html(self, node):
               self.body.append(self.starttag(node, 'math'))
           def depart_math_html(self, node):
               self.body.append('</math>')

           app.add_node(math, html=(visit_math_html, depart_math_html))

        Obviously, translators for which you don't specify visitor methods will
        choke on the node when encountered in a document to translate.

        .. versionchanged:: 0.5
           Added the support for keyword arguments giving visit functions.
        """
        logger.debug('[app] adding node: %r', (node, kwds))
        if not override and docutils.is_node_registered(node):
            logger.warning(__('while setting up extension %s: node class %r is '
                              'already registered, its visitors will be overridden'),
                           self._setting_up_extension, node.__name__,
                           type='app', subtype='add_node')
        docutils.register_node(node)
        self.registry.add_translation_handlers(node, **kwds)
 def add_node(self, node):
     if not docutils.is_node_registered(node):
         docutils.register_node(node)
Exemple #7
0
 def add_node(self, node):
     if not docutils.is_node_registered(node):
         docutils.register_node(node)