Exemplo n.º 1
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)
Exemplo n.º 2
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)
Exemplo n.º 3
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)
Exemplo n.º 4
0
 def add_node(self, node):
     if not docutils.is_node_registered(node):
         docutils.register_node(node)
Exemplo n.º 5
0
def setup(app):
    ConfluenceLogger.initialize()

    app.require_sphinx('1.8')
    app.add_builder(ConfluenceBuilder)
    app.add_builder(SingleConfluenceBuilder)
    app.registry.add_translator(ConfluenceBuilder.name,
                                ConfluenceStorageFormatTranslator)
    app.registry.add_translator(SingleConfluenceBuilder.name,
                                ConfluenceStorageFormatTranslator)

    # Images defined by data uri schemas can be resolved into generated images
    # after a document's post-transformation stage. After a document's doctree
    # has been resolved, re-check for any images that have been translated.
    def assetsDocTreeResolvedHook(app, doctree, docname):
        app.builder.assets.processDocument(doctree, docname, True)

    def builderInitedHook(app):
        if type(app.builder) == ConfluenceBuilder:
            app.connect('doctree-resolved', assetsDocTreeResolvedHook)

    app.connect('builder-inited', builderInitedHook)

    # remove math-node-migration post-transform as this extension manages both
    # future and legacy math implementations (removing this transform removes
    # a warning notification to the user)
    for transform in app.registry.get_post_transforms():
        if transform.__name__ == 'MathNodeMigrator':
            app.registry.get_post_transforms().remove(transform)
            break

    # ##########################################################################
    """(configuration - essential)"""
    """Enablement of publishing."""
    app.add_config_value('confluence_publish', None, False)
    """API key/password to login to Confluence API with."""
    app.add_config_value('confluence_server_pass', None, False)
    """URL of the Confluence instance to publish to."""
    app.add_config_value('confluence_server_url', None, False)
    """Username to login to Confluence API with."""
    app.add_config_value('confluence_server_user', None, False)
    """Confluence Space to publish to."""
    app.add_config_value('confluence_space_name', None, False)
    """(configuration - generic)"""
    """Add page and section numbers if doctree has :numbered: option"""
    app.add_config_value('confluence_add_secnumbers', True, False)
    """Default alignment for tables, figures, etc."""
    app.add_config_value('confluence_default_alignment', None, 'env')
    """File to get page header information from."""
    app.add_config_value('confluence_header_file', None, False)
    """File to get page footer information from."""
    app.add_config_value('confluence_footer_file', None, False)
    """Enablement of the maximum document depth (before inlining)."""
    app.add_config_value('confluence_max_doc_depth', None, False)
    """Enablement of publishing pages into a hierarchy from a master toctree."""
    app.add_config_value('confluence_page_hierarchy', None, False)
    """Show previous/next buttons (bottom, top, both, None)."""
    app.add_config_value('confluence_prev_next_buttons_location', None, False)
    """Suffix to put after section numbers, before section name"""
    app.add_config_value('confluence_secnumber_suffix', '. ', False)
    """(configuration - publishing)"""
    """Request for publish password to come from interactive session."""
    app.add_config_value('confluence_ask_password', False, False)
    """Request for publish username to come from interactive session."""
    app.add_config_value('confluence_ask_user', False, False)
    """Explicitly prevent auto-generation of titles for titleless documents."""
    app.add_config_value('confluence_disable_autogen_title', None, False)
    """Explicitly prevent page notifications on update."""
    app.add_config_value('confluence_disable_notifications', None, False)
    """Define a series of labels to apply to all published pages."""
    app.add_config_value('confluence_global_labels', None, False)
    """Enablement of configuring master as space's homepage."""
    app.add_config_value('confluence_master_homepage', None, False)
    """Root/parent page's name to publish documents into."""
    app.add_config_value('confluence_parent_page', None, False)
    """Perform a dry run of publishing to inspect what publishing will do."""
    app.add_config_value('confluence_publish_dryrun', None, '')
    """Publish only new content (no page updates, etc.)."""
    app.add_config_value('confluence_publish_onlynew', None, '')
    """Postfix to apply to title of published pages."""
    app.add_config_value('confluence_publish_postfix', None, False)
    """Prefix to apply to published pages."""
    app.add_config_value('confluence_publish_prefix', None, False)
    """Enablement of purging legacy child pages from a parent page."""
    app.add_config_value('confluence_purge', None, False)
    """Enablement of purging legacy child pages from a master page."""
    app.add_config_value('confluence_purge_from_master', None, False)
    """docname-2-title dictionary for title overrides."""
    app.add_config_value('confluence_title_overrides', None, 'env')
    """Timeout for network-related calls (publishing)."""
    app.add_config_value('confluence_timeout', None, False)
    """Whether or not new content should be watched."""
    app.add_config_value('confluence_watch', None, False)
    """(configuration - advanced publishing)"""
    """Whether or not labels will be appended instead of overwriting them."""
    app.add_config_value('confluence_append_labels', None, False)
    """Tri-state asset handling (auto, force push or disable)."""
    app.add_config_value('confluence_asset_override', None, False)
    """File/path to Certificate Authority"""
    app.add_config_value('confluence_ca_cert', None, False)
    """Path to client certificate to use for publishing"""
    app.add_config_value('confluence_client_cert', None, False)
    """Password for client certificate to use for publishing"""
    app.add_config_value('confluence_client_cert_pass', None, False)
    """Disable SSL validation with Confluence server."""
    app.add_config_value('confluence_disable_ssl_validation', None, False)
    """Root/parent page's identifier to publish documents into."""
    app.add_config_value('confluence_parent_page_id_check', None, False)
    """Proxy server needed to communicate with Confluence server."""
    app.add_config_value('confluence_proxy', None, False)
    """Subset of document names to publish"""
    app.add_config_value('confluence_publish_subset', [], False)
    """Authentication passthrough for Confluence REST interaction."""
    app.add_config_value('confluence_server_auth', None, False)
    """Cookie(s) to use for Confluence REST interaction."""
    app.add_config_value('confluence_server_cookies', None, False)
    """(configuration - advanced processing)"""
    """Filename suffix for generated files."""
    app.add_config_value('confluence_file_suffix', ".conf", False)
    """Translation of docname to a filename."""
    app.add_config_value('confluence_file_transform', None, False)
    """Configuration for named JIRA Servers"""
    app.add_config_value('confluence_jira_servers', {}, True)
    """Translation of a raw language to code block macro language."""
    app.add_config_value('confluence_lang_transform', None, False)
    """Link suffix for generated files."""
    app.add_config_value('confluence_link_suffix', None, False)
    """Translation of docname to a (partial) URI."""
    app.add_config_value('confluence_link_transform', None, False)
    """Remove a detected title from generated documents."""
    app.add_config_value('confluence_remove_title', True, False)
    """(configuration - undocumented)"""
    """Enablement for aggressive descendents search (for purge)."""
    app.add_config_value('confluence_adv_aggressive_search', None, False)
    """Enablement of the children macro for hierarchy mode."""
    app.add_config_value('confluence_adv_hierarchy_child_macro', None, False)
    """List of node types to ignore if no translator support exists."""
    app.add_config_value('confluence_adv_ignore_nodes', [], False)
    """Unknown node handler dictionary for advanced integrations."""
    app.add_config_value('confluence_adv_node_handler', None, '')
    """List of optional features/macros/etc. restricted for use."""
    app.add_config_value('confluence_adv_restricted', [], False)
    """Enablement of tracing processed data."""
    app.add_config_value('confluence_adv_trace_data', False, False)
    """Do not cap sections to a maximum of six (6) levels."""
    app.add_config_value('confluence_adv_writer_no_section_cap', None, False)
    """Indent to use for generated documents."""
    app.add_config_value('confluence_indent', STDINDENT, False)

    # ##########################################################################
    """JIRA directives"""
    """Adds the custom nodes needed for JIRA directives"""
    if not docutils.is_node_registered(jira):
        app.add_node(jira)
    if not docutils.is_node_registered(jira_issue):
        app.add_node(jira_issue)
    """Wires up the directives themselves"""
    app.add_directive('jira', JiraDirective)
    app.add_directive('jira_issue', JiraIssueDirective)
    """Confluence directives"""
    """Adds the custom nodes needed for Confluence directives"""
    if not docutils.is_node_registered(confluence_metadata):
        app.add_node(confluence_metadata)
    """Wires up the directives themselves"""
    app.add_directive('confluence_metadata', ConfluenceMetadataDirective)

    if 'sphinx.ext.autosummary' in app.config.extensions:
        add_autosummary_nodes(app)

    # lazy bind sphinx.ext.imgmath to provide configuration options
    #
    # If 'sphinx.ext.imgmath' is not already explicitly loaded, bind it into the
    # setup process to a configurer can use the same configuration options
    # outlined in the sphinx.ext.imgmath in this extension. This applies for
    # Sphinx 1.8 and higher which math support is embedded; for older versions,
    # users will need to explicitly load 'sphinx.ext.mathbase'.
    if (imgmath is not None
            and 'sphinx.ext.imgmath' not in app.config.extensions):
        imgmath.setup(app)

    return {
        'version': __version__,
        'parallel_read_safe': True,
        'parallel_write_safe': True,
    }
