我在 Sphinx 中编写了一个自定义域。它具有注册项目的指令(所有项目最终都在
data
成员中),然后并行构建与 merge_domaindata
合并在一起。
我想创建一个类似索引的页面,列出在域中注册的每个项目。我想要比常规
Index
拥有更多的控制权 - 特别是,我想为我的域中的 data
中的每个项目生成一些自定义节点。
有什么办法可以做到吗?看看核心事件序列,看起来我必须延迟到所有
env-merge-info
事件完成之后(因为在此之前,我们还没有将多个域对象合并在一起)。但我希望能够在生成的节点中使用交叉引用,因此它应该位于引用解析器转换后之前。
我可以注册一个后转换来做到这一点吗?我该如何解决这个问题,建议的转换优先级是什么?
我仍在寻找更好的答案,但这里至少有一种方法可以实现这一目标。
关键思想是:
对我来说,这最终看起来像这样。
首先,一个仅插入待处理节点的指令:
class CustomIndexDirective(SphinxDirective):
def run(self) -> list[nodes.Node]:
return [nodes.pending(None, transform_target="custom_index_transform")]
然后,一个后变换变压器找到挂起的节点并将其替换为我们想要生成的任何内容:
class CustomIndexTransform(SphinxPostTransform):
default_priority = 0 # still not sure if this is a best practice, but 0 seems to work
for pending_node in self.document.findall(
lambda node: isinstance(node, nodes.pending)
and node.attributes.get("transform_target") == "bmm_index"
):
my_domain = self.env.get_domain("my_domain")
new_node = ... # implement as necessary based on my_domain.data
pending_node.replace_self(new_node)
在扩展根目录中,注册指令和转换:
def setup(app: Sphinx) -> ExtensionMetadata:
app.add_directive("custom-index", CustomIndexDirective)
app.add_post_transform(CustomIndexTransform)
最后,在源树中的 .rst 文件之一中,调用自定义指令:
.. custom-index::