我想要实现的是使用 sphinx' python 域(手动)将 html 类插入到某些元素
例如我有这个字符串:
Lore Ipsum :py:mod:`dataclasses`
结果是:
Lore Ipsum <a class="reference external" href="...dataclasses.html#module-dataclasses">
<code class="xref py py-mod docutils literal notranslate">
<span class="pre">dataclass</span>
</code>
</a>
对于
a
或 code.class
我想添加一个额外的课程。例如"injected"
,得到以下结果
<code class="xref py py-mod docutils literal notranslate injected">
我做了一些研究来寻找解决方案
.. role : injected_mod(?py:mod?)
:class: injected
:injected_mod:`dataclasses`
问题:我不知道括号里要放什么,我想我不能在那里使用域 -> 不是有效的角色。
可能,但是,问题:我想保留来自
py
域的功能。
:py:
域 ❓# conf.py
def setup():
app.add_role_to_domain("py", "injected", PyXRefRole())
什么有效:添加一个我可以使用的
"py-injected"
类py:module
不起作用,即没有 <a class="reference external"
。我无法确定 sphinx 模块中的查找功能发生在何处以及是否可以扩展 PyXRefRole
来执行这两项操作。
这个问题类似,并在comboroles扩展中提供了有用的答案。
这有点好,因为我可以将它与角色指令结合起来来添加类。
:inject:`:py:mod:\`dataclasses\``
问题:这会在
<span class=injected>
生成的块周围添加额外的 py:mod
,而不是修改现有标签。
我不确定嵌套解析是否有点矫枉过正,但到目前为止我还没有添加额外类的解决方案。 我认为使用 comboroles 看起来是目前最有希望继续使用的,但我还不确定如何扩展它或将其实用程序移植到注入类而不是嵌套附加标签的自定义 role_function 中。 我想我需要访问和修改自定义函数中的节点,但这就是我陷入困境的地方。
备注:
目前我使用 comboroles 扩展
找到了这个解决方法
# conf.py
rst_prolog = """
.. role:: inject-role
:class: inject
"""
from sphinxnotes.comboroles import CompositeRole
class InjectClassRole(CompositeRole):
def run(self):
allnodes, messages = super().run()
inner = allnodes[0].children[0]
inner.attributes["classes"].extend(allnodes[0].attributes["classes"]) # type: ignore[attr-defined]
inner.parent = None
return [inner], messages
def setup(app):
app.add_role("inject", InjectClassRole(["inject-role"], nested_parse=True))
有了这个我就可以用了
:inject:`:py:mod:\`dataclasses\``
它将解析
:py:mod:
和 :inject-role:
,但不会创建新的 <span class="inject">
,而是将 inject
类添加到内部角色创建的标签中。我仍然想知道这是否有点过分了。
旁注:硬编码的组合角色也可以这样创建:
app.add_role("inject_mod", InjectClassRole(["inject", "py:mod"], nested_parse=False))
# Usage
:inject_mod:`dataclasses`
可以通过在
inject-role
方法中注入一个附加参数来调整 InjectClassRole.__init__
,而不是依赖额外的 run
。