You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止Sphinx将交叉引用目标中的大写字母转为小写?

解决Sphinx引用大小写不匹配问题

问题背景

将t2t格式旧文档转为rst后,Sphinx生成TeX/HTML时会把引用目标(如.. _test-ONE:)的大写字母转为小写(生成\label{\detokenize{testfile:test-one}}),但文本中的超引用(如test_ONE <#test-ONE>__)仍保留大写,导致链接失效。以下是无需批量修改rst文件的Sphinx内置解决方案:


方案1:保留引用目标的原始大小写

通过覆盖Sphinx默认的slugify函数,阻止其将引用ID转为小写。在项目的conf.py中添加以下代码:

from sphinx.util import slugify

def custom_slugify(value, separator="-"):
    # 仅替换空格为分隔符,保留原始大小写
    return value.replace(" ", separator)

# 替换默认的slugify处理逻辑
slugify = custom_slugify

修改后,引用目标.. _test-ONE:会被生成为\label{\detokenize{testfile:test-ONE}},与超引用中的目标完全匹配,链接即可正常工作。


方案2:将超引用的目标转为小写

如果希望保持引用目标的小写转换逻辑,可通过自定义文档转换规则,将所有超引用的锚点转为小写。在conf.py中添加以下代码:

from docutils import nodes
from sphinx.transforms import SphinxTransform

class LowercaseRefTargets(SphinxTransform):
    default_priority = 999  # 确保在其他转换后执行

    def apply(self):
        # 遍历文档中所有引用节点
        for ref in self.document.traverse(nodes.reference):
            # 处理同一文档内的锚点引用(以#开头)
            ref_uri = ref.get('refuri', '')
            if ref_uri.startswith('#'):
                ref['refuri'] = '#' + ref_uri[1:].lower()
            # 处理内部引用的refname属性
            ref_name = ref.get('refname')
            if ref_name:
                ref['refname'] = ref_name.lower()

def setup(app):
    app.add_transform(LowercaseRefTargets)

该转换会在文档构建过程中自动将所有超引用的目标转为小写,与Sphinx生成的小写引用目标匹配。


为什么之前的LaTeX配置无效

你尝试的latex_elements配置仅能禁用LaTeX层面的大写转换,但Sphinx在生成.tex文件时,已经提前将引用ID转为小写并写入\label中,因此LaTeX预定义无法修改已生成的标签内容。

内容的提问来源于stack exchange,提问作者Banone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 00:11:03