mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #3528 from jakobandersen/field-pending-xref-annotation
Callback on domains to annotate xrefs created from docfields.
This commit is contained in:
commit
a98414355a
1
CHANGES
1
CHANGES
@ -29,6 +29,7 @@ Bugs fixed
|
||||
* #3507: wrong quotes in latex output for productionlist directive
|
||||
* #3533: Moving from Sphinx 1.3.1 to 1.5.3 breaks LaTeX compilation of links
|
||||
rendered as code
|
||||
* #2665, #2607: Link names in C++ docfields, and make it possible for other domains.
|
||||
|
||||
Testing
|
||||
--------
|
||||
|
@ -218,6 +218,12 @@ class Domain(object):
|
||||
"""Process a document after it is read by the environment."""
|
||||
pass
|
||||
|
||||
def process_field_xref(self, pnode):
|
||||
"""Process a pending xref created in a doc field.
|
||||
For example, attach information about the current scope.
|
||||
"""
|
||||
pass
|
||||
|
||||
def resolve_xref(self, env, fromdocname, builder,
|
||||
typ, target, node, contnode):
|
||||
"""Resolve the pending_xref *node* with the given *typ* and *target*.
|
||||
|
@ -4470,6 +4470,12 @@ class CPPDomain(Domain):
|
||||
# print(self.data['root_symbol'].dump(0))
|
||||
pass
|
||||
|
||||
def process_field_xref(self, pnode):
|
||||
symbol = self.env.ref_context['cpp:parent_symbol']
|
||||
key = symbol.get_lookup_key()
|
||||
assert key
|
||||
pnode['cpp:parent_key'] = key
|
||||
|
||||
def merge_domaindata(self, docnames, otherdata):
|
||||
self.data['root_symbol'].merge_with(otherdata['root_symbol'],
|
||||
docnames, self.env)
|
||||
|
@ -86,9 +86,9 @@ def _pseudo_parse_arglist(signode, arglist):
|
||||
# when it comes to handling "." and "~" prefixes.
|
||||
class PyXrefMixin(object):
|
||||
def make_xref(self, rolename, domain, target, innernode=nodes.emphasis,
|
||||
contnode=None):
|
||||
contnode=None, env=None):
|
||||
result = super(PyXrefMixin, self).make_xref(rolename, domain, target,
|
||||
innernode, contnode)
|
||||
innernode, contnode, env)
|
||||
result['refspecific'] = True
|
||||
if target.startswith(('.', '~')):
|
||||
prefix, result['reftarget'] = target[0], target[1:]
|
||||
@ -102,7 +102,7 @@ class PyXrefMixin(object):
|
||||
return result
|
||||
|
||||
def make_xrefs(self, rolename, domain, target, innernode=nodes.emphasis,
|
||||
contnode=None):
|
||||
contnode=None, env=None):
|
||||
delims = '(\s*[\[\]\(\),](?:\s*or\s)?\s*|\s+or\s+)'
|
||||
delims_re = re.compile(delims)
|
||||
sub_targets = re.split(delims, target)
|
||||
@ -118,7 +118,7 @@ class PyXrefMixin(object):
|
||||
results.append(contnode or innernode(sub_target, sub_target))
|
||||
else:
|
||||
results.append(self.make_xref(rolename, domain, sub_target,
|
||||
innernode, contnode))
|
||||
innernode, contnode, env))
|
||||
|
||||
return results
|
||||
|
||||
|
@ -55,35 +55,37 @@ class Field(object):
|
||||
self.bodyrolename = bodyrolename
|
||||
|
||||
def make_xref(self, rolename, domain, target,
|
||||
innernode=addnodes.literal_emphasis, contnode=None):
|
||||
innernode=addnodes.literal_emphasis, contnode=None, env=None):
|
||||
if not rolename:
|
||||
return contnode or innernode(target, target)
|
||||
refnode = addnodes.pending_xref('', refdomain=domain, refexplicit=False,
|
||||
reftype=rolename, reftarget=target)
|
||||
refnode += contnode or innernode(target, target)
|
||||
if env:
|
||||
env.domains[domain].process_field_xref(refnode)
|
||||
return refnode
|
||||
|
||||
def make_xrefs(self, rolename, domain, target,
|
||||
innernode=addnodes.literal_emphasis, contnode=None):
|
||||
return [self.make_xref(rolename, domain, target, innernode, contnode)]
|
||||
innernode=addnodes.literal_emphasis, contnode=None, env=None):
|
||||
return [self.make_xref(rolename, domain, target, innernode, contnode, env)]
|
||||
|
||||
def make_entry(self, fieldarg, content):
|
||||
return (fieldarg, content)
|
||||
|
||||
def make_field(self, types, domain, item):
|
||||
def make_field(self, types, domain, item, env=None):
|
||||
fieldarg, content = item
|
||||
fieldname = nodes.field_name('', self.label)
|
||||
if fieldarg:
|
||||
fieldname += nodes.Text(' ')
|
||||
fieldname.extend(self.make_xrefs(self.rolename, domain,
|
||||
fieldarg, nodes.Text))
|
||||
fieldarg, nodes.Text, env=env))
|
||||
|
||||
if len(content) == 1 and (
|
||||
isinstance(content[0], nodes.Text) or
|
||||
(isinstance(content[0], nodes.inline) and len(content[0]) == 1 and
|
||||
isinstance(content[0][0], nodes.Text))):
|
||||
content = self.make_xrefs(self.bodyrolename, domain,
|
||||
content[0].astext(), contnode=content[0])
|
||||
content[0].astext(), contnode=content[0], env=env)
|
||||
fieldbody = nodes.field_body('', nodes.paragraph('', '', *content))
|
||||
return nodes.field('', fieldname, fieldbody)
|
||||
|
||||
@ -109,13 +111,13 @@ class GroupedField(Field):
|
||||
Field.__init__(self, name, names, label, True, rolename)
|
||||
self.can_collapse = can_collapse
|
||||
|
||||
def make_field(self, types, domain, items):
|
||||
def make_field(self, types, domain, items, env=None):
|
||||
fieldname = nodes.field_name('', self.label)
|
||||
listnode = self.list_type()
|
||||
for fieldarg, content in items:
|
||||
par = nodes.paragraph()
|
||||
par.extend(self.make_xrefs(self.rolename, domain, fieldarg,
|
||||
addnodes.literal_strong))
|
||||
addnodes.literal_strong, env=env))
|
||||
par += nodes.Text(' -- ')
|
||||
par += content
|
||||
listnode += nodes.list_item('', par)
|
||||
@ -155,11 +157,11 @@ class TypedField(GroupedField):
|
||||
self.typenames = typenames
|
||||
self.typerolename = typerolename
|
||||
|
||||
def make_field(self, types, domain, items):
|
||||
def make_field(self, types, domain, items, env=None):
|
||||
def handle_item(fieldarg, content):
|
||||
par = nodes.paragraph()
|
||||
par.extend(self.make_xrefs(self.rolename, domain, fieldarg,
|
||||
addnodes.literal_strong))
|
||||
addnodes.literal_strong, env=env))
|
||||
if fieldarg in types:
|
||||
par += nodes.Text(' (')
|
||||
# NOTE: using .pop() here to prevent a single type node to be
|
||||
@ -169,7 +171,7 @@ class TypedField(GroupedField):
|
||||
if len(fieldtype) == 1 and isinstance(fieldtype[0], nodes.Text):
|
||||
typename = u''.join(n.astext() for n in fieldtype)
|
||||
par.extend(self.make_xrefs(self.typerolename, domain, typename,
|
||||
addnodes.literal_emphasis))
|
||||
addnodes.literal_emphasis, env=env))
|
||||
else:
|
||||
par += fieldtype
|
||||
par += nodes.Text(')')
|
||||
@ -196,7 +198,7 @@ class DocFieldTransformer(object):
|
||||
"""
|
||||
|
||||
def __init__(self, directive):
|
||||
self.domain = directive.domain
|
||||
self.directive = directive
|
||||
if '_doc_field_type_map' not in directive.__class__.__dict__:
|
||||
directive.__class__._doc_field_type_map = \
|
||||
self.preprocess_fieldtypes(directive.__class__.doc_field_types)
|
||||
@ -308,7 +310,7 @@ class DocFieldTransformer(object):
|
||||
else:
|
||||
fieldtype, content = entry
|
||||
fieldtypes = types.get(fieldtype.name, {})
|
||||
new_list += fieldtype.make_field(fieldtypes, self.domain,
|
||||
content)
|
||||
new_list += fieldtype.make_field(fieldtypes, self.directive.domain,
|
||||
content, env=self.directive.env)
|
||||
|
||||
node.replace_self(new_list)
|
||||
|
Loading…
Reference in New Issue
Block a user