如何将对象添加到Sphinx的全局索引,或通过别名进行交叉引用?

2024-04-18 21:37:22 发布

您现在位置:Python中文网/ 问答频道 /正文

每次我必须引用一个方法,而不是:func:`package.subpackage.module.method`,特别是对于经常使用的方法。有没有办法以某种方式“注册”package.subpackage,这样只有module.method就足够了?(更好的是,package.subpackage.module,所以method就足够了,假设没有冲突)

解决方案不应该包括向packagesubpackage添加目录,但我可以向docs/添加任何内容。请注意,这里的问题涉及在docstring模块之外定义的method(否则.method可以工作)


Tags: 模块方法目录docspackage内容定义方式
2条回答

您可以添加一个简单的扩展来解析您定义的别名。下面的例子是一个简短的概念证明:

# add this to conf.py

from sphinx.addnodes import pending_xref
from sphinx.ext.intersphinx import missing_reference
from docutils.nodes import Text

# alias ref is mapped to a pair (real ref, text to render)
reftarget_aliases = {
    'foo.spam': ('foo.bar.baz.spam', 'spam'),
}


def resolve_intersphinx_aliases(app, env, node, contnode):
    alias = node.get('reftarget', None)
    if alias is not None and alias in reftarget_aliases:
        real_ref, text_to_render = reftarget_aliases[alias]
        # this will resolve the ref
        node['reftarget'] = real_ref

        # this will rewrite the rendered text:
        # find the text node child
        text_node = next(iter(contnode.traverse(lambda n: n.tagname == '#text')))
        # remove the old text node, add new text node with custom text
        text_node.parent.replace(text_node, Text(text_to_render, ''))

        # delegate all the rest of dull work to intersphinx
        return missing_reference(app, env, node, contnode)


def resolve_internal_aliases(app, doctree):
    pending_xrefs = doctree.traverse(condition=pending_xref)
    for node in pending_xrefs:
        alias = node.get('reftarget', None)
        if alias is not None and alias in reftarget_aliases:
            real_ref, text_to_render = reftarget_aliases[alias]
            # this will resolve the ref
            node['reftarget'] = real_ref

            # this will rewrite the rendered text:
            # find the text node child
            text_node = next(iter(node.traverse(lambda n: n.tagname == '#text')))
            # remove the old text node, add new text node with custom text
            text_node.parent.replace(text_node, Text(text_to_render, ''))


def setup(app):
    app.connect('doctree-read', resolve_internal_aliases)
    app.connect('missing-reference', resolve_intersphinx_aliases)

现在,所有的引用:role:`foo.spam`都将替换为:role:`spam <foo.bar.baz.spam>`,而不管具体的角色是什么(classfuncmod,无论什么)。当然,这只是一个草稿,未经测试,但你应该了解这个想法。甚至可能是新斯芬克斯扩建项目的良好起点:-)

从您看到类、函数或方法的那一刻起,在索引中您就可以省去名称的书写。 例如 不使用完全限定名称编写交叉引用:

:func:`~package.subpackage.module.method`
:meth:`~package.subpackage.module.method`

你可以简单地写:

:func:`.method`
:meth:`.method`

请注意,如果交叉引用本地范围之外的内容,则有必要使用点.。例如,如果您正在编写交叉引用的类中引用属性或方法,则以下操作不起作用:

:meth:`method`
:attr:`method`

还请注意,在范围内:meth::func:都可以互换工作。但是,在范围之外,您必须使用确切的角色,这取决于您是引用方法还是函数

请注意,您可能会发生名称冲突,因为相同的名称可用于不同对象的不同模块中。在这种情况下,您应该使用完全限定名来准确区分所引用的对象

检查索引以验证对象是否已插入其中非常重要(这是由.rst文件中的autodoc或domain指令自动完成的)。普通索引将显示“对象名(完全限定名)”,如果它在索引中,则可以交叉引用


编辑:下面是一个将.method显示为class.method的解决方法;以上信息适用

`ClassName.`:meth:`.method`

相关问题 更多 >