我想创建一个role
,coderef
,它将引用由sphinx.ext.viewcode
生成的插入模块代码。为此,我得到的印象是我需要适当地填充env._viewcode_modules
,但我不确定该怎么做。
看着viewcode
,看来viewcode.doctree_read
扫描文档树中的addnode.desc_signature
节点(嵌套在addnode.desc
节点下)时,填充了env._viewcode_modules
,这样就可以插入模块了。插入字典中的值最初是None
,如果无法插入模块,则将其替换为False
,或者是 document node (在此处不确定) ,何时可以掉毛。似乎sphinx.ext.viewcode.collect_pages
对这些内容进行了相应的迭代。
我的希望是加入这种机制,当遇到coderef
事件时,只需在env._viewcode_modules
中添加一些其他条目。但是,我不确定我是否正确执行了此操作。我拥有的代码如下:
from docutils import nodes, utils
from sphinx import addnodes
from sphinx.util.nodes import split_explicit_title
def coderef(role, rawtext, text, line, inliner, options={}, content=[]):
try :
env = inliner.document.settings.env
if not hasattr(env, '_viewcode_modules'): env._viewcode_modules = {} # View Code retains a list of modules, we sneak the cross linked modules into the list.
test, name, link = split_explicit_title(text)
refid = link.replace('.','-')
refuri = env.app.builder.get_relative_uri("/", "/".join(["_modules", *link.split('.')])) # Originally : "_modules/" + link.replace('.','/')
refname = utils.unescape(name) # Future : inliner.nested_parse() ?
reflink = utils.unescape("_modules/" + link.replace(".","/")) # str(Path("_modules").join(target.split('.')))
refnode = nodes.inline('', refname, classes=['viewcode-link']) # viewcode-link is a CSS class
coderef = addnodes.only(expr='html')
coderef+= addnodes.pending_xref('', refname,
refid = refid,
reftype = 'viewcode' or role, # The reference type, see viewcode extention
refdomain = 'std', #
refexplicit = False, #
refdoc = env.docname, # Originally : env.docname; This represents the name of the document with all extentions stripped, I think this doubles as a back reference.
reftarget = reflink)
return [coderef], []
except Exception as error : # This is bad form, specify explicit errors you know how to deal with
msg = inliner.reporter.error(
'An error occured while determining the code reference for'
' "%s" ' % text,
line = line)
prb = inliner.problematic(rawtext, text, msg)
return [prb], [msg]
以前,我设法使用nodes.reference
来部分解决这个问题,但是由于总是没有生成带斜线的模块,因为它们没有被添加到env._viewcode_modules
且未被sphinx.ext.viewcode.collect_pages
处理。
我尚不了解的一些奇怪之处是如何解决addnodes.pending_xref
。似乎必须同时具有反向引用和正向引用,并且我认为目前我还没有创建适当的反向引用。 addnodes.pending_xref
似乎也接受nodes.inline
节点,大概是最终链接中文本的节点;目前也无法正确管理。