Sphinx扩展开发问题:literal_block内inline节点无法渲染为span元素
问题:Sphinx扩展中literal_block内的inline节点无法渲染为span元素
我正在开发一款用于HTML输出的Sphinx扩展,目标是生成代码块并在其中插入文本与<span>元素。但创建literal_block并添加inline节点(对应span)时,只能显示inline节点的文本内容,无法渲染出带样式的span元素。
相关代码示例
from docutils import nodes from docutils.parsers import rst from sphinx.addnodes import highlightlang class MyDirective(rst.Directive): # 为简化和调试,暂不使用内容 has_content = True def run(self): node = nodes.literal_block() node += nodes.inline("", text = "Hello World", classes = ["myclass"] ) return [ highlightlang( lang = "none", force = None, linenothreshold = -1 ), node ] def setup(app): app.add_directive("helloworld", MyDirective)
期望的HTML输出
<div class="highlight-none notranslate"> <div class="highlight"> <pre><span class="myclass">Hello World</span></pre> </div> </div>
实际得到的HTML输出
<div class="highlight-none notranslate"> <div class="highlight"> <pre>Hello World</pre> </div> </div>
解决方法
literal_block节点在Sphinx的HTML渲染流程中,默认会被当作纯代码块处理,内部的inline节点会被剥离仅保留文本内容。要实现需求,可选择以下两种方式:
方式1:自定义HTML访问器,修改literal_block渲染逻辑
注册自定义HTML转换器,让literal_block渲染时保留内部inline节点结构:
from docutils import nodes from docutils.parsers import rst from sphinx.addnodes import highlightlang from sphinx.writers.html5 import HTML5Translator class MyDirective(rst.Directive): has_content = True def run(self): node = nodes.literal_block() inline_node = nodes.inline("Hello World", classes=["myclass"]) node.append(inline_node) return [ highlightlang(lang="none", force=None, linenothreshold=-1), node ] def setup(app): app.add_directive("helloworld", MyDirective) # 重写literal_block的HTML访问方法 def visit_literal_block(self, node): self.body.append(self.starttag(node, 'pre', '')) def depart_literal_block(self, node): self.body.append('</pre>\n') app.set_translator('html', HTML5Translator, override=True) HTML5Translator.visit_literal_block = visit_literal_block HTML5Translator.depart_literal_block = depart_literal_block
方式2:直接使用raw节点嵌入HTML
如果仅需支持HTML输出,可直接在literal_block中插入raw节点:
from docutils import nodes from docutils.parsers import rst from sphinx.addnodes import highlightlang class MyDirective(rst.Directive): has_content = True def run(self): raw_html = '<span class="myclass">Hello World</span>' raw_node = nodes.raw('', raw_html, format='html') node = nodes.literal_block() node.append(raw_node) return [ highlightlang(lang="none", force=None, linenothreshold=-1), node ] def setup(app): app.add_directive("helloworld", MyDirective)
说明:方式1保留docutils节点结构,兼容性更强;方式2实现简单,但仅适用于HTML场景。
内容的提问来源于stack exchange,提问作者Jonas
相关产品推荐
相关产品推荐