Exemplo n.º 6
0
 def add_node(self, node):
     if not docutils.is_node_registered(node):
         docutils.register_node(node)
Exemplo n.º 7
0
def confluence_builder_inited(app):
    """
    invoked when the configured sphinx builder is initialized

    Handling a `builder-inited` event generated from Sphinx.
    """

    # ignore non-confluence builder types
    if not isinstance(app.builder, ConfluenceBuilder):
        return

    # register nodes required by confluence-specific directives
    if not docutils.is_node_registered(confluence_metadata):
        app.add_node(confluence_metadata)
    if not docutils.is_node_registered(jira):
        app.add_node(jira)
    if not docutils.is_node_registered(jira_issue):
        app.add_node(jira_issue)

    # register directives
    app.add_directive('confluence_expand', ConfluenceExpandDirective)
    app.add_directive('confluence_latex', ConfluenceLatexDirective)
    app.add_directive('confluence_metadata', ConfluenceMetadataDirective)
    app.add_directive('confluence_newline', ConfluenceNewline)
    app.add_directive('confluence_toc', ConfluenceToc)
    app.add_directive('jira', JiraDirective)
    app.add_directive('jira_issue', JiraIssueDirective)

    # register roles
    app.add_role('confluence_latex', ConfluenceLatexRole)
    app.add_role('confluence_mention', ConfluenceMentionRole)
    app.add_role('confluence_status', ConfluenceStatusRole)
    app.add_role('jira', JiraRole)

    # inject compatible autosummary nodes if the extension is available/loaded
    if autosummary:
        for ext in app.extensions.values():
            if ext.name == 'sphinx.ext.autosummary':
                app.registry.add_translation_handlers(
                    autosummary.autosummary_table,
                    confluence=(
                        autosummary.autosummary_table_visit_html,
                        autosummary.autosummary_noop,
                    ),
                    singleconfluence=(
                        autosummary.autosummary_table_visit_html,
                        autosummary.autosummary_noop,
                    ),
                )
                app.registry.add_translation_handlers(
                    autosummary.autosummary_toc,
                    confluence=(
                        autosummary.autosummary_toc_visit_html,
                        autosummary.autosummary_noop,
                    ),
                    singleconfluence=(
                        autosummary.autosummary_toc_visit_html,
                        autosummary.autosummary_noop,
                    ),
                )
                break

    # lazy bind sphinx.ext.imgmath to provide configuration options
    #
    # If 'sphinx.ext.imgmath' is not already explicitly loaded, bind it into the
    # setup process to a configurer can use the same configuration options
    # outlined in the sphinx.ext.imgmath in this extension. This applies for
    # Sphinx 1.8 and higher which math support is embedded; for older versions,
    # users will need to explicitly load 'sphinx.ext.mathbase'.
    if imgmath is not None:
        if 'sphinx.ext.imgmath' not in app.config.extensions:
            imgmath.setup(app)

    # remove math-node-migration post-transform as this extension manages both
    # future and legacy math implementations (removing this transform removes
    # a warning notification to the user)
    for transform in app.registry.get_post_transforms():
        if transform.__name__ == 'MathNodeMigrator':
            app.registry.get_post_transforms().remove(transform)
            break