def fix_ids(self, tree):
"""Replace colons with hyphens in href and id attributes.
Some readers crash because they interpret the part as a
transport protocol specification.
"""
for node in tree.traverse(nodes.reference):
if 'refuri' in node:
m = _refuri_re.match(node['refuri'])
if m:
node['refuri'] = self.fix_fragment(m.group(1), m.group(2))
if 'refid' in node:
node['refid'] = self.fix_fragment('', node['refid'])
for node in tree.traverse(addnodes.desc_signature):
ids = node.attributes['ids']
newids = []
for id in ids:
newids.append(self.fix_fragment('', id))
node.attributes['ids'] = newids
python类desc_signature()的实例源码
def _pseudo_parse_arglist(signode, arglist):
# type: (addnodes.desc_signature, unicode) -> None
""""Parse" a list of arguments separated by commas.
Arguments can have "optional" annotations given by enclosing them in
brackets. Currently, this will split at any comma, even if it's inside a
string literal (e.g. default argument value).
This function comes from sphinx.domains.python.
"""
paramlist = addnodes.desc_parameterlist()
stack = [paramlist]
try:
for argument in arglist.split(','):
argument = argument.strip()
ends_open = ends_close = 0
while argument.startswith('['):
stack.append(addnodes.desc_optional())
stack[-2] += stack[-1]
argument = argument[1:].strip()
while argument.startswith(']'):
stack.pop()
argument = argument[1:].strip()
while argument.endswith(']') and not argument.endswith('[]'):
ends_close += 1
argument = argument[:-1].strip()
while argument.endswith('['):
ends_open += 1
argument = argument[:-1].strip()
if argument:
stack[-1] += addnodes.desc_parameter(argument, argument)
while ends_open:
stack.append(addnodes.desc_optional())
stack[-2] += stack[-1]
ends_open -= 1
while ends_close:
stack.pop()
ends_close -= 1
if len(stack) != 1:
raise IndexError
except IndexError:
# if there are too few or too many elements on the stack, just give up
# and treat the whole argument list as one argument, discarding the
# already partially populated paramlist node
signode += addnodes.desc_parameterlist()
signode[-1] += addnodes.desc_parameter(arglist, arglist)
else:
signode += paramlist
def doctree_read(app, doctree):
env = app.builder.env
resolve_target = getattr(env.config, 'linkcode_resolve', None)
if not isinstance(env.config.linkcode_resolve, collections.Callable):
raise LinkcodeError(
"Function `linkcode_resolve` is not given in conf.py")
domain_keys = dict(
py=['module', 'fullname'],
c=['names'],
cpp=['names'],
js=['object', 'fullname'],
)
for objnode in doctree.traverse(addnodes.desc):
domain = objnode.get('domain')
uris = set()
for signode in objnode:
if not isinstance(signode, addnodes.desc_signature):
continue
# Convert signode to a specified format
info = {}
for key in domain_keys.get(domain, []):
value = signode.get(key)
if not value:
value = ''
info[key] = value
if not info:
continue
# Call user code to resolve the link
uri = resolve_target(domain, info)
if not uri:
# no source
continue
if uri in uris or not uri:
# only one link per name, please
continue
uris.add(uri)
onlynode = addnodes.only(expr='html')
onlynode += nodes.reference('', '', internal=False, refuri=uri)
onlynode[0] += nodes.inline('', _('[source]'),
classes=['viewcode-link'])
signode += onlynode
def doctree_read(app, doctree):
env = app.builder.env
resolve_target = getattr(env.config, 'linkcode_resolve', None)
if not callable(env.config.linkcode_resolve):
raise LinkcodeError(
"Function `linkcode_resolve` is not given in conf.py")
domain_keys = dict(
py=['module', 'fullname'],
c=['names'],
cpp=['names'],
js=['object', 'fullname'],
)
for objnode in doctree.traverse(addnodes.desc):
domain = objnode.get('domain')
uris = set()
for signode in objnode:
if not isinstance(signode, addnodes.desc_signature):
continue
# Convert signode to a specified format
info = {}
for key in domain_keys.get(domain, []):
value = signode.get(key)
if not value:
value = ''
info[key] = value
if not info:
continue
# Call user code to resolve the link
uri = resolve_target(domain, info)
if not uri:
# no source
continue
if uri in uris or not uri:
# only one link per name, please
continue
uris.add(uri)
onlynode = addnodes.only(expr='html')
onlynode += nodes.reference('', '', internal=False, refuri=uri)
onlynode[0] += nodes.inline('', _('[source]'),
classes=['viewcode-link'])
signode += onlynode
def doctree_read(app, doctree):
env = app.builder.env
if not hasattr(env, '_viewcode_modules'):
env._viewcode_modules = {}
def has_tag(modname, fullname, docname, refname):
entry = env._viewcode_modules.get(modname, None)
try:
analyzer = ModuleAnalyzer.for_module(modname)
except Exception:
env._viewcode_modules[modname] = False
return
if not isinstance(analyzer.code, text_type):
code = analyzer.code.decode(analyzer.encoding)
else:
code = analyzer.code
if entry is None or entry[0] != code:
analyzer.find_tags()
entry = code, analyzer.tags, {}, refname
env._viewcode_modules[modname] = entry
elif entry is False:
return
_, tags, used, _ = entry
if fullname in tags:
used[fullname] = docname
return True
for objnode in doctree.traverse(addnodes.desc):
if objnode.get('domain') != 'py':
continue
names = set()
for signode in objnode:
if not isinstance(signode, addnodes.desc_signature):
continue
modname = signode.get('module')
fullname = signode.get('fullname')
refname = modname
if env.config.viewcode_import:
modname = _get_full_modname(app, modname, fullname)
if not modname:
continue
fullname = signode.get('fullname')
if not has_tag(modname, fullname, env.docname, refname):
continue
if fullname in names:
# only one link per name, please
continue
names.add(fullname)
pagename = '_modules/' + modname.replace('.', '/')
onlynode = addnodes.only(expr='html')
onlynode += addnodes.pending_xref(
'', reftype='viewcode', refdomain='std', refexplicit=False,
reftarget=pagename, refid=fullname,
refdoc=env.docname)
onlynode[0] += nodes.inline('', _('[source]'),
classes=['viewcode-link'])
signode += onlynode
def doctree_read(app, doctree):
env = app.builder.env
resolve_target = getattr(env.config, 'linkcode_resolve', None)
if not isinstance(env.config.linkcode_resolve, collections.Callable):
raise LinkcodeError(
"Function `linkcode_resolve` is not given in conf.py")
domain_keys = dict(
py=['module', 'fullname'],
c=['names'],
cpp=['names'],
js=['object', 'fullname'],
)
for objnode in doctree.traverse(addnodes.desc):
domain = objnode.get('domain')
uris = set()
for signode in objnode:
if not isinstance(signode, addnodes.desc_signature):
continue
# Convert signode to a specified format
info = {}
for key in domain_keys.get(domain, []):
value = signode.get(key)
if not value:
value = ''
info[key] = value
if not info:
continue
# Call user code to resolve the link
uri = resolve_target(domain, info)
if not uri:
# no source
continue
if uri in uris or not uri:
# only one link per name, please
continue
uris.add(uri)
onlynode = addnodes.only(expr='html')
onlynode += nodes.reference('', '', internal=False, refuri=uri)
onlynode[0] += nodes.inline('', _('[source]'),
classes=['viewcode-link'])
signode += onlynode